diff options
202 files changed, 3419 insertions, 743 deletions
diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in index 640bf70..9cff735 100644 --- a/Modules/AutomocInfo.cmake.in +++ b/Modules/AutomocInfo.cmake.in @@ -6,10 +6,9 @@ set(AM_MOC_OPTIONS @_moc_options@) set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") -set(AM_QT_MOC_EXECUTABLE "@QT_MOC_EXECUTABLE@") +set(AM_QT_MOC_EXECUTABLE "@_qt_moc_executable@") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") -set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) -set(AM_Qt5Core_VERSION_MAJOR "@Qt5Core_VERSION_MAJOR@" ) +set(AM_QT_VERSION_MAJOR "@_target_qt_version@") set(AM_TARGET_NAME @_moc_target_name@) set(AM_RELAXED_MODE "@_moc_relaxed_mode@") diff --git a/Modules/CMakeBackwardCompatibilityC.cmake b/Modules/CMakeBackwardCompatibilityC.cmake index e3b6c82..4783d68 100644 --- a/Modules/CMakeBackwardCompatibilityC.cmake +++ b/Modules/CMakeBackwardCompatibilityC.cmake @@ -55,7 +55,7 @@ if(NOT CMAKE_SKIP_COMPATIBILITY_TESTS) TEST_BIG_ENDIAN(CMAKE_WORDS_BIGENDIAN) include (FindX11) - if("${X11_X11_INCLUDE_PATH}" MATCHES "^/usr/include$") + if("${X11_X11_INCLUDE_PATH}" STREQUAL "/usr/include") set (CMAKE_X_CFLAGS "" CACHE STRING "X11 extra flags.") else() set (CMAKE_X_CFLAGS "-I${X11_X11_INCLUDE_PATH}" CACHE STRING diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake index 562e248..5cd62f6 100644 --- a/Modules/CTest.cmake +++ b/Modules/CTest.cmake @@ -84,13 +84,13 @@ if(BUILD_TESTING) endmacro() macro(SET_IF_SET var val) - if(NOT "${val}" MATCHES "^$") + if(NOT "${val}" STREQUAL "") set("${var}" "${val}") endif() endmacro() macro(SET_IF_SET_AND_NOT_SET var val) - if(NOT "${val}" MATCHES "^$") + if(NOT "${val}" STREQUAL "") SET_IF_NOT_SET("${var}" "${val}") endif() endmacro() diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 187f408..50669bd 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -391,7 +391,7 @@ function(_ExternalData_arg target arg options var_file) # Regular expression to match associated files. string(REGEX REPLACE "^REGEX:" "" regex "${opt}") list(APPEND associated_regex "${regex}") - elseif("x${opt}" MATCHES "^x:$") + elseif(opt STREQUAL ":") # Activate series matching. set(series_option "${opt}") elseif("x${opt}" MATCHES "^[^][:/*?]+$") @@ -551,7 +551,10 @@ function(_ExternalData_arg_find_files pattern regex) set(relname "${entry}") set(alg "") endif() - if("x${relname}" MATCHES "^x${regex}$" AND NOT IS_DIRECTORY "${top_src}/${entry}") + if("x${relname}" MATCHES "^x${regex}$" # matches + AND NOT IS_DIRECTORY "${top_src}/${entry}" # not a directory + AND NOT "x${relname}" MATCHES "(^x|/)\\.ExternalData_" # not staged obj + ) set(name "${top_src}/${relname}") set(file "${top_bin}/${relname}") if(alg) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 7f79b14..d1ce2f4 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -928,9 +928,13 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}") endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}") + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE NAMES ${_boost_RELEASE_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS} + HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} NAMES_PER_DIR DOC "${_boost_docstring_release}" ) @@ -960,9 +964,13 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}") endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}") + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG NAMES ${_boost_DEBUG_NAMES} - HINTS ${_boost_LIBRARY_SEARCH_DIRS} + HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} NAMES_PER_DIR DOC "${_boost_docstring_debug}" ) diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake index cd97b38..02a5777 100644 --- a/Modules/FindImageMagick.cmake +++ b/Modules/FindImageMagick.cmake @@ -81,7 +81,7 @@ function(FIND_IMAGEMAGICK_API component header) ${ImageMagick_INCLUDE_DIRS} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include" PATH_SUFFIXES - ImageMagick + ImageMagick ImageMagick-6 DOC "Path to the ImageMagick include dir." ) find_library(ImageMagick_${component}_LIBRARY diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index af0c2dd..2972198 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -156,6 +156,16 @@ function(_protobuf_find_libraries name filename) endif() endfunction() +# Internal function: find threads library +function(_protobuf_find_threads) + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + find_package(Threads) + if(Threads_FOUND) + list(APPEND PROTOBUF_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARIES}" PARENT_SCOPE) + endif() +endfunction() + # # Main. # @@ -190,6 +200,9 @@ if(MSVC) set(CMAKE_FIND_LIBRARY_PREFIXES "${PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES}") endif() +if(UNIX) + _protobuf_find_threads() +endif() # Find the include directory find_path(PROTOBUF_INCLUDE_DIR diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 68b37f3..8ce1934 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -884,16 +884,20 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) endforeach() if(Q_WS_WIN) - set(QT_MODULES ${QT_MODULES} QAxContainer QAxServer) - # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR - find_path(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt - PATHS ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH - ) - find_path(QT_QAXSERVER_INCLUDE_DIR ActiveQt - PATHS ${QT_HEADERS_DIR}/ActiveQt - NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH - ) + if (QT_QAXCONTAINER_FOUND) + set(QT_MODULES ${QT_MODULES} QAxContainer) + # Set QT_AXCONTAINER_INCLUDE_DIR and QT_AXSERVER_INCLUDE_DIR + find_path(QT_QAXCONTAINER_INCLUDE_DIR ActiveQt + PATHS ${QT_HEADERS_DIR}/ActiveQt + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH + ) + endif() + if (QT_QAXSERVER_FOUND) + find_path(QT_QAXSERVER_INCLUDE_DIR ActiveQt + PATHS ${QT_HEADERS_DIR}/ActiveQt + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH + ) + endif() endif() # Set QT_QTDESIGNERCOMPONENTS_INCLUDE_DIR @@ -1054,14 +1058,18 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) if(Q_WS_WIN) _QT4_ADJUST_LIB_VARS(qtmain) - _QT4_ADJUST_LIB_VARS(QAxServer) - set_property(TARGET Qt4::QAxServer PROPERTY - INTERFACE_QT4_NO_LINK_QTMAIN ON - ) - set_property(TARGET Qt4::QAxServer APPEND PROPERTY - COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN) + if(QT_QAXSERVER_FOUND) + _QT4_ADJUST_LIB_VARS(QAxServer) + set_property(TARGET Qt4::QAxServer PROPERTY + INTERFACE_QT4_NO_LINK_QTMAIN ON + ) + set_property(TARGET Qt4::QAxServer APPEND PROPERTY + COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN) + endif() - _QT4_ADJUST_LIB_VARS(QAxContainer) + if(QT_QAXCONTAINER_FOUND) + _QT4_ADJUST_LIB_VARS(QAxContainer) + endif() endif() # Only public dependencies are listed here. @@ -1083,7 +1091,9 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) _qt4_add_target_depends(QtWebKit Gui Network) _qt4_add_target_private_depends(Qt3Support Xml) - _qt4_add_target_private_depends(QtSvg Xml) + if(QT_VERSION VERSION_GREATER 4.6) + _qt4_add_target_private_depends(QtSvg Xml) + endif() _qt4_add_target_private_depends(QtDBus Xml) _qt4_add_target_private_depends(QtUiTools Xml Gui) _qt4_add_target_private_depends(QtHelp Sql Xml Network) @@ -1093,8 +1103,12 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) _qt4_add_target_private_depends(QtDeclarative XmlPatterns Svg Sql Gui) _qt4_add_target_private_depends(QtMultimedia Gui) _qt4_add_target_private_depends(QtOpenGL Gui) - _qt4_add_target_private_depends(QAxServer Gui) - _qt4_add_target_private_depends(QAxContainer Gui) + if(QT_QAXSERVER_FOUND) + _qt4_add_target_private_depends(QAxServer Gui) + endif() + if(QT_QAXCONTAINER_FOUND) + _qt4_add_target_private_depends(QAxContainer Gui) + endif() _qt4_add_target_private_depends(phonon Gui) if(QT_QTDBUS_FOUND) _qt4_add_target_private_depends(phonon DBus) diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake index 5d76777..f03908e 100644 --- a/Modules/FindThreads.cmake +++ b/Modules/FindThreads.cmake @@ -93,7 +93,7 @@ else() COMPILE_OUTPUT_VARIABLE OUTPUT) if(THREADS_HAVE_PTHREAD_ARG) - if(THREADS_PTHREAD_ARG MATCHES "^2$") + if(THREADS_PTHREAD_ARG STREQUAL "2") set(Threads_FOUND TRUE) message(STATUS "Check if compiler accepts -pthread - yes") else() diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake index 6bb578b..c80249b 100644 --- a/Modules/FindXMLRPC.cmake +++ b/Modules/FindXMLRPC.cmake @@ -53,7 +53,7 @@ if(XMLRPC_FOUND) endif() # Parse the include flags. - if("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$") + if("${XMLRPC_C_CONFIG_RESULT}" STREQUAL "0") # Convert the compile flags to a CMake list. string(REGEX REPLACE " +" ";" XMLRPC_C_CONFIG_CFLAGS "${XMLRPC_C_CONFIG_CFLAGS}") @@ -91,7 +91,7 @@ if(XMLRPC_FOUND) endif() # Parse the library names and directories. - if("${XMLRPC_C_CONFIG_RESULT}" MATCHES "^0$") + if("${XMLRPC_C_CONFIG_RESULT}" STREQUAL "0") string(REGEX REPLACE " +" ";" XMLRPC_C_CONFIG_LIBS "${XMLRPC_C_CONFIG_LIBS}") diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index 892ebc6..4ef14ac 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -267,6 +267,7 @@ macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY) if(_GEH_EXPORT_MACRO_NAME) set(EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_EXPORT_MACRO_NAME}) endif() + string(MAKE_C_IDENTIFIER ${EXPORT_MACRO_NAME} EXPORT_MACRO_NAME) if(_GEH_EXPORT_FILE_NAME) if(IS_ABSOLUTE ${_GEH_EXPORT_FILE_NAME}) set(EXPORT_FILE_NAME ${_GEH_EXPORT_FILE_NAME}) @@ -277,12 +278,15 @@ macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY) if(_GEH_DEPRECATED_MACRO_NAME) set(DEPRECATED_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_DEPRECATED_MACRO_NAME}) endif() + string(MAKE_C_IDENTIFIER ${DEPRECATED_MACRO_NAME} DEPRECATED_MACRO_NAME) if(_GEH_NO_EXPORT_MACRO_NAME) set(NO_EXPORT_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_NO_EXPORT_MACRO_NAME}) endif() + string(MAKE_C_IDENTIFIER ${NO_EXPORT_MACRO_NAME} NO_EXPORT_MACRO_NAME) if(_GEH_STATIC_DEFINE) set(STATIC_DEFINE ${_GEH_PREFIX_NAME}${_GEH_STATIC_DEFINE}) endif() + string(MAKE_C_IDENTIFIER ${STATIC_DEFINE} STATIC_DEFINE) if(_GEH_DEFINE_NO_DEPRECATED) set(DEFINE_NO_DEPRECATED TRUE) @@ -292,6 +296,7 @@ macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY) set(NO_DEPRECATED_MACRO_NAME ${_GEH_PREFIX_NAME}${_GEH_NO_DEPRECATED_MACRO_NAME}) endif() + string(MAKE_C_IDENTIFIER ${NO_DEPRECATED_MACRO_NAME} NO_DEPRECATED_MACRO_NAME) set(INCLUDE_GUARD_NAME "${EXPORT_MACRO_NAME}_H") @@ -300,6 +305,7 @@ macro(_DO_GENERATE_EXPORT_HEADER TARGET_LIBRARY) if(NOT EXPORT_IMPORT_CONDITION) set(EXPORT_IMPORT_CONDITION ${TARGET_LIBRARY}_EXPORTS) endif() + string(MAKE_C_IDENTIFIER ${EXPORT_IMPORT_CONDITION} EXPORT_IMPORT_CONDITION) configure_file("${_GENERATE_EXPORT_HEADER_MODULE_DIR}/exportheader.cmake.in" "${EXPORT_FILE_NAME}" @ONLY) @@ -307,11 +313,9 @@ endmacro() function(GENERATE_EXPORT_HEADER TARGET_LIBRARY) get_property(type TARGET ${TARGET_LIBRARY} PROPERTY TYPE) - if(${type} STREQUAL "MODULE") - message(WARNING "This macro should not be used with libraries of type MODULE") - return() - endif() - if(NOT ${type} STREQUAL "STATIC_LIBRARY" AND NOT ${type} STREQUAL "SHARED_LIBRARY") + if(NOT ${type} STREQUAL "STATIC_LIBRARY" + AND NOT ${type} STREQUAL "SHARED_LIBRARY" + AND NOT ${type} STREQUAL "MODULE_LIBRARY") message(WARNING "This macro can only be used with libraries") return() endif() diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index 2e6b71e..f0652b9 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -30,6 +30,11 @@ set(CMAKE_SHARED_MODULE_SUFFIX ".so") set(CMAKE_MODULE_EXISTS 1) set(CMAKE_DL_LIBS "") +# Enable rpath support for 10.5 and greater where it is known to work. +if("${DARWIN_MAJOR_VERSION}" GREATER 8) + set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") +endif() + set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") @@ -207,12 +212,8 @@ if("${CMAKE_BACKWARDS_COMPATIBILITY}" MATCHES "^1\\.[0-6]$") "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -flat_namespace -undefined suppress") endif() -if(NOT XCODE) - # Enable shared library versioning. This flag is not actually referenced - # but the fact that the setting exists will cause the generators to support - # soname computation. - set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") -endif() +# Enable shared library versioning. +set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") # Xcode does not support -isystem yet. if(XCODE) diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 251d57c..a0b2e31 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -21,15 +21,20 @@ ###################################### -macro (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options) +macro (QT4_EXTRACT_OPTIONS _qt4_files _qt4_options _qt4_target) set(${_qt4_files}) set(${_qt4_options}) set(_QT4_DOING_OPTIONS FALSE) + set(_QT4_DOING_TARGET FALSE) foreach(_currentArg ${ARGN}) - if ("${_currentArg}" STREQUAL "OPTIONS") + if ("x${_currentArg}" STREQUAL "xOPTIONS") set(_QT4_DOING_OPTIONS TRUE) + elseif ("x${_currentArg}" STREQUAL "xTARGET") + set(_QT4_DOING_TARGET TRUE) else () - if(_QT4_DOING_OPTIONS) + if(_QT4_DOING_TARGET) + set(${_qt4_target} "${_currentArg}") + elseif(_QT4_DOING_OPTIONS) list(APPEND ${_qt4_options} "${_currentArg}") else() list(APPEND ${_qt4_files} "${_currentArg}") @@ -92,34 +97,49 @@ endmacro() # helper macro to set up a moc rule -macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options) +macro (QT4_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target) # For Windows, create a parameters file to work around command line length limit - if (WIN32) - # Pass the parameters in a file. Set the working directory to - # be that containing the parameters file and reference it by - # just the file name. This is necessary because the moc tool on - # MinGW builds does not seem to handle spaces in the path to the - # file given with the @ syntax. - get_filename_component(_moc_outfile_name "${outfile}" NAME) - get_filename_component(_moc_outfile_dir "${outfile}" PATH) - if(_moc_outfile_dir) - set(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir}) - endif() - set (_moc_parameters_file ${outfile}_parameters) - set (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}") - string (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}") - file (WRITE ${_moc_parameters_file} "${_moc_parameters}") - add_custom_command(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} @${_moc_outfile_name}_parameters - DEPENDS ${infile} - ${_moc_working_dir} - VERBATIM) - else () - add_custom_command(OUTPUT ${outfile} - COMMAND ${QT_MOC_EXECUTABLE} - ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile} - DEPENDS ${infile} VERBATIM) - endif () + # Pass the parameters in a file. Set the working directory to + # be that containing the parameters file and reference it by + # just the file name. This is necessary because the moc tool on + # MinGW builds does not seem to handle spaces in the path to the + # file given with the @ syntax. + get_filename_component(_moc_outfile_name "${outfile}" NAME) + get_filename_component(_moc_outfile_dir "${outfile}" PATH) + if(_moc_outfile_dir) + set(_moc_working_dir WORKING_DIRECTORY ${_moc_outfile_dir}) + endif() + set (_moc_parameters_file ${outfile}_parameters) + set (_moc_parameters ${moc_flags} ${moc_options} -o "${outfile}" "${infile}") + string (REPLACE ";" "\n" _moc_parameters "${_moc_parameters}") + + set(targetincludes) + set(targetdefines) + if(moc_target) + list(APPEND targetincludes "$<TARGET_PROPERTY:${moc_target},INCLUDE_DIRECTORIES>") + list(APPEND targetdefines "$<TARGET_PROPERTY:${moc_target},COMPILE_DEFINITIONS>") + + set(targetincludes "$<$<BOOL:${targetincludes}>:-I$<JOIN:${targetincludes},\n-I>\n>") + set(targetdefines "$<$<BOOL:${targetdefines}>:-D$<JOIN:${targetdefines},\n-D>\n>") + + file (GENERATE + OUTPUT ${_moc_parameters_file} + CONTENT "${targetdefines}${targetincludes}${targetoptions}${_moc_parameters}\n" + CONDITION 1 + ) + + set(targetincludes) + set(targetdefines) + else() + file(WRITE ${_moc_parameters_file} "${_moc_parameters}\n") + endif() + + set(_moc_extra_parameters_file @${_moc_parameters_file}) + add_custom_command(OUTPUT ${outfile} + COMMAND ${QT_MOC_EXECUTABLE} ${_moc_extra_parameters_file} + DEPENDS ${infile} + ${_moc_working_dir} + VERBATIM) endmacro () @@ -131,7 +151,11 @@ macro (QT4_GENERATE_MOC infile outfile ) if(NOT IS_ABSOLUTE "${outfile}") set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}") endif() - QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "") + + if ("x${ARGV2}" STREQUAL "xTARGET") + set(moc_target ${ARGV3}) + endif() + QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}") set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file endmacro () @@ -141,12 +165,12 @@ endmacro () macro (QT4_WRAP_CPP outfiles ) # get include dirs QT4_GET_MOC_FLAGS(moc_flags) - QT4_EXTRACT_OPTIONS(moc_files moc_options ${ARGN}) + QT4_EXTRACT_OPTIONS(moc_files moc_options moc_target ${ARGN}) foreach (it ${moc_files}) get_filename_component(it ${it} ABSOLUTE) QT4_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile) - QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}") + QT4_CREATE_MOC_COMMAND(${it} ${outfile} "${moc_flags}" "${moc_options}" "${moc_target}") set(${outfiles} ${${outfiles}} ${outfile}) endforeach() @@ -156,7 +180,7 @@ endmacro () # QT4_WRAP_UI(outfiles inputfile ... ) macro (QT4_WRAP_UI outfiles ) - QT4_EXTRACT_OPTIONS(ui_files ui_options ${ARGN}) + QT4_EXTRACT_OPTIONS(ui_files ui_options ui_target ${ARGN}) foreach (it ${ui_files}) get_filename_component(outfile ${it} NAME_WE) @@ -175,7 +199,7 @@ endmacro () # QT4_ADD_RESOURCES(outfiles inputfile ... ) macro (QT4_ADD_RESOURCES outfiles ) - QT4_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN}) + QT4_EXTRACT_OPTIONS(rcc_files rcc_options rcc_target ${ARGN}) foreach (it ${rcc_files}) get_filename_component(outfilename ${it} NAME_WE) @@ -270,7 +294,7 @@ endmacro() macro(QT4_GENERATE_DBUS_INTERFACE _header) # _customName OPTIONS -some -options ) - QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options ${ARGN}) + QT4_EXTRACT_OPTIONS(_customName _qt4_dbus_options _qt4_dbus_target ${ARGN}) get_filename_component(_in_file ${_header} ABSOLUTE) get_filename_component(_basename ${_header} NAME_WE) @@ -366,7 +390,7 @@ macro(QT4_AUTOMOC) set(_header ${_abs_PATH}/${_basename}.h) endif() set(_moc ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC}) - QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "") + QT4_CREATE_MOC_COMMAND(${_header} ${_moc} "${_moc_INCS}" "" "") MACRO_ADD_FILE_DEPENDENCIES(${_abs_FILE} ${_moc}) endforeach () endif() @@ -376,7 +400,7 @@ endmacro() macro(QT4_CREATE_TRANSLATION _qm_files) - QT4_EXTRACT_OPTIONS(_lupdate_files _lupdate_options ${ARGN}) + QT4_EXTRACT_OPTIONS(_lupdate_files _lupdate_options _lupdate_target ${ARGN}) set(_my_sources) set(_my_dirs) set(_my_tsfiles) @@ -451,14 +475,22 @@ function(qt4_use_modules _target _link_type) endif() foreach(_module ${modules}) string(TOUPPER ${_module} _ucmodule) - if (NOT QT_QT${_ucmodule}_FOUND) - message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") - endif() - if ("${_ucmodule}" STREQUAL "MAIN") - message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.") + set(_targetPrefix QT_QT${_ucmodule}) + if (_ucmodule STREQUAL QAXCONTAINER OR _ucmodule STREQUAL QAXSERVER) + if (NOT QT_Q${_ucmodule}_FOUND) + message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") + endif() + set(_targetPrefix QT_Q${_ucmodule}) + else() + if (NOT QT_QT${_ucmodule}_FOUND) + message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") + endif() + if ("${_ucmodule}" STREQUAL "MAIN") + message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.") + endif() endif() - target_link_libraries(${_target} ${link_type} ${QT_QT${_ucmodule}_LIBRARY}) - set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${QT_QT${_ucmodule}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default) - set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${QT_QT${_ucmodule}_COMPILE_DEFINITIONS}) + target_link_libraries(${_target} ${link_type} ${${_targetPrefix}_LIBRARIES}) + set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${${_targetPrefix}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default) + set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${${_targetPrefix}_COMPILE_DEFINITIONS}) endforeach() endfunction() diff --git a/Modules/SelectLibraryConfigurations.cmake b/Modules/SelectLibraryConfigurations.cmake index 62137bb..5bca064 100644 --- a/Modules/SelectLibraryConfigurations.cmake +++ b/Modules/SelectLibraryConfigurations.cmake @@ -62,7 +62,7 @@ macro( select_library_configurations basename ) # if the generator supports configuration types or CMAKE_BUILD_TYPE # is set, then set optimized and debug options. if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) - set( ${basename}_LIBRARY ) + set( ${basename}_LIBRARY "" ) foreach( _libname IN LISTS ${basename}_LIBRARY_RELEASE ) list( APPEND ${basename}_LIBRARY optimized "${_libname}" ) endforeach() diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index e686c1d..9c23127 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -6,6 +6,10 @@ # add_jar(target_name # [SOURCES] source1 [source2 ...] [resource1 ...] # [INCLUDE_JARS jar1 [jar2 ...]] +# [ENTRY_POINT entry] +# [VERSION version] +# [OUTPUT_NAME name] +# [OUTPUT_DIR dir] # ) # # This command creates a <target_name>.jar. It compiles the given source files @@ -17,6 +21,9 @@ # listed as sources are ignored (as they have been since the first version of # this module). # +# The default OUTPUT_DIR can also be changed by setting the variable +# CMAKE_JAVA_TARGET_OUTPUT_DIR. +# # Additional instructions: # To add compile flags to the target you can set these flags with # the following variable: @@ -30,32 +37,30 @@ # # To use a different output name for the target you can set it with: # -# set(CMAKE_JAVA_TARGET_OUTPUT_NAME shibboleet.jar) -# add_jar(foobar foobar.java) +# add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar) # # To use a different output directory than CMAKE_CURRENT_BINARY_DIR # you can set it with: # -# set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) +# add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) # -# To define an entry point in your jar you can set it with: +# To define an entry point in your jar you can set it with the ENTRY_POINT +# named argument: # -# set(CMAKE_JAVA_JAR_ENTRY_POINT com/examples/MyProject/Main) +# add_jar(example ENTRY_POINT com/examples/MyProject/Main) # # To add a VERSION to the target output name you can set it using -# CMAKE_JAVA_TARGET_VERSION. This will create a jar file with the name -# shibboleet-1.0.0.jar and will create a symlink shibboleet.jar +# the VERSION named argument to add_jar. This will create a jar file with the +# name shibboleet-1.0.0.jar and will create a symlink shibboleet.jar # pointing to the jar with the version information. # -# set(CMAKE_JAVA_TARGET_VERSION 1.2.0) -# add_jar(shibboleet shibbotleet.java) +# add_jar(shibboleet shibbotleet.java VERSION 1.2.0) # # If the target is a JNI library, utilize the following commands to # create a JNI symbolic link: # # set(CMAKE_JNI_TARGET TRUE) -# set(CMAKE_JAVA_TARGET_VERSION 1.2.0) -# add_jar(shibboleet shibbotleet.java) +# add_jar(shibboleet shibbotleet.java VERSION 1.2.0) # install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet) # install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR}) # @@ -216,23 +221,43 @@ set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) function(add_jar _TARGET_NAME) - cmake_parse_arguments(_add_jar "" "" "SOURCES;INCLUDE_JARS" ${ARGN}) + if(DEFINED CMAKE_JAVA_TARGET_VERSION) + set(_add_jar_VERSION "${CMAKE_JAVA_TARGET_VERSION}") + endif() + if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) + set(_add_jar_OUTPUT_DIR "${CMAKE_JAVA_TARGET_OUTPUT_DIR}") + endif() + if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME) + set(_add_jar_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}") + # reset + set(CMAKE_JAVA_TARGET_OUTPUT_NAME) + endif() + if(DEFINED CMAKE_JAVA_JAR_ENTRY_POINT) + set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}") + endif() + + cmake_parse_arguments(_add_jar + "" + "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT" + "SOURCES;INCLUDE_JARS" + ${ARGN} + ) set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS}) - if (NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) - set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + if (NOT DEFINED _add_jar_OUTPUT_DIR) + set(_add_jar_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) endif() - if (CMAKE_JAVA_JAR_ENTRY_POINT) - set(_ENTRY_POINT_OPTION e) - set(_ENTRY_POINT_VALUE ${CMAKE_JAVA_JAR_ENTRY_POINT}) + if (_add_jar_ENTRY_POINT) + set(_ENTRY_POINT_OPTION e) + set(_ENTRY_POINT_VALUE ${_add_jar_ENTRY_POINT}) endif () if (LIBRARY_OUTPUT_PATH) set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH}) else () - set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR}) + set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${_add_jar_OUTPUT_DIR}) endif () set(CMAKE_JAVA_INCLUDE_PATH @@ -252,20 +277,18 @@ function(add_jar _TARGET_NAME) set(CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_PATH_FINAL}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}") endforeach() - set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_JAVA_TARGET_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") + set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${_add_jar_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}.jar") - if (CMAKE_JAVA_TARGET_OUTPUT_NAME AND CMAKE_JAVA_TARGET_VERSION) - set(_JAVA_TARGET_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}-${CMAKE_JAVA_TARGET_VERSION}.jar") - set(_JAVA_TARGET_OUTPUT_LINK "${CMAKE_JAVA_TARGET_OUTPUT_NAME}.jar") - elseif (CMAKE_JAVA_TARGET_VERSION) - set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}-${CMAKE_JAVA_TARGET_VERSION}.jar") + if (_add_jar_OUTPUT_NAME AND _add_jar_VERSION) + set(_JAVA_TARGET_OUTPUT_NAME "${_add_jar_OUTPUT_NAME}-${_add_jar_VERSION}.jar") + set(_JAVA_TARGET_OUTPUT_LINK "${_add_jar_OUTPUT_NAME}.jar") + elseif (_add_jar_VERSION) + set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}-${_add_jar_VERSION}.jar") set(_JAVA_TARGET_OUTPUT_LINK "${_TARGET_NAME}.jar") - elseif (CMAKE_JAVA_TARGET_OUTPUT_NAME) - set(_JAVA_TARGET_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}.jar") + elseif (_add_jar_OUTPUT_NAME) + set(_JAVA_TARGET_OUTPUT_NAME "${_add_jar_OUTPUT_NAME}.jar") endif () - # reset - set(CMAKE_JAVA_TARGET_OUTPUT_NAME) set(_JAVA_CLASS_FILES) set(_JAVA_COMPILE_FILES) @@ -279,7 +302,7 @@ function(add_jar _TARGET_NAME) get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE) if (_JAVA_EXT MATCHES ".java") - file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR} ${_JAVA_FULL}) + file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${_add_jar_OUTPUT_DIR} ${_JAVA_FULL}) file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL}) string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN) string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN) @@ -364,7 +387,7 @@ function(add_jar _TARGET_NAME) # create the jar file set(_JAVA_JAR_OUTPUT_PATH - ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME}) + ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME}) if (CMAKE_JNI_TARGET) add_custom_command( OUTPUT ${_JAVA_JAR_OUTPUT_PATH} @@ -372,12 +395,12 @@ function(add_jar _TARGET_NAME) -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_JAVA_RESOURCE_FILES} @java_class_filelist COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} + -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR} -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} + -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR} -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_JAR_OUTPUT_PATH} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} @@ -392,7 +415,7 @@ function(add_jar _TARGET_NAME) -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_JAVA_RESOURCE_FILES} @java_class_filelist COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} + -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR} -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} @@ -420,7 +443,7 @@ function(add_jar _TARGET_NAME) PROPERTY INSTALL_FILES ${_JAVA_JAR_OUTPUT_PATH} - ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} + ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} ) if (CMAKE_JNI_TARGET) @@ -429,7 +452,7 @@ function(add_jar _TARGET_NAME) ${_TARGET_NAME} PROPERTY JNI_SYMLINK - ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} + ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} ) endif () endif () diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index dd0a14e..d5e0330 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 11) -set(CMake_VERSION_TWEAK 20130523) +set(CMake_VERSION_TWEAK 20130605) #set(CMake_VERSION_RC 1) diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx index e3a2ad4..1b7a751 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands.cxx @@ -52,6 +52,7 @@ #include "cmFindProgramCommand.cxx" #include "cmForEachCommand.cxx" #include "cmFunctionCommand.cxx" +#include "cmGeneratorExpressionEvaluationFile.cxx" #include "cmGetCMakePropertyCommand.cxx" #include "cmGetDirectoryPropertyCommand.cxx" #include "cmGetFilenameComponentCommand.cxx" diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 227b226..75f2ae8 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -29,6 +29,7 @@ #include "cmSourceGroupCommand.cxx" #include "cmSubdirDependsCommand.cxx" #include "cmTargetCompileDefinitionsCommand.cxx" +#include "cmTargetCompileOptionsCommand.cxx" #include "cmTargetIncludeDirectoriesCommand.cxx" #include "cmTargetPropCommandBase.cxx" #include "cmUseMangledMesaCommand.cxx" @@ -71,6 +72,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands.push_back(new cmSubdirDependsCommand); commands.push_back(new cmTargetIncludeDirectoriesCommand); commands.push_back(new cmTargetCompileDefinitionsCommand); + commands.push_back(new cmTargetCompileOptionsCommand); commands.push_back(new cmUseMangledMesaCommand); commands.push_back(new cmUtilitySourceCommand); commands.push_back(new cmVariableRequiresCommand); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 0158508..02495c4 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1730,6 +1730,17 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target) { + // Ignore targets on Apple where install_name is not @rpath. + // The dependenty library can be found with other means such as + // @loader_path or full paths. + if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + if(!target->HasMacOSXRpath(this->Config)) + { + return; + } + } + // Libraries with unknown type must be handled using just the file // on disk. if(target->GetType() == cmTarget::UNKNOWN_LIBRARY) @@ -1762,25 +1773,60 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath) { // Get the name of the library from the file name. + bool is_shared_library = false; std::string file = cmSystemTools::GetFilenameName(fullPath); - if(!this->ExtractSharedLibraryName.find(file.c_str())) + + if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + // Check that @rpath is part of the install name. + // If it isn't, return. + std::string soname; + if(!cmSystemTools::GuessLibraryInstallName(fullPath, soname)) + { + return; + } + + if(soname.find("@rpath") == std::string::npos) + { + return; + } + } + + is_shared_library = this->ExtractSharedLibraryName.find(file.c_str()); + + if(!is_shared_library) { // On some platforms (AIX) a shared library may look static. if(this->ArchivesMayBeShared) { - if(!this->ExtractStaticLibraryName.find(file.c_str())) + if(this->ExtractStaticLibraryName.find(file.c_str())) { - // This is not the name of a shared library or archive. - return; + // This is the name of a shared library or archive. + is_shared_library = true; } } - else + } + + // It could be an Apple framework + if(!is_shared_library) + { + if(fullPath.find(".framework") != std::string::npos) { - // This is not the name of a shared library. - return; + cmsys::RegularExpression splitFramework; + splitFramework.compile("^(.*)/(.*).framework/.*/(.*)$"); + if(splitFramework.find(fullPath) && + (splitFramework.match(2) == splitFramework.match(3))) + { + is_shared_library = true; + } } } + if(!is_shared_library) + { + return; + } + // Include this library in the runtime path ordering. this->OrderRuntimeSearchPath->AddRuntimeLibrary(fullPath); if(this->LinkWithRuntimePath) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 9f38b25..bf28428 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -23,150 +23,130 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) this->BinaryDirectory = argv[1].c_str(); this->OutputFile = ""; // which signature were we called with ? - this->SrcFileSignature = false; - unsigned int i; + this->SrcFileSignature = true; const char* sourceDirectory = argv[2].c_str(); const char* projectName = 0; const char* targetName = 0; - char targetNameBuf[64]; - int extraArgs = 0; - - // look for CMAKE_FLAGS and store them std::vector<std::string> cmakeFlags; - for (i = 3; i < argv.size(); ++i) - { - if (argv[i] == "CMAKE_FLAGS") - { - // CMAKE_FLAGS is the first argument because we need an argv[0] that - // is not used, so it matches regular command line parsing which has - // the program name as arg 0 - for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" && - argv[i] != "OUTPUT_VARIABLE" && - argv[i] != "LINK_LIBRARIES"; - ++i) - { - extraArgs++; - cmakeFlags.push_back(argv[i]); - } - break; - } - } - - // look for OUTPUT_VARIABLE and store them + std::vector<std::string> compileDefs; std::string outputVariable; - for (i = 3; i < argv.size(); ++i) + std::string copyFile; + std::vector<cmTarget*> targets; + std::string libsToLink = " "; + bool useOldLinkLibs = true; + char targetNameBuf[64]; + bool didOutputVariable = false; + bool didCopyFile = false; + + enum Doing { DoingNone, DoingCMakeFlags, DoingCompileDefinitions, + DoingLinkLibraries, DoingOutputVariable, DoingCopyFile }; + Doing doing = DoingNone; + for(size_t i=3; i < argv.size(); ++i) { - if (argv[i] == "OUTPUT_VARIABLE") + if(argv[i] == "CMAKE_FLAGS") { - if ( argv.size() <= (i+1) ) - { - this->Makefile->IssueMessage(cmake::FATAL_ERROR, - "OUTPUT_VARIABLE specified but there is no variable"); - return -1; - } - extraArgs += 2; - outputVariable = argv[i+1]; - break; + doing = DoingCMakeFlags; + // CMAKE_FLAGS is the first argument because we need an argv[0] that + // is not used, so it matches regular command line parsing which has + // the program name as arg 0 + cmakeFlags.push_back(argv[i]); } - } - - // look for COMPILE_DEFINITIONS and store them - std::vector<std::string> compileFlags; - for (i = 3; i < argv.size(); ++i) - { - if (argv[i] == "COMPILE_DEFINITIONS") + else if(argv[i] == "COMPILE_DEFINITIONS") { - extraArgs++; - for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" && - argv[i] != "OUTPUT_VARIABLE" && - argv[i] != "LINK_LIBRARIES"; - ++i) - { - extraArgs++; - compileFlags.push_back(argv[i]); - } - break; + doing = DoingCompileDefinitions; } - } - - std::vector<cmTarget*> targets; - std::string libsToLink = " "; - bool useOldLinkLibs = true; - for (i = 3; i < argv.size(); ++i) - { - if (argv[i] == "LINK_LIBRARIES") + else if(argv[i] == "LINK_LIBRARIES") { - if ( argv.size() <= (i+1) ) - { - this->Makefile->IssueMessage(cmake::FATAL_ERROR, - "LINK_LIBRARIES specified but there is no content"); - return -1; - } - extraArgs++; - ++i; + doing = DoingLinkLibraries; useOldLinkLibs = false; - for ( ; i < argv.size() && argv[i] != "CMAKE_FLAGS" - && argv[i] != "COMPILE_DEFINITIONS" && argv[i] != "OUTPUT_VARIABLE"; - ++i) + } + else if(argv[i] == "OUTPUT_VARIABLE") + { + doing = DoingOutputVariable; + didOutputVariable = true; + } + else if(argv[i] == "COPY_FILE") + { + doing = DoingCopyFile; + didCopyFile = true; + } + else if(doing == DoingCMakeFlags) + { + cmakeFlags.push_back(argv[i]); + } + else if(doing == DoingCompileDefinitions) + { + compileDefs.push_back(argv[i]); + } + else if(doing == DoingLinkLibraries) + { + libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" "; + if(cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str())) { - extraArgs++; - libsToLink += argv[i] + " "; - cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str()); - if (!tgt) - { - continue; - } switch(tgt->GetType()) - { - case cmTarget::SHARED_LIBRARY: - case cmTarget::STATIC_LIBRARY: - case cmTarget::UNKNOWN_LIBRARY: - break; - case cmTarget::EXECUTABLE: - if (tgt->IsExecutableWithExports()) - { + { + case cmTarget::SHARED_LIBRARY: + case cmTarget::STATIC_LIBRARY: + case cmTarget::UNKNOWN_LIBRARY: break; - } - default: - this->Makefile->IssueMessage(cmake::FATAL_ERROR, - "Only libraries may be used as try_compile IMPORTED " - "LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of " - "type " + tgt->GetTargetTypeName(tgt->GetType()) + "."); - return -1; - } - if (!tgt->IsImported()) + case cmTarget::EXECUTABLE: + if (tgt->IsExecutableWithExports()) + { + break; + } + default: + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "Only libraries may be used as try_compile IMPORTED " + "LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of " + "type " + tgt->GetTargetTypeName(tgt->GetType()) + "."); + return -1; + } + if (tgt->IsImported()) { - continue; + targets.push_back(tgt); } - targets.push_back(tgt); } - break; + } + else if(doing == DoingOutputVariable) + { + outputVariable = argv[i].c_str(); + doing = DoingNone; + } + else if(doing == DoingCopyFile) + { + copyFile = argv[i].c_str(); + doing = DoingNone; + } + else if(i == 3) + { + this->SrcFileSignature = false; + projectName = argv[i].c_str(); + } + else if(i == 4 && !this->SrcFileSignature) + { + targetName = argv[i].c_str(); + } + else + { + cmOStringStream m; + m << "try_compile given unknown argument \"" << argv[i] << "\"."; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str()); } } - // look for COPY_FILE - std::string copyFile; - for (i = 3; i < argv.size(); ++i) + if(didCopyFile && copyFile.empty()) { - if (argv[i] == "COPY_FILE") - { - if ( argv.size() <= (i+1) ) - { - this->Makefile->IssueMessage(cmake::FATAL_ERROR, - "COPY_FILE specified but there is no variable"); - return -1; - } - extraArgs += 2; - copyFile = argv[i+1]; - break; - } + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "COPY_FILE must be followed by a file path"); + return -1; } - // do we have a srcfile signature - if (argv.size() - extraArgs == 3) + if(didOutputVariable && outputVariable.empty()) { - this->SrcFileSignature = true; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "OUTPUT_VARIABLE must be followed by a variable name"); + return -1; } // compute the binary dir when TRY_COMPILE is called with a src file @@ -179,10 +159,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) else { // only valid for srcfile signatures - if (compileFlags.size()) + if (compileDefs.size()) { this->Makefile->IssueMessage(cmake::FATAL_ERROR, - "COMPILE_FLAGS specified on a srcdir type TRY_COMPILE"); + "COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE"); return -1; } if (copyFile.size()) @@ -297,12 +277,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n"); fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n"); // handle any compile flags we need to pass on - if (compileFlags.size()) + if (compileDefs.size()) { fprintf(fout, "ADD_DEFINITIONS( "); - for (i = 0; i < compileFlags.size(); ++i) + for (size_t i = 0; i < compileDefs.size(); ++i) { - fprintf(fout,"%s ",compileFlags[i].c_str()); + fprintf(fout,"%s ",compileDefs[i].c_str()); } fprintf(fout, ")\n"); } @@ -398,16 +378,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } } - // else the srcdir bindir project target signature - else - { - projectName = argv[3].c_str(); - - if (argv.size() - extraArgs == 5) - { - targetName = argv[4].c_str(); - } - } bool erroroc = cmSystemTools::GetErrorOccuredFlag(); cmSystemTools::ResetErrorOccuredFlag(); diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index ae9ca50..a8b3847 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -40,6 +40,14 @@ "is exported using export(), or when the target is used by another " \ "target in the same buildsystem. Expands to the empty string " \ "otherwise.\n" \ + " $<C_COMPILER_ID> = The CMake-id of the C compiler " \ + "used.\n" \ + " $<C_COMPILER_ID:comp> = '1' if the CMake-id of the C " \ + "compiler matches comp, otherwise '0'.\n" \ + " $<CXX_COMPILER_ID> = The CMake-id of the CXX compiler " \ + "used.\n" \ + " $<CXX_COMPILER_ID:comp> = '1' if the CMake-id of the CXX " \ + "compiler matches comp, otherwise '0'.\n" \ " $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \ " $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \ " $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \ @@ -74,4 +82,12 @@ "the target on which the generator expression is evaluated.\n" \ "" +#define CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS \ + "Language related expressions:\n" \ + " $<LINK_LANGUAGE> = The link language of the target " \ + "being generated.\n" \ + " $<LINK_LANGUAGE:lang> = '1' if the link language of the " \ + "target being generated matches lang, else '0'.\n" \ + "" + #endif diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index e1c26c6..39184fb 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -143,7 +143,7 @@ cmExportBuildFileGenerator std::string prop = "IMPORTED_LOCATION"; prop += suffix; std::string value; - if(target->IsFrameworkOnApple() || target->IsAppBundleOnApple()) + if(target->IsAppBundleOnApple()) { value = target->GetFullPath(config, false); } @@ -211,3 +211,19 @@ cmExportBuildFileGenerator << "consider using the APPEND option with multiple separate calls."; this->ExportCommand->ErrorMessage = e.str(); } + +std::string +cmExportBuildFileGenerator::InstallNameDir(cmTarget* target, + const std::string& config) +{ + std::string install_name_dir; + + cmMakefile* mf = target->GetMakefile(); + if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + install_name_dir = + target->GetInstallNameDirForBuildTree(config.c_str()); + } + + return install_name_dir; +} diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 5e1be16..3ffdf8b 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -61,6 +61,8 @@ protected: cmTarget* target, ImportPropertyMap& properties); + std::string InstallNameDir(cmTarget* target, const std::string& config); + std::vector<cmTarget*> const* Exports; cmExportCommand* ExportCommand; }; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index a6ccbd5..6bef017 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -624,8 +624,12 @@ cmExportFileGenerator std::string value; if(target->HasSOName(config)) { + if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + value = this->InstallNameDir(target, config); + } prop = "IMPORTED_SONAME"; - value = target->GetSOName(config); + value += target->GetSOName(config); } else { diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 9f958a2..ed2d93b 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -159,6 +159,9 @@ private: std::vector<std::string> &missingTargets); virtual void ReplaceInstallPrefix(std::string &input); + + virtual std::string InstallNameDir(cmTarget* target, + const std::string& config) = 0; }; #endif diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 55081a7..ea671cc 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -351,27 +351,7 @@ cmExportInstallFileGenerator prop += suffix; // Append the installed file name. - if(target->IsFrameworkOnApple()) - { - value += itgen->GetInstallFilename(target, config); - value += ".framework/"; - value += itgen->GetInstallFilename(target, config); - } - else if(target->IsCFBundleOnApple()) - { - const char *ext = target->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - - value += itgen->GetInstallFilename(target, config); - value += "."; - value += ext; - value += "/"; - value += itgen->GetInstallFilename(target, config); - } - else if(target->IsAppBundleOnApple()) + if(target->IsAppBundleOnApple()) { value += itgen->GetInstallFilename(target, config); value += ".app/Contents/MacOS/"; @@ -497,3 +477,19 @@ cmExportInstallFileGenerator } cmSystemTools::Error(e.str().c_str()); } + +std::string +cmExportInstallFileGenerator::InstallNameDir(cmTarget* target, + const std::string&) +{ + std::string install_name_dir; + + cmMakefile* mf = target->GetMakefile(); + if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + install_name_dir = + target->GetInstallNameDirForInstallTree(); + } + + return install_name_dir; +} diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 20dd57a..7c634a4 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -85,6 +85,8 @@ protected: void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); + std::string InstallNameDir(cmTarget* target, const std::string& config); + cmInstallExportGenerator* IEGen; std::string ImportPrefix; diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index 75f2651..948508b 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -112,3 +112,18 @@ cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target, } } } +std::string +cmExportTryCompileFileGenerator::InstallNameDir(cmTarget* target, + const std::string& config) +{ + std::string install_name_dir; + + cmMakefile* mf = target->GetMakefile(); + if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + install_name_dir = + target->GetInstallNameDirForBuildTree(config.c_str()); + } + + return install_name_dir; +} diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h index ed393ab..91b4a61 100644 --- a/Source/cmExportTryCompileFileGenerator.h +++ b/Source/cmExportTryCompileFileGenerator.h @@ -43,6 +43,8 @@ protected: ImportPropertyMap& properties, std::set<cmTarget*> &emitted); + std::string InstallNameDir(cmTarget* target, + const std::string& config); private: std::string FindTargets(const char *prop, cmTarget *tgt, std::set<cmTarget*> &emitted); diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 62e9194..29d86a6 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -429,7 +429,9 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source, lg->AppendFlags(flags, makefile->GetDefineFlags()); // Add target-specific flags. - if(target->GetProperty("COMPILE_FLAGS")) + std::string targetFlags; + lg->GetCompileOptions(targetFlags, target, config); + if (!targetFlags.empty()) { std::string langIncludeExpr = "CMAKE_"; langIncludeExpr += language; @@ -440,7 +442,7 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source, cmsys::RegularExpression r(regex); std::vector<std::string> args; cmSystemTools:: - ParseWindowsCommandLine(target->GetProperty("COMPILE_FLAGS"), args); + ParseWindowsCommandLine(targetFlags.c_str(), args); for(std::vector<std::string>::iterator i = args.begin(); i != args.end(); ++i) { @@ -452,7 +454,7 @@ cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source, } else { - lg->AppendFlags(flags, target->GetProperty("COMPILE_FLAGS")); + lg->AppendFlags(flags, targetFlags.c_str()); } } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 2e6f3e0..e72e756 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -167,6 +167,10 @@ bool cmFileCommand { return this->HandleTimestampCommand(args); } + else if ( subCommand == "GENERATE" ) + { + return this->HandleGenerateCommand(args); + } std::string e = "does not recognize sub-command "+subCommand; this->SetError(e.c_str()); @@ -3250,6 +3254,80 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) } //---------------------------------------------------------------------------- +void cmFileCommand::AddEvaluationFile(const std::string &inputName, + const std::string &outputExpr, + const std::string &condition, + bool inputIsContent + ) +{ + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + + cmGeneratorExpression outputGe(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> outputCge + = outputGe.Parse(outputExpr); + + cmGeneratorExpression conditionGe(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> conditionCge + = conditionGe.Parse(condition); + + this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator()->AddEvaluationFile(inputName, + outputCge, + this->Makefile, + conditionCge, + inputIsContent); +} + +//---------------------------------------------------------------------------- +bool cmFileCommand::HandleGenerateCommand( + std::vector<std::string> const& args) +{ + if (args.size() < 5) + { + this->SetError("Incorrect arguments to GENERATE subcommand."); + return false; + } + if (args[1] != "OUTPUT") + { + this->SetError("Incorrect arguments to GENERATE subcommand."); + return false; + } + std::string condition; + if (args.size() > 5) + { + if (args[5] != "CONDITION") + { + this->SetError("Incorrect arguments to GENERATE subcommand."); + return false; + } + if (args.size() != 7) + { + this->SetError("Incorrect arguments to GENERATE subcommand."); + return false; + } + condition = args[6]; + if (condition.empty()) + { + this->SetError("CONDITION of sub-command GENERATE must not be empty if " + "specified."); + return false; + } + } + std::string output = args[2]; + const bool inputIsContent = args[3] != "INPUT"; + if (inputIsContent && args[3] != "CONTENT") + { + this->SetError("Incorrect arguments to GENERATE subcommand."); + return false; + } + std::string input = args[4]; + + this->AddEvaluationFile(input, output, condition, inputIsContent); + return true; +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleTimestampCommand( std::vector<std::string> const& args) { diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 5973fa7..586fee2 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -88,6 +88,9 @@ public: " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" " file(TIMESTAMP filename variable [<format string>] [UTC])\n" + " file(GENERATE OUTPUT output_file\n" + " <INPUT input_file|CONTENT input_content>\n" + " CONDITION expression)\n" "WRITE will write a message into a file called 'filename'. It " "overwrites the file if it already exists, and creates the file " "if it does not exist. (If the file is a build input, use " @@ -231,6 +234,15 @@ public: "it prints status messages, and NO_SOURCE_PERMISSIONS is default. " "Installation scripts generated by the install() command use this " "signature (with some undocumented options for internal use)." + "\n" + "GENERATE will write an <output_file> with content from an " + "<input_file>, or from <input_content>. The output is generated " + "conditionally based on the content of the <condition>. The file is " + "written at CMake generate-time and the input may contain generator " + "expressions. The <condition>, <output_file> and <input_file> may " + "also contain generator expressions. The <condition> must evaluate to " + "either '0' or '1'. The <output_file> must evaluate to a unique name " + "among all configurations and among all invocations of file(GENERATE)." // Undocumented INSTALL options: // - RENAME <name> // - OPTIONAL @@ -269,6 +281,13 @@ protected: bool HandleUploadCommand(std::vector<std::string> const& args); bool HandleTimestampCommand(std::vector<std::string> const& args); + bool HandleGenerateCommand(std::vector<std::string> const& args); + +private: + void AddEvaluationFile(const std::string &inputName, + const std::string &outputExpr, + const std::string &condition, + bool inputIsContent); }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 5cb50b9..e5ffb0c 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -168,3 +168,11 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 || strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0); } + +//---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::EvaluatingCompileOptions() const +{ + const char *prop = this->Property.c_str(); + return (strcmp(prop, "COMPILE_OPTIONS") == 0 + || strcmp(prop, "INTERFACE_COMPILE_OPTIONS") == 0 ); +} diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 62a5cdf..8d9fd76 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -40,6 +40,7 @@ struct cmGeneratorExpressionDAGChecker bool EvaluatingLinkLibraries(); bool EvaluatingIncludeDirectories() const; bool EvaluatingCompileDefinitions() const; + bool EvaluatingCompileOptions() const; private: Result checkGraph() const; diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx new file mode 100644 index 0000000..cab99ed --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -0,0 +1,151 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionEvaluationFile.h" + +#include "cmMakefile.h" + +#include <assert.h> + +//---------------------------------------------------------------------------- +cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( + const std::string &input, + cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr, + cmMakefile *makefile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> condition, + bool inputIsContent) + : Input(input), + OutputFileExpr(outputFileExpr), + Makefile(makefile), + Condition(condition), + InputIsContent(inputIsContent) +{ +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionEvaluationFile::Generate(const char *config, + cmCompiledGeneratorExpression* inputExpression, + std::map<std::string, std::string> &outputFiles) +{ + std::string rawCondition = this->Condition->GetInput(); + if (!rawCondition.empty()) + { + std::string condResult = this->Condition->Evaluate(this->Makefile, config); + if (condResult == "0") + { + return; + } + if (condResult != "1") + { + cmOStringStream e; + e << "Evaluation file condition \"" << rawCondition << "\" did " + "not evaluate to valid content. Got \"" << condResult << "\"."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + } + + const std::string outputFileName + = this->OutputFileExpr->Evaluate(this->Makefile, config); + const std::string outputContent + = inputExpression->Evaluate(this->Makefile, config); + + std::map<std::string, std::string>::iterator it + = outputFiles.find(outputFileName); + + if(it != outputFiles.end()) + { + if (it->second == outputContent) + { + return; + } + cmOStringStream e; + e << "Evaluation file to be written multiple times for different " + "configurations with different content:\n " << outputFileName; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + + this->Files.push_back(outputFileName); + outputFiles[outputFileName] = outputContent; + + std::ofstream fout(outputFileName.c_str()); + + if(!fout) + { + cmOStringStream e; + e << "Evaluation file \"" << outputFileName << "\" cannot be written."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + + fout << outputContent; + + fout.close(); +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionEvaluationFile::Generate() +{ + std::string inputContent; + if (this->InputIsContent) + { + inputContent = this->Input; + } + else + { + std::ifstream fin(this->Input.c_str()); + if(!fin) + { + cmOStringStream e; + e << "Evaluation file \"" << this->Input << "\" cannot be read."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + + std::string line; + std::string sep; + while(cmSystemTools::GetLineFromStream(fin, line)) + { + inputContent += sep + line; + sep = "\n"; + } + inputContent += sep; + } + + cmListFileBacktrace lfbt = this->OutputFileExpr->GetBacktrace(); + cmGeneratorExpression contentGE(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> inputExpression + = contentGE.Parse(inputContent); + + std::map<std::string, std::string> outputFiles; + + std::vector<std::string> allConfigs; + this->Makefile->GetConfigurations(allConfigs); + + if (allConfigs.empty()) + { + this->Generate(0, inputExpression.get(), outputFiles); + } + else + { + for(std::vector<std::string>::const_iterator li = allConfigs.begin(); + li != allConfigs.end(); ++li) + { + this->Generate(li->c_str(), inputExpression.get(), outputFiles); + if(cmSystemTools::GetFatalErrorOccured()) + { + return; + } + } + } +} diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h new file mode 100644 index 0000000..20ee5cb --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -0,0 +1,48 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionEvaluationFile_h +#define cmGeneratorExpressionEvaluationFile_h + +#include "cmStandardIncludes.h" +#include <cmsys/auto_ptr.hxx> + +#include "cmGeneratorExpression.h" + +//---------------------------------------------------------------------------- +class cmGeneratorExpressionEvaluationFile +{ +public: + cmGeneratorExpressionEvaluationFile(const std::string &input, + cmsys::auto_ptr<cmCompiledGeneratorExpression> outputFileExpr, + cmMakefile *makefile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> condition, + bool inputIsContent); + + void Generate(); + + std::vector<std::string> GetFiles() const { return this->Files; } + +private: + void Generate(const char *config, + cmCompiledGeneratorExpression* inputExpression, + std::map<std::string, std::string> &outputFiles); + +private: + const std::string Input; + const cmsys::auto_ptr<cmCompiledGeneratorExpression> OutputFileExpr; + cmMakefile *Makefile; + const cmsys::auto_ptr<cmCompiledGeneratorExpression> Condition; + std::vector<std::string> Files; + const bool InputIsContent; +}; + +#endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 9613673..5e7d00d 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -45,6 +45,11 @@ void reportError(cmGeneratorExpressionContext *context, //---------------------------------------------------------------------------- struct cmGeneratorExpressionNode { + enum { + DynamicParameters = 0, + OneOrMoreParameters = -1, + ZeroOrMoreParameters = -2 + }; virtual ~cmGeneratorExpressionNode() {} virtual bool GeneratesContent() const { return true; } @@ -110,8 +115,7 @@ static const struct ZeroNode installInterfaceNode; static const struct OP ## Node : public cmGeneratorExpressionNode \ { \ OP ## Node () {} \ -/* We let -1 carry the meaning 'at least one' */ \ - virtual int NumExpectedParameters() const { return -1; } \ + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \ \ std::string Evaluate(const std::vector<std::string> ¶meters, \ cmGeneratorExpressionContext *context, \ @@ -243,6 +247,104 @@ static const struct SemicolonNode : public cmGeneratorExpressionNode } semicolonNode; //---------------------------------------------------------------------------- +struct CompilerIdNode : public cmGeneratorExpressionNode +{ + CompilerIdNode() {} + + virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + + std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *, + const std::string &lang) const + { + const char *compilerId = context->Makefile ? + context->Makefile->GetSafeDefinition(( + "CMAKE_" + lang + "_COMPILER_ID").c_str()) : ""; + if (parameters.size() == 0) + { + return compilerId ? compilerId : ""; + } + else + { + cmsys::RegularExpression compilerIdValidator; + compilerIdValidator.compile("^[A-Za-z0-9_]*$"); + if (!compilerIdValidator.find(parameters.begin()->c_str())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!compilerId) + { + return parameters.front().empty() ? "1" : "0"; + } + + if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0) + { + return "1"; + } + return "0"; + } + } +}; + +//---------------------------------------------------------------------------- +static const struct CCompilerIdNode : public CompilerIdNode +{ + CCompilerIdNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (parameters.size() != 0 && parameters.size() != 1) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_ID> expression requires one or two parameters"); + return std::string(); + } + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_ID> may only be used with targets. It may not " + "be used with add_custom_command."); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "C"); + } +} cCompilerIdNode; + +//---------------------------------------------------------------------------- +static const struct CXXCompilerIdNode : public CompilerIdNode +{ + CXXCompilerIdNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (parameters.size() != 0 && parameters.size() != 1) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_ID> expression requires one or two parameters"); + return std::string(); + } + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_ID> may only be used with targets. It may not " + "be used with add_custom_command."); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "CXX"); + } +} cxxCompilerIdNode; + +//---------------------------------------------------------------------------- static const struct ConfigurationNode : public cmGeneratorExpressionNode { ConfigurationNode() {} @@ -306,6 +408,60 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } } configurationTestNode; +//---------------------------------------------------------------------------- +static const struct LinkLanguageNode : public cmGeneratorExpressionNode +{ + LinkLanguageNode() {} + + virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (parameters.size() != 0 && parameters.size() != 1) + { + reportError(context, content->GetOriginalExpression(), + "$<LINK_LANGUAGE> expression requires one or two parameters"); + return std::string(); + } + cmTarget* target = context->HeadTarget; + if (!target) + { + reportError(context, content->GetOriginalExpression(), + "$<LINK_LANGUAGE> may only be used with targets. It may not " + "be used with add_custom_command."); + } + + const char *lang = target->GetLinkerLanguage(context->Config); + if (parameters.size() == 0) + { + return lang ? lang : ""; + } + else + { + cmsys::RegularExpression langValidator; + langValidator.compile("^[A-Za-z0-9_]*$"); + if (!langValidator.find(parameters.begin()->c_str())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!lang) + { + return parameters.front().empty() ? "1" : "0"; + } + + if (strcmp(parameters.begin()->c_str(), lang) == 0) + { + return "1"; + } + return "0"; + } + } +} linkLanguageNode; static const struct JoinNode : public cmGeneratorExpressionNode { @@ -339,6 +495,60 @@ static const struct JoinNode : public cmGeneratorExpressionNode static const char* targetPropertyTransitiveWhitelist[] = { "INTERFACE_INCLUDE_DIRECTORIES" , "INTERFACE_COMPILE_DEFINITIONS" + , "INTERFACE_COMPILE_OPTIONS" +}; + +std::string getLinkedTargetsContent(const std::vector<std::string> &libraries, + cmTarget *target, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) +{ + cmGeneratorExpression ge(context->Backtrace); + + std::string sep; + std::string depString; + for (std::vector<std::string>::const_iterator + it = libraries.begin(); + it != libraries.end(); ++it) + { + if (*it == target->GetName()) + { + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + continue; + } + if (context->Makefile->FindTargetToUse(it->c_str())) + { + depString += + sep + "$<TARGET_PROPERTY:" + *it + "," + interfacePropertyName + ">"; + sep = ";"; + } + } + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString); + std::string linkedTargetsContent = cge->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + return linkedTargetsContent; +} + +//---------------------------------------------------------------------------- +struct TransitiveWhitelistCompare +{ + explicit TransitiveWhitelistCompare(const std::string &needle) + : Needle(needle) {} + bool operator() (const char *item) + { return strcmp(item, this->Needle.c_str()) == 0; } +private: + std::string Needle; }; //---------------------------------------------------------------------------- @@ -347,7 +557,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode TargetPropertyNode() {} // This node handles errors on parameter count itself. - virtual int NumExpectedParameters() const { return -1; } + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } std::string Evaluate(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, @@ -493,7 +703,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode else { assert(dagCheckerParent->EvaluatingIncludeDirectories() - || dagCheckerParent->EvaluatingCompileDefinitions()); + || dagCheckerParent->EvaluatingCompileDefinitions() + || dagCheckerParent->EvaluatingCompileOptions()); } } @@ -512,50 +723,42 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode { interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; } + else if (propertyName == "INTERFACE_COMPILE_OPTIONS" + || propertyName == "COMPILE_OPTIONS") + { + interfacePropertyName = "INTERFACE_COMPILE_OPTIONS"; + } - if (interfacePropertyName == "INTERFACE_INCLUDE_DIRECTORIES" - || interfacePropertyName == "INTERFACE_COMPILE_DEFINITIONS") + const char **transBegin = targetPropertyTransitiveWhitelist; + const char **transEnd = targetPropertyTransitiveWhitelist + + (sizeof(targetPropertyTransitiveWhitelist) / + sizeof(*targetPropertyTransitiveWhitelist)); + if (std::find_if(transBegin, transEnd, + TransitiveWhitelistCompare(propertyName)) != transEnd) { const cmTarget::LinkInterface *iface = target->GetLinkInterface( context->Config, context->HeadTarget); if(iface) { - cmGeneratorExpression ge(context->Backtrace); - - std::string sep; - std::string depString; - for (std::vector<std::string>::const_iterator - it = iface->Libraries.begin(); - it != iface->Libraries.end(); ++it) - { - if (*it == target->GetName()) - { - // Broken code can have a target in its own link interface. - // Don't follow such link interface entries so as not to create a - // self-referencing loop. - continue; - } - if (context->Makefile->FindTargetToUse(it->c_str())) - { - depString += - sep + "$<TARGET_PROPERTY:" + *it + "," - + interfacePropertyName + ">"; - sep = ";"; - } - } - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(depString); - linkedTargetsContent = cge->Evaluate(context->Makefile, - context->Config, - context->Quiet, - context->HeadTarget, - target, - &dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } + linkedTargetsContent = + getLinkedTargetsContent(iface->Libraries, target, + context, &dagChecker, + interfacePropertyName); + } + } + else if (std::find_if(transBegin, transEnd, + TransitiveWhitelistCompare(interfacePropertyName)) != transEnd) + { + const cmTarget::LinkImplementation *impl = target->GetLinkImplementation( + context->Config, + context->HeadTarget); + if(impl) + { + linkedTargetsContent = + getLinkedTargetsContent(impl->Libraries, target, + context, &dagChecker, + interfacePropertyName); } } @@ -957,10 +1160,16 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &orNode; else if (identifier == "NOT") return ¬Node; + else if (identifier == "C_COMPILER_ID") + return &cCompilerIdNode; + else if (identifier == "CXX_COMPILER_ID") + return &cxxCompilerIdNode; else if (identifier == "CONFIGURATION") return &configurationNode; else if (identifier == "CONFIG") return &configurationTestNode; + else if (identifier == "LINK_LANGUAGE") + return &linkLanguageNode; else if (identifier == "TARGET_FILE") return &targetFileNode; else if (identifier == "TARGET_LINKER_FILE") @@ -1188,7 +1397,8 @@ std::string GeneratorExpressionContent::EvaluateParameters( } } - if ((numExpected != -1 && (unsigned int)numExpected != parameters.size())) + if ((numExpected > cmGeneratorExpressionNode::DynamicParameters + && (unsigned int)numExpected != parameters.size())) { if (numExpected == 0) { @@ -1213,7 +1423,8 @@ std::string GeneratorExpressionContent::EvaluateParameters( return std::string(); } - if (numExpected == -1 && parameters.empty()) + if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters + && parameters.empty()) { reportError(context, this->GetOriginalExpression(), "$<" + identifier + "> expression requires at least one parameter."); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index f38ef65..3e3e5e4 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -26,6 +26,7 @@ #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionEvaluationFile.h" #include <cmsys/Directory.hxx> @@ -69,6 +70,13 @@ cmGlobalGenerator::~cmGlobalGenerator() { delete this->LocalGenerators[i]; } + for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator + li = this->EvaluationFiles.begin(); + li != this->EvaluationFiles.end(); + ++li) + { + delete *li; + } this->LocalGenerators.clear(); if (this->ExtraGenerator) @@ -955,7 +963,7 @@ void cmGlobalGenerator::Generate() for ( tit = targets->begin(); tit != targets->end(); ++ tit ) { - tit->second.AppendBuildInterfaceIncludes(); + tit->second.AppendBuildInterfaceIncludes(); } } @@ -981,6 +989,8 @@ void cmGlobalGenerator::Generate() // Create per-target generator information. this->CreateGeneratorTargets(); + this->ProcessEvaluationFiles(); + // Compute the inter-target dependencies. if(!this->ComputeTargetDepends()) { @@ -2560,3 +2570,44 @@ std::string cmGlobalGenerator::EscapeJSON(const std::string& s) { } return result; } + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr, + cmMakefile *makefile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> condition, + bool inputIsContent) +{ + this->EvaluationFiles.push_back( + new cmGeneratorExpressionEvaluationFile(inputFile, outputExpr, + makefile, condition, + inputIsContent)); +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::ProcessEvaluationFiles() +{ + std::set<std::string> generatedFiles; + for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator + li = this->EvaluationFiles.begin(); + li != this->EvaluationFiles.end(); + ++li) + { + (*li)->Generate(); + if (cmSystemTools::GetFatalErrorOccured()) + { + return; + } + std::vector<std::string> files = (*li)->GetFiles(); + for(std::vector<std::string>::const_iterator fi = files.begin(); + fi != files.end(); ++fi) + { + if (!generatedFiles.insert(*fi).second) + { + cmSystemTools::Error("File to be generated by multiple different " + "commands: ", fi->c_str()); + return; + } + } + } +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 9427434..2fcdc43 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -20,9 +20,11 @@ #include "cmSystemTools.h" // for cmSystemTools::OutputOption #include "cmExportSetMap.h" // For cmExportSetMap #include "cmGeneratorTarget.h" +#include "cmGeneratorExpression.h" class cmake; class cmGeneratorTarget; +class cmGeneratorExpressionEvaluationFile; class cmMakefile; class cmLocalGenerator; class cmExternalMakefileProjectGenerator; @@ -279,6 +281,14 @@ public: static std::string EscapeJSON(const std::string& s); + void AddEvaluationFile(const std::string &inputFile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> outputName, + cmMakefile *makefile, + cmsys::auto_ptr<cmCompiledGeneratorExpression> condition, + bool inputIsContent); + + void ProcessEvaluationFiles(); + protected: typedef std::vector<cmLocalGenerator*> GeneratorVector; // for a project collect all its targets by following depend @@ -338,6 +348,7 @@ protected: // All targets in the entire project. std::map<cmStdString,cmTarget *> TotalTargets; std::map<cmStdString,cmTarget *> ImportedTargets; + std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles; virtual const char* GetPredefinedTargetsFolder(); virtual bool UseFolderProperty(); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 13a14e1..a13b4f3 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -681,9 +681,11 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, { // Add flags from target and source file properties. std::string flags; - if(cmtarget.GetProperty("COMPILE_FLAGS")) + std::string targetFlags; + lg->GetCompileOptions(targetFlags, &cmtarget, 0); // TODO: Config? + if(!targetFlags.empty()) { - lg->AppendFlags(flags, cmtarget.GetProperty("COMPILE_FLAGS")); + lg->AppendFlags(flags, targetFlags.c_str()); } const char* srcfmt = sf->GetProperty("Fortran_FORMAT"); switch(this->CurrentLocalGenerator->GetFortranFormat(srcfmt)) @@ -748,12 +750,6 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, } } - if(cmtarget.IsCFBundleOnApple()) - { - cmtarget.SetProperty("PREFIX", ""); - cmtarget.SetProperty("SUFFIX", ""); - } - // Add the fileRef to the top level Resources group/folder if it is not // already there. // @@ -1321,8 +1317,40 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, = cmtarget.GetPreBuildCommands(); std::vector<cmCustomCommand> const & prelink = cmtarget.GetPreLinkCommands(); - std::vector<cmCustomCommand> const & postbuild + std::vector<cmCustomCommand> postbuild = cmtarget.GetPostBuildCommands(); + + if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY && + !cmtarget.IsFrameworkOnApple()) + { + cmCustomCommandLines cmd; + cmd.resize(1); + cmd[0].push_back(this->CurrentMakefile->GetDefinition("CMAKE_COMMAND")); + cmd[0].push_back("-E"); + cmd[0].push_back("cmake_symlink_library"); + std::string str_file = "$<TARGET_FILE:"; + str_file += cmtarget.GetName(); + str_file += ">"; + std::string str_so_file = "$<TARGET_SONAME_FILE:"; + str_so_file += cmtarget.GetName(); + str_so_file += ">"; + std::string str_link_file = "$<TARGET_LINKER_FILE:"; + str_link_file += cmtarget.GetName(); + str_link_file += ">"; + cmd[0].push_back(str_file); + cmd[0].push_back(str_so_file); + cmd[0].push_back(str_link_file); + + cmCustomCommand command(this->CurrentMakefile, + std::vector<std::string>(), + std::vector<std::string>(), + cmd, + "Creating symlinks", + ""); + + postbuild.push_back(command); + } + std::vector<cmSourceFile*>const &classes = cmtarget.GetSourceFiles(); // add all the sources std::vector<cmCustomCommand> commands; @@ -1719,30 +1747,26 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); + std::string extraLinkOptionsVar; std::string extraLinkOptions; if(target.GetType() == cmTarget::EXECUTABLE) { - extraLinkOptions = - this->CurrentMakefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS"); - std::string var = "CMAKE_EXE_LINKER_FLAGS_"; - var += cmSystemTools::UpperCase(configName); - std::string val = - this->CurrentMakefile->GetSafeDefinition(var.c_str()); - if(val.size()) - { - extraLinkOptions += " "; - extraLinkOptions += val; - } + extraLinkOptionsVar = "CMAKE_EXE_LINKER_FLAGS"; } - if(target.GetType() == cmTarget::SHARED_LIBRARY) + else if(target.GetType() == cmTarget::SHARED_LIBRARY) { - extraLinkOptions = this->CurrentMakefile-> - GetRequiredDefinition("CMAKE_SHARED_LINKER_FLAGS"); + extraLinkOptionsVar = "CMAKE_SHARED_LINKER_FLAGS"; } - if(target.GetType() == cmTarget::MODULE_LIBRARY) + else if(target.GetType() == cmTarget::MODULE_LIBRARY) { - extraLinkOptions = this->CurrentMakefile-> - GetRequiredDefinition("CMAKE_MODULE_LINKER_FLAGS"); + extraLinkOptionsVar = "CMAKE_MODULE_LINKER_FLAGS"; + } + if(extraLinkOptionsVar.size()) + { + this->CurrentLocalGenerator + ->AddConfigVariableFlags(extraLinkOptions, + extraLinkOptionsVar.c_str(), + configName); } const char* linkFlagsProp = "LINK_FLAGS"; @@ -1802,9 +1826,34 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, std::string pnprefix; std::string pnbase; std::string pnsuffix; - target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName); + const char* version = target.GetProperty("VERSION"); + const char* soversion = target.GetProperty("SOVERSION"); + if(!target.HasSOName(configName) || target.IsFrameworkOnApple()) + { + version = 0; + soversion = 0; + } + if(version && !soversion) + { + soversion = version; + } + if(!version && soversion) + { + version = soversion; + } + + std::string realName = pnbase; + std::string soName = pnbase; + if(version && soversion) + { + realName += "."; + realName += version; + soName += "."; + soName += soversion; + } + // Set attributes to specify the proper name for the target. std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory(); if(target.GetType() == cmTarget::STATIC_LIBRARY || @@ -1828,6 +1877,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, pndir = target.GetDirectory(configName); } + if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple()) + { + pnprefix = ""; + } + buildSettings->AddAttribute("EXECUTABLE_PREFIX", this->CreateString(pnprefix.c_str())); buildSettings->AddAttribute("EXECUTABLE_SUFFIX", @@ -1857,7 +1911,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // Store the product name for all target types. buildSettings->AddAttribute("PRODUCT_NAME", - this->CreateString(pnbase.c_str())); + this->CreateString(realName.c_str())); buildSettings->AddAttribute("SYMROOT", this->CreateString(pndir.c_str())); @@ -1935,9 +1989,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { if(target.GetPropertyAsBool("FRAMEWORK")) { - std::string version = target.GetFrameworkVersion(); + std::string fw_version = target.GetFrameworkVersion(); buildSettings->AddAttribute("FRAMEWORK_VERSION", - this->CreateString(version.c_str())); + this->CreateString(fw_version.c_str())); std::string plist = this->ComputeInfoPListLocation(target); // Xcode will create the final version of Info.plist at build time, @@ -2161,25 +2215,55 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if(target.GetType() == cmTarget::SHARED_LIBRARY) { // Get the install_name directory for the build tree. - install_name_dir = target.GetInstallNameDirForBuildTree(configName, true); - if(install_name_dir.empty()) - { - // Xcode will not pass the -install_name option at all if INSTALL_PATH - // is not given or is empty. We must explicitly put the flag in the - // link flags to create an install_name with just the library soname. - extraLinkOptions += " -install_name "; - extraLinkOptions += target.GetFullName(configName); - } - else + install_name_dir = target.GetInstallNameDirForBuildTree(configName); + // Xcode doesn't create the correct install_name in some cases. + // That is, if the INSTALL_PATH is empty, or if we have versioning + // of dylib libraries, we want to specify the install_name. + // This is done by adding a link flag to create an install_name + // with just the library soname. + std::string install_name; + if(!install_name_dir.empty()) { // Convert to a path for the native build tool. cmSystemTools::ConvertToUnixSlashes(install_name_dir); - // do not escape spaces on this since it is only a single path + install_name += install_name_dir; + install_name += "/"; + } + install_name += target.GetSOName(configName); + + if((realName != soName) || install_name_dir.empty()) + { + install_name_dir = ""; + extraLinkOptions += " -install_name "; + extraLinkOptions += XCodeEscapePath(install_name.c_str()); } } buildSettings->AddAttribute("INSTALL_PATH", this->CreateString(install_name_dir.c_str())); + // Create the LD_RUNPATH_SEARCH_PATHS + cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + if(pcli) + { + std::string search_paths; + std::vector<std::string> runtimeDirs; + pcli->GetRPath(runtimeDirs, false); + for(std::vector<std::string>::const_iterator i = runtimeDirs.begin(); + i != runtimeDirs.end(); ++i) + { + if(!search_paths.empty()) + { + search_paths += " "; + } + search_paths += this->XCodeEscapePath((*i).c_str()); + } + if(!search_paths.empty()) + { + buildSettings->AddAttribute("LD_RUNPATH_SEARCH_PATHS", + this->CreateString(search_paths.c_str())); + } + } + buildSettings->AddAttribute("OTHER_LDFLAGS", this->CreateString(extraLinkOptions.c_str())); buildSettings->AddAttribute("OTHER_REZFLAGS", @@ -2244,8 +2328,39 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { if(i->first.find("XCODE_ATTRIBUTE_") == 0) { - buildSettings->AddAttribute(i->first.substr(16).c_str(), - this->CreateString(i->second.GetValue())); + cmStdString attribute = i->first.substr(16); + // Handle [variant=<config>] condition explicitly here. + cmStdString::size_type beginVariant = + attribute.find("[variant="); + if (beginVariant != cmStdString::npos) + { + cmStdString::size_type endVariant = + attribute.find("]", beginVariant+9); + if (endVariant != cmStdString::npos) + { + // Compare the variant to the configuration. + cmStdString variant = + attribute.substr(beginVariant+9, endVariant-beginVariant-9); + if (variant == configName) + { + // The variant matches the configuration so use this + // attribute but drop the [variant=<config>] condition. + attribute.erase(beginVariant, endVariant-beginVariant+1); + } + else + { + // The variant does not match the configuration so + // do not use this attribute. + attribute.clear(); + } + } + } + + if (!attribute.empty()) + { + buildSettings->AddAttribute(attribute.c_str(), + this->CreateString(i->second.GetValue())); + } } } } diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 5f9b658..ed01210 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -198,14 +198,12 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, // Install the whole framework directory. type = cmInstallType_DIRECTORY; literal_args += " USE_SOURCE_PERMISSIONS"; - std::string from1 = fromDirConfig + targetName + ".framework"; + + std::string from1 = fromDirConfig + targetName; + from1 = cmSystemTools::GetFilenamePath(from1); // Tweaks apply to the binary inside the bundle. - std::string to1 = toDir + targetName; - to1 += ".framework/Versions/"; - to1 += this->Target->GetFrameworkVersion(); - to1 += "/"; - to1 += targetName; + std::string to1 = toDir + targetNameReal; filesFrom.push_back(from1); filesTo.push_back(to1); @@ -528,7 +526,7 @@ cmInstallTargetGenerator // components of the install_name field then we need to create a // mapping to be applied after installation. std::string for_build = tgt->GetInstallNameDirForBuildTree(config); - std::string for_install = tgt->GetInstallNameDirForInstallTree(config); + std::string for_install = tgt->GetInstallNameDirForInstallTree(); if(for_build != for_install) { // The directory portions differ. Append the filename to @@ -555,7 +553,7 @@ cmInstallTargetGenerator std::string for_build = this->Target->GetInstallNameDirForBuildTree(config); std::string for_install = - this->Target->GetInstallNameDirForInstallTree(config); + this->Target->GetInstallNameDirForInstallTree(); if(this->Target->IsFrameworkOnApple() && for_install.empty()) { @@ -608,6 +606,12 @@ cmInstallTargetGenerator return; } + // Skip if on Apple + if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + return; + } + // Get the link information for this target. // It can provide the RPATH. cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); @@ -647,30 +651,62 @@ cmInstallTargetGenerator return; } - // Construct the original rpath string to be replaced. - std::string oldRpath = cli->GetRPathString(false); - - // Get the install RPATH from the link information. - std::string newRpath = cli->GetChrpathString(); - - // Skip the rule if the paths are identical - if(oldRpath == newRpath) + if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { - return; - } + // If using install_name_tool, set up the rules to modify the rpaths. + std::string installNameTool = + this->Target->GetMakefile()-> + GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL"); + + std::vector<std::string> oldRuntimeDirs, newRuntimeDirs; + cli->GetRPath(oldRuntimeDirs, false); + cli->GetRPath(newRuntimeDirs, true); + + // Note: These are separate commands to avoid install_name_tool + // corruption on 10.6. + for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin(); + i != oldRuntimeDirs.end(); ++i) + { + os << indent << "execute_process(COMMAND " << installNameTool << "\n"; + os << indent << " -delete_rpath \"" << *i << "\"\n"; + os << indent << " \"" << toDestDirPath << "\")\n"; + } - // Write a rule to run chrpath to set the install-tree RPATH - if(newRpath.empty()) - { - os << indent << "FILE(RPATH_REMOVE\n" - << indent << " FILE \"" << toDestDirPath << "\")\n"; + for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin(); + i != newRuntimeDirs.end(); ++i) + { + os << indent << "execute_process(COMMAND " << installNameTool << "\n"; + os << indent << " -add_rpath \"" << *i << "\"\n"; + os << indent << " \"" << toDestDirPath << "\")\n"; + } } else { - os << indent << "FILE(RPATH_CHANGE\n" - << indent << " FILE \"" << toDestDirPath << "\"\n" - << indent << " OLD_RPATH \"" << oldRpath << "\"\n" - << indent << " NEW_RPATH \"" << newRpath << "\")\n"; + // Construct the original rpath string to be replaced. + std::string oldRpath = cli->GetRPathString(false); + + // Get the install RPATH from the link information. + std::string newRpath = cli->GetChrpathString(); + + // Skip the rule if the paths are identical + if(oldRpath == newRpath) + { + return; + } + + // Write a rule to run chrpath to set the install-tree RPATH + if(newRpath.empty()) + { + os << indent << "FILE(RPATH_REMOVE\n" + << indent << " FILE \"" << toDestDirPath << "\")\n"; + } + else + { + os << indent << "FILE(RPATH_CHANGE\n" + << indent << " FILE \"" << toDestDirPath << "\"\n" + << indent << " OLD_RPATH \"" << oldRpath << "\"\n" + << indent << " NEW_RPATH \"" << newRpath << "\")\n"; + } } } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index dce1838..c2da4a9 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1325,6 +1325,26 @@ std::string cmLocalGenerator::GetIncludeFlags( } //---------------------------------------------------------------------------- +void cmLocalGenerator::GetCompileOptions(std::string& flags, + cmTarget* target, + const char *config) +{ + // Add target-specific flags. + if(const char *prop = target->GetProperty("COMPILE_FLAGS")) + { + this->AppendFlags(flags, prop); + } + + std::vector<std::string> opts; // TODO: Emitted. + target->GetCompileOptions(opts, config); + for(std::vector<std::string>::const_iterator li = opts.begin(); + li != opts.end(); ++li) + { + this->AppendFlags(flags, li->c_str()); + } +} + +//---------------------------------------------------------------------------- void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, cmGeneratorTarget* target, const char* lang, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 84fd58c..9a71b9b 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -217,6 +217,9 @@ public: cmGeneratorTarget* target, const char* lang = "C", const char *config = 0, bool stripImplicitInclDirs = true); + void GetCompileOptions(std::string& flags, + cmTarget* target, + const char *config); /** Compute the language used to compile the given source file. */ const char* GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index dc94476..4c78f7f 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1639,9 +1639,9 @@ void cmLocalVisualStudio6Generator // store flags for each configuration std::string flags = " "; std::string flagsRelease = " "; - std::string flagsMinSize = " "; + std::string flagsMinSizeRel = " "; std::string flagsDebug = " "; - std::string flagsDebugRel = " "; + std::string flagsRelWithDebInfo = " "; if(target.GetType() >= cmTarget::EXECUTABLE && target.GetType() <= cmTarget::OBJECT_LIBRARY) { @@ -1664,16 +1664,16 @@ void cmLocalVisualStudio6Generator flagsRelease += " -DCMAKE_INTDIR=\\\"Release\\\" "; flagVar = baseFlagVar + "_MINSIZEREL"; - flagsMinSize = this->Makefile->GetSafeDefinition(flagVar.c_str()); - flagsMinSize += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" "; + flagsMinSizeRel = this->Makefile->GetSafeDefinition(flagVar.c_str()); + flagsMinSizeRel += " -DCMAKE_INTDIR=\\\"MinSizeRel\\\" "; flagVar = baseFlagVar + "_DEBUG"; flagsDebug = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsDebug += " -DCMAKE_INTDIR=\\\"Debug\\\" "; flagVar = baseFlagVar + "_RELWITHDEBINFO"; - flagsDebugRel = this->Makefile->GetSafeDefinition(flagVar.c_str()); - flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; + flagsRelWithDebInfo = this->Makefile->GetSafeDefinition(flagVar.c_str()); + flagsRelWithDebInfo += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; } // if _UNICODE and _SBCS are not found, then add -D_MBCS @@ -1686,12 +1686,31 @@ void cmLocalVisualStudio6Generator flags += " /D \"_MBCS\""; } + { + std::string targetFlags; + this->GetCompileOptions(targetFlags, &target, 0); // Add per-target flags. - if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS")) + if(!targetFlags.empty()) { flags += " "; flags += targetFlags; } + } +#define ADD_FLAGS(CONFIG) \ + { \ + std::string targetFlags; \ + this->GetCompileOptions(targetFlags, &target, #CONFIG); \ + if(!targetFlags.empty()) \ + { \ + flags ## CONFIG += " "; \ + flags ## CONFIG += targetFlags; \ + } \ + } + + ADD_FLAGS(Debug) + ADD_FLAGS(Release) + ADD_FLAGS(MinSizeRel) + ADD_FLAGS(RelWithDebInfo) // Add per-target and per-configuration preprocessor definitions. std::set<std::string> definesSet; @@ -1731,19 +1750,19 @@ void cmLocalVisualStudio6Generator flags += defines; flagsDebug += debugDefines; flagsRelease += releaseDefines; - flagsMinSize += minsizeDefines; - flagsDebugRel += debugrelDefines; + flagsMinSizeRel += minsizeDefines; + flagsRelWithDebInfo += debugrelDefines; // The template files have CXX FLAGS in them, that need to be replaced. // There are not separate CXX and C template files, so we use the same // variable names. The previous code sets up flags* variables to contain // the correct C or CXX flags cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", - flagsMinSize.c_str()); + flagsMinSizeRel.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", flagsDebug.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO", - flagsDebugRel.c_str()); + flagsRelWithDebInfo.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", flagsRelease.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str()); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 58d28da..e7badf0 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -723,8 +723,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, } } + std::string targetFlags; + this->GetCompileOptions(targetFlags, &target, configName); // Add the target-specific flags. - if(const char* targetFlags = target.GetProperty("COMPILE_FLAGS")) + if(!targetFlags.empty()) { flags += " "; flags += targetFlags; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index b7a454b..e4219a9 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -30,11 +30,8 @@ cmMakefileExecutableTargetGenerator this->TargetNamePDB, this->ConfigName); this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, - this->TargetNameOut, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); - this->MacContentDirectory = - this->OSXBundleGenerator->GetMacContentDirectory(); } //---------------------------------------------------------------------------- @@ -103,11 +100,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Construct the full path version of the names. std::string outpath = this->Target->GetDirectory(this->ConfigName); - outpath += "/"; if(this->Target->IsAppBundleOnApple()) { this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); } + outpath += "/"; std::string outpathImp; if(relink) { diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 5b4e4d7..347f26d 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -24,19 +24,14 @@ cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): cmMakefileTargetGenerator(target) { - cmOSXBundleGenerator::PrepareTargetProperties(this->Target); - this->CustomCommandDriver = OnDepends; this->Target->GetLibraryNames( this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, this->TargetNameImport, this->TargetNamePDB, this->ConfigName); this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, - this->TargetNameOut, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); - this->MacContentDirectory = - this->OSXBundleGenerator->GetMacContentDirectory(); } //---------------------------------------------------------------------------- @@ -292,14 +287,15 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string outpathImp; if(this->Target->IsFrameworkOnApple()) { - outpath = this->MacContentDirectory; - this->OSXBundleGenerator->CreateFramework(targetName); + outpath = this->Target->GetDirectory(this->ConfigName); + this->OSXBundleGenerator->CreateFramework(targetName, outpath); + outpath += "/"; } else if(this->Target->IsCFBundleOnApple()) { outpath = this->Target->GetDirectory(this->ConfigName); - outpath += "/"; this->OSXBundleGenerator->CreateCFBundle(targetName, outpath); + outpath += "/"; } else if(relink) { @@ -727,7 +723,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules commands1.clear(); // Add a rule to create necessary symlinks for the library. - if(targetOutPath != targetOutPathReal) + // Frameworks are handled by cmOSXBundleGenerator. + if(targetOutPath != targetOutPathReal && !this->Target->IsFrameworkOnApple()) { std::string symlink = "$(CMAKE_COMMAND) -E cmake_symlink_library "; symlink += targetOutPathReal; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a7be669..10b7849 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -335,21 +335,25 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n"; } + std::string targetFlags; for(std::set<cmStdString>::const_iterator l = languages.begin(); l != languages.end(); ++l) { *this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n"; *this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) << "\n\n"; + std::string targetLangFlags; + this->LocalGenerator->GetCompileOptions(targetLangFlags, this->Target, + this->LocalGenerator->ConfigurationName.c_str()); + if (!targetFlags.empty() && targetFlags != targetLangFlags) + { + targetFlags += " " + targetLangFlags; + } } - // Add target-specific flags. - if(this->Target->GetProperty("COMPILE_FLAGS")) + if (!targetFlags.empty()) { - std::string flags; - this->LocalGenerator->AppendFlags - (flags, this->Target->GetProperty("COMPILE_FLAGS")); - *this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n"; + *this->FlagFileStream << "# TARGET_FLAGS = " << targetFlags << "\n\n"; } } @@ -360,7 +364,7 @@ cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator() (cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->Generator->MacContentDirectory.empty()) + if(!this->Generator->GetTarget()->IsBundleOnApple()) { return; } @@ -535,8 +539,13 @@ cmMakefileTargetGenerator langFlags += "_FLAGS)"; this->LocalGenerator->AppendFlags(flags, langFlags.c_str()); - // Add target-specific flags. - if(this->Target->GetProperty("COMPILE_FLAGS")) + std::string configUpper = + cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); + + std::string targetFlags; + this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, + configUpper.c_str()); + if (!targetFlags.empty()) { std::string langIncludeExpr = "CMAKE_"; langIncludeExpr += lang; @@ -548,7 +557,7 @@ cmMakefileTargetGenerator cmsys::RegularExpression r(regex); std::vector<std::string> args; cmSystemTools::ParseWindowsCommandLine( - this->Target->GetProperty("COMPILE_FLAGS"), + targetFlags.c_str(), args); for(std::vector<std::string>::iterator i = args.begin(); i != args.end(); ++i) @@ -562,8 +571,7 @@ cmMakefileTargetGenerator } else { - this->LocalGenerator->AppendFlags - (flags, this->Target->GetProperty("COMPILE_FLAGS")); + this->LocalGenerator->AppendFlags(flags, targetFlags.c_str()); } } @@ -597,8 +605,6 @@ cmMakefileTargetGenerator << compile_defs << "\n" << "\n"; } - std::string configUpper = - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); std::string defPropName = "COMPILE_DEFINITIONS_"; defPropName += configUpper; if(const char* config_compile_defs = diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 2798e54..f7a1e2e 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -233,7 +233,6 @@ protected: std::string TargetNamePDB; // Mac OS X content info. - std::string MacContentDirectory; std::set<cmStdString> MacContentFolders; cmOSXBundleGenerator* OSXBundleGenerator; MacOSXContentGeneratorType* MacOSXContentGenerator; diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx index 4456aa7..1fa4e95 100644 --- a/Source/cmMakefileUtilityTargetGenerator.cxx +++ b/Source/cmMakefileUtilityTargetGenerator.cxx @@ -25,11 +25,8 @@ cmMakefileUtilityTargetGenerator { this->CustomCommandDriver = OnUtility; this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target, - this->TargetNameOut, this->ConfigName); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); - this->MacContentDirectory = - this->OSXBundleGenerator->GetMacContentDirectory(); } //---------------------------------------------------------------------------- diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index e5f3570..1bc4302 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -36,8 +36,6 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNamePDB() , TargetLinkLanguage(0) { - cmOSXBundleGenerator::PrepareTargetProperties(target); - this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) target->GetExecutableNames(this->TargetNameOut, @@ -61,7 +59,6 @@ cmNinjaNormalTargetGenerator(cmTarget* target) } this->OSXBundleGenerator = new cmOSXBundleGenerator(target, - this->TargetNameOut, this->GetConfigName()); this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders); } @@ -383,24 +380,32 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() if (this->GetTarget()->IsAppBundleOnApple()) { // Create the app bundle - std::string outpath; + std::string outpath = + this->GetTarget()->GetDirectory(this->GetConfigName()); this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); // Calculate the output path - targetOutput = outpath + this->TargetNameOut; + targetOutput = outpath; + targetOutput += "/"; + targetOutput += this->TargetNameOut; targetOutput = this->ConvertToNinjaPath(targetOutput.c_str()); - targetOutputReal = outpath + this->TargetNameReal; + targetOutputReal = outpath; + targetOutputReal += "/"; + targetOutputReal += this->TargetNameReal; targetOutputReal = this->ConvertToNinjaPath(targetOutputReal.c_str()); } else if (this->GetTarget()->IsFrameworkOnApple()) { // Create the library framework. - this->OSXBundleGenerator->CreateFramework(this->TargetNameOut); + std::string outpath = + this->GetTarget()->GetDirectory(this->GetConfigName()); + this->OSXBundleGenerator->CreateFramework(this->TargetNameOut, outpath); } else if(this->GetTarget()->IsCFBundleOnApple()) { // Create the core foundation bundle. - std::string outpath; + std::string outpath = + this->GetTarget()->GetDirectory(this->GetConfigName()); this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, outpath); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 778f86a..ae18a48 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -154,9 +154,9 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, language.c_str()); // Add include directory flags. + const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); { std::vector<std::string> includes; - const char *config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, language.c_str(), config); @@ -174,7 +174,9 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags()); // Add target-specific flags. - if(this->Target->GetProperty("COMPILE_FLAGS")) + std::string targetFlags; + this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, config); + if(!targetFlags.empty()) { std::string langIncludeExpr = "CMAKE_"; langIncludeExpr += language; @@ -186,7 +188,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, cmsys::RegularExpression r(regex); std::vector<std::string> args; cmSystemTools::ParseWindowsCommandLine( - this->Target->GetProperty("COMPILE_FLAGS"), + targetFlags.c_str(), args); for(std::vector<std::string>::iterator i = args.begin(); i != args.end(); ++i) @@ -201,7 +203,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, else { this->LocalGenerator->AppendFlags - (flags, this->Target->GetProperty("COMPILE_FLAGS")); + (flags, targetFlags.c_str()); } } @@ -702,7 +704,7 @@ cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( cmSourceFile& source, const char* pkgloc) { // Skip OS X content when not building a Framework or Bundle. - if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty()) + if(!this->Generator->GetTarget()->IsBundleOnApple()) { return; } diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 42fad07..d3cdf85 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -16,38 +16,19 @@ #include <cassert> -void cmOSXBundleGenerator::PrepareTargetProperties(cmTarget* target) -{ - if(target->IsCFBundleOnApple()) - { - target->SetProperty("PREFIX", ""); - target->SetProperty("SUFFIX", ""); - } -} - //---------------------------------------------------------------------------- cmOSXBundleGenerator:: cmOSXBundleGenerator(cmTarget* target, - std::string targetNameOut, const char* configName) : Target(target) , Makefile(target->GetMakefile()) , LocalGenerator(Makefile->GetLocalGenerator()) - , TargetNameOut(targetNameOut) , ConfigName(configName) - , MacContentDirectory() - , FrameworkVersion() , MacContentFolders(0) { if (this->MustSkip()) return; - this->MacContentDirectory = - this->Target->GetMacContentDirectory(this->ConfigName, - /*implib*/ false, - /*includeMacOS*/ false); - if(this->Target->IsFrameworkOnApple()) - this->FrameworkVersion = this->Target->GetFrameworkVersion(); } //---------------------------------------------------------------------------- @@ -57,41 +38,60 @@ bool cmOSXBundleGenerator::MustSkip() } //---------------------------------------------------------------------------- -void cmOSXBundleGenerator::CreateAppBundle(std::string& targetName, +void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, std::string& outpath) { if (this->MustSkip()) return; // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - outpath += "/"; - this->Makefile->AddCMakeOutputFile(outpath.c_str()); + std::string out = outpath; + out += "/"; + out += this->Target->GetAppBundleDirectory(this->ConfigName, false); + cmSystemTools::MakeDirectory(out.c_str()); + this->Makefile->AddCMakeOutputFile(out.c_str()); + + std::string newoutpath = out; // Configure the Info.plist file. Note that it needs the executable name // to be set. - std::string plist = this->MacContentDirectory + "Info.plist"; + std::string plist = outpath; + plist += "/"; + plist += this->Target->GetAppBundleDirectory(this->ConfigName, true); + plist += "/Info.plist"; this->LocalGenerator->GenerateAppleInfoPList(this->Target, targetName.c_str(), plist.c_str()); this->Makefile->AddCMakeOutputFile(plist.c_str()); + outpath = newoutpath; } //---------------------------------------------------------------------------- -void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) +void cmOSXBundleGenerator::CreateFramework( + const std::string& targetName, const std::string& outpath) { if (this->MustSkip()) return; assert(this->MacContentFolders); + // Compute the location of the top-level foo.framework directory. + std::string contentdir = outpath + "/" + + this->Target->GetFrameworkDirectory(this->ConfigName, true); + contentdir += "/"; + + std::string newoutpath = outpath + "/" + + this->Target->GetFrameworkDirectory(this->ConfigName, false); + + std::string frameworkVersion = this->Target->GetFrameworkVersion(); + // Configure the Info.plist file into the Resources directory. this->MacContentFolders->insert("Resources"); - std::string plist = this->MacContentDirectory + "Resources/Info.plist"; + std::string plist = newoutpath; + plist += "/Resources/Info.plist"; + std::string name = cmSystemTools::GetFilenameName(targetName); this->LocalGenerator->GenerateFrameworkInfoPList(this->Target, - targetName.c_str(), + name.c_str(), plist.c_str()); // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to @@ -99,25 +99,17 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) std::string oldName; std::string newName; - // Compute the location of the top-level foo.framework directory. - std::string top = this->Target->GetDirectory(this->ConfigName); - top += "/"; - top += this->TargetNameOut; - top += ".framework/"; // Make foo.framework/Versions - std::string versions = top; + std::string versions = contentdir; versions += "Versions"; cmSystemTools::MakeDirectory(versions.c_str()); // Make foo.framework/Versions/version - std::string version = versions; - version += "/"; - version += this->FrameworkVersion; - cmSystemTools::MakeDirectory(version.c_str()); + cmSystemTools::MakeDirectory(newoutpath.c_str()); // Current -> version - oldName = this->FrameworkVersion; + oldName = frameworkVersion; newName = versions; newName += "/Current"; cmSystemTools::RemoveFile(newName.c_str()); @@ -126,9 +118,9 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) // foo -> Versions/Current/foo oldName = "Versions/Current/"; - oldName += this->TargetNameOut; - newName = top; - newName += this->TargetNameOut; + oldName += name; + newName = contentdir; + newName += name; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); this->Makefile->AddCMakeOutputFile(newName.c_str()); @@ -138,7 +130,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) this->MacContentFolders->end()) { oldName = "Versions/Current/Resources"; - newName = top; + newName = contentdir; newName += "Resources"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); @@ -150,7 +142,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) this->MacContentFolders->end()) { oldName = "Versions/Current/Headers"; - newName = top; + newName = contentdir; newName += "Headers"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); @@ -162,7 +154,7 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) this->MacContentFolders->end()) { oldName = "Versions/Current/PrivateHeaders"; - newName = top; + newName = contentdir; newName += "PrivateHeaders"; cmSystemTools::RemoveFile(newName.c_str()); cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); @@ -171,23 +163,24 @@ void cmOSXBundleGenerator::CreateFramework(std::string const& targetName) } //---------------------------------------------------------------------------- -void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName, - std::string& outpath) +void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, + const std::string& root) { if (this->MustSkip()) return; // Compute bundle directory names. - outpath = this->MacContentDirectory; - outpath += "MacOS"; - cmSystemTools::MakeDirectory(outpath.c_str()); - outpath += "/"; - this->Makefile->AddCMakeOutputFile(outpath.c_str()); + std::string out = root; + out += "/"; + out += this->Target->GetCFBundleDirectory(this->ConfigName, false); + cmSystemTools::MakeDirectory(out.c_str()); + this->Makefile->AddCMakeOutputFile(out.c_str()); // Configure the Info.plist file. Note that it needs the executable name // to be set. - std::string plist = this->MacContentDirectory; - plist += "Info.plist"; + std::string plist = + this->Target->GetCFBundleDirectory(this->ConfigName, true); + plist += "/Info.plist"; this->LocalGenerator->GenerateAppleInfoPList(this->Target, targetName.c_str(), plist.c_str()); @@ -220,7 +213,11 @@ std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc) { // Construct the full path to the content subdirectory. - std::string macdir = this->MacContentDirectory; + + std::string macdir = + this->Target->GetMacContentDirectory(this->ConfigName, + /*implib*/ false); + macdir += "/"; macdir += pkgloc; cmSystemTools::MakeDirectory(macdir.c_str()); diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h index 01e3cbe..ec82b9a 100644 --- a/Source/cmOSXBundleGenerator.h +++ b/Source/cmOSXBundleGenerator.h @@ -25,15 +25,20 @@ class cmLocalGenerator; class cmOSXBundleGenerator { public: - static void PrepareTargetProperties(cmTarget* target); - cmOSXBundleGenerator(cmTarget* target, - std::string targetNameOut, const char* configName); - void CreateAppBundle(std::string& targetName, std::string& outpath); - void CreateFramework(std::string const& targetName); - void CreateCFBundle(std::string& targetName, std::string& outpath); + // create an app bundle at a given root, and return + // the directory within the bundle that contains the executable + void CreateAppBundle(const std::string& targetName, std::string& root); + + // create a framework at a given root + void CreateFramework(const std::string& targetName, + const std::string& root); + + // create a cf bundle at a given root + void CreateCFBundle(const std::string& targetName, + const std::string& root); struct MacOSXContentGeneratorType { @@ -46,10 +51,6 @@ public: MacOSXContentGeneratorType* generator); std::string InitMacOSXContentDirectory(const char* pkgloc); - std::string GetMacContentDirectory() const - { return this->MacContentDirectory; } - std::string GetFrameworkVersion() const - { return this->FrameworkVersion; } void SetMacContentFolders(std::set<cmStdString>* macContentFolders) { this->MacContentFolders = macContentFolders; } @@ -60,10 +61,7 @@ private: cmTarget* Target; cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; - std::string TargetNameOut; const char* ConfigName; - std::string MacContentDirectory; - std::string FrameworkVersion; std::set<cmStdString>* MacContentFolders; }; diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 6e41768..93885b2 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -36,8 +36,25 @@ public: OD(od), GlobalGenerator(od->GlobalGenerator) { this->FullPath = file; - this->Directory = cmSystemTools::GetFilenamePath(file); - this->FileName = cmSystemTools::GetFilenameName(file); + + if(file.rfind(".framework") != std::string::npos) + { + cmsys::RegularExpression splitFramework; + splitFramework.compile("^(.*)/(.*).framework/.*/(.*)$"); + if(splitFramework.find(file) && + (splitFramework.match(2) == splitFramework.match(3))) + { + this->Directory = splitFramework.match(1); + this->FileName = + std::string(file.begin() + this->Directory.size() + 1, file.end()); + } + } + + if(this->FileName.empty()) + { + this->Directory = cmSystemTools::GetFilenamePath(file); + this->FileName = cmSystemTools::GetFilenameName(file); + } } virtual ~cmOrderDirectoriesConstraint() {} @@ -301,22 +318,42 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath, // Add the runtime library at most once. if(this->EmmittedConstraintSOName.insert(fullPath).second) { + std::string soname2 = soname ? soname : ""; // Implicit link directories need special handling. if(!this->ImplicitDirectories.empty()) { std::string dir = cmSystemTools::GetFilenamePath(fullPath); + + if(fullPath.rfind(".framework") != std::string::npos) + { + cmsys::RegularExpression splitFramework; + splitFramework.compile("^(.*)/(.*).framework/(.*)/(.*)$"); + if(splitFramework.find(fullPath) && + (splitFramework.match(2) == splitFramework.match(4))) + { + dir = splitFramework.match(1); + soname2 = splitFramework.match(2); + soname2 += ".framework/"; + soname2 += splitFramework.match(3); + soname2 += "/"; + soname2 += splitFramework.match(4); + } + } + if(this->ImplicitDirectories.find(dir) != this->ImplicitDirectories.end()) { this->ImplicitDirEntries.push_back( - new cmOrderDirectoriesConstraintSOName(this, fullPath, soname)); + new cmOrderDirectoriesConstraintSOName(this, fullPath, + soname2.c_str())); return; } } // Construct the runtime information entry for this library. this->ConstraintEntries.push_back( - new cmOrderDirectoriesConstraintSOName(this, fullPath, soname)); + new cmOrderDirectoriesConstraintSOName(this, fullPath, + soname2.c_str())); } else { diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index a468fa7..350b462 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -309,6 +309,46 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) cmLocalGenerator::EscapeForCMake(_moc_headers.c_str()).c_str()); makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE"); + const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR"); + if (!qtVersion) + { + qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR"); + } + if (const char *targetQtVersion = + target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", 0)) + { + qtVersion = targetQtVersion; + } + if (qtVersion) + { + makefile->AddDefinition("_target_qt_version", qtVersion); + } + + { + const char *qtMoc = makefile->GetSafeDefinition("QT_MOC_EXECUTABLE"); + makefile->AddDefinition("_qt_moc_executable", qtMoc); + } + + if (strcmp(qtVersion, "5") == 0) + { + cmTarget *qt5Moc = makefile->FindTargetToUse("Qt5::moc"); + if (!qt5Moc) + { + cmSystemTools::Error("Qt5::moc target not found ", + automocTargetName.c_str()); + return; + } + makefile->AddDefinition("_qt_moc_executable", qt5Moc->GetLocation(0)); + } + else + { + if (strcmp(qtVersion, "4") != 0) + { + cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and " + "Qt 5 ", automocTargetName.c_str()); + } + } + const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); std::string inputFile = cmakeRoot; inputFile += "/Modules/AutomocInfo.cmake.in"; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 67f3023..803d0da 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2413,6 +2413,27 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath, } //---------------------------------------------------------------------------- +bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath, + std::string& soname) +{ + std::vector<cmStdString> cmds; + cmds.push_back("otool"); + cmds.push_back("-D"); + cmds.push_back(fullPath.c_str()); + + std::string output; + RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE); + + std::vector<std::string> strs = cmSystemTools::tokenize(output, "\n"); + if(strs.size() == 2) + { + soname = strs[1]; + return true; + } + return false; +} + +//---------------------------------------------------------------------------- #if defined(CMAKE_USE_ELF_PARSER) std::string::size_type cmSystemToolsFindRPath(std::string const& have, std::string const& want) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 8355d78..f5be26b 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -439,6 +439,10 @@ public: static bool GuessLibrarySOName(std::string const& fullPath, std::string& soname); + /** Try to guess the install name of a shared library. */ + static bool GuessLibraryInstallName(std::string const& fullPath, + std::string& soname); + /** Try to set the RPATH in an ELF binary. */ static bool ChangeRPath(std::string const& file, std::string const& oldRPath, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 47e36fd..ab051d0 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -130,31 +130,35 @@ public: typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType; SourceEntriesType SourceEntries; - struct IncludeDirectoriesEntry { - IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, + struct TargetPropertyEntry { + TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, const std::string &targetName = std::string()) : ge(cge), TargetName(targetName) {} const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; - std::vector<std::string> CachedIncludes; + std::vector<std::string> CachedEntries; const std::string TargetName; }; - std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; - std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; + std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; + std::vector<TargetPropertyEntry*> CompileOptionsEntries; + std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries; - std::map<std::string, std::vector<IncludeDirectoriesEntry*> > + std::map<std::string, std::vector<TargetPropertyEntry*> > CachedLinkInterfaceIncludeDirectoriesEntries; + std::map<std::string, std::vector<TargetPropertyEntry*> > + CachedLinkInterfaceCompileOptionsEntries; std::map<std::string, std::string> CachedLinkInterfaceCompileDefinitions; std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone; std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone; + std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone; }; //---------------------------------------------------------------------------- void deleteAndClear( - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries) + std::vector<cmTargetInternals::TargetPropertyEntry*> &entries) { - for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator + for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) @@ -167,10 +171,10 @@ void deleteAndClear( //---------------------------------------------------------------------------- void deleteAndClear( std::map<std::string, - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> > &entries) + std::vector<cmTargetInternals::TargetPropertyEntry*> > &entries) { for (std::map<std::string, - std::vector<cmTargetInternals::IncludeDirectoriesEntry*> >::iterator + std::vector<cmTargetInternals::TargetPropertyEntry*> >::iterator it = entries.begin(), end = entries.end(); it != end; ++it) { deleteAndClear(it->second); @@ -181,6 +185,7 @@ void deleteAndClear( cmTargetInternals::~cmTargetInternals() { deleteAndClear(this->CachedLinkInterfaceIncludeDirectoriesEntries); + deleteAndClear(this->CachedLinkInterfaceCompileOptionsEntries); } //---------------------------------------------------------------------------- @@ -199,6 +204,7 @@ cmTarget::cmTarget() this->IsImportedTarget = false; this->BuildInterfaceIncludesAppended = false; this->DebugIncludesDone = false; + this->DebugCompileOptionsDone = false; } //---------------------------------------------------------------------------- @@ -278,6 +284,7 @@ void cmTarget::DefineProperties(cmake *cm) "Contents of COMPILE_DEFINITIONS may use \"generator expressions\" with " "the syntax \"$<...>\". " CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS CM_DOCUMENT_COMPILE_DEFINITIONS_DISCLAIMER); cm->DefineProperty @@ -286,6 +293,32 @@ void cmTarget::DefineProperties(cmake *cm) "This is the configuration-specific version of COMPILE_DEFINITIONS."); cm->DefineProperty + ("COMPILE_OPTIONS", cmProperty::TARGET, + "List of options to pass to the compiler.", + "This property specifies the list of options specified " + "so far for this property. " + "This property exists on targets only. " + "\n" + "The target property values are used by the generators to set " + "the options for the compiler.\n" + "Contents of COMPILE_OPTIONS may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); + + cm->DefineProperty + ("INTERFACE_COMPILE_OPTIONS", cmProperty::TARGET, + "List of interface options to pass to the compiler.", + "Targets may populate this property to publish the compile options " + "required to compile against the headers for the target. Consuming " + "targets can add entries to their own COMPILE_OPTIONS property such " + "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS> to use the " + "compile options specified in the interface of 'foo'." + "\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); + + cm->DefineProperty ("DEFINE_SYMBOL", cmProperty::TARGET, "Define a symbol when compiling this target's sources.", "DEFINE_SYMBOL sets the name of the preprocessor symbol defined when " @@ -606,7 +639,8 @@ void cmTarget::DefineProperties(cmake *cm) "See also the include_directories command.\n" "Contents of INCLUDE_DIRECTORIES may use \"generator expressions\" with " "the syntax \"$<...>\". " - CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); cm->DefineProperty ("INSTALL_NAME_DIR", cmProperty::TARGET, @@ -803,7 +837,8 @@ void cmTarget::DefineProperties(cmake *cm) "as $<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES> to use the " "include directories specified in the interface of 'foo'." "\n" - CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); cm->DefineProperty ("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET, @@ -814,7 +849,8 @@ void cmTarget::DefineProperties(cmake *cm) "as $<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS> to use the " "compile definitions specified in the interface of 'foo'." "\n" - CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS); cm->DefineProperty ("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET, @@ -1211,6 +1247,15 @@ void cmTarget::DefineProperties(cmake *cm) "hard-code all the settings instead of using the target properties."); cm->DefineProperty + ("MACOSX_RPATH", cmProperty::TARGET, + "Whether to use rpaths on Mac OS X.", + "When this property is set to true, the directory portion of the" + "\"install_name\" field of shared libraries will default to \"@rpath\"." + "Runtime paths will also be embedded in binaries using this target." + "This property is initialized by the value of the variable " + "CMAKE_MACOSX_RPATH if it is set when a target is created."); + + cm->DefineProperty ("ENABLE_EXPORTS", cmProperty::TARGET, "Specify whether an executable exports symbols for loadable modules.", "Normally an executable does not export any symbols because it is " @@ -1353,6 +1398,11 @@ void cmTarget::DefineProperties(cmake *cm) "this value with \"ManagedCProj\", for example, in a Visual " "Studio managed C++ unit test project."); cm->DefineProperty + ("VS_GLOBAL_ROOTNAMESPACE", cmProperty::TARGET, + "Visual Studio project root namespace.", + "Sets the \"RootNamespace\" attribute for a generated Visual Studio " + "project. The attribute will be generated only if this is set."); + cm->DefineProperty ("VS_DOTNET_REFERENCES", cmProperty::TARGET, "Visual Studio managed project .NET references", "Adds one or more semicolon-delimited .NET references to a " @@ -1538,6 +1588,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); this->SetPropertyDefault("WIN32_EXECUTABLE", 0); this->SetPropertyDefault("MACOSX_BUNDLE", 0); + this->SetPropertyDefault("MACOSX_RPATH", 0); + // Collect the set of configuration types. std::vector<std::string> configNames; @@ -1712,6 +1764,13 @@ bool cmTarget::IsCFBundleOnApple() } //---------------------------------------------------------------------------- +bool cmTarget::IsBundleOnApple() +{ + return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() || + this->IsCFBundleOnApple(); +} + +//---------------------------------------------------------------------------- class cmTargetTraceDependencies { public: @@ -2757,7 +2816,18 @@ void cmTarget::SetProperty(const char* prop, const char* value) deleteAndClear(this->Internal->IncludeDirectoriesEntries); cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); this->Internal->IncludeDirectoriesEntries.push_back( - new cmTargetInternals::IncludeDirectoriesEntry(cge)); + new cmTargetInternals::TargetPropertyEntry(cge)); + return; + } + if(strcmp(prop,"COMPILE_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + deleteAndClear(this->Internal->CompileOptionsEntries); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); + this->Internal->CompileOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(cge)); return; } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) @@ -2770,14 +2840,14 @@ void cmTarget::SetProperty(const char* prop, const char* value) } if (strcmp(prop, "LINK_LIBRARIES") == 0) { - this->Internal->LinkInterfaceIncludeDirectoriesEntries.clear(); + this->Internal->LinkInterfacePropertyEntries.clear(); if (cmGeneratorExpression::IsValidTargetName(value) || cmGeneratorExpression::Find(value) != std::string::npos) { cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + this->Internal->LinkInterfacePropertyEntries.push_back(entry); } // Fall through } @@ -2799,7 +2869,16 @@ void cmTarget::AppendProperty(const char* prop, const char* value, this->Makefile->GetBacktrace(lfbt); cmGeneratorExpression ge(lfbt); this->Internal->IncludeDirectoriesEntries.push_back( - new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value))); + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); + return; + } + if(strcmp(prop,"COMPILE_OPTIONS") == 0) + { + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmGeneratorExpression ge(lfbt); + this->Internal->CompileOptionsEntries.push_back( + new cmTargetInternals::TargetPropertyEntry(ge.Parse(value))); return; } if(strcmp(prop,"EXPORT_NAME") == 0 && this->IsImported()) @@ -2818,7 +2897,7 @@ void cmTarget::AppendProperty(const char* prop, const char* value, cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfaceIncludeDirectoriesEntries.push_back(entry); + this->Internal->LinkInterfacePropertyEntries.push_back(entry); } // Fall through } @@ -2883,17 +2962,31 @@ void cmTarget::InsertInclude(const cmValueWithOrigin &entry, { cmGeneratorExpression ge(entry.Backtrace); - std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::iterator position + std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position = before ? this->Internal->IncludeDirectoriesEntries.begin() : this->Internal->IncludeDirectoriesEntries.end(); this->Internal->IncludeDirectoriesEntries.insert(position, - new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value))); + new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); +} + +//---------------------------------------------------------------------------- +void cmTarget::InsertCompileOption(const cmValueWithOrigin &entry, + bool before) +{ + cmGeneratorExpression ge(entry.Backtrace); + + std::vector<cmTargetInternals::TargetPropertyEntry*>::iterator position + = before ? this->Internal->CompileOptionsEntries.begin() + : this->Internal->CompileOptionsEntries.end(); + + this->Internal->CompileOptionsEntries.insert(position, + new cmTargetInternals::TargetPropertyEntry(ge.Parse(entry.Value))); } //---------------------------------------------------------------------------- static void processIncludeDirectories(cmTarget *tgt, - const std::vector<cmTargetInternals::IncludeDirectoriesEntry*> &entries, + const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, std::vector<std::string> &includes, std::set<std::string> &uniqueIncludes, cmGeneratorExpressionDAGChecker *dagChecker, @@ -2901,12 +2994,12 @@ static void processIncludeDirectories(cmTarget *tgt, { cmMakefile *mf = tgt->GetMakefile(); - for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator + for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { bool testIsOff = true; bool cacheIncludes = false; - std::vector<std::string> entryIncludes = (*it)->CachedIncludes; + std::vector<std::string> entryIncludes = (*it)->CachedEntries; if(!entryIncludes.empty()) { testIsOff = false; @@ -3009,7 +3102,7 @@ static void processIncludeDirectories(cmTarget *tgt, } if (cacheIncludes) { - (*it)->CachedIncludes = entryIncludes; + (*it)->CachedEntries = entryIncludes; } if (!usedIncludes.empty()) { @@ -3029,8 +3122,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) cmListFileBacktrace lfbt; cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INCLUDE_DIRECTORIES", 0, 0); + this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); this->AppendBuildInterfaceIncludes(); @@ -3065,8 +3158,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]) { for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfaceIncludeDirectoriesEntries.begin(), - end = this->Internal->LinkInterfaceIncludeDirectoriesEntries.end(); + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); it != end; ++it) { { @@ -3095,7 +3188,7 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) this->Internal ->CachedLinkInterfaceIncludeDirectoriesEntries[configString].push_back( - new cmTargetInternals::IncludeDirectoriesEntry(cge, + new cmTargetInternals::TargetPropertyEntry(cge, it->Value)); } } @@ -3123,6 +3216,159 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) } //---------------------------------------------------------------------------- +static void processCompileOptions(cmTarget *tgt, + const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + std::set<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const char *config, bool debugOptions) +{ + cmMakefile *mf = tgt->GetMakefile(); + + for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator + it = entries.begin(), end = entries.end(); it != end; ++it) + { + bool cacheOptions = false; + std::vector<std::string> entryOptions = (*it)->CachedEntries; + if(entryOptions.empty()) + { + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, + config, + false, + tgt, + dagChecker), + entryOptions); + if (mf->IsGeneratingBuildSystem() + && !(*it)->ge->GetHadContextSensitiveCondition()) + { + cacheOptions = true; + } + } + std::string usedOptions; + for(std::vector<std::string>::iterator + li = entryOptions.begin(); li != entryOptions.end(); ++li) + { + std::string opt = *li; + + if(uniqueOptions.insert(opt).second) + { + options.push_back(opt); + if (debugOptions) + { + usedOptions += " * " + opt + "\n"; + } + } + } + if (cacheOptions) + { + (*it)->CachedEntries = entryOptions; + } + if (!usedOptions.empty()) + { + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used compile options for target ") + + tgt->GetName() + ":\n" + + usedOptions, (*it)->ge->GetBacktrace()); + } + } +} + +//---------------------------------------------------------------------------- +void cmTarget::GetCompileOptions(std::vector<std::string> &result, + const char *config) +{ + std::set<std::string> uniqueOptions; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "COMPILE_OPTIONS", 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugOptions = !this->DebugCompileOptionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_OPTIONS") + != debugProperties.end(); + + if (this->Makefile->IsGeneratingBuildSystem()) + { + this->DebugCompileOptionsDone = true; + } + + processCompileOptions(this, + this->Internal->CompileOptionsEntries, + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + std::string configString = config ? config : ""; + if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[configString]) + { + for (std::vector<cmValueWithOrigin>::const_iterator + it = this->Internal->LinkInterfacePropertyEntries.begin(), + end = this->Internal->LinkInterfacePropertyEntries.end(); + it != end; ++it) + { + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(it->Value); + std::string targetResult = cge->Evaluate(this->Makefile, config, + false, this, 0, 0); + if (!this->Makefile->FindTargetToUse(targetResult.c_str())) + { + continue; + } + } + std::string optionGenex = "$<TARGET_PROPERTY:" + + it->Value + ",INTERFACE_COMPILE_OPTIONS>"; + if (cmGeneratorExpression::Find(it->Value) != std::string::npos) + { + // Because it->Value is a generator expression, ensure that it + // evaluates to the non-empty string before being used in the + // TARGET_PROPERTY expression. + optionGenex = "$<$<BOOL:" + it->Value + ">:" + optionGenex + ">"; + } + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse( + optionGenex); + + this->Internal + ->CachedLinkInterfaceCompileOptionsEntries[configString].push_back( + new cmTargetInternals::TargetPropertyEntry(cge, + it->Value)); + } + } + + processCompileOptions(this, + this->Internal->CachedLinkInterfaceCompileOptionsEntries[configString], + result, + uniqueOptions, + &dagChecker, + config, + debugOptions); + + if (!this->Makefile->IsGeneratingBuildSystem()) + { + deleteAndClear(this->Internal->CachedLinkInterfaceCompileOptionsEntries); + } + else + { + this->Internal->CacheLinkInterfaceCompileOptionsDone[configString] = true; + } +} + +//---------------------------------------------------------------------------- std::string cmTarget::GetCompileDefinitions(const char *config) { const char *configProp = 0; @@ -3408,17 +3654,23 @@ const char* cmTarget::NormalGetLocation(const char* config) // Now handle the deprecated build-time configuration location. this->Location = this->GetDirectory(); - if(!this->Location.empty()) - { - this->Location += "/"; - } const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); if(cfgid && strcmp(cfgid, ".") != 0) { - this->Location += cfgid; this->Location += "/"; + this->Location += cfgid; } - this->Location = this->BuildMacContentDirectory(this->Location, config); + + if(this->IsAppBundleOnApple()) + { + std::string macdir = this->BuildMacContentDirectory("", config, false); + if(!macdir.empty()) + { + this->Location += "/"; + this->Location += macdir; + } + } + this->Location += "/"; this->Location += this->GetFullName(config, false); return this->Location.c_str(); } @@ -3541,9 +3793,9 @@ const char *cmTarget::GetProperty(const char* prop, static std::string output; output = ""; std::string sep; - typedef cmTargetInternals::IncludeDirectoriesEntry - IncludeDirectoriesEntry; - for (std::vector<IncludeDirectoriesEntry*>::const_iterator + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for (std::vector<TargetPropertyEntry*>::const_iterator it = this->Internal->IncludeDirectoriesEntries.begin(), end = this->Internal->IncludeDirectoriesEntries.end(); it != end; ++it) @@ -3554,6 +3806,24 @@ const char *cmTarget::GetProperty(const char* prop, } return output.c_str(); } + if(strcmp(prop,"COMPILE_OPTIONS") == 0) + { + static std::string output; + output = ""; + std::string sep; + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for (std::vector<TargetPropertyEntry*>::const_iterator + it = this->Internal->CompileOptionsEntries.begin(), + end = this->Internal->CompileOptionsEntries.end(); + it != end; ++it) + { + output += sep; + output += (*it)->ge->GetInput(); + sep = ";"; + } + return output.c_str(); + } if (strcmp(prop,"IMPORTED") == 0) { @@ -3902,6 +4172,10 @@ std::string cmTarget::GetSOName(const char* config) else { // Use the soname given if any. + if(info->SOName.find("@rpath/") == 0) + { + return info->SOName.substr(6); + } return info->SOName; } } @@ -3924,6 +4198,75 @@ std::string cmTarget::GetSOName(const char* config) } //---------------------------------------------------------------------------- +bool cmTarget::HasMacOSXRpath(const char* config) +{ + bool install_name_is_rpath = false; + bool macosx_rpath = this->GetPropertyAsBool("MACOSX_RPATH"); + + if(!this->IsImportedTarget) + { + const char* install_name = this->GetProperty("INSTALL_NAME_DIR"); + bool use_install_name = + this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"); + if(install_name && use_install_name && + std::string(install_name) == "@rpath") + { + install_name_is_rpath = true; + } + } + else + { + // Lookup the imported soname. + if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this)) + { + if(!info->NoSOName && !info->SOName.empty()) + { + if(info->SOName.find("@rpath/") == 0) + { + install_name_is_rpath = true; + } + } + else + { + std::string install_name; + cmSystemTools::GuessLibraryInstallName(info->Location, install_name); + if(install_name.find("@rpath") != std::string::npos) + { + install_name_is_rpath = true; + } + } + } + } + + if(!install_name_is_rpath && !macosx_rpath) + { + return false; + } + + if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG")) + { + cmOStringStream w; + w << "Attempting to use"; + if(macosx_rpath) + { + w << " MACOSX_RPATH"; + } + else + { + w << " @rpath"; + } + w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set."; + w << " This could be because you are using a Mac OS X version"; + w << " less than 10.5 or because CMake's platform configuration is"; + w << " corrupt."; + cmake* cm = this->Makefile->GetCMakeInstance(); + cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace()); + } + + return true; +} + +//---------------------------------------------------------------------------- bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config) { if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY) @@ -4020,7 +4363,13 @@ std::string cmTarget::GetFullPath(const char* config, bool implib, std::string cmTarget::NormalGetFullPath(const char* config, bool implib, bool realname) { - std::string fpath = this->GetMacContentDirectory(config, implib); + std::string fpath = this->GetDirectory(config, implib); + fpath += "/"; + if(this->IsAppBundleOnApple()) + { + fpath = this->BuildMacContentDirectory(fpath, config, false); + fpath += "/"; + } // Add the full name of the target. if(implib) @@ -4152,10 +4501,28 @@ void cmTarget::GetFullNameInternal(const char* config, targetSuffix = this->Makefile->GetSafeDefinition(suffixVar); } - // frameworks do not have a prefix or a suffix + // frameworks have directory prefix but no suffix + std::string fw_prefix; if(this->IsFrameworkOnApple()) { - targetPrefix = 0; + fw_prefix = this->GetOutputName(config, false); + fw_prefix += ".framework/"; + targetPrefix = fw_prefix.c_str(); + targetSuffix = 0; + } + + if(this->IsCFBundleOnApple()) + { + fw_prefix = this->GetOutputName(config, false); + fw_prefix += "."; + const char *ext = this->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + fw_prefix += ext; + fw_prefix += "/Contents/MacOS/"; + targetPrefix = fw_prefix.c_str(); targetSuffix = 0; } @@ -4235,13 +4602,24 @@ void cmTarget::GetLibraryNames(std::string& name, // The library name. name = prefix+base+suffix; - // The library's soname. - this->ComputeVersionedName(soName, prefix, base, suffix, - name, soversion); - - // The library's real name on disk. - this->ComputeVersionedName(realName, prefix, base, suffix, - name, version); + if(this->IsFrameworkOnApple()) + { + realName = prefix; + realName += "Versions/"; + realName += this->GetFrameworkVersion(); + realName += "/"; + realName += base; + soName = realName; + } + else + { + // The library's soname. + this->ComputeVersionedName(soName, prefix, base, suffix, + name, soversion); + // The library's real name on disk. + this->ComputeVersionedName(realName, prefix, base, suffix, + name, version); + } // The import library name. if(this->GetType() == cmTarget::SHARED_LIBRARY || @@ -4529,14 +4907,13 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config) } //---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, - bool for_xcode) +std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) { // If building directly for installation then the build tree install_name // is the same as the install tree. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")) { - return GetInstallNameDirForInstallTree(config, for_xcode); + return GetInstallNameDirForInstallTree(); } // Use the build tree directory for the target. @@ -4544,12 +4921,16 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, !this->Makefile->IsOn("CMAKE_SKIP_RPATH") && !this->GetPropertyAsBool("SKIP_BUILD_RPATH")) { - std::string dir = this->GetDirectory(config); - dir += "/"; - if(this->IsFrameworkOnApple() && !for_xcode) + std::string dir; + if(this->GetPropertyAsBool("MACOSX_RPATH")) + { + dir = "@rpath"; + } + else { - dir += this->GetFrameworkDirectory(config); + dir = this->GetDirectory(config); } + dir += "/"; return dir; } else @@ -4559,8 +4940,7 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, } //---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, - bool for_xcode) +std::string cmTarget::GetInstallNameDirForInstallTree() { if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { @@ -4576,12 +4956,10 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, dir += "/"; } } - - if(this->IsFrameworkOnApple() && !for_xcode) + if(dir.empty() && this->GetPropertyAsBool("MACOSX_RPATH")) { - dir += this->GetFrameworkDirectory(config); + dir = "@rpath/"; } - return dir; } else @@ -5163,7 +5541,6 @@ void cmTarget::GetLanguages(std::set<cmStdString>& languages) const //---------------------------------------------------------------------------- bool cmTarget::IsChrpathUsed(const char* config) { -#if defined(CMAKE_USE_ELF_PARSER) // Only certain target types have an rpath. if(!(this->GetType() == cmTarget::SHARED_LIBRARY || this->GetType() == cmTarget::MODULE_LIBRARY || @@ -5197,6 +5574,12 @@ bool cmTarget::IsChrpathUsed(const char* config) return false; } + if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) + { + return true; + } + +#if defined(CMAKE_USE_ELF_PARSER) // Enable if the rpath flag uses a separator and the target uses ELF // binaries. if(const char* ll = this->GetLinkerLanguage(config, this)) @@ -6039,59 +6422,86 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head) } //---------------------------------------------------------------------------- -std::string cmTarget::GetFrameworkDirectory(const char* config) +std::string cmTarget::GetFrameworkDirectory(const char* config, + bool rootDir) { std::string fpath; - fpath += this->GetFullName(config, false); - fpath += ".framework/Versions/"; - fpath += this->GetFrameworkVersion(); - fpath += "/"; + fpath += this->GetOutputName(config, false); + fpath += ".framework"; + if(!rootDir) + { + fpath += "/Versions/"; + fpath += this->GetFrameworkVersion(); + } + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::GetCFBundleDirectory(const char* config, + bool contentOnly) +{ + std::string fpath; + fpath += this->GetOutputName(config, false); + fpath += "."; + const char *ext = this->GetProperty("BUNDLE_EXTENSION"); + if (!ext) + { + ext = "bundle"; + } + fpath += ext; + fpath += "/Contents"; + if(!contentOnly) + fpath += "/MacOS"; + return fpath; +} + +//---------------------------------------------------------------------------- +std::string cmTarget::GetAppBundleDirectory(const char* config, + bool contentOnly) +{ + std::string fpath = this->GetFullName(config, false); + fpath += ".app/Contents"; + if(!contentOnly) + fpath += "/MacOS"; return fpath; } //---------------------------------------------------------------------------- std::string cmTarget::BuildMacContentDirectory(const std::string& base, const char* config, - bool includeMacOS) + bool contentOnly) { std::string fpath = base; if(this->IsAppBundleOnApple()) { - fpath += this->GetFullName(config, false); - fpath += ".app/Contents/"; - if(includeMacOS) - fpath += "MacOS/"; + fpath += this->GetAppBundleDirectory(config, contentOnly); } if(this->IsFrameworkOnApple()) { - fpath += this->GetFrameworkDirectory(config); + fpath += this->GetFrameworkDirectory(config, contentOnly); } if(this->IsCFBundleOnApple()) { - fpath += this->GetFullName(config, false); - fpath += "."; - const char *ext = this->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - fpath += ext; - fpath += "/Contents/"; - if(includeMacOS) - fpath += "MacOS/"; + fpath += this->GetCFBundleDirectory(config, contentOnly); } return fpath; } //---------------------------------------------------------------------------- std::string cmTarget::GetMacContentDirectory(const char* config, - bool implib, - bool includeMacOS) + bool implib) { // Start with the output directory for the target. std::string fpath = this->GetDirectory(config, implib); fpath += "/"; - fpath = this->BuildMacContentDirectory(fpath, config, includeMacOS); + bool contentOnly = true; + if(this->IsFrameworkOnApple()) + { + // additional files with a framework go into the version specific + // directory + contentOnly = false; + } + fpath = this->BuildMacContentDirectory(fpath, config, contentOnly); return fpath; } @@ -6138,6 +6548,7 @@ cmTargetInternalPointer cmTargetInternalPointer::~cmTargetInternalPointer() { deleteAndClear(this->Pointer->IncludeDirectoriesEntries); + deleteAndClear(this->Pointer->CompileOptionsEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 508fc11..3bc0ab2 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -367,6 +367,9 @@ public: /** Get the soname of the target. Allowed only for a shared library. */ std::string GetSOName(const char* config); + /** Whether this library has @rpath and platform supports it. */ + bool HasMacOSXRpath(const char* config); + /** Test for special case of a third-party shared library that has no soname at all. */ bool IsImportedSharedLibWithoutSOName(const char* config); @@ -412,10 +415,14 @@ public: /** Return true if builtin chrpath will work for this target */ bool IsChrpathUsed(const char* config); - std::string GetInstallNameDirForBuildTree(const char* config, - bool for_xcode = false); - std::string GetInstallNameDirForInstallTree(const char* config, - bool for_xcode = false); + /** Return the install name directory for the target in the + * build tree. For example: "@rpath/", "@loader_path/", + * or "/full/path/to/library". */ + std::string GetInstallNameDirForBuildTree(const char* config); + + /** Return the install name directory for the target in the + * install tree. For example: "@rpath/" or "@loader_path/". */ + std::string GetInstallNameDirForInstallTree(); cmComputeLinkInformation* GetLinkInformation(const char* config, cmTarget *head = 0); @@ -467,6 +474,10 @@ public: /** Return whether this target is an executable Bundle on Apple. */ bool IsAppBundleOnApple(); + /** Return whether this target is an executable Bundle, a framework + or CFBundle on Apple. */ + bool IsBundleOnApple(); + /** Return the framework version string. Undefined if IsFrameworkOnApple returns false. */ std::string GetFrameworkVersion(); @@ -481,28 +492,33 @@ public: directory. */ bool UsesDefaultOutputDir(const char* config, bool implib); - /** Append to @a base the mac content directory and return it. */ - std::string BuildMacContentDirectory(const std::string& base, - const char* config = 0, - bool includeMacOS = true); - /** @return the mac content directory for this target. */ - std::string GetMacContentDirectory(const char* config = 0, - bool implib = false, - bool includeMacOS = true); + std::string GetMacContentDirectory(const char* config, + bool implib); /** @return whether this target have a well defined output file name. */ bool HaveWellDefinedOutputFiles(); /** @return the Mac framework directory without the base. */ - std::string GetFrameworkDirectory(const char* config = 0); + std::string GetFrameworkDirectory(const char* config, bool rootDir); + + /** @return the Mac CFBundle directory without the base */ + std::string GetCFBundleDirectory(const char* config, bool contentOnly); + + /** @return the Mac App directory without the base */ + std::string GetAppBundleDirectory(const char* config, bool contentOnly); std::vector<std::string> GetIncludeDirectories(const char *config); void InsertInclude(const cmValueWithOrigin &entry, bool before = false); + void InsertCompileOption(const cmValueWithOrigin &entry, + bool before = false); void AppendBuildInterfaceIncludes(); + void GetCompileOptions(std::vector<std::string> &result, + const char *config); + bool IsNullImpliedByLinkLibraries(const std::string &p); bool IsLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); @@ -601,6 +617,11 @@ private: the same as GetFullName. */ std::string NormalGetRealName(const char* config); + /** Append to @a base the mac content directory and return it. */ + std::string BuildMacContentDirectory(const std::string& base, + const char* config, + bool contentOnly); + private: std::string Name; std::vector<cmCustomCommand> PreBuildCommands; @@ -627,6 +648,7 @@ private: bool IsApple; bool IsImportedTarget; bool DebugIncludesDone; + bool DebugCompileOptionsDone; mutable std::set<std::string> LinkImplicitNullProperties; bool BuildInterfaceIncludesAppended; diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h index ec9b071..22d8fa8 100644 --- a/Source/cmTargetCompileDefinitionsCommand.h +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -70,6 +70,7 @@ public: "Arguments to target_compile_definitions may use \"generator " "expressions\" with the syntax \"$<...>\". " CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS ; } diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx new file mode 100644 index 0000000..e80c845 --- /dev/null +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -0,0 +1,62 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmTargetCompileOptionsCommand.h" + +bool cmTargetCompileOptionsCommand +::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) +{ + return this->HandleArguments(args, "COMPILE_OPTIONS", PROCESS_BEFORE); +} + +void cmTargetCompileOptionsCommand +::HandleImportedTarget(const std::string &tgt) +{ + cmOStringStream e; + e << "Cannot specify compile options for imported target \"" + << tgt << "\"."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +void cmTargetCompileOptionsCommand +::HandleMissingTarget(const std::string &name) +{ + cmOStringStream e; + e << "Cannot specify compile options for target \"" << name << "\" " + "which is not built by this project."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +//---------------------------------------------------------------------------- +std::string cmTargetCompileOptionsCommand +::Join(const std::vector<std::string> &content) +{ + std::string defs; + std::string sep; + for(std::vector<std::string>::const_iterator it = content.begin(); + it != content.end(); ++it) + { + defs += sep + *it; + sep = ";"; + } + return defs; +} + +//---------------------------------------------------------------------------- +void cmTargetCompileOptionsCommand +::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content, + bool) +{ + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmValueWithOrigin entry(this->Join(content), lfbt); + tgt->InsertCompileOption(entry); +} diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h new file mode 100644 index 0000000..87fa1a7 --- /dev/null +++ b/Source/cmTargetCompileOptionsCommand.h @@ -0,0 +1,90 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmTargetCompileOptionsCommand_h +#define cmTargetCompileOptionsCommand_h + +#include "cmTargetPropCommandBase.h" + +class cmTargetCompileOptionsCommand : public cmTargetPropCommandBase +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmTargetCompileOptionsCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() const { return "target_compile_options";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() const + { + return + "Add compile options to a target."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() const + { + return + " target_compile_options(<target> [BEFORE] " + "<INTERFACE|PUBLIC|PRIVATE> [items1...]\n" + " [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])\n" + "Specify compile options to use when compiling a given target. " + "The named <target> must have been created by a command such as " + "add_executable or add_library and must not be an IMPORTED target. " + "If BEFORE is specified, the content will be prepended to the property " + "instead of being appended.\n" + "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify " + "the scope of the following arguments. PRIVATE and PUBLIC items will " + "populate the COMPILE_OPTIONS property of <target>. PUBLIC and " + "INTERFACE items will populate the INTERFACE_COMPILE_OPTIONS " + "property of <target>. " + "The following arguments specify compile opitions. " + "Repeated calls for the same <target> append items in the order called." + "\n" + "Arguments to target_compile_options may use \"generator " + "expressions\" with the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + ; + } + + cmTypeMacro(cmTargetCompileOptionsCommand, cmTargetPropCommandBase); + +private: + virtual void HandleImportedTarget(const std::string &tgt); + virtual void HandleMissingTarget(const std::string &name); + + virtual void HandleDirectContent(cmTarget *tgt, + const std::vector<std::string> &content, + bool prepend); + virtual std::string Join(const std::vector<std::string> &content); +}; + +#endif diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h index e4bc9cf..4a1a4df 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.h +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -75,6 +75,7 @@ public: "Arguments to target_include_directories may use \"generator " "expressions\" with the syntax \"$<...>\". " CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS + CM_DOCUMENT_LANGUAGE_GENERATOR_EXPRESSIONS ; } diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index f5fdca4..3905e9b 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -15,6 +15,7 @@ static const char* const cmVariableWatchAccessStrings[] = { "READ_ACCESS", "UNKNOWN_READ_ACCESS", + "UNKNOWN_DEFINED_ACCESS", "ALLOWED_UNKNOWN_READ_ACCESS", "MODIFIED_ACCESS", "REMOVED_ACCESS", diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index a432943..297a92b 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -117,24 +117,9 @@ void cmVariableWatchCommand::VariableAccessed(const std::string& variable, if ( !processed ) { cmOStringStream msg; - msg << "* Variable \"" << variable.c_str() << "\" was accessed using " - << accessString << " in: " << currentListFile << std::endl; - msg << " The value of the variable: \"" << newValue << "\"" << std::endl; - msg << " The list file stack: " << stack.c_str(); - cmSystemTools::Message(msg.str().c_str()); - std::vector<std::string> vars = makefile->GetDefinitions(); - cmOStringStream msg2; - size_t cc; - for ( cc = 0; cc < vars.size(); cc ++ ) - { - if ( vars[cc] == variable ) - { - continue; - } - msg2 << vars[cc] << " = \"" - << makefile->GetDefinition(vars[cc].c_str()) << "\"" << std::endl; - } - //cmSystemTools::Message(msg2.str().c_str()); + msg << "Variable \"" << variable.c_str() << "\" was accessed using " + << accessString << " with value \"" << newValue << "\"."; + makefile->IssueMessage(cmake::LOG, msg.str()); } this->InCallback = false; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 88c4deb..f8de3a8 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -262,6 +262,15 @@ void cmVisualStudio10TargetGenerator::Generate() "</Keyword>\n"; } + const char* vsGlobalRootNamespace = + this->Target->GetProperty("VS_GLOBAL_ROOTNAMESPACE"); + if(vsGlobalRootNamespace) + { + this->WriteString("<RootNamespace>", 2); + (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalRootNamespace) << + "</RootNamespace>\n"; + } + this->WriteString("<Platform>", 2); (*this->BuildFileStream) << this->Platform << "</Platform>\n"; const char* projLabel = this->Target->GetProperty("PROJECT_LABEL"); @@ -1261,8 +1270,12 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( flags += " /TP "; } } + + std::string targetFlags; + this->LocalGenerator->GetCompileOptions(targetFlags, this->Target, + configName.c_str()); // Add the target-specific flags. - if(const char* targetFlags = this->Target->GetProperty("COMPILE_FLAGS")) + if(!targetFlags.empty()) { flags += " "; flags += targetFlags; diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 124b8ac..6f0281d 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -569,8 +569,17 @@ IF(KWSYS_USE_SystemTools) "Checking whether CXX compiler has unsetenv" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H "Checking whether CXX compiler has environ in stdlib.h" DIRECT) - SET_SOURCE_FILES_PROPERTIES(SystemTools.cxx PROPERTIES - COMPILE_FLAGS "-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}") + KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMES + "Checking whether CXX compiler has utimes" DIRECT) + KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_UTIMENSAT + "Checking whether CXX compiler has utimensat" DIRECT) + SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS + KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} + KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} + KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H} + KWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES} + KWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT} + ) ENDIF() IF(KWSYS_USE_SystemInformation) diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 9e2a93d..9db1dee 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -1471,7 +1471,7 @@ int SystemInformationImplementation::GetFullyQualifiedDomainName( { char host[NI_MAXHOST]={'\0'}; - int addrlen + socklen_t addrlen = (fam==AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6)); ierr=getnameinfo( @@ -3487,7 +3487,7 @@ bool SystemInformationImplementation::QueryLinuxMemory() bool have[6] = { false, false, false, false, false, false }; unsigned long value[6]; int count = 0; - while(fgets(buffer, sizeof(buffer), fd)) + while(fgets(buffer, static_cast<int>(sizeof(buffer)), fd)) { for(int i=0; i < 6; ++i) { diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 394d65e..652649f 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1124,22 +1124,58 @@ bool SystemTools::Touch(const char* filename, bool create) } return false; } -#ifdef _MSC_VER -#define utime _utime -#define utimbuf _utimbuf -#endif - struct stat fromStat; - if(stat(filename, &fromStat) < 0) +#if defined(_WIN32) && !defined(__CYGWIN__) + HANDLE h = CreateFile(filename, FILE_WRITE_ATTRIBUTES, + FILE_SHARE_WRITE, 0, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, 0); + if(!h) + { + return false; + } + FILETIME mtime; + GetSystemTimeAsFileTime(&mtime); + if(!SetFileTime(h, 0, 0, &mtime)) + { + CloseHandle(h); + return false; + } + CloseHandle(h); +#elif KWSYS_CXX_HAS_UTIMENSAT + struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}}; + if(utimensat(AT_FDCWD, filename, times, 0) < 0) + { + return false; + } +#else + struct stat st; + if(stat(filename, &st) < 0) { return false; } - struct utimbuf buf; - buf.actime = fromStat.st_atime; - buf.modtime = static_cast<time_t>(SystemTools::GetTime()); - if(utime(filename, &buf) < 0) + struct timeval mtime; + gettimeofday(&mtime, 0); +# if KWSYS_CXX_HAS_UTIMES + struct timeval times[2] = + { +# if KWSYS_STAT_HAS_ST_MTIM + {st.st_atim.tv_sec, st.st_atim.tv_nsec/1000}, /* tv_sec, tv_usec */ +# else + {st.st_atime, 0}, +# endif + mtime + }; + if(utimes(filename, times) < 0) { return false; } +# else + struct utimbuf times = {st.st_atime, mtime.tv_sec}; + if(utime(filename, ×) < 0) + { + return false; + } +# endif +#endif return true; } @@ -2742,14 +2778,23 @@ bool SystemTools::FileIsDirectory(const char* name) } // Remove any trailing slash from the name except in a root component. - char buffer[KWSYS_SYSTEMTOOLS_MAXPATH]; + char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH]; + std::string string_buffer; size_t last = length-1; if(last > 0 && (name[last] == '/' || name[last] == '\\') && strcmp(name, "/") !=0 && name[last-1] != ':') { - memcpy(buffer, name, last); - buffer[last] = 0; - name = buffer; + if(last < sizeof(local_buffer)) + { + memcpy(local_buffer, name, last); + local_buffer[last] = 0; + name = local_buffer; + } + else + { + string_buffer.append(name, last); + name = string_buffer.c_str(); + } } // Now check the file node type. diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index 48976c4..a7e3b50 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -494,6 +494,25 @@ int main() } #endif +#ifdef TEST_KWSYS_CXX_HAS_UTIMES +#include <sys/time.h> +int main() +{ + struct timeval* current_time = 0; + return utimes("/example", current_time); +} +#endif + +#ifdef TEST_KWSYS_CXX_HAS_UTIMENSAT +#include <fcntl.h> +#include <sys/stat.h> +int main() +{ + struct timespec times[2] = {{0,UTIME_OMIT},{0,UTIME_NOW}}; + return utimensat(AT_FDCWD, "/example", times, AT_SYMLINK_NOFOLLOW); +} +#endif + #ifdef TEST_KWSYS_CXX_TYPE_INFO /* Collect fundamental type information and save it to a CMake script. */ diff --git a/Source/kwsys/testIOS.cxx b/Source/kwsys/testIOS.cxx index 3b971e2..f0c7f1a 100644 --- a/Source/kwsys/testIOS.cxx +++ b/Source/kwsys/testIOS.cxx @@ -48,7 +48,7 @@ int testIOS(int, char*[]) return 1; } static const unsigned char array[] = { 0xff,0x4f,0xff,0x51,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x01,0x01,0xff,0x52,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x05,0x04,0x04,0x00,0x01,0xff,0x5c,0x00,0x13,0x40,0x40,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0x48,0x48,0x50,0xff,0x64,0x00,0x2c,0x00,0x00,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x62,0x79,0x20,0x49,0x54,0x4b,0x2f,0x47,0x44,0x43,0x4d,0x2f,0x4f,0x70,0x65,0x6e,0x4a,0x50,0x45,0x47,0x20,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2e,0x30,0xff,0x90,0x00,0x0a,0x00,0x00,0x00,0x00,0x06,0x2c,0x00,0x01,0xff,0x93,0xcf,0xb0,0x18,0x08,0x7f,0xc6,0x99,0xbf,0xff,0xc0,0xf8,0xc1,0xc1,0xf3,0x05,0x81,0xf2,0x83,0x0a,0xa5,0xff,0x10,0x90,0xbf,0x2f,0xff,0x04,0xa8,0x7f,0xc0,0xf8,0xc4,0xc1,0xf3,0x09,0x81,0xf3,0x0c,0x19,0x34 }; - const unsigned int narray = sizeof(array); // 180 + const size_t narray = sizeof(array); // 180 kwsys_ios::stringstream strstr; strstr.write( (char*)array, narray ); //strstr.seekp( narray / 2 ); // set position of put pointer in mid string diff --git a/Source/kwsys/testSystemInformation.cxx b/Source/kwsys/testSystemInformation.cxx index 49a686c..738043f 100644 --- a/Source/kwsys/testSystemInformation.cxx +++ b/Source/kwsys/testSystemInformation.cxx @@ -88,9 +88,9 @@ int testSystemInformation(int, char*[]) printMethod3(info, GetHostMemoryUsed(), "KiB"); printMethod3(info, GetProcMemoryUsed(), "KiB"); - for (int i = 0; i <= 31; i++) + for (long int i = 0; i <= 31; i++) { - if (info.DoesCPUSupportFeature(1 << i)) + if (info.DoesCPUSupportFeature(static_cast<long int>(1) << i)) { kwsys_ios::cout << "CPU feature " << i << "\n"; } diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt index 8f24afe..5cc7071 100644 --- a/Tests/BundleUtilities/CMakeLists.txt +++ b/Tests/BundleUtilities/CMakeLists.txt @@ -12,8 +12,7 @@ add_library(shared2 SHARED shared2.cpp shared2.h) # a framework library add_library(framework SHARED framework.cpp framework.h) -# TODO: fix problems with local frameworks without rpaths -#set_target_properties(framework PROPERTIES FRAMEWORK 1) +set_target_properties(framework PROPERTIES FRAMEWORK 1) # make sure rpaths are not helping BundleUtilities or the executables set_target_properties(shared shared2 framework PROPERTIES diff --git a/Tests/CFBundleTest/CMakeLists.txt b/Tests/CFBundleTest/CMakeLists.txt index 8fd9efd..bf9771c 100644 --- a/Tests/CFBundleTest/CMakeLists.txt +++ b/Tests/CFBundleTest/CMakeLists.txt @@ -54,3 +54,5 @@ set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/InfoPlist.strings ${CMAKE_CURRENT_BINARY_DIR}/Localized.rsrc PROPERTIES MACOSX_PACKAGE_LOCATION "Resources/English.lproj") + +export(TARGETS CFBundleTest FILE ${CMAKE_CURRENT_BINARY_DIR}/exp.cmake) diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt new file mode 100644 index 0000000..06a48fb --- /dev/null +++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt @@ -0,0 +1,35 @@ + +cmake_minimum_required(VERSION 2.8) + +project(target_compile_options) + +add_executable(target_compile_options + "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" +) +target_compile_options(target_compile_options + PRIVATE $<$<CXX_COMPILER_ID:GNU>:-DMY_PRIVATE_DEFINE> + PUBLIC $<$<CXX_COMPILER_ID:GNU>:-DMY_PUBLIC_DEFINE> + INTERFACE $<$<CXX_COMPILER_ID:GNU>:-DMY_INTERFACE_DEFINE> +) + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(target_compile_options + PRIVATE + "DO_GNU_TESTS" + ) +endif() + +add_executable(consumer + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" +) + +target_compile_options(consumer + PRIVATE $<$<CXX_COMPILER_ID:GNU>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>> +) + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(consumer + PRIVATE + "DO_GNU_TESTS" + ) +endif() diff --git a/Tests/CMakeCommands/target_compile_options/consumer.cpp b/Tests/CMakeCommands/target_compile_options/consumer.cpp new file mode 100644 index 0000000..1299606 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_options/consumer.cpp @@ -0,0 +1,18 @@ + +#ifdef DO_GNU_TESTS + +# ifdef MY_PRIVATE_DEFINE +# error Unexpected MY_PRIVATE_DEFINE +# endif + +# ifndef MY_PUBLIC_DEFINE +# error Expected MY_PUBLIC_DEFINE +# endif + +# ifndef MY_INTERFACE_DEFINE +# error Expected MY_INTERFACE_DEFINE +# endif + +#endif + +int main() { return 0; } diff --git a/Tests/CMakeCommands/target_compile_options/main.cpp b/Tests/CMakeCommands/target_compile_options/main.cpp new file mode 100644 index 0000000..961c06d --- /dev/null +++ b/Tests/CMakeCommands/target_compile_options/main.cpp @@ -0,0 +1,18 @@ + +#ifdef DO_GNU_TESTS + +# ifndef MY_PRIVATE_DEFINE +# error Expected MY_PRIVATE_DEFINE +# endif + +# ifndef MY_PUBLIC_DEFINE +# error Expected MY_PUBLIC_DEFINE +# endif + +# ifdef MY_INTERFACE_DEFINE +# error Unexpected MY_INTERFACE_DEFINE +# endif + +#endif + +int main() { return 0; } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 0b221e8..9d4f3b8 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -15,10 +15,7 @@ macro(ADD_TEST_MACRO NAME COMMAND) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}") endmacro() -macro(REGEX_ESCAPE_STRING _OUT _IN) - # Escape special regex metacharacters with a backslash - string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}") -endmacro() +include(${CMAKE_CURRENT_SOURCE_DIR}/RegexEscapeString.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake) @@ -245,6 +242,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(PolicyScope PolicyScope) ADD_TEST_MACRO(EmptyLibrary EmptyLibrary) ADD_TEST_MACRO(CompileDefinitions CompileDefinitions) + ADD_TEST_MACRO(CompileOptions CompileOptions) ADD_TEST_MACRO(CompatibleInterface CompatibleInterface) set_tests_properties(EmptyLibrary PROPERTIES PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test") @@ -1044,6 +1042,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --test-command ${CMAKE_CTEST_COMMAND} -V ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets") + + if(Qt5Widgets_FOUND AND NOT Qt5Widgets_VERSION VERSION_LESS 5.1.0) + add_test(Qt4And5Automoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Qt4And5Automoc" + "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc" + ${build_generator_args} + --build-project Qt4And5Automoc + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5Automoc") + endif() endif() add_test(ExternalProject ${CMAKE_CTEST_COMMAND} @@ -1233,6 +1245,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ endif() endif() + if(APPLE AND "${DARWIN_MAJOR_VERSION}" GREATER 9) + add_test(MacRuntimePath ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/MacRuntimePath" + "${CMake_BINARY_DIR}/Tests/MacRuntimePath" + ${build_generator_args} + --build-project MacRuntimePath + ) + endif() + add_test(linkorder1 ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/LinkLineOrder" @@ -1966,6 +1988,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions) + ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options) configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in" diff --git a/Tests/CMakeTests/GetPropertyTest.cmake.in b/Tests/CMakeTests/GetPropertyTest.cmake.in index 306ab72..a858418 100644 --- a/Tests/CMakeTests/GetPropertyTest.cmake.in +++ b/Tests/CMakeTests/GetPropertyTest.cmake.in @@ -28,92 +28,95 @@ if(NOT result STREQUAL "alpha") message(SEND_ERROR "bad value of VARIABLE PROPERTY test_var: got '${result}' instead of 'alpha'") endif() +include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake") +REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") + set(Missing-Argument-RESULT 1) -set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*") +set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*") check_cmake_test(GetProperty Missing-Argument ) set(Bad-Scope-RESULT 1) -set(Bad-Scope-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*") +set(Bad-Scope-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*") check_cmake_test(GetProperty Bad-Scope ) set(Bad-Argument-RESULT 1) -set(Bad-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*") +set(Bad-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*") check_cmake_test(GetProperty Bad-Argument ) set(No-Property-RESULT 1) -set(No-Property-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*") +set(No-Property-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*") check_cmake_test(GetProperty No-Property ) set(Global-Name-RESULT 1) -set(Global-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*") +set(Global-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*") check_cmake_test(GetProperty Global-Name ) set(Bad-Directory-RESULT 1) -set(Bad-Directory-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*") +set(Bad-Directory-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*") check_cmake_test(GetProperty Bad-Directory ) set(No-Target-RESULT 1) -set(No-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*") +set(No-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*") check_cmake_test(GetProperty No-Target ) set(Bad-Target-RESULT 1) -set(Bad-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*") +set(Bad-Target-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*") check_cmake_test(GetProperty Bad-Target ) set(No-Source-RESULT 1) -set(No-Source-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*") +set(No-Source-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*") check_cmake_test(GetProperty No-Source ) set(No-Test-RESULT 1) -set(No-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*") +set(No-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*") check_cmake_test(GetProperty No-Test ) set(Bad-Test-RESULT 1) -set(Bad-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*") +set(Bad-Test-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*") check_cmake_test(GetProperty Bad-Test ) set(Variable-Name-RESULT 1) -set(Variable-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*") +set(Variable-Name-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*") check_cmake_test(GetProperty Variable-Name ) set(No-Cache-RESULT 1) -set(No-Cache-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*") +set(No-Cache-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*") check_cmake_test(GetProperty No-Cache diff --git a/Tests/CMakeTests/IfTest.cmake.in b/Tests/CMakeTests/IfTest.cmake.in index 639e226..74b8e32 100644 --- a/Tests/CMakeTests/IfTest.cmake.in +++ b/Tests/CMakeTests/IfTest.cmake.in @@ -7,6 +7,9 @@ foreach(_arg "" 0 1 2 ${TRUE_NAMES} ${FALSE_NAMES}) set(VAR_${_arg} "${_arg}") endforeach() +include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake") +REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") + macro(test_vars _old) # Variables set to false or not set. foreach(_var "" 0 ${FALSE_NAMES} UNDEFINED) @@ -158,7 +161,7 @@ endforeach() test_vars("") set(Invalid-Argument-RESULT 1) -set(Invalid-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*") +set(Invalid-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?If-Invalid-Argument.cmake:1 \\(if\\):.*Unknown arguments specified.*") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(If diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in index f0ed70f..77c34a9 100644 --- a/Tests/CMakeTests/ListTest.cmake.in +++ b/Tests/CMakeTests/ListTest.cmake.in @@ -1,5 +1,8 @@ include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") +include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake") +REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") + macro(TEST command expected) if("x${result}" STREQUAL "x${expected}") #message("TEST \"${command}\" success: \"${result}\" expected: \"${expected}\"") @@ -101,7 +104,7 @@ list(SORT result) TEST("SORT empty result" "") set(No-Arguments-RESULT 1) -set(No-Arguments-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*") +set(No-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-No-Arguments.cmake:1 \\(list\\):.*list must be called with at least two arguments.*") # these trigger top-level condition foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort) @@ -130,33 +133,33 @@ foreach(cmd IN ITEMS Find Get Insert Length Remove_At Remove_Item) endforeach() set(Length-Too-Many-Arguments-RESULT 1) -set(Length-Too-Many-Arguments-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Length-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command LENGTH requires two arguments.*") +set(Length-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Length-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command LENGTH requires two arguments.*") set(Reverse-Too-Many-Arguments-RESULT 1) -set(Reverse-Too-Many-Arguments-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Reverse-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REVERSE only takes one argument.*") +set(Reverse-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Reverse-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REVERSE only takes one argument.*") set(Remove_Duplicates-Too-Many-Arguments-RESULT 1) -set(Remove_Duplicates-Too-Many-Arguments-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Remove_Duplicates-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REMOVE_DUPLICATES only takes one argument.*") +set(Remove_Duplicates-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Remove_Duplicates-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command REMOVE_DUPLICATES only takes one argument.*") set(Sort-Too-Many-Arguments-RESULT 1) -set(Sort-Too-Many-Arguments-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Sort-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command SORT only takes one argument.*") +set(Sort-Too-Many-Arguments-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Sort-Too-Many-Arguments.cmake:1 \\(list\\):.*list sub-command SORT only takes one argument.*") set(Invalid-Subcommand-RESULT 1) -set(Invalid-Subcommand-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Invalid-Subcommand.cmake:1 \\(list\\):.*list does not recognize sub-command NO_SUCH_SUBCOMMAND.*") +set(Invalid-Subcommand-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Invalid-Subcommand.cmake:1 \\(list\\):.*list does not recognize sub-command NO_SUCH_SUBCOMMAND.*") foreach(cmd Get Insert Remove_At) set(${cmd}-Invalid-Index-RESULT 1) - set(${cmd}-Invalid-Index-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-${cmd}-Invalid-Index.cmake:2 \\(list\\):.*list index: 3 out of range \\(-3, 2\\).*") + set(${cmd}-Invalid-Index-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Invalid-Index.cmake:2 \\(list\\):.*list index: 3 out of range \\(-3, 2\\).*") endforeach() foreach(cmd Remove_Item Reverse Remove_Duplicates Sort Remove_At) string(TOUPPER ${cmd} Cmd) set(${cmd}-Nonexistent-List-RESULT 1) - set(${cmd}-Nonexistent-List-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-${cmd}-Nonexistent-List.cmake:2 \\(list\\):.*sub-command ${Cmd} requires list to be present.*") + set(${cmd}-Nonexistent-List-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-${cmd}-Nonexistent-List.cmake:2 \\(list\\):.*sub-command ${Cmd} requires list to be present.*") endforeach() set(Get-CMP0007-Warn-RESULT 0) -set(Get-CMP0007-Warn-STDERR ".*CMake Warning \\(dev\\) at (@CMAKE_CURRENT_SOURCE_DIR@/)?List-Get-CMP0007-Warn.cmake:3 \\(list\\):.*Policy CMP0007 is not set:.*") +set(Get-CMP0007-Warn-STDERR ".*CMake Warning \\(dev\\) at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?List-Get-CMP0007-Warn.cmake:3 \\(list\\):.*Policy CMP0007 is not set:.*") check_cmake_test(List No-Arguments diff --git a/Tests/CMakeTests/WhileTest.cmake.in b/Tests/CMakeTests/WhileTest.cmake.in index 4cec291..d4cf7d7 100644 --- a/Tests/CMakeTests/WhileTest.cmake.in +++ b/Tests/CMakeTests/WhileTest.cmake.in @@ -1,6 +1,9 @@ set(NUMBERS "") set(COUNT 0) +include("@CMAKE_CURRENT_SOURCE_DIR@/../RegexEscapeString.cmake") +REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") + while(COUNT LESS 200) set(NUMBERS "${NUMBERS} ${COUNT}") set(COUNT "2${COUNT}") @@ -16,8 +19,9 @@ if(NOT NUMBERS STREQUAL " 0 3 30 20 3 30") message(SEND_ERROR "while loop nesting error, result: '${NUMBERS}'") endif() + set(Missing-Argument-RESULT 1) -set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*") +set(Missing-Argument-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(While @@ -25,28 +29,28 @@ check_cmake_test(While ) set(Missing-Endwhile-RESULT 1) -set(Missing-Endwhile-STDERR ".*CMake Error in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*") +set(Missing-Endwhile-STDERR ".*CMake Error in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*") check_cmake_test(While Missing-Endwhile ) set(Endwhile-Mismatch-RESULT 0) -set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*") +set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*") check_cmake_test(While Endwhile-Mismatch ) set(Endwhile-Alone-RESULT 1) -set(Endwhile-Alone-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$") +set(Endwhile-Alone-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$") check_cmake_test(While Endwhile-Alone ) set(Endwhile-Alone-Args-RESULT 1) -set(Endwhile-Alone-Args-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\. Or its arguments did not.*$") +set(Endwhile-Alone-Args-STDERR ".*CMake Error at (${CTEST_ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\. Or its arguments did not.*$") check_cmake_test(While Endwhile-Alone-Args diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt b/Tests/CTestTestMemcheck/CMakeLists.txt index 59d6816..ff02883 100644 --- a/Tests/CTestTestMemcheck/CMakeLists.txt +++ b/Tests/CTestTestMemcheck/CMakeLists.txt @@ -1,3 +1,5 @@ +REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + foreach (_retval 0 1) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY) endforeach () @@ -33,7 +35,7 @@ target_link_libraries(memcheck_fail CMakeLib) # same filenames. add_subdirectory(NoLogDummyChecker) -if (XCODE) +if (APPLE) # filter out additional messages by Guard Malloc integrated in Xcode set(GUARD_MALLOC_MSG "(ctest\([0-9]+\) malloc: [^\n]*\n)*") set(NORMAL_CTEST_OUTPUT "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+\\.[0-9]+ sec\n${GUARD_MALLOC_MSG}\n${GUARD_MALLOC_MSG}100% tests passed, 0 tests failed out of 1\n.*\n-- Processing memory checking output: \n${GUARD_MALLOC_MSG}Memory checking results:\n${GUARD_MALLOC_MSG}") @@ -75,7 +77,7 @@ function(gen_mcnl_test NAME CHECKER) ) set_tests_properties(CTestTestMemcheck${NAME} PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n") + PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n") endfunction(gen_mcnl_test) unset(CTEST_EXTRA_CONFIG) @@ -124,7 +126,7 @@ string(REPLACE ")" "\\)" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}") string(REPLACE "+" "\\+" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}") set_tests_properties(CTestTestMemcheckUnknown PROPERTIES - PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/Unknown/test.cmake\n") + PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/Unknown/test.cmake\n") set_tests_properties(CTestTestMemcheckNotExist PROPERTIES PASS_REGULAR_EXPRESSION "Memory checker \\(MemoryCheckCommand\\) not set, or cannot find the specified program.") @@ -141,7 +143,7 @@ foreach (_pp Pre Post) string(TOLOWER ${_pp} _pp_lower) set_tests_properties(CTestTestMemcheckDummyValgrindFail${_pp} PROPERTIES - PASS_REGULAR_EXPRESSION "\nProblem running command: ${CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n") + PASS_REGULAR_EXPRESSION "\nProblem running command: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n") endforeach () set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck @@ -152,7 +154,7 @@ set_tests_properties(CTestTestMemcheckDummyBC PROPERTIES PASS_REGULAR_EXPRESSION "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+.[0-9]+ sec\n\n100% tests passed, 0 tests failed out of 1\n(.*\n)?Error parsing XML in stream at line 1: no element found\n") set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n") + PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n") set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n") + PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n") diff --git a/Tests/CompileDefinitions/CMakeLists.txt b/Tests/CompileDefinitions/CMakeLists.txt index d3e9a3e..930d220 100644 --- a/Tests/CompileDefinitions/CMakeLists.txt +++ b/Tests/CompileDefinitions/CMakeLists.txt @@ -5,6 +5,7 @@ project(CompileDefinitions) if ("${CMAKE_GENERATOR}" STREQUAL "Visual Studio 6") add_definitions(-DNO_SPACES_IN_DEFINE_VALUES) + set(NO_SPACES_IN_DEFINE_VALUES 1) endif() # Use compile flags to tell executables which config is built diff --git a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt index d3886a1..23e0134 100644 --- a/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt +++ b/Tests/CompileDefinitions/add_definitions_command/CMakeLists.txt @@ -1,8 +1,15 @@ project(add_definitions_command) -add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun") -add_definitions(-DCMAKE_IS_="Fun" -DCMAKE_IS_REALLY="Very Fun" -DCMAKE_IS_FUN -DCMAKE_IS=Fun) +add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun -DCMAKE_IS_="Fun") +if (NOT NO_SPACES_IN_DEFINE_VALUES) + add_definitions(-DCMAKE_IS_REALLY="Very Fun") +endif() +add_definitions(-DCMAKE_IS_="Fun") +if (NOT NO_SPACES_IN_DEFINE_VALUES) + add_definitions(-DCMAKE_IS_REALLY="Very Fun") +endif() +add_definitions(-DCMAKE_IS_FUN -DCMAKE_IS=Fun) add_definitions(-DBUILD_IS_DEBUG=$<CONFIG:Debug> -DBUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>>) add_executable(add_definitions_command_executable ../compiletest.cpp) diff --git a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt b/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt index 5587f7f..55108db 100644 --- a/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt +++ b/Tests/CompileDefinitions/add_definitions_command_with_target_prop/CMakeLists.txt @@ -7,7 +7,9 @@ add_executable(add_definitions_command_with_target_prop_executable ../compiletes set_target_properties(add_definitions_command_with_target_prop_executable PROPERTIES COMPILE_DEFINITIONS CMAKE_IS_="Fun") -set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun") +if (NOT NO_SPACES_IN_DEFINE_VALUES) + set_property(TARGET add_definitions_command_with_target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun") +endif() add_definitions(-DCMAKE_IS_FUN) diff --git a/Tests/CompileDefinitions/compiletest.c b/Tests/CompileDefinitions/compiletest.c new file mode 100644 index 0000000..d7883af --- /dev/null +++ b/Tests/CompileDefinitions/compiletest.c @@ -0,0 +1,19 @@ + +#ifndef LINK_C_DEFINE +#error Expected LINK_C_DEFINE +#endif +#ifndef LINK_LANGUAGE_IS_C +#error Expected LINK_LANGUAGE_IS_C +#endif + +#ifdef LINK_CXX_DEFINE +#error Unexpected LINK_CXX_DEFINE +#endif +#ifdef LINK_LANGUAGE_IS_CXX +#error Unexpected LINK_LANGUAGE_IS_CXX +#endif + +int main(void) +{ + return 0; +} diff --git a/Tests/CompileDefinitions/compiletest.cpp b/Tests/CompileDefinitions/compiletest.cpp index 7379380..7df09df 100644 --- a/Tests/CompileDefinitions/compiletest.cpp +++ b/Tests/CompileDefinitions/compiletest.cpp @@ -56,6 +56,21 @@ enum { #error Expect PREFIX_DEF2 #endif +#ifndef LINK_CXX_DEFINE +#error Expected LINK_CXX_DEFINE +#endif +#ifndef LINK_LANGUAGE_IS_CXX +#error Expected LINK_LANGUAGE_IS_CXX +#endif + +#ifdef LINK_C_DEFINE +#error Unexpected LINK_C_DEFINE +#endif +#ifdef LINK_LANGUAGE_IS_C +#error Unexpected LINK_LANGUAGE_IS_C +#endif + + // TEST_GENERATOR_EXPRESSIONS #endif diff --git a/Tests/CompileDefinitions/compiletest_mixed_c.c b/Tests/CompileDefinitions/compiletest_mixed_c.c new file mode 100644 index 0000000..698c989 --- /dev/null +++ b/Tests/CompileDefinitions/compiletest_mixed_c.c @@ -0,0 +1,19 @@ + +#ifndef LINK_CXX_DEFINE +#error Expected LINK_CXX_DEFINE +#endif +#ifndef LINK_LANGUAGE_IS_CXX +#error Expected LINK_LANGUAGE_IS_CXX +#endif + +#ifdef LINK_C_DEFINE +#error Unexpected LINK_C_DEFINE +#endif +#ifdef LINK_LANGUAGE_IS_C +#error Unexpected LINK_LANGUAGE_IS_C +#endif + +void someFunc(void) +{ + +} diff --git a/Tests/CompileDefinitions/compiletest_mixed_cxx.cpp b/Tests/CompileDefinitions/compiletest_mixed_cxx.cpp new file mode 100644 index 0000000..c686854 --- /dev/null +++ b/Tests/CompileDefinitions/compiletest_mixed_cxx.cpp @@ -0,0 +1,19 @@ + +#ifndef LINK_CXX_DEFINE +#error Expected LINK_CXX_DEFINE +#endif +#ifndef LINK_LANGUAGE_IS_CXX +#error Expected LINK_LANGUAGE_IS_CXX +#endif + +#ifdef LINK_C_DEFINE +#error Unexpected LINK_C_DEFINE +#endif +#ifdef LINK_LANGUAGE_IS_C +#error Unexpected LINK_LANGUAGE_IS_C +#endif + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/Tests/CompileDefinitions/target_prop/CMakeLists.txt b/Tests/CompileDefinitions/target_prop/CMakeLists.txt index 34be917..6bf9c5c 100644 --- a/Tests/CompileDefinitions/target_prop/CMakeLists.txt +++ b/Tests/CompileDefinitions/target_prop/CMakeLists.txt @@ -5,7 +5,11 @@ add_executable(target_prop_executable ../compiletest.cpp) set_target_properties(target_prop_executable PROPERTIES COMPILE_DEFINITIONS CMAKE_IS_FUN) -set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun" CMAKE_IS=Fun) +if (NOT NO_SPACES_IN_DEFINE_VALUES) + set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_REALLY="Very Fun" CMAKE_IS=Fun) +else() + set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS=Fun) +endif() set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_IS_FUN CMAKE_IS_="Fun") set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS @@ -19,9 +23,29 @@ set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS LETTER_LIST3=\"$<JOIN:A;B;C;D,,->\" LETTER_LIST4=\"$<JOIN:A;B;C;D,-,->\" LETTER_LIST5=\"$<JOIN:A;B;C;D,-,>\" + "$<$<LINK_LANGUAGE:CXX>:LINK_CXX_DEFINE>" + "$<$<LINK_LANGUAGE:C>:LINK_C_DEFINE>" + "LINK_LANGUAGE_IS_$<LINK_LANGUAGE>" ) set_property(TARGET target_prop_executable APPEND PROPERTY COMPILE_DEFINITIONS BUILD_IS_DEBUG=$<CONFIG:Debug> BUILD_IS_NOT_DEBUG=$<NOT:$<CONFIG:Debug>> ) + +add_executable(target_prop_c_executable ../compiletest.c) + +set_property(TARGET target_prop_c_executable APPEND PROPERTY COMPILE_DEFINITIONS + "$<$<LINK_LANGUAGE:CXX>:LINK_CXX_DEFINE>" + "$<$<LINK_LANGUAGE:C>:LINK_C_DEFINE>" + "LINK_LANGUAGE_IS_$<LINK_LANGUAGE>" + ) + +# Resulting link language will be CXX +add_executable(target_prop_mixed_executable ../compiletest_mixed_c.c ../compiletest_mixed_cxx.cpp) + +set_property(TARGET target_prop_mixed_executable APPEND PROPERTY COMPILE_DEFINITIONS + "$<$<LINK_LANGUAGE:CXX>:LINK_CXX_DEFINE>" + "$<$<LINK_LANGUAGE:C>:LINK_C_DEFINE>" + "LINK_LANGUAGE_IS_$<LINK_LANGUAGE>" + ) diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt new file mode 100644 index 0000000..6d8a96a --- /dev/null +++ b/Tests/CompileOptions/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.8) + +project(CompileOptions) + +add_library(testlib other.cpp) + +add_executable(CompileOptions main.cpp) +set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS "$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE>") +target_link_libraries(CompileOptions testlib) + +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + target_compile_definitions(CompileOptions + PRIVATE + "DO_GNU_TESTS" + ) +endif() diff --git a/Tests/CompileOptions/main.cpp b/Tests/CompileOptions/main.cpp new file mode 100644 index 0000000..0d39050 --- /dev/null +++ b/Tests/CompileOptions/main.cpp @@ -0,0 +1,11 @@ + +#ifdef DO_GNU_TESTS +# ifndef TEST_DEFINE +# error Expected TEST_DEFINE +# endif +#endif + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/Tests/CompileOptions/other.cpp b/Tests/CompileOptions/other.cpp new file mode 100644 index 0000000..0e34375 --- /dev/null +++ b/Tests/CompileOptions/other.cpp @@ -0,0 +1,5 @@ + +void foo(void) +{ + +} diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt index 048f966..50dccbe 100644 --- a/Tests/Complex/CMakeLists.txt +++ b/Tests/Complex/CMakeLists.txt @@ -45,12 +45,12 @@ endmacro() TEST_ARGC(-DCMAKE_ARGV1 -DCMAKE_ARGV2 -DCMAKE_ARGV3 -DCMAKE_ARGV4) macro(TEST_VAR_ARG fa) - if("${ARGV}" MATCHES "^1;2;3$") + if("${ARGV}" STREQUAL "1;2;3") message(STATUS "ARGV works") else() message(FATAL_ERROR "ARGV does not work; got \"${ARGV}\" instead of \"1;2;3\"") endif() - if("${ARGN}" MATCHES "^2;3$") + if("${ARGN}" STREQUAL "2;3") message(STATUS "ARGN works") else() message(FATAL_ERROR "ARGV does not work; got \"${ARGN}\" instead of \"2;3\"") @@ -163,7 +163,7 @@ execute_process( COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG" OUTPUT_VARIABLE TEST_OUT ) -if("${TEST_OUT}" MATCHES "^ABCDEFG\n$") +if("${TEST_OUT}" STREQUAL "ABCDEFG\n") else() message(SEND_ERROR "EXECUTE_PROCESS output test failed: [${TEST_OUT}]") endif() @@ -177,7 +177,7 @@ endif() # ERROR_QUIET # RESULT_VARIABLE RESULT # ) -# if("${RESULT}" MATCHES "^0$") +# if("${RESULT}" STREQUAL "0") # message(SEND_ERROR # "EXECUTE_PROCESS result test failed with RESULT=[${RESULT}]") # else() @@ -387,10 +387,7 @@ if(NOT RESULT) message(SEND_ERROR "string(REGEX MATCHALL ... ) test failed.") endif() string(REGEX REPLACE ".([bd])." "[\\1]" RESULT "a(b)c(d)e") -if("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$") - set(STRING_REGEX_PASSED 1) -endif() -if(NOT STRING_REGEX_PASSED) +if(NOT RESULT STREQUAL "a[b]c[d]e") message(SEND_ERROR "string(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")") endif() diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt index b0748fe..cbb4286 100644 --- a/Tests/ComplexOneConfig/CMakeLists.txt +++ b/Tests/ComplexOneConfig/CMakeLists.txt @@ -45,12 +45,12 @@ endmacro() TEST_ARGC(-DCMAKE_ARGV1 -DCMAKE_ARGV2 -DCMAKE_ARGV3 -DCMAKE_ARGV4) macro(TEST_VAR_ARG fa) - if("${ARGV}" MATCHES "^1;2;3$") + if("${ARGV}" STREQUAL "1;2;3") message(STATUS "ARGV works") else() message(FATAL_ERROR "ARGV does not work; got \"${ARGV}\" instead of \"1;2;3\"") endif() - if("${ARGN}" MATCHES "^2;3$") + if("${ARGN}" STREQUAL "2;3") message(STATUS "ARGN works") else() message(FATAL_ERROR "ARGV does not work; got \"${ARGN}\" instead of \"2;3\"") @@ -163,7 +163,7 @@ execute_process( COMMAND ${CMAKE_COMMAND} -E echo "ABCDEFG" OUTPUT_VARIABLE TEST_OUT ) -if("${TEST_OUT}" MATCHES "^ABCDEFG\n$") +if("${TEST_OUT}" STREQUAL "ABCDEFG\n") else() message(SEND_ERROR "EXECUTE_PROCESS output test failed: [${TEST_OUT}]") endif() @@ -177,7 +177,7 @@ endif() # ERROR_QUIET # RESULT_VARIABLE RESULT # ) -# if("${RESULT}" MATCHES "^0$") +# if("${RESULT}" STREQUAL "0") # message(SEND_ERROR # "EXECUTE_PROCESS result test failed with RESULT=[${RESULT}]") # else() @@ -357,10 +357,7 @@ if(NOT RESULT) message(SEND_ERROR "string(REGEX MATCHALL ... ) test failed.") endif() string(REGEX REPLACE ".([bd])." "[\\1]" RESULT "a(b)c(d)e") -if("x${RESULT}" MATCHES "^xa\\[b\\]c\\[d\\]e$") - set(STRING_REGEX_PASSED 1) -endif() -if(NOT STRING_REGEX_PASSED) +if(NOT RESULT STREQUAL "a[b]c[d]e") message(SEND_ERROR "string(REGEX REPLACE ... ) test failed (\"${RESULT}\" v. \"a[b]c[d]e\")") endif() diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index 60d4c6a..088725b 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -110,6 +110,25 @@ set_property(TARGET libbad APPEND PROPERTY ) +add_library(includes_source_good empty.cpp) +target_include_directories(includes_source_good + INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}/good" + "${CMAKE_CURRENT_BINARY_DIR}/othergood/" +) +add_library(includes_source_bad empty.cpp) +target_include_directories(includes_source_bad + INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}/bad" +) + +add_library(includes_proxy SHARED empty.cpp) +target_link_libraries(includes_proxy includes_source_good) +target_link_libraries(includes_proxy LINK_INTERFACE_LIBRARIES includes_source_bad) +add_executable(copy_includes copy_includes.cpp) +target_include_directories(copy_includes PRIVATE $<TARGET_PROPERTY:includes_proxy,INCLUDE_DIRECTORIES>) + + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n") add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp") @@ -128,3 +147,19 @@ file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_ba file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/prefix_foo/prefix_bar/prefix_bat/prefix_foo_bar_bat.h" "// prefix_foo_bar_bat.h\n") target_include_directories(TargetIncludeDirectories PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/prefix_$<JOIN:foo;bar;bat,/prefix_>") + +# Test that the language generator expressions work +set_property(TARGET TargetIncludeDirectories + APPEND PROPERTY INCLUDE_DIRECTORIES + "$<$<LINK_LANGUAGE:C>:${CMAKE_CURRENT_BINARY_DIR}/bad>" + "$<$<LINK_LANGUAGE:CXX>:${CMAKE_CURRENT_BINARY_DIR}/good>" + "$<$<STREQUAL:$<LINK_LANGUAGE>,CXX>:${CMAKE_CURRENT_BINARY_DIR}/othergood/>" +) + +add_executable(TargetIncludeDirectories_C main.c) +set_property(TARGET TargetIncludeDirectories_C + APPEND PROPERTY INCLUDE_DIRECTORIES + "$<$<LINK_LANGUAGE:CXX>:${CMAKE_CURRENT_BINARY_DIR}/bad>" + "$<$<LINK_LANGUAGE:C>:${CMAKE_CURRENT_BINARY_DIR}/good>" + "$<$<STREQUAL:$<LINK_LANGUAGE>,C>:${CMAKE_CURRENT_BINARY_DIR}/othergood/>" +) diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp new file mode 100644 index 0000000..fed4c03 --- /dev/null +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/copy_includes.cpp @@ -0,0 +1,7 @@ + +#include "common.h" + +int main() +{ + return 0; +} diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp new file mode 100644 index 0000000..7279c5e --- /dev/null +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty(void) +{ + return 0; +} diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/main.c b/Tests/IncludeDirectories/TargetIncludeDirectories/main.c new file mode 100644 index 0000000..a597daa --- /dev/null +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/main.c @@ -0,0 +1,7 @@ + +#include "common.h" + +int main(void) +{ + return 0; +} diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp index 5bb34aa..aed0bde 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp @@ -11,6 +11,7 @@ #include "list.h" #include "target.h" #include "prefix_foo_bar_bat.h" +#include "common.h" int main(int, char**) { diff --git a/Tests/IncludeDirectories/empty.cpp b/Tests/IncludeDirectories/empty.cpp index ab32cf6..1787013 100644 --- a/Tests/IncludeDirectories/empty.cpp +++ b/Tests/IncludeDirectories/empty.cpp @@ -1 +1,4 @@ -// No content +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() { return 0; } diff --git a/Tests/MacRuntimePath/A/CMakeLists.txt b/Tests/MacRuntimePath/A/CMakeLists.txt new file mode 100644 index 0000000..6e6de42 --- /dev/null +++ b/Tests/MacRuntimePath/A/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 2.8) +project(MacRuntimePath_A) + +# a shared library +add_library(shared SHARED shared.cpp shared.h) +set_target_properties(shared PROPERTIES MACOSX_RPATH 1) + +# a shared library with custom set @rpath +add_library(shared2 SHARED shared.cpp shared.h) +set_target_properties(shared2 PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "@rpath") + +# a framework library +add_library(framework SHARED framework.cpp framework.h) +set_target_properties(framework PROPERTIES MACOSX_RPATH 1 FRAMEWORK 1) + +# executable to test a shared library dependency with install rpaths +add_executable(test1 test1.cpp) +target_link_libraries(test1 shared) +set_target_properties(test1 PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 INSTALL_RPATH "@loader_path/../lib") + +# executable to test a framework library dependency with install rpaths +add_executable(test2 test2.cpp) +target_link_libraries(test2 framework) +set_target_properties(test2 PROPERTIES + BUILD_WITH_INSTALL_RPATH 1 INSTALL_RPATH "@loader_path/../lib") + +# executable to test a framework library dependency with build tree rpaths +add_executable(test3 test3.cpp) +target_link_libraries(test3 framework) + +# executable to test a framework library dependency with build tree rpaths +add_executable(test4 test1.cpp) +target_link_libraries(test4 shared2) + +set_target_properties(shared shared2 framework PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib") +set_target_properties(test1 test2 test3 test4 PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") +foreach(config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${config} CONFIG) + set_target_properties(shared shared2 framework PROPERTIES + LIBRARY_OUTPUT_DIRECTORY_${CONFIG} + "${CMAKE_CURRENT_BINARY_DIR}/${config}/lib") + set_target_properties(test1 test2 test3 test4 PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_${CONFIG} + "${CMAKE_CURRENT_BINARY_DIR}/${config}/bin") +endforeach() + +foreach(test test1 test2 test3 test4) + add_custom_target(${test}_run ALL + COMMAND ${test} + DEPENDS ${test} + ) +endforeach() + +export(TARGETS shared shared2 framework FILE "${CMAKE_CURRENT_BINARY_DIR}/exp.cmake") + +install(TARGETS shared EXPORT MyExport DESTINATION lib) +install(TARGETS shared2 EXPORT MyExport DESTINATION lib2) +install(TARGETS framework EXPORT MyExport DESTINATION lib-fw) +install(EXPORT MyExport DESTINATION lib FILE exp.cmake) diff --git a/Tests/MacRuntimePath/A/framework.cpp b/Tests/MacRuntimePath/A/framework.cpp new file mode 100644 index 0000000..abda195 --- /dev/null +++ b/Tests/MacRuntimePath/A/framework.cpp @@ -0,0 +1,8 @@ + +#include "framework.h" +#include "stdio.h" + +void framework() +{ + printf("framework\n"); +} diff --git a/Tests/MacRuntimePath/A/framework.h b/Tests/MacRuntimePath/A/framework.h new file mode 100644 index 0000000..bdd10f0 --- /dev/null +++ b/Tests/MacRuntimePath/A/framework.h @@ -0,0 +1,17 @@ + +#ifndef framework_h +#define framework_h + +#ifdef WIN32 +# ifdef framework_EXPORTS +# define FRAMEWORK_EXPORT __declspec(dllexport) +# else +# define FRAMEWORK_EXPORT __declspec(dllimport) +# endif +#else +# define FRAMEWORK_EXPORT +#endif + +void FRAMEWORK_EXPORT framework(); + +#endif diff --git a/Tests/MacRuntimePath/A/shared.cpp b/Tests/MacRuntimePath/A/shared.cpp new file mode 100644 index 0000000..e5e7dc5 --- /dev/null +++ b/Tests/MacRuntimePath/A/shared.cpp @@ -0,0 +1,8 @@ + +#include "shared.h" +#include "stdio.h" + +void shared() +{ + printf("shared\n"); +} diff --git a/Tests/MacRuntimePath/A/shared.h b/Tests/MacRuntimePath/A/shared.h new file mode 100644 index 0000000..3588fb8 --- /dev/null +++ b/Tests/MacRuntimePath/A/shared.h @@ -0,0 +1,17 @@ + +#ifndef shared_h +#define shared_h + +#ifdef WIN32 +# ifdef shared_EXPORTS +# define SHARED_EXPORT __declspec(dllexport) +# else +# define SHARED_EXPORT __declspec(dllimport) +# endif +#else +# define SHARED_EXPORT +#endif + +void SHARED_EXPORT shared(); + +#endif diff --git a/Tests/MacRuntimePath/A/test1.cpp b/Tests/MacRuntimePath/A/test1.cpp new file mode 100644 index 0000000..cb93448 --- /dev/null +++ b/Tests/MacRuntimePath/A/test1.cpp @@ -0,0 +1,8 @@ + +#include "shared.h" + +int main(int, char**) +{ + shared(); + return 0; +} diff --git a/Tests/MacRuntimePath/A/test2.cpp b/Tests/MacRuntimePath/A/test2.cpp new file mode 100644 index 0000000..26bc9dd --- /dev/null +++ b/Tests/MacRuntimePath/A/test2.cpp @@ -0,0 +1,8 @@ + +#include "framework.h" + +int main(int, char**) +{ + framework(); + return 0; +} diff --git a/Tests/MacRuntimePath/A/test3.cpp b/Tests/MacRuntimePath/A/test3.cpp new file mode 100644 index 0000000..26bc9dd --- /dev/null +++ b/Tests/MacRuntimePath/A/test3.cpp @@ -0,0 +1,8 @@ + +#include "framework.h" + +int main(int, char**) +{ + framework(); + return 0; +} diff --git a/Tests/MacRuntimePath/B/CMakeLists.txt b/Tests/MacRuntimePath/B/CMakeLists.txt new file mode 100644 index 0000000..c361620 --- /dev/null +++ b/Tests/MacRuntimePath/B/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.8) +project(MacRuntimePath_B) + +include(${MacRuntimePath_B_BINARY_DIR}/../Root/lib/exp.cmake) + +add_executable(testb ${MacRuntimePath_B_SOURCE_DIR}/../A/test3.cpp) + +# test link with rpath enabled targets +target_link_libraries(testb shared framework) + +# test link with rpath enabled library by filename +target_link_libraries(testb $<TARGET_LINKER_FILE:shared2> framework) + +add_custom_target(testb_run ALL + COMMAND testb + DEPENDS testb + ) diff --git a/Tests/MacRuntimePath/CMakeLists.txt b/Tests/MacRuntimePath/CMakeLists.txt new file mode 100644 index 0000000..5e5b6c4 --- /dev/null +++ b/Tests/MacRuntimePath/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required (VERSION 2.8) +project(MacRuntimePath) + + +# Wipe out the install tree to make sure the exporter works. +add_custom_command( + OUTPUT ${MacRuntimePath_BINARY_DIR}/CleanupProject + COMMAND ${CMAKE_COMMAND} -E remove_directory ${MacRuntimePath_BINARY_DIR}/Root + ) +add_custom_target(CleanupTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/CleanupProject) +set_property( + SOURCE ${MacRuntimePath_BINARY_DIR}/CleanupProject + PROPERTY SYMBOLIC 1 + ) + +configure_file(${MacRuntimePath_SOURCE_DIR}/InitialCache.cmake.in + ${MacRuntimePath_BINARY_DIR}/InitialCache.cmake @ONLY) + +if(CMAKE_CONFIGURATION_TYPES) + set(NESTED_CONFIG_TYPE -C "${CMAKE_CFG_INTDIR}") +else() + if(CMAKE_BUILD_TYPE) + set(NESTED_CONFIG_TYPE -C "${CMAKE_BUILD_TYPE}") + else() + set(NESTED_CONFIG_TYPE) + endif() +endif() + +# Build and install the exporter. +add_custom_command( + OUTPUT ${MacRuntimePath_BINARY_DIR}/ExportProject + COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE} + --build-and-test + ${MacRuntimePath_SOURCE_DIR}/A + ${MacRuntimePath_BINARY_DIR}/A + --build-noclean + --build-project MacRuntimePath_A + --build-target install + --build-generator ${CMAKE_GENERATOR} + --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}" + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake + VERBATIM + ) +add_custom_target(ExportTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/ExportProject) +add_dependencies(ExportTarget CleanupTarget) +set_property( + SOURCE ${MacRuntimePath_BINARY_DIR}/ExportProject + PROPERTY SYMBOLIC 1 + ) + +# Build the importer. +add_custom_command( + OUTPUT ${MacRuntimePath_BINARY_DIR}/ImportProject + COMMAND ${CMAKE_CTEST_COMMAND} ${NESTED_CONFIG_TYPE} + --build-and-test + ${MacRuntimePath_SOURCE_DIR}/B + ${MacRuntimePath_BINARY_DIR}/B + --build-noclean + --build-project MacRuntimePath_B + --build-generator ${CMAKE_GENERATOR} + --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}" + --build-makeprogram ${CMAKE_MAKE_PROGRAM} + --build-options -C${MacRuntimePath_BINARY_DIR}/InitialCache.cmake + VERBATIM + ) +add_custom_target(ImportTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/ImportProject) +add_dependencies(ImportTarget ExportTarget) +set_property( + SOURCE ${MacRuntimePath_BINARY_DIR}/ImportProject + PROPERTY SYMBOLIC 1 + ) diff --git a/Tests/MacRuntimePath/InitialCache.cmake.in b/Tests/MacRuntimePath/InitialCache.cmake.in new file mode 100644 index 0000000..be15eb3 --- /dev/null +++ b/Tests/MacRuntimePath/InitialCache.cmake.in @@ -0,0 +1,13 @@ +set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@" CACHE STRING "C Compiler") +set(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@" CACHE STRING "C Flags") +set(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@" CACHE STRING "C Flags") +set(CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@" CACHE STRING "C Flags") +set(CMAKE_C_FLAGS_MINSIZEREL "@CMAKE_C_FLAGS_MINSIZEREL@" CACHE STRING "C Flags") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "@CMAKE_C_FLAGS_RELWITHDEBINFO@" CACHE STRING "C Flags") +set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@" CACHE STRING "C++ Compiler") +set(CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@" CACHE STRING "C++ Flags") +set(CMAKE_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@" CACHE STRING "C++ Flags") +set(CMAKE_CXX_FLAGS_RELEASE "@CMAKE_CXX_FLAGS_RELEASE@" CACHE STRING "C++ Flags") +set(CMAKE_CXX_FLAGS_MINSIZEREL "@CMAKE_CXX_FLAGS_MINSIZEREL@" CACHE STRING "C++ Flags") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRING "C++ Flags") +set(CMAKE_INSTALL_PREFIX "@MacRuntimePath_BINARY_DIR@/Root" CACHE STRING "Installation Prefix") diff --git a/Tests/Module/GenerateExportHeader/CMakeLists.txt b/Tests/Module/GenerateExportHeader/CMakeLists.txt index 359a1e3..09f1881 100644 --- a/Tests/Module/GenerateExportHeader/CMakeLists.txt +++ b/Tests/Module/GenerateExportHeader/CMakeLists.txt @@ -23,13 +23,13 @@ set( CMAKE_INCLUDE_CURRENT_DIR ON ) macro(TEST_FAIL value msg) if (${value}) - message (SEND_ERROR "Test fail:" ${msg} ${Out} ) + message (SEND_ERROR "Test fail:" "${msg}\n" ${Out} ) endif () endmacro() macro(TEST_PASS value msg) if (NOT ${value}) - message (SEND_ERROR "Test fail:" ${msg} ${Out} ) + message (SEND_ERROR "Test fail:" "${msg}\n" ${Out} ) endif () endmacro() @@ -170,6 +170,9 @@ add_subdirectory(lib_shared_and_statictest) add_subdirectory(override_symbol) add_subdirectory(nodeprecated) add_subdirectory(prefix) +if(NOT BORLAND) + add_subdirectory(c_identifier) +endif() if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES Clang)) # We deliberately call deprecated methods, and test for that elsewhere. diff --git a/Tests/Module/GenerateExportHeader/c_identifier/CMakeLists.txt b/Tests/Module/GenerateExportHeader/c_identifier/CMakeLists.txt new file mode 100644 index 0000000..9f8c8ef --- /dev/null +++ b/Tests/Module/GenerateExportHeader/c_identifier/CMakeLists.txt @@ -0,0 +1,13 @@ +project(c_identifier) + +set(c_identifier_lib_SRCS + c_identifier_class.cpp +) + +add_library(7c-identifier-lib++ SHARED c_identifier_class.cpp) + +generate_export_header(7c-identifier-lib++) + +add_executable(c_identifier_exe main.cpp) + +target_link_libraries(c_identifier_exe 7c-identifier-lib++) diff --git a/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.cpp b/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.cpp new file mode 100644 index 0000000..d252c8e --- /dev/null +++ b/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.cpp @@ -0,0 +1,7 @@ + +#include "c_identifier_class.h" + +int CIdentifierClass::someMethod() const +{ + return 0; +} diff --git a/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.h b/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.h new file mode 100644 index 0000000..741efdc --- /dev/null +++ b/Tests/Module/GenerateExportHeader/c_identifier/c_identifier_class.h @@ -0,0 +1,13 @@ + +#ifndef C_IDENTIFIER_CLASS_H +#define C_IDENTIFIER_CLASS_H + +#include "7c-identifier-lib++_export.h" + +class _7C_IDENTIFIER_LIB___EXPORT CIdentifierClass +{ +public: + int someMethod() const; +}; + +#endif diff --git a/Tests/Module/GenerateExportHeader/c_identifier/main.cpp b/Tests/Module/GenerateExportHeader/c_identifier/main.cpp new file mode 100644 index 0000000..68beebb --- /dev/null +++ b/Tests/Module/GenerateExportHeader/c_identifier/main.cpp @@ -0,0 +1,8 @@ + +#include "c_identifier_class.h" + +int main(int argc, char **argv) +{ + CIdentifierClass cic; + return cic.someMethod(); +} diff --git a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt index a5804fc..2a97d8f 100644 --- a/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt +++ b/Tests/Module/GenerateExportHeader/libsharedtest/CMakeLists.txt @@ -8,6 +8,7 @@ macro(shared_build_fail Source Message) endmacro() shared_build_pass("Libshared l; return l.libshared_exported();" "Failed to build exported") +shared_build_pass("return libshared_exported();" "Failed to build exported function.") # if (COMPILER_HAS_DEPRECATED) # shared_build_fail("Libshared l; return l.libshared_deprecated();" "Built use of deprecated class method. This should not be possible.") diff --git a/Tests/Qt4And5Automoc/CMakeLists.txt b/Tests/Qt4And5Automoc/CMakeLists.txt new file mode 100644 index 0000000..0cc80fe --- /dev/null +++ b/Tests/Qt4And5Automoc/CMakeLists.txt @@ -0,0 +1,13 @@ + +project(Qt4And5Automoc) + +find_package(Qt4 REQUIRED) +find_package(Qt5Core REQUIRED) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_executable(qt4_exe main_qt4.cpp) +target_link_libraries(qt4_exe Qt4::QtCore) +add_executable(qt5_exe main_qt5.cpp) +target_link_libraries(qt5_exe Qt5::Core) diff --git a/Tests/Qt4And5Automoc/main.cpp b/Tests/Qt4And5Automoc/main.cpp new file mode 100644 index 0000000..00fd641 --- /dev/null +++ b/Tests/Qt4And5Automoc/main.cpp @@ -0,0 +1,18 @@ + +#include <QObject> + +class SomeObject : public QObject +{ + Q_OBJECT +public: + explicit SomeObject(QObject *parent = 0) + : QObject(parent) + { + + } +}; + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/Tests/Qt4And5Automoc/main_qt4.cpp b/Tests/Qt4And5Automoc/main_qt4.cpp new file mode 100644 index 0000000..a84ce89 --- /dev/null +++ b/Tests/Qt4And5Automoc/main_qt4.cpp @@ -0,0 +1,4 @@ + +#include "main.cpp" + +#include "main_qt4.moc" diff --git a/Tests/Qt4And5Automoc/main_qt5.cpp b/Tests/Qt4And5Automoc/main_qt5.cpp new file mode 100644 index 0000000..287b261 --- /dev/null +++ b/Tests/Qt4And5Automoc/main_qt5.cpp @@ -0,0 +1,4 @@ + +#include "main.cpp" + +#include "main_qt5.moc" diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt index d0c9c66..af9fc3f 100644 --- a/Tests/Qt4Targets/CMakeLists.txt +++ b/Tests/Qt4Targets/CMakeLists.txt @@ -19,3 +19,20 @@ if (WIN32) target_link_libraries(activeqtexe Qt4::QAxServer Qt4::QtGui) endif() endif() + +qt4_generate_moc(main_gen_test.cpp + "${CMAKE_CURRENT_BINARY_DIR}/main_gen_test.moc" + TARGET Qt4GenerateMacroTest +) +add_executable(Qt4GenerateMacroTest WIN32 main_gen_test.cpp "${CMAKE_CURRENT_BINARY_DIR}/main_gen_test.moc") +set_property(TARGET Qt4GenerateMacroTest PROPERTY AUTOMOC OFF) +target_include_directories(Qt4GenerateMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface") +target_link_libraries(Qt4GenerateMacroTest Qt4::QtGui) + +qt4_wrap_cpp(moc_file mywrapobject.h + TARGET Qt4WrapMacroTest +) +add_executable(Qt4WrapMacroTest WIN32 main_wrap_test.cpp ${moc_file}) +set_property(TARGET Qt4WrapMacroTest PROPERTY AUTOMOC OFF) +target_include_directories(Qt4WrapMacroTest PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/interface") +target_link_libraries(Qt4WrapMacroTest Qt4::QtGui) diff --git a/Tests/Qt4Targets/interface/myinterface.h b/Tests/Qt4Targets/interface/myinterface.h new file mode 100644 index 0000000..59b43ad --- /dev/null +++ b/Tests/Qt4Targets/interface/myinterface.h @@ -0,0 +1,12 @@ + +#ifndef MYINTERFACE_H +#define MYINTERFACE_H + +class MyInterface +{ + +}; + +Q_DECLARE_INTERFACE(MyInterface, "org.cmake.example.MyInterface") + +#endif diff --git a/Tests/Qt4Targets/main_gen_test.cpp b/Tests/Qt4Targets/main_gen_test.cpp new file mode 100644 index 0000000..984424b --- /dev/null +++ b/Tests/Qt4Targets/main_gen_test.cpp @@ -0,0 +1,21 @@ + +#include <QObject> + +#include "myinterface.h" + +class MyObject : public QObject, MyInterface +{ + Q_OBJECT + Q_INTERFACES(MyInterface) +public: + explicit MyObject(QObject *parent = 0) : QObject(parent) { } +}; + +int main(int argc, char **argv) +{ + MyObject mo; + mo.objectName(); + return 0; +} + +#include "main_gen_test.moc" diff --git a/Tests/Qt4Targets/main_wrap_test.cpp b/Tests/Qt4Targets/main_wrap_test.cpp new file mode 100644 index 0000000..21edc7b --- /dev/null +++ b/Tests/Qt4Targets/main_wrap_test.cpp @@ -0,0 +1,11 @@ + +#include <QObject> + +#include "mywrapobject.h" + +int main(int argc, char **argv) +{ + MyWrapObject mwo; + mwo.objectName(); + return 0; +} diff --git a/Tests/Qt4Targets/mywrapobject.h b/Tests/Qt4Targets/mywrapobject.h new file mode 100644 index 0000000..de23540 --- /dev/null +++ b/Tests/Qt4Targets/mywrapobject.h @@ -0,0 +1,17 @@ + +#ifndef MYWRAPOBJECT_H +#define MYWRAPOBJECT_H + +#include <QObject> + +#include "myinterface.h" + +class MyWrapObject : public QObject, MyInterface +{ + Q_OBJECT + Q_INTERFACES(MyInterface) +public: + explicit MyWrapObject(QObject *parent = 0) : QObject(parent) { } +}; + +#endif diff --git a/Tests/RegexEscapeString.cmake b/Tests/RegexEscapeString.cmake new file mode 100644 index 0000000..92aed17 --- /dev/null +++ b/Tests/RegexEscapeString.cmake @@ -0,0 +1,4 @@ +macro(REGEX_ESCAPE_STRING _OUT _IN) + # Escape special regex metacharacters with a backslash + string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}") +endmacro() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 30be228..c1a08d2 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -88,9 +88,12 @@ add_RunCMake_test(add_dependencies) add_RunCMake_test(build_command) add_RunCMake_test(find_package) add_RunCMake_test(get_filename_component) +add_RunCMake_test(if) add_RunCMake_test(include) add_RunCMake_test(include_directories) add_RunCMake_test(list) +add_RunCMake_test(try_compile) +add_RunCMake_test(variable_watch) add_RunCMake_test(CMP0004) find_package(Qt4 QUIET) @@ -103,3 +106,5 @@ if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]") add_RunCMake_test(include_external_msproject) add_RunCMake_test(SolutionGlobalSections) endif() + +add_RunCMake_test(File_Generate) diff --git a/Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt b/Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt new file mode 100644 index 0000000..953ea68 --- /dev/null +++ b/Tests/RunCMake/ExternalData/LinkDirectory1-stdout.txt @@ -0,0 +1,5 @@ +-- Linked Dir/ToLink.txt.md5 to ExternalData MD5/c18ff9804c8deec9eaeb17063cda8b7b +-- Raw data correctly transformed to content link! +-- Staged content exists! +-- Staged content is correct! +-- Staged content was correctly not re-staged! diff --git a/Tests/RunCMake/ExternalData/LinkDirectory1.cmake b/Tests/RunCMake/ExternalData/LinkDirectory1.cmake new file mode 100644 index 0000000..541fc79 --- /dev/null +++ b/Tests/RunCMake/ExternalData/LinkDirectory1.cmake @@ -0,0 +1,37 @@ +include(ExternalData) +set(ExternalData_LINK_CONTENT MD5) +set(ExternalData_SOURCE_ROOT ${CMAKE_CURRENT_BINARY_DIR}) +set(ExternalData_BINARY_ROOT ${CMAKE_CURRENT_BINARY_DIR}/ExternalData) +set(input ${CMAKE_CURRENT_BINARY_DIR}/Dir) +set(output ${CMAKE_CURRENT_BINARY_DIR}/ExternalData/Dir) +set(staged "${input}/.ExternalData_MD5_c18ff9804c8deec9eaeb17063cda8b7b") +set(content "To be transformed into a content link.") +file(REMOVE ${staged}) +file(REMOVE_RECURSE ${input}) +file(WRITE ${input}/ToLink.txt "${content}") +ExternalData_Expand_Arguments(Data args "DATA{${input}/,REGEX:.*}") +if("x${args}" STREQUAL "x${output}") + message(STATUS "Raw data correctly transformed to content link!") +else() + message(FATAL_ERROR "Data reference transformed to:\n ${args}\n" + "but we expected:\n ${output}") +endif() +if(EXISTS "${staged}") + message(STATUS "Staged content exists!") +else() + message(FATAL_ERROR "Staged content missing!") +endif() + +# Expand again to check whether staged content is ignored. +ExternalData_Expand_Arguments(Data args "DATA{${input}/,REGEX:.*}") +file(STRINGS "${staged}" staged_content LIMIT_INPUT 1024) +if("${content}" STREQUAL "${staged_content}") + message(STATUS "Staged content is correct!") +else() + message(STATUS "Staged content is incorrect!") +endif() +if(EXISTS "${staged}.md5") + message(FATAL_ERROR "Staged content was incorrectly re-staged!") +else() + message(STATUS "Staged content was correctly not re-staged!") +endif() diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake index ceb2ecf..8fba82c 100644 --- a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake @@ -13,6 +13,7 @@ run_cmake(Directory4) run_cmake(Directory5) run_cmake(LinkContentMD5) run_cmake(LinkContentSHA1) +run_cmake(LinkDirectory1) run_cmake(MissingData) run_cmake(NoLinkInSource) run_cmake(NoURLTemplates) diff --git a/Tests/RunCMake/File_Generate/BadCondition-result.txt b/Tests/RunCMake/File_Generate/BadCondition-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/BadCondition-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/BadCondition-stderr.txt b/Tests/RunCMake/File_Generate/BadCondition-stderr.txt new file mode 100644 index 0000000..bab8368 --- /dev/null +++ b/Tests/RunCMake/File_Generate/BadCondition-stderr.txt @@ -0,0 +1,3 @@ +CMake Error in CMakeLists.txt: + Evaluation file condition \"\$<1:Bad>\" did not evaluate to valid content. + Got \"Bad\". diff --git a/Tests/RunCMake/File_Generate/BadCondition.cmake b/Tests/RunCMake/File_Generate/BadCondition.cmake new file mode 100644 index 0000000..82ad672 --- /dev/null +++ b/Tests/RunCMake/File_Generate/BadCondition.cmake @@ -0,0 +1,5 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION $<1:Bad> +) diff --git a/Tests/RunCMake/File_Generate/CMakeLists.txt b/Tests/RunCMake/File_Generate/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/File_Generate/CommandConflict-result.txt b/Tests/RunCMake/File_Generate/CommandConflict-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/CommandConflict-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt new file mode 100644 index 0000000..da97ba4 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt @@ -0,0 +1 @@ +CMake Error: File to be generated by multiple different commands: .*CommandConflict-build/output_.*.txt diff --git a/Tests/RunCMake/File_Generate/CommandConflict.cmake b/Tests/RunCMake/File_Generate/CommandConflict.cmake new file mode 100644 index 0000000..d57bc12 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CommandConflict.cmake @@ -0,0 +1,9 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_$<CONFIGURATION>.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION $<CONFIG:$<CONFIGURATION>> +) +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_$<CONFIGURATION>.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION $<CONFIG:$<CONFIGURATION>> +) diff --git a/Tests/RunCMake/File_Generate/DebugEvaluate.cmake b/Tests/RunCMake/File_Generate/DebugEvaluate.cmake new file mode 100644 index 0000000..1fa9b62 --- /dev/null +++ b/Tests/RunCMake/File_Generate/DebugEvaluate.cmake @@ -0,0 +1,5 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION $<CONFIG:Debug> +) diff --git a/Tests/RunCMake/File_Generate/EmptyCondition1-result.txt b/Tests/RunCMake/File_Generate/EmptyCondition1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt new file mode 100644 index 0000000..9fe39cc --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at EmptyCondition1.cmake:2 \(file\): + file Incorrect arguments to GENERATE subcommand. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/File_Generate/EmptyCondition1.cmake b/Tests/RunCMake/File_Generate/EmptyCondition1.cmake new file mode 100644 index 0000000..8574a5f --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition1.cmake @@ -0,0 +1,5 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION +) diff --git a/Tests/RunCMake/File_Generate/EmptyCondition2-result.txt b/Tests/RunCMake/File_Generate/EmptyCondition2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt b/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt new file mode 100644 index 0000000..73d5f25 --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition2-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at EmptyCondition2.cmake:2 \(file\): + file CONDITION of sub-command GENERATE must not be empty if specified. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/File_Generate/EmptyCondition2.cmake b/Tests/RunCMake/File_Generate/EmptyCondition2.cmake new file mode 100644 index 0000000..626bfb4 --- /dev/null +++ b/Tests/RunCMake/File_Generate/EmptyCondition2.cmake @@ -0,0 +1,5 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" + CONDITION "" +) diff --git a/Tests/RunCMake/File_Generate/OutputConflict-result.txt b/Tests/RunCMake/File_Generate/OutputConflict-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputConflict-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt new file mode 100644 index 0000000..dbd39de --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt @@ -0,0 +1,5 @@ +CMake Error in CMakeLists.txt: + Evaluation file to be written multiple times for different configurations + with different content: + + .*output.txt diff --git a/Tests/RunCMake/File_Generate/OutputConflict.cmake b/Tests/RunCMake/File_Generate/OutputConflict.cmake new file mode 100644 index 0000000..7f3e8c7 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputConflict.cmake @@ -0,0 +1,4 @@ + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" +) diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake new file mode 100644 index 0000000..f07431c --- /dev/null +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCMake) + +run_cmake(CommandConflict) +if("${RunCMake_GENERATOR}" MATCHES "Visual Studio" OR "${RunCMake_GENERATOR}" MATCHES "XCode" ) + run_cmake(OutputConflict) +endif() +run_cmake(EmptyCondition1) +run_cmake(EmptyCondition2) +run_cmake(BadCondition) +run_cmake(DebugEvaluate) diff --git a/Tests/RunCMake/File_Generate/input.txt b/Tests/RunCMake/File_Generate/input.txt new file mode 100644 index 0000000..3db429d --- /dev/null +++ b/Tests/RunCMake/File_Generate/input.txt @@ -0,0 +1 @@ +Some $<$<CONFIG:Debug>:conflicting> $<$<NOT:$<CONFIG:Debug>>:content> diff --git a/Tests/RunCMake/if/CMakeLists.txt b/Tests/RunCMake/if/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/if/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/if/IsDirectory-stdout.txt b/Tests/RunCMake/if/IsDirectory-stdout.txt new file mode 100644 index 0000000..b89446a --- /dev/null +++ b/Tests/RunCMake/if/IsDirectory-stdout.txt @@ -0,0 +1 @@ +CMAKE_CURRENT_SOURCE_DIR exists, tested with trailing slash diff --git a/Tests/RunCMake/if/IsDirectory.cmake b/Tests/RunCMake/if/IsDirectory.cmake new file mode 100644 index 0000000..23d126d --- /dev/null +++ b/Tests/RunCMake/if/IsDirectory.cmake @@ -0,0 +1,5 @@ +if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/") + message(STATUS "CMAKE_CURRENT_SOURCE_DIR exists, tested with trailing slash") +else() + message(FATAL_ERROR "CMAKE_CURRENT_SOURCE_DIR does not exist!") +endif() diff --git a/Tests/RunCMake/if/IsDirectoryLong-stdout.txt b/Tests/RunCMake/if/IsDirectoryLong-stdout.txt new file mode 100644 index 0000000..5e62754 --- /dev/null +++ b/Tests/RunCMake/if/IsDirectoryLong-stdout.txt @@ -0,0 +1 @@ +Directory path with length 94208 correctly does not exist. diff --git a/Tests/RunCMake/if/IsDirectoryLong.cmake b/Tests/RunCMake/if/IsDirectoryLong.cmake new file mode 100644 index 0000000..0e93be7 --- /dev/null +++ b/Tests/RunCMake/if/IsDirectoryLong.cmake @@ -0,0 +1,10 @@ +set(d "/long/path/to/directory") +foreach(i RANGE 11) + set(d "${d}${d}") +endforeach() +string(LENGTH "${d}" dl) +if(IS_DIRECTORY "${d}/") + message(FATAL_ERROR "Directory should not exist!") +else() + message(STATUS "Directory path with length ${dl} correctly does not exist.") +endif() diff --git a/Tests/RunCMake/if/RunCMakeTest.cmake b/Tests/RunCMake/if/RunCMakeTest.cmake new file mode 100644 index 0000000..6b6b74b --- /dev/null +++ b/Tests/RunCMake/if/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(IsDirectory) +run_cmake(IsDirectoryLong) diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries-result.txt b/Tests/RunCMake/try_compile/BadLinkLibraries-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/BadLinkLibraries-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt new file mode 100644 index 0000000..eceffec --- /dev/null +++ b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at BadLinkLibraries.cmake:2 \(try_compile\): + Only libraries may be used as try_compile IMPORTED LINK_LIBRARIES. Got + not_a_library of type UTILITY. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries.cmake b/Tests/RunCMake/try_compile/BadLinkLibraries.cmake new file mode 100644 index 0000000..e8b5add --- /dev/null +++ b/Tests/RunCMake/try_compile/BadLinkLibraries.cmake @@ -0,0 +1,3 @@ +add_custom_target(not_a_library) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c + LINK_LIBRARIES not_a_library) diff --git a/Tests/RunCMake/try_compile/CMakeLists.txt b/Tests/RunCMake/try_compile/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/try_compile/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/try_compile/NoArgs-result.txt b/Tests/RunCMake/try_compile/NoArgs-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoArgs-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoArgs-stderr.txt b/Tests/RunCMake/try_compile/NoArgs-stderr.txt new file mode 100644 index 0000000..8808fd1 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoArgs-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoArgs.cmake:1 \(try_compile\): + try_compile unknown error. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoArgs.cmake b/Tests/RunCMake/try_compile/NoArgs.cmake new file mode 100644 index 0000000..8f751d9 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoArgs.cmake @@ -0,0 +1 @@ +try_compile() diff --git a/Tests/RunCMake/try_compile/NoCopyFile-result.txt b/Tests/RunCMake/try_compile/NoCopyFile-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt b/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt new file mode 100644 index 0000000..d65d9488 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoCopyFile.cmake:1 \(try_compile\): + COPY_FILE must be followed by a file path +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoCopyFile.cmake b/Tests/RunCMake/try_compile/NoCopyFile.cmake new file mode 100644 index 0000000..8c648ff --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c + COPY_FILE) diff --git a/Tests/RunCMake/try_compile/NoCopyFile2-result.txt b/Tests/RunCMake/try_compile/NoCopyFile2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt b/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt new file mode 100644 index 0000000..e889524 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoCopyFile2.cmake:1 \(try_compile\): + COPY_FILE must be followed by a file path +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoCopyFile2.cmake b/Tests/RunCMake/try_compile/NoCopyFile2.cmake new file mode 100644 index 0000000..04b7f68 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoCopyFile2.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c + COPY_FILE CMAKE_FLAGS -DA=B) diff --git a/Tests/RunCMake/try_compile/NoOutputVariable-result.txt b/Tests/RunCMake/try_compile/NoOutputVariable-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt b/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt new file mode 100644 index 0000000..18ad751 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoOutputVariable.cmake:1 \(try_compile\): + OUTPUT_VARIABLE must be followed by a variable name +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoOutputVariable.cmake b/Tests/RunCMake/try_compile/NoOutputVariable.cmake new file mode 100644 index 0000000..3b9cb34 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE) diff --git a/Tests/RunCMake/try_compile/NoOutputVariable2-result.txt b/Tests/RunCMake/try_compile/NoOutputVariable2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt b/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt new file mode 100644 index 0000000..8b2cc25 --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoOutputVariable2.cmake:1 \(try_compile\): + OUTPUT_VARIABLE must be followed by a variable name +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NoOutputVariable2.cmake b/Tests/RunCMake/try_compile/NoOutputVariable2.cmake new file mode 100644 index 0000000..ad9ac9a --- /dev/null +++ b/Tests/RunCMake/try_compile/NoOutputVariable2.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE CMAKE_FLAGS -DA=B) diff --git a/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-result.txt b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt new file mode 100644 index 0000000..025e658 --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NonSourceCompileDefinitions.cmake:1 \(try_compile\): + COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NonSourceCompileDefinitions.cmake b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions.cmake new file mode 100644 index 0000000..8eb0d47 --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/proj + TestProject COMPILE_DEFINITIONS DEF) diff --git a/Tests/RunCMake/try_compile/NonSourceCopyFile-result.txt b/Tests/RunCMake/try_compile/NonSourceCopyFile-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCopyFile-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt b/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt new file mode 100644 index 0000000..f5893e1 --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NonSourceCopyFile.cmake:1 \(try_compile\): + COPY_FILE specified on a srcdir type TRY_COMPILE +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/NonSourceCopyFile.cmake b/Tests/RunCMake/try_compile/NonSourceCopyFile.cmake new file mode 100644 index 0000000..c44192f --- /dev/null +++ b/Tests/RunCMake/try_compile/NonSourceCopyFile.cmake @@ -0,0 +1,2 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/proj + TestProject COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/result) diff --git a/Tests/RunCMake/try_compile/OneArg-result.txt b/Tests/RunCMake/try_compile/OneArg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/OneArg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/OneArg-stderr.txt b/Tests/RunCMake/try_compile/OneArg-stderr.txt new file mode 100644 index 0000000..12835be --- /dev/null +++ b/Tests/RunCMake/try_compile/OneArg-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at OneArg.cmake:1 \(try_compile\): + try_compile unknown error. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/OneArg.cmake b/Tests/RunCMake/try_compile/OneArg.cmake new file mode 100644 index 0000000..e60a462 --- /dev/null +++ b/Tests/RunCMake/try_compile/OneArg.cmake @@ -0,0 +1 @@ +try_compile(RESULT) diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake new file mode 100644 index 0000000..31643cf --- /dev/null +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -0,0 +1,12 @@ +include(RunCMake) + +run_cmake(NoArgs) +run_cmake(OneArg) +run_cmake(TwoArgs) +run_cmake(NoCopyFile) +run_cmake(NoCopyFile2) +run_cmake(NoOutputVariable) +run_cmake(NoOutputVariable2) +run_cmake(BadLinkLibraries) +run_cmake(NonSourceCopyFile) +run_cmake(NonSourceCompileDefinitions) diff --git a/Tests/RunCMake/try_compile/TwoArgs-result.txt b/Tests/RunCMake/try_compile/TwoArgs-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/try_compile/TwoArgs-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/try_compile/TwoArgs-stderr.txt b/Tests/RunCMake/try_compile/TwoArgs-stderr.txt new file mode 100644 index 0000000..b9c08fc --- /dev/null +++ b/Tests/RunCMake/try_compile/TwoArgs-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at TwoArgs.cmake:1 \(try_compile\): + try_compile unknown error. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/try_compile/TwoArgs.cmake b/Tests/RunCMake/try_compile/TwoArgs.cmake new file mode 100644 index 0000000..7f2212d --- /dev/null +++ b/Tests/RunCMake/try_compile/TwoArgs.cmake @@ -0,0 +1 @@ +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/Tests/RunCMake/try_compile/proj/CMakeLists.txt b/Tests/RunCMake/try_compile/proj/CMakeLists.txt new file mode 100644 index 0000000..78a87c0 --- /dev/null +++ b/Tests/RunCMake/try_compile/proj/CMakeLists.txt @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 2.8.10) +project(TestProject NONE) diff --git a/Tests/RunCMake/try_compile/src.c b/Tests/RunCMake/try_compile/src.c new file mode 100644 index 0000000..78f2de1 --- /dev/null +++ b/Tests/RunCMake/try_compile/src.c @@ -0,0 +1 @@ +int main(void) { return 0; } diff --git a/Tests/RunCMake/variable_watch/CMakeLists.txt b/Tests/RunCMake/variable_watch/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/variable_watch/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/variable_watch/ModifiedAccess-stderr.txt b/Tests/RunCMake/variable_watch/ModifiedAccess-stderr.txt new file mode 100644 index 0000000..3ff96fc --- /dev/null +++ b/Tests/RunCMake/variable_watch/ModifiedAccess-stderr.txt @@ -0,0 +1,4 @@ +CMake Debug Log at ModifiedAccess.cmake:3 \(set\): + Variable "b" was accessed using MODIFIED_ACCESS with value "b". +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/variable_watch/ModifiedAccess.cmake b/Tests/RunCMake/variable_watch/ModifiedAccess.cmake new file mode 100644 index 0000000..87943b3 --- /dev/null +++ b/Tests/RunCMake/variable_watch/ModifiedAccess.cmake @@ -0,0 +1,3 @@ +set(b "a") +variable_watch(b) +set(b "b") diff --git a/Tests/RunCMake/variable_watch/NoWatcher-stderr.txt b/Tests/RunCMake/variable_watch/NoWatcher-stderr.txt new file mode 100644 index 0000000..d299429 --- /dev/null +++ b/Tests/RunCMake/variable_watch/NoWatcher-stderr.txt @@ -0,0 +1,5 @@ +my_func +CMake Debug Log at NoWatcher.cmake:8 \(set\): + Variable "b" was accessed using MODIFIED_ACCESS with value "". +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/variable_watch/NoWatcher.cmake b/Tests/RunCMake/variable_watch/NoWatcher.cmake new file mode 100644 index 0000000..8a68efb --- /dev/null +++ b/Tests/RunCMake/variable_watch/NoWatcher.cmake @@ -0,0 +1,8 @@ +function(my_func) + message("my_func") +endfunction() +variable_watch(a my_func) +set(a "") + +variable_watch(b) +set(b "") diff --git a/Tests/RunCMake/variable_watch/RunCMakeTest.cmake b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake new file mode 100644 index 0000000..8d20476 --- /dev/null +++ b/Tests/RunCMake/variable_watch/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(ModifiedAccess) +run_cmake(NoWatcher) diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt index 479d6ec..b969bfd 100644 --- a/Tests/SimpleInstall/CMakeLists.txt +++ b/Tests/SimpleInstall/CMakeLists.txt @@ -122,7 +122,7 @@ if(STAGE2) RESULT_VARIABLE SAMPLE_SCRIPT_RESULT OUTPUT_VARIABLE SAMPLE_SCRIPT_OUTPUT ) - if(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$") + if(NOT "${SAMPLE_SCRIPT_RESULT}" STREQUAL "0") message(FATAL_ERROR "Sample script [${CUR_SCRIPT}] failed: [${SAMPLE_SCRIPT_RESULT}]") endif() diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt index 479d6ec..b969bfd 100644 --- a/Tests/SimpleInstallS2/CMakeLists.txt +++ b/Tests/SimpleInstallS2/CMakeLists.txt @@ -122,7 +122,7 @@ if(STAGE2) RESULT_VARIABLE SAMPLE_SCRIPT_RESULT OUTPUT_VARIABLE SAMPLE_SCRIPT_OUTPUT ) - if(NOT "${SAMPLE_SCRIPT_RESULT}" MATCHES "^0$") + if(NOT "${SAMPLE_SCRIPT_RESULT}" STREQUAL "0") message(FATAL_ERROR "Sample script [${CUR_SCRIPT}] failed: [${SAMPLE_SCRIPT_RESULT}]") endif() @@ -1082,6 +1082,8 @@ KWSYS_STL_HAS_ALLOCATOR_OBJECTS=0 KWSYS_CXX_HAS_SETENV=0 KWSYS_CXX_HAS_UNSETENV=0 KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=0 +KWSYS_CXX_HAS_UTIMENSAT=0 +KWSYS_CXX_HAS_UTIMES=0 KWSYS_CXX_HAS_CSTDDEF=0 KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=0 KWSYS_CXX_HAS_MEMBER_TEMPLATES=0 @@ -1466,7 +1468,13 @@ if [ "x${cmake_cxx_flags}" != "x" ]; then fi cmake_c_flags_String="-DKWSYS_STRING_C" -cmake_cxx_flags_SystemTools="-DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}" +cmake_cxx_flags_SystemTools=" + -DKWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV} + -DKWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV} + -DKWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H} + -DKWSYS_CXX_HAS_UTIMENSAT=${KWSYS_CXX_HAS_UTIMENSAT} + -DKWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES} +" cmake_c_flags="${cmake_c_flags}-I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \ -I`cmake_escape \"${cmake_bootstrap_dir}\"`" cmake_cxx_flags="${cmake_cxx_flags} -I`cmake_escape \"${cmake_bootstrap_dir}\"` -I`cmake_escape \"${cmake_source_dir}/Source\"` \ |