CMake: can't find my header file in a different directory - c++

I have a CMake project with these relevant folders:
project_folder
-src
|--main.c
peripherals
|--something.h
|--something.c
My CMake in project_folder includes:
add_subdirectory(peripherals)
if (NOT $ENV{TARGET_SOURCES} STREQUAL "")
target_sources(app PRIVATE $ENV{TARGET_SOURCES})
else()
target_sources(app PRIVATE src/main.c)
endif()
My CMake under peripherals incudes:
add_library (peripherals something.c)
target_include_directories (peripherals PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
CMake under src:
add_executable(app main.c)
target_link_libraries(app PRIVATE peripherals)
My project is building fully but when I try to include my header file in main.c I get:
project_folder/peripherals/something.h:No such file or directory
In my main.c file I have #include "peripherals/something.h". Does anyone know how to fix this? I'm not sure if my #include statement is correct and I think I am missing stuff in my CMakeLists files

You can either do "#include "../peripherals/i2c_test.h" in your main.cpp
OR
in your CMake in project_folder:
target_include_directories(app ${CMAKE_CURRENT_SOURCE_DIR})
and then in main.c:
#include <peripherals/i2c_test.h>
....

You'll need to define executable and "link" it with the library:
# project_folder/CMakeLists.txt
add_subdirectory(peripherals)
add_subdirectory(src)
# project_folder/src/CMakeLists.txt
add_executable(my_executable main.c)
target_link_libraries(my_executable PRIVATE peripherals)
Then, you'll need to include the header in main.c properly- since you've linked against a library that includes peripherals directory, you can now directly include it:
#include "something.h"

Your include statement has to be relative to the included directory.
Edit: In your example ${CMAKE_CURRENT_SOURCE_DIR} is the project directory (where your CMake file is).
Therefore you should be able to write:
#include <peripherals/something.h>
You can always check a cmake variable's content by printing it. In your CMake file you can write:
message(STATUS ${CMAKE_CURRENT_SOURCE_DIR})
When running cmake you should see the path printed in the console output.

in your CMake in project_folder:
include_directories(src)
and then in main.c:
#include <peripherals/i2c_test.h>
OR
in your CMake in project_folder:
include_directories(src/peripherals)
and then in main.c:
#include <i2c_test.h>

Related

cmake : no such file or directory when compiling

using cmake to generate a static libary and link it in main.c. Here is directory hireachy:
├─.vscode
├─bin
└─mymathlib
├─include
├─lib
└─src
└─CMakeLists.txt
├─main.c
├─CMakeLists.txt
in main.c, I include a header file located in mymathlib/include
#include "mymath.h"
but it follows a error : mymath.h : no such file or directory
I use include_directories() in both CMakeLists.txt
CMakeLists(top level)
cmake_minimum_required(VERSION 3.10)
project(CALCULATOR)
include_directories(mymathlib/include)
add_subdirectory(mymathlib)
add_executable(calculator ${PROJECT_SOURCE_DIR}/main.c)
target_link_libraries(calculator myamth)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_compile_options(-Wall -g)
CMakeLists(in /mymathlib)
project(MyMathLib)
include_directories(include)
aux_source_directory(src SRCS)
add_library(mymath STATIC ${SRCS})
set(LIBRARY_OUTPUT_PATH lib)
I think include_directories() is enough for this problem, but it seems not.
How to fix this ? THX :)

CMakeLists include Header File from subdirectories

I am trying to work with CMake for the first time and am struggling to link header files into my main. My cmake directory looks like this:
Project
| CmakeLists.txt
| src
|| CMakeLists.txt
|| Main.cpp
| Libs
|| CMakeLists.txt
|| headers
|||obstacle_detection.hpp
||source
|||obstacle_detection.cpp
|build
||"build files"
I would like to link the files in the headers folder to main, but what I currently have does not appear to work. The following runs the CMake command correctly but fails to compile with the make command, being unable to find the given header file. My CMakeLists files are as follows:
Project:
cmake_minimum_required(VERSION 3.17)
project(Sensivision)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
find_package(OpenCV REQUIRED)
find_package(realsense2 REQUIRED)
find_library(darknet REQUIRED)
add_subdirectory(libs)
add_subdirectory(src)
target_link_libraries(${PROJECT_NAME} obstacle_detection)
Libs:
add_library(
obstacle_detection
headers/obstacle_detection.hpp
sources/obstacle_detection.cpp
)
target_link_directories(obstacle_detection PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
src:
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
target_link_libraries(${PROJECT_NAME} ${realsense2_LIBRARY})
My include in main.cpp is
include <obstacle_detection.hpp>
I have also tried
include <headers/obstacle_detection.hpp>
and
include <obstacle_detection>
Each gives the error:
obstacle_detection.hpp: no such file or directory
What am I doing incorrectly to link the header to the main?
You haven't added any include directories to the obstacle_detection library. By listing the header file in the add_library call, this may allow the header to be displayed in an IDE, but it doesn't do anything for compilation. You should use target_include_directories to add the headers directory as an include directory for the obstacle_detection library. Otherwise, it, and other consuming targets, will have no knowledge of the headers in that directory.
add_library(
obstacle_detection
headers/obstacle_detection.hpp
sources/obstacle_detection.cpp
)
# Add this line.
target_include_directories(obstacle_detection PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/headers)
# Not sure this line is necessary, as it doesn't appear you actually link anything...
target_link_directories(obstacle_detection PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
You haven't shown the CMake code in the src directory, but be sure to link the obstacle_detection library target to the main target, e.g.:
target_link_libraries(MyExeTarget PRIVATE obstacle_detection)
In addition, because this header file is local, it is best if you use quotes to include the header:
#include "obstacle_detection.hpp"
You can use target_include_directories to add folder where your headers are located and #include <header.hpp> where needed.
Ex:
libs cmake:
add_library(
obstacle_detection
headers/obstacle_detection.hpp
sources/obstacle_detection.cpp
)
target_include_directories(obstacle_detection PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
cpp:
#include <headers/obstacle_detection.hpp>

How To Properly Include SDL2 Source Code in Project CMake

I am confused on how to statically include the source code of SDL2. I am trying to do this to make a library I am working on more portable.
Currently, when I try to include my library in another project it says "Cannot open include file: 'SDL2/SDL.h': No such file or directory".
My Filesystem:
include
--Header Files
src
--Source Files
extern
--SDL2
build
Here is an example of the file causing the error:
#include <iostream>
#include <SDL2/SDL.h> //Error
using namespace std;
/* The code */
Here is an example of my main CMakeLists.txt:
cmake_minimum_required(VERSION 3.7)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
project(MyProject VERSION 1.0.0)
set(SDL2_SOURCE_DIR “${CMAKE_SOURCE_DIR}/extern/SDL2”)
add_subdirectory(extern/SDL2)
add_subdirectory(src)
Here is an example of my src CMakeLists.txt:
set(PROJECT_NAME MyProject)
file(GLOB HEADER_FILES "${CMAKE_SOURCE_DIR}/include/*.h")
file(GLOB SOURCES "*.cpp")
add_library(${PROJECT_NAME} ${SOURCES} ${HEADER_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2main SDL2-static)
set_target_properties( ${PROJECT_NAME}
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin"
)
add_subdirectory() will process the subdirectory as a cmake porject (process the provided CMakeLists.txt for SDL). If you read that CMakeLists.txt, you'd see that it add the include directories relative to SDL2_SOURCE_DIR, which is empty by default.
What I would try is to set SDL2_SOURCE_DIR to ${CMAKE_CURRENT_SOURCE_DIR}/extern/SDL2 to make the path absolute. Like that SDL include dirs will be valid everywhere in your project.
You can also manually add the correct includes by using the include_directories() directive.

CMake: Unable to include external library header files in my library's header files that are not included in any source files

I've tried looking for an answer to this question. There are similar questions but none that answer mine.
I am trying to create a library that depends on a couple other external libraries. I have the external libraries as git submodules and compile them myself in CMake using add_subdirectory followed by target_link_library.
After doing that, I am able to use the external libraries and include their header files in any source file in my library that I have added using target_sources and also in any header file that at least one of these source files include.
For example, I have an external library glm and call target_sources(myLib PRIVATE Application.cpp) in my library. The header files in my library are added to the project using target_include_directories.
Now, I can do #include <glm/glm.hpp> in the Application.cpp file with no problems.
I also have an Application.hpp file that is included in the Application.cpp file. Because it is included, that allows me to do #include <glm/glm.hpp> in the Application.hpp file as well.
However, now I also have a Core.hpp file without a corresponding Core.cpp file. Because the Core.hpp file is not included in any source files, doing #include <glm/glm.hpp> throws an error that the file cannot be found.
This is my root CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(Ivory)
set(CMAKE_CXX_STANDARD 20)
add_library(${PROJECT_NAME} SHARED)
# Determine compiler platform (x32 or x64)
math(EXPR PLATFORM_BITS "8*${CMAKE_SIZEOF_VOID_P}")
set(PLATFORM "x${PLATFORM_BITS}")
# Determine target build platform
target_compile_definitions(${PROJECT_NAME}
PUBLIC
IVORY_WINDOWS
PRIVATE
IVORY_BUILD_DLL
)
# Set output directory
set(OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/${CMAKE_SYSTEM_NAME}-${CMAKE_BUILD_TYPE}-${PLATFORM})
# Subdirectories
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(executables)
target_include_directories(${PROJECT_NAME} PUBLIC include)
# External Libraries #
set(BUILD_SHARED_LIBS OFF)
# GLM
add_subdirectory(lib/glm)
target_link_libraries(${PROJECT_NAME} PRIVATE glm)
# GLEW
add_subdirectory(lib/glew)
target_link_libraries(${PROJECT_NAME} PRIVATE libglew_static)
# SFML
add_subdirectory(lib/SFML)
target_link_libraries(${PROJECT_NAME} PRIVATE sfml-window sfml-audio)
# SPDLOG
add_subdirectory(lib/spdlog)
target_link_libraries(${PROJECT_NAME} PRIVATE spdlog)
# MinGW
target_link_libraries(${PROJECT_NAME} PRIVATE -static)
# Output Location
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY})
This is the src CMakeLists.txt:
target_sources(${PROJECT_NAME}
PRIVATE
Application.cpp
)
I am using CLion on Windows 10 with MinGW 7.3 compiler (64 bit).
What am I doing wrong?
If the Core.hpp header is meant to be included by clients and glm headers are called from this header the glm dependency in the target_link_libraries command must be PUBLIC not PRIVATE.
For the CMake documentation see here. For a more detailed explanation of the PUBLIC, PRIVATE, and INTERFACE keywords with examples see here.

cmake link subdirectories together

I have the following folder hieararchy in my QT project and I need to use some classes of the Utility folder in the classes of the ImageProcessing folder.
CMAKE file of Utilities:
file(GLOB Utilities_Files *.cpp *.h *.hpp)
# add component
add_library(Utilities ${Utilities_Files})
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(Utilities ${OpenCV_LIBRARIES})
CMAKE file of ImageProcessing:
file(GLOB ImageProcessing_FILES *.cpp *.h *.hpp)
# add component
add_library(ImageProcessing ${ImageProcessing_FILES})
include_directories(../Utilities)
target_link_libraries(ImageProcessing Utilities)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(ImageProcessing ${OpenCV_LIBRARIES})
when I try to include classes from Utilities in classes of ImageProcessing:
#include "Utilities/className.h"
The compiler always fails.. Not sure why? It seems there is something missed or misunderstood.
Thanks.
Your line include_directories(../Utilities) adds the path ../Utilities to include directories. However, you include Utilities/className.h in the source file which makes the compiler search for files ./Utilities/className.h and ../Utilities/Utilities/className.h.
Remove one of the Utilities in either include_directories or #include.
include_directories(..)
or
#include "className.h"