Opened 13 years ago
Closed 13 years ago
#32426 closed defect (fixed)
angelscript: sometimes rebuilds in destroot phase, causing wrong library install_name
Reported by: | ryandesign (Ryan Carsten Schmidt) | Owned by: | rudloff@… |
---|---|---|---|
Priority: | Normal | Milestone: | |
Component: | ports | Version: | 2.0.3 |
Keywords: | Cc: | ||
Port: | angelscript |
Description
The angelscript port added in r87787 has an intermittent problem where it will sometimes rebuild the libraries in the destroot phase. When it does this, it might use an incorrect compiler (i.e. if the user had selected a different compiler than the default, because we're only setting the CXX
environment variable in the build phase and not in the destroot phase), and it will definitely write the wrong install_name
into the library (because it's based on the LOCAL
variable which is prefixed with ${destroot}
in the destroot phase).
The reason this happens is because of the way the makefile is written. In the notes I will explain the problem in more detail and show how I'm fixing it. This is an upstream problem; the developers should fix it in their sources (though I won't claim that my method is the best way to fix it).
Change History (2)
comment:1 Changed 13 years ago by ryandesign (Ryan Carsten Schmidt)
comment:2 Changed 13 years ago by ryandesign (Ryan Carsten Schmidt)
Resolution: | → fixed |
---|---|
Status: | new → closed |
As shipped, the makefile does nothing in the all
rule, other than depend on TARG
. So I fixed the problem in r87788 by adding a step to the all
rule to change the modification time of the object and library directories to an earlier time, namely the time the makefile was modified (it seemed as good a time as any). That way, by the time the install
rule is called, the library directory will be older than the libraries, so a rebuild won't occur. I have never seen a makefile do this, and I know plenty of makefiles that create directories, so I feel like there must be an easier or better solution, but I don't know it. I have a feeling it might involve not using rules to represent directory creations, but changing that is more re-engineering than I wanted to get into right now.
The makefile defines a variable
TARG
representing all the targets that will be built and installed (i.e. the three libraries):The
all
andinstall
rules depend on this variable, and thus on all three libraries: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):
There are also variables
OBJ
andBOBJ
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:
The problem comes about because of the way
make
works, and the way directories work. The waymake
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:
make all
, which depends onTARG
, which expands to the three libraries.make install
, which depends onTARG
, which expands to the three libraries.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 UsingTheRightCompiler).