I have compiled program with cmake.The cmakelist.txt:
cmake_minimum_required (VERSION 2.6)
project (clustering)
IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(LIB_SUFFIX "")
ELSE(CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(LIB_SUFFIX 64)
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}")
find_package(Eigen2 REQUIRED)
include_directories(${Eigen2_INCLUDE_DIR})
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(LIB_NAME clusteringd)
else(CMAKE_BUILD_TYPE MATCHES "Debug")
set(LIB_NAME clustering)
endif(CMAKE_BUILD_TYPE MATCHES "Debug")
file(GLOB LIB_PUBLIC_HEADERS "${CMAKE_SOURCE_DIR}/*.h")
file(GLOB LIB_SOURCES "${CMAKE_SOURCE_DIR}/*.cpp")
#add_library (${LIB_NAME}-s STATIC ${LIB_PUBLIC_HEADERS} ${LIB_SOURCES})
add_library (${LIB_NAME} SHARED ${LIB_PUBLIC_HEADERS} ${LIB_SOURCES})
install(
TARGETS ${LIB_NAME}
LIBRARY DESTINATION lib${LIB_SUFFIX}
)
#install(
# TARGETS ${LIB_NAME}-s
# ARCHIVE DESTINATION lib${LIB_SUFFIX}
#)
install(
FILES ${LIB_PUBLIC_HEADERS}
DESTINATION include/${LIB_NAME}
)
The problem is that in my folder /clusteringmaster/build/CMakeFiles/2.8.12.2/ I have two folders CompilerIdC and CompilerIdCXX,both of them have exe file.As Sergey pointed out exe should be located in bin directory.When I list my CmakeFile
2.8.12.2 cmake.check_cache CMakeOutput.log Makefile2 progress.marks
clustering.dir CMakeDirectoryInformation.cmake CMakeTmp Makefile.cmake TargetDirectories.txt
From the authors tutorial
Build
You will need the Eigen2 library (libeigen2-devel) and CMake (only tested under Linux).
$ mkdir release
$ cd release
$ cmake ../
$ make
Should I write cmake -- build /home/milenko/clusteing-master/release?
I have not worked with cmake before,how should I solve this confusion?
One item is that should use the cmake variable ${PROJECT_NAME} as the target name for the add_library command. (Your project name is specified as "clustering" because of the project (clustering) statement.) To get a d suffix for the debug configuration build, use set(CMAKE_DEBUG_POSTFIX d). I also like to set the output directory variables using
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
(I will even set the _DEBUG and _RELEASE variants, but this may cause problems when you are first getting started, so I would wait before doing that.)
Related
I want to build an application that depends on the OpenCV (version 3.4.6) viz module. This module has the VTK library (version 7.1.1) as dependency. I want to use ExternalProject to build both, the vtk library and the opencv viz module and subsequently want to build the main application, all in one cmake run.
.
├── CMakeLists.txt
├── deps
│ └── CMakeLists.txt
└── main.cpp
I am using the cmake ExternalProject module to build both opencv and vtk inside a subdirectory like this:
deps/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(dependencies)
include(ExternalProject)
ExternalProject_add(
vtklib
GIT_REPOSITORY https://github.com/Kitware/vtk
GIT_TAG v7.1.1
GIT_PROGRESS TRUE
UPDATE_COMMAND ""
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DBUILD_TESTING=OFF
-DBUILD_EXAMPLES=OFF
-DVTK_DATA_EXCLUDE_FROM_ALL=ON
-DVTK_USE_CXX11_FEATURES=ON
-Wno-dev
)
add_library(vtk INTERFACE IMPORTED GLOBAL)
add_dependencies(vtk vtklib)
ExternalProject_add(
ocv
GIT_REPOSITORY https://github.com/opencv/opencv
GIT_TAG 3.4.6
GIT_PROGRESS TRUE
UPDATE_COMMAND ""
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DWITH_VTK=ON
-Wno-dev
)
# ExternalProject_Get_Property(ocv install_dir)
# include_directories(${install_dir}/src/ocv/include)
include_directories(${CMAKE_INSTALL_PREFIX}/include)
set(ocv_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_VS_PLATFORM_NAME}/vc15)
set(OCV_VERSION 346)
add_dependencies(ocv vtklib)
add_library(opencv_core SHARED IMPORTED)
set_target_properties(opencv_core PROPERTIES
IMPORTED_IMPLIB "${ocv_libdir}/lib/opencv_core${OCV_VERSION}.lib"
IMPORTED_LOCATION "${ocv_libdir}/bin/opencv_core${OCV_VERSION}.dll"
)
add_library(opencv_viz SHARED IMPORTED)
set_target_properties(opencv_viz PROPERTIES
IMPORTED_IMPLIB "${ocv_libdir}/lib/opencv_viz${OCV_VERSION}.lib"
IMPORTED_LOCATION "${ocv_libdir}/bin/opencv_viz${OCV_VERSION}.dll"
)
the main CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.14)
project(cmaketest VERSION 0.1 DESCRIPTION "" LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_Flags "${CMAKE_CXX_FLAGS} -std=c++17")
# include_directories(${CMAKE_INSTALL_PREFIX}/include)
add_subdirectory(deps)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} opencv_core opencv_viz)
install(
TARGETS ${PROJECT_NAME}
EXPORT "${PROJECT_NAME}-targets"
LIBRARY DESTINATION lib/
ARCHIVE DESTINATION lib/${CMAKE_PROJECT_NAME}
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include/${CMAKE_PROJECT_NAME}/${PROJECT_NAME}
)
the main.cpp for completeness:
#include <opencv2/viz.hpp>
int main(){}
but it seems that the include_directories and add_library calls inside deps/CMakeLists.txt do not work on the correct scope as i am getting the following error messages:
error C1083: File (Include) can not be opened: "opencv2/viz.hpp"
if i uncomment the include_directories inside the main CMakeLists.txt then i get a linker error (this is not what i want, included directories should be specified inside deps/CMakeLists.txt):
LNK1181: opencv_core.lib can not be opened
If i just copy the contents of deps/CMakeLists.txt in the main CMakeLists.txt in place of the add_subdirectory call everything works fine.
So, how do i get the include directories and the created targets from the subdirectory in my main CMakeLists?
edit:
call to cmake configure:
cmake.exe -B build -S . -G "Visual Studio 17 2022" -A x64 -T v141 -DCMAKE_INSTALL_PREFIX=D:/test
call to cmake build:
cmake.exe --build build --config Release --target install
Unlike to normal targets, which are global, an IMPORTED target by default is local to the directory where it is created.
For extend visibility of the IMPORTED target, use GLOBAL keyword:
add_library(opencv_core SHARED IMPORTED GLOBAL)
This is written in the documentation for add_library(IMPORTED):
The target name has scope in the directory in which it is created and below, but the GLOBAL option extends visibility.
cmake has couple steps:
configuration
generation (depends on configuration)
build (depends on generation)
test (depends on build)
install (depends on build)
Now problem is that your build step depends on result of install step. This happens here:
set(ocv_libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_VS_PLATFORM_NAME}/vc15)
and when this variable is used.
This is causing that to be able to complete build step you need success in install step. And cmake will do install step after successful build. So you have dependency cycle.
Instead importing opencv as shared library:
add_library(opencv_viz SHARED IMPORTED)
Link your target with targets created by imported project of opnecv.
I have a library that uses CMake as a building system. It builds for ubuntu, but not for windows.
The issue happens because on windows it searches 'Math.h' in system directories first, but not in the project's 'include' directory.
I've tried to rename all 'Math' files and class by 'Math2' and it works great. But I don't want to rename the class and files.
What do I have to do?
CMakeLists.txt:
cmake_minimum_required (VERSION 3.10)
project (Bint
VERSION "0.1.0"
DESCRIPTION "Bint is an arbitrary-precision arithmetic library."
LANGUAGES CXX
)
enable_testing()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
if(MSVC)
#add_compile_options(/Wall)
else()
add_compile_options(-Wall -Wextra -pedantic)
endif()
include_directories(BEFORE ./include)
set(BINT_SRC src/Bint.cpp)
set(MATH_SRC src/Math.cpp)
add_library(shareobjects OBJECT ${BINT_SRC} ${MATH_SRC})
add_executable(test-main-fast tests/main.cpp ${BINT_SRC} ${MATH_SRC})
set_target_properties(test-main-fast PROPERTIES COMPILE_FLAGS -Ofast)
add_test(NAME tst-main-fast COMMAND ./test-main-fast)
aux_source_directory(tests TESTS)
foreach(tstfile ${TESTS})
string(REGEX MATCH "\/(.*)\\.[^.]*$" dummy ${tstfile})
add_executable(test-${CMAKE_MATCH_1} ${tstfile} $<TARGET_OBJECTS:shareobjects>)
add_test(NAME tst-${CMAKE_MATCH_1} COMMAND ./test-${CMAKE_MATCH_1})
endforeach()
add_library(Bint SHARED ${BINT_SRC} ${MATH_SRC})
set_target_properties(test-main-fast PROPERTIES COMPILE_FLAGS -Ofast)
add_library(Bint_static STATIC $<TARGET_OBJECTS:shareobjects>)
set_target_properties(Bint_static PROPERTIES OUTPUT_NAME Bint)
From my own search, I'm not exactly sure what the "normal" behaviour is:
Does CMake normally rebuild .obj-files when a header included in the associated source file changes?
Because it doesn't do that in my project at all. Here's my top-level CMakeLists.txt:
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# project and binary name
project("myProjectName")
# compiler specific warnings
# and warnings are treated as errors
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(warnings "-Wall -Wextra -Werror")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(warnings "/W4 /WX /EHsc")
endif()
if (NOT CONFIGURED_ONCE)
set(CMAKE_CXX_FLAGS "${warnings}"
CACHE STRING "Flags used by the compiler during all build types." FORCE)
set(CMAKE_C_FLAGS "${warnings}"
CACHE STRING "Flags used by the compiler during all build types." FORCE)
endif()
# default build-type is Debug:
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
# =============================
# libraries
# =============================
# external
# eigen numerics library
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
set( EIGEN Eigen3::Eigen )
# some internal libraries here
set( LIB_NAME_1 lib1 )
set( LIB_NAME_2 lib2 )
# =============================
# directory configuration
# =============================
# for finding libraries and such in the project's subdirectories
# all paths are prepended with the project's root directory
set(CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR})
# specifiying output directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# the last one is disabled to allow for tests in a different directory
# include paths
include_directories(
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/lib # I put header-only libraries there
${CMAKE_SOURCE_DIR}/src # for template definitions
)
# =============================
# unit test configuration
# =============================
# enable_testing() sets the internal flag "CMAKE_TESTING_ENABLED" to 1
# add_test() commands are only run when enable_testing() has executed.
# here, it is only executed in debug mode
if(CMAKE_BUILD_TYPE MATCHES Debug)
enable_testing()
endif()
# the unit test framework used here is "Catch2" (single header file "catch.hpp")
# (https://github.com/catchorg/Catch2)
if ( ${CMAKE_TESTING_ENABLED} )
message( "-- Tests are enabled" )
set( UNIT_TEST_LIB catch2 )
endif()
# =============================
# subdir calls
# =============================
# the second parameter specifies the output path for binaries.
# however, the respective CMAKE_XYZ_OUTPUT_DIRECTORY takes precedence
add_subdirectory(lib)
add_subdirectory(src bin)
if ( ${CMAKE_TESTING_ENABLED} )
add_subdirectory(tests tests)
endif()
and then I have another CMakeLists.txt in lib, src and tests. These contain only addLibrary, addExecutable and targetLinkLibraries commands using the appropriate source files. Except in "tests", where there's also addTest and addCustomCommand to make the unit test executable run after building.
Here's the question: Did I miss something and it should be rebuilding when a header changes (1)? Or is this the normal behaviour (2)?
Possibly related questions:
Rebuilding object files when a header changes
Make doesn't rebuild headers when changed
GCC included header (using -include) changes not detected by CMake
CMake does rebuild object files when headers change, however CMake 3.15 had a bug where it didn't work properly for make targets. I encountered that issue too, and found that it was already reported: https://gitlab.kitware.com/cmake/cmake/issues/19507
It's fixed in 3.15.1, so the solution is to upgrade (and maybe change the cmake_minimum_required to 3.15.1).
I've started a little project on GitHub for an OpenSceneGraph plugin. Here, I plan on learning how to setup projects with CMake, unit testing with Boost.Test and continuous integration, with Travis-CI.
It has this structure:
root
|-> cmake
|-> conf [Create the `library`-config.cmake and `library`-depends.cmake files]
|-> find [Find module for the custom `Boost` installation at work]
|-> examples
|-> include [*.h]
|-> src [*.src]
|-> test
|-> options [CMakeFile.txt and .cpp file for the test]
|
|-> CMakeFile.txt [Root file]
I have two machines: my laptop, with Linux Mint 16 and g++ 4.8, and my work computer, with Windows 8.1, the MinGW suite and g++ 4.5.
The project (development branch!) builds fine with make, but afterwards, when I try to run the tests with make test in Windows I always end getting these errors:
The program can't start because libboost_unit_test_framework-mgw45-mt-1_51.dll is missing
and in the terminal:
Running tests...
"C:\Program Files (x86)\CMake 2.8\bin\ctest.exe" --force-new-ctest-process
Test project D:/PROJECTS/osgGML/build
Start 1: testOptions
1/1 Test #1: testOptions ......................***Exception: Other 1.84 sec
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 1.84 sec
The following tests FAILED:
1 - testOptions (OTHER_FAULT)
Errors while running CTest
mingw32-make: *** [test] Error 8
Whereas in Linux (tried in Linux Mint 16 and in the Travis-CI machine, it works).
The "root" CMakeFile:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(osgGML)
option(BUILD_SHARED_LIBS "Build shared libs" ON)
option(BUILD_EXAMPLES OFF)
option(BUILD_TESTS OFF)
option(BUILD_USE_LAMBDAS OFF)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Type of build" FORCE)
endif(NOT CMAKE_BUILD_TYPE)
set(LIBRARY_NAME "osgGML")
set(EXPORT_NAME "depends")
set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "" FORCE)
set(CMAKE_COLOR_MAKEFILE ON)
mark_as_advanced(CMAKE_VERBOSE_MAKEFILE)
# Common locatoins for Unix and Mac OS X
set(DEFAULT_BIN_SUBDIR bin)
set(DEFAULT_LIB_SUBDIR lib)
set(DEFAULT_SHARE_SUBDIR share/cmake)
set(DEFAULT_INCLUDE_SUBDIR include)
set(OSGGML_BIN_SUBDIR ${DEFAULT_BIN_SUBDIR} CACHE STRING
"Subdirectory where executables will be installed")
set(OSGGML_LIB_SUBDIR ${DEFAULT_LIB_SUBDIR} CACHE STRING
"Subdirectory where libraries will be installed")
set(OSGGML_INCLUDE_SUBDIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING
"Subdirectory where header files will be installed")
set(OSGGML_SHARE_SUBDIR ${DEFAULT_SHARE_SUBDIR} CACHE STRING
"Subdirectory where data will be installed")
# Full paths for the installation
set(OSGGML_BIN_DIR ${OSGGML_BIN_SUBDIR})
set(OSGGML_LIB_DIR ${OSGGML_LIB_SUBDIR})
set(OSGGML_INCLUDE_DIR ${OSGGML_INCLUDE_SUBDIR})
set(OSGGML_SHARE_DIR ${OSGGML_SHARE_SUBDIR})
##
# Set the build postfix extension according to what configuration is being built.
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually d")
set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty")
set(CMAKE_RELWITHDEBINFO_POSTFIX "rd" CACHE STRING "empty")
set(CMAKE_MINSIZEREL_POSTFIX "s" CACHE STRING "add a postfix, empty")
if(CMAKE_BUILD_TYPE MATCHES "Release")
set(CMAKE_BUILD_POSTFIX "${CMAKE_RELEASE_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "MinSizeRel")
set(CMAKE_BUILD_POSTFIX "${CMAKE_MINSIZEREL_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
set(CMAKE_BUILD_POSTFIX "${CMAKE_RELWITHDEBINFO_POSTFIX}")
elseif(CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_BUILD_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
else()
set(CMAKE_BUILD_POSTFIX "")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
if(BUILD_USE_LAMBDAS)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
if((GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif()
endif()
endif()
find_package(OpenSceneGraph REQUIRED COMPONENTS
osg
osgDB
OpenThreads
)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
link_directories(${OPENSCENEGRAPH_LIBRARY_DIRS})
# HACK!!!! DO THIS PROPERLY!!!
link_directories(${OPENSCENEGRAPH_BINARY_DIRS}/osgPlugins-3.2.1/)
set(DEPENDENCIES ${OPENSCENEGRAPH_LIBRARIES})
##
set(osgGML_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")
set(osgGML_SOURCE_DIRS "${PROJECT_SOURCE_DIR}/src")
set(HEADERS ${osgGML_INCLUDE_DIRS}/DebugUtils.h
${osgGML_INCLUDE_DIRS}/GmlOptions.h
${osgGML_INCLUDE_DIRS}/GmlOptionsIO.h
${osgGML_INCLUDE_DIRS}/GraphVisitor.h
${osgGML_INCLUDE_DIRS}/ReaderWriterGML.h
${osgGML_INCLUDE_DIRS}/Setup.h
)
set(SOURCES ${osgGML_SOURCE_DIRS}/GmlOptions.cpp
${osgGML_SOURCE_DIRS}/GmlOptionsIO.cpp
${osgGML_SOURCE_DIRS}/GraphVisitor.cpp
${osgGML_SOURCE_DIRS}/ReaderWriterGML.cpp
)
include_directories(${osgGML_INCLUDE_DIRS})
add_library(${LIBRARY_NAME} ${SOURCES})
target_link_libraries(${LIBRARY_NAME} ${DEPENDENCIES})
#
install(TARGETS ${LIBRARY_NAME}
EXPORT ${EXPORT_NAME}
RUNTIME DESTINATION ${OSGGML_BIN_DIR}
LIBRARY DESTINATION ${OSGGML_LIB_DIR}
ARCHIVE DESTINATION ${OSGGML_LIB_DIR}
)
install(FILES ${HEADERS} DESTINATION ${OSGGML_INCLUDE_DIR})
if(BUILD_EXAMPLES)
message(STATUS "Building EXAMPLES.")
set(OSGGML_EXAMPLES_BIN_DIR share/examples)
add_subdirectory(examples/options)
add_subdirectory(examples/visitor)
endif()
if(BUILD_TESTS)
enable_testing()
message(STATUS "Building TESTS")
set(OSGGML_TESTS_BIN_DIR share/tests)
add_subdirectory(test/options)
endif()
###########
add_subdirectory(cmake/conf)
###########
The CMakeFile for the test:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(OptionsTesting)
set(CMAKE_BUILD_TYPE "RELEASE")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
link_directories(${CMAKE_BINARY_DIR}/lib)
include_directories(../../include)
set(DEPENDENCIES ${DEPENDENCIES} ${LIBRARY_NAME})
# Hack for my weird Boost installation in Windows.
if(WIN32 AND MINGW)
set(BOOST_ROOT "D:/PROYECTOS/SITEGI/LIBRERIAS/Boost")
include(../../cmake/find/find_boost.cmake)
else()
find_package(Boost REQUIRED COMPONENTS unit_test_framework)
endif()
include_directories (${Boost_INCLUDE_DIRS})
set(DEPENDENCIES ${DEPENDENCIES} ${Boost_LIBRARIES})
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(BOOST_ALL_DYN_LINK ON)
find_package(OpenSceneGraph REQUIRED COMPONENTS osg osgDB OpenThreads)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
link_directories(${OPENSCENEGRAPH_LIBRARY_DIRS})
set(DEPENDENCIES ${DEPENDENCIES} ${OPENSCENEGRAPH_LIBRARIES})
file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
set(TEST_DEST ${CMAKE_BINARY_DIR}/testBinaries)
set(TEST_LINK_DEPS ${TEST_LINK_DEPS} "-Wl,-rpath,${CMAKE_BINARY_DIR}")
set(TEST_LINK_DEPS ${TEST_LINK_DEPS} "-Wl,-rpath,${Boost_LIBRARY_DIRS}")
foreach(testSrc ${TEST_SRCS})
#Extract the filename without an extension (NAME_WE)
get_filename_component(testName ${testSrc} NAME_WE)
add_executable(${testName} ${testSrc})
target_link_libraries(${testName} ${DEPENDENCIES})
set_target_properties(${testName} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${TEST_DEST}
LINK_FLAGS "${TEST_LINK_DEPS}"
)
add_test(NAME ${testName}
WORKING_DIRECTORY ${TEST_DEST}
COMMAND ${TEST_DEST}/${testName}
)
endforeach(testSrc)
I'm trying to tell CMake to use the newly-generated osgGML library in the build directory when linking the test executable (I have checked, libosgGML.dll is in ${CMAKE_BINARY_DIR}.
In this version of the file, I added the rpath to the library. In a previous one, aside from -Wl,-rpath,<library_dirs> I also specified the -L<library_dirs> right after that.
I've tried to link directly the dll's too, but nothing worked.
How can I tell the test executable to "find" the libraries in their respective directories, instead of copying them to the executable dir?
I have a directory structure in CMake as follows:
root
CMakeLists.txt
subproject_folder
my_dll_library
CMakeLists.txt
src
source1.cpp
source2.cpp
inc
library.h
CMakeLists.txt
library_demo
src
demo.cpp
CMakeLists.txt
build
bin
My root CmakeLists.txt contains this:
cmake_minimum_required(VERSION 2.8)
add_subdirectory(subproject_folder)
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
The CMakeLists in the subproject folder just contains
add_subdirectory(my_dll_library)
add_subdirectory(library_demo)
The CMakeLists in the library_demo folder contains
project(library_demo)
add_executable(librarydemo src/demo.cpp)
target_link_libraries(librarydemo my_dll_library)
install(TARGETS librarydemo DESTINATION bin)
The CMakeLists in the my_dll_library folder contains
add_library(lib_zaber SHARED src/source1.cpp src/source2.cpp)
install(TARGETS lib_zaber DESTINATION bin)
I want to have the demo executable and the library DLL copied to the bin folder, but it isn't working.
What am I doing wrong?
Try to set those variables too:
CMAKE_BINARY_DIR
CMAKE_CURRENT_BINARY_DIR
There's a whole list of variables you could try here:
http://www.cmake.org/Wiki/CMake_Useful_Variables
The command
install(.. DESTINATION <dir>)
installs to ${CMAKE_INSTALL_PREFIX}/<dir>.
You need to set CMAKE_INSTALL_PREFIX either in the CMakeLists.txt or when calling cmake:
cmake ... -DCMAKE_INSTALL_PREFIX=<dir>