我编写了一些模板类,它们是我需要编译的其他几个类的依赖项。关于如何在 Makefile 中执行此操作,我有几个选项:
-
每个需要模板的类都会列出其模板要求。这样做的缺点是每次我想添加新类时都需要重新创建依赖关系树。
-
以某种方式使模板成为目标。要么编译它们,要么创建一些不编译任何内容的影子依赖树,而只是在其中一个模板被修改时强制重新编译。
欢迎任何建议。
I have some template classes I've written that are dependencies for several other classes I need to compile. I have a few options as to how I can do this in my Makefile:
-
Each class that requires a template lists its template requirements. This has the drawback of needing to recreate the dependency tree every time I want to add a new class.
-
Make the templates into target somehow. Either by compiling them, or by making some shadow dependency tree that does not compile anything, but simply forces a recompilation in the event of one of the templates becoming modified.
Any suggestions are welcome.
发布评论
评论(2)
正如尼尔·巴特沃斯(Neil Butterworth)在评论中提到的那样,用文件进行交易。假设您有一个
foo.cpp
和一个bar.h
。后者包含您的模板。前者可能会这样做,例如:虽然您的
Foo
类继承并因此依赖于您的Bar
模板类,但您也已经使用声明了文件依赖项#include 。
它与您在 Makefile 中指定的文件依赖项相同:
对于此规则,make 期望您指定的命令基于
foo.cpp
和 < code>bar.h 文件。如果您已经构建过一次foo.o
,并且这些依赖项没有更改,那么 make 知道它可以完全跳过该规则。两次指定文件依赖项似乎很乏味,但幸运的是,GCC 可以使用
-M
命令从源代码中的#include
自动生成 Makefile 中的依赖项 -线路参数。您可以在gcc(1)
联机帮助页中了解这一点。只需获取 GCC 的输出,将其保存在某个位置(通常是foo.d
),然后将其包含
到您的 Makefile 中。通过一些技巧,您可以在构建应用程序的同一个 Makefile 中自动生成
*.d
依赖项文件。As Neil Butterworth mentioned in a comment, make deals with files. Say you have a
foo.cpp
and abar.h
. The latter contains your template. And the former might do, for example:While your
Foo
class inherits and thus depends on yourBar
template class, you are also already declaring your file dependencies with your#include
s.It's those same file dependencies that you specify in your Makefile:
For this rule, make expects that the commands you specify create
foo.o
, based on thefoo.cpp
andbar.h
files. If you've already builtfoo.o
once, and those dependencies haven't changed, make knows it can skip the rule altogether.It may seem tedious to specify file dependencies twice, but luckily dependencies in your Makefile can be automatically generated from
#include
s in your source code by GCC using the-M
command-line parameter. You can read about this in thegcc(1)
manpage. Simply take GCC's output, save it somewhere, typicallyfoo.d
, andinclude
that in your Makefile.With some wizardry, you can automate the generation of
*.d
dependency files in the same Makefile that builds your application.在选项 2 中,您可以使用 g++ 编译模板实例化。例如,假设您有:
并且在代码中使用了、std::greater 的实例化。 > 到目标文件中:
my_class, std::greater ; >
。使用 g++,您可以编译 my_class然后,在靠近底部的
Makefile
中添加:如果任何目标依赖于, std::vector, std::greater; >。
my_class_long_long_vector_greater_instantiation.o
,以及模板的声明my_class
已更改(my_class.hpp
文件已更改),然后 GNU make 将重新编译my_class_long_long_vector_greater_instantiation.cpp
,从而重新实例化 <代码>my_class另请参阅:模板在哪里?
On option 2, you can compile a template instantiation using g++. For example, suppose you had:
and in your code you used
my_class<long, std::vector<long>, std::greater<long> >
. With g++ you can compile the instantiation ofmy_class<long, std::vector<long>, std::greater<long> >
into an object file:Then, in your
Makefile
near the bottom you add:If any target depends on
my_class_long_long_vector_greater_instantiation.o
, and the declaration of templatemy_class
has changed (themy_class.hpp
file was changed), then GNU make will re-compilemy_class_long_long_vector_greater_instantiation.cpp
, hence re-instantiatemy_class<long, std::vector<long>, std::greater<long> >
.See also: Where's the Template?