Here’s the use case:
I have a .cpp file which has functions implemented in it. For sake of example say it has the following:
[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;
}
I want to perform some amount of automated testing on the function foo in this file but would need to replace out the main() function to do my testing. Preferably I’d like to have a separate file like this that I could link in over top of that one:
[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;
}
I’d like (if at all possible) to avoid changing the original .cpp file in order to do this — though this would be my approach if this is not possible:
- do a replace for
"(\s)main\s*\("==>"\1__oldmain\(" - compile as usual.
The environment I am targeting is a linux environment with g++.
I hate answering my own question, but here’s a solution I ended up finding deep in the man page of
g++, I’ve tested it and it works to what I would want it to…g++has the-Dflag which allows you to define macros when compiling object files. I know you are thinking “ugh macros” but hear me out… You can use the macro definition to effectively rename a symbol. In my case, I can run the following command to generate an object file of my students code without their main file:g++ -D main=__students_main__ main.cpp -c -o main.nomain.o.This creates an object file with their
int maindefined asint __students_main__. Now this isn’t necessarily callable directly as they could have defined main asint main(void)or with the various combinations ofargcandargv, but it allows me to effectively compile out their function.The final compile looks like this:
For my purposes, I wanted to create a Makefile that would accomplish this automagically (ish) and I feel that is relevant to this discussion so I’ll post what I came up with: