这是用例:
我有一个.cpp文件,其中实现了功能。举例来说,它具有以下特征:
[main.cpp]
#include <iostream>
int foo(int);
int foo(int a) {
return a * a;
}
int main() {
for (int i = 0; i < 5; i += 1) {
std::cout << foo(i) << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想foo对该文件中的功能执行一些自动化测试,但需要替换该main()功能以进行测试。最好是我想有一个这样的单独文件,我可以在该文件的顶部进行链接:
[mymain.cpp]
#include <iostream>
#include <cassert>
extern int foo(int);
int main() {
assert(foo(1) == 1);
assert(foo(2) == 4);
assert(foo(0) == 0);
assert(foo(-2) == 4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望(如果可能的话)避免更改原始.cpp文件以执行此操作-尽管如果无法这样做,这将是我的方法:
"(\s)main\s*\("==>"\1__oldmain\("我的目标环境是带有g ++的linux环境。
我讨厌回答我自己的问题,但这是我最终在 的手册页深处找到的解决方案g++,我已经对其进行了测试,并且可以达到我想要的效果...
g++具有-D允许您在编译目标文件时定义宏的标志。我知道你在想“呃宏”但听我说...你可以使用宏定义来有效地重命名一个符号。就我而言,我可以运行以下命令来生成我的学生代码的目标文件,而没有他们的主文件:g++ -D main=__students_main__ main.cpp -c -o main.nomain.o .
这将创建一个目标文件,其int main定义为int __students_main__. 现在,这并不一定是直接调用,因为它们可能已经定义主int main(void)或与各种组合argc和argv,但它可以让我有效地编出自己的作用。
最终编译如下:
g++ -c -D main=__students_main__ main.cpp -o main.nomain.o
g++ -c mymain.cpp -o mymain.o
g++ main.nomain.o mymain.o -o mymainstudentsfoo.out
Run Code Online (Sandbox Code Playgroud)
出于我的目的,我想创建一个 Makefile 来自动完成此操作(ish),我觉得这与本次讨论有关,因此我将发布我的想法:
HDIR=./ # Not relevant to question, but we have headers in a separate directory
CC=g++
CFLAGS=-I $(HDIR)
NOMAIN=-D main=__student_main__ # The main renaming magic
.SECONDARY: # I forget exactly what this does, I seem to remember it is a hack to prevent deletion of .o files
cpp = $(wildcard *.cpp)
obj = $(patsubst %.cpp,%.o,$(cpp))
objnomain = $(patsubst %.cpp,%.nomain.o,$(cpp))
all: $(obj) $(objnomain)
clean:
rm -f *.o *.out
%.nomain.o: %.cpp
$(CC) $(CFLAGS) $(NOMAIN) -c $^ -o $@
%.o: %.cpp
$(CC) $(CFLAGS) -c $^
Run Code Online (Sandbox Code Playgroud)