I am trying to figure out to create a small cmake file. The directory struture includes 4 sub folders and which has src and header files. There is no src or header file at root. All I want is to create a Shared library using cmake by compiling these four folders.
CMakeLists.txt at root
cmake_minimum_required (VERSION 2.8.7)
Project(NEWPROJ)
set(${PROJECT_NAME}_MAJOR_VERSION 00)
set(${PROJECT_NAME}_MINOR_VERSION 01)
set(${PROJECT_NAME} 0)
set(${PROJECT_NAME}_VERSION
${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION})
set(${PROJECT_NAME}_SOVERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION})
Message ( Root )
include_directories("${PROJECT_SOURCE_DIR}/Folder1/include")
include_directories("${PROJECT_SOURCE_DIR}/Folder2/include")
include_directories("${PROJECT_SOURCE_DIR}/Folder3/include")
include_directories("${PROJECT_SOURCE_DIR}/Folder4/include")
add_subdirectory ("${PROJECT_SOURCE_DIR}/Folder1")
add_subdirectory ("${PROJECT_SOURCE_DIR}/Folder2")
add_subdirectory ("${PROJECT_SOURCE_DIR}/Folder3")
add_subdirectory ("${PROJECT_SOURCE_DIR}/Folder4")
add_library( ${PROJECT_NAME} SHARED ${SOURCE} ${HEADERS})
CMakeLists.txt in Folder1
MESSAGE(Folder1)
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/src/file1.cc
${CMAKE_CURRENT_SOURCE_DIR}/src/file2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/file3.cc
PARENT_SCOPE
)
set(HEADERS
${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/include/file1.h
${CMAKE_CURRENT_SOURCE_DIR}/include/file2.h
${CMAKE_CURRENT_SOURCE_DIR}/include/file3.h
${CMAKE_CURRENT_SOURCE_DIR}/include/file4.h
PARENT_SCOPE
)
cmake .. successful
make folder1/src/file1.cc:1:20: fatal error: file1.h: No such file or directory
file1.cc
#include "file1.h"
...
Related
I have a simple exercise on cmake with following file tree:
proj01/
include/
functions.h
src/
main.cpp
functions.cpp
CMakeLists.txt
CMakeLists.txt
README
My project CMakeLists.txt is like this:
cmake_minimum_required(VERSION 3.21)
project (test01)
add_subdirectory(src)
set(SOURCES
main.cpp
functions.cpp
)
add_executable(myProgram ${SOURCES})
and when I tried to build, I got error:
# Error!
CMake Error at CMakeLists.txt:18 (add_executable):
Cannot find source file:
main.cpp
CMake Error at CMakeLists.txt:18 (add_executable):
No SOURCES given to target: myProgram
If I change the project CMakeLists.txt by giving the absolute path(relative to the project), it worked!
#add_subdirectory(src)
set(SOURCES
src/main.cpp
src/functions.cpp
)
add_executable(myProgram ${SOURCES})
When there is multiple source files in multiple subdirectories, it would be better to explicitly list all source files including their paths as what is done with my working version of the CMakeLists.txt.
Spent hours to search for command add_subdirectories(), this, this, and this, but no luck.
The closest one would be this question, but there is no solution for that question so far.
What did I miss with my add_subdirectory(src) in this simple specific scenario? Any help is appreciated.
add_subdirectory(src) results in cmake parsing src/CMakeLists.txt creating a new directory src in the build tree for building the part of the project in this cmake file.
It doesn't result in you being able to use shorter paths in the CMakeLists.txt file containing the add_subdirectory command.
If you move the target to src/CMakeLists.txt you could use the shorter paths:
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project (test01)
add_subdirectory(src) # add src/CMakeLists.txt to this project
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
set(SOURCES
main.cpp
functions.cpp
)
add_executable(myProgram ${SOURCES})
Personally I'd avoid adding an additional CMakeLists.txt file just to shorten the paths. It's easy to remove the duplication of the src dir, if that's what you're worried about.
set(SOURCES
main.cpp
functions.cpp
)
list(TRANSFORM SOURCES PREPEND "src/")
or
function(subdir_files VAR DIR FILE1)
set(FILES)
foreach(SRC IN ITEMS ${FILE1} ${ARGN})
list(APPEND FILES ${DIR}/${SRC})
endforeach()
set(${VAR} ${FILES} PARENT_SCOPE)
endfunction()
subdir_files(SOURCES src
main.cpp
functions.cpp
)
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.
I have a C++ project with this structure:
-- ProjectFolder
-- Project_Prototype1
-- Project_Prototype2
Project_Prototype1 has a CMakeLists file with this content:
cmake_minimum_required(VERSION 2.8)
project( Neuromarketing-RF )
find_package( Boost 1.58.0 REQUIRED COMPONENTS filesystem system )
include_directories( ${Boost_INCLUDE_DIRS} include src/external )
find_package( OpenCV 3 REQUIRED )
file(GLOB FACETRACKER_HEADERS "external/FaceTracker/include/FaceTracker/*.h")
file(GLOB FACETRACKER_SRC "external/FaceTracker/src/lib/*.cc")
file(GLOB SOURCES "src/*cpp")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/")
add_executable( Neuromarketing-RF ${FACETRACKER_SRC} ${SOURCES} )
target_link_libraries( Neuromarketing-RF ${OpenCV_LIBS} ${Boost_LIBRARIES} )
target_compile_features( Neuromarketing-RF PRIVATE cxx_range_for )
Prototype1 is using an external library called FaceTracker .
In the Prototype2 I wanna access a file from Prototype1 but I don't want to redefine all dependencies from Prototype1 on Prototype2 CMakeLists (FaceTracker, Boost, etc...).
How can I write the Prototype2 CMakeLists to use Prototype1 without redefining everything manually?
Here is my current CMakeLists.txt for Prototype2:
cmake_minimum_required (VERSION 2.6)
project (Neuromarketing-CNN)
find_package(OpenCV REQUIRED)
find_package(Boost 1.58.0 REQUIRED COMPONENTS filesystem system)
add_subdirectory("../Neuromarketing-RF" "../Neuromarketing-RF/bin" )
file ( GLOB NM_RF_SRC "../Neuromarketing-RF/src/*.cpp" )
include_directories(include ../Neuromarketing-RF/include ${Boost_INCLUDE_DIRS} )
file(GLOB SOURCES "src/*.cpp")
add_executable (bin/Neuromarketing-CNN ${SOURCES} ${NM_RF_SRC} )
target_link_libraries(bin/Neuromarketing-CNN ${OpenCV_LIBS} ${Boost_LIBRARIES} )
target_compile_features( bin/Neuromarketing-CNN PRIVATE cxx_range_for )
The easiest way would be to create a file containing all the dependencies common to both CMakeList.txt files and use include(). For instance have a file names ProjectFolder/my-includes.cmake that contains the relevant find_package() statements, and in both CMakeList.txt files add a line
include ("../my-includes.cmake")
Everything defined in the included file is available to the including file.
here is my CMakeLists.txt file which is exists in the current directory project1
in the project1 directory, I have a src directory which contains the source and headers files. I have the build directory.
cmake_minimum_required(VERSION 2.6)
#Declaration du projet
project(MYfirstcamke)
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
#Inclusion de opencv
include_directories(/usr/local/include/)
link_directories(/usr/local/lib)
file(
GLOB_RECURSE
source_files
src/*
)
#declaration de l'executable
add_executable(
my_executable
${source_files}
)
#Configuration de l'edition de lien.
target_link_libraries(
my_executable opencv_core opencv_imgproc opencv_video opencv_highgui
)
before, the file command I need to copy the *.cpp and *.hpp in src directory that exist the current directory. I write this code:
file(GLOB MY_PUBLIC_HEADERS
"*.hpp"
)
file(GLOB MY_PUBLIC_SOURCE
"*.cpp"
)
file(COPY ${MY_PUBLIC_SOURCE} DESTINATION "src/")
file(COPY ${MY_PUBLIC_HEADERS} DESTINATION "src/")
when I start the cmake.. where the current directory is build. *.hpp and *.cpp are copied to src but the problem here is, src is also copied to build and cmake does not work in this case. I need that src rest in the project1 directory. How can I fix this problem?
I have the following project structure:
CMakeLists.txt
lib1/CMakeLists.txt and all cpp and header files of the lib
lib2/CMakeLists.txt and all cpp and header files of the lib
app/CMakeLists.txt and all cpp and header files of the app
The main CMakeLists.txt looks like:
PROJECT( ${PROJECT_NAME} )
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
The lib1/CMakeLists.txt looks eg like (stripped):
SET(SOURCE
file.cpp
)
SET(HEADERS
some_lib_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
and the one for the app looks the same except of ADD_EXECUTABLE:
SET(SOURCE
main.cpp
)
SET(HEADERS
some_header.h
)
add_library( lib1 ${SOURCE} ${HEADERS} )
ADD_EXECUTABLE( app ${SOURCE} ${HEADERS} )
I found the setup working well this way because out of this, I can generate one Visual Studio solution file which contains all those three projects. But my problem is that my app includes header files of lib1 (and also of lib2, which depends on lib1). When I do
$mkdir build
$cd build
$cmake -C ..\myproject
it generates out-of-source VS .sln file as I want it, but the app doesn't compile because it can't find the header files of lib1 (obviously).
Now I read and tried many things, like TARGET_LINK_LIBRARIES( app lib1 ) (which got the app to link with the lib1, but not solve the header include issue), and things like add_subdirectory( ../lib1 ) in various variants in the CMakeLists.txt of app (which all throwed errors that I couldn't fix), and also find_package (which I guess is the wrong approach).
So how can I solve this (I guess simple...) problem?
Here's one possible solution:
Root CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(${PROJECT_NAME})
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
lib1/CMakeLists.txt:
project(Lib1)
add_library(lib1 lib1.cpp lib1.h)
lib2/CMakeLists.txt:
project(Lib2)
add_library(lib2 lib2.cpp lib2.h)
# Add /lib1 to #include search path
include_directories(${Lib1_SOURCE_DIR})
# Specify lib2's dependency on lib1
target_link_libraries(lib2 lib1)
app/CMakeLists.txt:
project(App)
add_executable(app main.cpp some_header.h)
# Add /lib1 and /lib2 to #include search path
include_directories(${Lib1_SOURCE_DIR} ${Lib2_SOURCE_DIR})
# Specify app's dependency on lib2.
# lib2's dependency on lib1 is automatically added.
target_link_libraries(app lib2)
There are plenty of different ways to achieve the same end result here. For a relatively small project, I'd probably just use a single CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)
add_library(lib1 lib1/lib1.cpp lib1/lib1.h)
add_library(lib2 lib2/lib2.cpp lib2/lib2.h)
add_executable(app app/main.cpp app/some_header.h)
include_directories(${CMAKE_SOURCE_DIR}/lib1 ${CMAKE_SOURCE_DIR}/lib2)
target_link_libraries(lib2 lib1)
target_link_libraries(app lib2)
For further info on the relevant commands and their rationale, run:
cmake --help-command add_subdirectory
cmake --help-command include_directories
cmake --help-command target_link_libraries
Project
CMakeLists.txt
\-lib1
CMakeLists.txt
\- include \ lib1
\- src
\-lib2
CMakeLists.txt
\- include \ lib2
\- src
\-app
CMakeLists.txt
\- src
Suppose dependencies as follow:
lib1 ---> lib2 ---> app
\--------------> app
Something like this:
CMakeLists.txt:
add_subdirectory(lib1)
add_subdirectory(lib2)
add_subdirectory(app)
lib1/CMakeLists.txt:
file(GLOB_RECURSE _HDRS "include/*.hpp")
file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
add_library(lib1 ${_HDRS} ${_SRCS})
#target_link_libraries(lib1)
target_include_directories(lib1 PUBLIC include)
install(TARGETS lib1 DESTINATION lib)
install(FILES ${_HDRS} DESTINATION include/lib1)
lib2/CMakeLists.txt:
file(GLOB_RECURSE _HDRS "include/*.hpp")
file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
add_library(lib2 ${_HDRS} ${_SRCS})
target_link_libraries(lib2 lib1)
target_include_directories(lib2 PUBLIC include)
install(TARGETS lib2 DESTINATION lib)
install(FILES ${_HDRS} DESTINATION include/lib2)
so in lib2/src/file.cpp you could do #include <lib1/header.hpp>
app/CMakeLists.txt:
file(GLOB_RECURSE _SRCS "src/*.[hc]pp")
add_executable(app ${_SRCS})
target_link_libraries(app lib1 lib2)
install(TARGETS app DESTINATION bin)
so in app/src/file.cpp you could do #include <lib1/header.hpp> and #include <lib2/header.hpp>
The magic is target_include_directories which attach the "include" directory to the target, so when linking with it you pull the include directory also ;)