diff options
| -rw-r--r-- | modules/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | modules/CheckCXXSourceCompiles.cmake | 68 | ||||
| -rw-r--r-- | modules/CheckCXXSourceRuns.cmake | 81 | ||||
| -rw-r--r-- | modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake | 81 | 
4 files changed, 231 insertions, 1 deletions
| diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 675659c4..70df69b2 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,4 +1,4 @@ -# install the cmake files +## install the cmake files  file(GLOB cmakeFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.cmake") diff --git a/modules/CheckCXXSourceCompiles.cmake b/modules/CheckCXXSourceCompiles.cmake new file mode 100644 index 00000000..ba7f185c --- /dev/null +++ b/modules/CheckCXXSourceCompiles.cmake @@ -0,0 +1,68 @@ +# - Check if the source code provided in the SOURCE argument compiles. +# CHECK_CXX_SOURCE_COMPILES(SOURCE VAR) +# - macro which checks if the source code compiles +#  SOURCE - source code to try to compile +#  VAR    - variable to store whether the source code compiled +# +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +#  CMAKE_REQUIRED_FLAGS = string of compile command line flags +#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +#  CMAKE_REQUIRED_INCLUDES = list of include directories +#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link + +GET_FILENAME_COMPONENT(_CHECK_CXX_SOURCE_COMPILES_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) +INCLUDE(${_CHECK_CXX_SOURCE_COMPILES_DIR}/HandleImportedTargetsInCMakeRequiredLibraries.cmake) + + +MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) +  IF("${VAR}" MATCHES "^${VAR}$") +    SET(MACRO_CHECK_FUNCTION_DEFINITIONS +      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") +    IF(CMAKE_REQUIRED_LIBRARIES) +      # this one translates potentially used imported library targets to their files on disk +      HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES(_CHECK_CXX_SOURCE_COMPILES_CMAKE_REQUIRED_LIBRARES) + +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES +        "-DLINK_LIBRARIES:STRING=${_CHECK_CXX_SOURCE_COMPILES_CMAKE_REQUIRED_LIBRARES}") +#        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") +    ELSE(CMAKE_REQUIRED_LIBRARIES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES) +    ENDIF(CMAKE_REQUIRED_LIBRARIES) +    IF(CMAKE_REQUIRED_INCLUDES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES +        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") +    ELSE(CMAKE_REQUIRED_INCLUDES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES) +    ENDIF(CMAKE_REQUIRED_INCLUDES) +    FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" +      "${SOURCE}\n") + +    MESSAGE(STATUS "Performing Test ${VAR}") +    TRY_COMPILE(${VAR} +      ${CMAKE_BINARY_DIR} +      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx +      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} +      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} +      "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}" +      "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}" +      OUTPUT_VARIABLE OUTPUT) +    IF(${VAR}) +      SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") +      MESSAGE(STATUS "Performing Test ${VAR} - Success") +      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log +        "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n" +        "${OUTPUT}\n" +        "Source file was:\n${SOURCE}\n") +    ELSE(${VAR}) +      MESSAGE(STATUS "Performing Test ${VAR} - Failed") +      SET(${VAR} "" CACHE INTERNAL "Test ${VAR}") +      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log +        "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n" +        "${OUTPUT}\n" +        "Source file was:\n${SOURCE}\n") +    ENDIF(${VAR}) +  ENDIF("${VAR}" MATCHES "^${VAR}$") +ENDMACRO(CHECK_CXX_SOURCE_COMPILES) + diff --git a/modules/CheckCXXSourceRuns.cmake b/modules/CheckCXXSourceRuns.cmake new file mode 100644 index 00000000..c18d8b37 --- /dev/null +++ b/modules/CheckCXXSourceRuns.cmake @@ -0,0 +1,81 @@ +# - Check if the C++ source code provided in the SOURCE argument compiles and runs. +# CHECK_CXX_SOURCE_RUNS(SOURCE VAR) +# +#  SOURCE - source code to try to compile +#  VAR    - variable to store the result, 1 for success, empty for failure +# +# The following variables may be set before calling this macro to +# modify the way the check is run: +# +#  CMAKE_REQUIRED_FLAGS = string of compile command line flags +#  CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar) +#  CMAKE_REQUIRED_INCLUDES = list of include directories +#  CMAKE_REQUIRED_LIBRARIES = list of libraries to link + +GET_FILENAME_COMPONENT(_CHECK_CXX_SOURCE_RUNS_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) +INCLUDE(${_CHECK_CXX_SOURCE_RUNS_DIR}/HandleImportedTargetsInCMakeRequiredLibraries.cmake) + +MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR) +  IF("${VAR}" MATCHES "^${VAR}$") +    SET(MACRO_CHECK_FUNCTION_DEFINITIONS  +      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") +    IF(CMAKE_REQUIRED_LIBRARIES) +      # this one translates potentially used imported library targets to their files on disk +      HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES(_CHECK_CXX_SOURCE_RUNS_CMAKE_REQUIRED_LIBRARES) + +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES +        "-DLINK_LIBRARIES:STRING=${_CHECK_CXX_SOURCE_RUNS_CMAKE_REQUIRED_LIBRARES}") +#        "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") +    ELSE(CMAKE_REQUIRED_LIBRARIES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES) +    ENDIF(CMAKE_REQUIRED_LIBRARIES) +    IF(CMAKE_REQUIRED_INCLUDES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES +        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") +    ELSE(CMAKE_REQUIRED_INCLUDES) +      SET(CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES) +    ENDIF(CMAKE_REQUIRED_INCLUDES) +    FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx" +      "${SOURCE}\n") + +    MESSAGE(STATUS "Performing Test ${VAR}") +    TRY_RUN(${VAR}_EXITCODE ${VAR}_COMPILED +      ${CMAKE_BINARY_DIR} +      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx +      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} +      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} +      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} +      "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}" +      "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}" +      COMPILE_OUTPUT_VARIABLE OUTPUT) + +    # if it did not compile make the return value fail code of 1 +    IF(NOT ${VAR}_COMPILED) +      SET(${VAR}_EXITCODE 1) +    ENDIF(NOT ${VAR}_COMPILED) +    # if the return value was 0 then it worked +    IF("${${VAR}_EXITCODE}" EQUAL 0) +      SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") +      MESSAGE(STATUS "Performing Test ${VAR} - Success") +      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log  +        "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n" +        "${OUTPUT}\n"  +        "Return value: ${${VAR}}\n" +        "Source file was:\n${SOURCE}\n") +    ELSE("${${VAR}_EXITCODE}" EQUAL 0) +      IF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN") +        SET(${VAR} "${${VAR}_EXITCODE}") +      ELSE(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN") +        SET(${VAR} "" CACHE INTERNAL "Test ${VAR}") +      ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN") + +      MESSAGE(STATUS "Performing Test ${VAR} - Failed") +      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log  +        "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n" +        "${OUTPUT}\n"   +        "Return value: ${${VAR}_EXITCODE}\n" +        "Source file was:\n${SOURCE}\n") +    ENDIF("${${VAR}_EXITCODE}" EQUAL 0) +  ENDIF("${VAR}" MATCHES "^${VAR}$") +ENDMACRO(CHECK_CXX_SOURCE_RUNS) + diff --git a/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake b/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake new file mode 100644 index 00000000..28564ab6 --- /dev/null +++ b/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake @@ -0,0 +1,81 @@ + +# This is a helper function used by CheckCXXSourceRuns.cmake and  +# CheckCXXSourceCompiles.cmake. Actually it should be used by all macros which  +# use TRY_COMPILE() or TRY_RUN(). +# It takes the CMAKE_REQUIRED_LIBRARY variable and searches it for imported +# (library) targets. Since the project created by TRY_COMPILE() (and TRY_RUN()) +# does not know about these imported targets, this macro here replaces these +# imported targets with the actual library files on disk and it also +# adds the libraries from the link interface of these imported targets. +# E.g the imported target KDE4__kdeui is replaced on my system with /opt/kdelibs/lib/libkdeui.so +# and the link interface libraries, which includes e.g. /opt/kdelibs/lib/libkdecore.so. +# This way imported targets work also when used with CHECK_CXX_SOURCE_COMPILES/RUNS(). + +# Copyright (c) 2009, Alexander Neundorf, <neundorf@kde.org> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +FUNCTION(HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES _RESULT) +# handle imported library targets +   SET(_CCSR_IMP_TARGETS_MAP) +   SET(_CCSR_REQ_LIBS ${CMAKE_REQUIRED_LIBRARIES}) +   SET(_CHECK_FOR_IMPORTED_TARGETS TRUE) +   SET(_CCSR_LOOP_COUNTER 0) +   WHILE(_CHECK_FOR_IMPORTED_TARGETS) +      MATH(EXPR _CCSR_LOOP_COUNTER "${_CCSR_LOOP_COUNTER} + 1 ") +      SET(_CCSR_NEW_REQ_LIBS ) +      SET(_CHECK_FOR_IMPORTED_TARGETS FALSE) +      FOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS}) +         GET_TARGET_PROPERTY(_importedConfigs ${_CURRENT_LIB} IMPORTED_CONFIGURATIONS) +         IF (_importedConfigs) +            # Ok, so this is an imported target. +            # First we get the imported configurations. +            # Then we get the location of the actual library on disk of the first configuration. +            # then we'll get its link interface libraries property, +            # iterate through it and replace all imported targets we find there +            # with there actual location. + +            # guard against infinite loop: abort after 100 iterations ( 100 is arbitrary chosen) +            IF ("${_CCSR_LOOP_COUNTER}" LESS 100) +               SET(_CHECK_FOR_IMPORTED_TARGETS TRUE) +#                ELSE ("${_CCSR_LOOP_COUNTER}" LESS 1) +#                   MESSAGE(STATUS "********* aborting loop, counter : ${_CCSR_LOOP_COUNTER}") +            ENDIF ("${_CCSR_LOOP_COUNTER}" LESS 100) + +            LIST(GET _importedConfigs 0 _firstImportedConfig) +            GET_TARGET_PROPERTY(_firstImportedLocation ${_CURRENT_LIB} LOCATION_${_firstImportedConfig}) +            GET_TARGET_PROPERTY(_linkInterfaceLibs ${_CURRENT_LIB} IMPORTED_LINK_INTERFACE_LIBRARIES_${_firstImportedConfig} ) + +            LIST(APPEND _CCSR_NEW_REQ_LIBS  ${_firstImportedLocation}) +#                MESSAGE(STATUS "Appending lib ${_CURRENT_LIB} as ${_firstImportedLocation}") +            FOREACH(_currentLinkInterfaceLib ${_linkInterfaceLibs}) +#                   MESSAGE(STATUS "Appending link interface lib ${_currentLinkInterfaceLib}") +               LIST(APPEND _CCSR_NEW_REQ_LIBS ${_currentLinkInterfaceLib} ) +            ENDFOREACH(_currentLinkInterfaceLib ${_linkInterfaceLibs}) +         ELSE(_importedConfigs) +            # "Normal" libraries are just used as they are. +            LIST(APPEND _CCSR_NEW_REQ_LIBS ${_CURRENT_LIB} ) +#                MESSAGE(STATUS "Appending lib directly: ${_CURRENT_LIB}") +         ENDIF(_importedConfigs) +      ENDFOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS}) + +      SET(_CCSR_REQ_LIBS ${_CCSR_NEW_REQ_LIBS} ) +   ENDWHILE(_CHECK_FOR_IMPORTED_TARGETS) + +   # Finally we iterate once more over all libraries. This loop only removes +   # all remaining imported target names (there shouldn't be any left anyway). +   SET(_CCSR_NEW_REQ_LIBS ) +   FOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS}) +      GET_TARGET_PROPERTY(_importedConfigs ${_CURRENT_LIB} IMPORTED_CONFIGURATIONS) +      IF (NOT _importedConfigs) +         LIST(APPEND _CCSR_NEW_REQ_LIBS ${_CURRENT_LIB} ) +#             MESSAGE(STATUS "final: appending ${_CURRENT_LIB}") +      ELSE (NOT _importedConfigs) +#             MESSAGE(STATUS "final: skipping ${_CURRENT_LIB}") +      ENDIF (NOT _importedConfigs) +   ENDFOREACH(_CURRENT_LIB ${_CCSR_REQ_LIBS}) +   SET(${_RESULT} ${_CCSR_NEW_REQ_LIBS} PARENT_SCOPE) + +ENDFUNCTION(HANDLE_IMPORTED_TARGETS_IN_CMAKE_REQUIRED_LIBRARIES _CCSR_REQ_LIBS) + | 
