编译模板和/或使用模板编译的正确程序是什么?

时间:2010-07-03 17:47:09

标签: c++ templates makefile

我有一些我编写的模板类,它们是我需要编译的其他几个类的依赖项。关于如何在Makefile中执行此操作,我有几个选项:

  1. 每个需要模板的类都会列出其模板要求。这样做的缺点是每次我想添加一个新类时都需要重新创建依赖树。

  2. 以某种方式将模板设为目标。通过编译它们,或者通过制作一些不编译任何东西的阴影依赖树,但只是在其中一个模板被修改时强制重新编译。

  3. 欢迎任何建议。

2 个答案:

答案 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> >

另请参阅:Where's the Template?

答案 1 :(得分:1)

正如Neil Butterworth在评论中提到的那样,处理文件。假设您有foo.cppbar.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.ofoo.cpp文件创建bar.h。如果您已经构建了foo.o一次,并且这些依赖项没有更改,那么make知道它可以完全跳过该规则。

两次指定文件依赖关系似乎很乏味,但幸运的是,Makefile中的依赖关系可以通过GCC使用#include命令行参数从源代码中的-M自动生成。您可以在gcc(1)联机帮助页中了解相关信息。只需获取GCC的输出,将其保存在Makefile中的某个位置,通常为foo.dinclude

通过一些魔法,您可以在构建应用程序的同一个Makefile中自动生成*.d依赖项文件。