Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
297 views
in Technique[技术] by (71.8m points)

c - CMake and issues with header files in subfolders

I'm trying to set up a project where header files can be found by the subfolder libraries src code as well as the src code in the top level using Cmake. Currently i am getting an error stating that the header file can not be found. The structure of my project looks like this:

root/
    src/           
        CMakeLists.txt     #(top level)  
        main.c     
        lib/
            lib1.c
            CMakeLists.txt     #(lower level)
            headers/
                lib1.h
    build/       

My top level CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 3.13.4)

project(CmakeTUT_Proj) 

add_executable(${PROJECT_NAME} main.c)

target_include_directories(${PROJECT_NAME} PUBLIC Lib/headers/)
                                                          
add_subdirectory(Lib/)

target_link_directories(${PROJECT_NAME} PRIVATE Lib/headers/)

target_link_libraries(${PROJECT_NAME} name_of_lib) 

My lower level CMakeLists.txt looks like:

add_library(name_of_lib  adder.c)

My main.c and my lib1.c programs include the library as #include "lib1.h", cmake runs fine without any errors but when i build the project with make i get an error like:

root/src/Lib/lib1.c:2:10: fatal error: lib1.h: No such file or directory
#include "lib1.h"

I want to structure my project so that main.c and lib1.c have access to lib1.h. Any ideas? Thank you.

question from:https://stackoverflow.com/questions/65559831/cmake-and-issues-with-header-files-in-subfolders

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As the name implies, target_include_directories only affects one target. So when you set target_include_directories(${PROJECT_NAME} PUBLIC Lib/headers/), this adds to the include path for the executable target named ${PROJECT_NAME} but not to the include path for the library name_of_lib.

To fix this, you can add the include path for your library in the lower level CMakeLists.txt:

target_include_directories(name_of_lib PUBLIC headers)

As a bonus, because it's PUBLIC, this path is also automatically added to any target that depends on name_of_lib. So in the top-level CMakeLists.txt, you can remove this line:

target_include_directories(${PROJECT_NAME} PUBLIC Lib/headers/)

Aside, this line looks useless and can probably be removed as well:

target_link_directories(${PROJECT_NAME} PRIVATE Lib/headers/)

Link libraries are not usually placed in headers directories.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...