Strange behaviour of ExternalProject_Add with a command containing a space - c++

I need to compile boost libraries with ExternalProject_Add, and the build command needs
c++11 flags on MacOS platform with Clang.
The command should look like this:
./bin/b2 debug release cxxflags="-std=c++11 -stdlib=libc++" linkflags=-stdlib=libc++
But I have a problem with the quotes and space.
set(BOOST_CXX_FLAGS cxxflags="-std=c++11 -stdlib=libc++")
set(BOOST_TOOL_SET toolset=clang ${BOOST_CXX_FLAGS}
linkflags=-stdlib=libc++)
ExternalProject_Add(boost
....
BUILD_COMMAND ./bin/b2 debug release
${BOOST_TOOL_SET}
....
)
The ${BOOST_TOOL_SET} value is a list, and cxxflags="-std=c++11
-stdlib=libc++" is one item in it. The generated command line becomes strange:
./bin/b2 debug release "cxxflags=\"-std=c++11 -stdlib=libc++\""
linkflags=-stdlib=libc++
It seems the flag is translated by CMake when it detected the space inside the argument and wrapped it with quote marks, but it's not what I want.
I searched on the Internet, but haven't found any help. Is there any tip about this issue?

This should work:
set(BOOST_CXX_FLAGS "cxxflags=-std=c++11 -stdlib=libc++")
This should produce
./bin/b2 debug release "cxxflags=-std=c++11 -stdlib=libc++"
Under normal shell parsing rules, this is equivalent to what works for you:
./bin/b2 debug release cxxflags="-std=c++11 -stdlib=libc++"

This doesn't answer your question exactly, as in I can't see a way to get your requested command line to the b2 exe with the cxxflags="-std=c++11 -stdlib=libc++" portion correctly formatted.
However, I believe you can accomplish the desired effect by calling cxxflags= twice. Each argument is appended to the compiler flags eventually invoked by b2.
So you should be able to do:
set(BOOST_CXX_FLAGS cxxflags=-std=c++11 cxxflags=-stdlib=libc++)
and the eventual command invoked by b2 will be something like
"clang++" ... -std=c++11 -stdlib=libc++ ...
To verify this, you can add -d+2 to your command:
BUILD_COMMAND ./bin/b2 debug release ${BOOST_TOOL_SET} -d+2
This causes the full commands to be written to the boost-build-out.log file in your boost-stamp directory.

Related

Failed to use gdb for an executive file generated by cmake

To do debug for C++ codes with cmake, I have a trick to add the following lines before the project (myProjectYY) line of the CMakeLists.txt file in the root directory of the source code.
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
So, after cmake and make, I have obtained the executable file mainYY, and I can simply run gdb mainYY to do the debug as I should be able to see the source codes of mainYY.cpp.
I have 2 separated projects that were already cmake and make by the others, namely a simple project (i.e. myProject1) and a complicated project (i.e. myProject2). For myProject1, the above trick works for me, i.e. after I added the above 3 lines and re-do the cmake and make again to obtain main1, I can see the source code of main1.cpp by simply executing l in gdb.
But for myProject2, I do same, i.e. I added the above 3 lines and re-do the cmake and make again to obtain main2, but in gdb there is no source code for main2.cpp. That is, gdb main2 firstly gave me Reading symbols from main2...(no debugging symbols found)...done. And then if I run l in gdb, I have No symbol table is loaded. Use the "file" command.
What are the most probable reasons for such differences between myProject1 and myProject2? How can I find out those probable reasons, and how can I do the fix such that I can debug for myProject2?
Thanks.
As you mentioned, your myProject2 is a complicated project. There could be SET( CMAKE_BUILD_TYPE Release ... FORCE ) somewhere. Check using fgrep -R "CMAKE_BUILD_TYPE" and even better, remove every definition of this everywhere.
Use cmake -DCMAKE_BUILD_TYPE=Debug instead.

QMake result (makefile) differs when executing from bash instead of QtCreator

My goal is to add my Qt project to a Jenkins buildserver, for nightly builds. Therefore I want to compile my project from the command line. I copied the buildsteps located in the build configuration:
"/opt/fslc-x11/2.5/sysroots/x86_64-fslcsdk-linux/usr/bin/qt5/qmake" "/home/xxxx/repositories/xxx/xxx.pro" -spec linux-oe-g++ && /usr/bin/make qmake_all
"/usr/bin/make"
I execute these commands in the build directory. The problem lies in the qmake command. The qmake command generates the makefile, but this makefile is different when I generate it in the command line instead of in QtCreator. The binary result after make is ofcourse very different.
It seems that the qmake command from the command line creates a debug makefile instead of a release makefile:
CFLAGS = -pipe -02 -pipe -g -feliminate-unused-debug-types --sysroot=.........
The -02 -pipe -g -feliminate-unused-debug-types part is the only thing added when I run qmake in the command line (checked with diff).
I've tried the following:
Added CONFIG+=release to the qmake command
Added CONFIG-=DEBUG to the qmake command
Furthermore I've verified that the system environment and the terminal emulator is the same.
My question comes down to:
Why does qmake add the (debug) flags when running from the command line?
Does QtCreator add more to the environment that I might have missed?
Let me know if you need more information about the settings or the makefile that is generated.
Ok. So long story short: I've tried compiling for the local Linux distro with the standard qmake and my problem was solved.
It seems that problem lies at the custom qmake of the target (x86_64-fslcsdk-linux). I'm not gonna put more time in this issue, so feel free to add a more satisfying answer. I'll be happy to try it out :).

How to config cmake for strip file

when I use cmake in Release mode I have the following binary:
64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=485ac09b0a3aa879f88b7f5db6c00ea8d8e1eaf6, not stripped
I want the binary to be stripped.
How can I say to cmake in a clean way to add the -s option to my compiler to make it stripped?
Why did the Default Release mode not strip my binary?
Cleanest possible way is to modify CFLAGS or CXXFLAGS (depending on C or C++ code)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
But there is one more hack if you do not want to change your build system (figuring out exact place where to put above lines might be tricky). You may just use strip as standalone application, like:
strip -s a.out
and do this after executable is ready to release as a post-build step. I found this way cleaner, then disturbing compiler flags.
You can try
set_target_properties(TARGET_NAME PROPERTIES LINK_FLAGS_RELEASE -s)
Using add_link_options() or set_target_properties() to add -s should work fine, additionally, CMake creates an install/strip target which also could be used for striping the binary if you have at least one install() command for your target (reference).
Example:
$ cmake --build . --config Release --target install/strip
This works fine:
add_link_options($<$<CONFIG:RELEASE>:-s>)

DistCC and CMake - select between local and distributed build when running make

My project is build using CMake and is compiled with DistCC + GCC.
I configure the compiler as follows:
SET(CMAKE_C_COMPILER "distcc variation-of-gcc")
To build the project, I simply run 'cmake' and then 'make -jXX'.
Although distcc really speeds up things, I sometimes want to build without distribution - I want it to build locally on the machine.
I know I can modify DISTCC_HOSTS to include only localhost - but this still has the overhead of distcc networking, although it is faster than the overhead for other machines...
I can also do that by rerunning cmake again and modifying the CMAKE_C_COMPILER using customization flags.
But I am looking for a way to do that by just adding a flag directly to 'make'.
I.e.
# This will use distcc:
make -jXX ...
# This will run locally:
make LOCAL_BUILD=1 -jX ...
Is there a CMake trick I can use?
We use the following to allow make time (rather than cmake time) switching on and off of the -Werror flag.
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
# TODO: this approach for the WERROR only works with makefiles not Ninja
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> $(WERROR) -o <OBJECT> -c <SOURCE>")
endif()
Then we run
make WERROR=-Werror
to turn on warnings as error.
I expect you could do something similar to have whether to use distcc come from a make variable. Like this:
set(CMAKE_CXX_COMPILE_OBJECT "$(USE_DISTCC) <CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
And then run either
make USE_DISTCC=distcc
or just
make
The simplest thing to do (IMO) is write a little script in your project that invokes the compiler, and change your CMake files to run that script instead of containing the name of the compiler directly:
SET(CMAKE_C_COMPILER "my-gcc-script")
Now you can have that script normally run distcc, but (based on an environment variable or something) also run without distcc. There isn't any need to change anything in your CMake files.

using clang to generate call graph for a project

I have c and c++ project, and i would like to check for dead function (function that could not be called), for that i want to build a call graph and see which could not be accessed from the written code.
for that i want to use clang with the flag "-S -emit-llvm" so i could creat a dot file.
im using autoconf to compile the project and the autoconfig dont recognize the file that has been compiled as an executable.
tried using this line :
./configure --enable-debug --prefix=/opt/ibutils CC=clang CXX=clang++ CXXFLAGS="-S -emit-llvm"
and this
./configure --enable-debug --prefix=/opt/ibutils CC=clang CXX=clang++ CXXFLAGS="-S -emit-llvm"
LD="llvm-link"
does anyone know the reason? have a suggestions what could i do?
thanks