Setting the library path for Boosts tests with CMake in Windows

872 views Asked by At

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?

0

There are 0 answers