我有一些我编写的模板类,它们是我需要编译的其他几个类的依赖项。关于如何在Makefile中执行此操作,我有几个选项:
每个需要模板的类都会列出其模板要求。这样做的缺点是每次我想添加一个新类时都需要重新创建依赖树。
以某种方式将模板设为目标。通过编译它们,或者通过制作一些不编译任何东西的阴影依赖树,但只是在其中一个模板被修改时强制重新编译。
欢迎任何建议。
答案 0 :(得分:1)
在选项2上,您可以使用g ++编译模板实例化。例如,假设你有:
// my_class.hpp
template <typename T1, class Container, typename Compare>
class my_class {
// ...
};
在您的代码中使用了my_class<long, std::vector<long>, std::greater<long> >
。使用g ++,您可以将my_class<long, std::vector<long>, std::greater<long> >
的实例化编译到目标文件中:
// my_class_long_long_vector_greater_instantiation.cpp
#include "my_class.hpp"
template class my_class<long, std::vector<long>, std::greater<long> >;
然后,在靠近底部的Makefile
中添加:
my_class_long_long_vector_greater_instantiation.o: my_class.hpp
如果任何目标依赖于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<long, std::vector<long>, std::greater<long> >
。
答案 1 :(得分:1)
正如Neil Butterworth在评论中提到的那样,处理文件。假设您有foo.cpp
和bar.h
。后者包含您的模板。而前者可能会这样做,例如:
#include "bar.h"
class Foo : public Bar<Widget> { [...] };
虽然您的Foo
类继承并因此取决于您的Bar
模板类,但您已经使用#include
声明了文件依赖性。
这是您在Makefile中指定的相同文件依赖项:
foo.o: foo.cpp bar.h
g++ -I. -o foo.o foo.cpp
对于此规则,make期望您指定的命令根据foo.o
和foo.cpp
文件创建bar.h
。如果您已经构建了foo.o
一次,并且这些依赖项没有更改,那么make知道它可以完全跳过该规则。
两次指定文件依赖关系似乎很乏味,但幸运的是,Makefile中的依赖关系可以通过GCC使用#include
命令行参数从源代码中的-M
自动生成。您可以在gcc(1)
联机帮助页中了解相关信息。只需获取GCC的输出,将其保存在Makefile中的某个位置,通常为foo.d
和include
。
通过一些魔法,您可以在构建应用程序的同一个Makefile中自动生成*.d
依赖项文件。