I have a file in source tree which name is "time.h", exactly as system "time.h". This cannot be changed. I have encountered a problem with cmake that when I use include_library option it is translated to -I flag which means that my custom "time.h" takes prcedence over system time.h even for <> includes. This is a definiti no-no.
I tried using include_directories (AFTER dir1 dir2) but it still generate -I option instead of expected -idirafter.
I don't think this is a problem with CMake; I believe gcc will always find your "time.h" before the system one, regardless of whether you use quotes or brackets in the #include and regardless of the various options in include_directories. See the entries for -I and -isystem in the gcc documentation
The AFTER option of CMake's include_directories relates only to the order of the directories as listed in the gcc command, it doesn't relate to gcc's -idirafter flag.
It's not a great plan to have your own files with identical names to system files, but if your hands are tied, you could avoid this issue without renaming time.h by qualifying the path for your own includes more fully, so rather than e.g.
CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR}/src)
header file: #include <time.h> // we want but don't get system one
#include "time.h" // we want and get own custom one
something more like
CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR})
header file: #include <time.h> // we want and get system one
#include "src/time.h" // we want and get own custom one
An alternative option would be to stick with your current #include setup (using angle brackets for the system time.h and quotes for your own) and not use include_directories at all in the CMakeLists.txt. Instead I think you could replace it with something like:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -iquote ${PROJECT_SOURCE_DIR}/src")
Using -iquote is probably a better option than -idirafter since the directory specified by -idirafter is (in this case incorrectly) treated as a system directory, and as such has warnings suppressed, etc.
If you do go for this choice, it's probably worth commenting the CMakeLists.txt to explain why there is no include_directories to avoid future refactoring reverting back to use the more normal include_directories command.
All in all, your best option if at all possible would be to rename your "time.h" file though.
Related
Does anyone know how to use gcc to generate all possible binary files from object files ? I know you can use : "gcc -MM" to generate all the .o files for some given source files.
But how would you use gcc to generate all possible binary files from object files
in a project ?
Example: I use "gcc -MM" to generate: a.o, b.o, c.o, d.o
If one were trying to generate a list of binaries files built from each of the .o files like this:
a: b.o c.o d.o
b: a.o c.o d.o
c: a.o b.o d.o
d: a.o b.o b.o
I can do this with a Perl script, but I was just curious if there was some way to do it with gcc
Thanks
Short answer, "no, but..."
gcc -MM can give you foo.o: bar.h because foo.cc contains the directive:
#include "bar.h"
That's easy. But foo.cc can also contain the declaration:
int bar_f1(int);
How can gcc know which object file contains the binary code for this function? Or if there are two object files containing functions with this signature, which it should use? It can't.
...Unless...
Long answer, "yes, if..."
If you refrain from giving source files forward declarations of things in other source files, and also refrain from giving a header file declarations of anything not contained in the corresponding source file, and also give the source file containing int main(...) a fixed name like, say, main.cc, then you can take the output of gcc -MM:
bar.o: bar.h baz.h
foo.o: bar.h
main.o: foo.h zot.h
pan.o: pan.h
zot.o: zot.h
and transform it without too much trouble (using e.g Perl or sed) into:
main: bar.o foo.o zot.o
In theory you could get by without these restrictions(*) by scanning the object files and constructing the dependency tree; this might be equivalent to scanning for the presence of int main(...), segregating those files and linking each of them against all the others, or just listing them, if all you want is a list of possible executables without dependencies (I'm still not sure exactly what you want). These things still require some scripting on your part, I know of no way to do them with gcc alone.
(*)You must still refrain from having two definitions of the same thing.
I mean whether gcc can insert some source code version infor into ELF binary as section or something similar. I do not want to change my source file, but add some info with gcc option in Makefile.
If you don't mind changing your source file just once, add something like this:
const volatile static char version[] = VERSION;
and compile with:
gcc -c -DVERSION='"1.2.3"'
The volatile keeps gcc from removing the string at higher optimization levels.
As written, this won't compile if you forget the -D option, which may be either good or bad depending on your requirements.
You can emit your version info into a text file, then turn that text file into an object file which you then statically link into your executable.
The first step is simple but you have to write some code: a script or something to write your version info in any format you like as a plain text file. Then write a makefile rule to produce say version.o from version.txt, using objcopy. Now you'll have an object file with two useful symbols defined in it: the beginning and end of the textual version info. Add that generated object to your executable, and you'll be able to access the version two ways: by running strings on the binary, or by writing code in the application to print the version string (you'll need to declare the start and end symbols as variables in some header file).
Even if you don't have access to your source anymore, you can link the object with this option:
gcc -Wl,--defsym,VERSION_1_2_3=0 prog.o -o prog
You can check it with hexdump -C prog | less and look for VERSION
Add this to your makefile and be sure to always know when a program was compiled:
BUILD = $(shell date +"%Y%m%d_%H%M%S")
LDLIBS = -Wl,--defsym,BUILD_$(BUILD)=0
With the GNU linker ld You can use
--version-script=version-scriptfile
Read more about the command-line options at:
Using LD, the GNU linker - Options
Read more about creating version scripts at:
Using LD, the GNU linker - Version Script
Let me warn you though, that it is not for the weak-hearted!
I have a C program that tries to modify a const string literal. As now I learned that this is not allowed.
When I compile the code with clang test.c the compiler gives no warning. But when I compile it with clang++ test.c it gives a warning:
test.c:6:15: warning: conversion from string literal to 'char *' is deprecated
[-Wdeprecated-writable-strings]
char *s = "hello world";
^
The problem is that it turns out clang++ is just a symbol link of clang:
ll `which clang++`
lrwxr-xr-x 1 root admin 5 Jan 1 12:34 /usr/bin/clang++# -> clang
So my question is how could clang++ behaves differently from clang given that it's a symbol link of clang?
Clang is looking at its argv[0] and altering its behavior depending on what it sees. This is an uncommon and discouraged, but not rare, trick going at least as far back as 4.2BSD ex and vi, which were the same executable, and probably farther.
In this case, clang is compiling your .c file as C, and clang++ is compiling it as C++. This is a historical wart which you should not rely on; use the appropriate compiler command and make sure that your file extension reflects the true contents of the file.
By convention, the name by which a command is invoked is passed as argv[0]; it is not especially unusual for programs to change their behavior based on this. (Historically, ln, cp, and mv were hardlinks to the same executable on Research Unix and used argv[0] to decide which action to do. Also, most shells look for a leading - in argv[0] to decide if they should be a login shell.) Often there is also some other way to get the same effect (options, environment variables, etc.); you should in general use this instead of playing argv[0] games.
There are reasons to do this, but in most cases it's not a good idea to rely on it or to design programs around it.
My configure.ac contains
AC_PROG_CXX
and my Makefile.am contains
AM_CXXFLAGS= -Werror -O3
and the resulting 'configure' script keeps on adding -O2 to the mix in addition to O3.
I have this suspicion that I'm supposed to do something in configure.ac to declare my preference for O3, but I can't find it in the doc. How do I tell it that I want to control the optimization level?
No, you are not supposed to add anything to configure.ac to indicate a preference for -O3. That sort of thing belongs in a user's CONFIG_SITE, not in configure.ac
However, if you insist on breaking the convention, you can do something like:
: ${CXXFLAGS=-Werror -O3}
Note that this line must appear before AC_PROG_CXX (or any macro that AC_REQUIRES it, such as LT_INIT, as that will cause AC_PROG_CXX to be emitted into the configure script before this line.)
The prior answer is correct in that it should be the installer's choice what flags are used. If you're still wondering where the -g -O2 comes from (likely), it is described at http://www.gnu.org/s/hello/manual/autoconf/C_002b_002b-Compiler.html.
That page does suggest "If your package does not like this default, then it is acceptable to insert the line ‘: ${CXXFLAGS=""}’ after AC_INIT and before AC_PROG_CXX to select an empty default instead."
I have a program, myprogram, which is linked with a static convenience library, call it libconvenience.a, which contains a function, func(). The function func() isn't called anywhere in myprogram; it needs to be able to be called from a plugin library, plugin.so.
The symbol func() is not getting exported dynamically in myprogram. If I run
nm myprogram | grep func
I get nothing. However, it isn't missing from libconvenience.a:
nm libconvenience/libconvenience.a | grep func
00000000 T func
I am using automake, but if I do the last linking step by hand on the command line instead, it doesn't work either:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/libconvenience.a `pkg-config --libs somelibraries`
However, if I link the program like this, skipping the use of a convenience library and linking the object files that would have gone into libconvenience.a directly, func() shows up in myprogram's symbols as it should:
gcc -Wl,--export-dynamic -o myprogram *.o libconvenience/*.o `pkg-config --libs somelibraries`
If I add a dummy call to func() somewhere in myprogram, then func() also shows up in myprogram's symbols. But I thought that --export-dynamic was supposed to export all symbols regardless of whether they were used in the program or not!
I am using automake 1.11.1 and gcc 4.5.1 on Fedora 14. I am also using Libtool 2.2.10 to build plugin.so (but not the convenience library.)
I didn't forget to put -Wl,--export-dynamic in myprogram_LDFLAGS, nor did I forget to put the source that contains func() in libconvenience_a_SOURCES (some Googling suggests that these are common causes of this problem.)
Can somebody help me understand what is going on here?
I managed to solve it. It was this note from John Calcote's excellent Autotools book that pointed me in the right direction:
Linkers add to the binary product every object file specified explicitly on the command line, but they only extract from archives those object files that are actually referenced in the code being linked.
To counteract this behavior, one can use the --whole-archive flag to libtool. However, this causes all the symbols from all the system libraries to be pulled in also, causing lots of double symbol definition errors. So --whole-archive needs to be right before libconvenience.a on the linker command line, and it needs to be followed by --no-whole-archive so that the other libraries aren't treated that way. This is a bit difficult since automake and libtool don't really guarantee keeping your flags in the same order on the command line, but this line in Makefile.am did the trick:
myprogram_LDFLAGS = -Wl,--export-dynamic \
-Wl,--whole-archive,libconvenience/libconvenience.a,--no-whole-archive
If you need func to be in plugin.so, you should try and locate it there if possible. Convenience libraries are meant to be just that -- a convenience to link to an executable or lib as an intermediate step.