Home > Back-end >  Intellisense works, but compiling doesn't with cmake `target_link_libraries`
Intellisense works, but compiling doesn't with cmake `target_link_libraries`

Time:01-20

I've looked at many different threads, but nothing seemed to work.

I'm trying to include the NLohmann JSON library using CMake. IntelliSense does autocomplete the filename sometimes, but you see a red or purple error line underneath the include and during compilation it can't find it. GTest does work though. Does someone know what's going on?

root: CMakeLists.txt

cmake_minimum_required (VERSION 3.10)

project(my_project LANGUAGES CXX VERSION 1.0.0)

enable_testing()

add_subdirectory("src")
add_subdirectory("test")

set_property(TARGET my_project PROPERTY CXX_STANDARD 20)

src: CMakeLists.txt

cmake_minimum_required (VERSION 3.10)

add_executable(my_project
    ...
    "main.cpp"
)

set_property(TARGET my_project PROPERTY CXX_STANDARD 20)

add_subdirectory("C:/dev/libs/nlohmann_json/3.11.2" "build/nlohmann_json")
target_link_libraries(my_project PRIVATE nlohmann_json::nlohmann_json)

test: CMakeLists.txt

cmake_minimum_required (VERSION 3.10)

add_executable(my_project_test
    "properties.cpp"
    "main.cpp"
)

set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
set(CMAKE_CXX_FLAGS_RELEASE "/MT")

set_property(TARGET my_project_test PROPERTY CXX_STANDARD 20)

add_subdirectory("C:/dev/libs/googletest/1.12.1" "build/google_test")
target_link_libraries(my_project_test PRIVATE gtest)

CodePudding user response:

I don't know how to make your setup work, but here is how I use the nlohmann json library in my project:

include(FetchContent)
FetchContent_Declare(
  json
  URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz
  DOWNLOAD_EXTRACT_TIMESTAMP YES  # <- May be needed depending on CMake version
)
FetchContent_MakeAvailable(json)
set(JSON_ImplicitConversions OFF) # <- You can skip this if you want

target_link_libraries(<your target> PRIVATE nlohmann_json::nlohmann_json)

FetchContent downloads, extracts, and compiles the library automatically, and then I just have to target_link_libraries to it.

CodePudding user response:

First of all your usage of add_subdirectory is not recommended, there is a reason why it's called add_subdirectory. That being said this is most likely due to the fact that the targets which you use are not exported and thus not visible to your CMakeLists.txt. REMOVE the build/nlohmann_json you should never include ANY build folder in your build process, if it would create a CMakeLists.txt you would build in circles...

The reason why Frodynes solution will work is because FetchContent_MakeAvailable(json) makes sure that the targets are exported.

What you need to do is use add_library with the IMPORTED tag. So to fix your solution you should most likely do the following to your CMakeLists.txt i.e. import the targets. Also note that I'm using the actual library name and not the alias. It might work with the alias but I'm not 100% sure about it:

set_property(TARGET my_project PROPERTY CXX_STANDARD 20)

add_subdirectory("C:/dev/libs/nlohmann_json/3.11.2") #do not add build folders here
#This doesn't generate a build step (which is already done by the add_subdirectory)
enter code here
add_library(nlohmann_json STATIC IMPORTED)
#OR add_library(nlohmann_json SHARED IMPORTED)
target_link_libraries(my_project PRIVATE nlohmann_json)

########
# OR with the alias:
# add_library(nlohmann_json::nlohmann_json STATIC IMPORTED)
# OR add_library(nlohmann_json::nlohmann_json SHARED IMPORTED)
# target_link_libraries(my_project PRIVATE nlohmann_json::nlohmann_json)
  • Related