Having CMake include_directories SYSTEM dirs prefix with equals character (=) - gcc

Is there a way to have CMake include_directories include the system directory prefix with equals(=) character? So that I can have gcc prefix the associated dirs with -isysroot flag for the cross compilation.
When I try to include the path with equals(=) prefix, assumes relative path and prefixes with current source path:
include_directories(AFTER SYSTEM "=/usr/include")
results:
-isystem /root/opencv-2-4-9/opencv/modules/highgui/=/usr/include/
what I expect is:
-isystem=/usr/include/

I checked the source code of CMake (both 2.8.12.2 and 3.0.0); It seems CMake adds current source directory all paths which are not starting with '/' in non windows systems.
Only exception is generator expressions. If path starts with "$<", then it skips prefixing the path and does not prefix it after evaluation of the generator expression. Therefore
include_directories(AFTER SYSTEM "$<1:=>/usr/include")
generates
-isystem =/usr/include/
This seems to be working at least for CMake 3.0.0. Ofcourse you should set CMAKE_SYSROOT for gcc to prefix with proper path.
set(CMAKE_SYSROOT /usr/arm-linux-gnueabi)

Set it together in one command:
set_target_properties(<targetname> PROPERTIES COMPILE_FLAGS "-isystem=/usr/include/")

Related

How to ask GCC for the configured PATH_SEPARATOR?

I want to use the environment variable CPATH for compiling my application with GCC. The GCC manual says that the list of paths assigned to CPATH must be separated by the special character PATH_SEPARATOR, which got defined when GCC was build. PATH_SEPARATOR is usually ';' on Windows and ':' elsewhere.
Since I want to build my code on multiple platforms I need to know the character PATH_SEPARATOR in my makefile (to concatenate the paths assigned to CPATH correctly).
Can I ask my used GCC, with which value for PATH_SEPARATOR it was build?
(Of course I can alternatively try to detect the host OS in GNU make, and speculate on a suitable path separator from there, but this is not exactly the same. (E.g. I expect unwanted problems with CygWin))

GCC - generate absolute paths for #includes in debug symbols

OS is Windows, GCC is 4.7.2, GDB is 7.3.
I have a .c file in the C:/project/src/ folder with an include:
#include "../inc/header.h"
After the compilation I have a relative path in the debug symbols:
> objdump -WL obj.o | grep header.h
C:/project/src/../inc/header.h
...
Yet I want it to be C:/project/inc/header.h, because setting BPs in gdb fail for me if I use absolute paths when issuing the set breakpoint command.
This situation is artificial, but due to the environmental conditions the only solution to my issue will be either absolute paths generation in the debug symbols or teaching GDB to resolve relative paths.
Is there a switch for GCC to turn on the absolute path generation in the debug symbols?
The solution is in GDB, not GCC.
The easiest way is to add the directory containing the header to the search path:
(gdb) directory /path/to/include/
A more complicated one that you might need is pathname substitution rules:
(gdb) set substitute-path ../inc /path/to/inc

Make gcc put relative filenames in debug information

The project I'm compiling uses CMake, which loves absolute pathnames.
When I compile with debugging information enabled, gcc puts those long names into .debug_str sections, which is bad for debugging. I'd like to have short relative-to-project-root pathnames there instead.
Is there some option to tell gcc to strip some part of pathname before emitting debug data? Or, maybe, there is some tool that could do that on compiled binaries?
I've tried using SET(CMAKE_USE_RELATIVE_PATHS ON) (which seems to be frowned upon by devs) option, but as I'm using out-of-source builds, pathnames are still not in the form I'd want them to be. I.e. they're ./../src/mod_foo/foo.c instead of mod_foo/foo.c.
You can use the -fdebug-prefix-map flag to remap the debugging information paths. For example, to make the paths relative to the build location use: -fdebug-prefix-map=/full/build/path=.
You can set the RULE_LAUNCH_COMPILE property of a CMake target to have CMake invoke a shell script which transforms the source file path to a project relative path before invoking gcc. Use the CMake function configure_file to generate a shell script which knows about the PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR of your project.
In your outermost CMakeLists.txt add the following code:
configure_file(
"${PROJECT_SOURCE_DIR}/gcc_debug_fix.sh.in"
"${PROJECT_BINARY_DIR}/gcc_debug_fix.sh"
#ONLY)
add_executable (MyExecutable ...)
set_target_properties(MyExecutable PROPERTIES
RULE_LAUNCH_COMPILE "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh")
The following template shell script gcc_debug_fix.sh.in needs to go to the root directory of the CMake project:
#!/bin/sh
PROJECT_BINARY_DIR="#PROJECT_BINARY_DIR#"
PROJECT_SOURCE_DIR="#PROJECT_SOURCE_DIR#"
# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE
# extract parameters
SOURCE_FILE="${#: -1:1}"
OBJECT_FILE="${#: -3:1}"
COMPILER_AND_FLAGS=${#:1:$#-4}
# make source file path relative to project source dir
SOURCE_FILE_RELATIVE="${SOURCE_FILE:${#PROJECT_SOURCE_DIR} + 1}"
# make object file path absolute
OBJECT_FILE_ABSOLUTE="$PROJECT_BINARY_DIR/$OBJECT_FILE"
cd "$PROJECT_SOURCE_DIR"
# invoke compiler
exec $COMPILER_AND_FLAGS -c "${SOURCE_FILE_RELATIVE}" -o "${OBJECT_FILE_ABSOLUTE}"
The shell script uses the information from the variables PROJECT_BINARY_DIR and PROJECT_SOURCE_DIR to transform the path of the source file to a path relative to the project root and the object file's path to an absolute path. Because gcc gets passed a project relative path now, .debug_str should use that path, too.
The following caveats apply:
Be sure to set the executable bit of gcc_debug_fix.sh.in.
For the script to work CMAKE_USE_RELATIVE_PATHS has to set to OFF again.
The script makes assumptions about the location of the file paths on the command line. This may not work if CMake uses a different rule to invoke the compiler. A more robust solution would be to scan the script arguments for the -o and -c flags.
If I really couldn't fix the make file/tool to do this properly, I would write a wrapper script for gcc that recognises absolute pathnames and converts then to relative ones.
It might look something like this in bash:
#!/bin/bash
out=()
for arg; do
out=("${out[#]}" $(echo "$arg" | sed 's:/my/absolute/directory/:../:'))
done
exec gcc "${out[#]}"
If your source directory has subdirectories then you'll need to handle those carefully, but the above should work for a flat source directory. I've not tested it though, and I wouldn't be surprised if I've got the quoting wrong, but that'll only be a problem if you have pathnames with spaces in. It also doesn't handle parameters like -I/whatever/include, but you can fix that.

How to write Makefiles to get a relative path in debug symbols?

I have a structure of code like this:
project_dir/
source1.c
subdir/
source2.c
The Makefile calls subdir/Makefile, so that the file subdir/source2.c is compiled in this way:
gcc -g -someoptions source2.c
and symbols in GDB link to source2.c instead of subdir/source2.c (with the result that GDB can not find symbols in source files). How should I write a Makefile or what options to use in gcc to get symbols using the relative path to the project main directory (or eventually the absolute path)?
I can not use:
cd .. && gcc -g -someoptions ../subdir/source2.c
because I would have to change references to header files in all files in subdir.
Your question is platform-specific (e.g. on Linux GDB should just work(TM), so I assume you are not on Linux).
One option is to build like this:
gcc -g ${PWD}/source2.c -o ...
Another option is to use GDB dir command to add ${TOP}/project_dir/subdir to the list of directories that GDB will search for sources.

How do I make ccache cache compilation when using absolute paths to the compiled files in different directories?

I use CMake to create a makefiles. CMake creates GCC line containing absolute paths.
To speed up compilation I use ccache.
Building same code from different locations (e.g. several developers compile the same code, each under its home directory) causes ccache cache misses.
As mentioned in a comment above, one problem is that any absolute paths in the preprocessor line directives are hashed by ccache, and if the compiler option -g is used, the compiler emits an absolute path to the source code file as well. Another similar problem is that if the path to the source code file is absolute on the command line, that path will be hashed if the code has an expansion of the __FILE__ macro.
The solution is to upgrade to ccache 3.0, which was released some days ago. It has optional support for rewriting absolute paths to relative paths in order to increase hit rate. See Compiling in different directories in the manual.
Well, maybe stating the obvious: you'd have to either get cmake to produce relative paths, or modify ccache to consider cache entries as matching if the only difference is the absolute path.
I have modified my copy of ccache to ignore the -pipe option when calculating the hash (which is used to name the cache entries); since that option causes no difference on the compiler output, only on its speed. Maybe it wouldn't be so hard to make it strip the initial /home/*/ from paths when calculating the hash.

Resources