|
|
(50 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| __TOC__
| | {{CMake/Template/Moved}} |
|
| |
|
| =Exporting and Importing Targets=
| | This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/notes/2.6 here]. |
| | |
| =Preprocessor Definitions=
| |
| | |
| =Linking=
| |
| | |
| CMake 2.6 implements a new approach to generating link lines for targets.
| |
| | |
| Consider these libraries:
| |
| | |
| /path/to/libfoo.a
| |
| /path/to/libfoo.so
| |
| | |
| Previously if someone wrote
| |
| | |
| target_link_libraries(myexe /path/to/libfoo.a)
| |
| | |
| CMake would generate this code to link it:
| |
| | |
| ... -L/path/to -Wl,-Bstatic -lfoo -Wl,-Bdynamic ...
| |
| | |
| This worked most of the time, but some platforms (such as OS X) do not
| |
| support the <code>-Bstatic</code> or equivalent flag. This made it impossible to
| |
| link to the static version of a library without creating a symlink in
| |
| another directory and using that one instead.
| |
| | |
| Now CMake will generate this code:
| |
| | |
| ... /path/to/libfoo.a ...
| |
| | |
| This guarantees that the correct library is chosen. However there are some side-effects.
| |
| | |
| ==Missing Linker Search Directories==
| |
| | |
| Projects used to be able to write this (wrong) code and it would work by accident:
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| where "<code>B</code>" is meant to link "<code>/path/to/libB.so</code>". This code is incorrect
| |
| because it asks CMake to link to <code>B</code> but does not provide the proper
| |
| linker search path for it. It used to work by accident because the
| |
| <code>-L/path/to</code> would get added as part of the implementation of linking to
| |
| A. The correct code would be
| |
| | |
| link_directories(/path/to)
| |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| or even better
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)
| |
| | |
| In order to support projects that have this bug, we've added a
| |
| compatibility feature that adds the "<code>-L/path/to</code>" paths for all libraries
| |
| linked with full paths even though the linker will not need those paths
| |
| to find the main libraries. The compatibility mode is enabled when a
| |
| link line contains a non-full-path library (like <code>B</code>) and either
| |
| <code>CMAKE_BACKWARDS_COMPATIBILITY</code> is set to 2.4 or lower or
| |
| <code>CMAKE_LINK_OLD_PATHS</code> is set to true.
| |
| | |
| If you are trying to build a project and run into this problem, a quick-fix is to run
| |
| | |
| cmake -DCMAKE_LINK_OLD_PATHS:BOOL=ON .
| |
| | |
| in the top of the build tree.
| |
| | |
| ==Linking to System Libraries==
| |
| | |
| System libraries on UNIX-like systems are typically provided in <code>/usr/lib</code> or <code>/lib</code>. These directories are considered implicit linker search paths because linkers automatically search these locations even without a flag like <code>-L/usr/lib</code>. Consider the code
| |
| | |
| find_library(M_LIB m)
| |
| target_link_libraries(myexe ${M_LIB})
| |
| | |
| Typically the <code>find_library</code> command would find the math library
| |
| | |
| /usr/lib/libm.so
| |
| | |
| In CMake 2.4 and lower this value would be assigned directly to <code>M_LIB</code>. Then the link line generation would split off the link directory <code>/usr/lib</code> and the library <code>libm.so</code> and produce the
| |
| | |
| ... -lm ...
| |
| | |
| Note that the <code>-L/usr/lib</code> option is left out because it is an implicit linker search path. The linker would see <code>-lm</code> and search for the math library. Typically the linker would find /usr/lib/libm.so too. However some platforms provide multiple versions of libraries correesponding to different architectures. For example, on an IRIX machine one might find the libraries
| |
| | |
| /usr/lib/libm.so (ELF o32)
| |
| /usr/lib32/libm.so (ELF n32)
| |
| /usr/lib64/libm.so (ELF 64)
| |
| | |
| On a Solaris machine one might find
| |
| | |
| /usr/lib/libm.so (sparcv8 architecture)
| |
| /usr/lib/sparcv9/libm.so (sparcv9 architecture)
| |
| | |
| When the linker sees <code>-lm</code> it in fact searches the system path corresponding to the current architecture. Internally it might use <code>-L/usr/lib/sparcv9</code> instead of <code>-L/usr/lib</code>.
| |
| | |
| In CMake 2.6 the code
| |
| | |
| target_link_libraries(myexe /usr/lib/libm.so)
| |
| | |
| would generate the link line
| |
| | |
| ... /usr/lib/libm.so ...
| |
| | |
| no matter what architecture is getting linked. This might cause the linker to complain if <code>/usr/lib/libm.so</code> does not match the architecture it wants. This is not a problem with the link line computation. CMake is linking <code>myexe</code> to the library to which it was told to link.
| |
| | |
| The problem is created because <code>find_library</code> may not know about all the architecture-specific system search paths used by the linker. In fact when it finds <code>/usr/lib/libm.so</code> it may be finding a library of incorrect architecture. The solution is for the command to recognize that when it finds a library in a system search path that it should ask the linker to find the correct version of the library at link time. Consider the original example:
| |
| | |
| find_library(M_LIB m)
| |
| target_link_libraries(myexe ${M_LIB})
| |
| | |
| In CMake 2.6 the <code>find_library</code> command will set <code>M_LIB</code> to contain just "<code>libm.so</code>" when it finds <code>/usr/lib/libm.so</code>. The link command will then be
| |
| | |
| target_link_libraries(myexe libm.so)
| |
| | |
| which will be converted to the link command line
| |
| | |
| ... -lm ...
| |
| | |
| and the linker will locate the correct version of the library. If <code>find_library</code> does not find the library in an implicit link directory it will report the full path as usual. The user might also edit the cache to set <code>M_LIB</code> to a full path. In both cases the full path given to target_link_libraries will be preserved on the final link line.
| |