No code coverage with Mac OS X Lion and XCode 4 / llvm-g++-4.2 - macos

Other people have reported not being able to generate code coverage with XCode 4, but I find not only can I not do it from within XCode 4, I can't do it even with a simple toy program from the command line. I followed the examples given here and here, which led me to create this cov.c file:
#include <stdio.h>
int main (void) {
int i;
for (i = 1; i < 10; i++) {
if (i % 3 == 0)
printf("%d is divisible by 3\n", i);
if (i % 11 == 0)
printf("%d is divisible by 11\n", i);
}
return 0;
}
I then used the following commands in an attempt to generate code coverage:
g++ -c -g -O0 --coverage -o $PWD/obj/cov.o $PWD/cov.c
g++ -g -O0 --coverage -o $PWD/bin/cov $PWD/obj/*.o
$PWD/bin/cov
Alas, no cov.gcno file exists in the obj directory. In fact, the only files I have after this are:
cov.c
obj/cov.o
bin/cov
Furthermore, if I type nm bin/cov, I get the following:
0000000100001048 S _NXArgc
0000000100001050 S _NXArgv
0000000100001060 S ___progname
0000000100000000 A __mh_execute_header
0000000100001058 S _environ
U _exit
0000000100000e40 T _main
U _printf
0000000100001000 s _pvars
U dyld_stub_binder
0000000100000e00 T start
This suggests that libgcov.a was never linked in. If I replace
g++ -g -O0 --coverage -o $PWD/bin/cov $PWD/obj/*.o
with:
g++ -g -O0 --coverage -o $PWD/bin/cov -lgcov $PWD/obj/*.o
I get the exact same results.
More information:
g++ --version yields: "i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1
(Based on Apple Inc. build 5658) (LLVM build 2336.1.00)"
I've also tried using gcc (which is llvm-gcc).

I was able to figure out an answer to this question using help from this answer. Basically, I changed my coverage commands to use clang instead of g++ (because the example file was pure C, I went with clang instead of clang++, which I've verified works just fine with C++ files). From there, I was able to use lcov to generate output similar to what I'm used to seeing from Java/cobertura.

On Lion g++ is an alias for llvm-g++, as you have discovered. To invoke "real" gcc, use gcc-4.2 or g++-4.2:
g++-4.2 -g -O0 --coverage -o $PWD/bin/cov $PWD/obj/*.o

Related

Which gcc version introduced `-fstack-protector-strong`?

In my build script, I want to conditionally add -fstack-protector-strong to my CFLAGS if the gcc supports it (my project builds using multiple versions of gcc).
I want my build script (written in bash) to parse the output of gcc --version and automatically add this flag if the gcc supports it.
Which version of gcc is the earliest to include the -fstack-protector-strong flag?
I want my build script (written in bash) to parse the output of gcc --version and automatically add this flag if the gcc supports it.
Instead of doing that, just call gcc -fstack-protector-strong with a valid source file and see if it compiles. Such method works universally for any compile option, which will save you time for searching which version has which options. You may take inspiration from CMake check_c_compile_flag function.
Taking inspiration from #KamilCuk's answer but bashifying it:
add_supported_cc_flag() {
CC=$1
CFLAG_TO_CHECK=$2
C_FILE=/tmp/test.$$.c
O_FILE=${C_FILE/.c/.o}
rm -f ${C_FILE}
cat > ${C_FILE} <<EOF
int main() { return 0; }
EOF
if $CC ${CFLAG_TO_CHECK} -c ${C_FILE} -o ${O_FILE} >/dev/null 2>&1
then
echo ${CFLAG_TO_CHECK}
fi
rm -f ${C_FILE} ${O_FILE}
}
CFLAGS="${CFLAGS} $(add_supported_cc_flag gcc -fstack-protector-strong)"
It appears that -fstack-protector-strong was first available in gcc 4.9.0.
The option doesn't show up in https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Optimize-Options.html (4.8.5 was the last 4.8.x gcc version), but the option does show up in https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Optimize-Options.html.
Note that -fstack-protector-all and -fstack-protector are available prior to gcc 4.9.0.

Why can't I rename a shared library after it's been built?

Here's a simple example:
lib.c:
#include <stdio.h>
void hello_world(void) {
puts("Hello, world!");
}
program.c:
void hello_world(void);
int main() {
hello_world();
return 0;
}
If I compile the library normally and link it, everything works fine:
$ cc lib.c -fPIC -shared -o libmylib.dylib
$ cc program.c -L. -lmylib
$ ./a.out
Hello, world!
But if I rename the library after building it (but before building the program), it doesn't work:
$ cc lib.c -fPIC -shared -o totally_different_name.dylib
$ mv totally_different_name.dylib libmylib.dylib
$ cc program.c -L. -lmylib
$ ./a.out
dyld: Library not loaded: totally_different_name.dylib
Referenced from: /private/tmp/./a.out
Reason: image not found
[1] 13229 abort ./a.out
Why is this the case? Why is dyld looking for the original library name?
This works okay on Linux, but when I try on macOS it completely fails (I don't know if it's a macOS vs Linux thing, or a clang vs gcc thing, since I'm using clang on macOS and gcc on Linux).
If it's relevant, cc --version is Apple LLVM version 8.0.0 (clang-800.0.42.1) x86_64-apple-darwin16.4.0.
Thanks to Florian Zwoch's comment, I was able to find a way to fix this. Run this command after renaming the dylib:
install_name_tool -id libmylib.dylib libmylib.dylib
That command changes the internal ID of the dylib. The command syntax is install_name_tool -id <new-id> <dylib-path>.
Originally, the dylib has the ID of totally_different_name.dylib. Renaming the file doesn't change the ID it has stored internally, and that has to be updated separately with install_name_tool.

Can you pass your code directly into gcc? For example: gcc -? 'int main(){return 0;}'

Can you pass your code directly into gcc? If so what is the command line option for it?
For example:
g++ -? 'int main(){return 0;}'
I need to know because I am using a system command and I rather not make files:
system("g++ -C "+code_string+" -o run.out");
Basile Starynkevitch solution worked, however I am getting compile errors when I use newlines:
echo '#include\nint main(){printf("Hello World"); return 0;}' | g++ -x c++ -Wall -o myprog /dev/stdin
Edit: fixed it
echo -e '#include\nint main(){printf("Hello World"); return 0;}' | g++ -x c++ -Wall -o myprog /dev/stdin
You could ask GCC to read from stdin. Read the Invoking GCC chapter of its documentation. Use its -x option with /dev/stdinor with -:
echo 'int main(){return 0;}' | g++ -x c++ -O -Wall -o myprog /dev/stdin
BTW, since int main(){return 0;} is a valid C program, you could use
echo 'int main(){return 0;}' | gcc -x c -O -Wall -o myprog -
Programatically, you should consider using popen(3) to get a some FILE* handle for a pipe(7) (so FILE* f = popen("g++ -x c++ -O -Wall -o myprog /dev/stdin", "w"); then check that f is not null) and fprintf into it then pclose it at last. Don't forget to test the status of pclose.
However, most of the time spent by GCC is not parsing (use -ftime-report developer option to find out). You often want to ask it to optimize (with -O2 -march=native or just -O for example), and you surely want to ask for all warnings (with at least -Wall and perhaps also -Wextra).
If you want to produce some plugin code in /tmp/someplugin.so from some emitted C++ code in /tmp/myemitted.cc to be dynamically loaded on Linux, compile it as position-independent code into a shared object dynamic library with e.g.
g++ -o /tmp/someplugin.so -fPIC -shared -Wall -O /tmp/myemitted.cc
etc.... then use dlopen(3) on /tmp/someplugin.so with dlsym(3) to fetch some loaded symbols. My GCC MELT is doing this.
Since parsing time is negligible, you could instead write C or C++ code in some temporary file (inside /tmp/ or /run which is often some fast tmpfs on most Linux systems, so writing into it does not require disk I/O).
At last, recent GCC (use at least GCC 6) also has GCCJIT (actually libgccjit). You could use it to build some representation of generated code then ask GCC to compile it.
See also this and that. Read the C++ dlopen mini howto and the Program Library HowTo, and Drepper's How To Write Shared Libraries
I rather not make files
Generating a temporary file (see mkstemp(3) etc... and you practically could also general some random file name under /tmp/ ending with .c, then register its removal with atexit(3) passed some function doing unlink(2)...) is really quick (but you should build some kind of AST in memory before emitting C++ or C code from it). And using some Makefile to compile the generated code with some make command has the advantage (for the advanced user) to be able to change compilers or options (by editing that Makefile to configure make).
So you are IMHO wrong in avoiding temporary files (notice that gcc & g++ are also generating and deleting temporary files, e.g. containing some assembler code). I would suggest on the contrary generating a temporary file (matching /tmp/mytemp*.cc) using some random numbers (see random(3); don't forget to seed the PRNG with e.g. srandom(time(NULL)); early in your main). It could be as simple as
char tmpbuf[80];
bool unique;
do { // in practice, this loop is extremely likely to run once
snprintf(tmpbuf, sizeof(tmpbuf), "/tmp/mytemp_%lx_p%d.cc",
random(), (int)getpid());
unique = access(tmpbuf, F_OK);
} while (unique);
// here tmpbuf contains a unique temporary file name
You coded:
system("g++ -C "+code_string+" -o run.out");
Beware, + is usually not string catenation. You might use snprintf(3) or asprintf(3) to build strings. Or use in C++ std::string. And if you use system(3) you should check its return code:
char cmdbuf[128];
snprintf(cmdbuf, sizeof(cmdbuf), "g++ -Wall -O %s -o run.out", tmpbuf);
fflush(NULL);
if (system(cmdbuf) != 0) {
fprintf(stderr, "compilation %s failed\n", cmdbuf);
exit(EXIT_FAILURE);
}
BTW, your example is wrong (missing <stdio.h>); it is C code, not C++ code. It should be
echo -e '#include <stdio.h>\nint main(){printf("Hello World"); return 0;}' \
| gcc -x c -Wall -O -o myprog -
PS. My answer is focused on Linux, but you could adapt it for your OS.

g++ : include problems when cross compiling

I've got a problem that's a bit strange.
We have a project that we compile for several different architectures, notably these 2: SH4 and MIPS.
We've had a problem for some time, where some code would compile in SH4, but not for MIPS, because of missing includes. I've narrowed down the problem to this test file:
#include <sstream>
// deliberately not including the needed includes
int main()
{
const char *toto = "Hello World";
// using printf and strlen which require <stdio.h> and <string.h>
printf("Toto has len %d\n", strlen(toto));
return 0;
}
Compiling to SH4 with this command
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
$
-> no problem at all. The file actually executes normally.
Whereas with MIPS
$ mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
test.cpp: In function 'int main()':
test.cpp:6: error: 'strlen' was not declared in this scope
$
Now, I've run several things, notably the dependency generation of both g++. What I see is this:
SH4 
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
/opt/STM/STLinux-2.3/devkit/sh4/target/usr/include/string.h \
-> string.h automatically included.
MIPS
mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
-> string.h missing in includes
For information:
SH4 version = 4.2.4 (2007)
MIPS version = 4.3.2 (2008)
What's going on here? The <sstream> include seems to drag along all what's needed for strlen() when compiling on SH4, whereas on MIPS it doesn't. I suspect this is because the versions are different, but I'm not sure.
My real problem, in the end, is that when I develop on SH4, I'd like to be sure that if it compiles, it will compile on all targets.
Is there a solution to this?
What's going on here?
You're basically asking "why does my non-standard code compile with one version of a compiler but not another?" Of course it's because the versions are different.
See the GCC 4.3 changes which say this under the Runtime Library (libstdc++) section:
Header dependencies have been streamlined, reducing unnecessary includes and pre-processed bloat.
We've continued reducing header dependencies in more recent versions too, to be stricter and to reduce namespace pollution (e.g. 4.6 avoids including <cstddef> unnecessarily, and 4.7 no longer includes <unistd.h> unnecessarily), so to answer your final question I would suggest using the most recent GCC version you can (even if only to check the code not for production builds) as it has the strictest, cleanest headers and will find the most problems. Another option would be to use an even stricter standard library implementation, such as libcomo.

Beginner's question, trying to understand how the linker searches for a static library

I have a working setup, where all files are in the same directory (Desktop). The Terminal output is like so:
$ gcc -c mymath.c
$ ar r mymath.a mymath.o
ar: creating archive mymath.a
$ ranlib mymath.a
$ gcc test.c mymath.a -o test
$ ./test
Hello World!
3.14
1.77
10.20
The files:
mymath.c:
float mysqrt(float n) {
return 10.2;
}
test.c:
#include <math.h>
#include <stdio.h>
#include "mymath.h"
main() {
printf("Hello World!\n");
float x = sqrt(M_PI);
printf("%3.2f\n", M_PI);
printf("%3.2f\n", sqrt(M_PI));
printf("%3.2f\n", mysqrt(M_PI));
return 0;
}
Now, I move the archive mymath.a into a subdirectory /temp. I haven't been able to get the linking to work:
$ gcc test.c mymath.a -o test -l/Users/telliott_admin/Desktop/temp/mymath.a
i686-apple-darwin10-gcc-4.2.1: mymath.a: No such file or directory
$ gcc test.c -o test -I/Users/telliott_admin/Desktop/temp -lmymath
ld: library not found for -lmymath
collect2: ld returned 1 exit status
What am I missing? What resources would you recommend?
Update: Thanks for your help. All answers were basically correct. I blogged about it here.
$ gcc test.c /Users/telliott_admin/Desktop/temp/mymath.a -o test
edit: gcc only needs the full path to the library for static libraries. You use -L to give a path where gcc should search in conjunction with -l.
To include the math libraries, use -lm, not -lmath. Also, you need to use -L with the subdirectory to include the library when linking (-I just includes the header for compiling).
You can compile and link with:
gcc test.c -o test -I/Users/telliott_admin/Desktop/temp /Users/telliott_admin/Desktop/temp/mymath.a
or with
gcc test.c -o test -I/Users/telliott_admin/Desktop/temp -L/Users/telliott_admin/Desktop/temp -lmymath
where mymath.a is renamed libmymath.a.
See link text for comments (search for "bad programming") on the practices of using -l:
In order for ld to find a library with -l, it must be named according to the pattern libyourname.a. Then you use -lmymath
So, there is no way to get it to take /temp/mymath.a with -l.
If you named it libmymath.a, then -L/temp -lmymath would find it.

Resources