I am trying to write a cmake file to create a shared library and use it in the executable file in my project. In the main I include heades as <pattern_follower/header_file_name.h>, but when I run make install it says pattern_follower/header_file_name.h does not exist.
cmake_minimum_required(VERSION 2.8)
project(pattern_follower)
add_definitions(-std=c++14)
file(GLOB SOURCES src/*)
file(GLOB HEADERS include/*)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -Wall -O4 -march=native -Wfatal-errors")
find_package(OpenCV REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(${PROJECT_NAME} SHARED ${SOURCES})
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS})
add_executable(${PROJECT_NAME}-main main.cpp)
set_target_properties(${PROJECT_NAME}-main PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
target_link_libraries( ${PROJECT_NAME}-main ${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(TARGETS ${PROJECT_NAME}-main DESTINATION bin)
install(DIRECTORY include DESTINATION include/${PROJECT_NAME})
Related
I have a simple project, which consists of several directories with sources and CMakeLists.txt files.
Here is my project structure:
CMakeLists.txt\
main.c
src/source1.c\
src/source1.h\
src/CMakeLists.txt
test/test.cpp\
test/main.cpp\
test/CMakeLists.txt
googletest
Main executable has been built successfully, but test executable not, linker errors instead (undefined references to functions from src directory). Here is my CMake files content:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(TIC-TAC-TOE)
set(CMAKE_C_STANDARD 99)
set(CXXMAKE_C_STANDARD 11)
set(POSITION_INDEPENDENT_CODE ON)
enable_testing()
include_directories(src)
add_subdirectory(test)
add_subdirectory(src)
add_subdirectory(googletest)
add_executable(TIC-TAC-TOE main.c)
target_link_libraries(TIC-TAC-TOE tic_tac_toe-lib)
src/CMakeLists.txt:
set(Sources tic-tac-toe.c tic-tac-toe.h)
add_library(tic_tac_toe-lib STATIC ${Sources})
test/CMakeLists.txt:
project(TIC-TAC-TOE-TEST)
set(Sources tic-tac-toe-test.cpp
main.cpp
)
add_executable(TIC-TAC-TOE-TEST ${Sources})
add_test(
NAME TIC-TAC-TOE-TEST
COMMAND TIC-TAC-TOE-TEST
)
target_link_libraries(TIC-TAC-TOE-TEST PUBLIC tic_tac_toe-lib gtest_main)
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.
When I was setting this up as executable the library was compiled with it fine, but when I changed it to a library it wouldn't include the library.
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". So it leads me to think that the cause of the error is that the include directories aren't exported with the static library.
My Filesystem:
include
--Header Files
src
--Source Files
extern
--SDL2
build
Here is an example of the file causing the error:
#include <iostream>
#include <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" PUBLIC "${CMAKE_SOURCE_DIR}/extern/SDL2/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"
)
From sdl2 CMakeLists.txt try:
set(SDL_STATIC 1)
add_subdirectory(extern/SDL2) # And I recommend EXCLUDE_FROM_ALL
Also to be sure add a check:
foreach(i IN ITEMS SDL2main SDL2-static)
if(NOT TARGET ${i})
message(FATAL_ERROR "${i} is not a target")
endif()
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2main SDL2-static)
I am building two C++ libraries(2 CMake projects). library2 depends on library1. I am installing my first library header files at ${CMAKE_INSTALL_INCLUDEDIR}/mylibraries. Now to include library1 header files in my library2, I am doing include_directories(${CMAKE_INSTALL_FULL_INCLUDEDIR}/mylibraries) in the library2's CMakeLists.txt.
But the make is failing with no such file or directory error.
library1.h no such file or directory from library2.cpp
library1's CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
include(GNUInstallDirs)
project (logger)
set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)
set (Umbrella "ferryfair")
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/pkgconfig.pc.in"
"${PROJECT_BINARY_DIR}/pkgconfig.pc"
)
set (GCC_COVERAGE_COMPILE_FLAGS "-std=c++14")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
file(GLOB HEADERS *.h)
file(GLOB SOURCES *.cpp)
include_directories(${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_INSTALL_FULL_INCLUDEDIR}/${Umbrella})
add_library(${PROJECT_NAME}Static STATIC ${SOURCES} ${HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME}Static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
set_target_properties(${PROJECT_NAME}Static
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
target_link_libraries(${PROJECT_NAME}Static ferrybase)
target_link_libraries(${PROJECT_NAME} ferrybase)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${PROJECT_NAME}Static DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${Umbrella})
install(FILES "${PROJECT_BINARY_DIR}/config.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${Umbrella}
RENAME ${PROJECT_NAME}Config.h)
install(FILES "${PROJECT_BINARY_DIR}/pkgconfig.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
RENAME "${PROJECT_NAME}.pc")
install(FILES "${PROJECT_BINARY_DIR}/pkgconfig.pc"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
RENAME "${PROJECT_NAME}.pc")
library2's CMakeLists.txt
cmake_minimum_required (VERSION 3.5)
include(GNUInstallDirs)
project (FFJSON)
IF (DEFINED _DEBUG)
ADD_DEFINITIONS(-D_DEBUG=${_DEBUG})
ENDIF()
set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)
set (Umbrella "ferryfair")
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Mac OS X specific code
SET(macOS ON)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/pkgconfig.pc.in"
"${PROJECT_BINARY_DIR}/pkgconfig.pc"
)
set (GCC_COVERAGE_COMPILE_FLAGS "-std=c++14")
set (GCC_COVERAGE_LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs")
IF (DEFINED _DEBUG)
set (GCC_COVERAGE_COMPILE_FLAGS "${GCC_COVERAGE_COMPILE_FLAGS} -g -O0")
set (GCC_COVERAGE_LINK_FLAGS "${GCC_COVERAGE_LINK_FLAGS} -g -O0")
ENDIF()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
file(GLOB HEADERS *.h)
file(GLOB SOURCES *.cpp)
include_directories(${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_INSTALL_FULL_INCLUDEDIR}/${Umbrella})
add_library(${PROJECT_NAME}Static STATIC ${SOURCES} ${HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME}Static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
set_target_properties(${PROJECT_NAME}Static
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
target_link_libraries(${PROJECT_NAME}Static logger ferrybase)
target_include_directories(TestFFJSON PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/${Umbrella}>
)
add_executable(IteratorIncrement tests/iteratorincrement.cpp)
target_link_libraries(IteratorIncrement FFJSON logger ferrybase)
target_include_directories(IteratorIncrement PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/${Umbrella}>
)
add_test(test1 TestFFJSON)
add_test(test2 IteratorIncrement)
ENDIF()
Its weird! ridiculous! pathetic!
executing cmake twice fixed the issue. Its an another entry into accidental discoveries.
I have the following project structure:
libs is the directory where the standalone library I'm writing lives.
src is where I consume the library
My three CMakeLists.txt files are the following:
The main entry point:
cmake_minimum_required(VERSION 3.4)
add_subdirectory(src)
add_subdirectory(libs)
The libs/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(Fibula)
message(STATUS "Fibula: v2.0.0")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework OpenGl -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -lGLEW -std=c++14 -Wall -pedantic")
set(FIBULA_INCLUDE_DIR "include")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR})
include_directories(${FIBULA_INCLUDE_DIR})
# This stuff needed to put every include file into needed directory when we do make install
file(GLOB BRIDGE ${FIBULA_INCLUDE_DIR}/Bridge/*.hpp)
file(GLOB CORE ${FIBULA_INCLUDE_DIR}/Core/*.hpp)
file(GLOB EVENTS ${FIBULA_INCLUDE_DIR}/Events/*.hpp)
file(GLOB GRAPHICS ${FIBULA_INCLUDE_DIR}/Graphics/*.hpp)
file(GLOB GRAPHICS_TILEMAP ${FIBULA_INCLUDE_DIR}/Graphics/TileMap/*.hpp)
file(GLOB_RECURSE SOURCE_LIST src/*.cpp)
set(HEADER_LIST
${BRIDGE}
${CORE}
${EVENTS}
${GRAPHICS}
${GRAPHICS_TILEMAP}
)
# GLM
find_package(GLM REQUIRED)
if (NOT GLM_FOUND)
message(SEND_ERROR "Failed to find GLM")
return()
else ()
include_directories(${GLM_INCLUDE_DIRS})
endif ()
# GLEW
find_package(GLEW REQUIRED)
if (NOT GLEW_FOUND)
message(SEND_ERROR "Failed to find GLEW")
return()
else ()
include_directories(${GLEW_INCLUDE_DIRS})
endif ()
# SFML
find_package(SFML 2.2 REQUIRED)
if (NOT SFML_FOUND)
message(SEND_ERROR "Failed to find SFML 2")
return()
else ()
include_directories(${SFML_INCLUDE_DIRS})
endif ()
add_library(Fibula SHARED ${SOURCE_LIST} ${HEADER_LIST})
target_link_libraries(Fibula
${GLM_LIBRARIES}
${GLEW_LIBRARIES}
${SFML_LIBARIES}
)
# When we do 'make install' it will put .so file into lib directory and include files into include directory
install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${PROJECT_NAME})
install(FILES ${BRIDGE} DESTINATION include/${PROJECT_NAME}/Bridge/)
install(FILES ${CORE} DESTINATION include/${PROJECT_NAME}/Core/)
install(FILES ${EVENTS} DESTINATION include/${PROJECT_NAME}/Events/)
install(FILES ${GRAPHICS} DESTINATION include/${PROJECT_NAME}/Graphics/)
install(FILES ${GRAPHICS_TILEMAP} DESTINATION include/${PROJECT_NAME}/Graphics/TileMap/)
add_custom_target(install_${PROJECT_NAME}
make install
DEPENDS ${PROJECT_NAME}
COMMENT "Installing ${PROJECT_NAME}")
And the src/CMakeLists.txt:
cmake_minimum_required(VERSION 3.4)
project(demo-game)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall")
find_library(FIBULA_LIBRARY
NAMES Fibula
HINTS "${CMAKE_CURRENT_LIST_DIR}/../libs/include/")
include_directories(
"${CMAKE_CURRENT_LIST_DIR}/../libs/include"
Core
)
file(GLOB SOURCE_LIST
*.cpp
../../src/Core/*.cpp
)
add_executable(demo-game ${SOURCE_LIST})
target_link_libraries(demo-game Fibula)
add_custom_target(valgrind)
When I try to include my library as:
#include <Fibula/Core/Kernel.hpp>
I get the following error:
for a project I need to create an executable that includes all the libraries that I used (opencv, cgal) in order to execute it on a computer that has not those libraries. Currently, this is my CMakeLists.txt (I use linux).
cmake_minimum_required(VERSION 2.8)
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -O2")
project( labeling )
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
add_library(OpenCV STATIC IMPORTED)
add_library(CGAL STATIC IMPORTED COMPONENTS Core)
add_library(GMP STATIC IMPORTED)
find_package(OpenCV REQUIRED)
find_package(CGAL QUIET COMPONENTS Core )
find_library(GMP_LIBRARY gmp /usr/lib)
include(src)
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
set(EXECUTABLE_OUTPUT_PATH ../bin)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
include_directories( src )
include_directories( ${OpenCV_INCLUDE_DIRS} )
file(GLOB_RECURSE nei_SRC "src/*.cpp")
add_executable( nei_segmentation ${nei_SRC})
target_link_libraries( nei_segmentation ${OpenCV_LIBS} ${GMP_LIBRARY})
In such a way only GMP and some other c++ libraries are included in my executable. My question is: How can I create a makefile in order to automatically including all the libraries in a static manner and creating only a "big" executable that contains all the libraries? Can you help me?
As global CMake settings, add these lines before add_executable, valid for gcc/clang:
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
On Modern CMake (3.x+ - target_link_libraries doc), you can apply the flag to specific targets, in this way:
target_link_libraries(your_target_name -static)
If you're using MSVC, you have to set the compiler and linker flags:
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
target_compile_options(your_target_name [PUBLIC|PRIVATE] /MT)
target_link_options(your_target_name [PUBLIC|PRIVATE] /INCREMENTAL:NO /NODEFAULTLIB:MSVCRT)
or alternatively also:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
and if you are using MFC, you need to specify the flag to 1 see here:
set(CMAKE_MFC_FLAG 1)
Add these lines after add_executable(MyExec "main.c") (for example) :
target_link_libraries(MyExec PUBLIC "-static")
or before: link_libraries("-static")