Makefile依赖关系,应该是什么依赖关系? [英] Makefile Dependencies, What Should Be a Dependency?

查看:94
本文介绍了Makefile依赖关系,应该是什么依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于Makefile依赖项的概念性问题,这是因为我在网上看到与此相关的不一致之处.

假设我有以下文件:

  main.cpp使用->my_math.cpp和my_strings.cppmy_math.cpp使用->my_math.hmy_strings.cpp使用->my_strings.h 

如果我有一个makefile,一般费用为:

 程序:$(all_objs)g ++ $(all_objs)-o程序main.o:..........my_math.o:..........my_strings.o:.......... 

我不知道每个依赖项应该包含什么内容.就像math.o #includes my_math.h和my_strings.h一样,这是否意味着如果我更改my_math.h,main.cpp需要重新编译吗?但为什么?它像图书馆一样使用它,对不对?不需要重新编译main.cpp还是它?

同样,main.o的结果应为:

  1)main.o:main.cppgcc -c main.cpp2) main.o: main.cpp my_strings.cpp my_strings.h my_math.cpp my_math.hgcc -c main.cpp3)main.o:main.cpp my_strings.cpp my_strings.h my_math.cpp my_math.hgcc -c main.cpp my_strings.cpp my_math.cpp 

我对依赖项以及链接的工作方式有些迷茫.

任何帮助将不胜感激!谢谢!

解决方案

依赖项是需要更改源代码的所有内容.这不仅包括您的 #include -d标头,而且还包括间接包含的系统标头,甚至(原则上)包括编译器和构建链本身(在升级时)C ++编译器,则应重新编译所有软件).如果您的某些C ++代码是从某些来源生成的(例如通过 GNU野牛之类的工具生成的,或Qt moc 或您自己的脚本),无论是来源还是生成工具是依赖项.另请参阅包装管理器.

实际上, GCC 编译器能够输出大多数 make 依赖项,尤其是 -M 和相关的处理器选项.另请阅读自动依赖项生成.另请参见.

(实际上,通常,您不会在 Makefile 中编写对编译器本身的显式依赖;但是,当出现以下情况时,请不要忘记进行 clean 编译器已升级)

除非您的 main.cpp 包括 my_strings.cpp (这不是常规的做法,而且味道很差),否则您的 make 规则将获胜从 my_strings.cpp main.o 没有依赖性.但是可能您的 main.cpp #include -ing(直接或间接) my_strings.h ,所以 main.o 应该不仅取决于 main.cpp ,而且还取决于 my_strings.h

根据经验,目标文件 my_strings.o 取决于源文件 my_strings.cpp 和所有头文件直接或间接在其中 #include -d.您的主要 program 可执行文件取决于其所有目标文件以及您链接到其中的库. g ++ 的程序参数顺序很重要.

它像图书馆一样使用它,对不对?

根据显示的内容,您没有任何图书馆(但是您可能使用标准的C ++库,也许还使用其他一些系统库).在Linux上,这些文件是 lib * .a 文件(静态库)或 lib * .so 文件(共享库).库是目标代码(有时是其他资源)的有组织的聚集.

我对依赖项以及链接的工作方式有些迷茫.

了解源代码文件与重定位信息)和可执行文件(在Linux中,对象文件,可执行文件和共享库都使用 ELF 格式).另请参阅编译器构建自动化(您正在使用 make ).>

阅读程序库的方法以及有关链接(& 名称修改),特别是Levine在链接器&装载器.

另请参见&&(有关用于C ++程序的 Makefile 的示例).

顺便说一句,编译C ++代码时应使用 g ++ (而不是 gcc ).存在重大差异(即使 gcc 有时能够编译C ++或Fortran代码,您也大多会使用 gcc 来编译C代码).并且(假设您专门使用GNU make),您的 Makefile 应该提到 $(CXX)(不是 g ++ ).您需要了解 make 的内置规则(只需运行一次 make -p 即可获取它们),然后最好利用它们(例如,使用 $(COMPILE.cc) $(COMPILE.cpp)等...).您当然应该将 -Wall -Wextra (以获取所有警告,甚至更多)和 -g (以获取调试信息)传递给 g ++ .实际上,您应该在 Makefile 中设置 CXXFLAGS 变量.

花点时间仔细阅读 GNU make文档,然后调用GCC .

查看现有自由软件项目的 Makefile -s.由于各种原因,某些项目正在使用 autoconf cmake 之类的工具生成 Makefile -s.但是大多数简单的项目不需要这种通用性,并且您应该能够为C ++项目编写自己的 Makefile .当然,可以从现有代码中汲取灵感.

I have a conceptual question regarding makefile dependencies and this is because I see inconsistency online about this.

Let's say I have the following files:

main.cpp         uses->     my_math.cpp and my_strings.cpp
my_math.cpp      uses->     my_math.h
my_strings.cpp   uses->     my_strings.h

If I have a makefile, with the general outlay of:

program: $(all_objs)
     g++ $(all_objs) -o program
main.o: ...
     .......
my_math.o: ...
     .......
my_strings.o: ...
     .......

I don't know what should go into each dependency. Like, math.o #includes my_math.h and my_strings.h, does that mean that main.cpp needs to recompile if I change my_math.h? But why? It uses it like a library, right? It doesn't need to recompile main.cpp or does it?

As in, should the result for main.o be:

1) main.o: main.cpp
         gcc -c main.cpp

2) main.o: main.cpp my_strings.cpp my_strings.h my_math.cpp my_math.h
         gcc -c main.cpp

3) main.o: main.cpp my_strings.cpp my_strings.h my_math.cpp my_math.h
         gcc -c main.cpp my_strings.cpp my_math.cpp

I'm a bit lost on dependencies and how linking works.

Any help would be appreciated! Thank you!

解决方案

The dependencies are everything whose change requires recompiling the source code. That includes not only your #include-d headers, but also the indirectly included system headers, and even (in principle) the compiler and build chain itself (when you upgrade your C++ compiler, you should recompile all your software). If some of your C++ code is generated from some source (e.g. by tools like GNU bison or Qt moc, or by your own script), both the sources and the generating tools are dependencies. Read also about package managers.

Practically speaking, the GCC compiler is able to output most make dependencies, notably with -M and related processor options. Read also about auto dependencies generation. See also this.

(in practice, you generally don't code in your Makefile some explicit dependency on the compiler itself; but you should not forget to make clean when the compiler has been upgraded)

Unless your main.cpp is including my_strings.cpp (which is not conventional and is very bad taste), your make rule won't have a dependency from my_strings.cpp to main.o. But probably your main.cpp is #include-ing (directly or indirectly) my_strings.h so main.o should depend not only on main.cpp but also on my_strings.h

As a rule of thumb, your object file my_strings.o depends on the source file my_strings.cpp and all the header files which are directly or indirectly #include-d in it. Your main program executable depends on all its object files and the libraries you are linking into it. Order of program arguments to g++ matters a lot.

It uses it like a library, right?

From what you are showing, you don't have any own libraries (but you probably use the standard C++ library, and perhaps some other system libraries). On Linux these are lib*.a files (static libraries) or lib*.so files (shared libraries). A library is an organized agglomeration of object code -and sometimes other resources.

I'm a bit lost on dependencies and how linking works.

Understand the difference between source code files, object files (they contain relocation information) and executables (on Linux, object files and executable files and shared libraries are using the ELF format). Read also about the role of compilers, linkers (the g++ program can run both) & build automation (for which you are using make).

Read Program Library HowTo and much more about translation units and linkers (& name mangling), notably Levine's book on Linkers & loaders.

See also this & that & this (examples about Makefile for C++ programs).

BTW, you should use g++ (not gcc) when compiling C++ code. There are significant differences (even if gcc is sometimes able to compile C++ or Fortran code, you'll mostly use gcc to compile C code). And (assuming you use specifically GNU make) your Makefile should mention $(CXX) (not g++). You need to understand the builtin rules of make (run once make -p to get them) and you'll better take advantage of them (e.g. use $(COMPILE.cc) or $(COMPILE.cpp) etc...). You certainly should pass -Wall -Wextra (to get all warnings, and even more), and -g (to get debugging information) to g++. Practically speaking, you should set your CXXFLAGS variable in your Makefile.

Take time to carefully read GNU make documentation and Invoking GCC.

Look into the Makefile-s of existing free software projects. For various reasons, some projects are generating their Makefile-s with tools like autoconf or cmake. But most simple projects don't need that generality, and you should be able to write your own Makefile for your C++ projects. Of course, take inspiration from existing code.

这篇关于Makefile依赖关系,应该是什么依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆