目标文件生成和使用 makefile 进行链接的最佳实践 - C++
背景
我刚刚开始在 LINUX 上进行 C++ 编程。 在我的上一个问题中,我询问了在大型应用程序中使用 makefile 的最佳实践。 “SO”用户建议阅读 Miller 关于递归 makefile 的论文并避免 makefile 递归(我正在使用递归 makefile)。
我跟随 miller 创建了一个如下所示的 makefile。 以下是项目结构
root
...makefile
...main.cpp
...foo
......foo.cpp
......foo.h
......module.mk
我的 makefile 如下所示
#Main makefile which does the build
CFLAGS =
CC = g++
PROG = fooexe
#each module will append the source files to here
SRC :=
#including the description
include foo/module.mk
OBJ := $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC))) main.o
#linking the program
fooexe: $(OBJ)
$(CC) -o $(PROG) $(OBJ)
%.o:
$(CC) -c $(SRC)
main.o:
$(CC) -c main.cpp
depend:
makedepend -- $(CFLAGS) -- $(SRC)
.PHONY:clean
clean:
rm -f *.o
这是 foo 目录中的 module.mk 。
SRC += foo/foo.cpp
当我运行 make -n 时,我得到以下输出。
g++ -c foo/foo.cpp
g++ -c main.cpp
g++ -o fooexe foo/foo.o main.o
问题
- 我应该在哪里创建对象(.o) 文件? 单个目录中的所有目标文件还是其自己的模块目录中的每个目标文件? 我的意思是哪个是生成 foo.o 的最佳位置? 它是在 foo 目录还是根目录中(我的示例在根目录中生成)?
- 在提供的示例中,g++ -c foo/foo.cpp 命令在根目录中生成 .o 文件。 但是当链接(g++ -o fooexe foo/foo.o main.o)时,它正在寻找foo/foo.o。 我该如何纠正这个问题?
任何帮助都会很棒
Background
I am just getting started with C++ programming on LINUX. In my last question, I asked about best practices of using makefiles for a big application. "SO" users suggested to read Miller's paper on recursive makefiles and avoid makefile recursion (I was using recursive makefiles).
I have followed miller and created a makefile like the below. Following is the project structure
root
...makefile
...main.cpp
...foo
......foo.cpp
......foo.h
......module.mk
My makefile looks like the below
#Main makefile which does the build
CFLAGS =
CC = g++
PROG = fooexe
#each module will append the source files to here
SRC :=
#including the description
include foo/module.mk
OBJ := $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC))) main.o
#linking the program
fooexe: $(OBJ)
$(CC) -o $(PROG) $(OBJ)
%.o:
$(CC) -c $(SRC)
main.o:
$(CC) -c main.cpp
depend:
makedepend -- $(CFLAGS) -- $(SRC)
.PHONY:clean
clean:
rm -f *.o
Here is the module.mk in foo directory.
SRC += foo/foo.cpp
When I run make -n, I get the following output.
g++ -c foo/foo.cpp
g++ -c main.cpp
g++ -o fooexe foo/foo.o main.o
Questions
- Where should I create the object(.o) files? All object files in a single directory or each object files in it's own modules directory? I mean which is the best place to generate foo.o? Is it in foo directory or the root (My example generates in the root)?
- In the provided example, g++ -c foo/foo.cpp command generates the .o file in the root directory. But when linking(g++ -o fooexe foo/foo.o main.o) it is looking for the foo/foo.o. How can I correct this?
Any help would be great
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我发现将对象文件本地化到模块级目录下的单独目录中更容易调查失败的构建。
根据项目的大小,这些目标文件被分组以形成更高级别的组件等等。 所有组件都进入主构建目录,主应用程序可以在该目录中运行(具有所有依赖库等)。
使用:
I find it easier for investigating failed builds to localize object files in a separate directory under the module level directory.
Depending on the size of the project, these object files are grouped to form a component at a higher level and so on. All components go to a main build directory which is where the main application can be run from (has all dependent libraries etc).
Use:
SCons +1。
我也在使用 SCons。 它会为您扫描依赖项,并且仅在源发生更改时才进行重建,因为它使用加密哈希和而不是时间戳。
在我的 SCons 中,构建对象位于与源并行的目录中(以启用多个构建,例如 32 位和 64 位的组合、发布和调试):
+1 for SCons.
I am using SCons, too. It scans the dependencies for you and it only rebuilds when source has changed as it uses cryptographic hash sums instead of timestamps.
In my SCons build the objects live in parallel directories to the source (to enable multiple builds like combinations of 32bit and 64bit, release and debug):
对于对象和其他生成的临时文件,我将它们放在与源完全分开的目录中(即,在排除备份和修订控制的目录下)。 在项目或 makefile 中进行设置可能会稍微麻烦一些,但它可以节省打包源代码的时间,并且更容易进行干净的备份和修订控制。
我为目标文件创建一个与源的子目录结构相匹配的子目录结构。 通常,我的每个库和程序都有一个单独的子目录。
此外,我还使用多个编译器(和版本)和多个操作系统,因此我将在每个编译器(具有较新版本的标准库和供应商库)的目录下重现目标文件目录结构,以防止目标文件不匹配包含的头文件版本。
With regards to object and other generated interim files, I put these in a directory completely separate from the sources (I.e. under a directory that is excluded from backup and revision control). It may be slightly more bother to setup in projects or makefiles, but it saves time packaging up sources, and it is easier to have clean backups and revision control.
I create a subdirectory structure for the object files that matches the subdirectory structure for sources. Typically I have a separate subdirectory for each of my libraries and programs.
Additionally I also use multiple compilers (and versions) and multiple operating systems, so I will reproduce the object file directory structure under a directory for each of these compilers (which have newer versions of the standard and vendor libraries) to prevent object files with mismatched included header file versions.
你能为自己做的最好的事情就是使用比 Make 更好的东西。 SCons 是我在 POSIX 系统上选择的工具。 Boost 还有一个非常灵活的构建工具,但我很难理解它。
哦,如果您想使用 make,请继续构建递归 makefile。 这确实没什么大不了的。 在过去的三年里,我使用了大量的递归 makefile 参与了一个巨大的项目,而且效果很好。
The best thing you can do for yourself is to use something better than Make. SCons is my tool of choice on POSIX systems. Boost also has a build tool that is very flexible, but I had a hard time wrapping my head around it.
Oh, and if you want to use make, go ahead and build recursive makefiles. It really isn't that big a deal. I worked on a gigantic project using tons of recursive makefiles over the last three years, and it worked just fine.