我想改用 Jam 作为我的构建系统。目前,我有一个 src、include 和 build 目录,我想知道如何让 Jam 将目标文件放入 build 目录并在 include 目录中搜索包含文件。
1 回答
使用 Jam 对您有好处!我想你会发现它比 makefile 容易得多,一旦你克服了它的一些奇怪之处。
您要问的是我经常使用的设置。在顶层,我有三个目录:src、inc 和 build。还有一个名为 Jamfile 的文件:
# top-level Jamfile
SubDir . ;
SubInclude src ;
SubInclude build ;
SubDir 行确定了该文件在目录结构中的位置,并且似乎是 Jam 工作所必需的。(我认为 Jam 可能被设计为不需要它,但它确实存在,就这样吧。) SubInclude 行告诉 Jam 包含两个子目录。没有包含 inc 子目录,因为那里没有需要直接编译的内容;它的所有内容都将包含在其他文件中。
在 inc 中,我有一个名为 header.h 的头文件:
/* header.h */
#define MESSAGE "Hello world!"
在 src 中,我有主程序 main.c 的源代码:
/* main.c */
#include "header.h"
#include <stdio.h>
int main(int argc, char** argv)
{
printf("%s\n", MESSAGE);
return 0;
}
src 中还有另一个 Jamfile,其中包含以下内容:
# src/Jamfile
SubDir .. src ;
HDRS += ../inc ;
Library helloworld : main.c ;
SubDir 行在目录结构中定位 Jamfile。HDRS 行告诉 Jam 在哪里可以找到额外的标头(它会在时机成熟时将其传递给编译器)。请注意使用 += 运算符,它附加到现有变量。Library 行告诉 Jam 从 main.c 构建一个库(是的,带有 main() 的库有点奇怪,但在像这样的小项目中可以)。
在 build 中只有一个 Jamfile:
# build/Jamfile
SubDir .. build ;
Main helloworld ;
LinkLibraries helloworld : helloworld ;
SubInclude .. src ;
SubDir 行在目录结构中定位 Jamfile。Main 行告诉 Jam 构建一个名为 helloworld 的可执行文件。请注意,它没有源文件依赖项。如果是这样,它看起来像Main hello world : foo.c ;
。LinkLibraries 行告诉 Jam 将 helloworld 可执行文件与一个库(也称为 helloworld)链接。在这种情况下,可执行文件和库具有相同的名称是可以的,但在实际程序中,您可能希望给它们不同的(更好的)名称。SubInclude 行告诉 Jam 在 src 目录中查找更多要构建的代码。这就是解决可执行文件和库之间的依赖关系的方式。这条线排在最后很重要。
现在,如果您导航到 build 目录并执行 jam 命令,Jam 将在 src 中构建一个 helloworld.a 文件,并将其链接到 build 中的 helloworld 可执行文件中。
因为 src 中的所有代码都被编译到一个库中,所以没有剩下的 .o 文件。毕竟,它们都存储在 .a 文件中,这是一个存档。如果您在构建中有其他源文件(如上面提到的假设 foo.c),那么编译后您将在构建目录中留下 .o 文件。
祝你好运。我从 Perforce网站和实验中学到了关于 Jam 的大部分知识。Jam 的主要 Perforce 页面在这里。