Reputation: 135
I want my Makefile to automate my testing for me. Basically I would have a bunch of test cases that my code runs on. I want the user to specify the number of test cases rather than that being hard coded in.
Basically I want something like this:
gcc main.c -o main
./main < test1.txt > output1.txt
./main < test2.txt > output2.txt
./main < test3.txt > output3.txt
./main < test4.txt > output4.txt
.
.
.
./main < test<n>.txt > output<n>.txt #for some value n
And turn it into something like this:
gcc main.c -o main
#of course this wouldn't be the syntax, but I just need the Makefile version of a loop, where all one has to do is change the n value
for(int i = 0; i < n+1; i++){
./main < test<i>.txt > output<i>.txt;
}
Thanks :)
Upvotes: 2
Views: 711
Reputation: 16361
Now updated to answer the question properly
What you might want to do (by the look of it) is have your makefile do various things for you:
# Target to build "main" its the first target and therefore the default
# call "make" to run
main:
@gcc main.c -o main
# Arbitrary max number of tests, can be overwritten by passing the variable in
NUM_TESTS=100
# Find all the tests, put them into an ordered list, then take the first
# 1 to NUM_TESTS of them. Finally substitute test* for output*
TEST_OUTPUTS=$(subst test,output,$(wordlist 1,$(NUM_TESTS),$(sort $(wildcard test*.txt))))
# Target to do your testing, call "make test NUM_TESTS=3" or "make test"
# to run all tests (up to 100).
.PHONY: test
test: $(TEST_OUTPUTS)
# Pattern rule to run each test - you don't call this directly
# Note: this has a dependency on main so if main is not built it
# will get built first
output%.txt: test%.txt main
@./main < $< > $@
# Target to clean up output files, call "make clean"
.PHONY: clean
clean:
rm -f main
rm -f $(TEST_OUTPUTS)
Use by:
make build
- build mainmake test
- run all tests that are found upto 100 (the max can be changed)make test NUM_TESTS=3
- run the first 3 tests (if they exist found)make test NUM_TESTS=3 -j6
- same as before but run 6 parallel jobs (or use -j
for as many parallel jobs as possible) - i.e. run the tests in parallelExplanation:
The pattern rule will generate a file output*.txt depending on the file test*.txt. But we want to call the rule outputX.txt
for this we generate a list of output files by searching for all output files (in variable TEST_OUTPUTS
) and then selecting the number of tests we want. We can do this by passing in a variable or if we don't pass in a variable then it does upto 100 tests (or whatever you set the maximum to be.
Note: I did not run this, so I would consider is to be pseudo code, but it should be pretty close)
Upvotes: 4