CMake with include and source paths - basic setup - c++

I'm trying to set up a test project looking like my own project just to get things working first and it looks like this:
/MainProject/inc/main.h
/MainProject/src/main.cpp
/LibProject/inc/test.h
/LibProject/src/test.cpp
I've found some tutorials, but I cant find out how to set up this when I have the inc and src folder? How would the CMakeLists.txt files look? Would I have one in /, one in each of the project folders? It seems like I dont need to have one in the inc and src folders?

You need a CMakeLists.txt for each source subdirectory. Your structure should look something like this:
root
|-MainProject
| |-inc
| | '-main.h
| |-src
| | |-main.cpp
| | '-CMakeLists.txt
| '-CMakeLists.txt
|-LibProject
| |-inc
| | '-test.h
| |-src
| | |-test.cpp
| | '-CMakeLists.txt
| '-CMakeLists.txt
'-CMakeLists.txt
Content of root/CMakeLists.txt:
project(MyProject)
add_subdirectory(MainProject)
add_subdirectory(LibProject)
Content of LibProject/CMakeLists.txt and MainProject/CMakeLists.txt:
add_subdirectory(src)
Content of LibProject/src/CMakeLists.txt:
# Notice name prefix of this variable, set by CMake according
# to value given with "project()" in the root CMakeLists.txt.
include_directories(${MyProject_SOURCE_DIR}/LibProject/inc)
add_library(LibProject test.cpp)
Content of MainProject/src/CMakeLists.txt:
include_directories(${MyProject_SOURCE_DIR}/MainProject/inc)
# I assume you want to use LibProject as a library in MainProject.
include_directories(${MyProject_SOURCE_DIR}/LibProject/inc)
link_directories(${MyProject_SOURCE_DIR}/LibProject/src)
add_executable(MainProject main.cpp)
target_link_libraries(MainProject LibProject)
Then configure and build with:
$ cd root
$ mkdir build
$ cd build
$ cmake ..
$ make

You could do it like following.
CMakeLists.txt in your MainProject directory:
project(MainProject)
add_subdirectory(LibProject/src)
add_subdirectory(MainProject/src)
CMakeLists.txt in your LibProject/src directory:
include_directories(${PROJECT_SOURCE_DIR}/LibProject/inc/)
add_library(LibProject test.cpp)
CMakeLists.txt in your MainProject/src directory:
include_directories(${PROJECT_SOURCE_DIR}/MainProject/inc/)
add_executable(MainProject main.cpp)
target_link_libraries(MainProject LibProject)

In my case I wanted to do it with a single CMakeList. And it worked for me. I add my solution in case it serves to anyone.
This is what I did in my case:
My structure:
Project
|CMakeLists.txt
|-src
| |*.cpp
| |*.c
|-include
| |*.hpp
| |*.h
My CMakeLists.txt have to main parts:
include_directories(
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/src
)
^ Enables .cpp files to add headers in the include folder.
file(GLOB all_SRCS
"${PROJECT_SOURCE_DIR}/include/*.h"
"${PROJECT_SOURCE_DIR}/include/*.hpp"
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.c"
)
^ Just add whatever is in those folders.
add_executable(MyTarget ${all_SRCS})
^ Build the target from the list of all sources
PS: if you want to see the full CMakeLists.txt go the the project link NEGU93/ForbiddenDesert.

Related

Create CMakeLists library with subdirectory sources

project
|
|----- src <-- Needs to be a library
| |
| |--- dir1 <-- Need not create a library
| | |--- dir1_1.cpp
| | |--- dir1_2.cpp
| | |--- CMakeLists.txt
| |
| |
| | --- dir2 <-- has an executable for testing and needs to be a library
| | |--- dir2.cpp
| | |--- dir2.h
| | |--- CMakeLists.txt
| |
| |
| | --- CMakeLists.txt
|
|
|
|----- CMakeLists.txt
How do I create CMakeLists in src such that it includes files from dir1 and dir2, such that only dir2 is a sub-project. I want to use add_subdirectory in src/CMakeLists.txt to add source files from dir1 and dir2. This way it will be easier to add more folders in the future.
I saw the use of PARENT_SCOPE but it also has some drawbacks. Is there a better solution? Maybe by using target_sources or something?
First of all, you should reconsider not making those subdirs self-contained modules, as modularity helps keep your projects cleaned.
Having said that, you can include in any variable defined in ./src/CMakeLists.txt any variable that's defined by ./src/dir1/CMakeLists.txt or ./src/dir2/CMakeLists.txt. Here's an example:
Here are the contents of ./src/dir1/CMakeLists.txt:
set(dir1_SOURCES
dir1/dir1_1.cpp
dir1/dir1_2.cpp
)
Here are the contents of ./src/CMakeLists.txt:
add_subdirectory(dir1)
set(src_SOURCES
${dir1_SOURCES}
)
You can create a library, then later add its source files in a subdirectory using target_sources. This gives you the flexibility to add more sources to MyLib or add more sub-projects later on, via additional calls to add_subdirectory.
It might look something like this:
src/CMakeLists.txt:
# Create a library
add_library(MyLib SHARED)
# Traverse to the 'dir1' subdirectory to populate the sources for MyLib.
add_subdirectory(dir1)
# Traverse to 'dir2' to create a sub-project.
add_subdirectory(dir2)
dir1/src/CMakeLists.txt:
target_sources(MyLib PUBLIC
dir1_1.cpp
dir1_2.cpp
)
# Add any headers from this directory.
target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
dir2/src/CMakeLists.txt:
project(MySubProject)
add_library(MyLib2 SHARED
dir2.cpp
)
# Add any headers from this directory.
target_include_directories(MyLib2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_executable(MyExe ...)
...

Share files between multiple groups under CMake

I`m trying to create a CMake setup for a project with the following structure:
workshop
| CMakeLists.txt
| utilities
| | utilities.h
| | utilities.cpp
| | CMakeLists.txt
| week_1
| | week_1.h
| | week_1.cpp
| | main.cpp
| | CMakeLists.txt
| week_2
| | main.h
| | week_2.cpp
| | main.cpp
| | CMakeLists.txt
Everything depends on OpenCV and the programs in week_X depend also on utilities.
I was able to do everything except the connection with utilities.
My trial:
File workshop\CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
PROJECT(workshop)
SET(OpenCV_DIR OPENCV_DIR)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS})
add_subdirectory(${CMAKE_SOURCE_DIR}/utilities)
add_subdirectory(${CMAKE_SOURCE_DIR}/week_1)
add_subdirectory(${CMAKE_SOURCE_DIR}/week_2)
File week_1\CMakeLists.txt (week_2\CMakeLists.txt is identical just changing 1 by 2)
cmake_minimum_required(VERSION 2.8.12)
include_directories( ${OpenCV_INCLUDE_DIRS})
set(SRCFILES week_1.cpp week_1.h main.cpp)
source_group(week_1 FILES ${SRCFILES})
add_executable(week_1 ${SRCFILES})
target_link_libraries(week_1 ${OpenCV_LIBS})
All is okay until the utilities. How would be the utilities\CMakeLists.txt?
I think you want utilities to be a library.
In the utilities CMakeLists.txt
# This will create libutilities.a
add_library(utilities
utilities.cpp
)
target_include_directories( utilities PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
# Third party libs
${OpenCV_INCLUDE_DIRS}
)
target_link_libraries(utilities
${OpenCV_LIBRARIES}
)
In week_X you'll use it as a library like so:
include_directories(
${OpenCV_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/utilities # Include utilities header
)
set(SRCFILES week_1.cpp week_1.h main.cpp)
source_group(week_1 FILES ${SRCFILES})
add_executable(week_1 ${SRCFILES})
target_link_libraries(
${OpenCV_LIBS}
utilities # Link to libutilites.a
)

Some headers-only files in my project cannot include "SFML/Graphics.hpp" using CMake and Vscode

I'm new to C++ and CMake and started a big project. Im using VScode as my text editor and CMake as my build tool.
The problem is that i can include "SFML/Graphics.hpp in all my header files that has a source file with the same name, but in header-only files if i include "SFML/Graphics.hpp" or any other file that include "SFML/Graphics" cmake won't build and returns an error.
Here's is my code
Project Directory Tree
Game|> (root)
|- CMakeLists.txt
|> include
| |- BaseComponent.hpp (Header-only)
| |- TransformComponent.hpp (Header-only)
| |- CombatComponent.hpp (Header-only)
| |- MovementComponent.hpp (Header-only)
| |- Constants.hpp (Header-only)
| |- TimeUtils.hpp (Header-only)
| |- EcsManager.hpp
| |- EntityManager.hpp
| |- Game.hpp
| |- GameContext.hpp (Header-only)
| |- Scene.hpp (Header-only)
| |- GameScene.hpp
| |- System.hpp
| |- Input.hpp
| |- MovementSystem.hpp
| |- RenderableSystem.hpp
|> src
| |- CMakeLists.txt
| |- main.cpp
| |- Game.cpp
| |- EntityManager.cpp
| |- SceneManager.cpp
| |- Input.cpp
| |- GameScene.cpp
| |> Ecs
| |- CMakeLists.txt
| |- EcsManager.cpp
| |- System.cpp
| |> Systems
| |- CMakeLists.txt
| |- MovementSystem.cpp
| |- RenderableSystem.cpp
|
|> bin
|> build
CMakeLists.txt - Root
project(RPG)
set(CMAKE_TOOLCHAIN_FILE
"C:/Users/dante/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")
set(SOURCES src/EntityManager.cpp src/Game.cpp src/GameScene.cpp
src/main.cpp src/SceneManager.cpp src/Input.cpp)
include_directories("${PROJECT_SOURCE_DIR}/include")
add_subdirectory(src)
find_package(SFML 2.5.1 COMPONENTS REQUIRED graphics window system network
audio)
find_package(nlohmann_json 3.2.0 REQUIRED)
add_executable(RPG ${SOURCES})
target_link_libraries(RPG sfml-graphics sfml-window sfml-system sfml-
network sfml-audio)
target_link_libraries(RPG nlohmann_json::nlohmann_json)
target_link_libraries(RPG ECS)
CMakeLists.txt - src
add_subdirectory(Ecs)
CMakeLists.txt - Ecs
add_subdirectory(Systems)
add_library(ECS EcsManager.cpp System.cpp )
target_link_libraries(ECS ECS_SYSTEMS)
CMakeLists.txt - Systems
add_library(ECS_SYSTEMS MovementSystem.cpp RenderableSystem.cpp)
The erro that Cmake outputs is : 'SFML/Graphics.hpp': No such file or directory MSVC(C1083)
If i include "SFML/Graphics.hpp" in any "Any"Component Class it gives error
If i include "SFML/Graphics.hpp" in a .hpp file that have a .cpp file associated with it and include that class in "Any"Component Class (or any other header-only) it gives error.
I can't find any solution to that in stackoverflow.
Don't judge my folder structure it was different when the error first came up... than i changed to that to see if the CMake would build.
You need to add the SFML include directory to the list of include directories.
After
find_package(SFML 2.5.1 COMPONENTS REQUIRED graphics window system network audio)
add the line
include_directories(${SFML_INCLUDE_DIR})

CMakeLists for large project with multiple directories?

I am writing a Game Engine, which is going very well. But I am running into a problem where my CMakeLists.txt is just too messy, and I don't know enough about CMake. My project uses multiple (CMake) libraries, which are added using add_subdirectory and then target_link_libraries. My project consists of the Engine(executable), the Editor(library), and some tests/examples. Here is my file structure:
C:.
| CMakeLists.txt
| tree.txt
|
+---Editor
| | README.md
| |
| \---src
| main.cpp
|
+---Engine
| | README.md
| |
| +---src
| | | main.cpp
| | |
| | +---API
| | | Core.h
| | |
| | +---App
| | | Application.cpp
| | |
| | +---ExtApp
| | | | AppInterface.cpp
| | | |
| | | +---Engine
| | | | ExtAppLoader.cpp
| | | |
| | | \---Game
| | | InfoExport.cpp
| | |
| | +---Framework
| | | Asset.cpp
| | |
| | +---Managing
| | | AssetLoader.cpp
| | |
| | +---Rendering
| | | | Renderer.cpp
| | | |
| | | \---Renderables
| | | Canvas2DRenderable.cpp
| | |
| | \---Types
| | Vector3f.cpp
| |
| \---TestResources
| \---Shaders
| Canvas2DTexturedTriangle.f
| Canvas2DTexturedTriangle.v
| Canvas2DUntexturedTriangle.f
| Canvas2DUntexturedTriangle.v
| ImTest.f
| ImTest.v
|
+---Libraries
| +---glfw
| | CMakeLists.txt
| |
| \---glm
| CMakeLists.txt
|
\---Tests
\---TestGame
\---src
main.cpp
As you can see I have one CMakeLists at the begin, which loads all the projects. Then I have libraries, which have a CMakeLists too. Every directory has only one file to make the tree less big, but there are multiple fies in a directory. Also, here is my current, messy, almost-useless CMakeLists file:
cmake_minimum_required(VERSION 3.6)
#project(3DEngine)
add_subdirectory(Libraries/glfw) #Add glfw to the project
# Make sure we're running C++17 so all features(like std::filesystem) are present.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(BUILD_ENGINE_FOR_EDITOR "Build the engine as DLL/SO for the editor and add editor specific things. Otherwise build engine as game exec" OFF)
option(BUILD_ENGINE_FOR_DLL_APPS "Have the Engine load the game(and plugins) from dll's." ON)
project (Engine)#project engine
include_directories(Libraries/whereami/src)
include_directories(Engine/src/)
include_directories(Libraries/glfw/include)
include_directories(Libraries/glm)
include_directories(Libraries/glad/include)
include_directories(Libraries/stb)
file(GLOB EngineRootSOURCES "Engine/src/*.cpp" "Engine/src/*.h")
file(GLOB EngineRenderingSOURCES "Engine/src/Rendering/*.cpp" "Engine/src/Rendering/*.h")
file(GLOB EngineAppSOURCES "Engine/src/App/*.cpp" "Engine/src/App/*.h")
file(GLOB EngineRenderingRenderablesSOURCES "Engine/src/Rendering/Renderables/*.cpp" "Engine/src/Rendering/Renderables/*.h")
file(GLOB EngineManagingSOURCES "Engine/src/Managing/*.cpp" "Engine/src/Managing/*.h")
file(GLOB EngineTypesSOURCES "Engine/src/Types/*.cpp" "Engine/src/Types/*.h")
file(GLOB EngineGameEssentialsSOURCES "Engine/src/GameEssentials/*.cpp" "Engine/src/GameEssentials/*.h")
file(GLOB EngineLibsSOURCES "Libraries/whereami/src/whereami.c" "Libraries/glad/src/glad.c")
file(GLOB EngineFrameworkSOURCES "Engine/src/Framework/*.h" "Engine/src/Framework/*.cpp")
file(GLOB APISOURCES "Engine/src/API/*.cpp" "Engine/src/API/*.h")
file(GLOB EngineExtAppSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
"Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")
file(GLOB EngineExtAppGameSOURCES "Engine/src/ExtApp/Game/*.cpp" "Engine/src/ExtApp/Game/*.h")
source_group("ExtApp" FILES ${EngineExtAppGameSOURCES})
file(GLOB EngineExtAppEngineSOURCES "Engine/src/ExtApp/Engine/*.cpp" "Engine/src/ExtApp/Engine/*.h")
source_group("ExtApp" FILES ${EngineExtAppEngineSOURCES})
if(BUILD_ENGINE_FOR_EDITOR)
file(GLOB EngineEditorSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
"Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")
if(BUILD_ENGINE_FOR_DLL_APPS)
add_library(Engine SHARED ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineEditorSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
source_group("ExtApp" FILES ${EngineExtAppSOURCES})
elseif(NOT BUILD_ENGINE_FOR_DLL_APPS)
add_library(Engine SHARED ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineEditorSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
endif()
target_link_libraries(Engine glfw)
source_group("Rendering" FILES ${EngineRenderingSOURCES})
source_group("Rendering/Renderables" FILES ${EngineRenderingRenderablesSOURCES})
source_group("Managing" FILES ${EngineManagingSOURCES})
source_group("App" FILES ${EngineAppSOURCES})
source_group("Types" FILES ${EngineTypesSOURCES})
source_group("GameEssentials" FILES ${EngineGameEssentialsSOURCES})
source_group("Libs" FILES ${EngineLibsSOURCES})
source_group("ExtApp" FILES ${EngineEditorSOURCES})
source_group("API" FILES ${APISOURCES})
source_group("Framework" FILES ${EngineFrameworkSOURCES})
elseif(NOT BUILD_ENGINE_FOR_EDITOR)
if(BUILD_ENGINE_FOR_DLL_APPS)
file(GLOB EngineExtAppSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
"Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")
add_executable(Engine ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
source_group("ExtApp" FILES ${EngineExtAppSOURCES})
elseif(NOT BUILD_ENGINE_FOR_DLL_APPS)
add_executable(Engine ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
endif()
target_link_libraries(Engine glfw)
source_group("Rendering" FILES ${EngineRenderingSOURCES})
source_group("Rendering/Renderables" FILES ${EngineRenderingRenderablesSOURCES})
source_group("Managing" FILES ${EngineManagingSOURCES})
source_group("App" FILES ${EngineAppSOURCES})
source_group("Types" FILES ${EngineTypesSOURCES})
source_group("GameEssentials" FILES ${EngineGameEssentialsSOURCES})
source_group("Libs" FILES ${EngineLibsSOURCES})
source_group("API" FILES ${APISOURCES})
source_group("Framework" FILES ${EngineFrameworkSOURCES})
endif()
#add_library(Engine SHARED ${EngineSOURCES})
## END project engine
project (Module_OpenGL_Renderer_Input)#project module_renderer_opengl3
include_directories(Libraries/glfw/include)
include_directories(Libraries/glm)
include_directories(Libraries/glad/include)
include_directories(Libraries/stb)
file(GLOB Module_OpenGL_Renderer_InputSOURCES "Modules/Module_OpenGL_Renderer_Input/src/*.cpp" "Modules/Module_OpenGL_Renderer_Input/src/*.h" "Libraries/glad/src/glad.c")
add_library(Module_OpenGL_Renderer_Input SHARED ${Module_OpenGL_Renderer_InputSOURCES})
target_link_libraries(glfw)
##END project module_renderer_opengl3
project (Test1)#project test | This project is used to test the engine functionality.
include_directories(Libraries/imgui)
file(GLOB Test1SOURCES "Tests/Test1/src/*.cpp" "Tests/Test1/src/*.h" "Libraries/imgui/imgui*.cpp" ${APISOURCES})
add_executable(Test1 ${Test1SOURCES})
target_link_libraries(Test1 ${CMAKE_DL_LIBS})
project (TestGame)#project test | This project is used to test the engine functionality.
include_directories(Libraries/imgui)
file(GLOB TestGameSOURCES "Tests/TestGame/src/*.cpp" "Tests/TestGame/src/*.h" "Libraries/imgui/imgui*.cpp" ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppSOURCES} ${EngineExtAppGameSOURCES} ${EngineFrameworkSOURCES})
add_library(TestGame SHARED ${TestGameSOURCES})
target_link_libraries(TestGame glfw)
project (Editor)#project editor | This is used to make projects and build projects(using the engine)
include_directories(Libraries/imgui)
file(GLOB EditorSOURCES "Editor/src/*.cpp" "Editor/src/*.h" "Libraries/imgui/imgui*.cpp" ${APISOURCES})
add_executable(Editor ${EditorSOURCES})
I contains lot's of things that are completely useless, or not needed anymore.
So here are my questions:
Does every directory NEED a CMakeLists file, like I see in a lot of projects?
Do I need to provide every directory containing source files, or can I have it search automatically for source and header files in directories?
I also see that a lot of other CMake projects provide each source/header file seperately, why? Isn't that a lot of work every time you add a file?
Does anyone have examples of large CMake projects that I can use as a guide?
Is there ANYTHING else I can improve?
Thanks!
Does every directory NEED a CMakeLists file
No, that is not necessary.
It's probably a good idea to have a CMakeLists.txt for each submodule and library - and one in the root for the project itself.
Do I need to provide every directory containing source files, or can I have it search automatically for source and header files in directories?
Firstly, see the answer to your question 3.
Secondly, I don't see why you'd want to search for header files. Simply specify the include directories.
Finally, if you want to use globbing, it is possible to put all your source files under a single directory, and use a single glob.
I also see that a lot of other CMake projects provide each source ... file seperately, why?
This is what the docs say:
Note
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate. The CONFIGURE_DEPENDS flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even if CONFIGURE_DEPENDS works reliably, there is still a cost to perform the check on every rebuild.
... each header file separately, why?
I've never seen this.
Is there ANYTHING else I can improve?
Use target_include_directories instead of include_directories. In general, always use target_X directives.

CMake: Why is an added_subdirectory not visible to other subdirectories

I have the following project structure:
project
- CMakeLists.txt
- src
- LibA
- CMakeLists.txt
- LibB
- CMakeLists.txt
The root CMakeLists.txt looks kind of like this:
add_subdirectory(LibA)
add_subdirectory(LibB)
add_executable(foo src/main.cpp)
target_link_libraries(foo LibA LibB)
However, LibB actually wants to use some functionality from LibA as well. However, I cannot access LibA from within LibB. But I can't add it as a subdirectory either. This is a real problem for me. How can I best solve it?
Thanks in advance.
The solution is a bit complex to tell, but I wish to explain it in a simplified way...
The project structure should be:
/src
|
+-- /lib-a
| +-- /includes
| +-- /sources
| +-- LibAConfig.cmake
| \-- CMakeLists.txt
+-- /lib-b
| +-- /includes
| +-- /sources
| +-- LibBConfig.cmake
| \-- CMakeLists.txt
\-- /main
| +-- /includes
| +-- /sources
| \-- CMakeLists.txt
\-- CMakeLists.txt
/src/lib-a/LibAConfig.cmake should be:
# Debug
MESSAGE ("-- Library A configuration...")
# Headers
include_directories(${CMAKE_CURRENT_LIST_DIR}/includes)
/src/lib-a/CMakeLists.txt should be:
# Define project
project(LibA CXX)
# Debug
message("-- Working on \"${CMAKE_CURRENT_SOURCE_DIR}\"...")
# Package registration
set(LibA_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
# Project files
include_directories(includes)
file(GLOB _SOURCES sources/*.cpp)
# Go on with your module setup...
/src/lib-b/LibBConfig.cmake should be:
# Debug
MESSAGE ("-- Library B configuration...")
# Headers
include_directories(${CMAKE_CURRENT_LIST_DIR}/includes)
/src/lib-b/CMakeLists.txt should be:
# Define project
project(LibB CXX)
# Debug
message("-- Working on \"${CMAKE_CURRENT_SOURCE_DIR}\"...")
# Package registration
set(LibB_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
# Project files
include_directories(includes)
file(GLOB _SOURCES sources/*.cpp)
# Reference/Link to LIB-A
find_package(LibA)
# Go on with your module setup...
/src/main/CMakeLists.txt should be:
# Define project
project(MainApp CXX)
# Debug
message("-- Working on \"${CMAKE_CURRENT_SOURCE_DIR}\"...")
# Project files
include_directories(includes)
file(GLOB _SOURCES sources/*.cpp)
# Reference/Link to LIB-A and LIB-B
find_package(LibA)
find_package(LibB)
# Go on with your module setup...
/src/CMakeLists.txt should be:
# Define project
project(MyProject CXX)
# Debug
message("-- Working on \"${CMAKE_CURRENT_SOURCE_DIR}\"...")
add_subdirectory(lib-a)
add_subdirectory(lib-b)
add_subdirectory(main)
# Go on with your module setup...
I have taken the above example from a project of mine...