[MacPorts] #32426: angelscript: sometimes rebuilds in destroot phase, causing wrong library install_name
MacPorts
noreply at macports.org
Mon Dec 5 22:19:55 PST 2011
#32426: angelscript: sometimes rebuilds in destroot phase, causing wrong library
install_name
-------------------------------------+--------------------------------------
Reporter: ryandesign@… | Owner: rudloff@…
Type: defect | Status: new
Priority: Normal | Milestone:
Component: ports | Version: 2.0.3
Keywords: | Port: angelscript
-------------------------------------+--------------------------------------
Comment(by ryandesign@…):
The makefile defines a variable `TARG` representing all the targets that
will be built and installed (i.e. the three libraries):
{{{
TARG = $(LIBDIR)/$(LIB) $(LIBDIR)/$(DEVLIB) $(LIBDIR)/$(BUNDLE)
}}}
The `all` and `install` rules depend on this variable, and thus on all
three libraries:
{{{
all: $(TARG)
...
install: $(TARG)
}}}
There are also two rules to create directories: the object directory
(where objects get built before they're packed into a library) and the
library directory (where the libraries go after they're built):
{{{
$(OBJDIR):
mkdir $(OBJDIR)
$(LIBDIR):
mkdir $(LIBDIR)
}}}
There are also variables `OBJ` and `BOBJ` containing the lists of objects
needed for the libraries, not relevant to the problem.
The three libraries are defined as depending on the creation of the
directories, and on their list of objects, as follows:
{{{
$(LIBDIR)/$(LIB): $(OBJDIR) $(LIBDIR) $(OBJ)
...
$(LIBDIR)/$(DEVLIB): $(OBJDIR) $(LIBDIR) $(OBJ)
...
$(LIBDIR)/$(BUNDLE): $(OBJDIR) $(LIBDIR) $(BOBJ)
...
}}}
The problem comes about because of the way `make` works, and the way
directories work. The way `make` works is that for each rule, it
determines whether the file (or directory) that the rule is for exists. If
not, it deals with the dependencies, and then makes the rule. If the file
the rule is for does exist, it looks at the timestamps of that file, and
of the dependencies' files, and of the makefile; if the makefile or the
dependencies are newer, then the rule is remade. The way directories work
is that if you add or remove a file in the directory, the directory's
modification time is updated.
The error is always reproducible in a serial build (unless you have a
computer that's 10-20 times faster than mine). The sequence of events is
as follows:
* T1
* MacPorts runs `make all`, which depends on `TARG`, which expands to
the three libraries.
* T2
* The dependencies of the first library are evaluated. Neither the
object directory nor the library directory exist, so those rules are run,
thus creating those directories. Their modification time is T2.
* T3
* The first object is built, in the object directory. The act of
creating the object file in the object directory causes the object
directory's modification time to be updated to T3.
* ... similarly for the other object files. This takes a couple dozen
seconds on my system. As each object is built, the object directory's
modification time advances.
* T4
* The first library is built. This takes some seconds. It gets put into
the library directory. This causes the library directory's modification
time to be updated and is now T4.
* T5
* The dependencies of the second library are evaluated. The directories
already exist; no action necessary. The objects are the same as the first
library's so they're already built too.
* T6
* The second library is built. This takes some seconds. It gets put
into the library directory, thus updating the library directory's
modification time to T6.
* ... similarly with the third library
* T7
* MacPorts runs `make install`, which depends on `TARG`, which expands
to the three libraries.
* T8
* The first library exists; its modification time is T4. The
dependencies of the first library are evaluated. The object directory
exists and its modification time is somewhere between T3 and T4 which is
older than the library so we move on. The library directory exists, but
its modification time is T6. This is newer than the library's T4
modification time, so `make` rebuilds the first library, and there we have
the problem.
The reason the problem is intermittent is that MacPorts runs a parallel
build by default -- and not a serial build -- provided you have enough
memory and processor cores. On my system, the libraries were either
finishing up their simultaneous builds at the same exact second (in which
case the destroot would happen normally), or a second apart (thus
triggering the rebuild in the destroot phase, and, in my case, an error
message from [wiki:UsingTheRightCompiler#testing]).
--
Ticket URL: <https://trac.macports.org/ticket/32426#comment:1>
MacPorts <http://www.macports.org/>
Ports system for Mac OS
More information about the macports-tickets
mailing list