Reputation: 316
I have a project with structure like this:
project/
├─ src/
│ ├─ main.cpp
│ ├─ CMakeLists.txt
├─ lib/
│ ├─ libapi.so
├─ CMakeLists.txt
├─ dep/
│ ├─ api/
│ │ ├─ api_types.h
In the main CMakeLists I have:
add_subdirectory(dep)
add_executable("my_${PROJECT_NAME}")
add_subdirectory(src)
And in CMakeLists inside src
folder:
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_library(api SHARED IMPORTED)
set_property(TARGET api PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/lib/libapi.so")
target_sources("my_${PROJECT_NAME}" PRIVATE main.cpp)
In main.cpp I do #include <api_types.h>
but I get this error during compile:
api_types.h: No such file or directory
How can I fix it?
Upvotes: 0
Views: 111
Reputation: 9008
First - add_subdirectory
in fact just looks for CMakeLists.txt
in
the specified directory to apply the sub-set of the rules to the
parent project. If the specified folder doesn't contain any
CMakeLists.txt
this command does nothing (i.e. the command
add_subdirectory(dep)
).
Second - target_include_directories
expects a target object to link against (not the project name). Assuming ${PROJECT_NAME}
is not a name of any of your targets (and the code given in the question reveals only two targets my_${PROJECT_NAME}
and api
) the command target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
does nothing sensible.
Last - you don't specify path to your actual headers anywhere. CMAKE_CURRENT_SOURCE_DIR
refers to the current folder CMakeLists.txt is located in. You should specify path to the folder the headers are located in.
Putting all the said info together, the desired content for the top-level CMakeLists.txt should be something like that:
cmake_minimum_required(VERSION 3.20)
set(PROJECT_NAME Hello)
project(${PROJECT_NAME})
add_executable(my_${PROJECT_NAME})
add_subdirectory(src)
And for src's file it's apparently something like that:
target_include_directories(my_${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/dep/api)
target_sources(my_${PROJECT_NAME} PRIVATE main.cpp)
This solution, however, doesn't resolve another mistake in your code - the CMake files you provided don't link the library itself to the executable target. However this is not the question asked, and with respect to the members of the community, I suggest referring to answers to another related question here.
Upvotes: 1
Reputation: 91
target_include_directories
requires your executable as target, in this case my_${PROJECT_NAME}
.
You can try
target_include_directories(my_${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
As alternative I would recommend following structure
project/
├─ src/
│ ├─ main.cpp
├─ lib/
│ ├─ libapi.so
├─ CMakeLists.txt
├─ include/
│ ├─ api/
│ │ ├─ api_types.h
with following CMakeList.txt
add_executable(my_${PROJECT_NAME} src/main.cpp)
target_include_directories(my_${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
link_directories(${CMAKE_SOURCE_DIR}/lib)
target_link_libraries(my_${PROJECT_NAME} libapi)
Upvotes: 0