# The timing for using \`target\_include\_directories\` and \`target\_link\_libraries\`

**URL:** https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711
**Category:** Usage
**Tags:** tool:cmake
**Created:** [December 25, 2023, 2:23am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711 "2023-12-25T02:23:11Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Sea\_Sea](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sea_sea/32/4025_2.png) [@Sea\_Sea](https://discourse.cmake.org/u/Sea_Sea)
#### Post date: [December 25, 2023, 2:23am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/1 "2023-12-25T02:23:11Z")

</div>

According to this project [#include errors detected](https://discourse.cmake.org/t/include-errors-detected/9615)

I want to know the usage timing for `target_include_directories` and `target_link_libraries`

situation 1:  
I build a third party lib.so or lib.dll  
And using it on my project.  
The situation 1 is using the \*.so or \*.dll , and it doesnt use the library include file.  
Because I already use the \*.so or \*.dll.

CMakeList.txt

```auto
find_package(LibDataChannelREQUIRED)
add_executable(iam ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(iam PRIVATE LibDataChannel::LibDataChannel)

```

situation 2:  
If I put the third party source code into my project.  
Maybe I just only use `target_link_libraries` and then I dont build the third party?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 26, 2023, 2:41pm UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/2 "2023-12-26T14:41:36Z")

</div>

> [@Sea\_Sea](#):
>
> then I dont build the third party?

You still need to build it as part of your project. If you do vendor it (i.e., put it in your source tree) consider:

- updating is a manual process
- using `FetchContent` so that other projects wanting to vendor it can coordinate on using a single copy

I’d recommend using `find_package` and the target rather than messing with `target_include_directories`.

---

<div class="post-metadata">

### Author: ![ferdnyc](https://discourse.cmake.org/user_avatar/discourse.cmake.org/ferdnyc/32/267_2.png) [@ferdnyc](https://discourse.cmake.org/u/ferdnyc)
#### Post date: [December 27, 2023, 1:34am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/3 "2023-12-27T01:34:23Z")

</div>

> [@Sea\_Sea](#):
>
> According to this project [#include errors detected](https://discourse.cmake.org/t/include-errors-detected/9615)
> 
> I want to know the usage timing for `target_include_directories` and `target_link_libraries`

Your previous question was about VSCode being able to pick up headers when browsing your project’s code. When you’re in that situation:

1. The library headers _absolutely are_ used — they’re how your downstream code knows the API of the shared library. You can’t use a C/C++ shared library _without_ a header file to define the public API.

2. From a VSCode perspective, what really matters isn’t when, how, or in what form your dependencies are incorporated into the project. What matters is that the `compile_commands.json` file CMake generates contains all of the correct `-I` flags (or `-isystem`) with the paths to your libraries’ header files. VSCode will read the commands in that file to determine where it should look for headers named in `#include` lines.

Any method of getting the include paths into your build commands will work for VSCode. For the purposes of code browsing/editing, it doesn’t matter if the headers are installed somewhere else on the system, inside your own source directory, or generated inside the build directory. (As long as they’re generated during the `cmake` run, so that they exist for the tools to find them!)

Using targets for external dependencies, with the `INTERFACE_INCLUDE_DIRECTORIES` property defined, is **strongly** recommended as the easiest and most maintainable method, for sure. But that’s more important from the perspective of building and maintaining your project code. In terms of what VSCode sees, by the time `cmake` is done those targets are already gone, and all of their properties have been turned into compiler commands.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 27, 2023, 4:48am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/4 "2023-12-27T04:48:43Z")

</div>

@ferdnyc Does VS Code really use `compile_commands.json`, or does it use the CMake file API now?

---

<div class="post-metadata">

### Author: ![Sea\_Sea](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sea_sea/32/4025_2.png) [@Sea\_Sea](https://discourse.cmake.org/u/Sea_Sea)
#### Post date: [December 27, 2023, 5:38am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/5 "2023-12-27T05:38:13Z")

</div>

Thanks everyone give me the detail information.

Is \*.so or \*.dll include the “header files”?

---

<div class="post-metadata">

### Author: ![Sea\_Sea](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sea_sea/32/4025_2.png) [@Sea\_Sea](https://discourse.cmake.org/u/Sea_Sea)
#### Post date: [December 29, 2023, 1:47am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/6 "2023-12-29T01:47:05Z")

</div>

I think I get it.

## For `target_link_libraries`

I have to build the \*.so or \*.dll

```auto
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)

add_executable(test_app ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)

target_link_libraries(test_app PRIVATE nlohmann_json::nlohmann_json)

```

## For `target_include_directories`

I have to put the json.hpp of [Releases · nlohmann/json · GitHub](https://github.com/nlohmann/json/releases)  
into my project.

where ${NLOHMANNJSON\_INCLUDE\_DIRS} is the location for nlohmann\_json on my project.

```auto
# CMakeLists.txt

add_executable(test_app ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_include_directories(test_app PUBLIC 
    ${NLOHMANNJSON_INCLUDE_DIRS}
)

```

## For set TARGET

I have to put the json.hpp of [Releases · nlohmann/json · GitHub](https://github.com/nlohmann/json/releases)  
into my project.

```auto
# CMakeLists.txt

find_path(
	NLOHMANNJSON_INCLUDE_DIRS
	NAMES nlohmann/json.hpp
	PATHS "deps/nlohmann_json/include"
)

if(json_FOUND)
  if(NOT TARGET nlohmann_json::nlohmann_json)
    add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
    set_target_properties(nlohmann_json::nlohmann_json PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${NLOHMANNJSON_INCLUDE_DIRS}")
  endif()
endif()

add_executable(test_app ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(test_app PRIVATE nlohmann_json::nlohmann_json)

```

here is my project structure  
`deps/nlohmann_json/include/nlohmann`

```auto
- project
  - .gitignore
  - README.md
  - LICENSE.md
  - CMakeLists.txt
  - cmake
    - FindSomeLib.cmake
    - something_else.cmake
  - include
    - project
      - lib.hpp
  - src
    - CMakeLists.txt
    - lib.cpp
  - apps
    - CMakeLists.txt
    - app.cpp
  - tests
    - CMakeLists.txt
    - testlib.cpp
  - docs
    - CMakeLists.txt
  - extern
    - googletest
  - scripts
    - helper.py
  - deps
     - nlohmann_json
        - include
            - nlohmann

```

## conclusion

By using the above methods  
I can use the header files

```auto
# main.cpp

#include<iostream>
#include <nlohmann/json.hpp>

int main() {

    nlohmann::json message = {{"id", 1}};
    std::cout << message.dump(4) << std::endl;

}

```

Is it right?

> **[GitHub - nlohmann/json: JSON for Modern C++](https://github.com/nlohmann/json#external)**
>
> JSON for Modern C++

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [December 30, 2023, 12:38am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/7 "2023-12-30T00:38:10Z")

</div>

> [@Sea\_Sea](#):
>
> ```cmake
> target_link_libraries(test_app PRIVATE nlohmann_json::nlohmann_json)
> 
> ```

This should be what you need.

> [@Sea\_Sea](#):
>
> ```cmake
> target_include_directories(test_app PUBLIC 
> ${NLOHMANNJSON_INCLUDE_DIRS}
> )
> 
> ```

You shouldn’t need to do this. If you use `target_link_libraries()` as shown further above, that will add any required header search paths, compiler options, etc. as usage requirements to any target that links to `nlohmann_json::nlohmann_json` (which is `test_app` in this example). As long as you’re not using an old `nlohmann_json` version that predates adding those details to `nlohman_json::nlohmann_json`, you should be fine.

> [@Sea\_Sea](#):
>
> ```cmake
> if(json_FOUND)
> if(NOT TARGET nlohmann_json::nlohmann_json)
> add_library(nlohmann_json::nlohmann_json INTERFACE IMPORTED)
> set_target_properties(nlohmann_json::nlohmann_json PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${NLOHMANNJSON_INCLUDE_DIRS}")
> endif()
> endif()
> 
> ```

Not sure what you’re trying to do here. You shouldn’t be creating this target yourself. You should be using `find_package(nlohmann_json)` instead, which would provide the `nlohmann_json::nlohmann_json` target for you. Alternatively, you could use FetchContent, which would download nlohmann\_json from GitHub and add it directly to your project:

```cmake
include(FetchContent)
FetchContent_Declare(
    nlohmann_json
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG v3.11.3
)
FetchContent_MakeAvailable(nlohmann_json)

```

---

<div class="post-metadata">

### Author: ![Sea\_Sea](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sea_sea/32/4025_2.png) [@Sea\_Sea](https://discourse.cmake.org/u/Sea_Sea)
#### Post date: [December 30, 2023, 1:24am UTC](https://discourse.cmake.org/t/the-timing-for-using-target-include-directories-and-target-link-libraries/9711/8 "2023-12-30T01:24:37Z")

</div>

> [@Sea\_Sea](#):
>
> ## For set TARGET

I fix the content for For set TARGET
