including external libraries in cmakelists.txt file - c++

I'm using cmake to build an executable to run on an Intel Galileo board.
My question is how do I include the external mraa library in the build process.
Mraa library
When I download the library from git (1) do I need to build it as described here
Mraa compiling instructions
What do I need to put in my CMakeLists.txt file to pick up the library?
This is what I have thus far in my CMakeLists.txt file but I believe it is incorrect.
### MRAA ###
add_subdirectory(mraa-master/src)
file(GLOB mraa_SRC
"mraa-master/src/*.c"
)
include_directories( "${PROJECT_SOURCE_DIR}/mraa-master/include" )
add_library( ${MRAA_LIBRARY_NAME} SHARED ${mraa_SRC} )
Thank you
cmake_minimum_required(VERSION 2.8)
MESSAGE( STATUS "Starting build process")
SET( CMAKE_VERBOSE_MAKEFILE on )
if (CMAKE_BUILD_TYPE EQUAL "Debug")
MESSAGE(STATUS "Building in debug mode")
elseif (CMAKE_BUILD_TYPE EQUAL "Release")
MESSAGE(STATUS "Building in release mode")
endif()
SET(PROJECT_NAME "TestProject")
SET(APPLICATION_NAME "TestApplication")
SET(SAFE_STRING_LIBRARY "SafeString")
SET(APPLICATION_LIBRARY "Applibrary")
PROJECT( ${PROJECT_NAME} )
MESSAGE( STATUS "PROJECT: " ${PROJECT_NAME} )
SET(WRSDK_PATH "$ENV{WINDRIVER_SDK_DIR}")
IF (WRSDK_PATH)
else()
SET(WRSDK_PATH /opt/windriver/wrlinux/5.0-intel-quark/)
endif()
SET(APPLIBRARY_NAME ${APPLICATION_LIBRARY} )
SET(SAFE_STRING_LIBRARY_NAME ${SAFE_STRING_LIBRARY} )
### SAFE STRING ###
add_subdirectory(SafeStringStaticLibrary/safeclib)
file(GLOB safestring_SRC
"SafeStringStaticLibrary/safeclib/*.c"
)
include_directories( "${PROJECT_SOURCE_DIR}/SafeStringStaticLibrary /safeclib" )
add_library( ${SAFE_STRING_LIBRARY_NAME} SHARED ${safestring_SRC} )
include(ExternalProject)
ExternalProject_Add(mraa
GIT_REPOSITORY https://github.com/intel-iot-devkit/mraa.git
GIT_TAG v0.8.0
UPDATE_COMMAND ""
INSTALL_COMMAND "" )
file(GLOB app_SRC
"classes/*.cpp"
"Logger.cpp"
"sqlite3.c"
"shell.c"
)
add_library( ${APPLIBRARY_NAME} SHARED ${app_SRC})
include_directories( "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/SafeStringStaticLibrary/include" )
add_executable( ${APPLICATION_NAME} ${APPLICATION_NAME}.cpp
include_directories( "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/SafeStringStaticLibrary/include" "${CMAKE_SOURCE_DIR}/classes")
TARGET_LINK_LIBRARIES( ${APPLICATION_NAME} ${APPLIBRARY_NAME} ${SAFE_STRING_LIBRARY_NAME} -lrt -lpthread -lgcov -ldl)

The simplest way for build your project alongside with 3d party project is add_subdirectory() that subproject. Approach below implies that you (manually) download(git clone) sources of mraa project into mraa-lib subdirectory of your project's sources.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
MESSAGE( STATUS "Starting build process")
# Configure subproject before definition of variables for main project.
#
# Subproject defines *mraa* library target.
add_subdirectory(mraa-lib)
# Before installation, public mraa headers are contained under *api* subdirectory.
include_directories(mraa-lib/api)
... # create executable ${APPLICATION_NAME}
# Linking with mraa library is straightforward.
target_link_libraries(${APPLICATION_NAME} mraa)
That way mraa subproject will be configured, built and installed alongside with your project. So, if you cross-compile your project(using toolchain file, or inside IDE), the subproject will also be cross-compiled.

Related

Creating installer using cpack and windeployqt, To contain qt and VTK libraries

Trying to package an application with Microsoft Visual Studio 2022 and qt6 libraries I do not no were to start from. I've done a bit of research most people used qt5 and when I replace the text with qt6 it doesn't seem to work. I used dependency walker to find the necessary libraries and I seem to have achieved a way to add the Visual Studio libraries but not qt and VTK.
cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
foreach(p
CMP0071 # 3.10: Let AUTOMOC and AUTOUIC process GENERATED files
)
if(POLICY ${p})
cmake_policy(SET ${p} NEW)
endif()
endforeach()
PROJECT( QtVTKExample )
#set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
if (MSVC_VERSION EQUAL 1930 AND MSVC_TOOLSET_VERSION EQUAL 142)
cmake_host_system_information(RESULT VS_DIR QUERY VS_17_DIR)
file(GLOB MSVC_REDIST_LIBRARIES "${VS_DIR}/VC/Redist/MSVC/*/${MSVC_C_ARCHITECTURE_ID}/Microsoft.VC143.CRT/*.dll")
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${MSVC_REDIST_LIBRARIES}")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS TRUE)
endif()
include(InstallRequiredSystemLibraries)
# Add to top of file CPACK stuff
include(CTest)
if(WIN32)
set(CPACK_GENERATOR "NSIS")
else()
set(CPACK_GENERATOR "ZIP")
endif()
include(CPack)
find_package(VTK COMPONENTS
vtkCommonColor
vtkCommonCore
vtkCommonDataModel
vtkInteractionStyle
vtkRenderingContextOpenGL2
vtkRenderingCore
vtkRenderingFreeType
vtkRenderingGL2PSOpenGL2
vtkRenderingOpenGL2
QUIET
)
# The CMake build process might generate some new files in the current
# directory. This makes sure they can be found.
set( CMAKE_INCLUDE_CURRENT_DIR ON )
# This allows CMake to run one of Qt's build tools called moc
# if it is needed. moc.exe can be found in Qt's bin directory.
# We'll look at what moc does later.
set( CMAKE_AUTOMOC ON )
set( CMAKE_AUTOUIC ON )
# Find the Qt widgets package. This locates the relevant include and
# lib directories, and the necessary static libraries for linking.
find_package( Qt6Widgets )
set( UIS mainwindow.ui )
qt6_wrap_ui( UI_Srcs ${UIS} )
set( ICONS Icons/icons.qrc )
qt6_add_resources( QRC_Srcs ${ICONS} )
# Also link to VTK
find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )
# Define the executable output and its sources
add_executable( QtVTKExample MACOSX_BUNDLE
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
tabcontent.cpp
tabcontent.h
tabcontent.ui
currentstl.cpp
currentstl.h
recentstl.cpp
recentstl.h
${UI_Srcs}
${QRC_Srcs}
)
# Tell CMake that the executable depends on the Qt::Widget libraries.
target_link_libraries( QtVTKExample Qt6::Widgets )
# Tell CMake that the executable depends on the VTK libraries
target_link_libraries( QtVTKExample ${VTK_LIBRARIES} )
# /calc_cmake/CMakeLists.txt
install(TARGETS QtVTKExample
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)

how do i distribute static library built using cmake

I have a cmake project which is a static library that i have to share with other teams in my company but just the .lib file and not the source code.
This library depends on Boost.
Now i build the library and transfer the install folder onto another pc (exe_pc) and use it in a exe project (this exe also depends on boost).
Now at compile time i get a linking error saying that E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib cannot be opened.
so i open and check the generated LibTargets.cmake and it contains absolute paths of boost library for pc on which the library was built.
# The installation prefix configured by this project.
set(_IMPORT_PREFIX "C:/Program Files/cpp_licensing")
# Create imported target Licensing::liblicensing
add_library(Licensing::liblicensing STATIC IMPORTED)
set_target_properties(Licensing::liblicensing PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "_LICENSING_DEBUG=0"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_system-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_system-vc140-mt-gd.lib>;\$<\$<NOT:\$<CONFIG:DEBUG>>:E:/Development/vcpkg/installed/x64-windows/lib/boost_filesystem-vc140-mt.lib>;\$<\$<CONFIG:DEBUG>:E:/Development/vcpkg/installed/x64-windows/debug/lib/boost_filesystem-vc140-mt-gd.lib>;cryptopp-static;wbemuuid"
)
LibLicensingTargets-release.cmake
et_target_properties(Licensing::liblicensing PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX"
IMPORTED_LOCATION_RELEASE "C:/Program Files/cpp_licensing/lib/licensing.lib"
)
list(APPEND _IMPORT_CHECK_TARGETS Licensing::liblicensing )
list(APPEND _IMPORT_CHECK_FILES_FOR_Licensing::liblicensing "C:/Program Files/cpp_licensing/lib/licensing.lib" )
The user is supposed to have boost installed, the only problem i have is that because absolute paths are used in targets file user has to manually change them on his pc in the targets file.
what changes do i make to cmake so that the libraries built folder can be shared. How do i distribute a library built using cmake ??
Here is the cmake for the library project
cmake_minimum_required(VERSION 3.10)
project(liblicensing)
message("~~ Project: " ${PROJECT_NAME})
set(LIB_NAME "${PROJECT_NAME}")
set(PROJECT_VERSION 1.0)
include_directories(
${PROJECT_SOURCE_DIR}/include
)
if (WIN32)
find_package(Boost REQUIRED system filesystem)
find_package(cryptopp REQUIRED)
find_package(unofficial-date REQUIRED)
include_directories(
${Boost_INCLUDE_DIR}
)
else()
find_package(date REQUIRED)
endif ()
file(GLOB_RECURSE HEADER_FILES include/*.h include/*.hpp)
file(GLOB_RECURSE SOURCES src/*.cpp)
add_library(${LIB_NAME} STATIC ${SOURCES} ${HEADER_FILES} )
set_target_properties(
${LIB_NAME}
PROPERTIES
OUTPUT_NAME "licensing"
POSITION_INDEPENDENT_CODE ON
CXX_STANDARD 14
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
LINKER_LANGUAGE CXX
)
if (MSVC)
set_target_properties(${LIB_NAME} PROPERTIES DEBUG_POSTFIX "_d")
endif()
add_library(Licensing::liblicensing ALIAS ${LIB_NAME})
set(INSTALLATION_DIR "${CMAKE_INSTALL_PREFIX}")
set(CMAKE_INSTALL_LIBDIR "${INSTALLATION_DIR}/lib")
set(CMAKE_INSTALL_BINDIR "${INSTALLATION_DIR}/bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})
target_include_directories(${LIB_NAME}
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if (WIN32)
target_link_libraries(
${LIB_NAME}
${Boost_LIBRARIES}
cryptopp-static
wbemuuid
)
else()
target_link_libraries(
${LIB_NAME}
cryptopp
boost_system
boost_filesystem
)
endif ()
if(CMAKE_BUILD_TYPE MATCHES Debug)
target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=1)
elseif(CMAKE_BUILD_TYPE MATCHES Release)
target_compile_definitions(${LIB_NAME} PUBLIC _LICENSING_DEBUG=0)
endif()
# Expose Projects's public includes to other subprojects through cache variable.
set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
###############
# Installation
##
install(TARGETS ${LIB_NAME}
EXPORT LibLicensingTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
# INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${LIB_NAME}
FILES_MATCHING PATTERN "*.h*")
install(EXPORT LibLicensingTargets
FILE LibLicensingTargets.cmake
NAMESPACE Licensing::
DESTINATION ${INSTALL_CONFIGDIR}
)
#####################
# ConfigVersion file
##
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/LibLicensingConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
## Install all the helper files
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/LibLicensingConfigVersion.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)
Not an entire answer but too much for a comment:
If you inspect your file LibLicensingTargets.cmake closely, you see that cryptopp-static and wbemuuid are not resolved down to the library level.
Looking at how you reference Boost you use the oldstyle version (${Boost_LIBRARIES}) that resolves down to the library level.
Try instead to use the targets provided by FindBoost.cmake module as follows:
if (WIN32)
target_link_libraries(
${LIB_NAME}
Boost::system
Boost::filesystem
cryptopp-static
wbemuuid
)
else()
target_link_libraries(
${LIB_NAME}
cryptopp
Boost::system
Boost::filesystem
)
endif()
Another thing that puzzles me is why you added the ALIAS:
add_library(Licensing::liblicensing ALIAS ${LIB_NAME})
This ALIAS is properly created in the LibLicensingTargets.cmake file, so you do not need to create it on your own.
Another thing is, that you are giving your INSTALL command absolute paths. To make the package entirely relocatable you need to use relative paths (relative to the CMAKE_INSTALL_PREFIX, the installation directory).
The following commands should therefore be changed to:
set(CMAKE_INSTALL_LIBDIR "lib")
set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${LIB_NAME})
If you further add the line:
export(TARGETS liblicensing NAMESPACE LibLicensing:: FILE LibLicensingTargets.cmake)
to your CMakeLists.txt, outside projects are able to import target from your build tree folder as of liblicensing was installed therein. See the CMake documentation of the export command.

CMake - Using my other projects code in my current project

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.

How to create a CMakeLists.txt for a project containing CGAL and VTK libraries

I've written a small programm for evaluating sientific data (3D surface mesh). I do all the geometric calculations with functions provided by the vtk library. The vtkBooleanOperationPolyDataFilter is no robust and crashes randomly. So i decided to performe the boolean operations with functions of the cgal library (tested with some sample data -> no stability problems).
Now I want to merge this two projects together.
The vtk project CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
PROJECT(calcporosity)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(calcporosity MACOSX_BUNDLE calcporosity)
if(VTK_LIBRARIES)
target_link_libraries(calcporosity ${VTK_LIBRARIES})
else()
target_link_libraries(calcporosity vtkHybrid vtkWidgets)
endif()
The cgal project CMakeLists.txt:
project( cgal_test )
cmake_minimum_required(VERSION 2.6.2)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER
2.6) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}"
VERSION_GREATER 2.8.3)
cmake_policy(VERSION 2.8.4) else()
cmake_policy(VERSION 2.6) endif() endif()
find_package(CGAL QUIET COMPONENTS Core )
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )
include_directories (BEFORE "../../include")
include_directories (BEFORE "include")
create_single_source_cgal_program( "cgaltest.cpp" ) else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()
I tried to merge this to files but I've failed. Could some give me a hint how to create a proper CMakeLists.txt for a project which utilizes both libraries.
Thanks in advance and best regards!
P.s.: I'm working on a Windows plattform
Basically what needs to happen is that you need to provide include directories and link libraries from both of your dependencies to your executable.
cmake_minimum_required(VERSION 2.8.4)
project( cgal_vtk_test )
# Find CGAL
find_package(CGAL REQUIRED COMPONENTS Core) # If the dependency is required, use REQUIRED option - if it's not found CMake will issue an error
include( ${CGAL_USE_FILE} )
# Find VTK
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
# Setup your executable
include_directories (BEFORE "../../include")
include_directories (BEFORE "include")
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "cgal_vtk_test.cpp" ) # This will create an executable target with name 'cgal_vtk_test'
# Add VTK link libraries to your executable target
target_link_libraries(cgal_vtk_test ${VTK_LIBRARIES})

Want to make standalone program with cmake

My program uses giblib and Imlib2 library and it is built with cmake.
It works perfectly in my computer but not in other's.
I guess the reason is I installed every library what my program needs but other's doesn't.
My goal is making standalone program. (don't need to install any other library addtionally)
What should I add in cmake file?
projectDef.cmake source code
file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
X11/[^.]*.cpp
X11/[^.]*.h
X11/[^.]*.cmake
)
SOURCE_GROUP(X11 FILES ${PLATFORM})
add_definitions(
)
set (SOURCES
${SOURCES}
${PLATFORM}
)
add_x11_plugin(${PROJECT_NAME} SOURCES)
target_link_libraries(${PROJECT_NAME}
${PLUGIN_INTERNAL_DEPS}
)
include_directories(/usr/include/giblib)
include_directories(/usr/include/X11)
target_link_libraries(MyProject X11)
target_link_libraries(MyProject Imlib2)
target_link_libraries(MyProject giblib)
CMakeList.txt source code
cmake_minimum_required (VERSION 2.6)
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
Project(${PLUGIN_NAME})
file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
[^.]*.cpp
[^.]*.h
[^.]*.cmake
)
include_directories(${PLUGIN_INCLUDE_DIRS})
SET_SOURCE_FILES_PROPERTIES(
${GENERATED}
PROPERTIES
GENERATED 1
)
SOURCE_GROUP(Generated FILES
${GENERATED}
)
SET( SOURCES
${GENERAL}
${GENERATED}
)
include_platform()
Try starting with this options in your root CMakeLists.txt:
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
BUILD_SHARED_LIBS is only needed if your project has its own libraries (add_library).
With the -static linker flag, you need static libs for ALL your additional libraries too! One common problem when static linking is to avoid circular dependencies.