[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