[CMake] To avoid target_link_libraries magic

Valeriy Bykov valery.bickov at gmail.com
Tue Mar 22 05:27:10 EDT 2011


Thanks for explanations.

It is possible to use imported targets for all libraries or
target properties but it is not convinient because I have
a lot of targets in my project.

So I'll try to describe all my problems:
I want to build all the project statically using certain version of glibc,
gcc and all other libs I need. They are situated in the folder "builddeps"
which I can simply checkout on any host and pass it's path to CMake.

I set compile option -nostdinc and specify all system and user include
directories explicitly in toolchain file. By this I can be sure that
only headers are used which I want, and no one from host system where
may be its own gcc and glibc too.

I set link option -static. It is enough to build all statically but in
command line of collect2 I've found the next (paths are shortened for
convinience):
.../builddeps/.../collect2 -m elf_x86_64 -static -o ../../../../test_atomic_lock ...builddeps/.../lib64/crt1.o .../builddeps/.../lib64/crti.o .../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtbeginT.o -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2 -L.../builddeps/.../lib/gcc -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../.. CMakeFiles/test_atomic_lock.dir/test_atomic_lock.c.o .../builddeps/glibc/lib/libpthread.a --start-group -lgcc -lgcc_eh -lc --end-group .../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtend.o .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64/crtn.o

We can see that startup object files are used from my own gcc, but ld
itself adds -L options to search libraries paths and then uses -lgcc,
-lgcc_eh and -lc, so I am afraid that I can link with host system libraries.

Then I try to specify libraries explicitly in toolchain file:
SET (GCC_DEFAULT_LIBS "-nodefaultlibs ${BUILDDEPS}/gcc45/lib64/libstdc++.a ${BUILDDEPS}/glibc/lib/libm.a --start-group ${BUILDDEPS}/gcc45/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/libgcc.a ${BUILDDEPS}/gcc45/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/libgcc_eh.a ${BUILDDEPS}/glibc/lib/libc.a --end-group ${BUILDDEPS}/glibc/lib/libpthread.a" CACHE STRING "GCC default libs" FORCE)"
SET (CMAKE_EXE_LINKER_FLAGS "-static ${GCC_DEFAULT_LIBS}" CACHE STRING "Flags used by the linker." FORCE)

But there is two problems as we can see from collect2 options:
.../builddeps/.../collect2 -m elf_x86_64 -static -o ../../../../test_atomic_lock .../builddeps/.../lib64/crt1.o .../builddeps/.../lib64/crti.o .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtbeginT.o -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2 -L.../builddeps/.../lib/gcc -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L.../builddeps/.../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../.. .../builddeps/gcc45/lib64/libstdc++.a .../builddeps/glibc/lib/libm.a .../builddeps/gcc45/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/libgcc.a .../builddeps/gcc45/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/libgcc_eh.a .../builddeps/glibc/lib/libc.a .../builddeps/glibc/lib/libpthread.a CMakeFiles/test_atomic_lock.dir/test_atomic_lock.c.o .../builddeps/glibc/lib/libpthread.a .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtend.o .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64/crtn.o

The first is that CMake eats "--start-group" and "--end-group".
The second is CMake inserts these system libraries in the front of
libraries therefore link fails.

So I avoid this way and simply specify my own LINK_DIRECTORIES to
${BUILDDEPS}/glibc/lib, ${BUILDDEPS}/gcc45/lib64 and
${BUILDDEPS}/gcc45/lib/gcc/x86_64-unknown-linux-gnu/4.5.2 in toolchain
file. Then this -L entries appear in front of those which are added by
ld and I hope I really uses libraries I need.

But then I have problem with -lpthread, which in ${BUILDDEPS}/glibc/lib
too... But! By some strange reason ${BUILDDEPS}/glibc/lib/libpthread.a
turns into -lpthread only when I specify -B${BUILDDEPS}/glibc/lib in
CMAKE_C_FLAGS. If I don't do it then CMake compiler tests fails on hosts
without installed system gcc and glibc. But on host with it all works
file:
.../builddeps/.../collect2 -m elf_x86_64 -static -o ../../../../test_atomic_lock .../builddeps/.../lib64/crt1.o .../builddeps/.../lib64/crti.o .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtbeginT.o -L.../builddeps/glibc/lib -L.../builddeps/glibc -L.../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2 -L.../builddeps/gcc45/bin/../lib/gcc -L.../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L.../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../.. CMakeFiles/test_atomic_lock.dir/test_atomic_lock.c.o .../builddeps/glibc/lib/libpthread.a -rpath .../builddeps/glibc/lib --start-group -lgcc -lgcc_eh -lc --end-group .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/crtend.o .../builddeps/gcc45/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../lib64/crtn.o

Do you see? There is -L.../builddeps/glibc/lib and
.../builddeps/glibc/lib/libpthread.a. So it's not obvious in which cases
transforming will be applied.

On Mon, Mar 21, 2011 at 10:30:58AM -0400, Brad King wrote:
> On 3/21/2011 10:12 AM, Valeriy Bykov wrote:
> > I'm using CMake version 2.8.4. Furthermore I use custom ToolChain but I
> > don't think it is important.
> >
> > ... /home/vbykov/svn/builddeps/glibc/lib/libpthread.a
>
> It may be important actually.  Is this path to libpthread.a in the
> implicit library search path for the toolchain?  What is the full
> link line produced?
>
> CMake behaves a bit differently for targets in implicit link
> directories.  Instead of using the full path it converts the
> library to '-lpthread' knowing that the linker will find it.
> This is because some toolchains substitute architecture-specific
> implicit link directories at the last moment.
>
> One may always use IMPORTED targets to tell CMake _exactly_ what
> path to use for a library:
>
>
> http://www.cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets#Importing_Targets
>
> See also the documentation here for why -B(static|dynamic) appear:
>
>
> http://www.cmake.org/cmake/help/cmake-2-8-docs.html#prop_tgt:LINK_SEARCH_END_STATIC
>
> and a recent change I made to help folks that want static linking:
>
>   http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5abfb571
>
> A version of CMake with this change is available as a nightly binary:
>
>   http://www.cmake.org/files/dev/?C=M;O=D
>
> -Brad

--
С уважением,
Быков Валерий


More information about the CMake mailing list