|---Engine
|----CMakeList.txt
|----Engine.cpp
|----Engine.h
|---Models
|----CMakeList.txt
|----Snake.cpp
|----Snake.hpp
|---Type
|----CMakeList.txt
|----Point.hpp
|---CMakeList.txt
|---main.cpp
I just can't tell the main sheet that I want to add a directory with files to it ...
Each time, errors of the following type appear:
CMake Error at CMakeLists.txt: 12 (target_include_directories):
Cannot specify include directories for target "Snake" which is not built by
this project.
CMake Error at CMakeLists.txt: 13 (target_link_directories):
Cannot specify link directories for target "Snake" which is not built by
this project.
CMake Error at Engine / CMakeLists.txt: 8 (target_include_directories):
Cannot specify include directories for target "Snake" which is not built by
this project.
CMake Error at CMakeLists.txt: 17 (target_link_libraries):
Cannot specify link libraries for target "Snake" which is not built by this
project.
- Configuring incomplete, errors occurred!
Which, for several hours of intensified attempts, are not corrected in any way. Can anyone help with this?
CMakeLists.txt from Engine folder:
set(HEADERS
Engine.h)
set(SOURCES
Engine.cpp)
add_library(Engine ${HEADERS} ${SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
Main CMakeList.txt:
cmake_minimum_required(VERSION 3.16.3)
project(Snake)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(PROJECT_SOURCES
main.cpp
)
target_include_directories(${PROJECT_NAME} PUBLIC Engine)
target_link_directories(${PROJECT_NAME} PUBLIC Engine)
add_subdirectory(Engine)
target_link_libraries(${PROJECT_NAME} Engine)
add_executable(${PROJECT_NAME}
${PROJECT_SOURCES}
)
find_package(SFML 2.5.1 COMPONENTS graphics audio REQUIRED)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} sfml-graphics sfml-audio)
set(SFML_STATIC_LIBRARIES FALSE)
There are two errors. The first one is to call a PROJECT_NAME that hasn't been built yet. add_executable(${PROJECT_NAME} ...) and add_library(${PROJECT_NAME ...) should be used before the target_include_directories and target_link_directories that refers to it. Because, as #Stephen Newell noted, otherwise you will be using a PROJECT NAME that hasn't been declared/built yet.
The second error is that you are calling a PROJECT_NAME inside Engine/CMakeLists. Maybe you are missing a project(...) inside of it.
Maybe you should move set(SFML_STATIC_LIBRARIES FALSE) before linking it, as well.
Related
I am trying to create a library on the top of SDL2. For the compilation I'm using cmake.
First I had this CMakeLists.txt for the library :
cmake_minimum_required(VERSION 3.10)
project(SquareEngine)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
include_directories(${SDL2_IMAGE_INCLUDE_DIRS})
set (SRCS Main.cpp
Rectangle.cpp
Scene.cpp
SquareEngine.cpp)
set (HEADERS Rectangle.hpp
Scene.hpp
SquareEngine.hpp
utils/Color.hpp
utils/Vector.hpp)
add_library(SquareEngine ${SRCS} ${HEADERS} ${SDL} ${SDL_SRC})
target_link_libraries(SquareEngine ${SDL2_LIBRARIES} ${SDL2_IMAGE_LIBRARIES})
To include the SDL2 and SDL2 image I follow this instructions.
When I try to build it's work perfectly.
Now I try to use my library in a project. I create my own project and I link my librairy that is located in a subfolder /SquareEngine in my project. For the project I use this CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(Demo)
set (SRCS Main.cpp)
add_subdirectory(SquareEngine)
add_executable(Demo ${SRCS})
target_link_libraries(Demo PUBLIC SquareEngine)
target_include_directories(Demo PUBLIC SquareEngine)
When I try to build the project I got an error like this :
Cannot open include file: 'SDL.h': No such file or directory
I try to figure out for long time and I don't have any clue why.
Maybe it will be better to use the SDL in static rather than shared ?
I think you need to add the SDL include dirs to the SquareEngine library:
target_include_directories(SquareEngine PUBLIC ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS})
The most recent SDL2 releases provide SDL2::* CMake targets such that you don't need to fiddle with CMake variables anymore.
So there's no more need to ship your custom FindSDL2.cmake and/or FindSDL2_image.cmake modules.
With those, you can rewrite your cmake script as:
cmake_minimum_required(VERSION 3.10)
project(SquareEngine)
find_package(SDL2 REQUIRED CONFIG)
find_package(SDL2_image REQUIRED CONFIG)
set (SRCS
Main.cpp
Rectangle.cpp
Scene.cpp
SquareEngine.cpp
)
set (HEADERS
Rectangle.hpp
Scene.hpp
SquareEngine.hpp
utils/Color.hpp
utils/Vector.hpp
)
add_library(SquareEngine ${SRCS} ${HEADERS})
target_link_libraries(SquareEngine PRIVATE SDL2::SDL2 SDL2_image::SDL2_image)
target_include_directories(SquareEngine
PUBLIC
$<TARGET_PROPERTY:SDL2::SDL2,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:SDL2_image::SDL2_image,INTERFACE_INCLUDE_DIRECTORIES>
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)
It can then be used in your game as:
cmake_minimum_required(VERSION 3.10)
project(Demo)
set (SRCS Main.cpp)
add_subdirectory(SquareEngine)
add_executable(Demo ${SRCS})
target_link_libraries(Demo PUBLIC SquareEngine)
I get the error:
CMake Error at CMakeLists.txt:11 (find_package):
By not providing "FindSDL2_ttf.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL2_ttf",
but CMake did not find one.
Could not find a package configuration file provided by "SDL2_ttf" with any
of the following names:
SDL2_ttfConfig.cmake
sdl2_ttf-config.cmake
Add the installation prefix of "SDL2_ttf" to CMAKE_PREFIX_PATH or set
"SDL2_ttf_DIR" to a directory containing one of the above files. If
"SDL2_ttf" provides a separate development package or SDK, be sure it has
been installed.
Here is what my cmake file looks like:
cmake_minimum_required(VERSION 3.14)
project(Smithereens)
set(CMAKE_CXX_STANDARD 17)
add_executable(Smithereens main.cpp)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_ttf_INCLUDE_DIRS})
target_link_libraries(Smithereens ${SDL2_LIBRARIES} ${SDL2_ttf_LIBRARIES})
Both SDL2 and SDL2_ttf are installed on my machine, I'm sure I'm just linking incorrectly, learning CMake has been a huge headache for me.
This works pretty well for me, Ubuntu 18.04.
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
PKG_SEARCH_MODULE(SDL2TTF REQUIRED SDL2_ttf>=2.0.0)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_include_directories(${PROJECT_NAME} PRIVATE
include ${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS} ${SDL2TTF_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE
${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES} ${SDL2TTF_LIBRARIES})
I have a folder structure that is as follows:
|-CMakeLists.txt
|-main.cpp
|-network
---------- CMakeLists.txt
---------- network.h
---------- network.cpp
Where network is a folder containing the last 3 items.
I'm struggling to build this in CMake because the documentation is very strange to me. In my root CMakeLists.txt, it's as follows:
cmake_minimum_required(VERSION 3.11.0)
project(Test)
set(CMAKE_CXX_STANDARD 11)
include_directories ("${PROJECT_SOURCE_DIR}/network")
add_subdirectory (${PROJECT_SOURCE_DIR}/network)
add_executable(server main.cpp)
target_link_libraries (network)
find_package(Boost 1.67 REQUIRED COMPONENTS thread)
# Check for libray, if found print message, include dirs and link libraries.
if(Boost_FOUND)
message("Boost Found")
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(server ${Boost_LIBRARIES})
target_link_libraries(server Boost::thread)
elseif(NOT Boost_FOUND)
error("Boost Not Found")
endif()
In the CMakeLists.txt in the network folder it's as follows:
cmake_minimum_required(VERSION 3.11.0)
project(Test)
set(CMAKE_CXX_STANDARD 11)
install(FILES ${MY_HEADER_FILES} DESTINATION ./)
add_executable(network network.cpp)
I made that by myself playing around to see if I can get CMake to add the files in that folder into the root project. Obviously, this is all just failing because I'm struggling to understand CMake from the documentation. My apologies. I get an error due to the implementation in "network.cpp" not being recognized:
main.cpp:(.text+0x409): undefined reference to `Socket::GetThis()'
I'm certain there's nothing wrong with the implementation because it's worked using another round about method but I want to build my project using the previous structure but I can't get my head around how to make the root CMakeLists and the network CMakeLists so that they work together.
How do I design the CMakeLists so that the network header and implementation are included in the root project. Also, the network library will be using Boost as well. Should I find the package in there too?
target_link_libraries (network)
You want to link "server" executable with "network" library. It's like this:
target_link_libraries(server PUBLIC network)
The PUBLIC can be omitted, but I like to specify it everywhere.
Also:
add_executable(network network.cpp)
should network.spp really be an executable? I guess there is no main in network.cpp`. You should:
add_library(network network.cpp)
And I guess the network include path is integral to the network library. So I would inside network/CMakeLists.txt do:
target_include_directories(network PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Also note the target_compile_feature is preferred over set(CMAKE_CXX_STANDARD 11).
Also, there is no error() function. There is message(FATAL_ERROR).
All in all, I would write it like this:
# root/CMakeLists.txt
cmake_minimum_required(VERSION 3.11.0)
project(Test)
# this tells cmake that all c++ files that are in this file
# and all in add_subdirectory projects
# will compile with C++11 (by default)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(network)
add_executable(server main.cpp)
# tell cmake to link server with network library
# ie. server executable uses network library
target_link_libraries(server PUBLIC network)
find_package(Boost 1.67 REQUIRED COMPONENTS thread)
# Check for libray, if found print message, include dirs and link libraries.
if(Boost_FOUND)
message(STATUS "Boost Found")
target_include_directories(server PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(server PUBLIC ${Boost_LIBRARIES} Boost::thread)
elseif(NOT Boost_FOUND)
message(FATAL_ERROR "Boost Not Found")
endif()
and:
# network/CMakeLists.txt
add_libraries(network network.cpp)
# tell cmake, that all targets that link with network library
# will have include path added
target_include_directories(network PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
I link only server executable with boost. I have no idea if your network library needs to link with boost too, if so, move the boost info netowrk/CMakeLists.txt and target_link_libraries(network PUBLIC ${Boost_LIBRARIES})
I think you have to change line
add_executable(server main.cpp)
to
add_executable(server main.cpp network.cpp)
P.S I personally prefer to use this construction:
SET(PROJECT_NAME "MyProject")
...
file(GLOB SRC_FILES *.cpp)
...
add_executable("${PROJECT_NAME}" "${SRC_FILES}")
I am having this weird issue where the paths that I use for my include_directories and target_link_libraries has to be all lowercase.
My project has a subdirectory under it at GLTestBed/src if I try to include it , ninja (or even the built VS solution) throws an error
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ninja : error : '../../GLTestBed/src/Mesh.cpp', needed by 'GLTestBed/CMakeFiles/GlTestBed.dir/src/Mesh.cpp.obj', missing and no known rule to make it
Mesh.cpp is the first file added in my add_Library directive, if I remove that it throws this error for the file that is at top, so I am pretty sure its not an error for just this particular file
However if I change the folder name from GLTestBed to gltestbed every thing builds correctly
CmakeLists.txt in main Folder (GLParticles)
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
project(GLParticles)
set (glparticlesdir "${CMAKE_CURRENT_SOURCE_DIR}/GLTestBed")
message ("-----" , ${glparticlesdir})
add_subdirectory(${glparticlesdir})
add_executable(GLParticles
src/main.cpp
src/ParticleWorld.cpp
src/ParticleWorld.h
src/BurstParticleUpdater.cpp
src/BurstParticleUpdater.h src/SineWaveUpdater.cpp src/SineWaveUpdater.h)
include_directories(${glparticlesdir}/src)
include_directories(${glparticlesdir}/ext/glm)
target_link_libraries(GLParticles
GlTestBed)
# SET(CMAKE_CXX_LINK_FLAGS "-framework OpenGL")
and the CmakeLists.txt in the GLTestBed folder
cmake_minimum_required(VERSION 3.10)
project(GlTestBed)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenGL REQUIRED)
#find_package(GLEW REQUIRED)
message ('--------' ${OPENGL_LIBRARIES})
add_Library(GlTestBed
src/Globals.h
src/Mesh.cpp
src/Mesh.h
src/ResourceManager.cpp
src/ResourceManager.hpp
src/Shader.cpp
src/Shader.h
src/stb_image.cpp
src/stb_image.h
src/Material.h
src/Engine.cpp src/Engine.h
src/Particle.cpp
src/Particle.h
src/Camera.h
src/Camera.cpp
src/ParticleManager.cpp
src/ParticleManager.h
src/ParticleUpdater.h)
target_include_directories(GlTestBed PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_include_directories(GlTestBed PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
target_link_libraries(GlTestBed
${OPENGL_LIBRARIES}
glew32.lib
sfml-graphics.lib
sfml-window.lib
sfml-system.lib)
if(APPLE)
target_include_directories(GlTestBed PUBLIC
/usr/local/include)
target_link_libraries(GlTestBed
/usr/local/Cellar/glew/2.1.0/lib/libGLEW.2.1.0.dylib
/usr/local/Cellar/sfml/2.4.2_1/lib/libsfml-window.2.4.2.dylib
/usr/local/Cellar/sfml/2.4.2_1/lib/libsfml-system.2.4.2.dylib ${OPENGL_LIBRARIES})
endif()
I'm trying to build a C++ application which uses the library libpamg0-dev.
I installed it with the following command on my elementaryOS VM.
apt-get install libpam0g-dev
When I try to compile the application, the compiler spits out the following errors:
undefined reference to `pam_start`
undefined reference to `pam_authenticate`
undefined reference to `pam_end`
My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.10)
project(application)
set(CMAKE_CXX_STANDARD 11)
INCLUDE_DIRECTORIES(/home/dnagl/dev/libs/restbed/distribution/include /usr/include/security)
LINK_DIRECTORIES(/home/dnagl/dev/libs/restbed/distribution/library /usr/lib/x86_64-linux-gnu)
add_executable(application main.cpp Utils/Json/Json.cpp Utils/Json/Json.h Utils/Stringhelper/Stringhelper.cpp Utils/Stringhelper/Stringhelper.h Utils/File/Filehelper.cpp Utils/File/Filehelper.h Utils/System/SystemHelper.cpp Utils/System/SystemHelper.h Controller/Info/InfoController.cpp Controller/Info/InfoController.h Rest/ResourceHandler/ResourceHandler.cpp Rest/ResourceHandler/ResourceHandler.h Controller/System/SystemController.cpp Controller/System/SystemController.h Rest/Log/RequestLogger.cpp Rest/Log/RequestLogger.h Controller/Authentication/AuthenticationController.cpp Controller/Authentication/AuthenticationController.h Controller/Log/LogController.cpp Controller/Log/LogController.h)
target_link_libraries(application restbed)
Maybe one of you knows how to link the library in the right way.
I have found a nice solution with find_package option from CMake. CMake provides a way to find packages/libraries with specified FindModule.cmake file.
A really good news is that there are a lot of existing module files. You can use this version to find PAM package on Linux. Put it to cmake/modules/ in your project folder and update your CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(restbed)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Notify CMake that we have module files to find packages/libs.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(PAM REQUIRED)
# Check if we found PAM.
if (NOT PAM_FOUND)
message(FATAL_ERROR "PAM library was not found.")
endif ()
# Source configuration.
include_directories(
${PAM_INCLUDE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set(EXECUTABLE_NAME "application")
# Add sources to this project's executable.
add_executable(${EXECUTABLE_NAME}
"main.cpp"
"Utils/Json/Json.cpp"
"Utils/Json/Json.h"
"Utils/Stringhelper/Stringhelper.cpp"
"Utils/Stringhelper/Stringhelper.h"
"Utils/File/Filehelper.cpp"
"Utils/File/Filehelper.h"
"Utils/System/SystemHelper.cpp"
"Utils/System/SystemHelper.h"
"Controller/Info/InfoController.cpp"
"Controller/Info/InfoController.h"
"Rest/ResourceHandler/ResourceHandler.cpp"
"Rest/ResourceHandler/ResourceHandler.h"
"Controller/System/SystemController.cpp"
"Controller/System/SystemController.h"
"Rest/Log/RequestLogger.cpp"
"Rest/Log/RequestLogger.h"
"Controller/Authentication/AuthenticationController.cpp"
"Controller/Authentication/AuthenticationController.h"
"Controller/Log/LogController.cpp"
"Controller/Log/LogController.h"
)
target_link_libraries(${EXECUTABLE_NAME}
${PAM_LIBRARIES}
)
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE CXX)
Hope this helps!