What can linking to a CMake target impact?

2019-09-21 01:23发布

问题:

I ran into an interesting problem today. I am trying to compile and link a test executable to the Boost unit test framework and I tried it in two different ways.

  1. The classic approach of linking directly to the "boost_unit_test_framework" library using -lboost_unit_test_framework
  2. The modern CMake approach of linking to the Boost::unit_test_framework CMake target.

Interestingly when I link to the library directly my code compiles and links fine; however when I link to the CMake target my code fails to compile before it even gets to the linking stage!

The errors I get are related to a header file that it suddenly can't seem to find anymore. This suggests that linking to the Boost::unit_test_framework somehow messed with my include path.

I know linking to a CMake target is supposed to be the more modern and preferred approach, but if it can have such unexpected and unexplainable side effects, it seems worse than just linking straight to the library...

Why would linking the CMake target cause header files to not be found anymore? Also what other kinds of things can linking to a CMake target instead of linking directly to a library impact?


In both scenarios I am using target_link_libraries to link to the boost library. For example

target_link_libraries(mytest_exe
    testlib
    -lboost_unit_test_framework
)

or

target_link_libraries(mytest_exe
    testlib
    Boost::unit_test_framework
)

回答1:

The fact that it is failing before linking means that the target_link_libraries command in CMake actually effects more than just linking. It is effecting the compilation as well.

Yes, it is true that new include directories are added when you link with a library target instead of the library file. This is why the approach is called "modern" - a single target_link_libraries call does all things which are needed to use the library (Boost in your case).

Reason of failing with "modern" approach could be that "true" Boost headers conflict with other headers you use. You may detect that via inspecting chain of include files in the error message.