[CMake] To avoid target_link_libraries magic

Valeriy Bykov valery.bickov at gmail.com
Tue Mar 22 06:44:36 EDT 2011


For now I have fixed build on different hosts by forcing ithe compiler.
But I don't understand why does it work and why lib is passed by full path
now.

On Tue, Mar 22, 2011 at 12:27:10PM +0300, Valeriy Bykov wrote:
> 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