如何仅使用一个 makefile 在子目录中生成带有源代码的 Makefile
我在一堆子目录中都有源代码,例如:
src/widgets/apple.cpp
src/widgets/knob.cpp
src/tests/blend.cpp
src/ui/flash.cpp
在项目的根目录中,我想使用以下规则生成单个 Makefile:
%.o: %.cpp
$(CC) -c $<
build/test.exe: build/widgets/apple.o build/widgets/knob.o build/tests/blend.o src/ui/flash.o
$(LD) build/widgets/apple.o .... build/ui/flash.o -o build/test.exe
当我尝试此操作时,它找不到 build/widgets/apple.o< 的规则/代码>。 我可以更改一些内容,以便在需要生成
build/widgets/apple.o
时使用 %.o: %.cpp
吗?
I have source in a bunch of subdirectories like:
src/widgets/apple.cpp
src/widgets/knob.cpp
src/tests/blend.cpp
src/ui/flash.cpp
In the root of the project I want to generate a single Makefile using a rule like:
%.o: %.cpp
$(CC) -c lt;
build/test.exe: build/widgets/apple.o build/widgets/knob.o build/tests/blend.o src/ui/flash.o
$(LD) build/widgets/apple.o .... build/ui/flash.o -o build/test.exe
When I try this it does not find a rule for build/widgets/apple.o
. Can I change something so that the %.o: %.cpp
is used when it needs to make build/widgets/apple.o
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
原因是您的规则
期望 .cpp 文件与您的建筑物的 .o 位于同一目录中。 由于您的情况下的 test.exe 取决于 build/widgets/apple.o (等),因此 make 期望 apple.cpp 为 build/widgets/apple.cpp。
您可以使用 VPATH 来解决此问题:
当尝试构建“build/widgets/apple.o”时,make 将在 VPATH 中搜索 apple.cpp。 请注意,构建规则必须使用特殊变量才能访问 make 找到的实际文件名:
其中“$<” 扩展到 make 位于第一个依赖项的路径。
另请注意,这将构建 build/widgets 中的所有 .o 文件。 如果您想在不同的目录中构建二进制文件,您可以执行类似的操作,
我建议您使用“
然后您可以有多个规则,如下所示:
The reason is that your rule
expects the .cpp file to reside in the same directory as the .o your building. Since test.exe in your case depends on build/widgets/apple.o (etc), make is expecting apple.cpp to be build/widgets/apple.cpp.
You can use VPATH to resolve this:
When attempting to build "build/widgets/apple.o", make will search for apple.cpp in VPATH. Note that the build rule has to use special variables in order to access the actual filename make finds:
Where "$<" expands to the path where make located the first dependency.
Also note that this will build all the .o files in build/widgets. If you want to build the binaries in different directories, you can do something like
I would recommend that you use "canned command sequences" in order to avoid repeating the actual compiler build rule:
You can then have multiple rules like this:
这可以解决问题:
这个 Makefile 假设您的包含文件位于源目录中。 它还检查构建目录是否存在,如果不存在则创建它们。
最后一行是最重要的。 它使用函数
make-goal
为每个构建创建隐式规则,并且没有必要一一编写它们。您还可以添加自动依赖项生成,使用特罗米的方式
This does the trick:
This Makefile assumes you have your include files in the source directories. Also it checks if the build directories exist, and creates them if they do not exist.
The last line is the most important. It creates the implicit rules for each build using the function
make-goal
, and it is not necessary write them one by oneYou can also add automatic dependency generation, using Tromey's way
事情是
$@
将包含源文件的整个(相对)路径,该路径又用于构造对象名称(及其相对路径)我们使用:
这将创建一个名为 的对象目录在
$(OBJDIR_1)
中指定以及根据源中子目录的子目录。
例如(假设 objs 作为顶级对象目录),在 Makefile 中:
会产生以下对象目录:
Thing is
$@
will include the entire (relative) path to the source file which is in turn used to construct the object name (and thus its relative path)We use:
This creates an object directory with name specified in
$(OBJDIR_1)
and subdirectories according to subdirectories in source.
For example (assume objs as toplevel object directory), in Makefile:
results in following object directory:
这是另一个技巧。
在主“Makefile”中,为每个源目录定义 SRCDIR,并为 SRCDIR 的每个值包含“makef.mk”。 在每个源目录中放置文件“files.mk”,其中包含源文件列表以及其中一些文件的编译选项。 在主“Makefile”中,可以定义编译选项并排除 SRCDIR 的每个值的文件。
Makefile:
makef.mk
./files.mk
./crc/files.mk
This is another trick.
In main 'Makefile' define SRCDIR for each source dir and include 'makef.mk' for each value of SRCDIR. In each source dir put file 'files.mk' with list of source files and compile options for some of them. In main 'Makefile' one can define compile options and exclude files for each value of SRCDIR.
Makefile:
makef.mk
./files.mk
./crc/files.mk
这是我的解决方案,灵感来自 Beta 的答案。 它比其他建议的解决方案更简单
我有一个包含多个 C 文件的项目,存储在许多子目录中。
例如:
这是我的 Makefile(在
src/
目录中):这个示例适用于共享库,并且应该很容易适应任何编译过程。
Here is my solution, inspired from Beta's answer. It's simpler than the other proposed solutions
I have a project with several C files, stored in many subdirectories.
For example:
Here is my Makefile (in the
src/
directory):This example works fine for a shared library, and it should be very easy to adapt for any compilation process.
这将不需要痛苦的操作或多个命令序列来做到这一点:
JasperE 已经解释了为什么“%.o: %.cpp”不起作用; 此版本有一个带命令但无先决条件的模式规则 (%.o:),以及两个带先决条件但无命令的模式规则(build/%.o: 和 src/%.o:)。 (请注意,我放入 src/%.o 规则来处理 src/ui/flash.o,假设这不是 build/ui/flash.o 的拼写错误,所以如果您不需要它,您可以忽略它。)
build/test.exe 需要 build/widgets/apple.o,
build/widgets/apple.o 看起来像 build/%.o,所以它需要 src/%.cpp (在本例中为 src/widgets/apple.cpp),
build/widgets/apple.o 也看起来像 %.o,因此它执行 CC 命令并使用刚刚找到的先决条件(即 src/widgets/apple.cpp)来构建目标(build/widgets/apple.o)
This will do it without painful manipulation or multiple command sequences:
JasperE has explained why "%.o: %.cpp" won't work; this version has one pattern rule (%.o:) with commands and no prereqs, and two pattern rules (build/%.o: and src/%.o:) with prereqs and no commands. (Note that I put in the src/%.o rule to deal with src/ui/flash.o, assuming that wasn't a typo for build/ui/flash.o, so if you don't need it you can leave it out.)
build/test.exe needs build/widgets/apple.o,
build/widgets/apple.o looks like build/%.o, so it needs src/%.cpp (in this case src/widgets/apple.cpp),
build/widgets/apple.o also looks like %.o, so it executes the CC command and uses the prereqs it just found (namely src/widgets/apple.cpp) to build the target (build/widgets/apple.o)
通常,在每个子目录中创建一个Makefile,并在顶层Makefile中编写以调用子目录中的make。
此页面可能会有所帮助。
Usually, you create a Makefile in each subdirectory, and write in the top-level Makefile to call make in the subdirectories.
This page may help.