foo.exe : foo.omake work. Ideally, a makefile should contain an explicit dependency like this for every file used by a rule. So, if foo.exe depends on foo.o and util.lib, there ought to be something like:foo.exe: foo.o util.libfoo.exe: gcc -o foo.exe foo.o
make evaluates prerequisites (strictly left-to-right). If the makefile indicatesall: foo.o util.lib foo.exemake all will provide the following build order:
foo.o
util.lib
foo.exe
all
make will evaluate the targets in this order, we can rely on this ordering to satisfy the implicit dependency between foo.exe and foo.o. Another way to produce this effect is to use a list and iterator structure to explicitly call submakes from within a rule body; in fact, any mechanism which invokes submakes - and therefore controls rule execution order - can do this.make will suddenly 'just work' when the ordering is accidentally right. Builds which break because an implicit dependency was not respected are just as common, and can be really hard to diagnose.tail of our build log:
g++ -DMYSQL_SERVER -DDEFAULT_MYSQL_HOME="\"/usr/local\"" -DDATADIR="\"/usr/local
/var\"" -DSHAREDIR="\"/usr/local/share/mysql\"" -DHAVE_CONFIG_H -I. -I. -I.. -I.
./zlib -I../innobase/include -I../include -I../include -I../regex -I. -O3 -D
DBUG_OFF -fno-implicit-templates -fno-exceptions -fno-rtti -c -I../zlib -I../
innobase/include -I../include -I../include -I../regex -I. -DTZINFO2SQL mysql_tz
info_to_sql.cc
make[4]: *** No rule to make target `../myisam/libmyisam.a', needed by `mysql_tz
info_to_sql.exe'. Stop.
make[4]: Leaving directory `c:/example/mysql-4.1.22/sql'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `c:/example/mysql-4.1.22/sql'
make[2]: *** [all] Error 2
make[2]: Leaving directory `c:/example/mysql-4.1.22/sql'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `c:/example/mysql-4.1.22'
make: *** [all] Error 2
No rule to make target can be a frustrating error, because there are generally no references in a build log to that file, and (of course) there won't be an obvious rule for it in the makefile. Let's open the log in SparkBuild Insight, and take a look at the failed job list:
all and all-recursive jobs. Double-clicking on mysql_tzinfo_to_sql.exe will bring up the complaining job:
emake.)

sql component directory, and the file we're missing (and don't know how to make) is in the myisam directory. This tells us to look for the rule to make ../myisam/libmyisam.a should be in myisam/Makefile:
gnu make is a narrow-minded piece of software. It can only work with the rules it has been given, and it doesn't know about rules other make instances have read - so the makefile in the myisam directory has a rule to build ../myisam/libmyisam.a - but that makefile isn't loaded by the submake in the sql directory, and the sql submake is the one complaining about 'No rule to make'.emake a map to follow when looking for the rule to make a target. In this instance, a build invoked from the sql directory with subbuilds turned on would be able to build ../myisam/libmyisam.a automatically.)sql submake isn't capable of building libmyisam.a, we need to figure out whether the myisam component was built. This can be done in SparkBuild Insight, starting in the Job Path pane of the mysql_tzinfo_to_sql.exe job. We're looking for a job which is run from the top-level source directory, and which invokes submakes in the individual component directories (like the sql submake.) By looking at the 'Working dir' field for each make instance, we can identify likely jobs pretty easily.all-recursive target appears to be what we're looking for (it's the rule job directly after the relevant make job):
all-recursive job exposes a valuable piece of the puzzle:
include, Docs, zlib, and sql submakes are executed, but nowhere does the myisam component show up. This explains why make couldn't get ../myisam/libmyisam.a to build mysql_tzinfo_to_sql.exe. So, why wasn't myisam built?all-recursive target.
all-recursive behavior:
mysql_tzinfo_to_sql.exe and libmyisam.a isn't available - so we'll have to generalize:sql : myisammyisam target to be built before the sql target - which is fine for serial make, but will slow down a parallel one. But, when we make this change to the makefile, the build still fails!
make of its ability to correctly order the targets. So our sql : myisam rule has no effect - the all-recursive target doesn't list any prerequisites, and at this make level there's no rule for myisam anyways.myisam/libmyisam.a is available for mysql_tzinfo_to_sql.exe it's therefore necessary to make sure that the list of directories for the iterator is properly ordered. Since our build failed because targets produced for myisam weren't available at the time sql was built, we now need to check the directory list ordering.$(SUBDIRS) macro, we can seek through the makefile to find it:SUBDIRS = . include Docs zlib sql libmysql\ cmd-line-utils sql-common \ pstack \ strings [...] myisam myisammrg [...]
sql target occurs earlier than the myisam in the list of directories which will be recursed through. But wait! Don't just move myisam earlier in the SUBDIRS definition - the sql target may have other dependencies. Going back to the makefile in the sql directory will help us make an informed fix:mysql_tzinfo_to_sql$(EXEEXT): $(mysql_tzinfo_to_sql_OBJECTS) $(mysql_tzinfo_to_sql_DEPENDENCIES)sql component - it will contain an explicit list of the files required for mysql_tzinfo_to_sql.exe - and the paths to those files should indicate components which should be built first.am__DEPENDENCIES_1 macro:
SUBDIRS declaration looks like this:SUBDIRS = . include Docs zlib \ cmd-line-utils sql-common \ pstack \ strings [...] myisam myisammrg [...] sql [...]
Tags: broken, build, compiler, debugging, emake, failure, gcc, insight, makefile, sparkbuild
© 2010 Created by Electric Cloud Administrator
You need to be a member of SparkBuild Community to add comments!
Join SparkBuild Community