CMake: How to automatically rebuild .obj-files when included header changed - c++

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).

Related

I want to link my project with the dynamic library "aravis" in the CMakeLists.txt file, but it always fails

Although I tried some methods, all the libraries involved in my project were not linked, even the most basic rclcpp library.
And there is also the problem that the header file cannot be found in vscode, although I think I have given the path to the header file in CMake and the .so file, but there is still no way to solve the problem.
cmake_minimum_required(VERSION 3.5)
project(camera_aravis)
# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
INCLUDE_DIRECTORIES(/usr/local/include/aravis-0.8
/home/nian/Documents/Dep/glib-2.45.2/glib
/home/nian/Documents/Dep/glib-2.45.2
/home/nian/Documents/Dep/glib-2.45.2/gmodule
/opt/ros/foxy/include
/home/nian/Documents/Dep/xmlrpcpp-master/include/xmlrpcpp
/home/nian/Documents/Dep/xmlrpcpp-master/include
)
LINK_DIRECTORIES(/usr/lib /home/nian/Documents/Dep/glib-2.45.2/glib
)
ADD_EXECUTABLE(camnode src/new.cpp)
TARGET_LINK_LIBRARIES(camnode libaravis-0.8.so libglib-2.0.so libgio-2.0.so
libgobject-2.0.so)
include_directories(
include_directories
${fcl_INCLUDE_DIRS}
)
# find other ROS2 packages
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(camera_info_manager REQUIRED)
find_package(image_transport REQUIRED)
add_executable(test_params_rclcpp src/new.cpp)
ament_target_dependencies(test_params_rclcpp
rclcpp
rclcpp_components
sensor_msgs
std_msgs
camera_info_manager
image_transport
camera_calibration_parsers)
install(TARGETS
test_params_rclcpp
DESTINATION lib/${PROJECT_NAME}
)
add_executable(camera_param_edit src/new.cpp)
ament_target_dependencies(camera_param_edit
rclcpp
rclcpp_components
sensor_msgs
std_msgs
camera_info_manager
image_transport
camera_calibration_parsers)
install(TARGETS
camera_param_edit
DESTINATION lib/${PROJECT_NAME}
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# uncomment the line when a copyright and license is not present in all source files
#set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# uncomment the line when this package is not in a git repo
#set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
This is my CMakeLists, but the error in the terminal is always "undefined reference to".
How can I solve this?
Below is part of my error messagea lot of errors about function references in the library

can I build CMakeLists.txt from a set of smaller files (to improve the readability and maintainability of CMakeLists.txt)

I am building a medium sized C++ library, and my CMakeLists.txt file is starting to get a bit long. I was reading Robert Martin's book The Clean Coder in which he discusses the elements of clean coding style for the sake of code maintenance and readability.
So I wanted to see if I could break up my CMakeLists.txt file into a set of smaller files--that would integrate when I ran a build command. I could then just manage these smaller files, just as I would break up classes into separate files. Now as a caveat, I am not building separate executables for different elements of the library. I am just building a single library with a set of classes and functions that I need for other projects.
Here is my current CMakeLists.txt file. Then I will show how I would like to break it up.
cmake_minimum_required(VERSION 3.7)
project(tvastrCpp)
set (tvastrCpp_VERSION_MAJOR 0)
set (tvastrCpp_VERSION_MINOR 1)
# 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} )
include(ExternalProject)
set(CMAKE_CXX_STANDARD 14)
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
include( ${EIGEN3_USE_FILE} )
endif()
find_package(Boost 1.58.0 REQUIRED COMPONENTS system filesystem program_options chrono timer date_time REQUIRED)
if(NOT Boost_FOUND)
message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.")
endif()
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
ExternalProject_Add(
catch
PREFIX ${CMAKE_BINARY_DIR}/catch
GIT_REPOSITORY https://github.com/philsquared/Catch.git
TIMEOUT 10
UPDATE_COMMAND ${GIT_EXECUTABLE} pull
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD ON
)
ExternalProject_Get_Property(catch source_dir)
set(CATCH_INCLUDE_DIR ${source_dir}/single_include CACHE INTERNAL "Path to include folder for Catch")
INCLUDE_DIRECTORIES ( "${EIGEN3_INCLUDE_DIR}" )
file(GLOB lib_SRC RELATIVE "lib" "*.h" "*.cpp")
file(GLOB test_SRC RELATIVE "tests" "*.h" "*.cpp")
# need to fix the instruction below to reference library
set(SOURCE_FILES ${lib_SRC})
add_library(tvastrCpp SHARED ${SOURCE_FILES})
add_executable(${PROJECT_NAME} main.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp)
add_executable(my_tests testcases.cpp RipsComplex.h RipsComplex.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp)
add_executable(gd_validator gudhi_validator.cpp)
TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} )
enable_testing(true)
add_test(NAME cooltests COMMAND my_tests)
Now I would like to create a separate file for the basic settings piece:
settings.txt:
cmake_minimum_required(VERSION 3.7)
project(tvastrCpp)
set (tvastrCpp_VERSION_MAJOR 0)
set (tvastrCpp_VERSION_MINOR 1)
Then a separate piece for the finding the CGAL library:
find_cgal.txt:
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} )
include(ExternalProject)
set(CMAKE_CXX_STANDARD 14)
find_package(Eigen3 3.1.0)
if (EIGEN3_FOUND)
include( ${EIGEN3_USE_FILE} )
endif()
And so forth.
Split your CMakeLists.txt into:
Project's top file:
Contains all common settings of the project
Includes the external projects
Include the sub directories
Set the common compiler settings
Builds the targets
Reusable functions file:
Store your own CMake macros and functions into a separate file to reuse it in your different projects
Source files:
Place a CMakeList.txt in every subdirectory of source code
Add the sources here to the variable SOURCE and use PARENT SCOPE
Tests:
Use a extra CMakeLists.txt to build the unit tests
Reuse the previous structure of CMake files in case of large test environment
I have small projects with one CMakeLists.txt and large projects for a single library with up to 10 files.

library can't see its own headers

FindFoo.cmake:
# Foo_FOUND - system has Foo
# Foo_INCLUDE_DIRS - the Foo include directories
# Foo_LIBRARIES - link these to use Foo
# Foo_VERSION
# Foo_DEFINITIONS - compiler switches required for using Foo
find_package(PkgConfig)
pkg_check_modules(PC_Foo QUIET Foo)
find_path(Foo_INCLUDE_DIR Foo/Foo.h
PATHS ${PC_Foo_INCLUDEDIR} ${PC_Foo_INCLUDE_DIRS}
)
find_library(Foo_LIBRARY Foo
PATHS ${PC_Foo_LIBDIR} ${PC_Foo_LIBRARY_DIRS}
)
set(Foo_VERSION ${PC_Foo_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo
FOUND_VAR Foo_FOUND
REQUIRED_VARS
Foo_LIBRARY
Foo_INCLUDE_DIR
VERSION_VAR Foo_VERSION
)
if(Foo_FOUND)
set(Foo_LIBRARIES ${Foo_LIBRARY})
set(Foo_INCLUDE_DIRS ${Foo_INCLUDE_DIR})
set(Foo_DEFINITIONS ${PC_Foo_CFLAGS_OTHER})
endif()
mark_as_advanced(
Foo_INCLUDE_DIR
Foo_LIBRARY
)
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
PROJECT(sandbox)
set(CMAKE_AUTOMOC ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
FIND_PACKAGE(Qt5Core REQUIRED)
find_package(Foo REQUIRED)
include_directories(${Foo_INCLUDE_DIRS})
SET(sandbox_SOURCES main.cpp)
ADD_EXECUTABLE(sandbox ${sandbox_SOURCES})
QT5_USE_MODULES(sandbox Core)
TARGET_LINK_LIBRARIES(sandbox ${Foo_LIBRARIES})
#include <Bar1.h> works in my program whereas #include <Foo/Bar1.h> doesn't. and the real problem is that i can't build my program because Bar1.h contains #include <Foo/Bar2.h> and:
...Foo/Bar1.h: fatal error: Foo/Bar2.h: No such file or directory
compilation terminated.
CMake 3.5.1
looks like the problem was CMake cache. i deleted everything from the CMakeFiles directory and then CMake couldn't configure the project:
Could NOT find Foo (missing: Foo_INCLUDE_DIR)
i had to add PATH_SUFFIXES to find_path(), and all the problems are gone.

How to solve this cmake issue with c++ code?

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.)

Setting the library path for Boosts tests with CMake in Windows

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?