Create CMakeLists library with subdirectory sources - c++

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 ...)
...

Related

How to create make file for template library in c++?

I am new to makefile concept and I Having this template library how can i create makefile to install this library on system, can i create makefile for template library.
Source code Folder structure(omitted some files):
artlib - c++
|
|--- include
| |
| |--- artlib.hpp
|
|--- source
|
|---- anixt
| |
| |--- anixt_config.hpp
| |--- anixt_font.hpp
| |--- anixt_style.hpp
| |--- basic_anixt.hpp
|
|---- runeape
|
|--- basic_runeape.hpp
|--- runeape_config.hpp
|--- runeape_gallery.hpp
|--- runeape_style.hpp
|-------- third_party/json/json.hpp
Now, How to install this files and artlib.hpp file includes all other file and have some type alias and some functions. I am currently build test
code by -I option in g++ and include artlib.hpp in source file
All suggestions are welcome,
Thanks in advance.
Here's a makefile to install a file template.h into /usr/local/include:
FILES := template.h
DESTDIR := /usr/local/include
INSTALLEDFILES := $(addprefix $(DESTDIR)/,$(FILES))
all: $(INSTALLEDFILES)
$(DESTDIR)/%: %
mkdir -p $(#D)
cp $< $#
Since you've not given us any actual details about what you want to do, that's about all we can say.

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})

How to Create Packages with CMake

.
+-- MyPack
| +-- Lib1
| | +-- include
| | | +-- Lib1.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- Lib2
| | +-- include
| | | +-- Lib2.h
| | +-- src
| | | +-- Lib2.cpp
| | +-- CMakeLists.txt
| +-- CMakeLists.txt
+-- SubProject1
| +-- CMakeLists.txt
+-- SubProject2
| +-- CMakeLists.txt
+-- CMakeLists.txt
Hi all.
I'm new to CMake and I'm trying to obtain something like the following.
Considering the above directory tree of my C++ project:
I have a directory (let's say "MyPack") that contains several subdirectories (Lib1, Lib2...) and each one represents a C++ Library that I wrote.
How can I setup everything so I can write find_package(MyPack)in the other subprojects?
Every subproject is a stand-alone project, and does not depend on other subprojects, but just on libraries in "MyPack".
Your drawing is a bit confusing because there is a CMakeLists.txt after Lib2 which belongs to no folder...
Anyway : is MyPack
Lib1 and Lib2 ?
Lib1/Lib2/Subproj1/Subproj2 ?
in the 2nd case :
The top directory CMakeLists.txt gives you access to targets of Lib1 and Lib2 that you can use in SubProject1 and SubProject2 if you have something like this :
project(MyPack)
add_subdirectory(Lib1) # Building Lib1
add_subdirectory(Lib2) # Building Lib2
add_subdirectory(SubProject1) # you can use Lib1 & Lib2 targets here
add_subdirectory(SubProject2) # you can use Lib1 & Lib2 targets here
If it is the 1st case, MyPack is only Lib1 and Lib2 :
Using find_package(MyPack) means that you need to create a Config file and install() your project:
project(MyPack)
add_subdirectory(Lib1)
add_subdirectory(Lib2)
in Lib1/CMakeLists.txt :
add_library(lib1 "")
add_library(MyPack::lib1 ALIAS lib1)
[...]
include(GNUInstallDirs)
install(
TARGET lib1
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
in Lib2/CMakeLists.txt :
add_library(lib2 "")
add_library(MyPack::lib2 ALIAS lib2)
[...]
include(GNUInstallDirs)
install(
TARGET lib2
EXPORT MyPackTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
Now you have lib1 and lib2 in the export MyPackTargets. You have to install that export as well.
anywhere after above :
install(
EXPORT MyPackTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
NAMESPACE MyPack::
FILE MyPackTargets.cmake # Not sure if this is still needed
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
"Config.cmake.in"
"MyPackConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyPack
PATH_VARS
CMAKE_INSTALL_LIBDIR
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake
VERSION 1.0.0
COMPATIBILITY SameMajorVersion
)
### Install Config and ConfigVersion files
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/MyPackConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MyPackConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/MyPack"
)
create a file Config.cmake.in with :
#PACKAGE_INIT#
include( "${CMAKE_CURRENT_LIST_DIR}/MyPackTargets.cmake" )
Now if you build and install your project MyPack, find_package(MyPack) from other project should find it and import the targets you've created.
Here is some documentation :
https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html
https://blog.kitware.com/cmake-superbuilds-git-submodules/
Hope that helps

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 with include and source paths - basic setup

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.