My Situation
I`m trying to set up a project structure and the build scripts using cmake but I get an error that my application is unable to find the header file that I try to include.
I hope that someone can guide me to a solution for this.
Current project
The project ist just an example reduced to one application and one library project. The goal is to have multiple clients and more than one library (some depending on each other).
clients/Desktop e.g. is an application making use of the core/ library.
The image shows the project structure (screenshot from Visual Studio Code explorer)

Having a folder named like the project in the include folder is to change the includes from Core.h to Core/Core.h. Or at least this was the plan. Maybe this is the problem?
Okay, so now the code:
clients\Desktop\src\main.cpp:
#include "Core/Core.h" #include <iostream> int main(int argc, char* argv[]) { ProjectStructure::Core::Example ex; ex.sayHello(); } Core\include\Core\Core.h:
#ifndef PROJECTSTRUCTURE_CORE_CORE_H #define PROJECTSTRUCTURE_CORE_CORE_H #include <iostream> namespace ProjectStructure { namespace Core { class Example { public: void sayHello(); }; } // namespace Core } // namespace ProjectStructure #endif Core\src\Core.cpp:
#include "Core/Core.h" namespace ProjectStructure { namespace Core { void Example::sayHello() { std::cout << "Hello world."; } } // namespace Core } // namespace ProjectStructure clients\Desktop\include\CMakeLists.txt:
ADD_SUBDIRECTORY("Desktop") clients\Desktop\src\CMakeLists.txt:
SET(APP_HEADERS ) SET(APP_SOURCES "main.cpp" ) # Make executable ADD_EXECUTABLE("${PROJECT_NAME}" "${APP_SOURCES}") TARGET_LINK_LIBRARIES("${PROJECT_NAME}" "Core") clients\Desktop\CMakeLists.txt:
# Version check cmake_minimum_required(VERSION 3.5) # Project PROJECT("Desktop" CXX) INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include") ADD_SUBDIRECTORY("include") ADD_SUBDIRECTORY("src") ADD_SUBDIRECTORY("test") clients\CMakeLists.txt:
# Executables ADD_SUBDIRECTORY("${PROJECTSTRUCTURE_CLIENTS_DIR}/Desktop") Core\include\CMakeLists.txt:
ADD_SUBDIRECTORY("Core") Core\src\CMakeLists.txt:
SET(LIB_HEADERS "../include/Core/Core.h" ) SET(LIB_SOURCES "Core.cpp" ) # Make library ADD_LIBRARY("${PROJECT_NAME}" STATIC "${LIB_SOURCES}") SET_TARGET_PROPERTIES("${PROJECT_NAME}" PROPERTIES FRAMEWORK FALSE PUBLIC_HEADER "${LIB_HEADERS}" ) INSTALL(TARGETS "${PROJECT_NAME}" EXPORT "${PROJECT_NAME}Targets" ARCHIVE DESTINATION lib COMPONENT libs RUNTIME DESTINATION bin COMPONENT libs LIBRARY DESTINATION lib COMPONENT libs PUBLIC_HEADER DESTINATION include/${PROJECT_NAME} COMPONENT devel INCLUDES DESTINATION include ) Core\CMakeLists.txt:
# Version check CMAKE_MINIMUM_REQUIRED(VERSION 3.5) # Project PROJECT("Core" CXX) INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include") ADD_SUBDIRECTORY("include") ADD_SUBDIRECTORY("src") ADD_SUBDIRECTORY("test") And last but not least the top level CMakeLists.txt:
# Version check CMAKE_MINIMUM_REQUIRED(VERSION 3.5) # Project PROJECT("ProjectStructure" CXX) # Status MESSAGE(STATUS "Cmake running...") MESSAGE(STATUS "System: ${CMAKE_SYSTEM}") MESSAGE(STATUS "System: ${CMAKE_SYSTEM_PROCESSOR}") MESSAGE(STATUS "Cmake-Version: ${CMAKE_VERSION}") MESSAGE(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER}") # Project structure SET(CMAKE_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/include") SET(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/build") SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}") SET(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}") SET(PROJECTSTRUCTURE_CLIENTS_DIR "${CMAKE_SOURCE_DIR}/clients") # Prohibit in source builds IF("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") MESSAGE(SEND_ERROR "In-source builds are not allowed. Remove generated files.") ENDIF() # Output settings SET(CMAKE_VERBOSE_MAKEFILE ON) SET(CMAKE_COLOR_MAKEFILE ON) # Build mode SET(CMAKE_BUILD_TYPE Debug) # Dev #SET(CMAKE_BUILD_TYPE RelWithDebInfo) # Test #SET(CMAKE_BUILD_TYPE Release) # Release # Used features SET(CMAKE_CXX_STANDARD 14) # -std=c++14 SET(CMAKE_CXX_STANDARD_REQUIRED ON) # Compiler flags SET(CMAKE_CXX_FLAGS "-Wall -Wextra") SET(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0") # Dev SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3") # Test SET(CMAKE_CXX_FLAGS_RELEASE "-O3") # Release # Libraries ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/core") # Executables ADD_SUBDIRECTORY("${PROJECTSTRUCTURE_CLIENTS_DIR}") I'm using out of source builds using the following commands:
cd build cmake .. -G "MSYS Makefiles" And then run using:
make Note: The real project is also containing directories for documentation and some other things. Also files like .gitignore and a .travis.yml (but that is the next thing I have to get working).
The problem:
The cmakecommand is working but the makecommand tells me that the included file (Core.h) could not be found.
I think the problem is in the part where the library gets installed. But I was unable to find the right way to do it. The solution I posted here is only one from many that I tried.
Additional questions:
1. The CMakeLists marked with an A are empty. They where just added so that every directory has a CMakeLists file. Should i remove them?
2. I would like to use google-test/mock in my projects with tests for each project in the project/test folder. I it enough to include google test in the top level CMakeLists to make this work or do I have to include it in each sub project?
3. Is it good practice to list the source files or to automatically load them? I think listing them is better even if it is more work. I think this has also advantages for cmake when reloading the project. Is this also true for tests? I am thinking about making a test file for each source file.