I have a project where two different packages (gtkmm and matlab engine) rely on different incompatible versions of the same library (libfreetype). I was told by mathworks to solve the problem in gcc with the line:
-Wl,-rpath,/usr/lib/x86_64-linux-gnu:/usr/local/MATLAB/R2014a/bin/glnxa64
This works well in the gcc command line. How can I translate this into cmake?
This is a linker flag, so you probably want to do something like
set(CMAKE_EXE_LINKER_FLAGS -Wl,-rpath,....)
Related
I'm trying to compile CMake using a non-default GCC installed in /usr/local/gcc530, on Solaris 2.11.
I have LD_LIBRARY_PATH=/usr/local/gcc530/lib/sparcv9
Bootstrap proceeds fine, bootstrapped cmake successfully compiles various object files, but when it tries to link the real cmake (and other executables), I get pages of "undefined reference" errors to various standard library functions, because, as running the link command manually with -Wl,-verbose shows, the linker links with /usr/lib/64/libstdc++.so of the system default, much older GCC.
This is because apparently CMake tries to find curses/ncurses libraries (even if I tell it BUILD_CursesDialog:BOOL=OFF), finds them in /usr/lib/64, and adds -L/usr/lib/64 to build/Source/CMakeFiles/cmake.dir/link.txt, which causes the linker to use libstdc++.so from there, and not my actual GCC's own.
I found a workaround: I can get the path to proper libraries from $CC -m64 -print-file-name=libstdc++.so then put it with -L into LDFLAGS when running ./configure, and all works well then.
Is there a less hacky way? It's really weird that I can't tell GCC to prioritize its own libraries.
Also, is there some way to have CMake explain where different parts of a resulting command line came from?
My cmake project shall compile c++14 code. It also uses the CMakeLists.txts included from its external libraries (which are git submodules in my project). The build fails on macOS Sierra (cmake 3.6.2) because the default STL of clang is old and doesn't handle c++11. As far as I understand, there are two STLs shipped with clang: libstdc++ (from gcc) (default) or libc++. So if I add the -stdlib=libc++ option to cmake, the source compiles:
add_compile_options( "$<$<COMPILE_LANGUAGE:CXX>:-std=c++14>" )
add_compile_options( "$<$<COMPILE_LANGUAGE:CXX>:-stdlib=libc++>" )
But then it fails at link time because it tries to use libstdc++ for linking. How do I specify in cmake that the new STL libc++ shall be used for the whole build process?
PS: What is the rationale behind clang using the gcc STL by default if it is too old? Could I permanently specify which STL it shall use? Or am I doing something completely wrong (could some of my subprojects silently force gcc?)?
You should rely on CMake to handle compile options. Just specify the wanted standard version:
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
target_compile_features can also be used to require particular features of the standard (and implicitly ask CMake to set the adequate configuration). More information here.
EDIT
You figured out the solution, you also had to remove the following line in the CMakeLists of Ogred3D:
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
Removing it prevented CMake to add the flag mmacosx-version-min=10.7 causing the error.
I suppose, you also need to pass that flang to the linker in the clang case:
link_libraries("-stdlib=libc++")
[Shamelessly cross-posted from the CMake help list]
I'm trying to create binaries as statically as possible. The fortran code I've got has got X11 and quadmath as dependencies, and I've come across a number of issues (maybe each of these issues should be in a different question?):
My variables are currently
set(CMAKE_LIBRARY_PATH /usr/X11/lib /usr/X11/include/X11 ${CMAKE_LIBRARY_PATH})
find_package(X11 REQUIRED)
find_library(X11 NAMES X11.a PATHS /usr/X11/include/X11/ /usr/X11/lib)
find_library(X11_Xaw_LIB NAMES Xaw Xaw /usr/X11/include/X11/ /usr/X11/lib ${X11_LIB_SEARCH_PATH})
find_library(Xaw Xaw7 PATHS ${X11_LIB_SEARCH_PATH})
set(CMAKE_LIBRARY_PATH /usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/x32 /usr/lib/gcc/x86_64-linux-gnu/4.7/32 ${CMAKE_LIBRARY_PATH})
find_library(quadmath NAMES quadmath.a)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(LINK_SEARCH_START_STATIC TRUE)
set(LINK_SEARCH_END_STATIC TRUE)
set(SHARED_LIBS OFF)
set(STATIC_LIBS ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
Using these, CMake attempts to build every program statically (as expected) - however, it fails because I don't have Xaw.a - I can't find out whether this actually should exist. I have installed the latest libxaw7-dev which I was expecting to fix it. One option would be to compile the X11 libraries myself, but I don't really want to do that...
if I comment out only set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static"), then CMake compiles everything, but uses shared libraries for every program, even though I specify the location of .a X11 libraries in my find_library() calls. I was expecting CMake to use the .a files where it could and then only use shared libraries - is there a way to force this behaviour?
does anyone know yet of a fix for the bug described here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539; whereby gfortran seemingly can't statically link libquadmath? I tried the fix using gcc but I can't get CMake to recognise the libgfortran flag:
cmake -DCMAKE_Fortran_COMPILER=gcc -DCMAKE_Fortran_FLAGS=-gfortran
results in
-- The Fortran compiler identification is unknown
-- Check for working Fortran compiler: /usr/bin/gcc
-- Check for working Fortran compiler: /usr/bin/gcc -- broken
CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestFortranCompiler.cmake:54 (message):
The Fortran compiler "/usr/bin/gcc" is not able to compile a simple test program.
However, as you might have noticed, I set the location of the libquadmath.a; when I build a program which doesn't use X11 but does use quadmath when I use
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
then the program does compile successfully (running ldd reports 'not a dynamic executable') - does this mean that the bug has been fixed, or does it only work because I set the location in CMake?
I was having a similar problem. Turns out that cmake was implicitly linking against libgfortran and libquadmath. To fix this I put the following in my top level CMakeLists.txt:
unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES)
I could then explicitly link again the libraries using:
SET_TARGET_PROPERTIES(main_f PROPERTIES LINKER_LANGUAGE "C"
LINK_FLAGS
"/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libgfortran.a
/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libquadmath.a -lm -lgcc"
)
The static version of libgfortran is necessary because the shared library also depends on libquadmath. The added "-lm" and "-lgcc" bring in the system dynamic versions of these libraries. On a mac system, you would want to use the full path to your libm.a as well.
I guess your questions are not that much related, I don't know the answer for all of them.
For your static linking problems, since you're using GCC, you can pass multiple -static and -dynamic flags to it:
set(CMAKE_EXE_LINKER_FLAGS "-static ${STATIC_LIBS} -dynamic ${EVERYTHING ELSE} -static ${MORE_STATIC_LIBS}")
I don't know why Xaw.a isn't available on your system, probably because the package maintainer of your Linux distribution didn't really make them available.
Also, compiling everything static might make things not compatible between all distros out there and you cripple the ability for others to use improved, up-to-date libraries with your program, it might not be what you want.
If you intend to make a self-contained package of your program, it might be better just to include the shared libraries you used together, like Dropbox and many other proprietary applications do (Humble Bundle games are other example).
I have a problem with the implicit LIBRARY_PATH modification of g++ between two versions (g++ -v gives this info). I set the LIBRARY_PATH to a single local directory where I have custom libraries. However, it turned out that only one version of the g++ (let's call it version A) correctly linked, the other (version B) linked to the system-default, which was not desired. Apparently, the order of directories was mixed up and my specification was not properly respected. It is a similar issue to LIBRARY_PATH not used before /usr/lib anymore in gcc 4.2 and later? although not with these versions.
Somehow I came along the idea to have a look at the specs files of the two different versions (got them via g++ -dumpspecs > specs). I then tried to see if running the version of g++ (B; that was producing the *un*expected modifications) with the specs file of the other version (A) would still yield that modification and to my relief the LIBRARY_PATH was now exactly as I expected it (matching version A)!
I further traced down the place of this weird modification to happen at the following line:
. !m64 !m32;.:../lib64 m64 !m32;.:../lib32 !m64 m32;
Besides appearing to affect the setting/modification of LIBRARY_PATH, I sadly have no clue what this line means.
Therefore I hope that some of you is able to "decipher" this line and explain what it means so that I can try to modify it according to my requirements.
Thank you!
That line affects how libraries are found relative to GCC's $PREFIX/lib directory (where $PREFIX is the directory GCC was installed to.)
There are three parts to it:
$PREFIX/lib/. is used when neither -m32 or -m64 is used on the command-line.
$PREFIX/lib/.:$PREFIX/lib/../lib64 is used when -m64 is used.
$PREFIX/lib/.:$PREFIX/lib/../lib32 is used when -m32 is used.
This suggests to me you are using Debian or Ubuntu, I don't think a vanilla GCC build from the FSF sources would have that in the specs. Were both your GCC versions from .deb packages or did you install them yourself? (The Multi Arch support in recent Debian/Ubuntu releases moves library directories and so breaks vanilla GCC, I think Debian and Ubuntu patch the GCC code for their .deb packages.)
Could you add the output of linking with g++ -v for each of your versions, to see the exact library search paths used by each version?
Also, why not just use -L instead of LIBRARY_PATH? Directories specified with -L always come first, before the system dirs or GCC's own dirs or the ones specified in LIBRARY_PATH.
I want to compile a source code, but there are some compiling errors about __sync_xxx functions (__sync_bool_compare_and_swap etc.)
GCC version on machine is 3.4.3 (it must be gcc 4.1 or over for supporting atomic builtins), so I have downloaded GCC v4.6, copied it to another directory (I didn't remove v3.4.3) then change the $PATH path for GCC but it doesn't work (the same error occurs).
I want to ask that is only changing gcc path with export PATH=... enough for compiling with new GCC?
Use the following configure option when compiling gcc:
--program-prefix=foo --program-suffix=bar
and it will produce bin programs of the form "foo-gcc-bar", so that you may differentiate different builds of gcc.
Replace foo and/or bar with an appropriate "tag" for your build (eg "-4.6" for example).
This way if it doesn't find your toolchain correctly it will fail fast rather than using the 3.4 version.
It also means that different toolchain builds can coexist in the standard installation prefix directories.
We have to use -march=686 switch to get it to work on intel.
Try checking and updating LD_LIBRARY_PATH, to use the lib path for the new gcc installed.