aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Neundorf <neundorf@kde.org>2009-03-19 00:55:45 +0000
committerAlexander Neundorf <neundorf@kde.org>2009-03-19 00:55:45 +0000
commit3e31cecffb401508cd893032be8b77889c721b83 (patch)
tree4209b1b0332eedca8ff6a9470fcc1bd0e79a4d7e
parentb6b707c5d1cbb53bc3207e12cc57392feb150fa2 (diff)
downloadextra-cmake-modules-3e31cecffb401508cd893032be8b77889c721b83.tar.gz
extra-cmake-modules-3e31cecffb401508cd893032be8b77889c721b83.tar.bz2
-add modified versions of CheckCXXSourceRuns/Compiles.cmake, which can handle imported library targets
(see http://lists.kde.org/?t=123686453500002&r=1&w=2 ) Alex svn path=/trunk/KDE/kdelibs/; revision=941177
-rw-r--r--modules/CMakeLists.txt2
-rw-r--r--modules/CheckCXXSourceCompiles.cmake68
-rw-r--r--modules/CheckCXXSourceRuns.cmake81
-rw-r--r--modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake81
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)
+