简体   繁体   English

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

[英]Object files generation and best practices for linking using makefiles - C++

Background 背景

I am just getting started with C++ programming on LINUX. 我刚刚开始在LINUX上进行C ++编程。 In my last question, I asked about best practices of using makefiles for a big application. 在最后一个问题中,我询问了在大型应用程序中使用makefile的最佳实践。 "SO" users suggested to read Miller's paper on recursive makefiles and avoid makefile recursion (I was using recursive makefiles). “ SO”用户建议阅读Miller关于递归makefile的论文,并避免makefile递归(我正在使用递归makefile)。

I have followed miller and created a makefile like the below. 我遵循了Miller的要求,并创建了一个如下所示的makefile。 Following is the project structure 以下是项目结构

root
...makefile
...main.cpp
...foo
......foo.cpp
......foo.h
......module.mk

My makefile looks like the below 我的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

Here is the module.mk in foo directory. 这是foo目录中的module.mk

SRC += foo/foo.cpp

When I run make -n , I get the following output. 运行make -n时 ,得到以下输出。

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? 我应该在哪里创建对象(.o)文件? 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? 我的意思是哪个是生成foo.o的最佳位置? Is it in foo directory or the root (My example generates in the root)? 是在foo目录中还是在根目录中(我的示例在根目录中生成)?
  • In the provided example, g++ -c foo/foo.cpp command generates the .o file in the root directory. 在提供的示例中, g ++ -c foo / foo.cpp命令在根目录中生成.o文件。 But when linking( g++ -o fooexe foo/foo.o main.o ) it is looking for the foo/foo.o . 但连接时( 克++ -o fooexe富/ foo.o的main.o),此它正在寻找的富/ foo.o的 How can I correct this? 我该如何纠正?

Any help would be great 任何帮助都会很棒

  • Where should I create the object(.o) files? 我应该在哪里创建对象(.o)文件? 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? 我的意思是哪个是生成foo.o的最佳位置? Is it in foo directory or the root (My example generates in the root)? 是在foo目录中还是在根目录中(我的示例在根目录中生成)?

I find it easier for investigating failed builds to localize object files in a separate directory under the module level directory. 我发现调查失败的构建将目标文件本地化在模块级别目录下的单独目录中更加容易。

foo
    |_ build
    |_ src 

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). 所有组件都进入主构建目录,该目录可在其中运行主应用程序(具有所有相关库等)。

  • In the provided example, g++ -c foo/foo.cpp command generates the .o file in the root directory. 在提供的示例中,g ++ -c foo / foo.cpp命令在根目录中生成.o文件。 But when linking(g++ -o fooexe foo/foo.o main.o) it is looking for the foo/foo.o. 但是当链接(g ++ -o fooexe foo / foo.o main.o)时,它正在寻找foo / foo.o。 How can I correct this? 我该如何纠正?

Use: 采用:

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

The best thing you can do for yourself is to use something better than Make. 您自己可以做的最好的事情就是使用比Make更好的东西。 SCons is my tool of choice on POSIX systems. SCons是我在POSIX系统上选择的工具。 Boost also has a build tool that is very flexible, but I had a hard time wrapping my head around it. Boost也有一个非常灵活的构建工具,但是我很难把它包起来。

Oh, and if you want to use make, go ahead and build recursive makefiles. 哦,如果要使用make,请继续构建递归的makefile。 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. 在过去三年中,我从事了一个使用大量递归Makefile的大型项目,并且效果很好。

+1 for SCons. SCons +1。
I am using SCons , too. 我也在使用SCons 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): 在我的SCons构建中,对象位于源的并行目录中(以启用多个构建,例如32位和64位的组合,发布和调试):

src
.build
  linux
    i686
      debug
      release
    x86_64
      debug
      release

With regards to object and other generated interim files, I put these in a directory completely separate from the sources (Ie 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. 在项目或makefile中进行设置可能会稍微麻烦一些,但是它可以节省打包源代码的时间,并且更容易进行干净的备份和版本控制。

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

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

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