1
votes

I'm learning CMake and I'm struggling with it a little. My "project" is using JsonCpp "library" that was provided as one .cpp file and two .h files. The structure looks like this:

myProject
    build/

    json/
       CMakeLists.txt
       jsoncpp.cpp
       include/
           json.h
           json-forward.h

    CMakeLists.txt 
    main.cpp

build/CMakeLists.txt:

cmake_minimum_required(VERSION 3.6.0)
project(myProject)
add_subdirectory(json)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE json)
# add_executable(app main.cpp json/jsoncpp.cpp json/include/json.h json/include/json-forwards.h)

json/CMakeLists.txt:

cmake_minimum_required(VERSION 3.6.0)

add_library(
    json
    jsoncpp.cpp
    include/json.h
    include/json-forwards.h
)

target_include_directories(json PUBLIC '${CMAKE_CURRENT_SOURCE_DIR}/include')

What's a difference between using only add_executable() with all .cpp files and using target_link_libraries that transforms jsoncpp into static library and then link it? What approach should I choose?

A next thing confusing me is a target_include_directories(). What are the benefits using this function? If I comment it, and run cmake (then makefile and launch the app) everything still works fine. If I delete "include/json.h" "include/json-forward.h" from add_library(), everything still works.

1

1 Answers

1
votes

What's a difference between using only add_executable() with all .cpp files and using target_link_libraries that transforms jsoncpp into static library and then link it? What approach should I choose?

Using add_library is required when you have 2 executables using the same jsoncpp code. In this case, if you list jsoncpp sources in both add_executable() calls, you'd have to compile it twice. Grouping them into add_library() will make it compile only once and then linked to both executables.

Another reason to use add_library is purely logical composition of modules.