繁体   English   中英

目标文件生成和使用Makefile链接的最佳实践-C ++

[英]Object files generation and best practices for linking using makefiles - 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文件。 但连接时( 克++ -o fooexe富/ foo.o的main.o),此它正在寻找的富/ foo.o的 我该如何纠正?

任何帮助都会很棒

  • 我应该在哪里创建对象(.o)文件? 单个目录中的所有目标文件还是它自己的模块目录中的每个目标文件? 我的意思是哪个是生成foo.o的最佳位置? 是在foo目录中还是在根目录中(我的示例在根目录中生成)?

我发现调查失败的构建将目标文件本地化在模块级别目录下的单独目录中更加容易。

foo
    |_ build
    |_ src 

根据项目的大小,这些目标文件被分组以形成更高级别的组件,依此类推。 所有组件都进入主构建目录,该目录可在其中运行主应用程序(具有所有相关库等)。

  • 在提供的示例中,g ++ -c foo / foo.cpp命令在根目录中生成.o文件。 但是当链接(g ++ -o fooexe foo / foo.o main.o)时,它正在寻找foo / foo.o。 我该如何纠正?

采用:

 g++ -o fooexe  foo.o main.o

您自己可以做的最好的事情就是使用比Make更好的东西。 SCons是我在POSIX系统上选择的工具。 Boost也有一个非常灵活的构建工具,但是我很难把它包起来。

哦,如果要使用make,请继续构建递归的makefile。 确实没什么大不了的。 在过去三年中,我从事了一个使用大量递归Makefile的大型项目,并且效果很好。

SCons +1。
我也在使用SCons 它会为您扫描依赖关系,并且仅在源发生更改时才重新构建,因为它使用加密哈希和而不是时间戳。

在我的SCons构建中,对象位于源的并行目录中(以启用多个构建,例如32位和64位的组合,发布和调试):

src
.build
  linux
    i686
      debug
      release
    x86_64
      debug
      release

关于对象文件和其他生成的临时文件,我将它们放在与源完全分开的目录中(即,位于备份和修订控制之外的目录下)。 在项目或makefile中进行设置可能会稍微麻烦一些,但是它可以节省打包源代码的时间,并且更容易进行干净的备份和版本控制。

我为对象文件创建一个与源文件的子目录结构匹配的子目录结构。 通常,每个库和程序都有一个单独的子目录。

此外,我还使用了多个编译器(和版本)和多个操作系统,因此我将为每个这些编译器(具有较新版本的标准库和供应商库)的目录下复制目标文件目录结构,以防止目标文件不匹配包含的头文件版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM