📄 jamfile.html
字号:
set to $(SOURCE_GRIST). So given this Jamfile: <PRE> SubDir TOP src lock ; Main locker : lock.c ; </PRE> the object file created is lock.o (or lock.obj) and its target identifier is <src!lock>lock.o (or <src!lock>lock.obj). <P> You can also call Objects directly. For example:<PRE> Objects a.c b.c c.c ;</PRE> This compiles a.c into a.o, b.c into b.o, etc. The object file suffix is supplied by the Objects rule.<P><H4> Object Rule</H4> Objects gets its work done by calling the Object rule on each of the source files. You could use the Object rule directly. For example, on Unix, you could use:<PRE> Object foo.o : foo.c ;</PRE> However, the Object rule does not provide suffixes, and it does not provide the grist needed to construct target identifiers if you are using the SubDir* rules. A portable and robust Jamfile would need to invoke Object thus: <PRE> Object <src!util>foo$(SUFOBJ) : <src!util>foo.c ; </PRE> which is inelegant and clearly shows why using Objects is better than using Object. <P> If there's any advantage to the Object rule, it's that it doesn't require that the object name bear any relationship to the source. It is thus possible to compile the same file into different objects. For example:<PRE> Object a.o : foo.c ; Object b.o : foo.c ; Object c.o : foo.c ;</PRE> This compiles foo.c (three times) into a.o, b.o, and c.o. Later examples show how this is useful.<P> The Object rule looks at the suffix of the source file and calls the appropriate rules to do the actual preprocessing (if any) and compiling needed to produce the output object file. The Object rule is capable of the generating of an object file from any type of source. For example:<PRE> Object grammar$(SUFOBJ) : grammar.y ; Object scanner$(SUFOBJ) : scanner.l ; Object fastf$(SUFOBJ) : fastf.f ; Object util$(SUFOBJ) : util.c ;</PRE> An even more elegant way to get the same result is to let the Objects rule call Object: <PRE> Objects grammar.y scanner.l fastf.f util.c ; </PRE> <P> In addition to calling the compile rules, Object sets up a bunch of variables specific to the source and target files. (See Variables Used in Compiling, below.)<P><H4> Cc, C++, Yacc, Lex, Fortran, As, etc. Rules</H4><P> The Object rule calls compile rules specific to the suffix of the source file. (You can see which suffixes are supported by looking at the Object rule definition in Jambase.) Because the extra work done by the Object rule, it is not always useful to call the compile rules directly. But the adventurous user might attempt it. For example:<PRE> Yacc grammar.c : grammar.y ; Lex scan.c : scan.l ; Cc prog.o : prog.c ;</PRE> These examples individually run yacc(1), lex(1), and the C compiler on their sources.<P><H4> UserObject Rule</H4> Any files with suffixes not understood by the Object rule are passed to the UserObject rule. The default definition of UserObject simply emits a warning that the suffix is not understood. This Jambase rule definition is intended to be overridden in Jamrules with one that recognizes the project-specific source file suffixes. For example:<PRE> #In Jamrules: rule UserObject { switch $(>) { case *.rc : ResourceCompiler $(<) : $(>) ; case * : ECHO "unknown suffix on" $(>) ; } } rule ResourceCompiler { DEPENDS $(<) : $(>) ; Clean clean : $(<) ; } actions ResourceCompiler { rc /fo $(<) $(RCFLAGS) $(>) } #In Jamfile: Library liblock : lockmgr.c ; if $(NT) { Library liblock : lock.rc ; }</PRE><P> In this example, the UserObject definition in Jamrules allows *.rc files to be handle as regular Main and Library sources. The lock.rc file is compiled into lock.obj by the "rc" command, and lock.obj is archived into a library with other compiled objects.<H4> LibraryFromObjects Rule</H4> Sometimes the Library rule's straightforward compiling of source into object modules to be archived isn't flexible enough. The LibraryFromObjects rule does the archiving (and deleting) job of the Library rule, but not the compiling. The user can make use of the Objects or Object rule for that. For example:<PRE> LibraryFromObjects libfoo.a : max.o min.o ; Object max.o : maxmin.c ; Object min.o : maxmin.c ; ObjectCcFlags max.o : -DUSEMAX ; ObjectCcFlags min.o : -DUSEMIN ;</PRE> This Unix-specific example compiles the same source file into two different objects, with different compile flags, and archives them. (The ObjectCcFlags rule is described shortly.) Unfortunately, the portable and robust implementation of the above example is not as pleasant to read: <PRE> SubDir TOP foo bar ; LibraryFromObjects libfoo$(SUFLIB) : <foo!bar>max$(SUFOBJ) <foo!bar>min$(SUFOBJ) ; Object <foo!bar>min$(SUFOBJ) : <foo!bar>maxmin.c ; Object <foo!bar>max$(SUFOBJ) : <foo!bar>maxmin.c ; ObjectCcFlags <foo!bar>min$(SUFOBJ) : -DUSEMIN ; ObjectCcFlags <foo!bar>max$(SUFOBJ) : -DUSEMAX ; </PRE> Note that, among other things, you must supply the library file suffix when using the LibraryFromObjects rule.<P><H4> MainFromObjects Rule</H4> Similar to LibraryFromObjects, MainFromObjects does the linking part of the Main rule, but not the compiling. MainFromObjects can be used when there are no objects at all, and everything is to be loaded from libraries. For example:<PRE> MainFromObjects testprog ; LinkLibraries testprog : libprog ; Library libprog : main.c util.c ;</PRE> On Unix, say, this generates a link command that looks like:<PRE> cc -o testprog libprog.a</PRE> Linking purely from libraries is something that doesn't work everywhere: it depends on the symbol "main" being undefined when the linker encounters the library that contains the definition of "main".<P><H4> Variables Used in Compiling</H4> The following variables control the compiling of source files:<P><CENTER><TABLE><TR><TD VALIGN=TOP> C++ <TD><TD>The C++ compiler command<TR><TD VALIGN=TOP> CC <TD><TD>The C compiler command<TR><TD VALIGN=TOP> C++FLAGS <BR> CCFLAGS <TD VALIGN=TOP><TD VALIGN=TOP>Compile flags, used to create or update compiled objects<TR><TD> SUBDIRC++FLAGS <BR> SUBDIRCCFLAGS <TD VALIGN=TOP><TD VALIGN=TOP>Additonal compile flags for source files in this directory.<TR><TD VALIGN=TOP> OPTIM <TD><TD>Compiler optimization flag. The Cc and C++ actions use this as well as C++FLAGS or CCFLAGS.<TR><TD VALIGN=TOP> HDRS <TD VALIGN=TOP><TD>Non-standard header directories; i.e., the directories the compiler will not look in by default and which therefore must be supplied to the compile command. These directories are also used by <b>jam</b> to scan for include files.<TR><TD VALIGN=TOP> STDHDRS <TD VALIGN=TOP><TD>Standard header directories, i.e., the directories the compiler searches automatically. These are not passed to the compiler, but they are used by <b>jam</b> to scan for include files.<TR><TD> SUBDIRHDRS <TD><TD>Additional paths to add to HDRS for source files in this directory.<TR><TD> LEX <TD><TD>The lex(1) command <TR><TD> YACC <TD><TD>The yacc(1) command </TABLE></CENTER><P> The Cc rule sets a target-specific $(CCFLAGS) to the current value of $(CCFLAGS) and $(SUBDIRCCFLAGS). Similarly for the C++ rule. The Object rule sets a target-specific $(HDRS) to the current value of $(HDRS) and $(SUBDDIRHDRS).<P> $(CC), $(C++), $(CCFLAGS), $(C++FLAGS), $(OPTIM), and $(HDRS) all affect the compiling of C and C++ files. $(OPTIM) is separate from $(CCFLAGS) and $(C++FLAGS) so they can be set independently.<P> $(HDRS) lists the directories to search for header files, and it is used in two ways: first, it is passed to the C compiler (with the flag -I prepended); second, it is used by HdrRule to locate the header files whose names were found when scanning source files. $(STDHDRS) lists the header directories that the C compiler already knows about. It does not need passing to the C compiler, but is used by HdrRule.<P> Note that these variables, if set as target-specific variables, must be set on the target, not the source file. The target file in this case is the object file to be generated. For example:<PRE> Library libximage : xtiff.c xjpeg.c xgif.c ; HDRS on xjpeg$(SUFOBJ) = /usr/local/src/jpeg ; CCFLAGS on xtiff$(SUFOBJ) = -DHAVE_TIFF ;</PRE> This can be done more easily with the rules that follow.<P><H4> ObjectCcFlags, ObjectC++Flags, ObjectHdrs Rules</H4> $(CCFLAGS), $(C++FLAGS) and $(HDRS) can be set on object file targets directly, but there are rules that allow these variables to be set by referring to the original source file name, rather than to the derived object file name. ObjectCcFlags adds object-specific flags to the $(CCFLAGS) variable, ObjectC++Flags adds object-specific flags to the $(C++FLAGS) variable, and ObjectHdrs add object-specific directories to the $(HDRS) variable. For example:<PRE> #In Jamrules: if $(NT) { CCFLAGS_X = /DXVERSION ; HDRS_X = \\\\SPARKY\\X11\\INCLUDE\\X11 ; } #In Jamfile: Main xviewer : viewer.c ; ObjectCcFlags viewer.c : $(CCFLAGS_X) ; ObjectHdrs viewer.c : $(HDRS_X) ;</PRE> The ObjectCcFlags and ObjectHdrs rules take .c files as targets, but actually set $(CCFLAGS) and $(HDRS) values on the .obj (or .o) files. As a result, the action that updates the target .obj file uses the target-specific values of $(CCFLAGS) and $(HDRS).<P><H4> SubDirCcFlags, SubDirC++Flags, SubDirHdrs Rules</H4> These rules set the values of $(SUBDIRCCFLAGS), $(SUBDIRC++FLAGS) and $(SUBDIRHDRS), which are used by the Cc, C++, and Object rules when setting the target-specific values for $(CCFLAGS), $(C++FLAGS) and $(HDRS). The SubDir rule clears these variables out, and thus they provide directory-specific values of $(CCFLAGS), $(C++FLAGS) and $(HDRS). For example:<PRE> #In Jamrules: GZHDRS = $(TOP)/src/gz/include ; GZFLAG = -DGZ ; #In Jamfile: SubDir TOP src gz utils ; SubDirHdrs $(GZHDRS) ; SubDirCcFlags $(GZFLAG) ; Library libgz : gizmo.c ; Main gizmo : main.c ; LinkLibraries gizmo : libgz ;</PRE> All .c files in this directory files will be compiled with $(GZFLAG) as well as the default $(CCFLAG), and the include paths used on the compile command will be $(GZHDRS) as well as the default $(HDRS).<H2>Header File Processing</H2> One of the functions of the Object rule is set up scanning of source files for (C style) header file inclusions. To do so, it sets the special variables $(HDRSCAN) and $(HDRRULE) as target-specific variables on the source file. The presence of these variables triggers a special mechanism in <B>jam</B> for scanning a file for header file inclusions and invoking a rule with the results of the scan. The $(HDRSCAN) variable is set to an egrep(1) pattern that matches "#include" statements in C source files, and the $(HDRRULE) variable is set to the name of the rule that gets invoked as such:<PRE> $(HDRRULE) source-file : included-files ;</PRE> This rule is supposed to set up the dependencies between the source file and the included files. The Object rule uses HdrRule to do the job. HdrRule itself expects another variable, $(HDRSEARCH), to be set to the list of directories where the included files can be found. Object does this as well, setting $(HDRSEARCH) to $(HDRS) and $(STDHDRS).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -