So I got the original ex29 — where Zed shows us each individual step of the compilation process — working. I’m trying to tackle the extra credit now, where we use the skeleton directory. I copied libex29.c
and ex29.c
in the directories specified and changed the TARGET
variable to build/libex29.a
. Then I ran make
and got a bunch of linking errors. Looking in the Makefile, I found that the LIBS
variable is never used, which explains those. Where do I put it so that the linker does its job? I tried putting it in various positions among the CFLAGS
, to no success.
Hmm for the linker I think I got a few of those variables wrong as they changed over time:
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
That should be base environment variables, then:
http://man7.org/linux/man-pages/man8/ld.so.8.html
Controls others, but this is in a Makefile so:
https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
I believe you want either LDLIBS, LDFLAGS. Let me know if that’s what you’re looking for.
Ah, LDLIBS
did the trick. LDFLAGS
, however, failed with the same linker errors as LIBS
. Now it just fails because I have to fill out the tests
Still, I see that LDLIBS
is never explicitly used. Is that just one of those implied dependencies you mentioned in the Ex2 video?
Yes, Make tries to figure a lot of this out for you automatically, and I remember that you set LIBS but I think either I remembered wrong or it changed. Probably a combination of them.
I have a basic understanding of *nix shell scripting, but how does this line of runtests.sh
work:
if $VALGRIND ./$i 2>> tests/tests.log
I know that
./$i 2>> tests/tests.log
will run each executable in tests/
whose filename ends in _tests
and redirect error messages to the log file, but how does this line constitute a valid test for the if
statement?
Valgrind “returns” an exit code which you can test for truth or falsity.
@florian is close, but it’s doing one more thing. If you have the VALGRIND variable set, then $VALGRIND gets replaced by the executable for valgrind, otherwise it’s empty. The if will then fail for a valgrind fail, or a test fail, and only run valgrind if you set it.
Now, the part I’m not clear on is whether this is parsed as:
if $VALGRIND
then
./$i 2>> tests/tests.log
fi
Or, I think it’s actually this (which is why it works):
if $VALGRIND ./$i
then
# empty
fi 2>> tests/tests.log
I wrote that so long ago I actually don’t remember, but I’m pretty sure it’s #2.