我正在编写第一个第二个makefile,因为在实际启动C ++项目之前我需要了解它们。这是我要链接的文件:
/storage/emulated/0/cpptest/test.h
#ifndef TEST_H_DEF
#define TEST_H_DEF
class Test {
private:
int value;
public:
Test(int);
operator int();
Test operator + (Test);
};
#endif
/storage/emulated/0/cpptest/test.cpp
#include "test.h"
Test::Test(int new_value):
value(new_value) {}
Test::operator int() {
return value;
}
Test Test::operator + (Test other) {
return Test(value + int(other));
}
/storage/emulated/0/cpptest/main.cpp
#include <iostream>
#include "test.h"
int main() {
Test o1(12);
Test o2(18);
std::cout << int(o1) << '\n';
std::cout << int(o2) << '\n';
std::cout << int(o1 + o2) << std::endl;
}
这是我对(可维护的)makefile的尝试:
CC = g++
default: test
#I'm actually using four spaces here on SO
test: main.o test.o
$(CC) -o test main.o test.o
#my issue starts here: what does main.o depends on? My guess is main.cpp only (which is really /storage/emulated...main.cpp)
main.o: main.cpp
$(CC) -o main.o /storage/emulated/0/cpptest/main.cpp
#same with test.o
test.o: test.cpp
$(CC) -o test.o /storage/emulated/0/cpptest/test.cpp
然后呢?我现在好吗?如何在不知道的情况下处理test.h的问题?
在编写文件时,我是否也正确使用了.h和.cpp文件?
答案 0 :(得分:5)
gcc可以为您生成依赖项。因此,不要手动输入源文件的所有依赖项(这将不可避免地是错误的或不完整的),而是使用编译器:
default: test
.PHONY : default
compiler := g++
objects := main.o test.o
depends := $(objects:.o=.d)
# include the depends rules if they exist
-include $(depends)
# test depends on all the objects, compiled together
test : $(objects)
$(compiler) -o $@ $^
# each object depends on its source file
# the recipe here will both compile the source file and generate its dependencies
%.o : %.cpp
$(compiler) -o $@ -c $< -MP -MMD -MF $(@:.o=.d)
这将为您生成名为main.d
和test.d
的文件,其中包含的makefile规则具有main.cpp
和test.cpp
的实际依赖关系。
每当您对您的文件的有效性产生怀疑时,运行make -pn
并检查在那里打印的所有内容总是有帮助的。这将有助于确保您的依赖项完全符合它们的应用程序。
例如,第一次编译时,*.d
文件不存在,因此include $(depends)
命令将失败(由于-include
而无声),以及此makefile创建一个看起来像的依赖图:
您应该阅读此内容,因为如果任何节点的子节点已经更新,任何节点都需要重新运行其配方(我填写了default
蓝色因为它是虚假的规则。)。因此,只要main.o
更新,就需要重新编译main.cpp
。请注意,test.h
没有依赖关系!这似乎是一个错误,但无论如何我们必须重新编译一切,所以我们不会错过。在我们第一次编译之后,我们已经生成了*.d
文件然后我们将它们带入了我们的include,新的依赖图看起来像:
这正是我们想要的。
答案 1 :(得分:1)
test.h的依赖关系适用于test.cpp和main cpp:
CC = g++
default: test
test: main.o test.o
$(CC) -o test main.o test.o
main.o: main.cpp test.h
$(CC) -o main.o /storage/emulated/0/cpptest/main.cpp
test.o: test.cpp test.h
$(CC) -o test.o /storage/emulated/0/cpptest/test.cpp
我们的想法是,如果test.h
内的某些内容发生变化,test.o
和main.o
都必须重新制作。