[英]C++ How would I combine two makefile object target rules (which are located in another folder) into one target/rule?
我的C ++程序包含三个文件:
我正在为此程序创建一个makefile。 对于我的任务,我需要一个目标('hello'),该目标将所有源文件编译为可执行文件。 另一个目标('obj')应该将所有'.cpp'文件编译为对象,并将它们链接到可执行文件中。
运行make时,我更喜欢将目标文件创建在名为“ bin”的单独文件夹中。 源文件将位于名为“ src”的文件夹中。 这些文件夹是同级文件,makefile在其父文件夹中。
我的makefile可以正常工作,但是我希望两个将两个目标'bin / main.o'和'bin / hellolib.o'合并为一个,以减少规则的数量,尤其是在以后处理更多源文件时。 我以为替换看起来像这样,但是似乎没有用。
它给了我错误:“ ***没有规则使目标'bin / main.o'被'obj'所需要。停止。
bin/%.o : src/%.cpp
$(CC) -c $< -o $@
工作文件:
CC = g++
SOURCES = ./src/main.cpp \
./src/hellolib.cpp
OBJECTS = ./bin/main.o \
./bin/hellolib.o
hello : $(SOURCES)
$(CC) -o $@ $^
obj : $(OBJECTS)
$(CC) -o $@ $^
bin/main.o : src/main.cpp
$(CC) -c $< -o $@
bin/hellolib.o : src/hellolib.cpp
$(CC) -c $< -o $@
clean:
@rm -rf hello obj bin/*.o
main.cpp:
#include "hellolib.h"
int main() {
Hello h("Name");
h.Print();
return 0;
}
hellolib.cpp
#include "hellolib.h"
#include <iostream>
Hello::Hello(std::string name) {
if (name.empty()) {
cout << "Name is not valid!";
return;
}
_name = name;
}
void Hello::Print() {
cout << "Hello " << _name << endl;
}
hellolib.h
#ifndef HELLO_LIB_H
#define HELLO_LIB_H
#include <string>
using namespace std;
class Hello {
std::string _name;
public:
Hello(std::string name);
void Print();
};
#endif
您需要更改:
OBJECTS = ./bin/main.o \
./bin/hellolib.o
至:
OBJECTS = bin/main.o \
bin/hellolib.o
(删除开头的“ ./
”)。 或者,或者将您的模式规则更改为包含./
“ ./
”:
./bin/%.o : src/%.cpp
$(CC) -c $< -o $@
使规则匹配使用文本匹配 。 它不是基于文件名的,因此“ ./././foo
”和“ foo
”不是同一回事。
我个人建议这样重写:
SOURCES = src/main.cpp \
src/hellolib.cpp
OBJECTS = $(patsubst src/%.cpp,bin/%.o,$(SOURCES))
因此您只需要将文件列表放在一个位置即可。
您可以制定一条规则来构建符合特定模式的规则,如下所示:
bin/%.o : src/%.cpp
$(CC) -c -o $@ $<
这将编译来自相应源src/%.cpp
任何bin/%.o
依赖项。
这也是编译C++
以使用CXX
而不是CC
(用于C
代码)的标准。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.