4

I am building a moderately sized C++ library and have cobbled together my CMakeLists.txt file from a bunch of different examples, etc. I was trying to understand the difference between include_directories versus the target_link_libraries instructions.

I list some of my code below, but just wanted to preface with a comment. I use the Boost library to build some of my code. So I have an instruction to INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) to include the Boost source directories in the build process. So I assume that Cmake will include these Boost Source files when building any executable--without any additional explicit instruction.

But later I have a TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} ) when building an executable. So that suggests that I need to not only include the Boost directory, but then also explicitly link it with the executable.

So I was not sure if I actually needed both steps, or if I just needed the INCLUDE_DIRECTORIES instruction and that was it.

cmake_minimum_required(VERSION 3.7)
project(XXX) 
find_package(Boost 1.58.0 REQUIRED COMPONENTS system filesystem program_options chrono timer date_time REQUIRED)
if(NOT Boost_FOUND)
    message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.")
endif()
set(Boost_USE_STATIC_LIBS        ON)
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF)

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})

file(GLOB lib_SRC RELATIVE "lib/" "*.h" "*.cpp")
file(GLOB test_SRC RELATIVE "tests/" "*.h" "*.cpp")

# need to fix the instruction below to reference library
set(SOURCE_FILES ${lib_SRC} tests/testComplexCreator.cpp tests/testDataFormatter.cpp tests/testComplexAnalysis.cpp tests/testFascadeClass.cpp)
add_library(libXXX SHARED ${SOURCE_FILES})    
add_executable(${PROJECT_NAME} main.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp)
add_executable(gd_validator gudhi_validator.cpp)
TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} )
krishnab
  • 9,270
  • 12
  • 66
  • 123

2 Answers2

10

Yes, you need both.

include_directories will tell to the compiler where to look for the header files, in this case, the header files for the boost library.

target_link_libraries will tell to the linker which libraries you want to link against your executable.

While headers will provide (most of the time) just the interface to access the library, the library itself is precompiled and linked to your application.

Natanael Ramos
  • 340
  • 3
  • 10
  • Okay right. So as I understand what what you are saying, the `target_link_libraries` will precompile the headers/source of the target library and then link that against my application. Is that correct? – krishnab Apr 17 '17 at 18:23
  • Actually the library is already precompiled. So the compiler will look for uses of the library in your code and just call it (shared libs) or replace the use with the actual library code (static libs). The whole point of using libraries is to avoid unnecessary compilations. You'll not need to add ``target_link_libraries`` only if the library is header-only – Natanael Ramos Apr 17 '17 at 18:28
  • Okay, that is great. Yeah, that is what I was wondering about. Thanks so much for clarifying. – krishnab Apr 17 '17 at 18:30
0

include_directories specifies the directories to be searched for included files (headers). target_link_libraries specifies the libraries to be linked to your target (executable or library). Two completely​ different things.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • Yeah, so this is what I was wondering about. So does `target_link_libraries` refer to only already compiled libraries? Usually I point to a directory with all of the Boost header and source files, and then the compiler will build against those files. So do I only need to `target_link_libraries` if I am pointing to a compiled library? – krishnab Apr 17 '17 at 18:21
  • `target_link_libraries` does a whole lot more than linking. For example, it finds include directories. – juanchopanza Apr 17 '17 at 18:22
  • Include files are used during compilation. Libraries are linked later. What's the confusion? You need to point the compiler at where to find includes. You also need to point the linker at libraries to link. These are completely different things and depending on what you want to do you need to do one or the other or both. – Jesper Juhl Apr 17 '17 at 18:25
  • @juanchopanza Thanks. See that is why I was asking. If `target_link_libraries` will find the include directories, then do I need a separate instruction for the `include_directories`? Or, does `target_link_libraries` rely on the folders identified by the `include_directories` instruction? – krishnab Apr 17 '17 at 18:27
  • 1
    @krishnab It depends how the library that is being "linked" is defined, but if done properly, `target_link_libraries` would also get you the headers exported by that library. It is a badly named function. – juanchopanza Apr 17 '17 at 18:35