How to make CMake append linker flags instead of prepending them?

Ashwin Nanjappa picture Ashwin Nanjappa · Mar 11, 2014 · Viewed 9.4k times · Source

CMake seems to prepend linker flags at the front of a GCC compilation command, instead of appending it at the end. How to make CMake append linker flags?

Here is a simple example to reproduce the problem. Consider this C++ code that uses clock_gettime:

// main.cpp
#include <iostream>
#include <time.h>

int main()
{
    timespec t;
    clock_gettime(CLOCK_REALTIME, &t);
    std::cout << t.tv_sec << std::endl;
    return 0;
}

This is a CMakeLists.txt to compile the C++ file above:

cmake_minimum_required(VERSION 2.8)
set(CMAKE_EXE_LINKER_FLAGS "-lrt")
add_executable(helloapp main.cpp)

Note that we have added -lrt since it has the definition of clock_gettime.

Compiling this using:

$ ls
  CMakeLists.txt main.cpp
$ mkdir build
$ cd build
$ cmake ..
$ make VERBOSE=1

Which throws up this error, even though you can see -lrt in the command:

/usr/bin/c++ -lrt CMakeFiles/helloapp.dir/main.cpp.o -o helloapp -rdynamic 
CMakeFiles/helloapp.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x15): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make[2]: *** [helloapp] Error 1

The problem here is the C++ compilation command generated by CMake has -lrt prepended at the front. The compilation works fine if it had been:

/usr/bin/c++ CMakeFiles/helloapp.dir/main.cpp.o -o helloapp -rdynamic -lrt

How to make CMake append the linker flags at the end?

Answer

steveire picture steveire · Mar 11, 2014

In general you can't (I think), but in the specific case that you want to link against a particular library, you should be using the syntax

target_link_libraries(helloapp rt)

instead. CMake knows that this corresponds to passing -lrt on the linker command line.