diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in index 13f21617b..640bf70a0 100644 --- a/Modules/AutomocInfo.cmake.in +++ b/Modules/AutomocInfo.cmake.in @@ -1,7 +1,6 @@ set(AM_SOURCES @_moc_files@ ) set(AM_HEADERS @_moc_headers@ ) set(AM_MOC_COMPILE_DEFINITIONS @_moc_compile_defs@) -set(AM_MOC_DEFINITIONS @_moc_defs@) set(AM_MOC_INCLUDES @_moc_incs@) set(AM_MOC_OPTIONS @_moc_options@) set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index cd77ba4e2..39236859b 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -24,7 +24,10 @@ # [HG_REPOSITORY url] # URL of mercurial repo # [HG_TAG tag] # Mercurial branch name, commit id or tag # [URL /.../src.tgz] # Full path or URL of source -# [URL_MD5 md5] # MD5 checksum of file at URL +# [URL_HASH ALGO=value] # Hash of file at URL +# [URL_MD5 md5] # Equivalent to URL_HASH MD5=md5 +# [TLS_VERIFY bool] # Should certificate for https be checked +# [TLS_CAINFO file] # Path to a certificate authority file # [TIMEOUT seconds] # Time allowed for file download operations # #--Update/Patch step---------- # [UPDATE_COMMAND cmd...] # Source work-tree update command @@ -184,6 +187,9 @@ if(_ep_func) set(_ep_keywords_${_ep_func} "${_ep_keywords_${_ep_func}})$") endif() +# Save regex matching supported hash algorithm names. +set(_ep_hash_algos "MD5|SHA1|SHA224|SHA256|SHA384|SHA512") +set(_ep_hash_regex "^(${_ep_hash_algos})=([0-9A-Fa-f]+)$") function(_ep_parse_arguments f name ns args) # Transfer the arguments to this function into target properties for the @@ -395,7 +401,7 @@ endif() endfunction() -function(_ep_write_downloadfile_script script_filename remote local timeout md5) +function(_ep_write_downloadfile_script script_filename remote local timeout hash tls_verify tls_cainfo) if(timeout) set(timeout_args TIMEOUT ${timeout}) set(timeout_msg "${timeout} seconds") @@ -404,10 +410,31 @@ function(_ep_write_downloadfile_script script_filename remote local timeout md5) set(timeout_msg "none") endif() - if(md5) - set(md5_args EXPECTED_MD5 ${md5}) + if("${hash}" MATCHES "${_ep_hash_regex}") + set(hash_args EXPECTED_HASH ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) else() - set(md5_args "# no EXPECTED_MD5") + set(hash_args "# no EXPECTED_HASH") + endif() + # check for curl globals in the project + if(DEFINED CMAKE_TLS_VERIFY) + set(tls_verify "set(CMAKE_TLS_VERIFY ${CMAKE_TLS_VERIFY})") + endif() + if(DEFINED CMAKE_TLS_CAINFO) + set(tls_cainfo "set(CMAKE_TLS_CAINFO \"${CMAKE_TLS_CAINFO}\")") + endif() + + # now check for curl locals so that the local values + # will override the globals + + # check for tls_verify argument + string(LENGTH "${tls_verify}" tls_verify_len) + if(tls_verify_len GREATER 0) + set(tls_verify "set(CMAKE_TLS_VERIFY ${tls_verify})") + endif() + # check for tls_cainfo argument + string(LENGTH "${tls_cainfo}" tls_cainfo_len) + if(tls_cainfo_len GREATER 0) + set(tls_cainfo "set(CMAKE_TLS_CAINFO \"${tls_cainfo}\")") endif() file(WRITE ${script_filename} @@ -416,11 +443,14 @@ function(_ep_write_downloadfile_script script_filename remote local timeout md5) dst='${local}' timeout='${timeout_msg}'\") +${tls_verify} +${tls_cainfo} + file(DOWNLOAD \"${remote}\" \"${local}\" SHOW_PROGRESS - ${md5_args} + ${hash_args} ${timeout_args} STATUS status LOG log) @@ -443,48 +473,30 @@ message(STATUS \"downloading... done\") endfunction() -function(_ep_write_verifyfile_script script_filename local md5) - file(WRITE ${script_filename} -"message(STATUS \"verifying file... - file='${local}'\") - -set(verified 0) - -# If an expected md5 checksum exists, compare against it: -# -if(NOT \"${md5}\" STREQUAL \"\") - execute_process(COMMAND \${CMAKE_COMMAND} -E md5sum \"${local}\" - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE rv) - - if(NOT rv EQUAL 0) - message(FATAL_ERROR \"error: computing md5sum of '${local}' failed\") - endif() - - string(REGEX MATCH \"^([0-9A-Fa-f]+)\" md5_actual \"\${ov}\") - - string(TOLOWER \"\${md5_actual}\" md5_actual) - string(TOLOWER \"${md5}\" md5) - - if(NOT \"\${md5}\" STREQUAL \"\${md5_actual}\") - message(FATAL_ERROR \"error: md5sum of '${local}' does not match expected value - md5_expected: \${md5} - md5_actual: \${md5_actual} -\") - endif() - - set(verified 1) -endif() - -if(verified) +function(_ep_write_verifyfile_script script_filename local hash) + if("${hash}" MATCHES "${_ep_hash_regex}") + set(algo "${CMAKE_MATCH_1}") + string(TOLOWER "${CMAKE_MATCH_2}" expect_value) + set(script_content "set(expect_value \"${expect_value}\") +file(${algo} \"\${file}\" actual_value) +if(\"\${actual_value}\" STREQUAL \"\${expect_value}\") message(STATUS \"verifying file... done\") else() - message(STATUS \"verifying file... warning: did not verify file - no URL_MD5 checksum argument? corrupt file?\") -endif() -" -) - + message(FATAL_ERROR \"error: ${algo} hash of + \${file} +does not match expected value + expected: \${expect_value} + actual: \${actual_value} +\") +endif()") + else() + set(script_content "message(STATUS \"verifying file... warning: did not verify file - no URL_HASH specified?\")") + endif() + file(WRITE ${script_filename} "set(file \"${local}\") +message(STATUS \"verifying file... + file='\${file}'\") +${script_content} +") endfunction() @@ -1254,10 +1266,22 @@ function(_ep_add_download_command name) list(APPEND depends ${stamp_dir}/${name}-hginfo.txt) elseif(url) get_filename_component(work_dir "${source_dir}" PATH) + get_property(hash TARGET ${name} PROPERTY _EP_URL_HASH) + if(hash AND NOT "${hash}" MATCHES "${_ep_hash_regex}") + message(FATAL_ERROR "URL_HASH is set to\n ${hash}\n" + "but must be ALGO=value where ALGO is\n ${_ep_hash_algos}\n" + "and value is a hex string.") + endif() get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5) + if(md5 AND NOT "MD5=${md5}" MATCHES "${_ep_hash_regex}") + message(FATAL_ERROR "URL_MD5 is set to\n ${md5}\nbut must be a hex string.") + endif() + if(md5 AND NOT hash) + set(hash "MD5=${md5}") + endif() set(repository "external project URL") set(module "${url}") - set(tag "${md5}") + set(tag "${hash}") configure_file( "${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in" "${stamp_dir}/${name}-urlinfo.txt" @@ -1283,7 +1307,10 @@ function(_ep_add_download_command name) string(REPLACE ";" "-" fname "${fname}") set(file ${download_dir}/${fname}) get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT) - _ep_write_downloadfile_script("${stamp_dir}/download-${name}.cmake" "${url}" "${file}" "${timeout}" "${md5}") + get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY) + get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO) + _ep_write_downloadfile_script("${stamp_dir}/download-${name}.cmake" + "${url}" "${file}" "${timeout}" "${hash}" "${tls_verify}" "${tls_cainfo}") set(cmd ${CMAKE_COMMAND} -P ${stamp_dir}/download-${name}.cmake COMMAND) set(comment "Performing download step (download, verify and extract) for '${name}'") @@ -1291,7 +1318,7 @@ function(_ep_add_download_command name) set(file "${url}") set(comment "Performing download step (verify and extract) for '${name}'") endif() - _ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${md5}") + _ep_write_verifyfile_script("${stamp_dir}/verify-${name}.cmake" "${file}" "${hash}") list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake COMMAND) _ep_write_extractfile_script("${stamp_dir}/extract-${name}.cmake" "${name}" "${file}" "${source_dir}") diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 0a98bf573..5a834b128 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -68,6 +68,13 @@ # CUDA_HOST_COMPILATION_CPP (Default ON) # -- Set to OFF for C compilation of host code. # +# CUDA_HOST_COMPILER (Default CMAKE_C_COMPILER, $(VCInstallDir)/bin for VS) +# -- Set the host compiler to be used by nvcc. Ignored if -ccbin or +# --compiler-bindir is already present in the CUDA_NVCC_FLAGS or +# CUDA_NVCC_FLAGS_ variables. For Visual Studio targets +# $(VCInstallDir)/bin is a special value that expands out to the path when +# the command is run from withing VS. +# # CUDA_NVCC_FLAGS # CUDA_NVCC_FLAGS_ # -- Additional NVCC command line arguments. NOTE: multiple arguments must be @@ -390,6 +397,12 @@ option(CUDA_HOST_COMPILATION_CPP "Generated file extension" ON) # Extra user settable flags set(CUDA_NVCC_FLAGS "" CACHE STRING "Semi-colon delimit multiple arguments.") +if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(CUDA_HOST_COMPILER "$(VCInstallDir)bin" CACHE FILEPATH "Host side compiler used by NVCC") +else() + set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "Host side compiler used by NVCC") +endif() + # Propagate the host flags to the host compiler via -Xcompiler option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" ON) @@ -932,12 +945,11 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) endif() # This needs to be passed in at this stage, because VS needs to fill out the - # value of VCInstallDir from within VS. + # value of VCInstallDir from within VS. Note that CCBIN is only used if + # -ccbin or --compiler-bindir isn't used and CUDA_HOST_COMPILER matches + # $(VCInstallDir)/bin. if(CMAKE_GENERATOR MATCHES "Visual Studio") - if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) - # Add nvcc flag for 64b Windows - set(ccbin_flags -D "\"CCBIN:PATH=$(VCInstallDir)bin\"" ) - endif() + set(ccbin_flags -D "\"CCBIN:PATH=$(VCInstallDir)bin\"" ) endif() # Figure out which configure we will use and pass that in as an argument to diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake index 8274cc718..f0aac8487 100644 --- a/Modules/FindCUDA/run_nvcc.cmake +++ b/Modules/FindCUDA/run_nvcc.cmake @@ -62,6 +62,7 @@ set(cmake_dependency_file "@cmake_dependency_file@") # path set(CUDA_make2cmake "@CUDA_make2cmake@") # path set(CUDA_parse_cubin "@CUDA_parse_cubin@") # path set(build_cubin @build_cubin@) # bool +set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # bool # We won't actually use these variables for now, but we need to set this, in # order to force this file to be run again if it changes. set(generated_file_path "@generated_file_path@") # path @@ -102,8 +103,15 @@ endif() # Add the build specific configuration flags list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}}) -if(DEFINED CCBIN) - set(CCBIN -ccbin "${CCBIN}") +# Any -ccbin existing in CUDA_NVCC_FLAGS gets highest priority +list( FIND CUDA_NVCC_FLAGS "-ccbin" ccbin_found0 ) +list( FIND CUDA_NVCC_FLAGS "--compiler-bindir" ccbin_found1 ) +if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 ) + if (CUDA_HOST_COMPILER STREQUAL "$(VCInstallDir)bin" AND DEFINED CCBIN) + set(CCBIN -ccbin "${CCBIN}") + else() + set(CCBIN -ccbin "${CUDA_HOST_COMPILER}") + endif() endif() # cuda_execute_process - Executes a command with optional command echo and status message. diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake new file mode 100644 index 000000000..37dff0324 --- /dev/null +++ b/Modules/FindGLEW.cmake @@ -0,0 +1,30 @@ +# - Find the OpenGL Extension Wrangler Library (GLEW) +# This module defines the following variables: +# GLEW_INCLUDE_DIRS - include directories for GLEW +# GLEW_LIBRARIES - libraries to link against GLEW +# GLEW_FOUND - true if GLEW has been found and can be used + +#============================================================================= +# Copyright 2012 Benjamin Eikel +# +# 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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +find_path(GLEW_INCLUDE_DIR GL/glew.h) +find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64) + +set(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR}) +set(GLEW_LIBRARIES ${GLEW_LIBRARY}) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(GLEW + REQUIRED_VARS GLEW_INCLUDE_DIR GLEW_LIBRARY) + +mark_as_advanced(GLEW_INCLUDE_DIR GLEW_LIBRARY) diff --git a/Modules/FindOpenSceneGraph.cmake b/Modules/FindOpenSceneGraph.cmake index 1f30fe3f1..4a5aaba41 100644 --- a/Modules/FindOpenSceneGraph.cmake +++ b/Modules/FindOpenSceneGraph.cmake @@ -145,23 +145,6 @@ if(OSG_INCLUDE_DIR) endif() endif() -# -# Version checking -# -if(OpenSceneGraph_FIND_VERSION AND OPENSCENEGRAPH_VERSION) - if(OpenSceneGraph_FIND_VERSION_EXACT) - if(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL ${OpenSceneGraph_FIND_VERSION}) - set(_osg_version_not_exact TRUE) - endif() - else() - # version is too low - if(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL ${OpenSceneGraph_FIND_VERSION} AND - NOT OPENSCENEGRAPH_VERSION VERSION_GREATER ${OpenSceneGraph_FIND_VERSION}) - set(_osg_version_not_high_enough TRUE) - endif() - endif() -endif() - set(_osg_quiet) if(OpenSceneGraph_FIND_QUIETLY) set(_osg_quiet "QUIET") @@ -190,63 +173,22 @@ if(OPENSCENEGRAPH_INCLUDE_DIR) endif() # -# Inform the users with an error message based on -# what version they have vs. what version was -# required. +# Check each module to see if it's found # +set(_osg_component_founds) if(OpenSceneGraph_FIND_REQUIRED) - set(_osg_version_output_type FATAL_ERROR) -else() - set(_osg_version_output_type STATUS) -endif() -if(_osg_version_not_high_enough) - set(_osg_EPIC_FAIL TRUE) - if(NOT OpenSceneGraph_FIND_QUIETLY) - message(${_osg_version_output_type} - "ERROR: Version ${OpenSceneGraph_FIND_VERSION} or higher of the OSG " - "is required. Version ${OPENSCENEGRAPH_VERSION} was found.") - endif() -elseif(_osg_version_not_exact) - set(_osg_EPIC_FAIL TRUE) - if(NOT OpenSceneGraph_FIND_QUIETLY) - message(${_osg_version_output_type} - "ERROR: Version ${OpenSceneGraph_FIND_VERSION} of the OSG is required " - "(exactly), version ${OPENSCENEGRAPH_VERSION} was found.") - endif() -else() - - # - # Check each module to see if it's found - # - if(OpenSceneGraph_FIND_REQUIRED) - set(_osg_missing_message) - foreach(_osg_module ${_osg_modules_to_process}) - string(TOUPPER ${_osg_module} _osg_module_UC) - if(NOT ${_osg_module_UC}_FOUND) - set(_osg_missing_nodekit_fail true) - set(_osg_missing_message "${_osg_missing_message} ${_osg_module}") - endif() - endforeach() - - if(_osg_missing_nodekit_fail) - message(FATAL_ERROR "ERROR: Missing the following osg " - "libraries: ${_osg_missing_message}.\n" - "Consider using CMAKE_PREFIX_PATH or the OSG_DIR " - "environment variable. See the " - "${CMAKE_CURRENT_LIST_FILE} for more details.") - endif() - endif() - - include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSceneGraph DEFAULT_MSG OPENSCENEGRAPH_LIBRARIES OPENSCENEGRAPH_INCLUDE_DIR) + foreach(_osg_module ${_osg_modules_to_process}) + string(TOUPPER ${_osg_module} _osg_module_UC) + list(APPEND _osg_component_founds ${_osg_module_UC}_FOUND) + endforeach() endif() -if(_osg_EPIC_FAIL) - # Zero out everything, we didn't meet version requirements - set(OPENSCENEGRAPH_FOUND FALSE) - set(OPENSCENEGRAPH_LIBRARIES) - set(OPENSCENEGRAPH_INCLUDE_DIR) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenSceneGraph + REQUIRED_VARS OPENSCENEGRAPH_LIBRARIES OPENSCENEGRAPH_INCLUDE_DIR ${_osg_component_founds} + VERSION_VAR OPENSCENEGRAPH_VERSION) + +unset(_osg_component_founds) set(OPENSCENEGRAPH_INCLUDE_DIRS ${OPENSCENEGRAPH_INCLUDE_DIR}) diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake index 487c5d346..adaec95a2 100644 --- a/Modules/FindSDL.cmake +++ b/Modules/FindSDL.cmake @@ -133,10 +133,12 @@ endif() if(SDL_LIBRARY_TEMP) # For SDLmain - if(NOT SDL_BUILDING_LIBRARY) - if(SDLMAIN_LIBRARY) - set(SDL_LIBRARY_TEMP ${SDLMAIN_LIBRARY} ${SDL_LIBRARY_TEMP}) + if(SDLMAIN_LIBRARY AND NOT SDL_BUILDING_LIBRARY) + list(FIND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" _SDL_MAIN_INDEX) + if(_SDL_MAIN_INDEX EQUAL -1) + list(APPEND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}") endif() + unset(_SDL_MAIN_INDEX) endif() # For OS X, SDL uses Cocoa as a backend so it must link to Cocoa. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 186aa6db6..2968ebbf1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -187,6 +187,12 @@ set(SRCS cmFileTimeComparison.cxx cmFileTimeComparison.h cmGeneratedFileStream.cxx + cmGeneratorExpressionEvaluator.cxx + cmGeneratorExpressionEvaluator.h + cmGeneratorExpressionLexer.cxx + cmGeneratorExpressionLexer.h + cmGeneratorExpressionParser.cxx + cmGeneratorExpressionParser.h cmGeneratorExpression.cxx cmGeneratorExpression.h cmGeneratorTarget.cxx @@ -553,7 +559,7 @@ endif() # Qt GUI option(BUILD_QtDialog "Build Qt dialog for CMake" FALSE) if(BUILD_QtDialog) - subdirs(QtDialog) + add_subdirectory(QtDialog) endif() include (${CMake_BINARY_DIR}/Source/LocalUserOptions.cmake OPTIONAL) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 83a41d5f4..7b6af1e0d 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 9) -set(CMake_VERSION_TWEAK 20120915) +set(CMake_VERSION_TWEAK 20120919) #set(CMake_VERSION_RC 1) diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 0969aea01..a1ffa2076 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -9,115 +9,129 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= -project(QtDialog) -set(QT_MIN_VERSION "4.4.0") -find_package(Qt4 REQUIRED) -if(NOT QT4_FOUND) - message(SEND_ERROR "Failed to find Qt 4.4 or greater.") +project(QtDialog) +find_package(Qt5Widgets QUIET) +if (Qt5Widgets_FOUND) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + add_definitions(${Qt5Widgets_DEFINITONS}) + macro(qt4_wrap_ui) + qt5_wrap_ui(${ARGN}) + endmacro() + macro(qt4_wrap_cpp) + qt5_wrap_cpp(${ARGN}) + endmacro() + macro(qt4_add_resources) + qt5_add_resources(${ARGN}) + endmacro() + set(QT_LIBRARIES ${Qt5Widgets_LIBRARIES}) else() + set(QT_MIN_VERSION "4.4.0") + find_package(Qt4 REQUIRED) + if(NOT QT4_FOUND) + message(SEND_ERROR "Failed to find Qt 4.4 or greater.") + return() + endif() include(${QT_USE_FILE}) - set(CMAKE_PACKAGE_QTGUI TRUE) - set(SRCS - AddCacheEntry.cxx - AddCacheEntry.h - CMakeSetup.cxx - CMakeSetupDialog.cxx - CMakeSetupDialog.h - FirstConfigure.cxx - FirstConfigure.h - QCMake.cxx - QCMake.h - QCMakeCacheView.cxx - QCMakeCacheView.h - QCMakeWidgets.cxx - QCMakeWidgets.h - QMacInstallDialog.cxx - QMacInstallDialog.h - ) - QT4_WRAP_UI(UI_SRCS - CMakeSetupDialog.ui - Compilers.ui - CrossCompiler.ui - AddCacheEntry.ui - MacInstallDialog.ui - ) - QT4_WRAP_CPP(MOC_SRCS - AddCacheEntry.h - Compilers.h - CMakeSetupDialog.h - FirstConfigure.h - QCMake.h - QCMakeCacheView.h - QCMakeWidgets.h - QMacInstallDialog.h - ) - QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc) - - set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS}) - if(Q_WS_WIN) - set(SRCS ${SRCS} CMakeSetup.rc) - endif() - if(Q_WS_MAC) - set(SRCS ${SRCS} CMakeSetup.icns) - set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns) - set_source_files_properties(CMakeSetup.icns PROPERTIES - MACOSX_PACKAGE_LOCATION Resources) - endif() - - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) - - add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS}) - target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) - if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) - if(APPLE) - set_target_properties(cmake-gui PROPERTIES - OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) - endif() - set(CMAKE_INSTALL_DESTINATION_ARGS - BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") - endif() - - install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) - - if(UNIX) - # install a desktop file so CMake appears in the application start menu - # with an icon - install(FILES CMake.desktop DESTINATION share/applications ) - install(FILES CMakeSetup32.png DESTINATION share/pixmaps ) - install(FILES cmakecache.xml DESTINATION share/mime/packages ) - endif() - - if(APPLE) - set(CMAKE_POSTFLIGHT_SCRIPT - "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") - set(CMAKE_POSTUPGRADE_SCRIPT - "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") - configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in" - "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") - configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in" - "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") - install(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui - WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") - endif() - - if(APPLE OR WIN32) - # install rules for including 3rd party libs such as Qt - # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation - set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}") - if(APPLE) - set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}") - endif() - install(CODE " - include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") - set(BU_CHMOD_BUNDLE_ITEMS ON) - fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") - ") - endif() - - configure_file("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" - "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) endif() +set(SRCS + AddCacheEntry.cxx + AddCacheEntry.h + CMakeSetup.cxx + CMakeSetupDialog.cxx + CMakeSetupDialog.h + FirstConfigure.cxx + FirstConfigure.h + QCMake.cxx + QCMake.h + QCMakeCacheView.cxx + QCMakeCacheView.h + QCMakeWidgets.cxx + QCMakeWidgets.h + QMacInstallDialog.cxx + QMacInstallDialog.h + ) +QT4_WRAP_UI(UI_SRCS + CMakeSetupDialog.ui + Compilers.ui + CrossCompiler.ui + AddCacheEntry.ui + MacInstallDialog.ui + ) +QT4_WRAP_CPP(MOC_SRCS + AddCacheEntry.h + Compilers.h + CMakeSetupDialog.h + FirstConfigure.h + QCMake.h + QCMakeCacheView.h + QCMakeWidgets.h + QMacInstallDialog.h + ) +QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc) + +set(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS}) +if(WIN32) + set(SRCS ${SRCS} CMakeSetup.rc) +endif() +if(APPLE) + set(SRCS ${SRCS} CMakeSetup.icns) + set(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns) + set_source_files_properties(CMakeSetup.icns PROPERTIES + MACOSX_PACKAGE_LOCATION Resources) +endif() + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_executable(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS}) +target_link_libraries(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) + +if(APPLE) + set_target_properties(cmake-gui PROPERTIES + OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) +endif() +set(CMAKE_INSTALL_DESTINATION_ARGS + BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") + +install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) + +if(UNIX) + # install a desktop file so CMake appears in the application start menu + # with an icon + install(FILES CMake.desktop DESTINATION share/applications ) + install(FILES CMakeSetup32.png DESTINATION share/pixmaps ) + install(FILES cmakecache.xml DESTINATION share/mime/packages ) +endif() + +if(APPLE) + set(CMAKE_POSTFLIGHT_SCRIPT + "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") + set(CMAKE_POSTUPGRADE_SCRIPT + "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") + configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in" + "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") + configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in" + "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") + install(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui + WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") +endif() + +if(APPLE OR WIN32) + # install rules for including 3rd party libs such as Qt + # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation + set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}") + if(APPLE) + set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}") + endif() + install(CODE " + include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\") + ") +endif() + +set(CMAKE_PACKAGE_QTGUI TRUE) +configure_file("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" + "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY) diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index a2b1567bf..0d0118164 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -348,7 +348,11 @@ void QCMake::interrupt() bool QCMake::interruptCallback(void* cd) { QCMake* self = reinterpret_cast(cd); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) return self->InterruptFlag; +#else + return self->InterruptFlag.load(); +#endif } void QCMake::progressCallback(const char* msg, float percent, void* cd) diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index a65012905..07df7d5e0 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -21,7 +21,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( cmCustomCommand const& cc, const char* config, cmMakefile* mf): CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()), OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars()), - GE(new cmGeneratorExpression(mf, config, cc.GetBacktrace())) + GE(new cmGeneratorExpression(cc.GetBacktrace())) { } @@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const { return target->GetLocation(this->Config); } - return this->GE->Process(argv0); + return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config); } //---------------------------------------------------------------------------- @@ -58,7 +58,8 @@ cmCustomCommandGenerator cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; for(unsigned int j=1;j < commandLine.size(); ++j) { - std::string arg = this->GE->Process(commandLine[j]); + std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile, + this->Config); cmd += " "; if(this->OldStyle) { diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index ad4ab76ee..b1bbd905d 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -636,9 +636,11 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, // the include directories for this target std::set uniqIncludeDirs; + cmGeneratorTarget *gtgt = this->GlobalGenerator + ->GetGeneratorTarget(target); std::vector includes; target->GetMakefile()->GetLocalGenerator()-> - GetIncludeDirectories(includes, target); + GetIncludeDirectories(includes, gtgt); for(std::vector::const_iterator dirIt=includes.begin(); dirIt != includes.end(); ++dirIt) diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 1f976f7d9..f1d9c31a8 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -884,11 +884,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) { - cmTargets & targets = (*it)->GetMakefile()->GetTargets(); - for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + cmGeneratorTargetsType targets = (*it)->GetMakefile() + ->GetGeneratorTargets(); + for (cmGeneratorTargetsType::iterator l = targets.begin(); + l != targets.end(); ++l) { std::vector includeDirs; - (*it)->GetIncludeDirectories(includeDirs, &l->second); + (*it)->GetIncludeDirectories(includeDirs, l->second); this->AppendIncludeDirectories(fout, includeDirs, emmited); } } diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index bb129804e..4d9eb7972 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2667,9 +2667,8 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) long inactivity_timeout = 0; std::string verboseLog; std::string statusVar; - std::string caFile; - bool checkSSL = false; - bool verifySSL = false; + bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY"); + const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO"); std::string expectedHash; std::string hashMatchMSG; cmsys::auto_ptr hash; @@ -2723,30 +2722,29 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) } statusVar = *i; } - else if(*i == "SSL_VERIFY") + else if(*i == "TLS_VERIFY") { ++i; if(i != args.end()) { - verifySSL = cmSystemTools::IsOn(i->c_str()); - checkSSL = true; + tls_verify = cmSystemTools::IsOn(i->c_str()); } else { - this->SetError("SSL_VERIFY missing bool value."); + this->SetError("TLS_VERIFY missing bool value."); return false; } } - else if(*i == "SSL_CAINFO_FILE") + else if(*i == "TLS_CAINFO") { ++i; if(i != args.end()) { - caFile = *i; + cainfo = i->c_str(); } else { - this->SetError("SSL_CAFILE missing file value."); + this->SetError("TLS_CAFILE missing file value."); return false; } } @@ -2865,41 +2863,23 @@ cmFileCommand::HandleDownloadCommand(std::vector const& args) cmFileCommandCurlDebugCallback); check_curl_result(res, "DOWNLOAD cannot set debug function: "); - // check to see if SSL verification is requested - const char* verifyValue = - this->Makefile->GetDefinition("CMAKE_CURLOPT_SSL_VERIFYPEER"); - // if there is a cmake variable or if the command has SSL_VERIFY requested - if(verifyValue || checkSSL) + // check to see if TLS verification is requested + if(tls_verify) { - // the args to the command come first - bool verify = verifySSL; - if(!verify && verifyValue) - { - verify = cmSystemTools::IsOn(verifyValue); - } - if(verify) - { - res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); - check_curl_result(res, "Unable to set SSL Verify on: "); - } - else - { - res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - check_curl_result(res, "Unable to set SSL Verify off: "); - } + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1); + check_curl_result(res, "Unable to set TLS/SSL Verify on: "); + } + else + { + res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + check_curl_result(res, "Unable to set TLS/SSL Verify off: "); } // check to see if a CAINFO file has been specified - const char* cainfo = - this->Makefile->GetDefinition("CMAKE_CURLOPT_CAINFO_FILE"); // command arg comes first - if(caFile.size()) - { - cainfo = caFile.c_str(); - } - if(cainfo) + if(cainfo && *cainfo) { res = ::curl_easy_setopt(curl, CURLOPT_CAINFO, cainfo); - check_curl_result(res, "Unable to set SSL Verify CAINFO: "); + check_curl_result(res, "Unable to set TLS/SSL Verify CAINFO: "); } cmFileCommandVectorOfChar chunkDebug; diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 413e2f4e2..bd6f612f1 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -85,7 +85,7 @@ public: " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]\n" " [EXPECTED_HASH MD5|SHA1|SHA224|SHA256|SHA384|SHA512 hash]\n" " [EXPECTED_MD5 sum]\n" - " [SSL_VERIFY on|off] [SSL_CAINFO_FILE file])\n" + " [TLS_VERIFY on|off] [TLS_CAINFO file])\n" " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" "WRITE will write a message into a file called 'filename'. It " @@ -177,12 +177,12 @@ public: "If SHOW_PROGRESS is specified, progress information will be printed " "as status messages until the operation is complete. " "For https URLs CMake must be built with OpenSSL. " - "SSL certificates are not checked by default. " - "Set SSL_VERIFY to ON to check certificates and/or use " + "TLS/SSL certificates are not checked by default. " + "Set TLS_VERIFY to ON to check certificates and/or use " "EXPECTED_HASH to verify downloaded content. " - "Set SSL_CAINFO_FILE to specify a custom Certificate Authority file. " - "If either SSL option is not given CMake will check variables " - "CMAKE_CURLOPT_SSL_VERIFYPEER and CMAKE_CURLOPT_CAINFO_FILE, " + "Set TLS_CAINFO to specify a custom Certificate Authority file. " + "If either TLS option is not given CMake will check variables " + "CMAKE_TLS_VERIFY and CMAKE_TLS_CAINFO, " "respectively." "\n" "UPLOAD will upload the given file to the given URL. " diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 92bbf1d82..0885616ad 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -16,233 +16,112 @@ #include +#include "cmGeneratorExpressionEvaluator.h" +#include "cmGeneratorExpressionLexer.h" +#include "cmGeneratorExpressionParser.h" + //---------------------------------------------------------------------------- cmGeneratorExpression::cmGeneratorExpression( - cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace, bool quiet): - Makefile(mf), Config(config), Backtrace(backtrace), Quiet(quiet) + cmListFileBacktrace const& backtrace): + Backtrace(backtrace), CompiledExpression(0) { - this->TargetInfo.compile("^\\$$"); - this->TestConfig.compile("^\\$$"); } //---------------------------------------------------------------------------- -const char* cmGeneratorExpression::Process(std::string const& input) +const cmCompiledGeneratorExpression & +cmGeneratorExpression::Parse(std::string const& input) { - return this->Process(input.c_str()); + return this->Parse(input.c_str()); } //---------------------------------------------------------------------------- -const char* cmGeneratorExpression::Process(const char* input) +const cmCompiledGeneratorExpression & +cmGeneratorExpression::Parse(const char* input) { - this->Data.clear(); + cmGeneratorExpressionLexer l; + std::vector tokens = l.Tokenize(input); + bool needsParsing = l.GetSawGeneratorExpression(); + std::vector evaluators; - // We construct and evaluate expressions directly in the output - // buffer. Each expression is replaced by its own output value - // after evaluation. A stack of barriers records the starting - // indices of open (pending) expressions. - for(const char* c = input; *c; ++c) + if (needsParsing) { - if(c[0] == '$' && c[1] == '<') - { - this->Barriers.push(this->Data.size()); - this->Data.push_back('$'); - this->Data.push_back('<'); - c += 1; - } - else if(c[0] == '>' && !this->Barriers.empty()) - { - this->Data.push_back('>'); - if(!this->Evaluate()) { break; } - this->Barriers.pop(); - } - else - { - this->Data.push_back(c[0]); - } + cmGeneratorExpressionParser p(tokens); + p.Parse(evaluators); } - // Return a null-terminated output value. - this->Data.push_back('\0'); - return &*this->Data.begin(); + delete this->CompiledExpression; + this->CompiledExpression = new cmCompiledGeneratorExpression( + this->Backtrace, + evaluators, + input, + needsParsing); + return *this->CompiledExpression; +} + +cmGeneratorExpression::~cmGeneratorExpression() +{ + delete this->CompiledExpression; } //---------------------------------------------------------------------------- -bool cmGeneratorExpression::Evaluate() +const char *cmCompiledGeneratorExpression::Evaluate( + cmMakefile* mf, const char* config, bool quiet) const { - // The top-most barrier points at the beginning of the expression. - size_t barrier = this->Barriers.top(); - - // Construct a null-terminated representation of the expression. - this->Data.push_back('\0'); - const char* expr = &*(this->Data.begin()+barrier); - - // Evaluate the expression. - std::string result; - if(this->Evaluate(expr, result)) + if (!this->NeedsParsing) { - // Success. Replace the expression with its evaluation result. - this->Data.erase(this->Data.begin()+barrier, this->Data.end()); - this->Data.insert(this->Data.end(), result.begin(), result.end()); - return true; + return this->Input; } - else if(!this->Quiet) + + this->Output = ""; + + std::vector::const_iterator it + = this->Evaluators.begin(); + const std::vector::const_iterator end + = this->Evaluators.end(); + + cmGeneratorExpressionContext context; + context.Makefile = mf; + context.Config = config; + context.Quiet = quiet; + context.HadError = false; + context.Backtrace = this->Backtrace; + + for ( ; it != end; ++it) { - // Failure. Report the error message. - cmOStringStream e; - e << "Error evaluating generator expression:\n" - << " " << expr << "\n" - << result; - this->Makefile->GetCMakeInstance() - ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), - this->Backtrace); - return false; + this->Output += (*it)->Evaluate(&context); + if (context.HadError) + { + this->Output = ""; + break; + } } - return true; + + this->Targets = context.Targets; + // TODO: Return a std::string from here instead? + return this->Output.c_str(); } +cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( + cmListFileBacktrace const& backtrace, + const std::vector &evaluators, + const char *input, bool needsParsing) + : Backtrace(backtrace), Evaluators(evaluators), Input(input), + NeedsParsing(needsParsing) +{ + +} + + //---------------------------------------------------------------------------- -static bool cmGeneratorExpressionBool(const char* c, std::string& result, - const char* name, - const char* a, const char* b) +cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() { - result = a; - while((c[0] == '0' || c[0] == '1') && (c[1] == ',' || c[1] == '>')) + std::vector::const_iterator it + = this->Evaluators.begin(); + const std::vector::const_iterator end + = this->Evaluators.end(); + + for ( ; it != end; ++it) { - if(c[0] == b[0]) { result = b; } - c += 2; + delete *it; } - if(c[0]) - { - result = name; - result += " requires one or more comma-separated '0' or '1' values."; - return false; - } - return true; -} - -//---------------------------------------------------------------------------- -bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result) -{ - if(this->TargetInfo.find(expr)) - { - if(!this->EvaluateTargetInfo(result)) - { - return false; - } - } - else if(strcmp(expr, "$") == 0) - { - result = this->Config? this->Config : ""; - } - else if(strncmp(expr, "$<0:",4) == 0) - { - result = ""; - } - else if(strncmp(expr, "$<1:",4) == 0) - { - result = std::string(expr+4, strlen(expr)-5); - } - else if(strncmp(expr, "$TestConfig.find(expr)) - { - result = cmsysString_strcasecmp(this->TestConfig.match(1).c_str(), - this->Config? this->Config:"") == 0 - ? "1":"0"; - } - else - { - result = "Expression syntax not recognized."; - return false; - } - return true; -} - -//---------------------------------------------------------------------------- -bool cmGeneratorExpression::EvaluateTargetInfo(std::string& result) -{ - // Lookup the referenced target. - std::string name = this->TargetInfo.match(3); - cmTarget* target = this->Makefile->FindTargetToUse(name.c_str()); - if(!target) - { - result = "No target \"" + name + "\""; - return false; - } - if(target->GetType() >= cmTarget::UTILITY && - target->GetType() != cmTarget::UNKNOWN_LIBRARY) - { - result = "Target \"" + name + "\" is not an executable or library."; - return false; - } - this->Targets.insert(target); - - // Lookup the target file with the given purpose. - std::string purpose = this->TargetInfo.match(1); - if(purpose == "") - { - // The target implementation file (.so.1.2, .dll, .exe, .a). - result = target->GetFullPath(this->Config, false, true); - } - else if(purpose == "_LINKER") - { - // The file used to link to the target (.so, .lib, .a). - if(!target->IsLinkable()) - { - result = ("TARGET_LINKER_FILE is allowed only for libraries and " - "executables with ENABLE_EXPORTS."); - return false; - } - result = target->GetFullPath(this->Config, target->HasImportLibrary()); - } - else if(purpose == "_SONAME") - { - // The target soname file (.so.1). - if(target->IsDLLPlatform()) - { - result = "TARGET_SONAME_FILE is not allowed for DLL target platforms."; - return false; - } - if(target->GetType() != cmTarget::SHARED_LIBRARY) - { - result = "TARGET_SONAME_FILE is allowed only for SHARED libraries."; - return false; - } - result = target->GetDirectory(this->Config); - result += "/"; - result += target->GetSOName(this->Config); - } - - // Extract the requested portion of the full path. - std::string part = this->TargetInfo.match(2); - if(part == "_NAME") - { - result = cmSystemTools::GetFilenameName(result); - } - else if(part == "_DIR") - { - result = cmSystemTools::GetFilenamePath(result); - } - return true; } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index a023eb0c9..b8467c27c 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -19,6 +19,10 @@ class cmTarget; class cmMakefile; class cmListFileBacktrace; +struct cmGeneratorExpressionEvaluator; + +class cmCompiledGeneratorExpression; + /** \class cmGeneratorExpression * \brief Evaluate generate-time query expression syntax. * @@ -31,29 +35,48 @@ class cmListFileBacktrace; class cmGeneratorExpression { public: - /** Construct with an evaluation context and configuration. */ - cmGeneratorExpression(cmMakefile* mf, const char* config, - cmListFileBacktrace const& backtrace, - bool quiet = false); + /** Construct. */ + cmGeneratorExpression(cmListFileBacktrace const& backtrace); + ~cmGeneratorExpression(); - /** Evaluate generator expressions in a string. */ - const char* Process(std::string const& input); - const char* Process(const char* input); + const cmCompiledGeneratorExpression& Parse(std::string const& input); + const cmCompiledGeneratorExpression& Parse(const char* input); + +private: + cmGeneratorExpression(const cmGeneratorExpression &); + void operator=(const cmGeneratorExpression &); + + cmListFileBacktrace const& Backtrace; + cmCompiledGeneratorExpression *CompiledExpression; +}; + +class cmCompiledGeneratorExpression +{ +public: + const char* Evaluate(cmMakefile* mf, const char* config, + bool quiet = false) const; /** Get set of targets found during evaluations. */ std::set const& GetTargets() const { return this->Targets; } + + ~cmCompiledGeneratorExpression(); + private: - cmMakefile* Makefile; - const char* Config; + cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, + const std::vector &evaluators, + const char *input, bool needsParsing); + + friend class cmGeneratorExpression; + + cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &); + void operator=(const cmCompiledGeneratorExpression &); + cmListFileBacktrace const& Backtrace; - bool Quiet; - std::vector Data; - std::stack Barriers; - cmsys::RegularExpression TargetInfo; - cmsys::RegularExpression TestConfig; - std::set Targets; - bool Evaluate(); - bool Evaluate(const char* expr, std::string& result); - bool EvaluateTargetInfo(std::string& result); + const std::vector Evaluators; + const char* const Input; + const bool NeedsParsing; + + mutable std::set Targets; + mutable std::string Output; }; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx new file mode 100644 index 000000000..acc844a39 --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -0,0 +1,568 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 "cmMakefile.h" + +#include "cmGeneratorExpressionEvaluator.h" +#include "cmGeneratorExpressionParser.h" + +//---------------------------------------------------------------------------- +static void reportError(cmGeneratorExpressionContext *context, + const std::string &expr, const std::string &result) +{ + context->HadError = true; + if (context->Quiet) + { + return; + } + + cmOStringStream e; + e << "Error evaluating generator expression:\n" + << " " << expr << "\n" + << result; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), + context->Backtrace); +} + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionNode +{ + virtual ~cmGeneratorExpressionNode() {} + + virtual bool GeneratesContent() const { return true; } + + virtual bool AcceptsSingleArbitraryContentParameter() const + { return false; } + + virtual int NumExpectedParameters() const { return 1; } + + virtual std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content + ) const = 0; +}; + +//---------------------------------------------------------------------------- +static const struct ZeroNode : public cmGeneratorExpressionNode +{ + ZeroNode() {} + + virtual bool GeneratesContent() const { return false; } + + std::string Evaluate(const std::vector &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *) const + { + // Unreachable + return std::string(); + } +} zeroNode; + +//---------------------------------------------------------------------------- +static const struct OneNode : public cmGeneratorExpressionNode +{ + OneNode() {} + + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *) const + { + // Unreachable + return std::string(); + } +} oneNode; + +//---------------------------------------------------------------------------- +#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ +static const struct OP ## Node : public cmGeneratorExpressionNode \ +{ \ + OP ## Node () {} \ +/* We let -1 carry the meaning 'at least one' */ \ + virtual int NumExpectedParameters() const { return -1; } \ + \ + std::string Evaluate(const std::vector ¶meters, \ + cmGeneratorExpressionContext *context, \ + const GeneratorExpressionContent *content) const \ + { \ + std::vector::const_iterator it = parameters.begin(); \ + const std::vector::const_iterator end = parameters.end(); \ + for ( ; it != end; ++it) \ + { \ + if (*it == #FAILURE_VALUE) \ + { \ + return #FAILURE_VALUE; \ + } \ + else if (*it != #SUCCESS_VALUE) \ + { \ + reportError(context, content->GetOriginalExpression(), \ + "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \ + return std::string(); \ + } \ + } \ + return #SUCCESS_VALUE; \ + } \ +} OPNAME; + +BOOLEAN_OP_NODE(andNode, AND, 1, 0) +BOOLEAN_OP_NODE(orNode, OR, 0, 1) + +#undef BOOLEAN_OP_NODE + +//---------------------------------------------------------------------------- +static const struct NotNode : public cmGeneratorExpressionNode +{ + NotNode() {} + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) const + { + if (*parameters.begin() != "0" && *parameters.begin() != "1") + { + reportError(context, content->GetOriginalExpression(), + "$ parameter must resolve to exactly one '0' or '1' value."); + return std::string(); + } + return *parameters.begin() == "0" ? "1" : "0"; + } +} notNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationNode : public cmGeneratorExpressionNode +{ + ConfigurationNode() {} + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector &, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *) const + { + return context->Config ? context->Config : ""; + } +} configurationNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationTestNode : public cmGeneratorExpressionNode +{ + ConfigurationTestNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) const + { + if (!context->Config) + { + return std::string(); + } + + cmsys::RegularExpression configValidator; + configValidator.compile("^[A-Za-z0-9_]*$"); + if (!configValidator.find(parameters.begin()->c_str())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + return *parameters.begin() == context->Config ? "1" : "0"; + } +} configurationTestNode; + +//---------------------------------------------------------------------------- +template +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The target soname file (.so.1). + if(target->IsDLLPlatform()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is not allowed " + "for DLL target platforms."); + return std::string(); + } + if(target->GetType() != cmTarget::SHARED_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is allowed only for " + "SHARED libraries."); + return std::string(); + } + std::string result = target->GetDirectory(context->Config); + result += "/"; + result += target->GetSOName(context->Config); + return result; + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The file used to link to the target (.so, .lib, .a). + if(!target->IsLinkable()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_LINKER_FILE is allowed only for libraries and " + "executables with ENABLE_EXPORTS."); + return std::string(); + } + return target->GetFullPath(context->Config, + target->HasImportLibrary()); + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *) + { + return target->GetFullPath(context->Config, false, true); + } +}; + + +//---------------------------------------------------------------------------- +template +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenameName(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenamePath(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result) + { return result; } +}; + +//---------------------------------------------------------------------------- +template +struct TargetFilesystemArtifact : public cmGeneratorExpressionNode +{ + TargetFilesystemArtifact() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) const + { + // Lookup the referenced target. + std::string name = *parameters.begin(); + + cmsys::RegularExpression targetValidator; + targetValidator.compile("^[A-Za-z0-9_]+$"); + if (!targetValidator.find(name.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + cmTarget* target = context->Makefile->FindTargetToUse(name.c_str()); + if(!target) + { + ::reportError(context, content->GetOriginalExpression(), + "No target \"" + name + "\""); + return std::string(); + } + if(target->GetType() >= cmTarget::UTILITY && + target->GetType() != cmTarget::UNKNOWN_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "Target \"" + name + "\" is not an executable or library."); + return std::string(); + } + context->Targets.insert(target); + + std::string result = + TargetFilesystemArtifactResultCreator::Create( + target, + context, + content); + if (context->HadError) + { + return std::string(); + } + return + TargetFilesystemArtifactResultGetter::Get(result); + } +}; + +//---------------------------------------------------------------------------- +static const +TargetFilesystemArtifact targetFileNode; +static const +TargetFilesystemArtifact targetLinkerFileNode; +static const +TargetFilesystemArtifact targetSoNameFileNode; +static const +TargetFilesystemArtifact targetFileNameNode; +static const +TargetFilesystemArtifact targetLinkerFileNameNode; +static const +TargetFilesystemArtifact targetSoNameFileNameNode; +static const +TargetFilesystemArtifact targetFileDirNode; +static const +TargetFilesystemArtifact targetLinkerFileDirNode; +static const +TargetFilesystemArtifact targetSoNameFileDirNode; + +//---------------------------------------------------------------------------- +static const +cmGeneratorExpressionNode* GetNode(const std::string &identifier) +{ + if (identifier == "0") + return &zeroNode; + if (identifier == "1") + return &oneNode; + if (identifier == "AND") + return &andNode; + if (identifier == "OR") + return &orNode; + if (identifier == "NOT") + return ¬Node; + else if (identifier == "CONFIGURATION") + return &configurationNode; + else if (identifier == "CONFIG") + return &configurationTestNode; + else if (identifier == "TARGET_FILE") + return &targetFileNode; + else if (identifier == "TARGET_LINKER_FILE") + return &targetLinkerFileNode; + else if (identifier == "TARGET_SONAME_FILE") + return &targetSoNameFileNode; + else if (identifier == "TARGET_FILE_NAME") + return &targetFileNameNode; + else if (identifier == "TARGET_LINKER_FILE_NAME") + return &targetLinkerFileNameNode; + else if (identifier == "TARGET_SONAME_FILE_NAME") + return &targetSoNameFileNameNode; + else if (identifier == "TARGET_FILE_DIR") + return &targetFileDirNode; + else if (identifier == "TARGET_LINKER_FILE_DIR") + return &targetLinkerFileDirNode; + else if (identifier == "TARGET_SONAME_FILE_DIR") + return &targetSoNameFileDirNode; + return 0; +} + +//---------------------------------------------------------------------------- +GeneratorExpressionContent::GeneratorExpressionContent( + const char *startContent, + unsigned int length) + : StartContent(startContent), ContentLength(length) +{ + +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::GetOriginalExpression() const +{ + return std::string(this->StartContent, this->ContentLength); +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::Evaluate( + cmGeneratorExpressionContext *context) const +{ + std::string identifier; + { + std::vector::const_iterator it + = this->IdentifierChildren.begin(); + const std::vector::const_iterator end + = this->IdentifierChildren.end(); + for ( ; it != end; ++it) + { + identifier += (*it)->Evaluate(context); + if (context->HadError) + { + return std::string(); + } + } + } + + const cmGeneratorExpressionNode *node = GetNode(identifier); + + if (!node) + { + reportError(context, this->GetOriginalExpression(), + "Expression did not evaluate to a known generator expression"); + return std::string(); + } + + if (!node->GeneratesContent()) + { + return std::string(); + } + + if (node->AcceptsSingleArbitraryContentParameter()) + { + std::string result; + std::vector >::const_iterator + pit = this->ParamChildren.begin(); + const + std::vector >::const_iterator + pend = this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + if (!result.empty()) + { + result += ","; + } + + std::vector::const_iterator it + = pit->begin(); + const std::vector::const_iterator end + = pit->end(); + for ( ; it != end; ++it) + { + result += (*it)->Evaluate(context); + if (context->HadError) + { + return std::string(); + } + } + } + return result; + } + + std::vector parameters; + { + std::vector >::const_iterator + pit = this->ParamChildren.begin(); + const + std::vector >::const_iterator + pend = this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + std::string parameter; + std::vector::const_iterator it = + pit->begin(); + const std::vector::const_iterator end = + pit->end(); + for ( ; it != end; ++it) + { + parameter += (*it)->Evaluate(context); + if (context->HadError) + { + return std::string(); + } + } + parameters.push_back(parameter); + } + } + + int numExpected = node->NumExpectedParameters(); + if ((numExpected != -1 && (unsigned int)numExpected != parameters.size())) + { + if (numExpected == 0) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires no parameters."); + } + else if (numExpected == 1) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires " + "exactly one parameter."); + } + else + { + cmOStringStream e; + e << "$<" + identifier + "> expression requires " + << numExpected + << " comma separated parameters, but got " + << parameters.size() << " instead."; + reportError(context, this->GetOriginalExpression(), e.str()); + } + return std::string(); + } + + if (numExpected == -1 && parameters.empty()) + { + reportError(context, this->GetOriginalExpression(), "$<" + identifier + + "> expression requires at least one parameter."); + return std::string(); + } + + return node->Evaluate(parameters, context, this); +} + +//---------------------------------------------------------------------------- +static void deleteAll(const std::vector &c) +{ + std::vector::const_iterator it + = c.begin(); + const std::vector::const_iterator end + = c.end(); + for ( ; it != end; ++it) + { + delete *it; + } +} + +//---------------------------------------------------------------------------- +GeneratorExpressionContent::~GeneratorExpressionContent() +{ + deleteAll(this->IdentifierChildren); + + typedef std::vector EvaluatorVector; + typedef std::vector TokenVector; + std::vector::const_iterator pit = + this->ParamChildren.begin(); + const std::vector::const_iterator pend = + this->ParamChildren.end(); + for ( ; pit != pend; ++pit) + { + deleteAll(*pit); + } +} diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h new file mode 100644 index 000000000..5163ca002 --- /dev/null +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -0,0 +1,118 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 cmGeneratorExpressionEvaluator_h +#define cmGeneratorExpressionEvaluator_h + +#include +#include + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionContext +{ + cmListFileBacktrace Backtrace; + std::set Targets; + cmMakefile *Makefile; + const char *Config; + cmTarget *Target; + bool Quiet; + bool HadError; +}; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionEvaluator +{ + cmGeneratorExpressionEvaluator() {} + virtual ~cmGeneratorExpressionEvaluator() {} + + enum Type + { + Text, + Generator + }; + + virtual Type GetType() const = 0; + + virtual std::string Evaluate(cmGeneratorExpressionContext *context + ) const = 0; + +private: + cmGeneratorExpressionEvaluator(const cmGeneratorExpressionEvaluator &); + void operator=(const cmGeneratorExpressionEvaluator &); +}; + +struct TextContent : public cmGeneratorExpressionEvaluator +{ + TextContent(const char *start, unsigned int length) + : Content(start), Length(length) + { + + } + + std::string Evaluate(cmGeneratorExpressionContext *) const + { + return std::string(this->Content, this->Length); + } + + Type GetType() const + { + return cmGeneratorExpressionEvaluator::Text; + } + + void Extend(unsigned int length) + { + this->Length += length; + } + + unsigned int GetLength() + { + return this->Length; + } + +private: + const char *Content; + unsigned int Length; +}; + +//---------------------------------------------------------------------------- +struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator +{ + GeneratorExpressionContent(const char *startContent, unsigned int length); + void SetIdentifier(std::vector identifier) + { + this->IdentifierChildren = identifier; + } + + void SetParameters( + std::vector > parameters) + { + this->ParamChildren = parameters; + } + + Type GetType() const + { + return cmGeneratorExpressionEvaluator::Generator; + } + + std::string Evaluate(cmGeneratorExpressionContext *context) const; + + std::string GetOriginalExpression() const; + + ~GeneratorExpressionContent(); + +private: + std::vector IdentifierChildren; + std::vector > ParamChildren; + const char *StartContent; + unsigned int ContentLength; +}; + +#endif diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx new file mode 100644 index 000000000..cd71ec033 --- /dev/null +++ b/Source/cmGeneratorExpressionLexer.cxx @@ -0,0 +1,85 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 "cmGeneratorExpressionLexer.h" + + +//---------------------------------------------------------------------------- +cmGeneratorExpressionLexer::cmGeneratorExpressionLexer() + : SawBeginExpression(false), SawGeneratorExpression(false) +{ + +} + +//---------------------------------------------------------------------------- +static void InsertText(const char *upto, const char *c, + std::vector &result) +{ + if (upto != c) + { + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::Text, upto, c - upto)); + } +} + +//---------------------------------------------------------------------------- +std::vector +cmGeneratorExpressionLexer::Tokenize(const char *input) +{ + std::vector result; + if (!input) + return result; + + const char *c = input; + const char *upto = c; + + for ( ; *c; ++c) + { + if(c[0] == '$' && c[1] == '<') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::BeginExpression, upto, 2)); + upto = c + 2; + ++c; + SawBeginExpression = true; + } + else if(c[0] == '>') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::EndExpression, upto, 1)); + upto = c + 1; + SawGeneratorExpression = SawBeginExpression; + } + else if(c[0] == ':') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::ColonSeparator, upto, 1)); + upto = c + 1; + } + else if(c[0] == ',') + { + InsertText(upto, c, result); + upto = c; + result.push_back(cmGeneratorExpressionToken( + cmGeneratorExpressionToken::CommaSeparator, upto, 1)); + upto = c + 1; + } + } + InsertText(upto, c, result); + + return result; +} diff --git a/Source/cmGeneratorExpressionLexer.h b/Source/cmGeneratorExpressionLexer.h new file mode 100644 index 000000000..5f16712fb --- /dev/null +++ b/Source/cmGeneratorExpressionLexer.h @@ -0,0 +1,58 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 cmGeneratorExpressionLexer_h +#define cmGeneratorExpressionLexer_h + +#include "cmStandardIncludes.h" + +#include + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionToken +{ + cmGeneratorExpressionToken(unsigned type, const char *c, unsigned l) + : TokenType(type), Content(c), Length(l) + { + } + enum { + Text, + BeginExpression, + EndExpression, + ColonSeparator, + CommaSeparator + }; + unsigned TokenType; + const char *Content; + unsigned Length; +}; + +/** \class cmGeneratorExpressionLexer + * + */ +class cmGeneratorExpressionLexer +{ +public: + cmGeneratorExpressionLexer(); + + std::vector Tokenize(const char *input); + + bool GetSawGeneratorExpression() const + { + return this->SawGeneratorExpression; + } + +private: + bool SawBeginExpression; + bool SawGeneratorExpression; +}; + +#endif diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx new file mode 100644 index 000000000..2a5cc7aae --- /dev/null +++ b/Source/cmGeneratorExpressionParser.cxx @@ -0,0 +1,235 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 "cmGeneratorExpressionParser.h" + +#include "cmGeneratorExpressionEvaluator.h" + +//---------------------------------------------------------------------------- +cmGeneratorExpressionParser::cmGeneratorExpressionParser( + const std::vector &tokens) + : Tokens(tokens), NestingLevel(0) +{ +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::Parse( + std::vector &result) +{ + it = this->Tokens.begin(); + + while (this->it != this->Tokens.end()) + { + this->ParseContent(result); + } +} + +//---------------------------------------------------------------------------- +static void extendText(std::vector &result, + std::vector::const_iterator it) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast(*(result.end() - 1)); + textContent->Extend(it->Length); + } + else + { + TextContent *textContent = new TextContent(it->Content, it->Length); + result.push_back(textContent); + } +} + +//---------------------------------------------------------------------------- +static void extendResult(std::vector &result, + const std::vector &contents) +{ + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text + && (*contents.begin())->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + TextContent *textContent = static_cast(*(result.end() - 1)); + textContent->Extend( + static_cast(*contents.begin())->GetLength()); + delete *contents.begin(); + result.insert(result.end(), contents.begin() + 1, contents.end()); + } else { + result.insert(result.end(), contents.begin(), contents.end()); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseGeneratorExpression( + std::vector &result) +{ + unsigned int nestedLevel = this->NestingLevel; + ++this->NestingLevel; + + std::vector::const_iterator startToken + = this->it - 1; + + std::vector identifier; + while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression + && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) + { + this->ParseContent(identifier); + if (this->it == this->Tokens.end()) + { + break; + } + } + if (identifier.empty()) + { + // ERROR + } + + if (this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + { + GeneratorExpressionContent *content = new GeneratorExpressionContent( + startToken->Content, this->it->Content + - startToken->Content + + this->it->Length); + ++this->it; + --this->NestingLevel; + content->SetIdentifier(identifier); + result.push_back(content); + return; + } + + std::vector > parameters; + std::vector::const_iterator> + commaTokens; + std::vector::const_iterator colonToken; + if (this->it->TokenType == cmGeneratorExpressionToken::ColonSeparator) + { + colonToken = this->it; + parameters.resize(parameters.size() + 1); + ++this->it; + while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression) + { + this->ParseContent(*(parameters.end() - 1)); + if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + { + commaTokens.push_back(this->it); + parameters.resize(parameters.size() + 1); + ++this->it; + } + if (this->it == this->Tokens.end()) + { + break; + } + } + if(this->it->TokenType == cmGeneratorExpressionToken::EndExpression) + { + --this->NestingLevel; + ++this->it; + } + if (parameters.empty()) + { + // ERROR + } + } + + if (nestedLevel != this->NestingLevel) + { + // There was a '$<' in the text, but no corresponding '>'. Rebuild to + // treat the '$<' as having been plain text, along with the + // corresponding : and , tokens that might have been found. + extendText(result, startToken); + extendResult(result, identifier); + if (!parameters.empty()) + { + extendText(result, colonToken); + + typedef std::vector EvaluatorVector; + typedef std::vector TokenVector; + std::vector::const_iterator pit = parameters.begin(); + const std::vector::const_iterator pend = + parameters.end(); + std::vector::const_iterator commaIt = + commaTokens.begin(); + for ( ; pit != pend; ++pit, ++commaIt) + { + extendResult(result, *pit); + if (commaIt != commaTokens.end()) + { + extendText(result, *commaIt); + } + } + } + return; + } + + int contentLength = ((this->it - 1)->Content + - startToken->Content) + + (this->it - 1)->Length; + GeneratorExpressionContent *content = new GeneratorExpressionContent( + startToken->Content, contentLength); + content->SetIdentifier(identifier); + content->SetParameters(parameters); + result.push_back(content); +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionParser::ParseContent( + std::vector &result) +{ + switch(this->it->TokenType) + { + case cmGeneratorExpressionToken::Text: + { + if (this->NestingLevel == 0) + { + if (result.size() > 0 + && (*(result.end() - 1))->GetType() + == cmGeneratorExpressionEvaluator::Text) + { + // A comma in 'plain text' could have split text that should + // otherwise be continuous. Extend the last text content instead of + // creating a new one. + TextContent *textContent = + static_cast(*(result.end() - 1)); + textContent->Extend(this->it->Length); + ++this->it; + return; + } + } + cmGeneratorExpressionEvaluator* n = new TextContent(this->it->Content, + this->it->Length); + result.push_back(n); + ++this->it; + return ; + } + case cmGeneratorExpressionToken::BeginExpression: + ++this->it; + this->ParseGeneratorExpression(result); + return; + case cmGeneratorExpressionToken::EndExpression: + case cmGeneratorExpressionToken::ColonSeparator: + case cmGeneratorExpressionToken::CommaSeparator: + if (this->NestingLevel == 0) + { + extendText(result, this->it); + } + else + { + // TODO: Unreachable. Assert? + } + ++this->it; + return; + } + // Unreachable. Assert? +} diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h new file mode 100644 index 000000000..28f14410f --- /dev/null +++ b/Source/cmGeneratorExpressionParser.h @@ -0,0 +1,45 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + 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 cmGeneratorExpressionParser_h +#define cmGeneratorExpressionParser_h + +#include "cmGeneratorExpressionLexer.h" + +#include +#include + +#include "cmListFileCache.h" + +class cmMakefile; +class cmTarget; +struct cmGeneratorExpressionEvaluator; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionParser +{ + cmGeneratorExpressionParser( + const std::vector &tokens); + + void Parse(std::vector &result); + +private: + void ParseContent(std::vector &); + void ParseGeneratorExpression( + std::vector &); + +private: + std::vector::const_iterator it; + const std::vector Tokens; + unsigned int NestingLevel; +}; + +#endif diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 6e2e23da5..db88834b9 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -14,9 +14,12 @@ #include "cmTarget.h" #include "cmMakefile.h" #include "cmLocalGenerator.h" +#include "cmComputeLinkInformation.h" #include "cmGlobalGenerator.h" #include "cmSourceFile.h" +#include + //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) { @@ -27,6 +30,45 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) this->LookupObjectLibraries(); } +cmGeneratorTarget::~cmGeneratorTarget() +{ + for(std::map::iterator i + = LinkInformation.begin(); i != LinkInformation.end(); ++i) + { + delete i->second; + } +} + +//---------------------------------------------------------------------------- +int cmGeneratorTarget::GetType() const +{ + return this->Target->GetType(); +} + +//---------------------------------------------------------------------------- +const char *cmGeneratorTarget::GetName() const +{ + return this->Target->GetName(); +} + +//---------------------------------------------------------------------------- +const char *cmGeneratorTarget::GetProperty(const char *prop) +{ + return this->Target->GetProperty(prop); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::GetPropertyAsBool(const char *prop) +{ + return this->Target->GetPropertyAsBool(prop); +} + +//---------------------------------------------------------------------------- +std::vector const& cmGeneratorTarget::GetSourceFiles() +{ + return this->Target->GetSourceFiles(); +} + //---------------------------------------------------------------------------- void cmGeneratorTarget::ClassifySources() { @@ -175,3 +217,179 @@ void cmGeneratorTarget::UseObjectLibraries(std::vector& objs) } } } + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GenerateTargetManifest(const char* config) +{ + cmMakefile* mf = this->Target->GetMakefile(); + cmLocalGenerator* lg = mf->GetLocalGenerator(); + cmGlobalGenerator* gg = lg->GetGlobalGenerator(); + + // Get the names. + std::string name; + std::string soName; + std::string realName; + std::string impName; + std::string pdbName; + if(this->GetType() == cmTarget::EXECUTABLE) + { + this->Target->GetExecutableNames(name, realName, impName, pdbName, + config); + } + else if(this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY) + { + this->Target->GetLibraryNames(name, soName, realName, impName, pdbName, + config); + } + else + { + return; + } + + // Get the directory. + std::string dir = this->Target->GetDirectory(config, false); + + // Add each name. + std::string f; + if(!name.empty()) + { + f = dir; + f += "/"; + f += name; + gg->AddToManifest(config? config:"", f); + } + if(!soName.empty()) + { + f = dir; + f += "/"; + f += soName; + gg->AddToManifest(config? config:"", f); + } + if(!realName.empty()) + { + f = dir; + f += "/"; + f += realName; + gg->AddToManifest(config? config:"", f); + } + if(!pdbName.empty()) + { + f = dir; + f += "/"; + f += pdbName; + gg->AddToManifest(config? config:"", f); + } + if(!impName.empty()) + { + f = this->Target->GetDirectory(config, true); + f += "/"; + f += impName; + gg->AddToManifest(config? config:"", f); + } +} + +//---------------------------------------------------------------------------- +cmComputeLinkInformation* +cmGeneratorTarget::GetLinkInformation(const char* config) +{ + // Lookup any existing information for this configuration. + std::map::iterator + i = this->LinkInformation.find(config?config:""); + if(i == this->LinkInformation.end()) + { + // Compute information for this configuration. + cmComputeLinkInformation* info = + new cmComputeLinkInformation(this->Target, config); + if(!info || !info->Compute()) + { + delete info; + info = 0; + } + + // Store the information for this configuration. + std::map::value_type + entry(config?config:"", info); + i = this->LinkInformation.insert(entry).first; + } + return i->second; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetAppleArchs(const char* config, + std::vector& archVec) +{ + const char* archs = 0; + if(config && *config) + { + std::string defVarName = "OSX_ARCHITECTURES_"; + defVarName += cmSystemTools::UpperCase(config); + archs = this->Target->GetProperty(defVarName.c_str()); + } + if(!archs) + { + archs = this->Target->GetProperty("OSX_ARCHITECTURES"); + } + if(archs) + { + cmSystemTools::ExpandListArgument(std::string(archs), archVec); + } +} + +//---------------------------------------------------------------------------- +const char* cmGeneratorTarget::GetCreateRuleVariable() +{ + switch(this->GetType()) + { + case cmTarget::STATIC_LIBRARY: + return "_CREATE_STATIC_LIBRARY"; + case cmTarget::SHARED_LIBRARY: + return "_CREATE_SHARED_LIBRARY"; + case cmTarget::MODULE_LIBRARY: + return "_CREATE_SHARED_MODULE"; + case cmTarget::EXECUTABLE: + return "_LINK_EXECUTABLE"; + default: + break; + } + return ""; +} + +//---------------------------------------------------------------------------- +std::vector cmGeneratorTarget::GetIncludeDirectories() +{ + std::vector includes; + const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES"); + if(prop) + { + cmSystemTools::ExpandListArgument(prop, includes); + } + + std::set uniqueIncludes; + std::vector orderedAndUniqueIncludes; + for(std::vector::const_iterator + li = includes.begin(); li != includes.end(); ++li) + { + if(uniqueIncludes.insert(*li).second) + { + orderedAndUniqueIncludes.push_back(*li); + } + } + + return orderedAndUniqueIncludes; +} + +//---------------------------------------------------------------------------- +const char *cmGeneratorTarget::GetCompileDefinitions(const char *config) +{ + if (!config) + { + return this->Target->GetProperty("COMPILE_DEFINITIONS"); + } + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += + cmSystemTools::UpperCase(config); + + return this->Target->GetProperty(defPropName.c_str()); +} diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 5c7578d94..060e25a8b 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,6 +14,7 @@ #include "cmStandardIncludes.h" +class cmComputeLinkInformation; class cmCustomCommand; class cmGlobalGenerator; class cmLocalGenerator; @@ -25,6 +26,13 @@ class cmGeneratorTarget { public: cmGeneratorTarget(cmTarget*); + ~cmGeneratorTarget(); + + int GetType() const; + const char *GetName() const; + const char *GetProperty(const char *prop); + bool GetPropertyAsBool(const char *prop); + std::vector const& GetSourceFiles(); cmTarget* Target; cmMakefile* Makefile; @@ -52,6 +60,25 @@ public: void UseObjectLibraries(std::vector& objs); + /** Add the target output files to the global generator manifest. */ + void GenerateTargetManifest(const char* config); + + std::map LinkInformation; + + cmComputeLinkInformation* GetLinkInformation(const char* config); + + void GetAppleArchs(const char* config, + std::vector& archVec); + + ///! Return the rule variable used to create this type of target, + // need to add CMAKE_(LANG) for full name. + const char* GetCreateRuleVariable(); + + /** Get the include directories for this target. */ + std::vector GetIncludeDirectories(); + + const char *GetCompileDefinitions(const char *config = 0); + private: void ClassifySources(); void LookupObjectLibraries(); @@ -60,4 +87,6 @@ private: void operator=(cmGeneratorTarget const&); }; +typedef std::map cmGeneratorTargetsType; + #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 83a8641af..bdd34612e 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1075,23 +1075,46 @@ void cmGlobalGenerator::CreateGeneratorTargets() // Construct per-target generator information. for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { - cmTargets& targets = - this->LocalGenerators[i]->GetMakefile()->GetTargets(); + cmGeneratorTargetsType generatorTargets; + + cmMakefile *mf = this->LocalGenerators[i]->GetMakefile(); + const char *noconfig_compile_definitions = + mf->GetProperty("COMPILE_DEFINITIONS"); + + std::vector configs; + mf->GetConfigurations(configs); + + cmTargets& targets = mf->GetTargets(); for(cmTargets::iterator ti = targets.begin(); ti != targets.end(); ++ti) { cmTarget* t = &ti->second; + + { + t->AppendProperty("COMPILE_DEFINITIONS", noconfig_compile_definitions); + for(std::vector::const_iterator ci = configs.begin(); + ci != configs.end(); ++ci) + { + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += cmSystemTools::UpperCase(*ci); + t->AppendProperty(defPropName.c_str(), + mf->GetProperty(defPropName.c_str())); + } + } + cmGeneratorTarget* gt = new cmGeneratorTarget(t); this->GeneratorTargets[t] = gt; this->ComputeTargetObjects(gt); + generatorTargets[t] = gt; } + mf->SetGeneratorTargets(generatorTargets); } } //---------------------------------------------------------------------------- void cmGlobalGenerator::ClearGeneratorTargets() { - for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); + for(cmGeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); i != this->GeneratorTargets.end(); ++i) { delete i->second; @@ -1102,7 +1125,7 @@ void cmGlobalGenerator::ClearGeneratorTargets() //---------------------------------------------------------------------------- cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const { - GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t); + cmGeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t); if(ti == this->GeneratorTargets.end()) { this->CMakeInstance->IssueMessage( @@ -1129,13 +1152,13 @@ void cmGlobalGenerator::CheckLocalGenerators() { manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); this->LocalGenerators[i]->ConfigureFinalPass(); - cmTargets & targets = - this->LocalGenerators[i]->GetMakefile()->GetTargets(); - for (cmTargets::iterator l = targets.begin(); + cmGeneratorTargetsType targets = + this->LocalGenerators[i]->GetMakefile()->GetGeneratorTargets(); + for (cmGeneratorTargetsType::iterator l = targets.begin(); l != targets.end(); l++) { const cmTarget::LinkLibraryVectorType& libs = - l->second.GetOriginalLinkLibraries(); + l->second->Target->GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin(); lib != libs.end(); ++lib) { @@ -1151,14 +1174,14 @@ void cmGlobalGenerator::CheckLocalGenerators() } std::string text = notFoundMap[varName]; text += "\n linked by target \""; - text += l->second.GetName(); + text += l->second->GetName(); text += "\" in directory "; text+=this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory(); notFoundMap[varName] = text; } } std::vector incs; - this->LocalGenerators[i]->GetIncludeDirectories(incs, &l->second); + this->LocalGenerators[i]->GetIncludeDirectories(incs, l->second); for( std::vector::const_iterator incDir = incs.begin(); incDir != incs.end(); ++incDir) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 71c3a4d80..0aab2d63e 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -19,6 +19,8 @@ #include "cmTargetDepend.h" // For cmTargetDependSet #include "cmSystemTools.h" // for cmSystemTools::OutputOption #include "cmExportSetMap.h" // For cmExportSetMap +#include "cmGeneratorTarget.h" + class cmake; class cmGeneratorTarget; class cmMakefile; @@ -372,8 +374,7 @@ private: TargetDependMap TargetDependencies; // Per-target generator information. - typedef std::map GeneratorTargetsType; - GeneratorTargetsType GeneratorTargets; + cmGeneratorTargetsType GeneratorTargets; void CreateGeneratorTargets(); void ClearGeneratorTargets(); virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; diff --git a/Source/cmGlobalVisualStudio8Win64Generator.cxx b/Source/cmGlobalVisualStudio8Win64Generator.cxx index 60e45b840..164d11636 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio8Win64Generator.cxx @@ -22,17 +22,6 @@ cmGlobalVisualStudio8Win64Generator::cmGlobalVisualStudio8Win64Generator() this->ArchitectureId = "x64"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio8Win64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg - = new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS8); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio8Win64Generator ::GetDocumentation(cmDocumentationEntry& entry) const diff --git a/Source/cmGlobalVisualStudio8Win64Generator.h b/Source/cmGlobalVisualStudio8Win64Generator.h index 136cdb8b4..12f80125a 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.h +++ b/Source/cmGlobalVisualStudio8Win64Generator.h @@ -38,9 +38,6 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalVisualStudio9IA64Generator.cxx b/Source/cmGlobalVisualStudio9IA64Generator.cxx index 993340ae8..38dbfacc4 100644 --- a/Source/cmGlobalVisualStudio9IA64Generator.cxx +++ b/Source/cmGlobalVisualStudio9IA64Generator.cxx @@ -19,17 +19,6 @@ cmGlobalVisualStudio9IA64Generator::cmGlobalVisualStudio9IA64Generator() this->ArchitectureId = "Itanium"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio9IA64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio9IA64Generator ::GetDocumentation(cmDocumentationEntry& entry) const diff --git a/Source/cmGlobalVisualStudio9IA64Generator.h b/Source/cmGlobalVisualStudio9IA64Generator.h index e33ee1550..989b0d1af 100644 --- a/Source/cmGlobalVisualStudio9IA64Generator.h +++ b/Source/cmGlobalVisualStudio9IA64Generator.h @@ -38,9 +38,6 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalVisualStudio9Win64Generator.cxx b/Source/cmGlobalVisualStudio9Win64Generator.cxx index 08f537d1a..4d8a6463b 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio9Win64Generator.cxx @@ -19,17 +19,6 @@ cmGlobalVisualStudio9Win64Generator::cmGlobalVisualStudio9Win64Generator() this->ArchitectureId = "x64"; } -///! Create a local generator appropriate to this Global Generator -cmLocalGenerator *cmGlobalVisualStudio9Win64Generator::CreateLocalGenerator() -{ - cmLocalVisualStudio7Generator *lg = - new cmLocalVisualStudio7Generator(cmLocalVisualStudioGenerator::VS9); - lg->SetPlatformName(this->GetPlatformName()); - lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); - lg->SetGlobalGenerator(this); - return lg; -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio9Win64Generator ::GetDocumentation(cmDocumentationEntry& entry) const diff --git a/Source/cmGlobalVisualStudio9Win64Generator.h b/Source/cmGlobalVisualStudio9Win64Generator.h index 0ce1afe3d..7c20cf4e2 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.h +++ b/Source/cmGlobalVisualStudio9Win64Generator.h @@ -38,9 +38,6 @@ public: /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; - ///! create the correct local generator - virtual cmLocalGenerator *CreateLocalGenerator(); - /** * Try to determine system infomation such as shared library * extension, pthreads, byte order etc. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index e8ab38fe1..f9a1503d5 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1713,7 +1713,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // Set target-specific architectures. std::vector archs; - target.GetAppleArchs(configName, archs); + { + cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); + gtgt->GetAppleArchs(configName, archs); + } if(!archs.empty()) { // Enable ARCHS attribute. @@ -1950,7 +1953,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, BuildObjectListOrString dirs(this, this->XcodeVersion >= 30); BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30); std::vector includes; - this->CurrentLocalGenerator->GetIncludeDirectories(includes, &target); + cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); + this->CurrentLocalGenerator->GetIncludeDirectories(includes, gtgt); std::set emitted; emitted.insert("/System/Library/Frameworks"); for(std::vector::iterator i = includes.begin(); @@ -2625,7 +2629,8 @@ void cmGlobalXCodeGenerator } // Compute the link library and directory information. - cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName); + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget); + cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName); if(!pcli) { continue; diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index ffc0f35b8..56d717031 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -409,14 +409,18 @@ namespace enum Op { OpLess, OpEqual, OpGreater }; bool HandleVersionCompare(Op op, const char* lhs_str, const char* rhs_str) { - // Parse out up to 4 components. - unsigned int lhs[4] = {0,0,0,0}; - unsigned int rhs[4] = {0,0,0,0}; - sscanf(lhs_str, "%u.%u.%u.%u", &lhs[0], &lhs[1], &lhs[2], &lhs[3]); - sscanf(rhs_str, "%u.%u.%u.%u", &rhs[0], &rhs[1], &rhs[2], &rhs[3]); + // Parse out up to 8 components. + unsigned int lhs[8] = {0,0,0,0,0,0,0,0}; + unsigned int rhs[8] = {0,0,0,0,0,0,0,0}; + sscanf(lhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", + &lhs[0], &lhs[1], &lhs[2], &lhs[3], + &lhs[4], &lhs[5], &lhs[6], &lhs[7]); + sscanf(rhs_str, "%u.%u.%u.%u.%u.%u.%u.%u", + &rhs[0], &rhs[1], &rhs[2], &rhs[3], + &rhs[4], &rhs[5], &rhs[6], &rhs[7]); // Do component-wise comparison. - for(unsigned int i=0; i < 4; ++i) + for(unsigned int i=0; i < 8; ++i) { if(lhs[i] < rhs[i]) { diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 5f9b6585e..347ad3ec5 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -16,6 +16,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmake.h" +#include "cmGeneratorTarget.h" #include @@ -26,7 +27,8 @@ cmInstallTargetGenerator std::vector const& configurations, const char* component, bool optional): cmInstallGenerator(dest, configurations, component), Target(&t), - ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) + ImportLibrary(implib), FilePermissions(file_permissions), + Optional(optional), GeneratorTarget(0) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; @@ -484,6 +486,17 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os, this->AddStripRule(os, indent, file); } +void cmInstallTargetGenerator::CreateGeneratorTarget() +{ + if (!this->GeneratorTarget) + { + this->GeneratorTarget = this->Target->GetMakefile() + ->GetLocalGenerator() + ->GetGlobalGenerator() + ->GetGeneratorTarget(this->Target); + } +} + //---------------------------------------------------------------------------- void cmInstallTargetGenerator @@ -507,10 +520,13 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Build a map of build-tree install_name to install-tree install_name for // shared libraries linked to this target. std::map install_name_remap; - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config)) { std::set const& sharedLibs = cli->GetSharedLibrariesLinked(); for(std::set::const_iterator j = sharedLibs.begin(); @@ -608,9 +624,12 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); + cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config); if(!cli) { return; @@ -639,9 +658,12 @@ cmInstallTargetGenerator return; } + this->CreateGeneratorTarget(); + // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); + cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(config); if(!cli) { return; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 5d158b8d0..cab3e9065 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -15,6 +15,8 @@ #include "cmInstallGenerator.h" #include "cmTarget.h" +class cmGeneratorTarget; + /** \class cmInstallTargetGenerator * \brief Generate target installation rules. */ @@ -92,11 +94,14 @@ protected: void AddRanlibRule(std::ostream& os, Indent const& indent, const std::string& toDestDirPath); + void CreateGeneratorTarget(); + cmTarget* Target; bool ImportLibrary; std::string FilePermissions; bool Optional; NamelinkModeType NamelinkMode; + cmGeneratorTarget* GeneratorTarget; }; #endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index cf2af0a4f..662f87666 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -533,10 +533,11 @@ void cmLocalGenerator::GenerateTargetManifest() this->Makefile->GetConfigurations(configNames); // Add our targets to the manifest for each configuration. - cmTargets& targets = this->Makefile->GetTargets(); - for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) + cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets(); + for(cmGeneratorTargetsType::iterator t = targets.begin(); + t != targets.end(); ++t) { - cmTarget& target = t->second; + cmGeneratorTarget& target = *t->second; if(configNames.empty()) { target.GenerateTargetManifest(0); @@ -554,9 +555,9 @@ void cmLocalGenerator::GenerateTargetManifest() } void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, - const char* lang, - cmSourceFile& source, - cmTarget& target) + const char* lang, + cmSourceFile& source, + cmGeneratorTarget& target) { std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname)); objectDir = this->Convert(objectDir.c_str(),START_OUTPUT,SHELL); @@ -635,7 +636,8 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, ); } -void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) +void cmLocalGenerator::AddBuildTargetRule(const char* llang, + cmGeneratorTarget& target) { cmStdString objs; std::vector objVector; @@ -669,7 +671,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) std::string createRule = "CMAKE_"; createRule += llang; createRule += target.GetCreateRuleVariable(); - std::string targetName = target.GetFullName(); + std::string targetName = target.Target->GetFullName(); // Executable : // Shared Library: // Static Library: @@ -677,7 +679,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) std::string linkLibs; // should be set std::string flags; // should be set std::string linkFlags; // should be set - this->GetTargetFlags(linkLibs, flags, linkFlags, target); + this->GetTargetFlags(linkLibs, flags, linkFlags, &target); cmLocalGenerator::RuleVariables vars; vars.Language = llang; vars.Objects = objs.c_str(); @@ -714,7 +716,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) // Store this command line. commandLines.push_back(commandLine); } - std::string targetFullPath = target.GetFullPath(); + std::string targetFullPath = target.Target->GetFullPath(); // Generate a meaningful comment for the command. std::string comment = "Linking "; comment += llang; @@ -728,7 +730,7 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) comment.c_str(), this->Makefile->GetStartOutputDirectory() ); - target.AddSourceFile + target.Target->AddSourceFile (this->Makefile->GetSource(targetFullPath.c_str())); } @@ -736,11 +738,11 @@ void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target) void cmLocalGenerator ::CreateCustomTargetsAndCommands(std::set const& lang) { - cmTargets &tgts = this->Makefile->GetTargets(); - for(cmTargets::iterator l = tgts.begin(); + cmGeneratorTargetsType tgts = this->Makefile->GetGeneratorTargets(); + for(cmGeneratorTargetsType::iterator l = tgts.begin(); l != tgts.end(); l++) { - cmTarget& target = l->second; + cmGeneratorTarget& target = *l->second; switch(target.GetType()) { case cmTarget::STATIC_LIBRARY: @@ -748,12 +750,12 @@ void cmLocalGenerator case cmTarget::MODULE_LIBRARY: case cmTarget::EXECUTABLE: { - const char* llang = target.GetLinkerLanguage(); + const char* llang = target.Target->GetLinkerLanguage(); if(!llang) { cmSystemTools::Error ("CMake can not determine linker language for target:", - target.GetName()); + target.Target->GetName()); return; } // if the language is not in the set lang then create custom @@ -1318,7 +1320,7 @@ std::string cmLocalGenerator::GetIncludeFlags( //---------------------------------------------------------------------------- void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, - cmTarget* target, + cmGeneratorTarget* target, const char* lang) { // Need to decide whether to automatically include the source and @@ -1449,7 +1451,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, - cmTarget& target) + cmGeneratorTarget* target) { std::string buildType = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); @@ -1457,12 +1459,12 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library - switch(target.GetType()) + switch(target->GetType()) { case cmTarget::STATIC_LIBRARY: { const char* targetLinkFlags = - target.GetProperty("STATIC_LIBRARY_FLAGS"); + target->GetProperty("STATIC_LIBRARY_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1472,7 +1474,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string build = "STATIC_LIBRARY_FLAGS_"; build += buildType; - targetLinkFlags = target.GetProperty(build.c_str()); + targetLinkFlags = target->GetProperty(build.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1498,7 +1500,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, if(this->Makefile->IsOn("WIN32") && !(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW"))) { - const std::vector& sources = target.GetSourceFiles(); + const std::vector& sources = target->GetSourceFiles(); for(std::vector::const_iterator i = sources.begin(); i != sources.end(); ++i) { @@ -1513,7 +1515,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } } - const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); + const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1523,7 +1525,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string configLinkFlags = "LINK_FLAGS_"; configLinkFlags += buildType; - targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); + targetLinkFlags = target->GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1531,7 +1533,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } } cmOStringStream linklibsStr; - this->OutputLinkLibraries(linklibsStr, target, false); + this->OutputLinkLibraries(linklibsStr, *target, false); linkLibs = linklibsStr.str(); } break; @@ -1547,17 +1549,17 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += this->Makefile->GetSafeDefinition(build.c_str()); linkFlags += " "; } - const char* linkLanguage = target.GetLinkerLanguage(); + const char* linkLanguage = target->Target->GetLinkerLanguage(); if(!linkLanguage) { cmSystemTools::Error ("CMake can not determine linker language for target:", - target.GetName()); + target->Target->GetName()); return; } this->AddLanguageFlags(flags, linkLanguage, buildType.c_str()); cmOStringStream linklibs; - this->OutputLinkLibraries(linklibs, target, false); + this->OutputLinkLibraries(linklibs, *target, false); linkLibs = linklibs.str(); if(cmSystemTools::IsOn (this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) @@ -1567,7 +1569,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += this->Makefile->GetSafeDefinition(sFlagVar.c_str()); linkFlags += " "; } - if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) + if ( target->GetPropertyAsBool("WIN32_EXECUTABLE") ) { linkFlags += this->Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE"); @@ -1579,7 +1581,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); linkFlags += " "; } - if (target.IsExecutableWithExports()) + if (target->Target->IsExecutableWithExports()) { std::string exportFlagVar = "CMAKE_EXE_EXPORTS_"; exportFlagVar += linkLanguage; @@ -1589,7 +1591,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, this->Makefile->GetSafeDefinition(exportFlagVar.c_str()); linkFlags += " "; } - const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); + const char* targetLinkFlags = target->GetProperty("LINK_FLAGS"); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1599,7 +1601,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, { std::string configLinkFlags = "LINK_FLAGS_"; configLinkFlags += buildType; - targetLinkFlags = target.GetProperty(configLinkFlags.c_str()); + targetLinkFlags = target->GetProperty(configLinkFlags.c_str()); if(targetLinkFlags) { linkFlags += targetLinkFlags; @@ -1651,7 +1653,7 @@ std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib) * to the name of the library. This will not link a library against itself. */ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, - cmTarget& tgt, + cmGeneratorTarget& tgt, bool relink) { const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); @@ -1778,7 +1780,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, //---------------------------------------------------------------------------- void cmLocalGenerator::AddArchitectureFlags(std::string& flags, - cmTarget* target, + cmGeneratorTarget* target, const char *lang, const char* config) { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index b3396e3a5..0916d4422 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -16,6 +16,7 @@ class cmMakefile; class cmGlobalGenerator; +class cmGeneratorTarget; class cmTarget; class cmTargetManifest; class cmSourceFile; @@ -135,7 +136,7 @@ public: std::vector& GetChildren() { return this->Children; }; - void AddArchitectureFlags(std::string& flags, cmTarget* target, + void AddArchitectureFlags(std::string& flags, cmGeneratorTarget* target, const char *lang, const char* config); void AddLanguageFlags(std::string& flags, const char* lang, @@ -205,7 +206,7 @@ public: /** Get the include flags for the current makefile and language. */ void GetIncludeDirectories(std::vector& dirs, - cmTarget* target, + cmGeneratorTarget* target, const char* lang = "C"); /** Compute the language used to compile the given source file. */ @@ -334,11 +335,12 @@ public: void GetTargetFlags(std::string& linkLibs, std::string& flags, std::string& linkFlags, - cmTarget&target); + cmGeneratorTarget* target); protected: ///! put all the libraries for a target on into the given stream - virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink); + virtual void OutputLinkLibraries(std::ostream&, cmGeneratorTarget&, + bool relink); // Expand rule variables in CMake of the type found in language rules void ExpandRuleVariables(std::string& string, @@ -354,12 +356,12 @@ protected: /** Convert a target to a utility target for unsupported * languages of a generator */ - void AddBuildTargetRule(const char* llang, cmTarget& target); + void AddBuildTargetRule(const char* llang, cmGeneratorTarget& target); ///! add a custom command to build a .o file that is part of a target void AddCustomCommandToCreateObject(const char* ofname, const char* lang, cmSourceFile& source, - cmTarget& target); + cmGeneratorTarget& target); // Create Custom Targets and commands for unsupported languages // The set passed in should contain the languages supported by the // generator directly. Any targets containing files that are not diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 9f2a8635e..72b56e71c 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -862,10 +862,13 @@ cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target) // the length threatens this problem. unsigned int maxIncludeLength = 3000; bool useShortPath = false; + + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); for(int j=0; j < 2; ++j) { std::vector includes; - this->GetIncludeDirectories(includes, &target); + this->GetIncludeDirectories(includes, gt); std::vector::iterator i; for(i = includes.begin(); i != includes.end(); ++i) @@ -1676,37 +1679,25 @@ void cmLocalVisualStudio6Generator std::set minsizeDefinesSet; std::set debugrelDefinesSet; - this->AppendDefines( - definesSet, - this->Makefile->GetProperty("COMPILE_DEFINITIONS")); - this->AppendDefines( - debugDefinesSet, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_DEBUG")); - this->AppendDefines( - releaseDefinesSet, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELEASE")); - this->AppendDefines( - minsizeDefinesSet, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_MINSIZEREL")); - this->AppendDefines( - debugrelDefinesSet, - this->Makefile->GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO")); + + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); this->AppendDefines( definesSet, - target.GetProperty("COMPILE_DEFINITIONS")); + gt->GetCompileDefinitions()); this->AppendDefines( debugDefinesSet, - target.GetProperty("COMPILE_DEFINITIONS_DEBUG")); + gt->GetCompileDefinitions("DEBUG")); this->AppendDefines( releaseDefinesSet, - target.GetProperty("COMPILE_DEFINITIONS_RELEASE")); + gt->GetCompileDefinitions("RELEASE")); this->AppendDefines( minsizeDefinesSet, - target.GetProperty("COMPILE_DEFINITIONS_MINSIZEREL")); + gt->GetCompileDefinitions("MINSIZEREL")); this->AppendDefines( debugrelDefinesSet, - target.GetProperty("COMPILE_DEFINITIONS_RELWITHDEBINFO")); + gt->GetCompileDefinitions("RELWITHDEBINFO")); std::string defines = " "; std::string debugDefines = " "; @@ -1776,8 +1767,10 @@ void cmLocalVisualStudio6Generator const std::string extraOptions, std::string& options) { + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); // Compute the link information for this configuration. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 2dfca025c..2ededfe0a 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -819,7 +819,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); fout << "\t\t\t\tAdditionalIncludeDirectories=\""; std::vector includes; - this->GetIncludeDirectories(includes, &target); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + this->GetIncludeDirectories(includes, gt); std::vector::iterator i = includes.begin(); for(;i != includes.end(); ++i) { @@ -1079,7 +1081,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; @@ -1164,7 +1168,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); if(!pcli) { return; diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index a68b57c23..75a76a42e 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -58,11 +58,12 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) // Now extract any include paths from the targets std::set uniqueIncludes; std::vector orderedAndUniqueIncludes; - cmTargets & targets = this->Makefile->GetTargets(); - for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets(); + for (cmGeneratorTargetsType::iterator l = targets.begin(); + l != targets.end(); ++l) { const std::vector& includes = - l->second.GetIncludeDirectories(); + l->second->GetIncludeDirectories(); for(std::vector::const_iterator j = includes.begin(); j != includes.end(); ++j) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9a9c1c859..f067da491 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3984,6 +3984,12 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name) return this->LocalGenerator->GetGlobalGenerator()->FindTarget(0, name); } +cmGeneratorTarget* cmMakefile::FindGeneratorTargetToUse(const char* name) +{ + cmTarget *t = this->FindTargetToUse(name); + return this->LocalGenerator->GetGlobalGenerator()->GetGeneratorTarget(t); +} + //---------------------------------------------------------------------------- bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg, bool isCustom) diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 74c8039b3..80a50d6e6 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -20,6 +20,7 @@ #include "cmSystemTools.h" #include "cmTarget.h" #include "cmNewLineStyle.h" +#include "cmGeneratorTarget.h" #include "cmake.h" #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -519,11 +520,22 @@ public: */ const cmTargets &GetTargets() const { return this->Targets; } + const cmGeneratorTargetsType &GetGeneratorTargets() const + { + return this->GeneratorTargets; + } + + void SetGeneratorTargets(const cmGeneratorTargetsType &targets) + { + this->GeneratorTargets = targets; + } + cmTarget* FindTarget(const char* name); /** Find a target to use in place of the given name. The target returned may be imported or built within the project. */ cmTarget* FindTargetToUse(const char* name); + cmGeneratorTarget* FindGeneratorTargetToUse(const char* name); /** * Mark include directories as system directories. @@ -865,6 +877,7 @@ protected: // libraries, classes, and executables cmTargets Targets; + cmGeneratorTargetsType GeneratorTargets; std::vector SourceFiles; // Tests diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ab5150a36..ca5f26ac9 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -210,7 +210,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Add language feature flags. this->AddFeatureFlags(flags, linkLanguage); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, linkLanguage, this->ConfigName); // Add target-specific linker flags. @@ -319,7 +319,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // Collect up flags to link in needed libraries. cmOStringStream linklibs; - this->LocalGenerator->OutputLinkLibraries(linklibs, *this->Target, relink); + this->LocalGenerator->OutputLinkLibraries(linklibs, *this->GeneratorTarget, + relink); // Construct object file lists that may be needed to expand the // rule. diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 577e5fd07..368d6fc68 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -546,7 +546,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) { this->LocalGenerator - ->OutputLinkLibraries(linklibs, *this->Target, relink); + ->OutputLinkLibraries(linklibs, *this->GeneratorTarget, relink); } // Construct object file lists that may be needed to expand the @@ -625,7 +625,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string langFlags; this->AddFeatureFlags(langFlags, linkLanguage); - this->LocalGenerator->AddArchitectureFlags(langFlags, this->Target, + this->LocalGenerator->AddArchitectureFlags(langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName); // remove any language flags that might not work with the diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 95738c473..9560c1062 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -259,7 +259,7 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) // Add language feature flags. this->AddFeatureFlags(flags, lang); - this->LocalGenerator->AddArchitectureFlags(flags, this->Target, + this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget, lang, this->ConfigName); // Fortran-specific flags computed for this target. @@ -302,16 +302,11 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty("COMPILE_DEFINITIONS")); + (defines, this->GeneratorTarget->GetCompileDefinitions()); + this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty("COMPILE_DEFINITIONS")); - std::string defPropName = "COMPILE_DEFINITIONS_"; - defPropName += - cmSystemTools::UpperCase(this->LocalGenerator->ConfigurationName); - this->LocalGenerator->AppendDefines - (defines, this->Makefile->GetProperty(defPropName.c_str())); - this->LocalGenerator->AppendDefines - (defines, this->Target->GetProperty(defPropName.c_str())); + (defines, this->GeneratorTarget->GetCompileDefinitions( + this->LocalGenerator->ConfigurationName.c_str())); std::string definesString; this->LocalGenerator->JoinDefines(defines, definesString, lang); @@ -1022,7 +1017,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n"; std::set emitted; const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { cmComputeLinkInformation::ItemVector const& items = cli->GetItems(); for(cmComputeLinkInformation::ItemVector::const_iterator @@ -1061,7 +1057,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() *this->InfoFileStream << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n"; std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget); for(std::vector::iterator i = includes.begin(); i != includes.end(); ++i) { @@ -1546,7 +1543,8 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() emitted.insert("/System/Library/Frameworks"); #endif std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget); std::vector::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework @@ -1590,7 +1588,8 @@ void cmMakefileTargetGenerator // Loop over all library dependencies. const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = + this->GeneratorTarget->GetLinkInformation(cfg)) { std::vector const& libDeps = cli->GetDepends(); for(std::vector::const_iterator j = libDeps.begin(); @@ -1850,7 +1849,8 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target, lang); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget, lang); std::string includeFlags = this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile); @@ -1953,7 +1953,8 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget); for(std::vector::const_iterator idi = includes.begin(); idi != includes.end(); ++idi) { diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 9dc860ee9..6f991e29d 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -423,7 +423,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], vars["LINK_FLAGS"], - *this->GetTarget()); + this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); @@ -434,7 +434,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() ? vars["FLAGS"] : vars["ARCH_FLAGS"]); this->GetLocalGenerator()->AddArchitectureFlags(flags, - this->GetTarget(), + this->GetGeneratorTarget(), this->TargetLinkLanguage, this->GetConfigName()); if (targetType == cmTarget::EXECUTABLE) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 4cc23cacf..1d11acab9 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -134,7 +134,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, this->AddFeatureFlags(flags, language.c_str()); this->GetLocalGenerator()->AddArchitectureFlags(flags, - this->GetTarget(), + this->GeneratorTarget, language.c_str(), this->GetConfigName()); @@ -152,7 +152,7 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // Add include directory flags. { std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target, + this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, language.c_str()); std::string includeFlags = this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), @@ -195,10 +195,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty("COMPILE_DEFINITIONS")); - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetProperty("COMPILE_DEFINITIONS")); + this->GeneratorTarget->GetCompileDefinitions()); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); @@ -207,10 +204,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language) defPropName += cmSystemTools::UpperCase(this->GetConfigName()); this->LocalGenerator->AppendDefines (defines, - this->Makefile->GetProperty(defPropName.c_str())); - this->LocalGenerator->AppendDefines - (defines, - this->Target->GetProperty(defPropName.c_str())); + this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName())); this->LocalGenerator->AppendDefines (defines, source->GetProperty(defPropName.c_str())); @@ -231,7 +225,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const return cmNinjaDeps(); cmComputeLinkInformation* cli = - this->Target->GetLinkInformation(this->GetConfigName()); + this->GeneratorTarget->GetLinkInformation(this->GetConfigName()); if(!cli) return cmNinjaDeps(); diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index cd20694b4..cf06bfdf5 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -52,6 +52,9 @@ protected: cmTarget* GetTarget() const { return this->Target; } + cmGeneratorTarget* GetGeneratorTarget() const + { return this->GeneratorTarget; } + cmLocalNinjaGenerator* GetLocalGenerator() const { return this->LocalGenerator; } diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 71feffddd..68f10466b 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -111,6 +111,7 @@ cmQtAutomoc::cmQtAutomoc() void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { cmMakefile* makefile = target->GetMakefile(); + cmLocalGenerator* localGen = makefile->GetLocalGenerator(); const char* targetName = target->GetName(); // don't do anything if there is no Qt4 or Qt5Core (which contains moc): std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); @@ -193,12 +194,28 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } } - const char* tmp = makefile->GetProperty("INCLUDE_DIRECTORIES"); - std::string _moc_incs = (tmp!=0 ? tmp : ""); - tmp = makefile->GetProperty("DEFINITIONS"); - std::string _moc_defs = (tmp!=0 ? tmp : ""); - tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); + std::vector includeDirs; + cmGeneratorTarget gtgt(target); + localGen->GetIncludeDirectories(includeDirs, >gt, "CXX"); + std::string _moc_incs = ""; + const char* sep = ""; + for(std::vector::const_iterator incDirIt = includeDirs.begin(); + incDirIt != includeDirs.end(); + ++incDirIt) + { + _moc_incs += sep; + sep = ";"; + _moc_incs += *incDirIt; + } + + const char* tmp = target->GetProperty("COMPILE_DEFINITIONS"); std::string _moc_compile_defs = (tmp!=0 ? tmp : ""); + tmp = makefile->GetProperty("COMPILE_DEFINITIONS"); + if (tmp) + { + _moc_compile_defs += ";"; + _moc_compile_defs += tmp; + } tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS"); std::string _moc_options = (tmp!=0 ? tmp : ""); @@ -210,8 +227,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) cmLocalGenerator::EscapeForCMake(automocTargetName.c_str()).c_str()); makefile->AddDefinition("_moc_incs", cmLocalGenerator::EscapeForCMake(_moc_incs.c_str()).c_str()); - makefile->AddDefinition("_moc_defs", - cmLocalGenerator::EscapeForCMake(_moc_defs.c_str()).c_str()); makefile->AddDefinition("_moc_compile_defs", cmLocalGenerator::EscapeForCMake(_moc_compile_defs.c_str()).c_str()); makefile->AddDefinition("_moc_options", @@ -314,7 +329,6 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); this->MocCompileDefinitionsStr = makefile->GetSafeDefinition( "AM_MOC_COMPILE_DEFINITIONS"); - this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS"); this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); @@ -332,7 +346,7 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, std::string cmQtAutomoc::MakeCompileSettingsString(cmMakefile* makefile) { std::string s; - s += makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); + s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS"); s += " ~~~ "; s += makefile->GetSafeDefinition("AM_MOC_INCLUDES"); s += " ~~~ "; @@ -387,32 +401,11 @@ void cmQtAutomoc::Init() std::vector cdefList; cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); - if (!cdefList.empty()) + for(std::vector::const_iterator it = cdefList.begin(); + it != cdefList.end(); + ++it) { - for(std::vector::const_iterator it = cdefList.begin(); - it != cdefList.end(); - ++it) - { - this->MocDefinitions.push_back("-D" + (*it)); - } - } - else - { - std::string tmpMocDefs = this->MocDefinitionsStr; - cmSystemTools::ReplaceString(tmpMocDefs, " ", ";"); - - std::vector defList; - cmSystemTools::ExpandListArgument(tmpMocDefs, defList); - - for(std::vector::const_iterator it = defList.begin(); - it != defList.end(); - ++it) - { - if (this->StartsWith(*it, "-D")) - { - this->MocDefinitions.push_back(*it); - } - } + this->MocDefinitions.push_back("-D" + (*it)); } cmSystemTools::ExpandListArgument(this->MocOptionsStr, this->MocOptions); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index f6d72e2f7..a73747781 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -69,7 +69,6 @@ private: std::string Builddir; std::string MocExecutable; std::string MocCompileDefinitionsStr; - std::string MocDefinitionsStr; std::string MocIncludesStr; std::string MocOptionsStr; std::string ProjectBinaryDir; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 789713fcc..5a47d1749 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -15,7 +15,6 @@ #include "cmSourceFile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" -#include "cmComputeLinkInformation.h" #include "cmDocumentCompileDefinitions.h" #include "cmDocumentLocationUndefined.h" #include "cmListFileCache.h" @@ -1623,7 +1622,11 @@ cmTargetTraceDependencies { // Transform command names that reference targets built in this // project to corresponding target-level dependencies. - cmGeneratorExpression ge(this->Makefile, 0, cc.GetBacktrace(), true); + cmGeneratorExpression ge(cc.GetBacktrace()); + + // Add target-level dependencies referenced by generator expressions. + std::set targets; + for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin(); cit != cc.GetCommandLines().end(); ++cit) { @@ -1645,12 +1648,17 @@ cmTargetTraceDependencies for(cmCustomCommandLine::const_iterator cli = cit->begin(); cli != cit->end(); ++cli) { - ge.Process(*cli); + const cmCompiledGeneratorExpression &cge = ge.Parse(*cli); + cge.Evaluate(this->Makefile, 0, true); + std::set geTargets = cge.GetTargets(); + for(std::set::const_iterator it = geTargets.begin(); + it != geTargets.end(); ++it) + { + targets.insert(*it); + } } } - // Add target-level dependencies referenced by generator expressions. - std::set targets = ge.GetTargets(); for(std::set::iterator ti = targets.begin(); ti != targets.end(); ++ti) { @@ -2944,25 +2952,6 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc) } } -//---------------------------------------------------------------------------- -const char* cmTarget::GetCreateRuleVariable() -{ - switch(this->GetType()) - { - case cmTarget::STATIC_LIBRARY: - return "_CREATE_STATIC_LIBRARY"; - case cmTarget::SHARED_LIBRARY: - return "_CREATE_SHARED_LIBRARY"; - case cmTarget::MODULE_LIBRARY: - return "_CREATE_SHARED_MODULE"; - case cmTarget::EXECUTABLE: - return "_LINK_EXECUTABLE"; - default: - break; - } - return ""; -} - //---------------------------------------------------------------------------- const char* cmTarget::GetSuffixVariableInternal(bool implib) { @@ -3505,76 +3494,6 @@ bool cmTarget::GetImplibGNUtoMS(std::string const& gnuName, return false; } -//---------------------------------------------------------------------------- -void cmTarget::GenerateTargetManifest(const char* config) -{ - cmMakefile* mf = this->Makefile; - cmLocalGenerator* lg = mf->GetLocalGenerator(); - cmGlobalGenerator* gg = lg->GetGlobalGenerator(); - - // Get the names. - std::string name; - std::string soName; - std::string realName; - std::string impName; - std::string pdbName; - if(this->GetType() == cmTarget::EXECUTABLE) - { - this->GetExecutableNames(name, realName, impName, pdbName, config); - } - else if(this->GetType() == cmTarget::STATIC_LIBRARY || - this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY) - { - this->GetLibraryNames(name, soName, realName, impName, pdbName, config); - } - else - { - return; - } - - // Get the directory. - std::string dir = this->GetDirectory(config, false); - - // Add each name. - std::string f; - if(!name.empty()) - { - f = dir; - f += "/"; - f += name; - gg->AddToManifest(config? config:"", f); - } - if(!soName.empty()) - { - f = dir; - f += "/"; - f += soName; - gg->AddToManifest(config? config:"", f); - } - if(!realName.empty()) - { - f = dir; - f += "/"; - f += realName; - gg->AddToManifest(config? config:"", f); - } - if(!pdbName.empty()) - { - f = dir; - f += "/"; - f += pdbName; - gg->AddToManifest(config? config:"", f); - } - if(!impName.empty()) - { - f = this->GetDirectory(config, true); - f += "/"; - f += impName; - gg->AddToManifest(config? config:"", f); - } -} - //---------------------------------------------------------------------------- void cmTarget::SetPropertyDefault(const char* property, const char* default_value) @@ -3970,27 +3889,6 @@ void cmTarget::GetLanguages(std::set& languages) const } } -//---------------------------------------------------------------------------- -void cmTarget::GetAppleArchs(const char* config, - std::vector& archVec) -{ - const char* archs = 0; - if(config && *config) - { - std::string defVarName = "OSX_ARCHITECTURES_"; - defVarName += cmSystemTools::UpperCase(config); - archs = this->GetProperty(defVarName.c_str()); - } - if(!archs) - { - archs = this->GetProperty("OSX_ARCHITECTURES"); - } - if(archs) - { - cmSystemTools::ExpandListArgument(std::string(archs), archVec); - } -} - //---------------------------------------------------------------------------- bool cmTarget::IsChrpathUsed(const char* config) { @@ -4661,56 +4559,6 @@ std::string cmTarget::CheckCMP0004(std::string const& item) return lib; } -//---------------------------------------------------------------------------- -cmComputeLinkInformation* -cmTarget::GetLinkInformation(const char* config) -{ - // Lookup any existing information for this configuration. - std::map::iterator - i = this->LinkInformation.find(config?config:""); - if(i == this->LinkInformation.end()) - { - // Compute information for this configuration. - cmComputeLinkInformation* info = - new cmComputeLinkInformation(this, config); - if(!info || !info->Compute()) - { - delete info; - info = 0; - } - - // Store the information for this configuration. - std::map::value_type - entry(config?config:"", info); - i = this->LinkInformation.insert(entry).first; - } - return i->second; -} - -//---------------------------------------------------------------------------- -std::vector cmTarget::GetIncludeDirectories() -{ - std::vector includes; - const char *prop = this->GetProperty("INCLUDE_DIRECTORIES"); - if(prop) - { - cmSystemTools::ExpandListArgument(prop, includes); - } - - std::set uniqueIncludes; - std::vector orderedAndUniqueIncludes; - for(std::vector::const_iterator - li = includes.begin(); li != includes.end(); ++li) - { - if(uniqueIncludes.insert(*li).second) - { - orderedAndUniqueIncludes.push_back(*li); - } - } - - return orderedAndUniqueIncludes; -} - //---------------------------------------------------------------------------- std::string cmTarget::GetFrameworkDirectory(const char* config) { @@ -4768,29 +4616,6 @@ std::string cmTarget::GetMacContentDirectory(const char* config, return fpath; } -//---------------------------------------------------------------------------- -cmTargetLinkInformationMap -::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() -{ - // Ideally cmTarget instances should never be copied. However until - // we can make a sweep to remove that, this copy constructor avoids - // allowing the resources (LinkInformation) from getting copied. In - // the worst case this will lead to extra cmComputeLinkInformation - // instances. We also enforce in debug mode that the map be emptied - // when copied. - static_cast(r); - assert(r.empty()); -} - -//---------------------------------------------------------------------------- -cmTargetLinkInformationMap::~cmTargetLinkInformationMap() -{ - for(derived::iterator i = this->begin(); i != this->end(); ++i) - { - delete i->second; - } -} - //---------------------------------------------------------------------------- cmTargetInternalPointer::cmTargetInternalPointer() { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 98eaeec76..a025eea8e 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -22,18 +22,8 @@ class cmake; class cmMakefile; class cmSourceFile; class cmGlobalGenerator; -class cmComputeLinkInformation; class cmListFileBacktrace; -struct cmTargetLinkInformationMap: - public std::map -{ - typedef std::map derived; - cmTargetLinkInformationMap() {} - cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r); - ~cmTargetLinkInformationMap(); -}; - class cmTargetInternals; class cmTargetInternalPointer { @@ -330,10 +320,6 @@ public: ///! Return the preferred linker language for this target const char* GetLinkerLanguage(const char* config = 0); - ///! Return the rule variable used to create this type of target, - // need to add CMAKE_(LANG) for full name. - const char* GetCreateRuleVariable(); - /** Get the full name of the target according to the settings in its makefile. */ std::string GetFullName(const char* config=0, bool implib = false); @@ -381,9 +367,6 @@ public: bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out, const char* newExt = 0); - /** Add the target output files to the global generator manifest. */ - void GenerateTargetManifest(const char* config); - /** * Compute whether this target must be relinked before installing. */ @@ -400,8 +383,6 @@ public: std::string GetInstallNameDirForInstallTree(const char* config, bool for_xcode = false); - cmComputeLinkInformation* GetLinkInformation(const char* config); - // Get the properties cmPropertyMap &GetProperties() { return this->Properties; }; @@ -419,9 +400,6 @@ public: // until we have per-target object file properties. void GetLanguages(std::set& languages) const; - /** Get the list of OS X target architectures to be built. */ - void GetAppleArchs(const char* config, std::vector& archVec); - /** Return whether this target is an executable with symbol exports enabled. */ bool IsExecutableWithExports(); @@ -459,9 +437,6 @@ public: directory. */ bool UsesDefaultOutputDir(const char* config, bool implib); - /** Get the include directories for this target. */ - std::vector GetIncludeDirectories(); - /** Append to @a base the mac content directory and return it. */ std::string BuildMacContentDirectory(const std::string& base, const char* config = 0, @@ -599,8 +574,6 @@ private: ImportInfo const* GetImportInfo(const char* config); void ComputeImportInfo(std::string const& desired_config, ImportInfo& info); - cmTargetLinkInformationMap LinkInformation; - bool ComputeLinkInterface(const char* config, LinkInterface& iface); void ComputeLinkImplementation(const char* config, diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index e0892b282..2f650e72e 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -91,8 +91,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, this->TestGenerated = true; // Set up generator expression evaluation context. - cmMakefile* mf = this->Test->GetMakefile(); - cmGeneratorExpression ge(mf, config, this->Test->GetBacktrace()); + cmGeneratorExpression ge(this->Test->GetBacktrace()); // Start the test command. os << indent << "ADD_TEST(" << this->Test->GetName() << " "; @@ -103,6 +102,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Check whether the command executable is a target whose name is to // be translated. std::string exe = command[0]; + cmMakefile* mf = this->Test->GetMakefile(); cmTarget* target = mf->FindTargetToUse(exe.c_str()); if(target && target->GetType() == cmTarget::EXECUTABLE) { @@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, else { // Use the command name given. - exe = ge.Process(exe.c_str()); + exe = ge.Parse(exe.c_str()).Evaluate(mf, config); cmSystemTools::ConvertToUnixSlashes(exe); } @@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, for(std::vector::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) { - os << " " << lg->EscapeForCMake(ge.Process(*ci)); + os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config)); } // Finish the test command. diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 3d2828dab..fea117a4f 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1452,7 +1452,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& // Replace spaces in libs with ; cmSystemTools::ReplaceString(libs, " ", ";"); cmComputeLinkInformation* pcli = - this->Target->GetLinkInformation(config.c_str()); + this->GeneratorTarget->GetLinkInformation(config.c_str()); if(!pcli) { cmSystemTools::Error @@ -1594,7 +1594,8 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() static_cast (this->GlobalGenerator)->GetConfigurations(); std::vector includes; - this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + this->LocalGenerator->GetIncludeDirectories(includes, + this->GeneratorTarget); for(std::vector::iterator i = configs->begin(); i != configs->end(); ++i) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index c6787b9d0..e559fe0e8 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -630,7 +630,8 @@ bool cmake::FindPackage(const std::vector& args) std::string linkLibs; std::string flags; std::string linkFlags; - lg->GetTargetFlags(linkLibs, flags, linkFlags, *tgt); + cmGeneratorTarget gtgt(tgt); + lg->GetTargetFlags(linkLibs, flags, linkFlags, >gt); printf("%s\n", linkLibs.c_str() ); diff --git a/Tests/CMakeTests/VersionTest.cmake.in b/Tests/CMakeTests/VersionTest.cmake.in index 215bb2b96..9e31cb431 100644 --- a/Tests/CMakeTests/VersionTest.cmake.in +++ b/Tests/CMakeTests/VersionTest.cmake.in @@ -7,3 +7,10 @@ if("${CMAKE_VERSION}" VERSION_LESS "${min_ver}") else() message("CMAKE_VERSION=[${CMAKE_VERSION}] is not less than [${min_ver}]") endif() + +set(v 1.2.3.4.5.6.7) +if("${v}.8" VERSION_LESS "${v}.9") + message(STATUS "${v}.8 is less than ${v}.9") +else() + message(FATAL_ERROR "${v}.8 is not less than ${v}.9?") +endif() diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 33ffe2ede..3f8e8273d 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -189,7 +189,7 @@ set_property(TARGET ${proj} PROPERTY FOLDER "Local/TGZ") set(proj TutorialStep1-LocalNoDirTGZ) ExternalProject_Add(${proj} URL "${CMAKE_CURRENT_SOURCE_DIR}/Step1NoDir.tgz" - URL_MD5 0b8182edcecdf40bf1c9d71d7d259f78 + URL_HASH SHA256=496229e2a5ed620a37c385ad9406004a18026beab8b55dd2c4565d4b7f1d5383 CMAKE_GENERATOR "${CMAKE_GENERATOR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= INSTALL_COMMAND "" diff --git a/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt index ced21d806..36302db9b 100644 --- a/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadAND-stderr.txt @@ -1,9 +1,18 @@ +CMake Error at BadAND.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ expression requires at least one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ CMake Error at BadAND.cmake:1 \(add_custom_target\): Error evaluating generator expression: \$ - AND requires one or more comma-separated '0' or '1' values. + Parameters to \$ must resolve to either '0' or '1'. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) + @@ -12,6 +21,24 @@ CMake Error at BadAND.cmake:1 \(add_custom_target\): \$ - AND requires one or more comma-separated '0' or '1' values. + Parameters to \$ must resolve to either '0' or '1'. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadAND.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Parameters to \$ must resolve to either '0' or '1'. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadAND.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Parameters to \$ must resolve to either '0' or '1'. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadAND.cmake b/Tests/RunCMake/GeneratorExpression/BadAND.cmake index 792654046..265e4149b 100644 --- a/Tests/RunCMake/GeneratorExpression/BadAND.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadAND.cmake @@ -1,4 +1,7 @@ add_custom_target(check ALL COMMAND check + $ $ $ + $ + $ VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt index 7c86b250f..1cfbf404e 100644 --- a/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG-stderr.txt @@ -1,8 +1,44 @@ +CMake Error at BadCONFIG.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ expression requires exactly one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ CMake Error at BadCONFIG.cmake:1 \(add_custom_target\): Error evaluating generator expression: \$ + Expression syntax not recognized. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadCONFIG.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ expression requires exactly one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadCONFIG.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Expression syntax not recognized. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadCONFIG.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + Expression syntax not recognized. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake index 0c13f8944..c27ea5f73 100644 --- a/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadCONFIG.cmake @@ -1,3 +1,7 @@ add_custom_target(check ALL COMMAND check + $ $ + $ + $ + $<$:foo> VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt index 5721f5fe1..32169c537 100644 --- a/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadNOT-stderr.txt @@ -1,9 +1,17 @@ CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ expression requires exactly one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++CMake Error at BadNOT.cmake:1 \(add_custom_target\): Error evaluating generator expression: \$ - NOT requires exactly one '0' or '1' value. + \$ parameter must resolve to exactly one '0' or '1' value. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) + @@ -12,7 +20,7 @@ CMake Error at BadNOT.cmake:1 \(add_custom_target\): \$ - NOT requires exactly one '0' or '1' value. + \$ parameter must resolve to exactly one '0' or '1' value. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) + @@ -21,6 +29,24 @@ CMake Error at BadNOT.cmake:1 \(add_custom_target\): \$ - NOT requires exactly one '0' or '1' value. + \$ expression requires exactly one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ parameter must resolve to exactly one '0' or '1' value. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadNOT.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ parameter must resolve to exactly one '0' or '1' value. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadNOT.cmake b/Tests/RunCMake/GeneratorExpression/BadNOT.cmake index 452293b8d..c2dada3c2 100644 --- a/Tests/RunCMake/GeneratorExpression/BadNOT.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadNOT.cmake @@ -1,5 +1,8 @@ add_custom_target(check ALL COMMAND check + $ $ $ $ + $ + $ VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt index 72ef2dd3c..d4ccab74c 100644 --- a/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadOR-stderr.txt @@ -1,9 +1,18 @@ +CMake Error at BadOR.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + \$ expression requires at least one parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ CMake Error at BadOR.cmake:1 \(add_custom_target\): Error evaluating generator expression: \$ - OR requires one or more comma-separated '0' or '1' values. + Parameters to \$ must resolve to either '0' or '1'. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) + @@ -12,6 +21,24 @@ CMake Error at BadOR.cmake:1 \(add_custom_target\): \$ - OR requires one or more comma-separated '0' or '1' values. + Parameters to \$ must resolve to either '0' or '1'. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadOR.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Parameters to \$ must resolve to either '0' or '1'. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadOR.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$ + + Parameters to \$ must resolve to either '0' or '1'. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadOR.cmake b/Tests/RunCMake/GeneratorExpression/BadOR.cmake index f16f56a3c..0813400d6 100644 --- a/Tests/RunCMake/GeneratorExpression/BadOR.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadOR.cmake @@ -1,4 +1,7 @@ add_custom_target(check ALL COMMAND check + $ $ $ + $ + $ VERBATIM) diff --git a/bootstrap b/bootstrap index d51d80f81..9b6d6345b 100755 --- a/bootstrap +++ b/bootstrap @@ -204,6 +204,9 @@ CMAKE_CXX_SOURCES="\ cmInstallDirectoryGenerator \ cmGeneratedFileStream \ cmGeneratorTarget \ + cmGeneratorExpressionEvaluator \ + cmGeneratorExpressionLexer \ + cmGeneratorExpressionParser \ cmGeneratorExpression \ cmGlobalGenerator \ cmLocalGenerator \