diff options
432 files changed, 9684 insertions, 3168 deletions
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index 1a46688..9eee655 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -1,3 +1,7 @@ +SET(CTEST_CUSTOM_ERROR_MATCH + ${CTEST_CUSTOM_ERROR_MATCH} + "ERROR:") + SET(CTEST_CUSTOM_WARNING_EXCEPTION ${CTEST_CUSTOM_WARNING_EXCEPTION} "xtree.[0-9]+. : warning C4702: unreachable code" @@ -44,6 +48,7 @@ SET(CTEST_CUSTOM_WARNING_EXCEPTION "cc-3968 CC: WARNING File.*" # "implicit" truncation by static_cast "ld: warning: directory not found for option .-(F|L)" "warning.*This version of Mac OS X is unsupported" + "clang.*: warning: argument unused during compilation: .-g" # Ignore clang's summary warning, assuming prior text has matched some # other warning expression: diff --git a/Docs/cmake-completion b/Docs/cmake-completion index d82d608..d70ac24 100644 --- a/Docs/cmake-completion +++ b/Docs/cmake-completion @@ -130,6 +130,16 @@ _cpack() COMPREPLY=( $(compgen -f ${cur}) ) return 0 ;; + --help-variable) + local running=$(for x in `cpack --help-variable-list | grep -v "cpack version" `; do echo ${x} ; done ) + COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) + return 0 + ;; + --help-command) + local running=$(for x in `cpack --help-command-list | grep -v "cpack version" `; do echo ${x} ; done ) + COMPREPLY=( $(compgen -W "${running}" -- ${cur}) ) + return 0 + ;; *) ;; esac diff --git a/Docs/cmake-mode.el b/Docs/cmake-mode.el index 4418bfa..9517455 100644 --- a/Docs/cmake-mode.el +++ b/Docs/cmake-mode.el @@ -68,9 +68,9 @@ set the path with these commands: "\\|" "[ \t\r\n]" "\\)*")) (defconst cmake-regex-block-open - "^\\(IF\\|MACRO\\|FOREACH\\|ELSE\\|ELSEIF\\|WHILE\\|FUNCTION\\)$") + "^\\([iI][fF]\\|[mM][aA][cC][rR][oO]\\|[fF][oO][rR][eE][aA][cC][hH]\\|[eE][lL][sS][eE]\\|[eE][lL][sS][eE][iI][fF]\\|[wW][hH][iI][lL][eE]\\|[fF][uU][nN][cC][tT][iI][oO][nN]\\)$") (defconst cmake-regex-block-close - "^[ \t]*\\(ENDIF\\|ENDFOREACH\\|ENDMACRO\\|ELSE\\|ELSEIF\\|ENDWHILE\\|ENDFUNCTION\\)[ \t]*(") + "^[ \t]*\\([eE][nN][dD][iI][fF]\\|[eE][nN][dD][fF][oO][rR][eE][aA][cC][hH]\\|[eE][nN][dD][mM][aA][cC][rR][oO]\\|[eE][lL][sS][eE]\\|[eE][lL][sS][eE][iI][fF]\\|[eE][nN][dD][wW][hH][iI][lL][eE]\\|[eE][nN][dD][fF][uU][nN][cC][tT][iI][oO][nN]\\)[ \t]*(") ;------------------------------------------------------------------------------ diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake new file mode 100644 index 0000000..abd9100 --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory.cmake @@ -0,0 +1,206 @@ +# - Use MinGW gfortran from VS if a fortran compiler is not found. +# The 'add_fortran_subdirectory' function adds a subdirectory +# to a project that contains a fortran only sub-project. The module +# will check the current compiler and see if it can support fortran. +# If no fortran compiler is found and the compiler is MSVC, then +# this module will find the MinGW gfortran. It will then use +# an external project to build with the MinGW tools. It will also +# create imported targets for the libraries created. This will only +# work if the fortran code is built into a dll, so BUILD_SHARED_LIBS +# is turned on in the project. In addition the CMAKE_GNUtoMS option +# is set to on, so that the MS .lib files are created. +# Usage is as follows: +# cmake_add_fortran_subdirectory( +# <subdir> # name of subdirectory +# PROJECT <project_name> # project name in subdir top CMakeLists.txt +# ARCHIVE_DIR <dir> # dir where project places .lib files +# RUNTIME_DIR <dir> # dir where project places .dll files +# LIBRARIES <lib>... # names of library targets to import +# LINK_LIBRARIES # link interface libraries for LIBRARIES +# [LINK_LIBS <lib> <dep>...]... +# CMAKE_COMMAND_LINE ... # extra command line flags to pass to cmake +# NO_EXTERNAL_INSTALL # skip installation of external project +# ) +# Relative paths in ARCHIVE_DIR and RUNTIME_DIR are interpreted with respect +# to the build directory corresponding to the source directory in which the +# function is invoked. +# +# Limitations: +# +# NO_EXTERNAL_INSTALL is required for forward compatibility with a +# future version that supports installation of the external project +# binaries during "make install". + +#============================================================================= +# Copyright 2011-2012 Kitware, Inc. +# +# 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.) + + +set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +include(CheckLanguage) +include(ExternalProject) +include(CMakeParseArguments) + +function(_setup_mingw_config_and_build source_dir build_dir) + # Look for a MinGW gfortran. + find_program(MINGW_GFORTRAN + NAMES gfortran + PATHS + c:/MinGW/bin + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MinGW;InstallLocation]/bin" + ) + if(NOT MINGW_GFORTRAN) + message(FATAL_ERROR + "gfortran not found, please install MinGW with the gfortran option." + "Or set the cache variable MINGW_GFORTRAN to the full path. " + " This is required to build") + endif() + + # Validate the MinGW gfortran we found. + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_mingw_target "Target:.*64.*mingw") + else() + set(_mingw_target "Target:.*mingw32") + endif() + execute_process(COMMAND "${MINGW_GFORTRAN}" -v + ERROR_VARIABLE out ERROR_STRIP_TRAILING_WHITESPACE) + if(NOT "${out}" MATCHES "${_mingw_target}") + string(REPLACE "\n" "\n " out " ${out}") + message(FATAL_ERROR + "MINGW_GFORTRAN is set to\n" + " ${MINGW_GFORTRAN}\n" + "which is not a MinGW gfortran for this architecture. " + "The output from -v does not match \"${_mingw_target}\":\n" + "${out}\n" + "Set MINGW_GFORTRAN to a proper MinGW gfortran for this architecture." + ) + endif() + + # Configure scripts to run MinGW tools with the proper PATH. + get_filename_component(MINGW_PATH ${MINGW_GFORTRAN} PATH) + file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) + string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") + configure_file( + ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in + ${build_dir}/config_mingw.cmake + @ONLY) + configure_file( + ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in + ${build_dir}/build_mingw.cmake + @ONLY) +endfunction() + +function(_add_fortran_library_link_interface library depend_library) + set_target_properties(${library} PROPERTIES + IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG "${depend_library}") +endfunction() + + +function(cmake_add_fortran_subdirectory subdir) + # Parse arguments to function + set(options NO_EXTERNAL_INSTALL) + set(oneValueArgs PROJECT ARCHIVE_DIR RUNTIME_DIR) + set(multiValueArgs LIBRARIES LINK_LIBRARIES CMAKE_COMMAND_LINE) + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT ARGS_NO_EXTERNAL_INSTALL) + message(FATAL_ERROR + "Option NO_EXTERNAL_INSTALL is required (for forward compatibility) " + "but was not given." + ) + endif() + + # if we are not using MSVC without fortran support + # then just use the usual add_subdirectory to build + # the fortran library + check_language(Fortran) + if(NOT (MSVC AND (NOT CMAKE_Fortran_COMPILER))) + add_subdirectory(${subdir}) + return() + endif() + + # if we have MSVC without Intel fortran then setup + # external projects to build with mingw fortran + + set(source_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}") + set(project_name "${ARGS_PROJECT}") + set(library_dir "${ARGS_ARCHIVE_DIR}") + set(binary_dir "${ARGS_RUNTIME_DIR}") + set(libraries ${ARGS_LIBRARIES}) + # use the same directory that add_subdirectory would have used + set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}") + foreach(dir_var library_dir binary_dir) + if(NOT IS_ABSOLUTE "${${dir_var}}") + get_filename_component(${dir_var} + "${CMAKE_CURRENT_BINARY_DIR}/${${dir_var}}" ABSOLUTE) + endif() + endforeach() + # create build and configure wrapper scripts + _setup_mingw_config_and_build("${source_dir}" "${build_dir}") + # create the external project + externalproject_add(${project_name}_build + SOURCE_DIR ${source_dir} + BINARY_DIR ${build_dir} + CONFIGURE_COMMAND ${CMAKE_COMMAND} + -P ${build_dir}/config_mingw.cmake + BUILD_COMMAND ${CMAKE_COMMAND} + -P ${build_dir}/build_mingw.cmake + INSTALL_COMMAND "" + ) + # make the external project always run make with each build + externalproject_add_step(${project_name}_build forcebuild + COMMAND ${CMAKE_COMMAND} + -E remove + ${CMAKE_CURRENT_BUILD_DIR}/${project_name}-prefix/src/${project_name}-stamp/${project_name}-build + DEPENDEES configure + DEPENDERS build + ALWAYS 1 + ) + # create imported targets for all libraries + foreach(lib ${libraries}) + add_library(${lib} SHARED IMPORTED GLOBAL) + set_property(TARGET ${lib} APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG) + set_target_properties(${lib} PROPERTIES + IMPORTED_IMPLIB_NOCONFIG "${library_dir}/lib${lib}.lib" + IMPORTED_LOCATION_NOCONFIG "${binary_dir}/lib${lib}.dll" + ) + add_dependencies(${lib} ${project_name}_build) + endforeach() + + # now setup link libraries for targets + set(start FALSE) + set(target) + foreach(lib ${ARGS_LINK_LIBRARIES}) + if("${lib}" STREQUAL "LINK_LIBS") + set(start TRUE) + else() + if(start) + if(DEFINED target) + # process current target and target_libs + _add_fortran_library_link_interface(${target} "${target_libs}") + # zero out target and target_libs + set(target) + set(target_libs) + endif() + # save the current target and set start to FALSE + set(target ${lib}) + set(start FALSE) + else() + # append the lib to target_libs + list(APPEND target_libs "${lib}") + endif() + endif() + endforeach() + # process anything that is left in target and target_libs + if(DEFINED target) + _add_fortran_library_link_interface(${target} "${target_libs}") + endif() +endfunction() diff --git a/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in new file mode 100644 index 0000000..55b271a --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory/build_mingw.cmake.in @@ -0,0 +1,2 @@ +set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}") +execute_process(COMMAND "@CMAKE_COMMAND@" --build . ) diff --git a/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in new file mode 100644 index 0000000..97f6769 --- /dev/null +++ b/Modules/CMakeAddFortranSubdirectory/config_mingw.cmake.in @@ -0,0 +1,9 @@ +set(ENV{PATH} "@MINGW_PATH@\;$ENV{PATH}") +set(CMAKE_COMMAND_LINE "@ARGS_CMAKE_COMMAND_LINE@") +execute_process( + COMMAND "@CMAKE_COMMAND@" "-GMinGW Makefiles" + -DCMAKE_Fortran_COMPILER:PATH=@MINGW_GFORTRAN@ + -DBUILD_SHARED_LIBS=ON + -DCMAKE_GNUtoMS=ON + ${CMAKE_COMMAND_LINE} + "@source_dir@") diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index b0f5eb6..06aa9bf 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -26,6 +26,12 @@ # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) + #elif defined(__BORLANDC__) # define COMPILER_ID "Borland" /* __BORLANDC__ = 0xVRR */ diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 927f7f4..95fc852 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -28,6 +28,12 @@ # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH HEX(__CODEGEARC_VERSION__ & 0xFFFF) + #elif defined(__BORLANDC__) # define COMPILER_ID "Borland" /* __BORLANDC__ = 0xVRR */ diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake index b97a69c..25abb8c 100644 --- a/Modules/CMakeCXXInformation.cmake +++ b/Modules/CMakeCXXInformation.cmake @@ -93,12 +93,6 @@ IF(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX) ENDIF() -# for most systems a module is the same as a shared library -# so unless the variable CMAKE_MODULE_EXISTS is set just -# copy the values from the LIBRARY variables -IF(NOT CMAKE_MODULE_EXISTS) - SET(CMAKE_SHARED_MODULE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) -ENDIF(NOT CMAKE_MODULE_EXISTS) # Create a set of shared library variable specific to C++ # For 90% of the systems, these are the same flags as the C versions # so if these are not set just copy the flags from the c version @@ -158,6 +152,14 @@ IF(NOT CMAKE_INCLUDE_FLAG_SEP_CXX) SET(CMAKE_INCLUDE_FLAG_SEP_CXX ${CMAKE_INCLUDE_FLAG_SEP_C}) ENDIF(NOT CMAKE_INCLUDE_FLAG_SEP_CXX) +# for most systems a module is the same as a shared library +# so unless the variable CMAKE_MODULE_EXISTS is set just +# copy the values from the LIBRARY variables +IF(NOT CMAKE_MODULE_EXISTS) + SET(CMAKE_SHARED_MODULE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) + SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS}) +ENDIF(NOT CMAKE_MODULE_EXISTS) + # repeat for modules IF(NOT CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS) SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS}) diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index efcba29..ade6d58 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -50,7 +50,7 @@ IF(NOT CMAKE_Fortran_COMPILER) # fort77: native F77 compiler under HP-UX (and some older Crays) # frt: Fujitsu F77 compiler # pathf90/pathf95/pathf2003: PathScale Fortran compiler - # pgf77/pgf90/pgf95: Portland Group F77/F90/F95 compilers + # pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers # xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers # lf95: Lahey-Fujitsu F95 compiler # fl32: Microsoft Fortran 77 "PowerStation" compiler @@ -64,8 +64,8 @@ IF(NOT CMAKE_Fortran_COMPILER) # then 77 or older compilers, gnu is always last in the group, # so if you paid for a compiler it is picked by default. SET(CMAKE_Fortran_COMPILER_LIST - ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 lf95 xlf95 fort - gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77 + ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95 + fort gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77 frt pgf77 xlf fl32 af77 g77 f77 ) @@ -73,7 +73,7 @@ IF(NOT CMAKE_Fortran_COMPILER) SET(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77) SET(_Fortran_COMPILER_NAMES_Intel ifort ifc efc) SET(_Fortran_COMPILER_NAMES_Absoft af95 af90 af77) - SET(_Fortran_COMPILER_NAMES_PGI pgf95 pgf90 pgf77) + SET(_Fortran_COMPILER_NAMES_PGI pgf95 pgfortran pgf90 pgf77) SET(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90) SET(_Fortran_COMPILER_NAMES_XL xlf) SET(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf) diff --git a/Modules/CMakeExpandImportedTargets.cmake b/Modules/CMakeExpandImportedTargets.cmake new file mode 100644 index 0000000..fba071a --- /dev/null +++ b/Modules/CMakeExpandImportedTargets.cmake @@ -0,0 +1,129 @@ +# CMAKE_EXPAND_IMPORTED_TARGETS(<var> LIBRARIES lib1 lib2...libN +# [CONFIGURATION <config>] ) +# +# CMAKE_EXPAND_IMPORTED_TARGETS() takes a list of libraries and replaces +# all imported targets contained in this list with their actual file paths +# of the referenced libraries on disk, including the libraries from their +# link interfaces. +# If a CONFIGURATION is given, it uses the respective configuration of the +# imported targets if it exists. If no CONFIGURATION is given, it uses +# the first configuration from ${CMAKE_CONFIGURATION_TYPES} if set, otherwise +# ${CMAKE_BUILD_TYPE}. +# This macro is used by all Check*.cmake files which use +# TRY_COMPILE() or TRY_RUN() and support CMAKE_REQUIRED_LIBRARIES , so that +# these checks support imported targets in CMAKE_REQUIRED_LIBRARIES: +# cmake_expand_imported_targets(expandedLibs LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} +# CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}" ) + + +#============================================================================= +# Copyright 2012 Kitware, Inc. +# Copyright 2009-2012 Alexander Neundorf <neundorf@kde.org> +# +# 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.) + +include(CMakeParseArguments) + +function(CMAKE_EXPAND_IMPORTED_TARGETS _RESULT ) + + set(options ) + set(oneValueArgs CONFIGURATION ) + set(multiValueArgs LIBRARIES ) + + cmake_parse_arguments(CEIT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(CEIT_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to CMAKE_EXPAND_IMPORTED_TARGETS(): \"${CEIT_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT CEIT_CONFIGURATION) + if(CMAKE_CONFIGURATION_TYPES) + list(GET CMAKE_CONFIGURATION_TYPES 0 CEIT_CONFIGURATION) + else() + set(CEIT_CONFIGURATION ${CMAKE_BUILD_TYPE}) + endif() + endif() + + # handle imported library targets + + set(_CCSR_REQ_LIBS ${CEIT_LIBRARIES}) + + set(_CHECK_FOR_IMPORTED_TARGETS TRUE) + set(_CCSR_LOOP_COUNTER 0) + while(_CHECK_FOR_IMPORTED_TARGETS) + math(EXPR _CCSR_LOOP_COUNTER "${_CCSR_LOOP_COUNTER} + 1 ") + set(_CCSR_NEW_REQ_LIBS ) + set(_CHECK_FOR_IMPORTED_TARGETS FALSE) + foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS}) + get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS) + if (_importedConfigs) +# message(STATUS "Detected imported target ${_CURRENT_LIB}") + # Ok, so this is an imported target. + # First we get the imported configurations. + # Then we get the location of the actual library on disk of the first configuration. + # then we'll get its link interface libraries property, + # iterate through it and replace all imported targets we find there + # with there actual location. + + # guard against infinite loop: abort after 100 iterations ( 100 is arbitrary chosen) + if ("${_CCSR_LOOP_COUNTER}" LESS 100) + set(_CHECK_FOR_IMPORTED_TARGETS TRUE) +# else ("${_CCSR_LOOP_COUNTER}" LESS 1) +# message(STATUS "********* aborting loop, counter : ${_CCSR_LOOP_COUNTER}") + endif ("${_CCSR_LOOP_COUNTER}" LESS 100) + + # if one of the imported configurations equals ${CMAKE_TRY_COMPILE_CONFIGURATION}, + # use it, otherwise simply use the first one: + list(FIND _importedConfigs "${CEIT_CONFIGURATION}" _configIndexToUse) + if("${_configIndexToUse}" EQUAL -1) + set(_configIndexToUse 0) + endif("${_configIndexToUse}" EQUAL -1) + list(GET _importedConfigs ${_configIndexToUse} _importedConfigToUse) + + get_target_property(_importedLocation "${_CURRENT_LIB}" IMPORTED_LOCATION_${_importedConfigToUse}) + get_target_property(_linkInterfaceLibs "${_CURRENT_LIB}" IMPORTED_LINK_INTERFACE_LIBRARIES_${_importedConfigToUse} ) + + list(APPEND _CCSR_NEW_REQ_LIBS "${_importedLocation}") +# message(STATUS "Appending lib ${_CURRENT_LIB} as ${_importedLocation}") + if(_linkInterfaceLibs) + foreach(_currentLinkInterfaceLib ${_linkInterfaceLibs}) +# message(STATUS "Appending link interface lib ${_currentLinkInterfaceLib}") + if(_currentLinkInterfaceLib) + list(APPEND _CCSR_NEW_REQ_LIBS "${_currentLinkInterfaceLib}" ) + endif(_currentLinkInterfaceLib) + endforeach(_currentLinkInterfaceLib "${_linkInterfaceLibs}") + endif(_linkInterfaceLibs) + else(_importedConfigs) + # "Normal" libraries are just used as they are. + list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" ) +# message(STATUS "Appending lib directly: ${_CURRENT_LIB}") + endif(_importedConfigs) + endforeach(_CURRENT_LIB ${_CCSR_REQ_LIBS}) + + set(_CCSR_REQ_LIBS ${_CCSR_NEW_REQ_LIBS} ) + endwhile(_CHECK_FOR_IMPORTED_TARGETS) + + # Finally we iterate once more over all libraries. This loop only removes + # all remaining imported target names (there shouldn't be any left anyway). + set(_CCSR_NEW_REQ_LIBS ) + foreach(_CURRENT_LIB ${_CCSR_REQ_LIBS}) + get_target_property(_importedConfigs "${_CURRENT_LIB}" IMPORTED_CONFIGURATIONS) + if (NOT _importedConfigs) + list(APPEND _CCSR_NEW_REQ_LIBS "${_CURRENT_LIB}" ) +# message(STATUS "final: appending ${_CURRENT_LIB}") + else (NOT _importedConfigs) +# message(STATUS "final: skipping ${_CURRENT_LIB}") + endif (NOT _importedConfigs) + endforeach(_CURRENT_LIB ${_CCSR_REQ_LIBS}) +# message(STATUS "setting -${_RESULT}- to -${_CCSR_NEW_REQ_LIBS}-") + set(${_RESULT} "${_CCSR_NEW_REQ_LIBS}" PARENT_SCOPE) + +endfunction() diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake index 4296577..59c7ba5 100644 --- a/Modules/CMakeFindPackageMode.cmake +++ b/Modules/CMakeFindPackageMode.cmake @@ -71,7 +71,8 @@ if(UNIX) # use the file utility to check whether itself is 64 bit: find_program(FILE_EXECUTABLE file) if(FILE_EXECUTABLE) - execute_process(COMMAND "${FILE_EXECUTABLE}" "${FILE_EXECUTABLE}" OUTPUT_VARIABLE fileOutput ERROR_QUIET) + get_filename_component(FILE_ABSPATH "${FILE_EXECUTABLE}" ABSOLUTE) + execute_process(COMMAND "${FILE_ABSPATH}" "${FILE_ABSPATH}" OUTPUT_VARIABLE fileOutput ERROR_QUIET) if("${fileOutput}" MATCHES "64-bit") set(CMAKE_SIZEOF_VOID_P 8) endif() diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake index aed1fd2..76cf34e 100644 --- a/Modules/CMakeFortranInformation.cmake +++ b/Modules/CMakeFortranInformation.cmake @@ -109,6 +109,14 @@ IF(NOT DEFINED CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG) SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_C_FLAG}) ENDIF() +# for most systems a module is the same as a shared library +# so unless the variable CMAKE_MODULE_EXISTS is set just +# copy the values from the LIBRARY variables +IF(NOT CMAKE_MODULE_EXISTS) + SET(CMAKE_SHARED_MODULE_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_Fortran_FLAGS}) + SET(CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS}) +ENDIF(NOT CMAKE_MODULE_EXISTS) + # repeat for modules IF(NOT DEFINED CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS) SET(CMAKE_SHARED_MODULE_CREATE_Fortran_FLAGS ${CMAKE_SHARED_MODULE_CREATE_C_FLAGS}) diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake index 6cd8fe6..ee8040e 100644 --- a/Modules/CMakeGenericSystem.cmake +++ b/Modules/CMakeGenericSystem.cmake @@ -39,6 +39,8 @@ SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) SET (CMAKE_SKIP_RPATH "NO" CACHE BOOL "If set, runtime paths are not added when using shared libraries.") +SET (CMAKE_SKIP_INSTALL_RPATH "NO" CACHE BOOL + "If set, runtime paths are not added when installing shared libraries, but are added when building.") SET(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.") @@ -168,5 +170,6 @@ ENDIF(CMAKE_HOST_UNIX) MARK_AS_ADVANCED( CMAKE_SKIP_RPATH + CMAKE_SKIP_INSTALL_RPATH CMAKE_VERBOSE_MAKEFILE ) diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake new file mode 100644 index 0000000..f15c3e0 --- /dev/null +++ b/Modules/CMakeNinjaFindMake.cmake @@ -0,0 +1,17 @@ + +#============================================================================= +# Copyright 2011 Kitware, Inc. +# +# 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_PROGRAM(CMAKE_MAKE_PROGRAM ninja + DOC "Program used to build from build.ninja files.") +MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM) diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake new file mode 100644 index 0000000..b174e98 --- /dev/null +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -0,0 +1,189 @@ +# - CONFIGURE_PACKAGE_CONFIG_FILE(), WRITE_BASIC_PACKAGE_VERSION_FILE() +# +# CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path> +# [PATH_VARS <var1> <var2> ... <varN>] +# [NO_SET_AND_CHECK_MACRO] ) +# +# CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain +# CONFIGURE_FILE() command when creating the <Name>Config.cmake or <Name>-config.cmake +# file for installing a project or library. It helps making the resulting package +# relocatable by avoiding hardcoded paths in the installed Config.cmake file. +# +# In a FooConfig.cmake file there may be code like this to make the +# install destinations know to the using project: +# set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" ) +# set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" ) +# set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" ) +# ...logic to determine installedPrefix from the own location... +# set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" ) +# All 4 options shown above are not sufficient, since the first 3 hardcode +# the absolute directory locations, and the 4th case works only if the logic +# to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains +# a relative path, which in general cannot be guaranteed. +# This has the effect that the resulting FooConfig.cmake file would work poorly +# under Windows and OSX, where users are used to choose the install location +# of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX +# was set at build/cmake time. +# +# Using CONFIGURE_PACKAGE_CONFIG_FILE() helps. If used correctly, it makes the +# resulting FooConfig.cmake file relocatable. +# Usage: +# 1. write a FooConfig.cmake.in file as you are used to +# 2. insert a line containing only the string "@PACKAGE_INIT@" +# 3. instead of SET(FOO_DIR "@SOME_INSTALL_DIR@"), use SET(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@") +# (this must be after the @PACKAGE_INIT@ line) +# 4. instead of using the normal CONFIGURE_FILE(), use CONFIGURE_PACKAGE_CONFIG_FILE() +# +# The <input> and <output> arguments are the input and output file, the same way +# as in CONFIGURE_FILE(). +# +# The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake +# file will be installed to. This can either be a relative or absolute path, both work. +# +# The variables <var1> to <varN> given as PATH_VARS are the variables which contain +# install destinations. For each of them the macro will create a helper variable +# PACKAGE_<var...>. These helper variables must be used +# in the FooConfig.cmake.in file for setting the installed location. They are calculated +# by CONFIGURE_PACKAGE_CONFIG_FILE() so that they are always relative to the +# installed location of the package. This works both for relative and also for absolute locations. +# For absolute locations it works only if the absolute location is a subdirectory +# of CMAKE_INSTALL_PREFIX. +# +# By default configure_package_config_file() also generates a macro set_and_check() +# into the FooConfig.cmake file. This should be used instead of the normal set() +# command for setting directories and file locations. Additionally to setting the +# variable it also checks that the referenced file or directory actually exists +# and fails with a FATAL_ERROR otherwise. This makes sure that the created +# FooConfig.cmake file does not contain wrong references. +# When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the +# FooConfig.cmake file. +# +# For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE(). +# +# +# WRITE_BASIC_PACKAGE_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion) ) +# +# Writes a file for use as <package>ConfigVersion.cmake file to <filename>. +# See the documentation of FIND_PACKAGE() for details on this. +# filename is the output filename, it should be in the build tree. +# major.minor.patch is the version number of the project to be installed +# The COMPATIBILITY mode AnyNewerVersion means that the installed package version +# will be considered compatible if it is newer or exactly the same as the requested version. +# If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion +# in that the major version number must be the same as requested, e.g. version 2.0 will +# not be considered compatible if 1.0 is requested. +# If your project has more elaborated version matching rules, you will need to write your +# own custom ConfigVersion.cmake file instead of using this macro. +# +# Internally, this macro executes configure_file() to create the resulting +# version file. Depending on the COMPATIBLITY, either the file +# BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in +# is used. Please note that these two files are internal to CMake and you should +# not call configure_file() on them yourself, but they can be used as starting +# point to create more sophisticted custom ConfigVersion.cmake files. +# +# +# Example using both configure_package_config_file() and write_basic_package_version_file(): +# CMakeLists.txt: +# set(INCLUDE_INSTALL_DIR include/ ... CACHE ) +# set(LIB_INSTALL_DIR lib/ ... CACHE ) +# set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE ) +# ... +# include(CMakePackageConfigHelpers) +# configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake +# INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake +# PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR) +# write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake +# VERSION 1.2.3 +# COMPATIBILITY SameMajorVersion ) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake +# DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake ) +# +# With a FooConfig.cmake.in: +# set(FOO_VERSION x.y.z) +# ... +# @PACKAGE_INIT@ +# ... +# set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +# set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@") + + +#============================================================================= +# Copyright 2012 Alexander Neundorf <neundorf@kde.org> +# +# 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.) + +include(CMakeParseArguments) + +include(WriteBasicConfigVersionFile) + +macro(WRITE_BASIC_PACKAGE_VERSION_FILE) + write_basic_config_version_file(${ARGN}) +endmacro() + + +function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile) + set(options NO_SET_AND_CHECK_MACRO) + set(oneValueArgs INSTALL_DESTINATION ) + set(multiValueArgs PATH_VARS ) + + cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(CCF_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT CCF_INSTALL_DESTINATION) + message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()") + endif() + + if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}") + set(absInstallDir "${CCF_INSTALL_DESTINATION}") + else() + set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}") + endif() + file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" ) + + foreach(var ${CCF_PATH_VARS}) + if(NOT DEFINED ${var}) + message(FATAL_ERROR "Variable ${var} does not exist") + else() + if(IS_ABSOLUTE "${${var}}") + string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}" + PACKAGE_${var} "${${var}}") + else() + set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}") + endif() + endif() + endforeach() + + set(PACKAGE_INIT " +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE) +") + + if(NOT CCF_NO_SET_AND_CHECK_MACRO) + set(PACKAGE_INIT "${PACKAGE_INIT} +macro(set_and_check _var _file) + set(\${_var} \"\${_file}\") + if(NOT EXISTS \"\${_file}\") + message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\") + endif() +endmacro() +") + endif() + + set(PACKAGE_INIT "${PACKAGE_INIT} +####################################################################################") + + configure_file("${_inputFile}" "${_outputFile}" @ONLY) + +endfunction() diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 2cc27cf..571770e 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -1,5 +1,7 @@ -# - Build binary and source package installers -# +##section Variables common to all CPack generators +##end +##module +# - Build binary and source package installers. # The CPack module generates binary and source installers in a variety # of formats using the cpack program. Inclusion of the CPack module # adds two new targets to the resulting makefiles, package and @@ -29,16 +31,16 @@ # on a per-generator basis. It only need contain overrides. # # Here's how it works: -# - cpack runs -# - it includes CPackConfig.cmake -# - it iterates over the generators listed in that file's -# CPACK_GENERATOR list variable (unless told to use just a -# specific one via -G on the command line...) +# - cpack runs +# - it includes CPackConfig.cmake +# - it iterates over the generators listed in that file's +# CPACK_GENERATOR list variable (unless told to use just a +# specific one via -G on the command line...) # -# - foreach generator, it then -# - sets CPACK_GENERATOR to the one currently being iterated -# - includes the CPACK_PROJECT_CONFIG_FILE -# - produces the package for that generator +# - foreach generator, it then +# - sets CPACK_GENERATOR to the one currently being iterated +# - includes the CPACK_PROJECT_CONFIG_FILE +# - produces the package for that generator # # This is the key: For each generator listed in CPACK_GENERATOR # in CPackConfig.cmake, cpack will *reset* CPACK_GENERATOR @@ -48,174 +50,216 @@ # Before including this CPack module in your CMakeLists.txt file, # there are a variety of variables that can be set to customize # the resulting installers. The most commonly-used variables are: -# -# CPACK_PACKAGE_NAME - The name of the package (or application). If -# not specified, defaults to the project name. -# -# CPACK_PACKAGE_VENDOR - The name of the package vendor (e.g., -# "Kitware"). -# -# CPACK_PACKAGE_VERSION_MAJOR - Package major Version -# -# CPACK_PACKAGE_VERSION_MINOR - Package minor Version -# -# CPACK_PACKAGE_VERSION_PATCH - Package patch Version -# -# CPACK_PACKAGE_DESCRIPTION_FILE - A text file used to describe the -# project. Used, for example, the introduction screen of a -# CPack-generated Windows installer to describe the project. -# -# CPACK_PACKAGE_DESCRIPTION_SUMMARY - Short description of the -# project (only a few words). -# -# CPACK_PACKAGE_FILE_NAME - The name of the package file to generate, -# not including the extension. For example, cmake-2.6.1-Linux-i686. -# -# CPACK_PACKAGE_INSTALL_DIRECTORY - Installation directory on the -# target system, e.g., "CMake 2.5". -# -# CPACK_PROJECT_CONFIG_FILE - File included at cpack time, once per -# generator after setting CPACK_GENERATOR to the actual generator -# being used. Allows per-generator setting of CPACK_* variables at -# cpack time. -# -# CPACK_RESOURCE_FILE_LICENSE - License file for the project, which -# will typically be displayed to the user (often with an explicit -# "Accept" button, for graphical installers) prior to installation. -# -# CPACK_RESOURCE_FILE_README - ReadMe file for the project, which -# typically describes in some detail -# -# CPACK_RESOURCE_FILE_WELCOME - Welcome file for the project, which -# welcomes users to this installer. Typically used in the graphical -# installers on Windows and Mac OS X. -# -# CPACK_MONOLITHIC_INSTALL - Disables the component-based -# installation mechanism, so that all components are always installed. -# -# CPACK_GENERATOR - List of CPack generators to use. If not -# specified, CPack will create a set of options (e.g., -# CPACK_BINARY_NSIS) allowing the user to enable/disable individual -# generators. -# -# CPACK_OUTPUT_CONFIG_FILE - The name of the CPack configuration file -# for binary installers that will be generated by the CPack -# module. Defaults to CPackConfig.cmake. -# -# CPACK_PACKAGE_EXECUTABLES - Lists each of the executables along -# with a text label, to be used to create Start Menu shortcuts on -# Windows. For example, setting this to the list ccmake;CMake will -# create a shortcut named "CMake" that will execute the installed -# executable ccmake. -# -# CPACK_STRIP_FILES - List of files to be stripped. Starting with -# CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which -# enables stripping of all files (a list of files evaluates to TRUE -# in CMake, so this change is compatible). +##end +# +##variable +# CPACK_PACKAGE_NAME - The name of the package (or application). If +# not specified, defaults to the project name. +##end +# +##variable +# CPACK_PACKAGE_VENDOR - The name of the package vendor. (e.g., +# "Kitware"). +##end +# +##variable +# CPACK_PACKAGE_VERSION_MAJOR - Package major Version +##end +# +##variable +# CPACK_PACKAGE_VERSION_MINOR - Package minor Version +##end +# +##variable +# CPACK_PACKAGE_VERSION_PATCH - Package patch Version +##end +# +##variable +# CPACK_PACKAGE_DESCRIPTION_FILE - A text file used to describe the +# project. Used, for example, the introduction screen of a +# CPack-generated Windows installer to describe the project. +##end +# +##variable +# CPACK_PACKAGE_DESCRIPTION_SUMMARY - Short description of the +# project (only a few words). +##end +# +##variable +# CPACK_PACKAGE_FILE_NAME - The name of the package file to generate, +# not including the extension. For example, cmake-2.6.1-Linux-i686. +# The default value is +# ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}. +##end +# +##variable +# CPACK_PACKAGE_INSTALL_DIRECTORY - Installation directory on the +# target system. This may be used by some CPack generators +# like NSIS to create an installation directory e.g., "CMake 2.5" +# below the installation prefix. All installed element will be +# put inside this directory. +##end +# +##variable +# CPACK_PACKAGE_ICON - A branding image that will be displayed inside +# the installer (used by GUI installers). +##end +# +##variable +# CPACK_PROJECT_CONFIG_FILE - CPack-time project CPack configuration +# file. This file included at cpack time, once per +# generator after CPack has set CPACK_GENERATOR to the actual generator +# being used. It allows per-generator setting of CPACK_* variables at +# cpack time. +##end +# +##variable +# CPACK_RESOURCE_FILE_LICENSE - License to be embedded in the installer. It +# will typically be displayed to the user by the produced installer +# (often with an explicit "Accept" button, for graphical installers) +# prior to installation. This license file is NOT added to installed +# file but is used by some CPack generators like NSIS. If you want +# to install a license file (may be the same as this one) +# along with your project you must add an appropriate CMake INSTALL +# command in your CMakeLists.txt. +##end +# +##variable +# CPACK_RESOURCE_FILE_README - ReadMe file to be embedded in the installer. It +# typically describes in some detail the purpose of the project +# during the installation. Not all CPack generators uses +# this file. +##end +# +##variable +# CPACK_RESOURCE_FILE_WELCOME - Welcome file to be embedded in the +# installer. It welcomes users to this installer. +# Typically used in the graphical installers on Windows and Mac OS X. +##end +# +##variable +# CPACK_MONOLITHIC_INSTALL - Disables the component-based +# installation mechanism. When set the component specification is ignored +# and all installed items are put in a single "MONOLITHIC" package. +# Some CPack generators do monolithic packaging by default and +# may be asked to do component packaging by setting +# CPACK_<GENNAME>_COMPONENT_INSTALL to 1/TRUE. +##end +# +##variable +# CPACK_GENERATOR - List of CPack generators to use. If not +# specified, CPack will create a set of options CPACK_BINARY_<GENNAME> (e.g., +# CPACK_BINARY_NSIS) allowing the user to enable/disable individual +# generators. This variable may be used on the command line +# as well as in: +# +# cpack -D CPACK_GENERATOR="ZIP;TGZ" /path/to/build/tree +##end +# +##variable +# CPACK_OUTPUT_CONFIG_FILE - The name of the CPack binary configuration +# file. This file is the CPack configuration generated by the CPack module +# for binary installers. Defaults to CPackConfig.cmake. +##end +# +##variable +# CPACK_PACKAGE_EXECUTABLES - Lists each of the executables and associated +# text label to be used to create Start Menu shortcuts. For example, +# setting this to the list ccmake;CMake will +# create a shortcut named "CMake" that will execute the installed +# executable ccmake. Not all CPack generators use it (at least NSIS and +# OSXX11 do). +##end +# +##variable +# CPACK_STRIP_FILES - List of files to be stripped. Starting with +# CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which +# enables stripping of all files (a list of files evaluates to TRUE +# in CMake, so this change is compatible). +##end # # The following CPack variables are specific to source packages, and # will not affect binary packages: # -# CPACK_SOURCE_PACKAGE_FILE_NAME - The name of the source package, -# e.g., cmake-2.6.1 -# -# CPACK_SOURCE_STRIP_FILES - List of files in the source tree that -# will be stripped. Starting with CMake 2.6.0 -# CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables -# stripping of all files (a list of files evaluates to TRUE in CMake, -# so this change is compatible). -# -# CPACK_SOURCE_GENERATOR - List of generators used for the source -# packages. As with CPACK_GENERATOR, if this is not specified then -# CPack will create a set of options (e.g., CPACK_SOURCE_ZIP) -# allowing users to select which packages will be generated. -# -# CPACK_SOURCE_OUTPUT_CONFIG_FILE - The name of the CPack -# configuration file for source installers that will be generated by -# the CPack module. Defaults to CPackSourceConfig.cmake. -# -# CPACK_SOURCE_IGNORE_FILES - Pattern of files in the source tree -# that won't be packaged when building a source package. This is a -# list of patterns, e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.* -# -# The following variables are specific to the DragNDrop installers -# built on Mac OS X: -# -# CPACK_DMG_VOLUME_NAME - The volume name of the generated disk -# image. Defaults to CPACK_PACKAGE_FILE_NAME. -# -# CPACK_DMG_FORMAT - The disk image format. Common values are UDRO -# (UDIF read-only), UDZO (UDIF zlib-compressed) or UDBZ (UDIF -# bzip2-compressed). Refer to hdiutil(1) for more information on -# other available formats. -# -# CPACK_DMG_DS_STORE - Path to a custom .DS_Store file which e.g. -# can be used to specify the Finder window position/geometry and -# layout (such as hidden toolbars, placement of the icons etc.). -# This file has to be generated by the Finder (either manually or -# through OSA-script) using a normal folder from which the .DS_Store -# file can then be extracted. -# -# CPACK_DMG_BACKGROUND_IMAGE - Path to an image file which is to be -# used as the background for the Finder Window when the disk image -# is opened. By default no background image is set. The background -# image is applied after applying the custom .DS_Store file. -# -# CPACK_COMMAND_HDIUTIL - Path to the hdiutil(1) command used to -# operate on disk image files on Mac OS X. This variable can be used -# to override the automatically detected command (or specify its -# location if the auto-detection fails to find it.) -# -# CPACK_COMMAND_SETFILE - Path to the SetFile(1) command used to set -# extended attributes on files and directories on Mac OS X. This -# variable can be used to override the automatically detected -# command (or specify its location if the auto-detection fails to -# find it.) -# -# CPACK_COMMAND_REZ - Path to the Rez(1) command used to compile -# resources on Mac OS X. This variable can be used to override the -# automatically detected command (or specify its location if the -# auto-detection fails to find it.) -# -# The following variable is specific to installers build on Mac OS X -# using PackageMaker: -# -# CPACK_OSX_PACKAGE_VERSION - The version of Mac OS X that the -# resulting PackageMaker archive should be compatible -# with. Different versions of Mac OS X support different -# features. For example, CPack can only build component-based -# installers for Mac OS X 10.4 or newer, and can only build -# installers that download component son-the-fly for Mac OS X 10.5 -# or newer. If left blank, this value will be set to the minimum -# version of Mac OS X that supports the requested features. Set this -# variable to some value (e.g., 10.4) only if you want to guarantee -# that your installer will work on that version of Mac OS X, and -# don't mind missing extra features available in the installer -# shipping with later versions of Mac OS X. +##variable +# CPACK_SOURCE_PACKAGE_FILE_NAME - The name of the source package. For +# example cmake-2.6.1. +##end +# +##variable +# CPACK_SOURCE_STRIP_FILES - List of files in the source tree that +# will be stripped. Starting with CMake 2.6.0 +# CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables +# stripping of all files (a list of files evaluates to TRUE in CMake, +# so this change is compatible). +##end +# +##variable +# CPACK_SOURCE_GENERATOR - List of generators used for the source +# packages. As with CPACK_GENERATOR, if this is not specified then +# CPack will create a set of options (e.g., CPACK_SOURCE_ZIP) +# allowing users to select which packages will be generated. +##end +# +##variable +# CPACK_SOURCE_OUTPUT_CONFIG_FILE - The name of the CPack source +# configuration file. This file is the CPack configuration generated by the +# CPack module for source installers. Defaults to CPackSourceConfig.cmake. +##end +# +##variable +# CPACK_SOURCE_IGNORE_FILES - Pattern of files in the source tree +# that won't be packaged when building a source package. This is a +# list of regular expression patterns (that must be properly escaped), +# e.g., /CVS/;/\\.svn/;\\.swp$;\\.#;/#;.*~;cscope.* +##end # # The following variables are for advanced uses of CPack: # -# CPACK_CMAKE_GENERATOR - What CMake generator should be used if the -# project is CMake project. Defaults to the value of CMAKE_GENERATOR; -# few users will want to change this setting. -# -# CPACK_INSTALL_CMAKE_PROJECTS - List of four values that specify -# what project to install. The four values are: Build directory, -# Project Name, Project Component, Directory. If omitted, CPack will -# build an installer that installers everything. -# -# CPACK_SYSTEM_NAME - System name, defaults to the value of -# ${CMAKE_SYSTEM_NAME}. -# -# CPACK_PACKAGE_VERSION - Package full version, used internally. By -# default, this is built from CPACK_PACKAGE_VERSION_MAJOR, -# CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH. -# -# CPACK_TOPLEVEL_TAG - Directory for the installed files. -# -# CPACK_INSTALL_COMMANDS - Extra commands to install components. -# -# CPACK_INSTALLED_DIRECTORIES - Extra directories to install. +##variable +# CPACK_CMAKE_GENERATOR - What CMake generator should be used if the +# project is CMake project. Defaults to the value of CMAKE_GENERATOR +# few users will want to change this setting. +##end +# +##variable +# CPACK_INSTALL_CMAKE_PROJECTS - List of four values that specify +# what project to install. The four values are: Build directory, +# Project Name, Project Component, Directory. If omitted, CPack will +# build an installer that installers everything. +##end +# +##variable +# CPACK_SYSTEM_NAME - System name, defaults to the value of +# ${CMAKE_SYSTEM_NAME}. +##end +# +##variable +# CPACK_PACKAGE_VERSION - Package full version, used internally. By +# default, this is built from CPACK_PACKAGE_VERSION_MAJOR, +# CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH. +##end +# +##variable +# CPACK_TOPLEVEL_TAG - Directory for the installed files. +##end +# +##variable +# CPACK_INSTALL_COMMANDS - Extra commands to install components. +##end +# +##variable +# CPACK_INSTALLED_DIRECTORIES - Extra directories to install. +##end +# +##variable +# CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Registry key used when +# installing this project. This is only used +# by installer for Windows. +##end +##variable +# CPACK_CREATE_DESKTOP_LINKS - List of desktop links to create. +##end # #============================================================================= @@ -259,7 +303,7 @@ MACRO(cpack_set_if_not_set name value) ENDIF(NOT DEFINED "${name}") ENDMACRO(cpack_set_if_not_set) -# Macro to encode variables for the configuration file +# cpack_encode_variables - Macro to encode variables for the configuration file # find any variable that starts with CPACK and create a variable # _CPACK_OTHER_VARIABLES_ that contains SET commands for # each cpack variable. _CPACK_OTHER_VARIABLES_ is then @@ -350,6 +394,12 @@ macro(cpack_optional_append _list _cond _item) endif(${_cond}) endmacro(cpack_optional_append _list _cond _item) +##variable +# CPACK_BINARY_<GENNAME> - CPack generated options for binary generators. The +# CPack.cmake module generates (when CPACK_GENERATOR is not set) +# a set of CMake options (see CMake option command) which may then be used to +# select the CPack generator(s) to be used when launching the package target. +##end # Provide options to choose generators # we might check here if the required tools for the generates exist # and set the defaults according to the results diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake index 3ac4ea8..0da51e3 100644 --- a/Modules/CPackBundle.cmake +++ b/Modules/CPackBundle.cmake @@ -1,25 +1,36 @@ +##section Variables specific to CPack Bundle generator +##end +##module # - CPack Bundle generator (Mac OS X) specific options # # Installers built on Mac OS X using the Bundle generator use the -# aforementioned DragNDrop variables, plus the following Bundle-specific -# parameters: +# aforementioned DragNDrop (CPACK_DMG_xxx) variables, plus +# the following Bundle-specific parameters (CPACK_BUNDLE_xxx). +##end # -# CPACK_BUNDLE_NAME - The name of the generated bundle. This -# appears in the OSX finder as the bundle name. Required. +##variable +# CPACK_BUNDLE_NAME - The name of the generated bundle. This +# appears in the OSX finder as the bundle name. Required. +##end # -# CPACK_BUNDLE_PLIST - Path to an OSX plist file that will be used -# as the Info.plist for the generated bundle. This assumes that -# the caller has generated or specified their own Info.plist file. -# Required. +##variable +# CPACK_BUNDLE_PLIST - Path to an OSX plist file that will be used +# for the generated bundle. This assumes that the caller has generated +# or specified their own Info.plist file. Required. +##end # -# CPACK_BUNDLE_ICON - Path to an OSX icns file that will be used as -# the icon for the generated bundle. This is the icon that appears -# in the OSX finder for the bundle, and in the OSX dock when the -# bundle is opened. Required. +##variable +# CPACK_BUNDLE_ICON - Path to an OSX icon file that will be used as +# the icon for the generated bundle. This is the icon that appears in the +# OSX finder for the bundle, and in the OSX dock when the bundle is opened. +# Required. +##end # -# CPACK_BUNDLE_STARTUP_SCRIPT - Path to an executable or script that -# will be run whenever an end-user double-clicks the generated bundle -# in the OSX Finder. Optional. +##variable +# CPACK_BUNDLE_STARTUP_COMMAND - Path to a startup script. This is a path to +# an executable or script that will be run whenever an end-user double-clicks +# the generated bundle in the OSX Finder. Optional. +##end #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 1c10372..1598703 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -1,3 +1,6 @@ +##section Variables concerning CPack Components +##end +##module # - Build binary and source package installers # # The CPackComponent module is the module which handles @@ -20,7 +23,54 @@ # components are identified by the COMPONENT argument of CMake's # INSTALL commands, and should be further described by the following # CPack commands: -# +##end +# +##variable +# CPACK_COMPONENTS_ALL - The list of component to install. +# +# The default value of this variable is computed by CPack +# and contains all components defined by the project. The +# user may set it to only include the specified components. +##end +# +##variable +# CPACK_<GENNAME>_COMPONENT_INSTALL - Enable/Disable component install for +# CPack generator <GENNAME>. +# +# Each CPack Generator (RPM, DEB, ARCHIVE, NSIS, DMG, etc...) has a legacy +# default behavior. e.g. RPM builds monolithic whereas NSIS builds component. +# One can change the default behavior by setting this variable to 0/1 or OFF/ON. +##end +##variable +# CPACK_COMPONENTS_GROUPING - Specify how components are grouped for multi-package +# component-aware CPack generators. +# +# Some generators like RPM or ARCHIVE family (TGZ, ZIP, ...) generates several +# packages files when asked for component packaging. They group the component +# differently depending on the value of this variable: +# - ONE_PER_GROUP (default): creates one package file per component group +# - ALL_COMPONENTS_IN_ONE : creates a single package with all (requested) component +# - IGNORE : creates one package per component, i.e. IGNORE component group +# One can specify different grouping for different CPack generator by using +# a CPACK_PROJECT_CONFIG_FILE. +##end +##variable +# CPACK_COMPONENT_<compName>_DISPLAY_NAME - The name to be displayed for a component. +##end +##variable +# CPACK_COMPONENT_<compName>_DESCRIPTION - The description of a component. +##end +##variable +# CPACK_COMPONENT_<compName>_GROUP - The group of a component. +##end +##variable +# CPACK_COMPONENT_<compName>_DEPENDS - The dependencies (list of components) +# on which this component depends. +##end +##variable +# CPACK_COMPONENT_<compName>_REQUIRED - True is this component is required. +##end +##macro # cpack_add_component - Describes a CPack installation component # named by the COMPONENT argument to a CMake INSTALL command. # @@ -90,7 +140,9 @@ # create a file with some name based on CPACK_PACKAGE_FILE_NAME and # the name of the component. See cpack_configure_downloads for more # information. +##end # +##macro # cpack_add_component_group - Describes a group of related CPack # installation components. # @@ -134,7 +186,9 @@ # # BOLD_TITLE indicates that the group title should appear in bold, # to call the user's attention to the group. +##end # +##macro # cpack_add_install_type - Add a new installation type containing a # set of predefined component selections to the graphical installer. # @@ -153,7 +207,9 @@ # DISPLAY_NAME is the displayed name of the install type, which will # typically show up in a drop-down box within a graphical # installer. This value can be any string. +##end # +##macro # cpack_configure_downloads - Configure CPack to download selected # components on-the-fly as part of the installation process. # @@ -203,6 +259,7 @@ # that can be called from Windows' Add/Remove Programs dialog (via the # "Modify" button) to change the set of installed components. NO_ADD_REMOVE # turns off this behavior. This option is ignored on Mac OS X. +##endmacro #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/CPackCygwin.cmake b/Modules/CPackCygwin.cmake new file mode 100644 index 0000000..7ed7f67 --- /dev/null +++ b/Modules/CPackCygwin.cmake @@ -0,0 +1,33 @@ +##section Variables specific to CPack Cygwin generator +##end +##module +# - Cygwin CPack generator (Cygwin). +# The following variable is specific to installers build on +# and/or for Cygwin: +##end +# +##variable +# CPACK_CYGWIN_PATCH_NUMBER - The Cygwin patch number. +# FIXME: This documentation is incomplete. +##end +##variable +# CPACK_CYGWIN_PATCH_FILE - The Cygwin patch file. +# FIXME: This documentation is incomplete. +##end +##variable +# CPACK_CYGWIN_BUILD_SCRIPT - The Cygwin build script. +# FIXME: This documentation is incomplete. +##end + +#============================================================================= +# Copyright 2006-2012 Kitware, Inc. +# +# 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.) diff --git a/Modules/CPackDMG.cmake b/Modules/CPackDMG.cmake new file mode 100644 index 0000000..e866bab --- /dev/null +++ b/Modules/CPackDMG.cmake @@ -0,0 +1,70 @@ +##section Variables specific to CPack DragNDrop generator +##end +##module +# - DragNDrop CPack generator (Mac OS X). +# The following variables are specific to the DragNDrop installers +# built on Mac OS X: +##end +# +##variable +# CPACK_DMG_VOLUME_NAME - The volume name of the generated disk +# image. Defaults to CPACK_PACKAGE_FILE_NAME. +##end +# +##variable +# CPACK_DMG_FORMAT - The disk image format. Common values are UDRO +# (UDIF read-only), UDZO (UDIF zlib-compressed) or UDBZ (UDIF +# bzip2-compressed). Refer to hdiutil(1) for more information on +# other available formats. +##end +# +##variable +# CPACK_DMG_DS_STORE - Path to a custom DS_Store file. This .DS_Store +# file e.g. can be used to specify the Finder window +# position/geometry and layout (such as hidden toolbars, placement of the +# icons etc.). This file has to be generated by the Finder (either manually or +# through OSA-script) using a normal folder from which the .DS_Store +# file can then be extracted. +##end +# +##variable +# CPACK_DMG_BACKGROUND_IMAGE - Path to a background image file. This +# file will be used as the background for the Finder Window when the disk +# image is opened. By default no background image is set. The background +# image is applied after applying the custom .DS_Store file. +##end +# +##variable +# CPACK_COMMAND_HDIUTIL - Path to the hdiutil(1) command used to +# operate on disk image files on Mac OS X. This variable can be used +# to override the automatically detected command (or specify its +# location if the auto-detection fails to find it.) +##end +# +##variable +# CPACK_COMMAND_SETFILE - Path to the SetFile(1) command used to set +# extended attributes on files and directories on Mac OS X. This +# variable can be used to override the automatically detected +# command (or specify its location if the auto-detection fails to +# find it.) +##end +# +##variable +# CPACK_COMMAND_REZ - Path to the Rez(1) command used to compile +# resources on Mac OS X. This variable can be used to override the +# automatically detected command (or specify its location if the +# auto-detection fails to find it.) +##end + +#============================================================================= +# Copyright 2006-2012 Kitware, Inc. +# +# 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.) diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index 26433bb..fe81dc9 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -1,3 +1,6 @@ +##section Variables specific to CPack Debian (DEB) generator +##end +##module # - The builtin (binary) CPack Deb generator (Unix only) # CPackDeb may be used to create Deb package using CPack. # CPackDeb is a CPack generator thus it uses the CPACK_XXX variables @@ -11,43 +14,63 @@ # the wiki: # http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#DEB_.28UNIX_only.29 # However as a handy reminder here comes the list of specific variables: +##end # +##variable # CPACK_DEBIAN_PACKAGE_NAME # Mandatory : YES # Default : CPACK_PACKAGE_NAME (lower case) # The debian package summary +##end +##variable # CPACK_DEBIAN_PACKAGE_VERSION # Mandatory : YES # Default : CPACK_PACKAGE_VERSION # The debian package version +##end +##variable # CPACK_DEBIAN_PACKAGE_ARCHITECTURE # Mandatory : YES # Default : Output of dpkg --print-architecture (or i386 if dpkg is not found) # The debian package architecture +##end +##variable # CPACK_DEBIAN_PACKAGE_DEPENDS # Mandatory : NO # Default : - # May be used to set deb dependencies. +##end +##variable # CPACK_DEBIAN_PACKAGE_MAINTAINER # Mandatory : YES # Default : CPACK_PACKAGE_CONTACT # The debian package maintainer +##end +##variable # CPACK_DEBIAN_PACKAGE_DESCRIPTION # Mandatory : YES # Default : CPACK_PACKAGE_DESCRIPTION_SUMMARY # The debian package description +##end +##variable # CPACK_DEBIAN_PACKAGE_SECTION # Mandatory : YES # Default : 'devel' # The debian package section +##end +##variable # CPACK_DEBIAN_PACKAGE_PRIORITY # Mandatory : YES # Default : 'optional' # The debian package priority +##end +##variable # CPACK_DEBIAN_PACKAGE_HOMEPAGE # Mandatory : NO # Default : - # The URL of the web site for this package +##end +##variable # CPACK_DEBIAN_PACKAGE_SHLIBDEPS # Mandatory : NO # Default : OFF @@ -57,11 +80,15 @@ # if you use this feature, because if you don't dpkg-shlibdeps # may fail to find your own shared libs. # See http://www.cmake.org/Wiki/CMake_RPATH_handling. +##end +##variable # CPACK_DEBIAN_PACKAGE_DEBUG # Mandatory : NO # Default : - # May be set when invoking cpack in order to trace debug information # during CPackDeb run. +##end +##variable # CPACK_DEBIAN_PACKAGE_PREDEPENDS # Mandatory : NO # Default : - @@ -69,12 +96,16 @@ # This field is like Depends, except that it also forces dpkg to complete installation of # the packages named before even starting the installation of the package which declares # the pre-dependency. +##end +##variable # CPACK_DEBIAN_PACKAGE_ENHANCES # Mandatory : NO # Default : - # see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # This field is similar to Suggests but works in the opposite direction. # It is used to declare that a package can enhance the functionality of another package. +##end +##variable # CPACK_DEBIAN_PACKAGE_BREAKS # Mandatory : NO # Default : - @@ -82,23 +113,30 @@ # When one binary package declares that it breaks another, dpkg will refuse to allow the # package which declares Breaks be installed unless the broken package is deconfigured first, # and it will refuse to allow the broken package to be reconfigured. +##end +##variable # CPACK_DEBIAN_PACKAGE_CONFLICTS # Mandatory : NO # Default : - # see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # When one binary package declares a conflict with another using a Conflicts field, # dpkg will refuse to allow them to be installed on the system at the same time. +##end +##variable # CPACK_DEBIAN_PACKAGE_PROVIDES # Mandatory : NO # Default : - # see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # A virtual package is one which appears in the Provides control field of another package. +##end +##variable # CPACK_DEBIAN_PACKAGE_REPLACES # Mandatory : NO # Default : - # see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # Packages can declare in their control file that they should overwrite # files in certain other packages, or completely replace other packages. +##end #============================================================================= # Copyright 2007-2009 Kitware, Inc. diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake index d9dab53..7d9f29b 100644 --- a/Modules/CPackNSIS.cmake +++ b/Modules/CPackNSIS.cmake @@ -1,70 +1,111 @@ +##section Variables specific to CPack NSIS generator +##end +##module # - CPack NSIS generator specific options # # The following variables are specific to the graphical installers built # on Windows using the Nullsoft Installation System. +##end # -# CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Registry key used when -# installing this project. -# +##variable # CPACK_NSIS_INSTALL_ROOT - The default installation directory presented # to the end user by the NSIS installer is under this root dir. The full # directory presented to the end user is: # ${CPACK_NSIS_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY} +##end # +##variable # CPACK_NSIS_MUI_ICON - The icon file (.ico) for the generated # install program. +##end # +##variable # CPACK_NSIS_MUI_UNIICON - The icon file (.ico) for the generated # uninstall program. +##end # -# CPACK_PACKAGE_ICON - A branding image that will be displayed inside -# the installer. -# +##variable # CPACK_NSIS_EXTRA_INSTALL_COMMANDS - Extra NSIS commands that will # be added to the install Section. +##end # +##variable # CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS - Extra NSIS commands that will # be added to the uninstall Section. +##end # +##variable # CPACK_NSIS_COMPRESSOR - The arguments that will be passed to the # NSIS SetCompressor command. +##end # +##variable # CPACK_NSIS_MODIFY_PATH - If this is set to "ON", then an extra page # will appear in the installer that will allow the user to choose # whether the program directory should be added to the system PATH # variable. +##end # +##variable # CPACK_NSIS_DISPLAY_NAME - The display name string that appears in # the Windows Add/Remove Program control panel +##end # +##variable # CPACK_NSIS_PACKAGE_NAME - The title displayed at the top of the # installer. +##end # +##variable # CPACK_NSIS_INSTALLED_ICON_NAME - A path to the executable that # contains the installer icon. +##end # +##variable # CPACK_NSIS_HELP_LINK - URL to a web site providing assistance in # installing your application. +##end # +##variable # CPACK_NSIS_URL_INFO_ABOUT - URL to a web site providing more # information about your application. +##end # +##variable # CPACK_NSIS_CONTACT - Contact information for questions and comments # about the installation process. +##end # +##variable # CPACK_NSIS_CREATE_ICONS_EXTRA - Additional NSIS commands for # creating start menu shortcuts. +##end # +##variable # CPACK_NSIS_DELETE_ICONS_EXTRA -Additional NSIS commands to # uninstall start menu shortcuts. +##end # +##variable # CPACK_NSIS_EXECUTABLES_DIRECTORY - Creating NSIS start menu links # assumes that they are in 'bin' unless this variable is set. # For example, you would set this to 'exec' if your executables are # in an exec directory. +##end # +##variable # CPACK_NSIS_MUI_FINISHPAGE_RUN - Specify an executable to add an option # to run on the finish page of the NSIS installer. +##end +##variable +# CPACK_NSIS_MENU_LINKS - Specify links in [application] menu. +# This should contain a list of pair "link" "link name". The link +# may be an URL or a path relative to installation prefix. +# Like: +# set(CPACK_NSIS_MENU_LINKS +# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help" +# "http://www.cmake.org" "CMake Web Site") +##end #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/CPackPackageMaker.cmake b/Modules/CPackPackageMaker.cmake new file mode 100644 index 0000000..45ba465 --- /dev/null +++ b/Modules/CPackPackageMaker.cmake @@ -0,0 +1,35 @@ +##section Variables specific to CPack PackageMaker generator +##end +##module +# - PackageMaker CPack generator (Mac OS X). +# The following variable is specific to installers build on Mac OS X +# using PackageMaker: +##end +# +##variable +# CPACK_OSX_PACKAGE_VERSION - The version of Mac OS X that the +# resulting PackageMaker archive should be compatible with. Different +# versions of Mac OS X support different +# features. For example, CPack can only build component-based +# installers for Mac OS X 10.4 or newer, and can only build +# installers that download component son-the-fly for Mac OS X 10.5 +# or newer. If left blank, this value will be set to the minimum +# version of Mac OS X that supports the requested features. Set this +# variable to some value (e.g., 10.4) only if you want to guarantee +# that your installer will work on that version of Mac OS X, and +# don't mind missing extra features available in the installer +# shipping with later versions of Mac OS X. +##end + +#============================================================================= +# Copyright 2006-2012 Kitware, Inc. +# +# 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.) diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index e1e76ed..442d7c4 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -1,3 +1,6 @@ +##section Variables specific to CPack RPM generator +##end +##module # - The builtin (binary) CPack RPM generator (Unix only) # CPackRPM may be used to create RPM package using CPack. # CPackRPM is a CPack generator thus it uses the CPACK_XXX variables @@ -15,52 +18,67 @@ # You'll find a detailed usage of CPackRPM on the wiki: # http://www.cmake.org/Wiki/CMake:CPackPackageGenerators#RPM_.28Unix_Only.29 # However as a handy reminder here comes the list of specific variables: +##end # -# CPACK_RPM_PACKAGE_SUMMARY +##variable +# CPACK_RPM_PACKAGE_SUMMARY - The RPM package summary. # Mandatory : YES # Default : CPACK_PACKAGE_DESCRIPTION_SUMMARY -# The RPM package summary -# CPACK_RPM_PACKAGE_NAME +##end +##variable +# CPACK_RPM_PACKAGE_NAME - The RPM package name. # Mandatory : YES # Default : CPACK_PACKAGE_NAME -# The RPM package name -# CPACK_RPM_PACKAGE_VERSION +##end +##variable +# CPACK_RPM_PACKAGE_VERSION - The RPM package version. # Mandatory : YES # Default : CPACK_PACKAGE_VERSION -# The RPM package version -# CPACK_RPM_PACKAGE_ARCHITECTURE +##end +##variable +# CPACK_RPM_PACKAGE_ARCHITECTURE - The RPM package architecture. # Mandatory : NO # Default : - -# The RPM package architecture. This may be set to "noarch" if you +# This may be set to "noarch" if you # know you are building a noarch package. -# CPACK_RPM_PACKAGE_RELEASE +##end +##variable +# CPACK_RPM_PACKAGE_RELEASE - The RPM package release. # Mandatory : YES # Default : 1 -# The RPM package release. This is the numbering of the RPM package +# This is the numbering of the RPM package # itself, i.e. the version of the packaging and not the version of the # content (see CPACK_RPM_PACKAGE_VERSION). One may change the default # value if the previous packaging was buggy and/or you want to put here # a fancy Linux distro specific numbering. -# CPACK_RPM_PACKAGE_LICENSE +##end +##variable +# CPACK_RPM_PACKAGE_LICENSE - The RPM package license policy. # Mandatory : YES # Default : "unknown" -# The RPM package license policy. -# CPACK_RPM_PACKAGE_GROUP +##end +##variable +# CPACK_RPM_PACKAGE_GROUP - The RPM package group. # Mandatory : YES # Default : "unknown" -# The RPM package group. -# CPACK_RPM_PACKAGE_VENDOR +##end +##variable +# CPACK_RPM_PACKAGE_VENDOR - The RPM package vendor. # Mandatory : YES # Default : CPACK_PACKAGE_VENDOR if set or "unknown" -# The RPM package vendor. -# CPACK_RPM_PACKAGE_URL +##end +##variable +# CPACK_RPM_PACKAGE_URL - The projects URL. # Mandatory : NO # Default : - -# The projects URL. -# CPACK_RPM_PACKAGE_DESCRIPTION +##end +##variable +# CPACK_RPM_PACKAGE_DESCRIPTION - RPM package description. # Mandatory : YES # Default : CPACK_PACKAGE_DESCRIPTION_FILE if set or "no package description available" -# CPACK_RPM_COMPRESSION_TYPE +##end +##variable +# CPACK_RPM_COMPRESSION_TYPE - RPM compression type. # Mandatory : NO # Default : - # May be used to override RPM compression type to be used @@ -68,7 +86,9 @@ # to lzma or xz compression whereas older cannot use such RPM. # Using this one can enforce compression type to be used. # Possible value are: lzma, xz, bzip2 and gzip. -# CPACK_RPM_PACKAGE_REQUIRES +##end +##variable +# CPACK_RPM_PACKAGE_REQUIRES - RPM spec requires field. # Mandatory : NO # Default : - # May be used to set RPM dependencies (requires). @@ -77,22 +97,30 @@ # set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.5.0, cmake >= 2.8") # The required package list of an RPM file could be printed with # rpm -qp --requires file.rpm -# CPACK_RPM_PACKAGE_SUGGESTS +##end +##variable +# CPACK_RPM_PACKAGE_SUGGESTS - RPM spec suggest field. # Mandatory : NO # Default : - # May be used to set weak RPM dependencies (suggests). # Note that you must enclose the complete requires string between quotes. -# CPACK_RPM_PACKAGE_PROVIDES +##end +##variable +# CPACK_RPM_PACKAGE_PROVIDES - RPM spec provides field. # Mandatory : NO # Default : - # May be used to set RPM dependencies (provides). # The provided package list of an RPM file could be printed with # rpm -qp --provides file.rpm -# CPACK_RPM_PACKAGE_OBSOLETES +##end +##variable +# CPACK_RPM_PACKAGE_OBSOLETES - RPM spec obsoletes field. # Mandatory : NO # Default : - # May be used to set RPM packages that are obsoleted by this one. -# CPACK_RPM_PACKAGE_RELOCATABLE +##end +##variable +# CPACK_RPM_PACKAGE_RELOCATABLE - build a relocatable RPM. # Mandatory : NO # Default : CPACK_PACKAGE_RELOCATABLE # If this variable is set to TRUE or ON CPackRPM will try @@ -103,7 +131,9 @@ # If CPACK_SET_DESTDIR is set then you will get a warning message # but if there is file installed with absolute path you'll get # unexpected behavior. -# CPACK_RPM_SPEC_INSTALL_POST [deprecated] +##end +##variable +# CPACK_RPM_SPEC_INSTALL_POST - [deprecated]. # Mandatory : NO # Default : - # This way of specifying post-install script is deprecated use @@ -111,23 +141,31 @@ # May be used to set an RPM post-install command inside the spec file. # For example setting it to "/bin/true" may be used to prevent # rpmbuild to strip binaries. -# CPACK_RPM_SPEC_MORE_DEFINE +##end +##variable +# CPACK_RPM_SPEC_MORE_DEFINE - RPM extended spec definitions lines. # Mandatory : NO # Default : - # May be used to add any %define lines to the generated spec file. -# CPACK_RPM_PACKAGE_DEBUG +##end +##variable +# CPACK_RPM_PACKAGE_DEBUG - Toggle CPackRPM debug output. # Mandatory : NO # Default : - # May be set when invoking cpack in order to trace debug information # during CPack RPM run. For example you may launch CPack like this # cpack -D CPACK_RPM_PACKAGE_DEBUG=1 -G RPM -# CPACK_RPM_USER_BINARY_SPECFILE +##end +##variable +# CPACK_RPM_USER_BINARY_SPECFILE - A user provided spec file. # Mandatory : NO # Default : - # May be set by the user in order to specify a USER binary spec file # to be used by CPackRPM instead of generating the file. # The specified file will be processed by CONFIGURE_FILE( @ONLY). -# CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE +##end +##variable +# CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE - Spec file template. # Mandatory : NO # Default : - # If set CPack will generate a template for USER specified binary @@ -135,6 +173,8 @@ # cpack -D CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE=1 -G RPM # The user may then use this file in order to hand-craft is own # binary spec file which may be used with CPACK_RPM_USER_BINARY_SPECFILE. +##end +##variable # CPACK_RPM_PRE_INSTALL_SCRIPT_FILE # CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE # Mandatory : NO @@ -143,11 +183,13 @@ # The refered script file(s) will be read and directly # put after the %pre or %preun section # If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for -# each component can be overriden with +# each component can be overridden with # CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE and # CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE # One may verify which scriptlet has been included with # rpm -qp --scripts package.rpm +##end +##variable # CPACK_RPM_POST_INSTALL_SCRIPT_FILE # CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE # Mandatory : NO @@ -156,26 +198,31 @@ # The refered script file(s) will be read and directly # put after the %post or %postun section # If CPACK_RPM_COMPONENT_INSTALL is set to ON the (un)install script for -# each component can be overriden with +# each component can be overridden with # CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE and # CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE # One may verify which scriptlet has been included with # rpm -qp --scripts package.rpm +##end +##variable # CPACK_RPM_USER_FILELIST # CPACK_RPM_<COMPONENT>_USER_FILELIST # Mandatory : NO # Default : - -# May be used to explicitely specify %(<directive>) file line +# May be used to explicitly specify %(<directive>) file line # in the spec file. Like %config(noreplace) or any other directive # that be found in the %files section. Since CPackRPM is generating # the list of files (and directories) the user specified files of # the CPACK_RPM_<COMPONENT>_USER_FILELIST list will be removed from the generated list. -# CPACK_RPM_CHANGELOG_FILE +##end +##variable +# CPACK_RPM_CHANGELOG_FILE - RPM changelog file. # Mandatory : NO # Default : - # May be used to embed a changelog in the spec file. # The refered file will be read and directly put after the %changelog # section. +##end #============================================================================= # Copyright 2007-2009 Kitware, Inc. diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake index 5380f4d..1c08c59 100644 --- a/Modules/CheckCCompilerFlag.cmake +++ b/Modules/CheckCCompilerFlag.cmake @@ -9,6 +9,7 @@ #============================================================================= # Copyright 2006-2011 Kitware, Inc. # Copyright 2006 Alexander Neundorf <neundorf@kde.org> +# Copyright 2011 Matthias Kretz <kretz@kde.org> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -32,9 +33,11 @@ MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT) FAIL_REGEX "unknown .*option" # Clang FAIL_REGEX "ignoring unknown option" # MSVC FAIL_REGEX "warning D9002" # MSVC, any lang + FAIL_REGEX "option .*not supported" # Intel FAIL_REGEX "[Uu]nknown option" # HP FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro FAIL_REGEX "command option .* is not recognized" # XL + FAIL_REGEX "WARNING: unknown flag:" # Open64 ) SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") ENDMACRO (CHECK_C_COMPILER_FLAG) diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake index d59fe55..2669336 100644 --- a/Modules/CheckCSourceCompiles.cmake +++ b/Modules/CheckCSourceCompiles.cmake @@ -24,6 +24,9 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_C_SOURCE_COMPILES SOURCE VAR) IF("${VAR}" MATCHES "^${VAR}$") SET(_FAIL_REGEX) @@ -40,8 +43,10 @@ MACRO(CHECK_C_SOURCE_COMPILES SOURCE VAR) SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake index 764c756..feee93a 100644 --- a/Modules/CheckCSourceRuns.cmake +++ b/Modules/CheckCSourceRuns.cmake @@ -24,13 +24,18 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_C_SOURCE_RUNS SOURCE VAR) IF("${VAR}" MATCHES "^${VAR}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS + SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_C_SOURCE_COMPILES_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) @@ -61,7 +66,7 @@ MACRO(CHECK_C_SOURCE_RUNS SOURCE VAR) IF("${${VAR}_EXITCODE}" EQUAL 0) SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") MESSAGE(STATUS "Performing Test ${VAR} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Performing C SOURCE FILE Test ${VAR} succeded with the following output:\n" "${OUTPUT}\n" "Return value: ${${VAR}}\n" @@ -74,7 +79,7 @@ MACRO(CHECK_C_SOURCE_RUNS SOURCE VAR) ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN") MESSAGE(STATUS "Performing Test ${VAR} - Failed") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing C SOURCE FILE Test ${VAR} failed with the following output:\n" "${OUTPUT}\n" "Return value: ${${VAR}_EXITCODE}\n" diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake index 3da04b4..6fa69b1 100644 --- a/Modules/CheckCXXCompilerFlag.cmake +++ b/Modules/CheckCXXCompilerFlag.cmake @@ -9,6 +9,7 @@ #============================================================================= # Copyright 2006-2010 Kitware, Inc. # Copyright 2006 Alexander Neundorf <neundorf@kde.org> +# Copyright 2011 Matthias Kretz <kretz@kde.org> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -27,15 +28,18 @@ MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") CHECK_CXX_SOURCE_COMPILES("int main() { return 0;}" ${_RESULT} # Some compilers do not fail with a bad flag + FAIL_REGEX "command line option .* is valid for .* but not for C\\\\+\\\\+" # GNU FAIL_REGEX "unrecognized .*option" # GNU FAIL_REGEX "unknown .*option" # Clang FAIL_REGEX "ignoring unknown option" # MSVC FAIL_REGEX "warning D9002" # MSVC, any lang + FAIL_REGEX "option .*not supported" # Intel FAIL_REGEX "[Uu]nknown option" # HP FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro FAIL_REGEX "command option .* is not recognized" # XL FAIL_REGEX "not supported in this configuration; ignored" # AIX FAIL_REGEX "File with unknown suffix passed to linker" # PGI + FAIL_REGEX "WARNING: unknown flag:" # Open64 ) SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") ENDMACRO (CHECK_CXX_COMPILER_FLAG) diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake index 0491b37..7f7336e 100644 --- a/Modules/CheckCXXSourceCompiles.cmake +++ b/Modules/CheckCXXSourceCompiles.cmake @@ -24,6 +24,9 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) IF("${VAR}" MATCHES "^${VAR}$") SET(_FAIL_REGEX) @@ -41,8 +44,10 @@ MACRO(CHECK_CXX_SOURCE_COMPILES SOURCE VAR) SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake index ace60d1..cd68d57 100644 --- a/Modules/CheckCXXSourceRuns.cmake +++ b/Modules/CheckCXXSourceRuns.cmake @@ -24,13 +24,18 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR) IF("${VAR}" MATCHES "^${VAR}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS + SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${VAR} ${CMAKE_REQUIRED_FLAGS}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) @@ -62,9 +67,9 @@ MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR) IF("${${VAR}_EXITCODE}" EQUAL 0) SET(${VAR} 1 CACHE INTERNAL "Test ${VAR}") MESSAGE(STATUS "Performing Test ${VAR} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Performing C++ SOURCE FILE Test ${VAR} succeded with the following output:\n" - "${OUTPUT}\n" + "${OUTPUT}\n" "Return value: ${${VAR}}\n" "Source file was:\n${SOURCE}\n") ELSE("${${VAR}_EXITCODE}" EQUAL 0) @@ -75,9 +80,9 @@ MACRO(CHECK_CXX_SOURCE_RUNS SOURCE VAR) ENDIF(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES "FAILED_TO_RUN") MESSAGE(STATUS "Performing Test ${VAR} - Failed") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n" - "${OUTPUT}\n" + "${OUTPUT}\n" "Return value: ${${VAR}_EXITCODE}\n" "Source file was:\n${SOURCE}\n") ENDIF("${${VAR}_EXITCODE}" EQUAL 0) diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake index 6e932d0..abec9f7 100644 --- a/Modules/CheckFortranFunctionExists.cmake +++ b/Modules/CheckFortranFunctionExists.cmake @@ -22,12 +22,17 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE) if(NOT DEFINED ${VARIABLE}) message(STATUS "Looking for Fortran ${FUNCTION}") if(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") else(CMAKE_REQUIRED_LIBRARIES) set(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES) endif(CMAKE_REQUIRED_LIBRARIES) @@ -50,13 +55,13 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE) if(${VARIABLE}) set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}") message(STATUS "Looking for Fortran ${FUNCTION} - found") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the Fortran ${FUNCTION} exists passed with the following output:\n" "${OUTPUT}\n\n") else(${VARIABLE}) message(STATUS "Looking for Fortran ${FUNCTION} - not found") set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}") - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the Fortran ${FUNCTION} exists failed with the following output:\n" "${OUTPUT}\n\n") endif(${VARIABLE}) diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake index 0ba36d9..8c469f0 100644 --- a/Modules/CheckFunctionExists.cmake +++ b/Modules/CheckFunctionExists.cmake @@ -27,14 +27,19 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) IF("${VARIABLE}" MATCHES "^${VARIABLE}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS + SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}") MESSAGE(STATUS "Looking for ${FUNCTION}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_FUNCTION_EXISTS_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) @@ -55,13 +60,13 @@ MACRO(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE) IF(${VARIABLE}) SET(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}") MESSAGE(STATUS "Looking for ${FUNCTION} - found") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the function ${FUNCTION} exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the function ${FUNCTION} exists failed with the following output:\n" "${OUTPUT}\n\n") ENDIF(${VARIABLE}) diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake index 75b5ca1..642d962 100644 --- a/Modules/CheckIncludeFiles.cmake +++ b/Modules/CheckIncludeFiles.cmake @@ -44,7 +44,7 @@ MACRO(CHECK_INCLUDE_FILES INCLUDE VARIABLE) CONFIGURE_FILE("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c" @ONLY IMMEDIATE) - MESSAGE(STATUS "Looking for include files ${VARIABLE}") + MESSAGE(STATUS "Looking for include files ${INCLUDE}") TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFiles.c @@ -54,15 +54,15 @@ MACRO(CHECK_INCLUDE_FILES INCLUDE VARIABLE) "${CHECK_INCLUDE_FILES_INCLUDE_DIRS}" OUTPUT_VARIABLE OUTPUT) IF(${VARIABLE}) - MESSAGE(STATUS "Looking for include files ${VARIABLE} - found") - SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${VARIABLE}") + MESSAGE(STATUS "Looking for include files ${INCLUDE} - found") + SET(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}") FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if files ${INCLUDE} " "exist passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) - MESSAGE(STATUS "Looking for include files ${VARIABLE} - not found.") - SET(${VARIABLE} "" CACHE INTERNAL "Have includes ${VARIABLE}") + MESSAGE(STATUS "Looking for include files ${INCLUDE} - not found.") + SET(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}") FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if files ${INCLUDE} " "exist failed with the following output:\n" diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake new file mode 100644 index 0000000..87a4018 --- /dev/null +++ b/Modules/CheckLanguage.cmake @@ -0,0 +1,65 @@ +# - Check if a language can be enabled +# Usage: +# check_language(<lang>) +# where <lang> is a language that may be passed to enable_language() +# such as "Fortran". If CMAKE_<lang>_COMPILER is already defined the +# check does nothing. Otherwise it tries enabling the language in a +# test project. The result is cached in CMAKE_<lang>_COMPILER as the +# compiler that was found, or NOTFOUND if the language cannot be enabled. +# +# Example: +# check_language(Fortran) +# if(CMAKE_Fortran_COMPILER) +# enable_language(Fortran) +# else() +# message(STATUS "No Fortran support") +# endif() + +#============================================================================= +# Copyright 2009-2012 Kitware, Inc. +# +# 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.) + +macro(check_language lang) + if(NOT DEFINED CMAKE_${lang}_COMPILER) + set(_desc "Looking for a ${lang} compiler") + message(STATUS ${_desc}) + file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/CMakeLists.txt" + "cmake_minimum_required(VERSION 2.8) +project(Check${lang} ${lang}) +file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" + \"set(CMAKE_${lang}_COMPILER \\\"\${CMAKE_${lang}_COMPILER}\\\")\\n\" + ) +") + execute_process( + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang} + COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR} + OUTPUT_VARIABLE output + ERROR_VARIABLE output + RESULT_VARIABLE result + ) + include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL) + if(CMAKE_${lang}_COMPILER AND "${result}" STREQUAL "0") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "${_desc} passed with the following output:\n" + "${output}\n") + else() + set(CMAKE_${lang}_COMPILER NOTFOUND) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "${_desc} failed with the following output:\n" + "${output}\n") + endif() + message(STATUS "${_desc} - ${CMAKE_${lang}_COMPILER}") + set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler") + mark_as_advanced(CMAKE_${lang}_COMPILER) + endif() +endmacro() diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake index caf4f4c..59fca0a 100644 --- a/Modules/CheckLibraryExists.cmake +++ b/Modules/CheckLibraryExists.cmake @@ -26,21 +26,26 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE) IF("${VARIABLE}" MATCHES "^${VARIABLE}$") - SET(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION + SET(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION "-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}") MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY}") SET(CHECK_LIBRARY_EXISTS_LIBRARIES ${LIBRARY}) IF(CMAKE_REQUIRED_LIBRARIES) - SET(CHECK_LIBRARY_EXISTS_LIBRARIES - ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${CMAKE_REQUIRED_LIBRARIES}) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") + SET(CHECK_LIBRARY_EXISTS_LIBRARIES + ${CHECK_LIBRARY_EXISTS_LIBRARIES} ${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}) ENDIF(CMAKE_REQUIRED_LIBRARIES) TRY_COMPILE(${VARIABLE} ${CMAKE_BINARY_DIR} ${CMAKE_ROOT}/Modules/CheckFunctionExists.c COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} - CMAKE_FLAGS + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_LIBRARY_EXISTS_DEFINITION} -DLINK_DIRECTORIES:STRING=${LOCATION} "-DLINK_LIBRARIES:STRING=${CHECK_LIBRARY_EXISTS_LIBRARIES}" @@ -49,14 +54,14 @@ MACRO(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE) IF(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found") SET(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " "passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) MESSAGE(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found") SET(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the function ${FUNCTION} exists in the ${LIBRARY} " "failed with the following output:\n" "${OUTPUT}\n\n") diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake index 244b9b5..63d4242 100644 --- a/Modules/CheckPrototypeDefinition.cmake +++ b/Modules/CheckPrototypeDefinition.cmake @@ -34,8 +34,11 @@ # License text for the above reference.) # +include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) + function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE) if ("${_VARIABLE}" MATCHES "^${_VARIABLE}$") @@ -43,8 +46,10 @@ function(CHECK_PROTOTYPE_DEFINITION _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS}) if (CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") set(CHECK_PROTOTYPE_DEFINITION_LIBS - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") else(CMAKE_REQUIRED_LIBRARIES) set(CHECK_PROTOTYPE_DEFINITION_LIBS) endif(CMAKE_REQUIRED_LIBRARIES) diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake index 515319d..e6e677d 100644 --- a/Modules/CheckSymbolExists.cmake +++ b/Modules/CheckSymbolExists.cmake @@ -35,6 +35,9 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_SYMBOL_EXISTS SYMBOL FILES VARIABLE) _CHECK_SYMBOL_EXISTS("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckSymbolExists.c" "${SYMBOL}" "${FILES}" "${VARIABLE}" ) ENDMACRO(CHECK_SYMBOL_EXISTS) @@ -44,8 +47,10 @@ MACRO(_CHECK_SYMBOL_EXISTS SOURCEFILE SYMBOL FILES VARIABLE) SET(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n") SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_SYMBOL_EXISTS_LIBS - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_SYMBOL_EXISTS_LIBS) ENDIF(CMAKE_REQUIRED_LIBRARIES) diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake index 5d5c931..1717718 100644 --- a/Modules/CheckTypeSize.cmake +++ b/Modules/CheckTypeSize.cmake @@ -47,6 +47,7 @@ # License text for the above reference.) include(CheckIncludeFile) +include("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") cmake_policy(PUSH) cmake_minimum_required(VERSION 2.6 FATAL_ERROR) @@ -76,6 +77,10 @@ function(__check_type_size_impl type var map builtin) endforeach() # Perform the check. + + # this one translates potentially used imported library targets to their files on disk + cmake_expand_imported_targets(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") + set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c) set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin) configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY) @@ -84,7 +89,7 @@ function(__check_type_size_impl type var map builtin) CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}" "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}" - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}" + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}" OUTPUT_VARIABLE output COPY_FILE ${bin} ) diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake index 9832891..7d6c794 100644 --- a/Modules/CheckVariableExists.cmake +++ b/Modules/CheckVariableExists.cmake @@ -1,6 +1,6 @@ # - Check if the variable exists. # CHECK_VARIABLE_EXISTS(VAR VARIABLE) -# +# # VAR - the name of the variable # VARIABLE - variable to store the result # @@ -26,14 +26,19 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +INCLUDE("${CMAKE_CURRENT_LIST_DIR}/CMakeExpandImportedTargets.cmake") + + MACRO(CHECK_VARIABLE_EXISTS VAR VARIABLE) IF("${VARIABLE}" MATCHES "^${VARIABLE}$") - SET(MACRO_CHECK_VARIABLE_DEFINITIONS + SET(MACRO_CHECK_VARIABLE_DEFINITIONS "-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}") MESSAGE(STATUS "Looking for ${VAR}") IF(CMAKE_REQUIRED_LIBRARIES) + # this one translates potentially used imported library targets to their files on disk + CMAKE_EXPAND_IMPORTED_TARGETS(_ADJUSTED_CMAKE_REQUIRED_LIBRARIES LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} CONFIGURATION "${CMAKE_TRY_COMPILE_CONFIGURATION}") SET(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES - "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + "-DLINK_LIBRARIES:STRING=${_ADJUSTED_CMAKE_REQUIRED_LIBRARIES}") ELSE(CMAKE_REQUIRED_LIBRARIES) SET(CHECK_VARIABLE_EXISTS_ADD_LIBRARIES) ENDIF(CMAKE_REQUIRED_LIBRARIES) @@ -47,13 +52,13 @@ MACRO(CHECK_VARIABLE_EXISTS VAR VARIABLE) IF(${VARIABLE}) SET(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}") MESSAGE(STATUS "Looking for ${VAR} - found") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Determining if the variable ${VAR} exists passed with the following output:\n" "${OUTPUT}\n\n") ELSE(${VARIABLE}) SET(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}") MESSAGE(STATUS "Looking for ${VAR} - not found") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the variable ${VAR} exists failed with the following output:\n" "${OUTPUT}\n\n") ENDIF(${VARIABLE}) diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 8d6f5df..bdcaf9d 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -24,6 +24,15 @@ macro(__compiler_gnu lang) set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") + # Older versions of gcc (< 4.5) contain a bug causing them to report a missing + # header file as a warning if depfiles are enabled, causing check_header_file + # tests to always succeed. Work around this by disabling dependency tracking + # in try_compile mode. + GET_PROPERTY(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE) + if(NOT _IN_TC OR CMAKE_FORCE_DEPFILES) + set(CMAKE_DEPFILE_FLAGS_${lang} "-MMD -MF <DEPFILE>") + endif() + # Initial configuration flags. set(CMAKE_${lang}_FLAGS_INIT "") set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-g") diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake index 83f322c..b37695d 100644 --- a/Modules/DeployQt4.cmake +++ b/Modules/DeployQt4.cmake @@ -82,6 +82,7 @@ include(BundleUtilities) set(DeployQt4_cmake_dir "${CMAKE_CURRENT_LIST_DIR}") +set(DeployQt4_apple_plugins_dir "PlugIns") function(write_qt4_conf qt_conf_dir qt_conf_contents) set(qt_conf_path "${qt_conf_dir}/qt.conf") @@ -125,11 +126,17 @@ function(fixup_qt4_executable executable) if(QT_LIBRARY_DIR) list(APPEND dirs "${QT_LIBRARY_DIR}") endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() if(APPLE) set(qt_conf_dir "${executable}/Contents/Resources") set(executable_path "${executable}") set(write_qt_conf TRUE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt4_apple_plugins_dir}") + endif() else() get_filename_component(executable_path "${executable}" PATH) if(NOT executable_path) @@ -141,7 +148,7 @@ function(fixup_qt4_executable executable) foreach(plugin ${qtplugins}) set(installed_plugin_path "") - install_qt4_plugin("${plugin}" "${plugins_dir}" "${executable}" 1 installed_plugin_path) + install_qt4_plugin("${plugin}" "${executable}" 1 installed_plugin_path) list(APPEND libs ${installed_plugin_path}) endforeach() @@ -166,23 +173,19 @@ function(install_qt4_plugin_path plugin executable copy installed_plugin_path_va set(component ${ARGV5}) set(configurations ${ARGV6}) if(EXISTS "${plugin}") - if(plugins_dir) - set(plugins_dir "${plugins_dir}") - else() - if(APPLE) - set(plugins_dir "PlugIns") - else() - set(plugins_dir "plugins") - endif() - endif() if(APPLE) + if(NOT plugins_dir) + set(plugins_dir "${DeployQt4_apple_plugins_dir}") + endif() set(plugins_path "${executable}/Contents/${plugins_dir}") else() - get_filename_component(executable_path "${executable}" PATH) - if(NOT executable_path) - set(executable_path ".") + get_filename_component(plugins_path "${executable}" PATH) + if(NOT plugins_path) + set(plugins_path ".") + endif() + if(plugins_dir) + set(plugins_path "${plugins_path}/${plugins_dir}") endif() - set(plugins_path "${executable_path}/${plugins_dir}") endif() set(plugin_group "") @@ -210,7 +213,7 @@ function(install_qt4_plugin_path plugin executable copy installed_plugin_path_va endif() install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component}) endif() - set(${installed_plugin_path_var} ${${installed_path_var}} "${plugins_path}/${plugin_name}" PARENT_SCOPE) + set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE) endif() endfunction() @@ -220,11 +223,7 @@ function(install_qt4_plugin plugin executable copy installed_plugin_path_var) if(EXISTS "${plugin}") install_qt4_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") else() - if(QT_IS_STATIC) - string(TOUPPER "QT_${plugin}_LIBRARY" plugin_var) - else() - string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) - endif() + string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var) set(plugin_release_var "${plugin_var}_RELEASE") set(plugin_debug_var "${plugin_var}_DEBUG") set(plugin_release "${${plugin_release_var}}") @@ -232,10 +231,24 @@ function(install_qt4_plugin plugin executable copy installed_plugin_path_var) if(DEFINED "${plugin_release_var}" AND DEFINED "${plugin_debug_var}" AND NOT EXISTS "${plugin_release}" AND NOT EXISTS "${plugin_debug}") message(WARNING "Qt plugin \"${plugin}\" not recognized or found.") endif() - install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel") - install_qt4_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}" "Debug") + if(NOT EXISTS "${${plugin_debug_var}}") + set(plugin_debug "${plugin_release}") + endif() + + if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel") + install_qt4_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug") + + if(CMAKE_BUILD_TYPE MATCHES "^Debug$") + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug}) + else() + set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release}) + endif() + else() + install_qt4_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") + endif() endif() - set(installed_plugin_path_var "${installed_plugin_path_var}" PARENT_SCOPE) + set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE) endfunction() function(install_qt4_executable executable) @@ -248,6 +261,9 @@ function(install_qt4_executable executable) if(QT_LIBRARY_DIR) list(APPEND dirs "${QT_LIBRARY_DIR}") endif() + if(QT_BINARY_DIR) + list(APPEND dirs "${QT_BINARY_DIR}") + endif() if(component) set(component COMPONENT ${component}) else() @@ -264,16 +280,16 @@ function(install_qt4_executable executable) set(qt_plugins_dir "") endif() - if(NOT qtplugins AND QT_LIBRARIES_PLUGINS) - set(qtplugins "${QT_LIBRARIES_PLUGINS}") + if(QT_IS_STATIC) + message(WARNING "Qt built statically: not installing plugins.") + else() + foreach(plugin ${qtplugins}) + set(installed_plugin_paths "") + install_qt4_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") + list(APPEND libs ${installed_plugin_paths}) + endforeach() endif() - foreach(plugin ${qtplugins}) - set(installed_plugin_paths "") - install_qt4_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}") - list(APPEND libs ${installed_plugin_paths}) - endforeach() - resolve_qt4_paths(libs) install(CODE diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index fb55d3b..b6fe190 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -833,6 +833,12 @@ function(ExternalProject_Add_StepTargets name) foreach(step ${steps}) add_custom_target(${name}-${step} DEPENDS ${stamp_dir}${cfgdir}/${name}-${step}) + + # Depend on other external projects (target-level). + get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + foreach(arg IN LISTS deps) + add_dependencies(${name}-${step} ${arg}) + endforeach() endforeach() endfunction(ExternalProject_Add_StepTargets) @@ -1451,9 +1457,18 @@ function(ExternalProject_Add name) # depends on the 'done' mark so that it rebuilds when this project # rebuilds. It is important that 'done' is not the output of any # custom command so that CMake does not propagate build rules to - # other external project targets. + # other external project targets, which may cause problems during + # parallel builds. However, the Ninja generator needs to see the entire + # dependency graph, and can cope with custom commands belonging to + # multiple targets, so we add the 'done' mark as an output for Ninja only. + set(complete_outputs ${cmf_dir}${cfgdir}/${name}-complete) + if(${CMAKE_GENERATOR} MATCHES "Ninja") + set(complete_outputs + ${complete_outputs} ${stamp_dir}${cfgdir}/${name}-done) + endif() + add_custom_command( - OUTPUT ${cmf_dir}${cfgdir}/${name}-complete + OUTPUT ${complete_outputs} COMMENT "Completed '${name}'" COMMAND ${CMAKE_COMMAND} -E make_directory ${cmf_dir}${cfgdir} COMMAND ${CMAKE_COMMAND} -E touch ${cmf_dir}${cfgdir}/${name}-complete diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index eb10cbc..cef647e 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -125,7 +125,7 @@ # # set_package_properties(LibXml2 PROPERTIES TYPE RECOMMENDED # PURPOSE "Enables HTML-import in MyWordProcessor") -# ... +# ... # set_package_properties(LibXml2 PROPERTIES TYPE OPTIONAL # PURPOSE "Enables odt-export in MyWordProcessor") # diff --git a/Modules/FindALSA.cmake b/Modules/FindALSA.cmake index ec6e3a8..4a0b693 100644 --- a/Modules/FindALSA.cmake +++ b/Modules/FindALSA.cmake @@ -12,8 +12,8 @@ # #============================================================================= -# Copyright 2009 Kitware, Inc. -# Copyright 2009 Philip Lowman <philip@yhbt.com> +# Copyright 2009-2011 Kitware, Inc. +# Copyright 2009-2011 Philip Lowman <philip@yhbt.com> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -25,8 +25,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_path(ALSA_INCLUDE_DIR NAMES asoundlib.h - PATH_SUFFIXES alsa +find_path(ALSA_INCLUDE_DIR NAMES alsa/asoundlib.h DOC "The ALSA (asound) include directory" ) @@ -34,8 +33,8 @@ find_library(ALSA_LIBRARY NAMES asound DOC "The ALSA (asound) library" ) -if(ALSA_INCLUDE_DIR AND EXISTS "${ALSA_INCLUDE_DIR}/version.h") - file(STRINGS "${ALSA_INCLUDE_DIR}/version.h" alsa_version_str REGEX "^#define[\t ]+SND_LIB_VERSION_STR[\t ]+\".*\"") +if(ALSA_INCLUDE_DIR AND EXISTS "${ALSA_INCLUDE_DIR}/alsa/version.h") + file(STRINGS "${ALSA_INCLUDE_DIR}/alsa/version.h" alsa_version_str REGEX "^#define[\t ]+SND_LIB_VERSION_STR[\t ]+\".*\"") string(REGEX REPLACE "^.*SND_LIB_VERSION_STR[\t ]+\"([^\"]*)\".*$" "\\1" ALSA_VERSION_STRING "${alsa_version_str}") unset(alsa_version_str) diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index 9b76d90..9eadfd1 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -23,6 +23,7 @@ ########## ### List of vendors (BLA_VENDOR) valid in this module ## Goto,ATLAS PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model), +## Intel10_64lp_seq (intel mkl v10 64 bit,sequential code, lp64 model), ## Intel( older versions of mkl 32 and 64 bit), ACML,ACML_MP,ACML_GPU,Apple, NAS, Generic # C/CXX should be enabled to use Intel mkl @@ -85,6 +86,7 @@ if (NOT _libdir) set(_libdir /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH) endif () endif () + foreach(_library ${_list}) set(_combined_name ${_combined_name}_${_library}) @@ -115,7 +117,7 @@ foreach(_library ${_list}) endforeach(_library ${_list}) if(_libraries_work) # Test this combination of libraries. - set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threads}) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread}) # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") if (_CHECK_FORTRAN) check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS) @@ -460,117 +462,99 @@ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") else(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) find_package(Threads REQUIRED) endif(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED) - if (WIN32) + + set(BLAS_SEARCH_LIBS "") + if(BLA_F95) - if(NOT BLAS95_LIBRARIES) - check_fortran_libraries( - BLAS95_LIBRARIES - BLAS - sgemm - "" - "mkl_blas95;mkl_intel_c;mkl_intel_thread;mkl_core;libguide40" - "" - ) - endif(NOT BLAS95_LIBRARIES) - else(BLA_F95) - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - SGEMM - "" - "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40" - "" - ) - endif(NOT BLAS_LIBRARIES) - endif(BLA_F95) - else(WIN32) - if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - if(BLA_F95) - if(NOT BLAS95_LIBRARIES) - check_fortran_libraries( - BLAS95_LIBRARIES - BLAS - sgemm - "" - "mkl_blas95;mkl_intel;mkl_intel_thread;mkl_core;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS95_LIBRARIES) - else(BLA_F95) - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "mkl_intel;mkl_intel_thread;mkl_core;guide" - "${CMAKE_THREAD_LIBS_INIT}" - "${LM}" - ) - endif(NOT BLAS_LIBRARIES) - endif(BLA_F95) - endif (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") - if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") - if(BLA_F95) - if(NOT BLAS95_LIBRARIES) - check_fortran_libraries( - BLAS95_LIBRARIES - BLAS - sgemm - "" - "mkl_blas95;mkl_intel_lp64;mkl_intel_thread;mkl_core;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS95_LIBRARIES) - else(BLA_F95) - if(NOT BLAS_LIBRARIES) + set(BLAS_mkl_SEARCH_SYMBOL SGEMM) + set(_LIBRARIES BLAS95_LIBRARIES) + if (WIN32) + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_intel_c mkl_intel_thread mkl_core libguide40") + else (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_intel mkl_intel_thread mkl_core guide") + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") + # old version + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95 mkl_intel_lp64 mkl_intel_thread mkl_core guide") + + # mkl >= 10.3 + if (CMAKE_C_COMPILER MATCHES ".+gcc.*") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_lp64 mkl_intel_lp64 mkl_gnu_thread mkl_core") + set(LM "${LM};-lgomp") + else () + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_lp64 mkl_intel_lp64 mkl_intel_thread mkl_core iomp5") + endif () + endif () + endif (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_blas95_lp64 mkl_intel_lp64 mkl_sequential mkl_core") + endif () + else (BLA_F95) + set(BLAS_mkl_SEARCH_SYMBOL sgemm) + set(_LIBRARIES BLAS_LIBRARIES) + if (WIN32) + list(APPEND BLAS_SEARCH_LIBS + "mkl_c_dll mkl_intel_thread_dll mkl_core_dll libguide40") + else (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel mkl_intel_thread mkl_core guide") + endif () + if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") + + # old version + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_intel_thread mkl_core guide") + + # mkl >= 10.3 + if (CMAKE_C_COMPILER MATCHES ".+gcc.*") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_gnu_thread mkl_core") + set(LM "${LM};-lgomp") + else () + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_intel_thread mkl_core iomp5") + endif () + endif () + + #older vesions of intel mkl libs + if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl") + list(APPEND BLAS_SEARCH_LIBS + "mkl_ia32") + list(APPEND BLAS_SEARCH_LIBS + "mkl_em64t") + endif () + endif (WIN32) + if (BLA_VENDOR STREQUAL "Intel10_64lp_seq" OR BLA_VENDOR STREQUAL "All") + list(APPEND BLAS_SEARCH_LIBS + "mkl_intel_lp64 mkl_sequential mkl_core") + endif () + endif (BLA_F95) + + foreach (IT ${BLAS_SEARCH_LIBS}) + string(REPLACE " " ";" SEARCH_LIBS ${IT}) + if (${_LIBRARIES}) + else () check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS_LIBRARIES) - endif(BLA_F95) - endif (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All") - endif (WIN32) - #older vesions of intel mkl libs - # BLAS in intel mkl library? (shared) - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "mkl;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS_LIBRARIES) - #BLAS in intel mkl library? (static, 32bit) - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "mkl_ia32;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS_LIBRARIES) - #BLAS in intel mkl library? (static, em64t 64bit) - if(NOT BLAS_LIBRARIES) - check_fortran_libraries( - BLAS_LIBRARIES - BLAS - sgemm - "" - "mkl_em64t;guide" - "${CMAKE_THREAD_LIBS_INIT};${LM}" - ) - endif(NOT BLAS_LIBRARIES) + ${_LIBRARIES} + BLAS + ${BLAS_mkl_SEARCH_SYMBOL} + "" + "${SEARCH_LIBS}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif () + endforeach () + endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 4d91a92..9f8d575 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -906,7 +906,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS: '${format}'. Use OBJ or PTX.") endif() - # Set up all the command line flags here, so that they can be overriden on a per target basis. + # Set up all the command line flags here, so that they can be overridden on a per target basis. set(nvcc_flags "") diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake index 6251805..e6f6702 100644 --- a/Modules/FindFreetype.cmake +++ b/Modules/FindFreetype.cmake @@ -3,6 +3,7 @@ # FREETYPE_LIBRARIES, the library to link against # FREETYPE_FOUND, if false, do not try to link to FREETYPE # FREETYPE_INCLUDE_DIRS, where to find headers. +# FREETYPE_VERSION_STRING, the version of freetype found (since CMake 2.8.8) # This is the concatenation of the paths: # FREETYPE_INCLUDE_DIR_ft2build # FREETYPE_INCLUDE_DIR_freetype2 @@ -77,10 +78,33 @@ IF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2) ENDIF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2) SET(FREETYPE_LIBRARIES "${FREETYPE_LIBRARY}") +IF(FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h") + FILE(STRINGS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h" freetype_version_str + REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$") + + UNSET(FREETYPE_VERSION_STRING) + FOREACH(VPART MAJOR MINOR PATCH) + FOREACH(VLINE ${freetype_version_str}) + IF(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}") + STRING(REGEX REPLACE "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$" "\\1" + FREETYPE_VERSION_PART "${VLINE}") + IF(FREETYPE_VERSION_STRING) + SET(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_STRING}.${FREETYPE_VERSION_PART}") + ELSE(FREETYPE_VERSION_STRING) + SET(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}") + ENDIF(FREETYPE_VERSION_STRING) + UNSET(FREETYPE_VERSION_PART) + ENDIF() + ENDFOREACH(VLINE) + ENDFOREACH(VPART) +ENDIF(FREETYPE_INCLUDE_DIR_freetype2 AND EXISTS "${FREETYPE_INCLUDE_DIR_freetype2}/freetype/freetype.h") + + # handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if # all listed variables are TRUE INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype DEFAULT_MSG FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS) - +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype + REQUIRED_VARS FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS + VERSION_VAR FREETYPE_VERSION_STRING) MARK_AS_ADVANCED(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build) diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake index af88997..8205779 100644 --- a/Modules/FindGLUT.cmake +++ b/Modules/FindGLUT.cmake @@ -64,25 +64,23 @@ ELSE (WIN32) ENDIF (WIN32) -SET( GLUT_FOUND "NO" ) -IF(GLUT_INCLUDE_DIR) - IF(GLUT_glut_LIBRARY) - # Is -lXi and -lXmu required on all platforms that have it? - # If not, we need some way to figure out what platform we are on. - SET( GLUT_LIBRARIES - ${GLUT_glut_LIBRARY} - ${GLUT_Xmu_LIBRARY} - ${GLUT_Xi_LIBRARY} - ${GLUT_cocoa_LIBRARY} - ) - SET( GLUT_FOUND "YES" ) - - #The following deprecated settings are for backwards compatibility with CMake1.4 - SET (GLUT_LIBRARY ${GLUT_LIBRARIES}) - SET (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR}) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_glut_LIBRARY GLUT_INCLUDE_DIR) + +IF (GLUT_FOUND) + # Is -lXi and -lXmu required on all platforms that have it? + # If not, we need some way to figure out what platform we are on. + SET( GLUT_LIBRARIES + ${GLUT_glut_LIBRARY} + ${GLUT_Xmu_LIBRARY} + ${GLUT_Xi_LIBRARY} + ${GLUT_cocoa_LIBRARY} + ) - ENDIF(GLUT_glut_LIBRARY) -ENDIF(GLUT_INCLUDE_DIR) + #The following deprecated settings are for backwards compatibility with CMake1.4 + SET (GLUT_LIBRARY ${GLUT_LIBRARIES}) + SET (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIR}) +ENDIF(GLUT_FOUND) MARK_AS_ADVANCED( GLUT_INCLUDE_DIR diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index 635090b..6dbc026 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -61,6 +61,17 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gettext INCLUDE(CMakeParseArguments) +FUNCTION(_GETTEXT_GET_UNIQUE_TARGET_NAME _name _unique_name) + SET(propertyName "_GETTEXT_UNIQUE_COUNTER_${_name}") + GET_PROPERTY(currentCounter GLOBAL PROPERTY "${propertyName}") + IF(NOT currentCounter) + SET(currentCounter 1) + ENDIF() + SET(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE) + MATH(EXPR currentCounter "${currentCounter} + 1") + SET_PROPERTY(GLOBAL PROPERTY ${propertyName} ${currentCounter} ) +ENDFUNCTION() + MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg) # make it a real variable, so we can modify it here SET(_firstPoFile "${_firstPoFileArg}") @@ -94,7 +105,15 @@ MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstPoFileArg) ENDFOREACH (_currentPoFile ) - ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles}) + IF(NOT TARGET translations) + ADD_CUSTOM_TARGET(translations) + ENDIF() + + _GETTEXT_GET_UNIQUE_TARGET_NAME(translations uniqueTargetName) + + ADD_CUSTOM_TARGET(${uniqueTargetName} ${_addToAll} DEPENDS ${_gmoFiles}) + + ADD_DEPENDENCIES(translations ${uniqueTargetName}) ENDMACRO(GETTEXT_CREATE_TRANSLATIONS ) @@ -133,11 +152,20 @@ FUNCTION(GETTEXT_PROCESS_POT_FILE _potFile) LIST(APPEND _gmoFiles ${_gmoFile}) ENDFOREACH (_lang ) + IF(NOT TARGET potfiles) + ADD_CUSTOM_TARGET(potfiles) + ENDIF() + + _GETTEXT_GET_UNIQUE_TARGET_NAME( potfiles uniqueTargetName) + IF(_parsedArguments_ALL) - ADD_CUSTOM_TARGET(potfiles ALL DEPENDS ${_gmoFiles}) + ADD_CUSTOM_TARGET(${uniqueTargetName} ALL DEPENDS ${_gmoFiles}) ELSE(_parsedArguments_ALL) - ADD_CUSTOM_TARGET(potfiles DEPENDS ${_gmoFiles}) + ADD_CUSTOM_TARGET(${uniqueTargetName} DEPENDS ${_gmoFiles}) ENDIF(_parsedArguments_ALL) + + ADD_DEPENDENCIES(potfiles ${uniqueTargetName}) + ENDFUNCTION(GETTEXT_PROCESS_POT_FILE) @@ -165,11 +193,21 @@ FUNCTION(GETTEXT_PROCESS_PO_FILES _lang) LIST(APPEND _gmoFiles ${_gmoFile}) ENDFOREACH(_current_PO_FILE) + + IF(NOT TARGET pofiles) + ADD_CUSTOM_TARGET(pofiles) + ENDIF() + + _GETTEXT_GET_UNIQUE_TARGET_NAME( pofiles uniqueTargetName) + IF(_parsedArguments_ALL) - ADD_CUSTOM_TARGET(pofiles ALL DEPENDS ${_gmoFiles}) + ADD_CUSTOM_TARGET(${uniqueTargetName} ALL DEPENDS ${_gmoFiles}) ELSE(_parsedArguments_ALL) - ADD_CUSTOM_TARGET(pofiles DEPENDS ${_gmoFiles}) + ADD_CUSTOM_TARGET(${uniqueTargetName} DEPENDS ${_gmoFiles}) ENDIF(_parsedArguments_ALL) + + ADD_DEPENDENCIES(pofiles ${uniqueTargetName}) + ENDFUNCTION(GETTEXT_PROCESS_PO_FILES) IF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE ) diff --git a/Modules/FindGnuplot.cmake b/Modules/FindGnuplot.cmake index 3e36e4b..b8dc3f4 100644 --- a/Modules/FindGnuplot.cmake +++ b/Modules/FindGnuplot.cmake @@ -5,6 +5,8 @@ # GNUPLOT_FOUND - system has Gnuplot # GNUPLOT_EXECUTABLE - the Gnuplot executable # GNUPLOT_VERSION_STRING - the version of Gnuplot found (since CMake 2.8.8) +# +# GNUPLOT_VERSION_STRING will not work for old versions like 3.7.1. #============================================================================= # Copyright 2002-2009 Kitware, Inc. diff --git a/Modules/FindHSPELL.cmake b/Modules/FindHSPELL.cmake index 054f565..ca5709b 100644 --- a/Modules/FindHSPELL.cmake +++ b/Modules/FindHSPELL.cmake @@ -32,12 +32,15 @@ IF (HSPELL_INCLUDE_DIR) FILE(READ "${HSPELL_INCLUDE_DIR}/hspell.h" HSPELL_H) STRING(REGEX REPLACE ".*#define HSPELL_VERSION_MAJOR ([0-9]+).*" "\\1" HSPELL_VERSION_MAJOR "${HSPELL_H}") STRING(REGEX REPLACE ".*#define HSPELL_VERSION_MINOR ([0-9]+).*" "\\1" HSPELL_VERSION_MINOR "${HSPELL_H}") + SET(HSPELL_VERSION_STRING "${HSPELL_VERSION_MAJOR}.${HSPELL_VERSION_MINOR}") ENDIF() # handle the QUIETLY and REQUIRED arguments and set HSPELL_FOUND to TRUE if # all listed variables are TRUE INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(HSPELL DEFAULT_MSG HSPELL_LIBRARIES HSPELL_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(HSPELL + REQUIRED_VARS HSPELL_LIBRARIES HSPELL_INCLUDE_DIR + VERSION_VAR HSPELL_VERSION_STRING) MARK_AS_ADVANCED(HSPELL_INCLUDE_DIR HSPELL_LIBRARIES) diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake index 75523f4..f21b630 100644 --- a/Modules/FindImageMagick.cmake +++ b/Modules/FindImageMagick.cmake @@ -27,6 +27,8 @@ # ImageMagick_VERSION_STRING - the version of ImageMagick found # (since CMake 2.8.8) # +# ImageMagick_VERSION_STRING will not work for old versions like 5.2.3. +# # There are also components for the following ImageMagick APIs: # # Magick++ @@ -169,9 +171,9 @@ FOREACH(component ${ImageMagick_FIND_COMPONENTS} LIST(APPEND ImageMagick_REQUIRED_VARS ImageMagick_${component}_EXECUTABLE) ENDIF(is_requested GREATER -1) ELSEIF(ImageMagick_${component}_EXECUTABLE) - # if no components were requested explicitely put all (default) executables + # if no components were requested explicitly put all (default) executables # in the list - LIST(APPEND ImageMagick_DEFAULT_EXECUTABLES "${ImageMagick_${component}_EXECUTABLE}") + LIST(APPEND ImageMagick_DEFAULT_EXECUTABLES ImageMagick_${component}_EXECUTABLE) ENDIF(ImageMagick_FIND_COMPONENTS) ENDIF(component STREQUAL "Magick++") ENDFOREACH(component) diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index 884266f..0ae98df 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -219,40 +219,69 @@ if (BLA_VENDOR STREQUAL "Generic" OR endif ( NOT LAPACK_LIBRARIES ) endif () #intel lapack - if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") +if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") + if (NOT WIN32) + set(LM "-lm") + endif () if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) - if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) find_PACKAGE(Threads) - else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - find_package(Threads REQUIRED) - endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) - if (BLA_F95) - if(NOT LAPACK95_LIBRARIES) - check_lapack_libraries( - LAPACK95_LIBRARIES - LAPACK - cheev - "" - "mkl_lapack95" - "${BLAS95_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT}" - ) - endif(NOT LAPACK95_LIBRARIES) - else(BLA_F95) - if(NOT LAPACK_LIBRARIES) - check_lapack_libraries( - LAPACK_LIBRARIES - LAPACK - cheev - "" - "mkl_lapack" - "${BLAS_LIBRARIES}" - "${CMAKE_THREAD_LIBS_INIT}" - ) - endif(NOT LAPACK_LIBRARIES) - endif(BLA_F95) + else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_package(Threads REQUIRED) + endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + if (BLA_F95) + if(NOT LAPACK95_LIBRARIES) + # old + check_lapack_libraries( + LAPACK95_LIBRARIES + LAPACK + cheev + "" + "mkl_lapack95" + "${BLAS95_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif(NOT LAPACK95_LIBRARIES) + if(NOT LAPACK95_LIBRARIES) + # new >= 10.3 + check_lapack_libraries( + LAPACK95_LIBRARIES + LAPACK + CHEEV + "" + "mkl_intel_lp64" + "${BLAS95_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif(NOT LAPACK95_LIBRARIES) + else(BLA_F95) + if(NOT LAPACK_LIBRARIES) + # old + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "mkl_lapack" + "${BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif(NOT LAPACK_LIBRARIES) + if(NOT LAPACK_LIBRARIES) + # new >= 10.3 + check_lapack_libraries( + LAPACK_LIBRARIES + LAPACK + cheev + "" + "mkl_gf_lp64" + "${BLAS_LIBRARIES}" + "${CMAKE_THREAD_LIBS_INIT};${LM}" + ) + endif(NOT LAPACK_LIBRARIES) + endif(BLA_F95) endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX) - endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") +endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All") else(BLAS_FOUND) message(STATUS "LAPACK requires BLAS") endif(BLAS_FOUND) diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake index cedcd24..be931c5 100644 --- a/Modules/FindLibArchive.cmake +++ b/Modules/FindLibArchive.cmake @@ -54,8 +54,9 @@ endif() # itself includes this FindLibArchive when built with an older CMake that does # not provide it. The older CMake also does not have CMAKE_CURRENT_LIST_DIR.) include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args(LibArchive DEFAULT_MSG - LibArchive_LIBRARY LibArchive_INCLUDE_DIR +find_package_handle_standard_args(LibArchive + REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR + VERSION_VAR LibArchive_VERSION ) set(LibArchive_FOUND ${LIBARCHIVE_FOUND}) unset(LIBARCHIVE_FOUND) diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake index 1e42f42..dd5aac4 100644 --- a/Modules/FindLibXslt.cmake +++ b/Modules/FindLibXslt.cmake @@ -5,6 +5,7 @@ # LIBXSLT_INCLUDE_DIR - the LibXslt include directory # LIBXSLT_LIBRARIES - Link these to LibXslt # LIBXSLT_DEFINITIONS - Compiler switches required for using LibXslt +# LIBXSLT_VERSION_STRING - version of LibXslt found (since CMake 2.8.8) # Additionally, the following two variables are set (but not required for using xslt): # LIBXSLT_EXSLT_LIBRARIES - Link to these if you need to link against the exslt library # LIBXSLT_XSLTPROC_EXECUTABLE - Contains the full path to the xsltproc executable if found @@ -51,10 +52,21 @@ SET(LIBXSLT_EXSLT_LIBRARIES ${LIBXSLT_EXSLT_LIBRARY} ) FIND_PROGRAM(LIBXSLT_XSLTPROC_EXECUTABLE xsltproc) -# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if -# all listed variables are TRUE +IF(PC_LIBXSLT_VERSION) + SET(LIBXSLT_VERSION_STRING ${PC_LIBXSLT_VERSION}) +ELSEIF(LIBXSLT_INCLUDE_DIR AND EXISTS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h") + FILE(STRINGS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h" libxslt_version_str + REGEX "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\".*\"") + + STRING(REGEX REPLACE "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1" + LIBXSLT_VERSION_STRING "${libxslt_version_str}") + UNSET(libxslt_version_str) +ENDIF() + INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXslt DEFAULT_MSG LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXslt + REQUIRED_VARS LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIR + VERSION_VAR LIBXSLT_VERSION_STRING) MARK_AS_ADVANCED(LIBXSLT_INCLUDE_DIR LIBXSLT_LIBRARIES diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 652803c..b96a2ec 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -1,7 +1,7 @@ # - Finds OpenMP support # This module can be used to detect OpenMP support in a compiler. # If the compiler supports OpenMP, the flags required to compile with -# openmp support are set. +# openmp support are set. # # The following variables are set: # OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support @@ -13,6 +13,7 @@ #============================================================================= # Copyright 2009 Kitware, Inc. # Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no> +# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -24,31 +25,54 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -include(CheckCSourceCompiles) -include(CheckCXXSourceCompiles) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) - -set(OpenMP_C_FLAG_CANDIDATES - #Gnu - "-fopenmp" - #Microsoft Visual Studio - "/openmp" - #Intel windows - "-Qopenmp" - #Intel - "-openmp" - #Empty, if compiler automatically accepts openmp - " " - #Sun - "-xopenmp" - #HP - "+Oopenmp" - #IBM XL C/c++ - "-qsmp" - #Portland Group - "-mp" -) -set(OpenMP_CXX_FLAG_CANDIDATES ${OpenMP_C_FLAG_CANDIDATES}) +set(_OPENMP_REQUIRED_VARS) + +function(_OPENMP_FLAG_CANDIDATES LANG) + set(OpenMP_FLAG_CANDIDATES + #GNU + "-fopenmp" + #Microsoft Visual Studio + "/openmp" + #Intel windows + "-Qopenmp" + #PathScale, Intel + "-openmp" + #Empty, if compiler automatically accepts openmp + " " + #Sun + "-xopenmp" + #HP + "+Oopenmp" + #IBM XL C/c++ + "-qsmp" + #Portland Group, MIPSpro + "-mp" + ) + + set(OMP_FLAG_GNU "-fopenmp") + set(OMP_FLAG_HP "+Oopenmp") + if(WIN32) + set(OMP_FLAG_Intel "-Qopenmp") + else() + set(OMP_FLAG_Intel "-openmp") + endif() + set(OMP_FLAG_MIPSpro "-mp") + set(OMP_FLAG_MSVC "/openmp") + set(OMP_FLAG_PathScale "-openmp") + set(OMP_FLAG_PGI "-mp") + set(OMP_FLAG_SunPro "-xopenmp") + set(OMP_FLAG_XL "-qsmp") + + # Move the flag that matches the compiler to the head of the list, + # this is faster and doesn't clutter the output that much. If that + # flag doesn't work we will still try all. + if(OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}) + list(REMOVE_ITEM OpenMP_FLAG_CANDIDATES "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + list(INSERT OpenMP_FLAG_CANDIDATES 0 "${OMP_FLAG_${CMAKE_${LANG}_COMPILER_ID}}") + endif() + + set(OpenMP_${LANG}_FLAG_CANDIDATES "${OpenMP_FLAG_CANDIDATES}" PARENT_SCOPE) +endfunction(_OPENMP_FLAG_CANDIDATES) # sample openmp source code to test set(OpenMP_C_TEST_SOURCE @@ -62,53 +86,82 @@ int main() { #endif } ") -# use the same source for CXX as C for now -set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) -# if these are set then do not try to find them again, -# by avoiding any try_compiles for the flags -if(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) - set(OpenMP_C_FLAG_CANDIDATES) - set(OpenMP_CXX_FLAG_CANDIDATES) -endif(DEFINED OpenMP_C_FLAGS AND DEFINED OpenMP_CXX_FLAGS) # check c compiler -foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - unset(OpenMP_FLAG_DETECTED CACHE) - message(STATUS "Try OpenMP C flag = [${FLAG}]") - check_c_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_FLAG_DETECTED) - set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) +if(CMAKE_C_COMPILER_LOADED) + # if these are set then do not try to find them again, + # by avoiding any try_compiles for the flags + if(OpenMP_C_FLAGS) + unset(OpenMP_C_FLAG_CANDIDATES) + else() + _OPENMP_FLAG_CANDIDATES("C") + include(CheckCSourceCompiles) + endif() + + foreach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(OpenMP_FLAG_DETECTED CACHE) + message(STATUS "Try OpenMP C flag = [${FLAG}]") + check_c_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(OpenMP_FLAG_DETECTED) + set(OpenMP_C_FLAGS_INTERNAL "${FLAG}") + break() + endif(OpenMP_FLAG_DETECTED) + endforeach(FLAG ${OpenMP_C_FLAG_CANDIDATES}) + + set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" + CACHE STRING "C compiler flags for OpenMP parallization") + + list(APPEND _OPENMP_REQUIRED_VARS OpenMP_C_FLAGS) + unset(OpenMP_C_FLAG_CANDIDATES) +endif() # check cxx compiler -foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) - set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - unset(OpenMP_FLAG_DETECTED CACHE) - message(STATUS "Try OpenMP CXX flag = [${FLAG}]") - check_cxx_source_compiles("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED) - set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") - if(OpenMP_FLAG_DETECTED) - set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") - break() - endif(OpenMP_FLAG_DETECTED) -endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) - -set(OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}" - CACHE STRING "C compiler flags for OpenMP parallization") - -set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" - CACHE STRING "C++ compiler flags for OpenMP parallization") -# handle the standard arguments for find_package -find_package_handle_standard_args(OpenMP DEFAULT_MSG - OpenMP_C_FLAGS OpenMP_CXX_FLAGS ) - -mark_as_advanced( - OpenMP_C_FLAGS - OpenMP_CXX_FLAGS -) +if(CMAKE_CXX_COMPILER_LOADED) + # if these are set then do not try to find them again, + # by avoiding any try_compiles for the flags + if(OpenMP_CXX_FLAGS) + unset(OpenMP_CXX_FLAG_CANDIDATES) + else() + _OPENMP_FLAG_CANDIDATES("CXX") + include(CheckCXXSourceCompiles) + + # use the same source for CXX as C for now + set(OpenMP_CXX_TEST_SOURCE ${OpenMP_C_TEST_SOURCE}) + endif() + + foreach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(OpenMP_FLAG_DETECTED CACHE) + message(STATUS "Try OpenMP CXX flag = [${FLAG}]") + check_cxx_source_compiles("${OpenMP_CXX_TEST_SOURCE}" OpenMP_FLAG_DETECTED) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(OpenMP_FLAG_DETECTED) + set(OpenMP_CXX_FLAGS_INTERNAL "${FLAG}") + break() + endif(OpenMP_FLAG_DETECTED) + endforeach(FLAG ${OpenMP_CXX_FLAG_CANDIDATES}) + + set(OpenMP_CXX_FLAGS "${OpenMP_CXX_FLAGS_INTERNAL}" + CACHE STRING "C++ compiler flags for OpenMP parallization") + + list(APPEND _OPENMP_REQUIRED_VARS OpenMP_CXX_FLAGS) + unset(OpenMP_CXX_FLAG_CANDIDATES) + unset(OpenMP_CXX_TEST_SOURCE) +endif() + +if(_OPENMP_REQUIRED_VARS) + include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + + find_package_handle_standard_args(OpenMP + REQUIRED_VARS ${_OPENMP_REQUIRED_VARS}) + + mark_as_advanced(${_OPENMP_REQUIRED_VARS}) + + unset(_OPENMP_REQUIRED_VARS) +else() + message(SEND_ERROR "FindOpenMP requires C or CXX language to be enabled") +endif() diff --git a/Modules/FindOpenSceneGraph.cmake b/Modules/FindOpenSceneGraph.cmake index 460f0fd..52f9316 100644 --- a/Modules/FindOpenSceneGraph.cmake +++ b/Modules/FindOpenSceneGraph.cmake @@ -78,7 +78,7 @@ list(APPEND _osg_modules_to_process "osg" "OpenThreads") list(REMOVE_DUPLICATES _osg_modules_to_process) if(OpenSceneGraph_DEBUG) - message("[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " + message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " "Components = ${_osg_modules_to_process}") endif() @@ -93,7 +93,7 @@ endif() # Try to ascertain the version... if(OSG_INCLUDE_DIR) if(OpenSceneGraph_DEBUG) - message("[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " + message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " "Detected OSG_INCLUDE_DIR = ${OSG_INCLUDE_DIR}") endif() @@ -127,14 +127,14 @@ if(OSG_INCLUDE_DIR) string(REGEX REPLACE ".*#define OPENSCENEGRAPH_PATCH_VERSION[ \t]+([0-9]+).*" "\\1" _osg_VERSION_PATCH ${_osg_Version_contents}) else() - message("[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " + message(WARNING "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " "Failed to parse version number, please report this as a bug") endif() set(OPENSCENEGRAPH_VERSION "${_osg_VERSION_MAJOR}.${_osg_VERSION_MINOR}.${_osg_VERSION_PATCH}" CACHE INTERNAL "The version of OSG which was detected") if(OpenSceneGraph_DEBUG) - message("[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " + message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " "Detected version ${OPENSCENEGRAPH_VERSION}") endif() endif() @@ -165,7 +165,7 @@ endif() # foreach(_osg_module ${_osg_modules_to_process}) if(OpenSceneGraph_DEBUG) - message("[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " + message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] " "Calling find_package(${_osg_module} ${_osg_required} ${_osg_quiet})") endif() find_package(${_osg_module} ${_osg_quiet}) diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake index db393e7..ae686df 100644 --- a/Modules/FindPerl.cmake +++ b/Modules/FindPerl.cmake @@ -1,8 +1,9 @@ # - Find perl # this module looks for Perl # -# PERL_EXECUTABLE - the full path to perl -# PERL_FOUND - If false, don't attempt to use perl. +# PERL_EXECUTABLE - the full path to perl +# PERL_FOUND - If false, don't attempt to use perl. +# PERL_VERSION_STRING - version of perl found (since CMake 2.8.8) #============================================================================= # Copyright 2001-2009 Kitware, Inc. @@ -39,12 +40,44 @@ FIND_PROGRAM(PERL_EXECUTABLE PATHS ${PERL_POSSIBLE_BIN_PATHS} ) +IF(PERL_EXECUTABLE) + ### PERL_VERSION + EXECUTE_PROCESS( + COMMAND + ${PERL_EXECUTABLE} -V:version + OUTPUT_VARIABLE + PERL_VERSION_OUTPUT_VARIABLE + RESULT_VARIABLE + PERL_VERSION_RESULT_VARIABLE + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + IF(NOT PERL_VERSION_RESULT_VARIABLE AND NOT PERL_VERSION_OUTPUT_VARIABLE MATCHES "^version='UNKNOWN'") + STRING(REGEX REPLACE "version='([^']+)'.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE}) + ELSE() + EXECUTE_PROCESS( + COMMAND ${PERL_EXECUTABLE} -v + OUTPUT_VARIABLE PERL_VERSION_OUTPUT_VARIABLE + RESULT_VARIABLE PERL_VERSION_RESULT_VARIABLE + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + IF(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl.*[ \\(]v([0-9\\._]+)[ \\)]") + STRING(REGEX REPLACE ".*This is perl.*[ \\(]v([0-9\\._]+)[ \\)].*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE}) + ELSEIF(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl, version ([0-9\\._]+) +") + STRING(REGEX REPLACE ".*This is perl, version ([0-9\\._]+) +.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE}) + ENDIF() + ENDIF() +ENDIF(PERL_EXECUTABLE) + # Deprecated settings for compatibility with CMake1.4 SET(PERL ${PERL_EXECUTABLE}) # handle the QUIETLY and REQUIRED arguments and set PERL_FOUND to TRUE if # all listed variables are TRUE INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Perl DEFAULT_MSG PERL_EXECUTABLE) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Perl + REQUIRED_VARS PERL_EXECUTABLE + VERSION_VAR PERL_VERSION_STRING) MARK_AS_ADVANCED(PERL_EXECUTABLE) diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake index eea55f1..b2ffd3c 100644 --- a/Modules/FindPerlLibs.cmake +++ b/Modules/FindPerlLibs.cmake @@ -55,19 +55,6 @@ if (PERL_EXECUTABLE) string(REGEX REPLACE "prefix='([^']+)'.*" "\\1" PERL_PREFIX ${PERL_PREFIX_OUTPUT_VARIABLE}) endif (NOT PERL_PREFIX_RESULT_VARIABLE) - ### PERL_VERSION - execute_process( - COMMAND - ${PERL_EXECUTABLE} -V:version - OUTPUT_VARIABLE - PERL_VERSION_OUTPUT_VARIABLE - RESULT_VARIABLE - PERL_VERSION_RESULT_VARIABLE - ) - if (NOT PERL_VERSION_RESULT_VARIABLE) - string(REGEX REPLACE "version='([^']+)'.*" "\\1" PERL_VERSION ${PERL_VERSION_OUTPUT_VARIABLE}) - endif (NOT PERL_VERSION_RESULT_VARIABLE) - ### PERL_ARCHNAME execute_process( COMMAND @@ -107,6 +94,7 @@ if (PERL_EXECUTABLE) ) if (NOT PERL_SITESEARCH_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_SITESEARCH ${PERL_SITESEARCH_OUTPUT_VARIABLE}) + file(TO_CMAKE_PATH "${PERL_SITESEARCH}" PERL_SITESEARCH) endif (NOT PERL_SITESEARCH_RESULT_VARIABLE) ### PERL_SITELIB @@ -120,6 +108,7 @@ if (PERL_EXECUTABLE) ) if (NOT PERL_SITELIB_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_SITELIB ${PERL_SITELIB_OUTPUT_VARIABLE}) + file(TO_CMAKE_PATH "${PERL_SITELIB}" PERL_SITELIB) endif (NOT PERL_SITELIB_RESULT_VARIABLE) ### PERL_VENDORARCH @@ -133,6 +122,7 @@ if (PERL_EXECUTABLE) ) if (NOT PERL_VENDORARCH_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_VENDORARCH ${PERL_VENDORARCH_OUTPUT_VARIABLE}) + file(TO_CMAKE_PATH "${PERL_VENDORARCH}" PERL_VENDORARCH) endif (NOT PERL_VENDORARCH_RESULT_VARIABLE) ### PERL_VENDORLIB @@ -146,6 +136,7 @@ if (PERL_EXECUTABLE) ) if (NOT PERL_VENDORLIB_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_VENDORLIB ${PERL_VENDORLIB_OUTPUT_VARIABLE}) + file(TO_CMAKE_PATH "${PERL_VENDORLIB}" PERL_VENDORLIB) endif (NOT PERL_VENDORLIB_RESULT_VARIABLE) macro(perl_adjust_darwin_lib_variable varname) @@ -186,6 +177,7 @@ if (PERL_EXECUTABLE) if (NOT PERL_ARCHLIB_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_ARCHLIB ${PERL_ARCHLIB_OUTPUT_VARIABLE}) perl_adjust_darwin_lib_variable( ARCHLIB ) + file(TO_CMAKE_PATH "${PERL_ARCHLIB}" PERL_ARCHLIB) endif (NOT PERL_ARCHLIB_RESULT_VARIABLE) ### PERL_PRIVLIB @@ -200,28 +192,10 @@ if (PERL_EXECUTABLE) if (NOT PERL_PRIVLIB_RESULT_VARIABLE) string(REGEX REPLACE "install[a-z]+='([^']+)'.*" "\\1" PERL_PRIVLIB ${PERL_PRIVLIB_OUTPUT_VARIABLE}) perl_adjust_darwin_lib_variable( PRIVLIB ) + file(TO_CMAKE_PATH "${PERL_PRIVLIB}" PERL_PRIVLIB) endif (NOT PERL_PRIVLIB_RESULT_VARIABLE) - - ### PERL_POSSIBLE_INCLUDE_PATHS - set(PERL_POSSIBLE_INCLUDE_PATHS - ${PERL_ARCHLIB}/CORE - /usr/lib/perl5/${PERL_VERSION}/${PERL_ARCHNAME}/CORE - /usr/lib/perl/${PERL_VERSION}/${PERL_ARCHNAME}/CORE - /usr/lib/perl5/${PERL_VERSION}/CORE - /usr/lib/perl/${PERL_VERSION}/CORE - ) - - ### PERL_POSSIBLE_LIB_PATHS - set(PERL_POSSIBLE_LIB_PATHS - ${PERL_ARCHLIB}/CORE - /usr/lib/perl5/${PERL_VERSION}/${PERL_ARCHNAME}/CORE - /usr/lib/perl/${PERL_VERSION}/${PERL_ARCHNAME}/CORE - /usr/lib/perl5/${PERL_VERSION}/CORE - /usr/lib/perl/${PERL_VERSION}/CORE - ) - - ### PERL_POSSIBLE_LIBRARY_NAME + ### PERL_POSSIBLE_LIBRARY_NAMES execute_process( COMMAND ${PERL_EXECUTABLE} -V:libperl @@ -231,10 +205,9 @@ if (PERL_EXECUTABLE) PERL_LIBRARY_RESULT_VARIABLE ) if (NOT PERL_LIBRARY_RESULT_VARIABLE) - foreach(_perl_lib_path ${PERL_POSSIBLE_LIB_PATHS}) - string(REGEX REPLACE "libperl='([^']+)'" "\\1" PERL_LIBRARY_OUTPUT_VARIABLE ${PERL_LIBRARY_OUTPUT_VARIABLE}) - set(PERL_POSSIBLE_LIBRARY_NAME ${PERL_POSSIBLE_LIBRARY_NAME} "${_perl_lib_path}/${PERL_LIBRARY_OUTPUT_VARIABLE}") - endforeach(_perl_lib_path ${PERL_POSSIBLE_LIB_PATHS}) + string(REGEX REPLACE "libperl='([^']+)'.*" "\\1" PERL_POSSIBLE_LIBRARY_NAMES ${PERL_LIBRARY_OUTPUT_VARIABLE}) + else (NOT PERL_LIBRARY_RESULT_VARIABLE) + set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl) endif (NOT PERL_LIBRARY_RESULT_VARIABLE) ### PERL_INCLUDE_PATH @@ -242,17 +215,23 @@ if (PERL_EXECUTABLE) NAMES perl.h PATHS - ${PERL_POSSIBLE_INCLUDE_PATHS} + ${PERL_ARCHLIB}/CORE + /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE + /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE + /usr/lib/perl5/${PERL_VERSION_STRING}/CORE + /usr/lib/perl/${PERL_VERSION_STRING}/CORE ) - + ### PERL_LIBRARY find_library(PERL_LIBRARY NAMES - ${PERL_POSSIBLE_LIBRARY_NAME} - perl${PERL_VERSION} - perl + ${PERL_POSSIBLE_LIBRARY_NAMES} PATHS - ${PERL_POSSIBLE_LIB_PATHS} + ${PERL_ARCHLIB}/CORE + /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE + /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE + /usr/lib/perl5/${PERL_VERSION_STRING}/CORE + /usr/lib/perl/${PERL_VERSION_STRING}/CORE ) endif (PERL_EXECUTABLE) @@ -261,15 +240,16 @@ endif (PERL_EXECUTABLE) # all listed variables are TRUE include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args(PerlLibs REQUIRED_VARS PERL_LIBRARY PERL_INCLUDE_PATH - VERSION_VAR PERL_VERSION) + VERSION_VAR PERL_VERSION_STRING) # Introduced after CMake 2.6.4 to bring module into compliance set(PERL_INCLUDE_DIR ${PERL_INCLUDE_PATH}) set(PERL_INCLUDE_DIRS ${PERL_INCLUDE_PATH}) set(PERL_LIBRARIES ${PERL_LIBRARY}) +# For backward compatibility with CMake before 2.8.8 +set(PERL_VERSION ${PERL_VERSION_STRING}) mark_as_advanced( PERL_INCLUDE_PATH - PERL_EXECUTABLE PERL_LIBRARY ) diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index ce58899..5d93ab1 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -13,14 +13,17 @@ # When the 'QUIET' argument is set, no status messages will be printed. # # It sets the following variables: -# PKG_CONFIG_FOUND ... true if pkg-config works on the system -# PKG_CONFIG_EXECUTABLE ... pathname of the pkg-config program -# <PREFIX>_FOUND ... set to 1 if module(s) exist +# PKG_CONFIG_FOUND ... true if pkg-config works on the system +# PKG_CONFIG_EXECUTABLE ... pathname of the pkg-config program +# PKG_CONFIG_VERSION_STRING ... the version of the pkg-config program found +# (since CMake 2.8.8) +# PKG_CONFIG_FOUND ... if pkg-config executable was found # # For the following variables two sets of values exist; first one is the # common one and has the given PREFIX. The second set contains flags # which are given out when pkgconfig was called with the '--static' # option. +# <XPREFIX>_FOUND ... set to 1 if module(s) exist # <XPREFIX>_LIBRARIES ... only the libraries (w/o the '-l') # <XPREFIX>_LIBRARY_DIRS ... the paths of the libraries (w/o the '-L') # <XPREFIX>_LDFLAGS ... all required linker flags @@ -89,9 +92,17 @@ set(PKG_CONFIG_VERSION 1) find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable") mark_as_advanced(PKG_CONFIG_EXECUTABLE) -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -find_package_handle_standard_args(PkgConfig DEFAULT_MSG PKG_CONFIG_EXECUTABLE) +if (PKG_CONFIG_EXECUTABLE) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version + OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif (PKG_CONFIG_EXECUTABLE) +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(PkgConfig + REQUIRED_VARS PKG_CONFIG_EXECUTABLE + VERSION_VAR PKG_CONFIG_VERSION_STRING) # Unsets the given variables macro(_pkgconfig_unset var) diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake index 5c1d56b..a131c5f 100644 --- a/Modules/FindPythonInterp.cmake +++ b/Modules/FindPythonInterp.cmake @@ -10,11 +10,14 @@ # PYTHON_VERSION_MINOR - Python minor version found e.g. 5 # PYTHON_VERSION_PATCH - Python patch version found e.g. 2 # -# Python_ADDITIONAL_VERSIONS - list of additional Python versions to search for +# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of +# version numbers that should be taken into account when searching for Python. +# You need to set this variable before calling find_package(PythonInterp). #============================================================================= # Copyright 2005-2010 Kitware, Inc. # Copyright 2011 Bjoern Ricks <bjoern.ricks@gmail.com> +# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -88,24 +91,42 @@ endif() # determine python version string if(PYTHON_EXECUTABLE) - execute_process(COMMAND "${PYTHON_EXECUTABLE}" --version - ERROR_VARIABLE _VERSION + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c + "import sys; sys.stdout.write(';'.join([str(x) for x in sys.version_info[:3]]))" + OUTPUT_VARIABLE _VERSION RESULT_VARIABLE _PYTHON_VERSION_RESULT - OUTPUT_QUIET - ERROR_STRIP_TRAILING_WHITESPACE) - if(_PYTHON_VERSION_RESULT) - execute_process(COMMAND "${PYTHON_EXECUTABLE}" -V - ERROR_VARIABLE _VERSION + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REPLACE ";" "." PYTHON_VERSION_STRING "${_VERSION}") + list(GET _VERSION 0 PYTHON_VERSION_MAJOR) + list(GET _VERSION 1 PYTHON_VERSION_MINOR) + list(GET _VERSION 2 PYTHON_VERSION_PATCH) + if(PYTHON_VERSION_PATCH EQUAL 0) + # it's called "Python 2.7", not "2.7.0" + string(REGEX REPLACE "\\.0$" "" PYTHON_VERSION_STRING "${PYTHON_VERSION_STRING}") + endif() + else() + # sys.version predates sys.version_info, so use that + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.version)" + OUTPUT_VARIABLE _VERSION RESULT_VARIABLE _PYTHON_VERSION_RESULT - OUTPUT_QUIET - ERROR_STRIP_TRAILING_WHITESPACE) - endif(_PYTHON_VERSION_RESULT) - if(NOT _PYTHON_VERSION_RESULT AND _VERSION MATCHES "^Python [0-9]+\\.[0-9]+.*") - string(REPLACE "Python " "" PYTHON_VERSION_STRING "${_VERSION}") - string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}") - string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}") - if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*") - string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}") + ERROR_QUIET) + if(NOT _PYTHON_VERSION_RESULT) + string(REGEX REPLACE " .*" "" PYTHON_VERSION_STRING "${_VERSION}") + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" PYTHON_VERSION_MAJOR "${PYTHON_VERSION_STRING}") + string(REGEX REPLACE "^[0-9]+\\.([0-9])+.*" "\\1" PYTHON_VERSION_MINOR "${PYTHON_VERSION_STRING}") + if(PYTHON_VERSION_STRING MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+.*") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" PYTHON_VERSION_PATCH "${PYTHON_VERSION_STRING}") + else() + set(PYTHON_VERSION_PATCH "0") + endif() + else() + # sys.version was first documented for Python 1.5, so assume + # this is older. + set(PYTHON_VERSION_STRING "1.4") + set(PYTHON_VERSION_MAJOR "1") + set(PYTHON_VERSION_MAJOR "4") + set(PYTHON_VERSION_MAJOR "0") endif() endif() unset(_PYTHON_VERSION_RESULT) diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake index da7a1ac..fcd0838 100644 --- a/Modules/FindPythonLibs.cmake +++ b/Modules/FindPythonLibs.cmake @@ -7,8 +7,12 @@ # PYTHON_LIBRARIES - path to the python library # PYTHON_INCLUDE_PATH - path to where Python.h is found (deprecated) # PYTHON_INCLUDE_DIRS - path to where Python.h is found -# PYTHON_DEBUG_LIBRARIES - path to the debug library -# Python_ADDITIONAL_VERSIONS - list of additional Python versions to search for +# PYTHON_DEBUG_LIBRARIES - path to the debug library (deprecated) +# PYTHONLIBS_VERSION_STRING - version of the Python libs found (since CMake 2.8.8) +# +# The Python_ADDITIONAL_VERSIONS variable can be used to specify a list of +# version numbers that should be taken into account when searching for Python. +# You need to set this variable before calling find_package(PythonLibs). #============================================================================= # Copyright 2001-2009 Kitware, Inc. @@ -27,11 +31,42 @@ INCLUDE(CMakeFindFrameworks) # Search for the python framework on Apple. CMAKE_FIND_FRAMEWORKS(Python) +SET(_PYTHON1_VERSIONS 1.6 1.5) +SET(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0) +SET(_PYTHON3_VERSIONS 3.3 3.2 3.1 3.0) + +IF(PythonLibs_FIND_VERSION) + IF(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") + STRING(REGEX REPLACE "^([0-9]+\\.[0-9]+).*" "\\1" _PYTHON_FIND_MAJ_MIN "${PythonLibs_FIND_VERSION}") + STRING(REGEX REPLACE "^([0-9]+).*" "\\1" _PYTHON_FIND_MAJ "${_PYTHON_FIND_MAJ_MIN}") + UNSET(_PYTHON_FIND_OTHER_VERSIONS) + IF(NOT PythonLibs_FIND_VERSION_EXACT) + FOREACH(_PYTHON_V ${_PYTHON${_PYTHON_FIND_MAJ}_VERSIONS}) + IF(NOT _PYTHON_V VERSION_LESS _PYTHON_FIND_MAJ_MIN) + LIST(APPEND _PYTHON_FIND_OTHER_VERSIONS ${_PYTHON_V}) + ENDIF() + ENDFOREACH() + ENDIF(NOT PythonLibs_FIND_VERSION_EXACT) + UNSET(_PYTHON_FIND_MAJ_MIN) + UNSET(_PYTHON_FIND_MAJ) + ELSE(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") + SET(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON${PythonLibs_FIND_VERSION}_VERSIONS}) + ENDIF(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$") +ELSE(PythonLibs_FIND_VERSION) + SET(_PYTHON_FIND_OTHER_VERSIONS ${_PYTHON3_VERSIONS} ${_PYTHON2_VERSIONS} ${_PYTHON1_VERSIONS}) +ENDIF(PythonLibs_FIND_VERSION) + # Set up the versions we know about, in the order we will search. Always add # the user supplied additional versions to the front. -set(_Python_VERSIONS +SET(_Python_VERSIONS ${Python_ADDITIONAL_VERSIONS} - 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0 1.6 1.5) + ${_PYTHON_FIND_OTHER_VERSIONS} + ) + +UNSET(_PYTHON_FIND_OTHER_VERSIONS) +UNSET(_PYTHON1_VERSIONS) +UNSET(_PYTHON2_VERSIONS) +UNSET(_PYTHON3_VERSIONS) FOREACH(_CURRENT_VERSION ${_Python_VERSIONS}) STRING(REPLACE "." "" _CURRENT_VERSION_NO_DOTS ${_CURRENT_VERSION}) @@ -92,6 +127,17 @@ FOREACH(_CURRENT_VERSION ${_Python_VERSIONS}) SET(PYTHON_INCLUDE_PATH "${PYTHON_INCLUDE_DIR}" CACHE INTERNAL "Path to where Python.h is found (deprecated)") + IF(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") + FILE(STRINGS "${PYTHON_INCLUDE_DIR}/patchlevel.h" python_version_str + REGEX "^#define[ \t]+PY_VERSION[ \t]+\"[^\"]+\"") + STRING(REGEX REPLACE "^#define[ \t]+PY_VERSION[ \t]+\"([^\"]+)\".*" "\\1" + PYTHONLIBS_VERSION_STRING "${python_version_str}") + UNSET(python_version_str) + ENDIF(PYTHON_INCLUDE_DIR AND EXISTS "${PYTHON_INCLUDE_DIR}/patchlevel.h") + + IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) + BREAK() + ENDIF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) ENDFOREACH(_CURRENT_VERSION) MARK_AS_ADVANCED( @@ -105,13 +151,23 @@ MARK_AS_ADVANCED( # library. We now set the variables listed by the documentation for this # module. SET(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}") -SET(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") SET(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}") +# These variables have been historically named in this module different from +# what SELECT_LIBRARY_CONFIGURATIONS() expects. +SET(PYTHON_LIBRARY_DEBUG "${PYTHON_DEBUG_LIBRARY}") +SET(PYTHON_LIBRARY_RELEASE "${PYTHON_LIBRARY}") +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake) +SELECT_LIBRARY_CONFIGURATIONS(PYTHON) +# SELECT_LIBRARY_CONFIGURATIONS() sets ${PREFIX}_FOUND if it has a library. +# Unset this, this prefix doesn't match the module prefix, they are different +# for historical reasons. +UNSET(PYTHON_FOUND) INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs DEFAULT_MSG PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS) - +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibs + REQUIRED_VARS PYTHON_LIBRARIES PYTHON_INCLUDE_DIRS + VERSION_VAR PYTHONLIBS_VERSION_STRING) # PYTHON_ADD_MODULE(<name> src1 src2 ... srcN) is used to build modules for python. # PYTHON_WRITE_MODULES_HEADER(<filename>) writes a header file you can include diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake index bacbb07..2d8dbde 100644 --- a/Modules/FindQt3.cmake +++ b/Modules/FindQt3.cmake @@ -1,10 +1,11 @@ # - Locate Qt include paths and libraries # This module defines: -# QT_INCLUDE_DIR - where to find qt.h, etc. -# QT_LIBRARIES - the libraries to link against to use Qt. -# QT_DEFINITIONS - definitions to use when -# compiling code that uses Qt. -# QT_FOUND - If false, don't try to use Qt. +# QT_INCLUDE_DIR - where to find qt.h, etc. +# QT_LIBRARIES - the libraries to link against to use Qt. +# QT_DEFINITIONS - definitions to use when +# compiling code that uses Qt. +# QT_FOUND - If false, don't try to use Qt. +# QT_VERSION_STRING - the version of Qt found # # If you need the multithreaded version of Qt, set QT_MT_REQUIRED to TRUE # @@ -46,13 +47,16 @@ IF(QT4_FOUND) ENDIF(QT4_FOUND) -FILE(GLOB GLOB_PATHS_BIN /usr/lib/qt-3*/bin/) +FILE(GLOB GLOB_PATHS /usr/lib/qt-3*) +FOREACH(GLOB_PATH ${GLOB_PATHS}) + LIST(APPEND GLOB_PATHS_BIN "${GLOB_PATH}/bin") +ENDFOREACH(GLOB_PATH) FIND_PATH(QT_INCLUDE_DIR qt.h "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/include/Qt" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt" $ENV{QTDIR}/include - ${GLOB_PATHS_BIN} + ${GLOB_PATHS} /usr/local/qt/include /usr/lib/qt/include /usr/lib/qt3/include @@ -71,12 +75,13 @@ ENDIF(NOT EXISTS ${QT_INCLUDE_DIR}/qglobal.h) IF(QT_INCLUDE_DIR) #extract the version string from qglobal.h FILE(READ ${QT_INCLUDE_DIR}/qglobal.h QGLOBAL_H) - STRING(REGEX MATCH "#define[\t ]+QT_VERSION_STR[\t ]+\"([0-9]+.[0-9]+.[0-9]+)\"" QGLOBAL_H "${QGLOBAL_H}") - STRING(REGEX REPLACE ".*\"([0-9]+.[0-9]+.[0-9]+)\".*" "\\1" qt_version_str "${QGLOBAL_H}") + STRING(REGEX MATCH "#define[\t ]+QT_VERSION_STR[\t ]+\"[0-9]+.[0-9]+.[0-9]+[a-z]*\"" QGLOBAL_H "${QGLOBAL_H}") + STRING(REGEX REPLACE ".*\"([0-9]+.[0-9]+.[0-9]+[a-z]*)\".*" "\\1" qt_version_str "${QGLOBAL_H}") # Under windows the qt library (MSVC) has the format qt-mtXYZ where XYZ is the # version X.Y.Z, so we need to remove the dots from version STRING(REGEX REPLACE "\\." "" qt_version_str_lib "${qt_version_str}") + SET(QT_VERSION_STRING "${qt_version_str}") ENDIF(QT_INCLUDE_DIR) FILE(GLOB GLOB_PATHS_LIB /usr/lib/qt-3*/lib/) @@ -183,67 +188,28 @@ ENDIF(QT_UIC_EXECUTABLE) IF (WIN32) FIND_LIBRARY(QT_QTMAIN_LIBRARY qtmain + HINTS + $ENV{QTDIR}/lib "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.1;InstallDir]/lib" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/lib" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/lib" + PATHS "$ENV{ProgramFiles}/qt/lib" - $ENV{QTDIR}/lib "C:/Program Files/qt/lib" + "C:/Program Files/qt/lib" DOC "This Library is only needed by and included with Qt3 on MSWindows. It should be NOTFOUND, undefined or IGNORE otherwise." ) ENDIF (WIN32) - -IF (QT_MIN_VERSION) - - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" qt_major_vers "${qt_version_str}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" qt_minor_vers "${qt_version_str}") - STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" qt_patch_vers "${qt_version_str}") - - #now parse the parts of the user given version string into variables - STRING(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+$" req_qt_major_vers "${QT_MIN_VERSION}") - IF (NOT req_qt_major_vers) - error_message( "Invalid Qt version string given: \"${QT_MIN_VERSION}\", expected e.g. \"3.1.5\"") - ENDIF (NOT req_qt_major_vers) - - STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_qt_major_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" req_qt_minor_vers "${QT_MIN_VERSION}") - STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_qt_patch_vers "${QT_MIN_VERSION}") - - # req = "6.5.4", qt = "3.2.1" - MACRO(error_message msg) - IF(QT3_REQUIRED) - MESSAGE( FATAL_ERROR ${msg}) - ELSE(QT3_REQUIRED) - MESSAGE( STATUS ${msg}) - ENDIF(QT3_REQUIRED) - ENDMACRO(error_message) - - IF (req_qt_major_vers GREATER qt_major_vers) # (6 > 3) ? - ERROR_MESSAGE( "Qt major version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes - ELSE (req_qt_major_vers GREATER qt_major_vers) # no - IF (req_qt_major_vers LESS qt_major_vers) # (6 < 3) ? - SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes - ELSE (req_qt_major_vers LESS qt_major_vers) # ( 6==3) ? - IF (req_qt_minor_vers GREATER qt_minor_vers) # (5>2) ? - ERROR_MESSAGE( "Qt minor version not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes - ELSE (req_qt_minor_vers GREATER qt_minor_vers) # no - IF (req_qt_minor_vers LESS qt_minor_vers) # (5<2) ? - SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes - ELSE (req_qt_minor_vers LESS qt_minor_vers) # (5==2) - IF (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ? - ERROR_MESSAGE( "Qt patch level not matched (required: ${QT_MIN_VERSION}, found: ${qt_version_str})") # yes - ELSE (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ? - SET( QT_VERSION_BIG_ENOUGH "YES" ) # yes - ENDIF (req_qt_patch_vers GREATER qt_patch_vers) # (4>1) ? - ENDIF (req_qt_minor_vers LESS qt_minor_vers) - ENDIF (req_qt_minor_vers GREATER qt_minor_vers) - ENDIF (req_qt_major_vers LESS qt_major_vers) - ENDIF (req_qt_major_vers GREATER qt_major_vers) -ENDIF (QT_MIN_VERSION) +#support old QT_MIN_VERSION if set, but not if version is supplied by find_package() +IF(NOT Qt3_FIND_VERSION AND QT_MIN_VERSION) + SET(Qt3_FIND_VERSION ${QT_MIN_VERSION}) +ENDIF(NOT Qt3_FIND_VERSION AND QT_MIN_VERSION) # if the include a library are found then we have it INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt3 DEFAULT_MSG QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Qt3 + REQUIRED_VARS QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE + VERSION_VAR QT_VERSION_STRING) SET(QT_FOUND ${QT3_FOUND} ) IF(QT_FOUND) @@ -293,8 +259,16 @@ IF(QT_FOUND) ENDIF(QT_QT_LIBRARY MATCHES "qt-mt") ENDIF(QT_FOUND) -EXEC_PROGRAM(${QT_MOC_EXECUTABLE} ARGS "-v" OUTPUT_VARIABLE QTVERSION_MOC) -EXEC_PROGRAM(${QT_UIC_EXECUTABLE} ARGS "-version" OUTPUT_VARIABLE QTVERSION_UIC) +IF(QT_MOC_EXECUTABLE) + EXECUTE_PROCESS(COMMAND ${QT_MOC_EXECUTABLE} "-v" + OUTPUT_VARIABLE QTVERSION_MOC + ERROR_QUIET) +ENDIF(QT_MOC_EXECUTABLE) +IF(QT_UIC_EXECUTABLE) + EXECUTE_PROCESS(COMMAND ${QT_UIC_EXECUTABLE} "-version" + OUTPUT_VARIABLE QTVERSION_UIC + ERROR_QUIET) +ENDIF(QT_UIC_EXECUTABLE) SET(_QT_UIC_VERSION_3 FALSE) IF("${QTVERSION_UIC}" MATCHES ".* 3..*") diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index c56827e..9b646b4 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -588,8 +588,9 @@ IF (QT_QMAKE_EXECUTABLE AND QTVERSION) SET(QT_LIBRARY_DIR ${QT_LIBRARY_DIR_TMP} CACHE INTERNAL "Qt library dir" FORCE) SET(QT_QTCORE_FOUND 1) ELSE() - MESSAGE("Warning: QT_QMAKE_EXECUTABLE reported QT_INSTALL_LIBS as ${QT_LIBRARY_DIR_TMP}") - MESSAGE("Warning: But QtCore couldn't be found. Qt must NOT be installed correctly, or it wasn't found for cross compiling.") + MESSAGE(WARNING "${QT_QMAKE_EXECUTABLE} reported QT_INSTALL_LIBS as \"${QT_LIBRARY_DIR_TMP}\" " + "but QtCore could not be found there. " + "Qt is NOT installed correctly for the target build environment.") IF(Qt4_FIND_REQUIRED) MESSAGE( FATAL_ERROR "Could NOT find QtCore. Check ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log for more details.") ENDIF(Qt4_FIND_REQUIRED) diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index c4adfd1..5e973e4 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -61,49 +61,44 @@ FIND_PROGRAM(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}) IF(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR) - # query the ruby version - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['MAJOR']" - OUTPUT_VARIABLE RUBY_VERSION_MAJOR) + FUNCTION(_RUBY_CONFIG_VAR RBVAR OUTVAR) + EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']" + RESULT_VARIABLE _RUBY_SUCCESS + OUTPUT_VARIABLE _RUBY_OUTPUT + ERROR_QUIET) + IF(_RUBY_SUCCESS OR NOT _RUBY_OUTPUT) + EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']" + RESULT_VARIABLE _RUBY_SUCCESS + OUTPUT_VARIABLE _RUBY_OUTPUT + ERROR_QUIET) + ENDIF(_RUBY_SUCCESS OR NOT _RUBY_OUTPUT) + SET(${OUTVAR} "${_RUBY_OUTPUT}" PARENT_SCOPE) + ENDFUNCTION(_RUBY_CONFIG_VAR) - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['MINOR']" - OUTPUT_VARIABLE RUBY_VERSION_MINOR) - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['TEENY']" - OUTPUT_VARIABLE RUBY_VERSION_PATCH) + # query the ruby version + _RUBY_CONFIG_VAR("MAJOR" RUBY_VERSION_MAJOR) + _RUBY_CONFIG_VAR("MINOR" RUBY_VERSION_MINOR) + _RUBY_CONFIG_VAR("TEENY" RUBY_VERSION_PATCH) # query the different directories - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['archdir']" - OUTPUT_VARIABLE RUBY_ARCH_DIR) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['arch']" - OUTPUT_VARIABLE RUBY_ARCH) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['rubyhdrdir']" - OUTPUT_VARIABLE RUBY_HDR_DIR) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['libdir']" - OUTPUT_VARIABLE RUBY_POSSIBLE_LIB_DIR) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['rubylibdir']" - OUTPUT_VARIABLE RUBY_RUBY_LIB_DIR) + _RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR) + _RUBY_CONFIG_VAR("arch" RUBY_ARCH) + _RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR) + _RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR) + _RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR) # site_ruby - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['sitearchdir']" - OUTPUT_VARIABLE RUBY_SITEARCH_DIR) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['sitelibdir']" - OUTPUT_VARIABLE RUBY_SITELIB_DIR) + _RUBY_CONFIG_VAR("sitearchdir" RUBY_SITEARCH_DIR) + _RUBY_CONFIG_VAR("sitelibdir" RUBY_SITELIB_DIR) # vendor_ruby available ? EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r vendor-specific -e "print 'true'" OUTPUT_VARIABLE RUBY_HAS_VENDOR_RUBY ERROR_QUIET) IF(RUBY_HAS_VENDOR_RUBY) - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['vendorlibdir']" - OUTPUT_VARIABLE RUBY_VENDORLIB_DIR) - - EXECUTE_PROCESS(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['vendorarchdir']" - OUTPUT_VARIABLE RUBY_VENDORARCH_DIR) + _RUBY_CONFIG_VAR("vendorlibdir" RUBY_VENDORLIB_DIR) + _RUBY_CONFIG_VAR("vendorarchdir" RUBY_VENDORARCH_DIR) ENDIF(RUBY_HAS_VENDOR_RUBY) # save the results in the cache so we don't have to run ruby the next time again diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake index 0dc02f5..1c04726 100644 --- a/Modules/FindSDL.cmake +++ b/Modules/FindSDL.cmake @@ -81,7 +81,6 @@ FIND_PATH(SDL_INCLUDE_DIR SDL.h /opt/csw # Blastwave /opt ) -#MESSAGE("SDL_INCLUDE_DIR is ${SDL_INCLUDE_DIR}") # SDL-1.1 is the name used by FreeBSD ports... # don't confuse it for the version number. @@ -97,8 +96,6 @@ FIND_LIBRARY(SDL_LIBRARY_TEMP /opt ) -#MESSAGE("SDL_LIBRARY_TEMP is ${SDL_LIBRARY_TEMP}") - IF(NOT SDL_BUILDING_LIBRARY) IF(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework") # Non-OS X framework versions expect you to also dynamically link to @@ -134,7 +131,6 @@ IF(MINGW) SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") ENDIF(MINGW) -SET(SDL_FOUND "NO") IF(SDL_LIBRARY_TEMP) # For SDLmain IF(NOT SDL_BUILDING_LIBRARY) @@ -169,9 +165,9 @@ IF(SDL_LIBRARY_TEMP) SET(SDL_LIBRARY ${SDL_LIBRARY_TEMP} CACHE STRING "Where the SDL Library can be found") # Set the temp variable to INTERNAL so it is not seen in the CMake GUI SET(SDL_LIBRARY_TEMP "${SDL_LIBRARY_TEMP}" CACHE INTERNAL "") - - SET(SDL_FOUND "YES") ENDIF(SDL_LIBRARY_TEMP) -#MESSAGE("SDL_LIBRARY is ${SDL_LIBRARY}") +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL + REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR) diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake index 5a5f59b..9a130fa 100644 --- a/Modules/FindSDL_image.cmake +++ b/Modules/FindSDL_image.cmake @@ -68,8 +68,7 @@ FIND_LIBRARY(SDLIMAGE_LIBRARY /opt ) -SET(SDLIMAGE_FOUND "NO") -IF(SDLIMAGE_LIBRARY AND SDLIMAGE_INCLUDE_DIR) - SET(SDLIMAGE_FOUND "YES") -ENDIF(SDLIMAGE_LIBRARY AND SDLIMAGE_INCLUDE_DIR) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLIMAGE + REQUIRED_VARS SDLIMAGE_LIBRARY SDLIMAGE_INCLUDE_DIR) diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake index e2b2294..ce1ae9e 100644 --- a/Modules/FindSDL_mixer.cmake +++ b/Modules/FindSDL_mixer.cmake @@ -68,8 +68,7 @@ FIND_LIBRARY(SDLMIXER_LIBRARY /opt ) -SET(SDLMIXER_FOUND "NO") -IF(SDLMIXER_LIBRARY AND SDLMIXER_INCLUDE_DIR) - SET(SDLMIXER_FOUND "YES") -ENDIF(SDLMIXER_LIBRARY AND SDLMIXER_INCLUDE_DIR) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLMIXER + REQUIRED_VARS SDLMIXER_LIBRARY SDLMIXER_INCLUDE_DIR) diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake index 730b129..b5ada54 100644 --- a/Modules/FindSDL_net.cmake +++ b/Modules/FindSDL_net.cmake @@ -67,8 +67,7 @@ FIND_LIBRARY(SDLNET_LIBRARY /opt ) -SET(SDLNET_FOUND "NO") -IF(SDLNET_LIBRARY AND SDLNET_INCLUDE_DIR) - SET(SDLNET_FOUND "YES") -ENDIF(SDLNET_LIBRARY AND SDLNET_INCLUDE_DIR) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLNET + REQUIRED_VARS SDLNET_LIBRARY SDLNET_INCLUDE_DIR) diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake index 959f3eb..8edf6ca 100644 --- a/Modules/FindSDL_sound.cmake +++ b/Modules/FindSDL_sound.cmake @@ -114,7 +114,6 @@ FIND_LIBRARY(SDL_SOUND_LIBRARY /opt/lib ) -SET(SDL_SOUND_FOUND "NO") IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) # CMake is giving me problems using TRY_COMPILE with the CMAKE_FLAGS @@ -414,8 +413,9 @@ IF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) ENDIF(NOT MY_RESULT) SET(SDL_SOUND_LIBRARIES "${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARIES_TMP}" CACHE INTERNAL "SDL_sound and dependent libraries") - SET(SDL_SOUND_FOUND "YES") ENDIF(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) - # MESSAGE("SDL_SOUND_LIBRARIES is ${SDL_SOUND_LIBRARIES}") +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_SOUND + REQUIRED_VARS SDL_SOUND_LIBRARIES SDL_SOUND_INCLUDE_DIR) diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake index b36ddd3..3d07ab7 100644 --- a/Modules/FindSDL_ttf.cmake +++ b/Modules/FindSDL_ttf.cmake @@ -68,8 +68,7 @@ FIND_LIBRARY(SDLTTF_LIBRARY PATH_SUFFIXES lib64 lib ) -SET(SDLTTF_FOUND "NO") -IF(SDLTTF_LIBRARY AND SDLTTF_INCLUDE_DIR) - SET(SDLTTF_FOUND "YES") -ENDIF(SDLTTF_LIBRARY AND SDLTTF_INCLUDE_DIR) +INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDLTTF + REQUIRED_VARS SDLTTF_LIBRARY SDLTTF_INCLUDE_DIR) diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake index 04646c0..76fb3c9 100644 --- a/Modules/FindX11.cmake +++ b/Modules/FindX11.cmake @@ -20,7 +20,7 @@ # X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND # X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND # X11_xf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_xf86misc_FOUND -# X11_xf86vmode_INCLUDE_PATH, X11_xf86vmode_FOUND +# X11_xf86vmode_INCLUDE_PATH, X11_Xxf86vm_LIB X11_xf86vmode_FOUND # X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND # X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND # X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND @@ -29,6 +29,7 @@ # X11_Xkb_INCLUDE_PATH, X11_Xkb_FOUND # X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND # X11_Xkbfile_INCLUDE_PATH, X11_Xkbfile_LIB, X11_Xkbfile_FOUND +# X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND # X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND # X11_XTest_INCLUDE_PATH, X11_XTest_LIB, X11_XTest_FOUND # X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND @@ -103,6 +104,7 @@ IF (UNIX) FIND_PATH(X11_Xkb_INCLUDE_PATH X11/extensions/XKB.h ${X11_INC_SEARCH_PATH}) FIND_PATH(X11_Xkblib_INCLUDE_PATH X11/XKBlib.h ${X11_INC_SEARCH_PATH}) FIND_PATH(X11_Xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h ${X11_INC_SEARCH_PATH}) + FIND_PATH(X11_Xmu_INCLUDE_PATH X11/Xmu/Xmu.h ${X11_INC_SEARCH_PATH}) FIND_PATH(X11_Xpm_INCLUDE_PATH X11/xpm.h ${X11_INC_SEARCH_PATH}) FIND_PATH(X11_XTest_INCLUDE_PATH X11/extensions/XTest.h ${X11_INC_SEARCH_PATH}) FIND_PATH(X11_XShm_INCLUDE_PATH X11/extensions/XShm.h ${X11_INC_SEARCH_PATH}) @@ -134,6 +136,7 @@ IF (UNIX) FIND_LIBRARY(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xinput_LIB Xi ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH}) + FIND_LIBRARY(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xrandr_LIB Xrandr ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH}) @@ -143,6 +146,7 @@ IF (UNIX) FIND_LIBRARY(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xv_LIB Xv ${X11_LIB_SEARCH_PATH}) FIND_LIBRARY(X11_Xxf86misc_LIB Xxf86misc ${X11_LIB_SEARCH_PATH}) + FIND_LIBRARY(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH}) SET(X11_LIBRARY_DIR "") IF(X11_X11_LIB) @@ -267,10 +271,10 @@ IF (UNIX) SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86misc_INCLUDE_PATH}) ENDIF (X11_xf86misc_INCLUDE_PATH AND X11_Xxf86misc_LIB) - IF (X11_xf86vmode_INCLUDE_PATH) + IF (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB) SET(X11_xf86vmode_FOUND TRUE) SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_xf86vmode_INCLUDE_PATH}) - ENDIF (X11_xf86vmode_INCLUDE_PATH) + ENDIF (X11_xf86vmode_INCLUDE_PATH AND X11_Xxf86vm_LIB) IF (X11_Xcursor_INCLUDE_PATH AND X11_Xcursor_LIB) SET(X11_Xcursor_FOUND TRUE) @@ -297,6 +301,11 @@ IF (UNIX) SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xkbfile_INCLUDE_PATH} ) ENDIF (X11_Xkbfile_INCLUDE_PATH AND X11_Xkbfile_LIB AND X11_Xlib_INCLUDE_PATH) + IF (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB) + SET(X11_Xmu_FOUND TRUE) + SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xmu_INCLUDE_PATH}) + ENDIF (X11_Xmu_INCLUDE_PATH AND X11_Xmu_LIB) + IF (X11_Xinput_INCLUDE_PATH AND X11_Xinput_LIB) SET(X11_Xinput_FOUND TRUE) SET(X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${X11_Xinput_INCLUDE_PATH}) @@ -435,6 +444,7 @@ IF (UNIX) X11_XRes_INCLUDE_PATH X11_Xxf86misc_LIB X11_xf86misc_INCLUDE_PATH + X11_Xxf86vm_LIB X11_xf86vmode_INCLUDE_PATH X11_Xi_LIB X11_Xi_INCLUDE_PATH @@ -456,6 +466,8 @@ IF (UNIX) X11_Xkblib_INCLUDE_PATH X11_Xkbfile_INCLUDE_PATH X11_Xkbfile_LIB + X11_Xmu_INCLUDE_PATH + X11_Xmu_LIB X11_Xscreensaver_INCLUDE_PATH X11_Xscreensaver_LIB X11_Xpm_INCLUDE_PATH diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index 781b6e7..ce23d5d 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -18,7 +18,7 @@ # [PREFIX_NAME <prefix_name>] # ) # -# ADD_COMPILER_EXPORT_FLAGS( [FATAL_WARNINGS] ) +# ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] ) # # By default GENERATE_EXPORT_HEADER() generates macro names in a file name # determined by the name of the library. The ADD_COMPILER_EXPORT_FLAGS function @@ -149,46 +149,20 @@ include(CheckCXXCompilerFlag) macro(_check_cxx_compiler_attribute _ATTRIBUTE _RESULT) check_cxx_source_compiles("${_ATTRIBUTE} int somefunc() { return 0; } int main() { return somefunc();}" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "unrecognized .*option" # GNU - FAIL_REGEX "ignoring unknown option" # MSVC - FAIL_REGEX "warning D9002" # MSVC, any lang - FAIL_REGEX "[Uu]nknown option" # HP - FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro - FAIL_REGEX "command option .* is not recognized" # XL ) endmacro() macro(_test_compiler_hidden_visibility) - if(CMAKE_COMPILER_IS_GNUCXX) - exec_program(${CMAKE_C_COMPILER} ARGS --version - OUTPUT_VARIABLE _gcc_version_info) - string(REGEX MATCH "[345]\\.[0-9]\\.[0-9]" - _gcc_version "${_gcc_version_info}") - # gcc on mac just reports: "gcc (GCC) 3.3 20030304 ..." without the - # patch level, handle this here: - if(NOT _gcc_version) - string(REGEX REPLACE ".*\\(GCC\\).* ([34]\\.[0-9]) .*" "\\1.0" - _gcc_version "${_gcc_version_info}") - endif() - - if(${_gcc_version} VERSION_LESS "4.2") - set(GCC_TOO_OLD TRUE) - message(WARNING "GCC version older than 4.2") - endif() - endif() - - if(CMAKE_CXX_COMPILER_ID MATCHES Intel) - exec_program(${CMAKE_CXX_COMPILER} ARGS -V - OUTPUT_VARIABLE _intel_version_info) - string(REGEX REPLACE ".*Version ([0-9]+(\\.[0-9]+)+).*" "\\1" - _intel_version "${_intel_version_info}") - - if(${_intel_version} VERSION_LESS "12.0") - set(_INTEL_TOO_OLD TRUE) - message(WARNING "Intel compiler older than 12.0") - endif() + if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.2") + set(GCC_TOO_OLD TRUE) + message(WARNING "GCC version older than 4.2") + elseif(CMAKE_COMPILER_IS_GNUC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.2") + set(GCC_TOO_OLD TRUE) + message(WARNING "GCC version older than 4.2") + elseif(CMAKE_CXX_COMPILER_ID MATCHES Intel AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.0") + set(_INTEL_TOO_OLD TRUE) + message(WARNING "Intel compiler older than 12.0") endif() diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in index 6259a5b..819cc5c 100644 --- a/Modules/NSIS.template.in +++ b/Modules/NSIS.template.in @@ -922,12 +922,12 @@ Function .onInit Pop $0 UserInfo::GetAccountType Pop $1 - StrCmp $1 "Admin" 0 +3 + StrCmp $1 "Admin" 0 +4 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Admin group' StrCpy $SV_ALLUSERS "AllUsers" Goto done - StrCmp $1 "Power" 0 +3 + StrCmp $1 "Power" 0 +4 SetShellVarContext all ;MessageBox MB_OK 'User "$0" is in the Power Users group' StrCpy $SV_ALLUSERS "AllUsers" diff --git a/Modules/Platform/Windows-Borland-C.cmake b/Modules/Platform/Windows-Borland-C.cmake index ebb74a1..e2f76aa 100644 --- a/Modules/Platform/Windows-Borland-C.cmake +++ b/Modules/Platform/Windows-Borland-C.cmake @@ -1,2 +1 @@ -include(Platform/Windows-Borland) -__borland_language(C) +include(Platform/Windows-Embarcadero-C) diff --git a/Modules/Platform/Windows-Borland-CXX.cmake b/Modules/Platform/Windows-Borland-CXX.cmake index 1260c0e..809490f 100644 --- a/Modules/Platform/Windows-Borland-CXX.cmake +++ b/Modules/Platform/Windows-Borland-CXX.cmake @@ -1,2 +1 @@ -include(Platform/Windows-Borland) -__borland_language(CXX) +include(Platform/Windows-Embarcadero-CXX) diff --git a/Modules/Platform/Windows-Embarcadero-C.cmake b/Modules/Platform/Windows-Embarcadero-C.cmake new file mode 100644 index 0000000..607fd4e --- /dev/null +++ b/Modules/Platform/Windows-Embarcadero-C.cmake @@ -0,0 +1,3 @@ +set(_lang C) +include(Platform/Windows-Embarcadero) +__embarcadero_language(C) diff --git a/Modules/Platform/Windows-Embarcadero-CXX.cmake b/Modules/Platform/Windows-Embarcadero-CXX.cmake new file mode 100644 index 0000000..279a4de --- /dev/null +++ b/Modules/Platform/Windows-Embarcadero-CXX.cmake @@ -0,0 +1,3 @@ +set(_lang CXX) +include(Platform/Windows-Embarcadero) +__embarcadero_language(CXX) diff --git a/Modules/Platform/Windows-Borland.cmake b/Modules/Platform/Windows-Embarcadero.cmake index 5c402bd..87b3767 100644 --- a/Modules/Platform/Windows-Borland.cmake +++ b/Modules/Platform/Windows-Embarcadero.cmake @@ -1,6 +1,6 @@ #============================================================================= -# Copyright 2002-2009 Kitware, Inc. +# Copyright 2002-2012 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -13,26 +13,33 @@ # License text for the above reference.) # This module is shared by multiple languages; use include blocker. -if(__WINDOWS_BORLAND) +if(__WINDOWS_EMBARCADERO) return() endif() -set(__WINDOWS_BORLAND 1) +set(__WINDOWS_EMBARCADERO 1) SET(BORLAND 1) -# Borland target type flags (bcc32 -h -t): -# -tW GUI App (implies -U__CONSOLE__) -# -tWC Console App (implies -D__CONSOLE__=1) -# -tWD Build a DLL (implies -D__DLL__=1 -D_DLL=1) -# -tWM Enable threads (implies -D__MT__=1 -D_MT=1) -# -tWR Use DLL runtime (implies -D_RTLDLL, and '-tW' too!!) -# -# Notes: -# - The flags affect linking so we pass them to the linker. -# - The flags affect preprocessing so we pass them to the compiler. -# - Since '-tWR' implies '-tW' we use '-tWR -tW-' instead. -# - Since '-tW-' disables '-tWD' we use '-tWR -tW- -tWD' for DLLs. -set(_RTLDLL "-tWR -tW-") +if("${CMAKE_${_lang}_COMPILER_VERSION}" VERSION_LESS 6.30) + # Borland target type flags (bcc32 -h -t): + set(_tW "-tW") # -tW GUI App (implies -U__CONSOLE__) + set(_tC "-tWC") # -tWC Console App (implies -D__CONSOLE__=1) + set(_tD "-tWD") # -tWD Build a DLL (implies -D__DLL__=1 -D_DLL=1) + set(_tM "-tWM") # -tWM Enable threads (implies -D__MT__=1 -D_MT=1) + set(_tR "-tWR -tW-") # -tWR Use DLL runtime (implies -D_RTLDLL, and '-tW' too!!) + # Notes: + # - The flags affect linking so we pass them to the linker. + # - The flags affect preprocessing so we pass them to the compiler. + # - Since '-tWR' implies '-tW' we use '-tWR -tW-' instead. + # - Since '-tW-' disables '-tWD' we use '-tWR -tW- -tWD' for DLLs. +else() + set(EMBARCADERO 1) + set(_tC "-tC") # Target is a console application + set(_tD "-tD") # Target is a shared library + set(_tM "-tM") # Target is multi-threaded + set(_tR "-tR") # Target uses the dynamic RTL + set(_tW "-tW") # Target is a Windows application +endif() set(_COMPILE_C "-c") set(_COMPILE_CXX "-P -c") @@ -50,14 +57,14 @@ SET(CMAKE_FIND_LIBRARY_SUFFIXES "-bcc.lib" ".lib") SET (CMAKE_MANGLE_OBJECT_FILE_NAMES "ON") # extra flags for a win32 exe -SET(CMAKE_CREATE_WIN32_EXE "-tW" ) +SET(CMAKE_CREATE_WIN32_EXE "${_tW}" ) # extra flags for a console app -SET(CMAKE_CREATE_CONSOLE_EXE "-tWC" ) +SET(CMAKE_CREATE_CONSOLE_EXE "${_tC}" ) SET (CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel.") -SET (CMAKE_EXE_LINKER_FLAGS_INIT "-tWM -lS:10000000 -lSc:10000000 ") +SET (CMAKE_EXE_LINKER_FLAGS_INIT "${_tM} -lS:10000000 -lSc:10000000 ") SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "-v") SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "-v") SET (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT}) @@ -67,18 +74,19 @@ SET (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT}) SET (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT}) SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT}) -macro(__borland_language lang) - set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-tWD") + +macro(__embarcadero_language lang) + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # compile a source file into an object file # place <DEFINES> outside the response file because Borland refuses # to parse quotes from the response file. set(CMAKE_${lang}_COMPILE_OBJECT - "<CMAKE_${lang}_COMPILER> ${_RTLDLL} <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}" + "<CMAKE_${lang}_COMPILER> ${_tR} <DEFINES> ${CMAKE_START_TEMP_FILE}-DWIN32 -o<OBJECT> <FLAGS> ${_COMPILE_${lang}} <SOURCE>${CMAKE_END_TEMP_FILE}" ) set(CMAKE_${lang}_LINK_EXECUTABLE - "<CMAKE_${lang}_COMPILER> ${_RTLDLL} -e<TARGET> ${CMAKE_START_TEMP_FILE}<LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" + "<CMAKE_${lang}_COMPILER> ${_tR} -e<TARGET> ${CMAKE_START_TEMP_FILE}<LINK_FLAGS> <FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" # "implib -c -w <TARGET_IMPLIB> <TARGET>" ) @@ -91,7 +99,7 @@ macro(__borland_language lang) # Create a module library. set(CMAKE_${lang}_CREATE_SHARED_MODULE - "<CMAKE_${lang}_COMPILER> ${_RTLDLL} -tWD ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" + "<CMAKE_${lang}_COMPILER> ${_tR} ${_tD} ${CMAKE_START_TEMP_FILE}-e<TARGET> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS>${CMAKE_END_TEMP_FILE}" ) # Create an import library for another target. @@ -112,7 +120,7 @@ macro(__borland_language lang) ) # Initial configuration flags. - set(CMAKE_${lang}_FLAGS_INIT "-tWM") + set(CMAKE_${lang}_FLAGS_INIT "${_tM}") set(CMAKE_${lang}_FLAGS_DEBUG_INIT "-Od -v") set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "-O1 -DNDEBUG") set(CMAKE_${lang}_FLAGS_RELEASE_INIT "-O2 -DNDEBUG") diff --git a/Modules/Platform/Windows-cl.cmake b/Modules/Platform/Windows-cl.cmake index ccccbc9..be6abb6 100644 --- a/Modules/Platform/Windows-cl.cmake +++ b/Modules/Platform/Windows-cl.cmake @@ -37,7 +37,7 @@ SET(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>") # that is automatically copied into try_compile directories # by the global generator. SET(MSVC_IDE 1) -IF(CMAKE_GENERATOR MATCHES "Makefiles") +IF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") SET(MSVC_IDE 0) IF(NOT CMAKE_VC_COMPILER_TESTS_RUN) SET(CMAKE_VC_COMPILER_TESTS 1) @@ -125,7 +125,7 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles") ENDIF(CMAKE_COMPILER_RETURN) MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3") ENDIF(NOT CMAKE_VC_COMPILER_TESTS_RUN) -ENDIF(CMAKE_GENERATOR MATCHES "Makefiles") +ENDIF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") IF(MSVC_C_ARCHITECTURE_ID MATCHES 64) SET(CMAKE_CL_64 1) diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 4da1a3f..f327125 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -393,7 +393,13 @@ MACRO(QT4_CREATE_TRANSLATION _qm_files) FOREACH(_pro_src ${_my_sources}) SET(_pro_srcs "${_pro_srcs} \"${_pro_src}\"") ENDFOREACH(_pro_src ${_my_sources}) - FILE(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}") + SET(_pro_includes) + GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES) + FOREACH(_pro_include ${_inc_DIRS}) + GET_FILENAME_COMPONENT(_abs_include "${_pro_include}" ABSOLUTE) + SET(_pro_includes "${_pro_includes} \"${_abs_include}\"") + ENDFOREACH(_pro_include ${CMAKE_CXX_INCLUDE_PATH}) + FILE(WRITE ${_ts_pro} "SOURCES = ${_pro_srcs}\nINCLUDEPATH = ${_pro_includes}\n") ENDIF(_my_sources) ADD_CUSTOM_COMMAND(OUTPUT ${_ts_file} COMMAND ${QT_LUPDATE_EXECUTABLE} diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index b78278c..84d0afd 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -25,6 +25,15 @@ # set(CMAKE_JAVA_TARGET_OUTPUT_NAME shibboleet.jar) # add_jar(foobar foobar.java) # +# To use a different output directory than CMAKE_CURRENT_BINARY_DIR +# you can set it with: +# +# set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) +# +# To define an entry point in your jar you can set it with: +# +# set(CMAKE_JAVA_JAR_ENTRY_POINT com/examples/MyProject/Main) +# # To add a VERSION to the target output name you can set it using # CMAKE_JAVA_TARGET_VERSION. This will create a jar file with the name # shibboleet-1.0.0.jar and will create a symlink shibboleet.jar @@ -112,7 +121,7 @@ # [VERSION TRUE|FALSE] # ) # -# Create jave documentation based on files or packages. For more +# Create java documentation based on files or packages. For more # details please read the javadoc manpage. # # There are two main signatures for create_javadoc. The first @@ -198,10 +207,19 @@ set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) function(add_jar _TARGET_NAME) set(_JAVA_SOURCE_FILES ${ARGN}) + if (NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) + set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) + endif(NOT DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) + + if (CMAKE_JAVA_JAR_ENTRY_POINT) + set(_ENTRY_POINT_OPTION e) + set(_ENTRY_POINT_VALUE ${CMAKE_JAVA_JAR_ENTRY_POINT}) + endif (CMAKE_JAVA_JAR_ENTRY_POINT) + if (LIBRARY_OUTPUT_PATH) set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH}) else (LIBRARY_OUTPUT_PATH) - set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR}) endif (LIBRARY_OUTPUT_PATH) set(CMAKE_JAVA_INCLUDE_PATH @@ -221,7 +239,7 @@ function(add_jar _TARGET_NAME) set(CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_PATH_FINAL}${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}") endforeach(JAVA_INCLUDE_DIR) - set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") + set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_JAVA_TARGET_OUTPUT_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}.jar") if (CMAKE_JAVA_TARGET_OUTPUT_NAME AND CMAKE_JAVA_TARGET_VERSION) @@ -246,7 +264,7 @@ function(add_jar _TARGET_NAME) get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH) get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE) - file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} ${_JAVA_FULL}) + file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_JAVA_TARGET_OUTPUT_DIR} ${_JAVA_FULL}) file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL}) string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN) string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN) @@ -312,20 +330,22 @@ function(add_jar _TARGET_NAME) endif (_JAVA_COMPILE_FILES) # create the jar file + set(_JAVA_JAR_OUTPUT_PATH + ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME}) if (CMAKE_JNI_TARGET) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + OUTPUT ${_JAVA_JAR_OUTPUT_PATH} COMMAND ${Java_JAR_EXECUTABLE} - -cf ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_JAVA_RESOURCE_FILES} @java_class_filelist COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} + -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} - -D_JAVA_TARGET_OUTPUT_NAME=${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} + -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_JAR_OUTPUT_PATH} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist @@ -334,12 +354,12 @@ function(add_jar _TARGET_NAME) ) else () add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + OUTPUT ${_JAVA_JAR_OUTPUT_PATH} COMMAND ${Java_JAR_EXECUTABLE} - -cf ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + -cf${_ENTRY_POINT_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_JAVA_RESOURCE_FILES} @java_class_filelist COMMAND ${CMAKE_COMMAND} - -D_JAVA_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} + -D_JAVA_TARGET_DIR=${CMAKE_JAVA_TARGET_OUTPUT_DIR} -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME} -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK} -P ${_JAVA_SYMLINK_SCRIPT} @@ -350,14 +370,14 @@ function(add_jar _TARGET_NAME) endif (CMAKE_JNI_TARGET) # Add the target and make sure we have the latest resource files. - add_custom_target(${_TARGET_NAME} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME}) + add_custom_target(${_TARGET_NAME} ALL DEPENDS ${_JAVA_JAR_OUTPUT_PATH}) set_property( TARGET ${_TARGET_NAME} PROPERTY INSTALL_FILES - ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + ${_JAVA_JAR_OUTPUT_PATH} ) if (_JAVA_TARGET_OUTPUT_LINK) @@ -366,8 +386,8 @@ function(add_jar _TARGET_NAME) ${_TARGET_NAME} PROPERTY INSTALL_FILES - ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} - ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_LINK} + ${_JAVA_JAR_OUTPUT_PATH} + ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} ) if (CMAKE_JNI_TARGET) @@ -376,7 +396,7 @@ function(add_jar _TARGET_NAME) ${_TARGET_NAME} PROPERTY JNI_SYMLINK - ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_LINK} + ${CMAKE_JAVA_TARGET_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK} ) endif (CMAKE_JNI_TARGET) endif (_JAVA_TARGET_OUTPUT_LINK) @@ -386,7 +406,7 @@ function(add_jar _TARGET_NAME) ${_TARGET_NAME} PROPERTY JAR_FILE - ${CMAKE_CURRENT_BINARY_DIR}/${_JAVA_TARGET_OUTPUT_NAME} + ${_JAVA_JAR_OUTPUT_PATH} ) set_property( diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 2a83045..ef76724 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -47,20 +47,17 @@ MACRO(SWIG_MODULE_INITIALIZE name language) SET(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}") SET(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}") - IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$") - MESSAGE(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") - ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xUNKNOWNx$") - SET(SWIG_MODULE_${name}_REAL_NAME "${name}") - IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$") + IF("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN") + MESSAGE(FATAL_ERROR "SWIG Error: Language \"${language}\" not found") + ELSEIF("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON") # when swig is used without the -interface it will produce in the module.py # a 'import _modulename' statement, which implies having a corresponding # _modulename.so (*NIX), _modulename.pyd (Win32). SET(SWIG_MODULE_${name}_REAL_NAME "_${name}") - ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPYTHONx$") - IF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$") + ELSEIF("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL") SET(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow") - ENDIF("x${SWIG_MODULE_${name}_LANGUAGE}x" MATCHES "^xPERLx$") + ENDIF() ENDMACRO(SWIG_MODULE_INITIALIZE) # diff --git a/Modules/WriteBasicConfigVersionFile.cmake b/Modules/WriteBasicConfigVersionFile.cmake index 0b6519d..038cb57 100644 --- a/Modules/WriteBasicConfigVersionFile.cmake +++ b/Modules/WriteBasicConfigVersionFile.cmake @@ -1,31 +1,6 @@ # WRITE_BASIC_CONFIG_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion) ) # -# Writes a file for use as <package>ConfigVersion.cmake file to <filename>. -# See the documentation of FIND_PACKAGE() for details on this. -# filename is the output filename, it should be in the build tree. -# major.minor.patch is the version number of the project to be installed -# The COMPATIBILITY mode AnyNewerVersion means that the installed package version -# will be considered compatible if it is newer or exactly the same as the requested version. -# If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion -# in that the major version number must be the same as requested, e.g. version 2.0 will -# not be considered compatible if 1.0 is requested. -# If your project has more elaborated version matching rules, you will need to write your -# own custom ConfigVersion.cmake file instead of using this macro. -# -# Example: -# write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake -# VERSION 1.2.3 -# COMPATIBILITY SameMajorVersion ) -# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake -# ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake -# DESTINATION lib/cmake/Foo ) -# -# Internally, this macro executes configure_file() to create the resulting -# version file. Depending on the COMPATIBLITY, either the file -# BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in -# is used. Please note that these two files are internal to CMake and you should -# not call configure_file() on them yourself, but they can be used as starting -# point to create more sophisticted custom ConfigVersion.cmake files. +# Deprecated, see WRITE_BASIC_PACKAGE_VERSION_FILE(), it is identical. #============================================================================= # Copyright 2008-2011 Alexander Neundorf, <neundorf@kde.org> diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index b5115b7..f9d1c03 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -185,6 +185,8 @@ SET(SRCS cmGeneratedFileStream.cxx cmGeneratorExpression.cxx cmGeneratorExpression.h + cmGeneratorTarget.cxx + cmGeneratorTarget.h cmGlobalGenerator.cxx cmGlobalGenerator.h cmGlobalUnixMakefileGenerator3.cxx @@ -353,6 +355,36 @@ IF (WIN32) ENDIF(NOT UNIX) ENDIF (WIN32) +# turn on Ninja by default +set(_CMAKE_DEFAULT_NINJA_VALUE TRUE) +# turn it off for platforms where it does not pass all the +# tests +if(WIN32 OR APPLE) + SET(_CMAKE_DEFAULT_NINJA_VALUE FALSE) +endif() +SET(CMAKE_ENABLE_NINJA ${_CMAKE_DEFAULT_NINJA_VALUE} CACHE BOOL + "Enable the ninja generator for CMake. currently not fully working for Windows or OSX") +MARK_AS_ADVANCED(CMAKE_ENABLE_NINJA) +IF(CMAKE_ENABLE_NINJA) + MESSAGE(STATUS "Enable ninja generator.") + SET(SRCS ${SRCS} + cmGlobalNinjaGenerator.cxx + cmGlobalNinjaGenerator.h + cmNinjaTypes.h + cmLocalNinjaGenerator.cxx + cmLocalNinjaGenerator.h + cmNinjaTargetGenerator.cxx + cmNinjaTargetGenerator.h + cmNinjaNormalTargetGenerator.cxx + cmNinjaNormalTargetGenerator.h + cmNinjaUtilityTargetGenerator.cxx + cmNinjaUtilityTargetGenerator.h + ) + ADD_DEFINITIONS(-DCMAKE_USE_NINJA) +ELSE() + MESSAGE(STATUS "Disable ninja generator.") +ENDIF() + # create a library used by the command line and the GUI ADD_LIBRARY(CMakeLib ${SRCS}) TARGET_LINK_LIBRARIES(CMakeLib cmsys @@ -449,6 +481,8 @@ SET(CPACK_SRCS CPack/cmCPackTarBZip2Generator.cxx CPack/cmCPackTarCompressGenerator.cxx CPack/cmCPackZIPGenerator.cxx + CPack/cmCPackDocumentVariables.cxx + CPack/cmCPackDocumentMacros.cxx ) IF(CYGWIN) diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 0ce5b01..0ff9050 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -57,13 +57,20 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive, std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); // Change to local toplevel cmSystemTools::ChangeDirectory(localToplevel.c_str()); + std::string filePrefix; + if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) + { + filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME"); + filePrefix += "/"; + } std::vector<std::string>::const_iterator fileIt; for (fileIt = component->Files.begin(); fileIt != component->Files.end(); ++fileIt ) { + std::string rp = filePrefix + *fileIt; cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: " - << (*fileIt) << std::endl); - archive.Add(*fileIt); + << rp << std::endl); + archive.Add(rp); if (!archive) { cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: " diff --git a/Source/CPack/cmCPackDocumentMacros.cxx b/Source/CPack/cmCPackDocumentMacros.cxx new file mode 100644 index 0000000..ddc75a4 --- /dev/null +++ b/Source/CPack/cmCPackDocumentMacros.cxx @@ -0,0 +1,16 @@ +#include "cmCPackDocumentMacros.h" + +void cmCPackDocumentMacros::GetMacrosDocumentation( + std::vector<cmDocumentationEntry>& ) +{ + // Commented-out example of use + // + // cmDocumentationEntry e("cpack_<macro>", + // "Brief Description" + // "which may be on several lines.", + // "Long description in pre-formatted format" + // " blah\n" + // " blah\n" + //); + //v.push_back(e); +} diff --git a/Source/CPack/cmCPackDocumentMacros.h b/Source/CPack/cmCPackDocumentMacros.h new file mode 100644 index 0000000..544f74f --- /dev/null +++ b/Source/CPack/cmCPackDocumentMacros.h @@ -0,0 +1,21 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + 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 cmCPackDocumentMacros_h +#define cmCPackDocumentMacros_h +#include "cmStandardIncludes.h" +class cmCPackDocumentMacros +{ +public: + static void GetMacrosDocumentation(std::vector<cmDocumentationEntry>& v); +}; + +#endif diff --git a/Source/CPack/cmCPackDocumentVariables.cxx b/Source/CPack/cmCPackDocumentVariables.cxx new file mode 100644 index 0000000..d2e3802 --- /dev/null +++ b/Source/CPack/cmCPackDocumentVariables.cxx @@ -0,0 +1,80 @@ +#include "cmCPackDocumentVariables.h" +#include "cmake.h" + +void cmCPackDocumentVariables::DefineVariables(cmake* cm) +{ + // Subsection: variables defined/used by cpack, + // which are common to all CPack generators + + cm->DefineProperty + ("CPACK_PACKAGING_INSTALL_PREFIX", cmProperty::VARIABLE, + "The prefix used in the built package.", + "Each CPack generator has a default value (like /usr)." + " This default value may" + " be overwritten from the CMakeLists.txt or the cpack command line" + " by setting an alternative value.\n" + "e.g. " + " set(CPACK_PACKAGING_INSTALL_PREFIX \"/opt\")\n" + "This is not the same purpose as CMAKE_INSTALL_PREFIX which" + " is used when installing from the build tree without building" + " a package." + "", false, + "Variables common to all CPack generators"); + + cm->DefineProperty + ("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", cmProperty::VARIABLE, + "Boolean toggle to include/exclude top level directory.", + "When preparing a package CPack installs the item under" + " the so-called top level directory. The purpose of" + " is to include (set to 1 or ON or TRUE) the top level directory" + " in the package or not (set to 0 or OFF or FALSE).\n" + "Each CPack generator as a built-in default value for this" + " variable. E.g. Archive generators (ZIP, TGZ, ...) includes" + " the top level whereas RPM or DEB don't. The user may override" + " the default value byt setting this variable.\n" + "There is a similar variable " + "CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY" + "which may be used to override the behavior for the component" + "packaging case which may have different default value for" + "historical (now backward compatibility) reason.", false, + "Variables common to all CPack generators"); + + cm->DefineProperty + ("CPACK_SET_DESTDIR", cmProperty::VARIABLE, + "Boolean toggle to make CPack use DESTDIR mechanism when" + " packaging.", "DESTDIR means DESTination DIRectory." + " It is commonly used by makefile " + "users in order to install software at non-default location. It " + "is a basic relocation mechanism. " + "It is usually invoked like this:\n" + " make DESTDIR=/home/john install\n" + "which will install the concerned software using the" + " installation prefix, e.g. \"/usr/local\" prepended with " + "the DESTDIR value which finally gives \"/home/john/usr/local\"." + " When preparing a package, CPack first installs the items to be " + "packaged in a local (to the build tree) directory by using the " + "same DESTDIR mechanism. Nevertheless, if " + "CPACK_SET_DESTDIR is set then CPack will set DESTDIR before" + " doing the local install. The most noticeable difference is" + " that without CPACK_SET_DESTDIR, CPack uses " + "CPACK_PACKAGING_INSTALL_PREFIX as a prefix whereas with " + "CPACK_SET_DESTDIR set, CPack will use CMAKE_INSTALL_PREFIX as" + " a prefix.\n" + "Manually setting CPACK_SET_DESTDIR may help (or simply be" + " necessary) if some install rules uses absolute " + "DESTINATION (see CMake INSTALL command)." + " However, starting with" + " CPack/CMake 2.8.3 RPM and DEB installers tries to handle DESTDIR" + " automatically so that it is seldom necessary for the user to set" + " it.", false, + "Variables common to all CPack generators"); + + cm->DefineProperty + ("CPACK_INSTALL_SCRIPT", cmProperty::VARIABLE, + "Extra CMake script provided by the user.", + "If set this CMake script will be executed by CPack " + "during its local [CPack-private] installation " + "which is done right before packaging the files." + " The script is not called by e.g.: make install.", false, + "Variables common to all CPack generators"); +} diff --git a/Source/CPack/cmCPackDocumentVariables.h b/Source/CPack/cmCPackDocumentVariables.h new file mode 100644 index 0000000..e7971be --- /dev/null +++ b/Source/CPack/cmCPackDocumentVariables.h @@ -0,0 +1,21 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + 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 cmCPackDocumentVariables_h +#define cmCPackDocumentVariables_h +class cmake; +class cmCPackDocumentVariables +{ +public: + static void DefineVariables(cmake* cm); +}; + +#endif diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 83b6b64..3b6135e 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -421,6 +421,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, if(ifs.is_open()) { cmGeneratedFileStream osf(sla_r.c_str()); + osf << "#include <CoreServices/CoreServices.r>\n\n"; osf << SLAHeader; osf << "\n"; osf << "data 'TEXT' (5002, \"English\") {\n"; @@ -481,13 +482,11 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Rez the SLA cmOStringStream embed_sla_command; - embed_sla_command << "/bin/bash -c \""; // need expansion of "*.r" embed_sla_command << this->GetOption("CPACK_COMMAND_REZ"); - embed_sla_command << " /Developer/Headers/FlatCarbon/*.r "; - embed_sla_command << "'" << sla_r << "'"; + embed_sla_command << " \"" << sla_r << "\""; embed_sla_command << " -a -o "; - embed_sla_command << "'" << temp_udco << "'\""; - + embed_sla_command << "\"" << temp_udco << "\""; + if(!this->RunCommand(embed_sla_command, &error)) { cmCPackLogger(cmCPackLog::LOG_ERROR, diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 083279f..f7d8a4d 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -691,6 +691,11 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // one install directory for each component. tempInstallDirectory += GetComponentInstallDirNameSuffix(installComponent); + if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) + { + tempInstallDirectory += "/"; + tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + } } if (!setDestDir) diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 2b94067..0787ef9 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -344,9 +344,9 @@ int cmCPackNSISGenerator::InitializeInternal() if ( cmSystemTools::IsOn(this->GetOption( "CPACK_INCLUDE_TOPLEVEL_DIRECTORY")) ) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY. " - "This option will be ignored." + cmCPackLogger(cmCPackLog::LOG_WARNING, + "NSIS Generator cannot work with CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. " + "This option will be reset to 0 (for this generator only)." << std::endl); this->SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", 0); } diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 163f744..6f5055c 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -14,6 +14,8 @@ // Need these for documentation support. #include "cmake.h" #include "cmDocumentation.h" +#include "cmCPackDocumentVariables.h" +#include "cmCPackDocumentMacros.h" #include "cmCPackGeneratorFactory.h" #include "cmCPackGenerator.h" #include "cmake.h" @@ -24,6 +26,7 @@ #include "cmCPackLog.h" #include <cmsys/CommandLineArguments.hxx> +#include <cmsys/SystemTools.hxx> #include <memory> // auto_ptr //---------------------------------------------------------------------------- @@ -90,6 +93,40 @@ static const char * cmDocumentationOptions[][3] = "If vendor is not specified on cpack command line " "(or inside CMakeLists.txt) then" "CPack.cmake defines it with a default value"}, + {"--help-command cmd [file]", "Print help for a single command and exit.", + "Full documentation specific to the given command is displayed. " + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-command-list [file]", "List available commands and exit.", + "The list contains all commands for which help may be obtained by using " + "the --help-command argument followed by a command name. " + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-commands [file]", "Print help for all commands and exit.", + "Full documentation specific for all current command is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variable var [file]", + "Print help for a single variable and exit.", + "Full documentation specific to the given variable is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variable-list [file]", "List documented variables and exit.", + "The list contains all variables for which help may be obtained by using " + "the --help-variable argument followed by a variable name. If a file is " + "specified, the help is written into it." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, + {"--help-variables [file]", "Print help for all variables and exit.", + "Full documentation for all variables is displayed." + "If a file is specified, the documentation is written into and the output " + "format is determined depending on the filename suffix. Supported are man " + "page, HTML, DocBook and plain text."}, {0,0,0} }; @@ -137,12 +174,15 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, return 1; } + //---------------------------------------------------------------------------- // this is CPack. int main (int argc, char *argv[]) { cmSystemTools::FindExecutableDirectory(argv[0]); cmCPackLog log; + int nocwd = 0; + log.SetErrorPrefix("CPack Error: "); log.SetWarningPrefix("CPack Warning: "); log.SetOutputPrefix("CPack: "); @@ -154,6 +194,7 @@ int main (int argc, char *argv[]) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Current working directory cannot be established." << std::endl); + nocwd = 1; } std::string generator; @@ -179,7 +220,6 @@ int main (int argc, char *argv[]) cpackConfigFile = ""; - cmDocumentation doc; cmsys::CommandLineArguments arg; arg.Initialize(argc, argv); typedef cmsys::CommandLineArguments argT; @@ -252,17 +292,25 @@ int main (int argc, char *argv[]) generators.SetLogger(&log); cmCPackGenerator* cpackGenerator = 0; - if ( !helpFull.empty() || !helpMAN.empty() || - !helpHTML.empty() || helpVersion ) + cmDocumentation doc; + doc.addCPackStandardDocSections(); + /* Were we invoked to display doc or to do some work ? */ + if(doc.CheckOptions(argc, argv,"-G") || nocwd) { - help = true; + help = true; } + else + { + help = false; + } + + // This part is used for cpack documentation lookup as well. + cminst.AddCMakePaths(); if ( parsed && !help ) { // find out which system cpack is running on, so it can setup the search // paths, so FIND_XXX() commands can be used in scripts - cminst.AddCMakePaths(); std::string systemFile = globalMF->GetModulesFile("CMakeDetermineSystem.cmake"); if (!globalMF->ReadListFile(0, systemFile.c_str())) @@ -465,14 +513,48 @@ int main (int argc, char *argv[]) */ if ( help ) { - doc.CheckOptions(argc, argv); // Construct and print requested documentation. + doc.SetName("cpack"); doc.SetSection("Name",cmDocumentationName); doc.SetSection("Usage",cmDocumentationUsage); doc.SetSection("Description",cmDocumentationDescription); doc.PrependSection("Options",cmDocumentationOptions); + // statically (in C++ code) defined variables + cmCPackDocumentVariables::DefineVariables(&cminst); + + std::vector<cmDocumentationEntry> commands; + + std::string docedFile; + std::string docPath; + cmDocumentation::documentedModulesList_t docedModList; + + docedFile = globalMF->GetModulesFile("CPack.cmake"); + if (docedFile.length()!=0) + { + docPath = cmSystemTools::GetFilenamePath(docedFile.c_str()); + doc.getDocumentedModulesListInDir(docPath,"CPack*.cmake",docedModList); + } + + // parse the files for documentation. + cmDocumentation::documentedModulesList_t::iterator docedIt; + for (docedIt = docedModList.begin(); + docedIt!= docedModList.end(); ++docedIt) + { + doc.GetStructuredDocFromFile( + (docedIt->first).c_str(), + commands,&cminst); + } + + std::map<std::string,cmDocumentationSection *> propDocs; + cminst.GetPropertiesDocumentation(propDocs); + doc.SetSections(propDocs); + cminst.GetCommandDocumentation(commands,true,false); + // statically (in C++ code) defined macros/commands + cmCPackDocumentMacros::GetMacrosDocumentation(commands); + doc.SetSection("Commands",commands); + std::vector<cmDocumentationEntry> v; cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt; for( generatorIt = generators.GetGeneratorsList().begin(); diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h index 9eb4907..cabc39b 100644 --- a/Source/CTest/cmCTestBuildCommand.h +++ b/Source/CTest/cmCTestBuildCommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_build";} + virtual const char* GetName() const { return "ctest_build";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Build the project."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_build([BUILD build_dir] [TARGET target] [RETURN_VALUE res]\n" diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h index 156e6f2..b343fc1 100644 --- a/Source/CTest/cmCTestConfigureCommand.h +++ b/Source/CTest/cmCTestConfigureCommand.h @@ -38,12 +38,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_configure";} + virtual const char* GetName() const { return "ctest_configure";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Configure the project build tree."; } @@ -51,7 +51,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_configure([BUILD build_dir] [SOURCE source_dir] [APPEND]\n" diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h index 25c10dc..2fe762c 100644 --- a/Source/CTest/cmCTestCoverageCommand.h +++ b/Source/CTest/cmCTestCoverageCommand.h @@ -39,12 +39,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_coverage";} + virtual const char* GetName() const { return "ctest_coverage";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Collect coverage tool results."; } @@ -52,7 +52,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_coverage([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n" diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 0b1c9fe..309abb1 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -555,7 +555,7 @@ int cmCTestCoverageHandler::ProcessHandler() covSumFile << "\t<File Name=\"" << cmXMLSafe(fileName) << "\" FullPath=\"" << cmXMLSafe( this->CTest->GetShortPathToFile(fullFileName.c_str())) - << "\" Covered=\"" << (tested > 0 ? "true":"false") << "\">\n" + << "\" Covered=\"" << (tested+untested > 0 ? "true":"false") << "\">\n" << "\t\t<LOCTested>" << tested << "</LOCTested>\n" << "\t\t<LOCUnTested>" << untested << "</LOCUnTested>\n" << "\t\t<PercentCoverage>"; diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h index cf61045..a763fe9 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h @@ -48,12 +48,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_empty_binary_directory";} + virtual const char* GetName() const { return "ctest_empty_binary_directory";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "empties the binary directory"; } @@ -61,7 +61,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_empty_binary_directory( directory )\n" diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h index 8fa142f..399fe8b 100644 --- a/Source/CTest/cmCTestMemCheckCommand.h +++ b/Source/CTest/cmCTestMemCheckCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_memcheck";} + virtual const char* GetName() const { return "ctest_memcheck";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Run tests with a dynamic analysis tool."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_memcheck([BUILD build_dir] [RETURN_VALUE res] [APPEND]\n" diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h index 2213c8f..f382b0f 100644 --- a/Source/CTest/cmCTestReadCustomFilesCommand.h +++ b/Source/CTest/cmCTestReadCustomFilesCommand.h @@ -46,12 +46,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_read_custom_files";} + virtual const char* GetName() const { return "ctest_read_custom_files";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "read CTestCustom files."; } @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_read_custom_files( directory ... )\n" diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h index 5765150..6df69af 100644 --- a/Source/CTest/cmCTestRunScriptCommand.h +++ b/Source/CTest/cmCTestRunScriptCommand.h @@ -47,12 +47,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_run_script";} + virtual const char* GetName() const { return "ctest_run_script";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "runs a ctest -S script"; } @@ -60,7 +60,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_run_script([NEW_PROCESS] script_file_name script_file_name1 \n" diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h index 468cd85..80fd6af 100644 --- a/Source/CTest/cmCTestSleepCommand.h +++ b/Source/CTest/cmCTestSleepCommand.h @@ -47,12 +47,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_sleep";} + virtual const char* GetName() const { return "ctest_sleep";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "sleeps for some amount of time"; } @@ -60,7 +60,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_sleep(<seconds>)\n" diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index afbc77b..6be4770 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h @@ -55,12 +55,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_start";} + virtual const char* GetName() const { return "ctest_start";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Starts the testing for a given model"; } @@ -68,7 +68,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_start(Model [TRACK <track>] [APPEND] [source [binary]])\n" diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index edc9c65..53ee875 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -48,12 +48,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_submit";} + virtual const char* GetName() const { return "ctest_submit";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Submit results to a dashboard server."; } @@ -61,7 +61,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_submit([PARTS ...] [FILES ...] [RETRY_COUNT count] " diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h index c6fd631..d184ff2 100644 --- a/Source/CTest/cmCTestTestCommand.h +++ b/Source/CTest/cmCTestTestCommand.h @@ -39,12 +39,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_test";} + virtual const char* GetName() const { return "ctest_test";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Run tests in the project build tree."; } @@ -52,7 +52,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_test([BUILD build_dir] [APPEND]\n" diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 9b12393..ead449e 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -59,11 +59,11 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "subdirs";} + virtual const char* GetName() const { return "subdirs";} // Unused methods - virtual const char* GetTerseDocumentation() { return ""; } - virtual const char* GetFullDocumentation() { return ""; } + virtual const char* GetTerseDocumentation() const { return ""; } + virtual const char* GetFullDocumentation() const { return ""; } cmTypeMacro(cmCTestSubdirCommand, cmCommand); @@ -161,11 +161,11 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_subdirectory";} + virtual const char* GetName() const { return "add_subdirectory";} // Unused methods - virtual const char* GetTerseDocumentation() { return ""; } - virtual const char* GetFullDocumentation() { return ""; } + virtual const char* GetTerseDocumentation() const { return ""; } + virtual const char* GetFullDocumentation() const { return ""; } cmTypeMacro(cmCTestAddSubdirectoryCommand, cmCommand); @@ -251,11 +251,11 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ADD_TEST";} + virtual const char* GetName() const { return "ADD_TEST";} // Unused methods - virtual const char* GetTerseDocumentation() { return ""; } - virtual const char* GetFullDocumentation() { return ""; } + virtual const char* GetTerseDocumentation() const { return ""; } + virtual const char* GetFullDocumentation() const { return ""; } cmTypeMacro(cmCTestAddTestCommand, cmCommand); @@ -299,11 +299,11 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "SET_TESTS_PROPERTIES";} + virtual const char* GetName() const { return "SET_TESTS_PROPERTIES";} // Unused methods - virtual const char* GetTerseDocumentation() { return ""; } - virtual const char* GetFullDocumentation() { return ""; } + virtual const char* GetTerseDocumentation() const { return ""; } + virtual const char* GetFullDocumentation() const { return ""; } cmTypeMacro(cmCTestSetTestsPropertiesCommand, cmCommand); diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h index 7f36928..c578fff 100644 --- a/Source/CTest/cmCTestUpdateCommand.h +++ b/Source/CTest/cmCTestUpdateCommand.h @@ -39,12 +39,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_update";} + virtual const char* GetName() const { return "ctest_update";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Update the work tree from version control."; } @@ -52,7 +52,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_update([SOURCE source] [RETURN_VALUE res])\n" diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index 6c2a4c2..62f379f 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "ctest_upload";} + virtual const char* GetName() const { return "ctest_upload";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Upload files to a dashboard server."; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " ctest_upload(FILES ...)\n" diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index b1a72af..623d7d3 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -102,6 +102,7 @@ int main(int argc, char** argv) { cmSystemTools::FindExecutableDirectory(argv[0]); cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(doc.CheckOptions(argc, argv)) { cmake hcm; diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 6c7627f..4fee0bb 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -409,12 +409,11 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */) char thirdLine[512]=""; if (process) { - sprintf(firstLine, - " "); - sprintf(secondLine, - " "); - sprintf(thirdLine, - " "); + const char* clearLine = + " "; + strcpy(firstLine, clearLine); + strcpy(secondLine, clearLine); + strcpy(thirdLine, clearLine); } else { diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 4785188..056e48e 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -10,11 +10,11 @@ # See the License for more information. #============================================================================= PROJECT(QtDialog) -SET(QT_MIN_VERSION "4.3.0") +SET(QT_MIN_VERSION "4.4.0") FIND_PACKAGE(Qt4 REQUIRED) IF(NOT QT4_FOUND) - MESSAGE(SEND_ERROR "Failed to find Qt 4.3 or greater.") + MESSAGE(SEND_ERROR "Failed to find Qt 4.4 or greater.") ELSE(NOT QT4_FOUND) INCLUDE(${QT_USE_FILE}) diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 7ba7f51..b4f3d72 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -64,6 +64,7 @@ int main(int argc, char** argv) // check docs first so that X is not need to get docs // do docs, if args were given cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(argc >1 && doc.CheckOptions(argc, argv)) { // Construct and print requested documentation. diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 338eaff..45b4cd3 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -554,8 +554,7 @@ void CMakeSetupDialog::doHelp() void CMakeSetupDialog::doInterrupt() { this->enterState(Interrupting); - QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), - "interrupt", Qt::QueuedConnection); + this->CMakeThread->cmakeInstance()->interrupt(); } void CMakeSetupDialog::doSourceBrowse() diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index a40a175..73050f3 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -63,6 +63,8 @@ QCMake::QCMake(QObject* p) #endif this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this); + cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this); + std::vector<std::string> generators; this->CMakeInstance->GetRegisteredGenerators(generators); std::vector<std::string>::iterator iter; @@ -170,6 +172,7 @@ void QCMake::configure() this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode); this->CMakeInstance->PreLoadCMakeFiles(); + InterruptFlag = 0; cmSystemTools::ResetErrorOccuredFlag(); int err = this->CMakeInstance->Configure(); @@ -188,7 +191,9 @@ void QCMake::generate() UINT lastErrorMode = SetErrorMode(0); #endif + InterruptFlag = 0; cmSystemTools::ResetErrorOccuredFlag(); + int err = this->CMakeInstance->Generate(); #ifdef Q_OS_WIN @@ -337,7 +342,13 @@ QCMakePropertyList QCMake::properties() const void QCMake::interrupt() { - cmSystemTools::SetFatalErrorOccured(); + this->InterruptFlag.ref(); +} + +bool QCMake::interruptCallback(void* cd) +{ + QCMake* self = reinterpret_cast<QCMake*>(cd); + return self->InterruptFlag; } void QCMake::progressCallback(const char* msg, float percent, void* cd) diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index 0d10823..0d68586 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -23,6 +23,7 @@ #include <QList> #include <QStringList> #include <QMetaType> +#include <QAtomicInt> class cmake; @@ -78,7 +79,7 @@ public slots: void generate(); /// set the property values void setProperties(const QCMakePropertyList&); - /// interrupt the configure or generate process + /// interrupt the configure or generate process (if connecting, make a direct connection) void interrupt(); /// delete the cache in binary directory void deleteCache(); @@ -133,6 +134,7 @@ signals: protected: cmake* CMakeInstance; + static bool interruptCallback(void*); static void progressCallback(const char* msg, float percent, void* cd); static void errorCallback(const char* msg, const char* title, bool&, void* cd); @@ -145,6 +147,7 @@ protected: QString Generator; QStringList AvailableGenerators; QString CMakeExecutable; + QAtomicInt InterruptFlag; }; #endif // __QCMake_h diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h index 05e7dc2..1f770ed 100644 --- a/Source/cmAddCustomCommandCommand.h +++ b/Source/cmAddCustomCommandCommand.h @@ -44,12 +44,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "add_custom_command";} + virtual const char* GetName() const {return "add_custom_command";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a custom build rule to the generated build system."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "There are two main signatures for add_custom_command " diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h index 6d94fb2..50bffef 100644 --- a/Source/cmAddCustomTargetCommand.h +++ b/Source/cmAddCustomTargetCommand.h @@ -42,13 +42,13 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() + virtual const char* GetName() const {return "add_custom_target";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a target with no output so it will always be built."; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_custom_target(Name [ALL] [command1 [args1...]]\n" diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h index 0617f04..7bb3767 100644 --- a/Source/cmAddDefinitionsCommand.h +++ b/Source/cmAddDefinitionsCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "add_definitions";} + virtual const char* GetName() const {return "add_definitions";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Adds -D define flags to the compilation of source files."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_definitions(-DFOO -DBAR ...)\n" diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h index fee011c..14a7741 100644 --- a/Source/cmAddDependenciesCommand.h +++ b/Source/cmAddDependenciesCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_dependencies";} + virtual const char* GetName() const { return "add_dependencies";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a dependency between top-level targets."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_dependencies(target-name depend-target1\n" diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h index 6834f58..1e9f9b3 100644 --- a/Source/cmAddExecutableCommand.h +++ b/Source/cmAddExecutableCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_executable";} + virtual const char* GetName() const { return "add_executable";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add an executable to the project using the specified source files."; @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_executable(<name> [WIN32] [MACOSX_BUNDLE]\n" diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 9a776fb..c1d0e9d 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -64,6 +64,12 @@ bool cmAddLibraryCommand type = cmTarget::MODULE_LIBRARY; haveSpecifiedType = true; } + else if(libType == "OBJECT") + { + ++s; + type = cmTarget::OBJECT_LIBRARY; + haveSpecifiedType = true; + } else if(libType == "UNKNOWN") { ++s; @@ -118,6 +124,14 @@ bool cmAddLibraryCommand this->SetError("called with IMPORTED argument but no library type."); return false; } + if(type == cmTarget::OBJECT_LIBRARY) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "The OBJECT library type may not be used for IMPORTED libraries." + ); + return true; + } // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(libName.c_str())) diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h index edca1bb..9ca9cbe 100644 --- a/Source/cmAddLibraryCommand.h +++ b/Source/cmAddLibraryCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_library";} + virtual const char* GetName() const { return "add_library";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a library to the project using the specified source files."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_library(<name> [STATIC | SHARED | MODULE]\n" diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h index dae705e..3d6f51e 100644 --- a/Source/cmAddSubDirectoryCommand.h +++ b/Source/cmAddSubDirectoryCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_subdirectory";} + virtual const char* GetName() const { return "add_subdirectory";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a subdirectory to the build."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_subdirectory(source_dir [binary_dir] \n" diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h index edaf12c..59f10f6 100644 --- a/Source/cmAddTestCommand.h +++ b/Source/cmAddTestCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "add_test";} + virtual const char* GetName() const { return "add_test";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add a test to the project with the specified arguments."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " add_test(testname Exename arg1 arg2 ... )\n" diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h index 704e2ed..f059e44 100644 --- a/Source/cmAuxSourceDirectoryCommand.h +++ b/Source/cmAuxSourceDirectoryCommand.h @@ -44,12 +44,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "aux_source_directory";} + virtual const char* GetName() const { return "aux_source_directory";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Find all source files in a directory."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " aux_source_directory(<dir> <variable>)\n" diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx index 554f452..9097a74 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands.cxx @@ -12,7 +12,7 @@ // This file is used to compile all the commands // that CMake knows about at compile time. // This is sort of a boot strapping approach since you would -// like to have CMake to build CMake. +// like to have CMake to build CMake. #include "cmCommands.h" #include "cmAddCustomCommandCommand.cxx" #include "cmAddCustomTargetCommand.cxx" @@ -38,6 +38,7 @@ #include "cmEndFunctionCommand.cxx" #include "cmEndIfCommand.cxx" #include "cmEndMacroCommand.cxx" +#include "cmEndWhileCommand.cxx" #include "cmExecProgramCommand.cxx" #include "cmExecuteProcessCommand.cxx" #include "cmExternalMakefileProjectGenerator.cxx" @@ -91,6 +92,7 @@ #include "cmTryCompileCommand.cxx" #include "cmTryRunCommand.cxx" #include "cmUnsetCommand.cxx" +#include "cmWhileCommand.cxx" void GetBootstrapCommands(std::list<cmCommand*>& commands) { @@ -111,11 +113,12 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands) commands.push_back(new cmDefinePropertyCommand); commands.push_back(new cmElseCommand); commands.push_back(new cmEnableLanguageCommand); - commands.push_back(new cmEnableTestingCommand); + commands.push_back(new cmEnableTestingCommand); commands.push_back(new cmEndForEachCommand); commands.push_back(new cmEndFunctionCommand); commands.push_back(new cmEndIfCommand); commands.push_back(new cmEndMacroCommand); + commands.push_back(new cmEndWhileCommand); commands.push_back(new cmExecProgramCommand); commands.push_back(new cmExecuteProcessCommand); commands.push_back(new cmFileCommand); @@ -164,4 +167,5 @@ void GetBootstrapCommands(std::list<cmCommand*>& commands) commands.push_back(new cmTryCompileCommand); commands.push_back(new cmTryRunCommand); commands.push_back(new cmUnsetCommand); + commands.push_back(new cmWhileCommand); } diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h index 72796e8..67ef37e 100644 --- a/Source/cmBreakCommand.h +++ b/Source/cmBreakCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "break";} + virtual const char* GetName() const {return "break";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Break from an enclosing foreach or while loop."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " break()\n" diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h index 1d247d2..a333c5d 100644 --- a/Source/cmBuildCommand.h +++ b/Source/cmBuildCommand.h @@ -50,12 +50,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "build_command";} + virtual const char* GetName() const {return "build_command";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get the command line to build this project."; } @@ -63,7 +63,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " build_command(<variable>\n" diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h index 29a680f..26505a2 100644 --- a/Source/cmBuildNameCommand.h +++ b/Source/cmBuildNameCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "build_name";} + virtual const char* GetName() const {return "build_name";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use ${CMAKE_SYSTEM} and ${CMAKE_CXX_COMPILER} instead."; @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " build_name(variable)\n" @@ -69,7 +69,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h index 1121386..d23ce79 100644 --- a/Source/cmCMakeMinimumRequired.h +++ b/Source/cmCMakeMinimumRequired.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "cmake_minimum_required";} + virtual const char* GetName() const {return "cmake_minimum_required";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set the minimum required version of cmake for a project."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]]\n" diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h index afd3001..4f1ed36 100644 --- a/Source/cmCMakePolicyCommand.h +++ b/Source/cmCMakePolicyCommand.h @@ -41,17 +41,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "cmake_policy";} + virtual const char* GetName() const {return "cmake_policy";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Manage CMake Policy settings."; } @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "As CMake evolves it is sometimes necessary to change existing " diff --git a/Source/cmCommand.h b/Source/cmCommand.h index 7817eb3..4faaee3 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -96,7 +96,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() + virtual bool IsScriptable() const { return false; } @@ -105,25 +105,36 @@ public: * This determines if usage of the method is discouraged or not. * This is currently only used for generating the documentation. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return false; } /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() const + { + return true; + } + + /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() = 0; + virtual const char* GetName() const = 0; /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() = 0; + virtual const char* GetTerseDocumentation() const = 0; /** * More documentation. */ - virtual const char* GetFullDocumentation() = 0; + virtual const char* GetFullDocumentation() const = 0; /** * Enable the command. @@ -140,7 +151,7 @@ public: /** * Query whether the command is enabled. */ - bool GetEnabled() + bool GetEnabled() const {return this->Enabled;} /** diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h index a211e95..cdb832b 100644 --- a/Source/cmCommandArgumentParserHelper.h +++ b/Source/cmCommandArgumentParserHelper.h @@ -81,7 +81,6 @@ private: cmStdString InputBuffer; std::vector<char> OutputBuffer; int CurrentLine; - int UnionsAvailable; int Verbose; void Print(const char* place, const char* str); diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index bb1e4e2..49ed967 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -14,7 +14,6 @@ #include "cmAuxSourceDirectoryCommand.cxx" #include "cmBuildNameCommand.cxx" #include "cmElseIfCommand.cxx" -#include "cmEndWhileCommand.cxx" #include "cmExportCommand.cxx" #include "cmExportLibraryDependencies.cxx" #include "cmFLTKWrapUICommand.cxx" @@ -34,7 +33,6 @@ #include "cmVariableRequiresCommand.cxx" #include "cmVariableWatchCommand.cxx" -#include "cmWhileCommand.cxx" #include "cmWriteFileCommand.cxx" // This one must be last because it includes windows.h and @@ -53,7 +51,6 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands.push_back(new cmAuxSourceDirectoryCommand); commands.push_back(new cmBuildNameCommand); commands.push_back(new cmElseIfCommand); - commands.push_back(new cmEndWhileCommand); commands.push_back(new cmExportCommand); commands.push_back(new cmExportLibraryDependenciesCommand); commands.push_back(new cmFLTKWrapUICommand); @@ -73,7 +70,6 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands.push_back(new cmUtilitySourceCommand); commands.push_back(new cmVariableRequiresCommand); commands.push_back(new cmVariableWatchCommand); - commands.push_back(new cmWhileCommand); commands.push_back(new cmWriteFileCommand); #endif } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 9a075bd..055aab0 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -27,7 +27,7 @@ This file computes an ordered list of link items to use when linking a single target in one configuration. Each link item is identified by the string naming it. A graph of dependencies is created in which -each node corresponds to one item and directed eges lead from nodes to +each node corresponds to one item and directed edges lead from nodes to those which must *follow* them on the link line. For example, the graph @@ -42,7 +42,7 @@ search of the link dependencies starting from the main target. There are two types of items: those with known direct dependencies and those without known dependencies. We will call the two types "known -items" and "unknown items", respecitvely. Known items are those whose +items" and "unknown items", respectively. Known items are those whose names correspond to targets (built or imported) and those for which an old-style <item>_LIB_DEPENDS variable is defined. All other items are unknown and we must infer dependencies for them. For items that look @@ -150,7 +150,7 @@ times the component needs to be seen (once for trivial components, twice for non-trivial). If at any time another component finishes and re-adds an already pending component, the pending component is reset so that it needs to be seen in its entirety again. This ensures that -all dependencies of a component are satisified no matter where it +all dependencies of a component are satisfied no matter where it appears. After the original link line has been completed, we append to it the @@ -633,6 +633,19 @@ cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index, tgt = 0; } + if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY) + { + cmOStringStream e; + e << "Target \"" << this->Target->GetName() << "\" links to " + "OBJECT library \"" << tgt->GetName() << "\" but this is not " + "allowed. " + "One may link only to STATIC or SHARED libraries, or to executables " + "with the ENABLE_EXPORTS property set."; + this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(), + this->Target->GetBacktrace()); + tgt = 0; + } + // Return the target found, if any. return tgt; } diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index edf6c35..df78bf8 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -248,6 +248,10 @@ cmComputeLinkInformation this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); this->CMakeInstance = this->GlobalGenerator->GetCMakeInstance(); + // Check whether to recognize OpenBSD-style library versioned names. + this->OpenBSD = this->Makefile->GetCMakeInstance() + ->GetPropertyAsBool("FIND_LIBRARY_USE_OPENBSD_VERSIONING"); + // The configuration being linked. this->Config = config; @@ -973,7 +977,15 @@ cmComputeLinkInformation } // Finish the list. - libext += ")$"; + libext += ")"; + + // Add an optional OpenBSD version component. + if(this->OpenBSD) + { + libext += "(\\.[0-9]+\\.[0-9]+)?"; + } + + libext += "$"; return libext; } @@ -1760,6 +1772,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, !linking_for_install); bool use_link_rpath = outputRuntime && linking_for_install && + !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH") && this->Target->GetPropertyAsBool("INSTALL_RPATH_USE_LINK_PATH"); // Construct the RPATH. diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index bbeed68..f60f8d3 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -128,6 +128,7 @@ private: cmsys::RegularExpression ExtractSharedLibraryName; cmsys::RegularExpression ExtractAnyLibraryName; std::string SharedRegexString; + bool OpenBSD; void AddLinkPrefix(const char* p); void AddLinkExtension(const char* e, LinkType type); std::string CreateExtensionRegex(std::vector<std::string> const& exts); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 8e701c4..ab77c6b 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -31,7 +31,7 @@ dependencies for each target such that no cycles are left and the build order is safe. For most target types cyclic dependencies are not allowed. However -STATIC libraries may depend on each other in a cyclic fasion. In +STATIC libraries may depend on each other in a cyclic fashion. In general the directed dependency graph forms a directed-acyclic-graph of strongly connected components. All strongly connected components should consist of only STATIC_LIBRARY targets. diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h index be33569..de497a9 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -34,17 +34,17 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "configure_file";} + virtual const char* GetName() const { return "configure_file";} /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Copy a file to another location and modify its contents."; } @@ -52,7 +52,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " configure_file(<input> <output>\n" diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index dca2fb3..48f644b 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -26,6 +26,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) const char* sourceDirectory = argv[2].c_str(); const char* projectName = 0; const char* targetName = 0; + char targetNameBuf[64]; int extraArgs = 0; // look for CMAKE_FLAGS and store them @@ -152,11 +153,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) std::string ccFile = this->BinaryDirectory + "/CMakeCache.txt"; cmSystemTools::RemoveFile(ccFile.c_str()); - // we need to create a directory and CMakeList file etc... + // we need to create a directory and CMakeLists file etc... // first create the directories sourceDirectory = this->BinaryDirectory.c_str(); - // now create a CMakeList.txt file in that directory + // now create a CMakeLists.txt file in that directory FILE *fout = fopen(outFileName.c_str(),"w"); if (!fout) { @@ -281,16 +282,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) cmakeFlags.push_back(flag); } + /* Use a random file name to avoid rapid creation and deletion + of the same executable name (some filesystems fail on that). */ + sprintf(targetNameBuf, "cmTryCompileExec%u", + cmSystemTools::RandomSeed()); + targetName = targetNameBuf; + /* Put the executable at a known location (for COPY_FILE). */ fprintf(fout, "SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"%s\")\n", this->BinaryDirectory.c_str()); /* Create the actual executable. */ - fprintf(fout, "ADD_EXECUTABLE(cmTryCompileExec \"%s\")\n",source.c_str()); - fprintf(fout, - "TARGET_LINK_LIBRARIES(cmTryCompileExec ${LINK_LIBRARIES})\n"); + fprintf(fout, "ADD_EXECUTABLE(%s \"%s\")\n", targetName, source.c_str()); + fprintf(fout, "TARGET_LINK_LIBRARIES(%s ${LINK_LIBRARIES})\n",targetName); fclose(fout); projectName = "CMAKE_TRY_COMPILE"; - targetName = "cmTryCompileExec"; // if the source is not in CMakeTmp if(source.find("CMakeTmp") == source.npos) { diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx index 953328a..de20cb7 100644 --- a/Source/cmCreateTestSourceList.cxx +++ b/Source/cmCreateTestSourceList.cxx @@ -70,7 +70,7 @@ bool cmCreateTestSourceList if (cmSystemTools::GetFilenameExtension(*i).size() < 2) { this->SetError( - "You must specify a file extenion for the test driver file."); + "You must specify a file extension for the test driver file."); return false; } std::string driver = this->Makefile->GetCurrentOutputDirectory(); diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h index c4c6ae7..806e5a9 100644 --- a/Source/cmCreateTestSourceList.h +++ b/Source/cmCreateTestSourceList.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "create_test_sourcelist";} + virtual const char* GetName() const {return "create_test_sourcelist";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Create a test driver and source list for building test programs."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " create_test_sourcelist(sourceListName driverName\n" diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h index 1fb7801..55ef521 100644 --- a/Source/cmDefinePropertyCommand.h +++ b/Source/cmDefinePropertyCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "define_property";} + virtual const char* GetName() const { return "define_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Define and document custom properties."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |\n" diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 19558fa..9296d4c 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -260,12 +260,27 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, //---------------------------------------------------------------------------- void cmDepends::SetIncludePathFromLanguage(const char* lang) { + // Look for the new per "TARGET_" variant first: + const char * includePath = 0; std::string includePathVar = "CMAKE_"; includePathVar += lang; - includePathVar += "_INCLUDE_PATH"; + includePathVar += "_TARGET_INCLUDE_PATH"; cmMakefile* mf = this->LocalGenerator->GetMakefile(); - if(const char* includePath = mf->GetDefinition(includePathVar.c_str())) + includePath = mf->GetDefinition(includePathVar.c_str()); + if(includePath) { cmSystemTools::ExpandListArgument(includePath, this->IncludePath); } + else + { + // Fallback to the old directory level variable if no per-target var: + includePathVar = "CMAKE_"; + includePathVar += lang; + includePathVar += "_INCLUDE_PATH"; + includePath = mf->GetDefinition(includePathVar.c_str()); + if(includePath) + { + cmSystemTools::ExpandListArgument(includePath, this->IncludePath); + } + } } diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 9e4726c..c1b6090 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -30,7 +30,7 @@ class cmDependsFortranSourceInfo { public: - // The name of the soruce file. + // The name of the source file. std::string Source; // Set of provided and required modules. @@ -810,8 +810,8 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile, * -GNU * -Intel * - * Eat the stream content until all recompile only realated changes - * are left bedind. + * Eat the stream content until all recompile only related changes + * are left behind. */ if (strcmp(compilerId, "GNU") == 0 ) { @@ -852,7 +852,7 @@ bool cmDependsFortran::ModulesDiffer(const char* modFile, } } - // Compare the remainng content. If no compiler id matched above, + // Compare the remaining content. If no compiler id matched above, // including the case none was given, this will compare the whole // content. if(!cmDependsFortranStreamsDiffer(finModFile, finStampFile)) @@ -1209,7 +1209,7 @@ void cmDependsFortranParser_RuleElif(cmDependsFortranParser* parser) * cmDependsFortranParser_RuleIf(..) */ - // Allways taken unless an #ifdef or #ifndef-branch has been taken + // Always taken unless an #ifdef or #ifndef-branch has been taken // already. If the second condition isn't meet already // (parser->InPPFalseBranch == 0) correct it. if(!parser->SkipToEnd.empty() && @@ -1228,7 +1228,7 @@ void cmDependsFortranParser_RuleElse(cmDependsFortranParser* parser) return; } - // parser->InPPFalseBranch is either 0 or 1. We change it denpending on + // parser->InPPFalseBranch is either 0 or 1. We change it depending on // parser->SkipToEnd.top() if(!parser->SkipToEnd.empty() && parser->SkipToEnd.top()) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 1cab2b5..897e516 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -355,7 +355,9 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "If this is set to TRUE, then the rpath information " "is not added to compiled executables. The default " "is to add rpath information if the platform supports it. " - "This allows for easy running from the build tree.",false, + "This allows for easy running from the build tree. To omit RPATH" + "in the install step, but not the build step, use " + "CMAKE_SKIP_INSTALL_RPATH instead.",false, "Variables that Provide Information"); cm->DefineProperty ("CMAKE_SOURCE_DIR", cmProperty::VARIABLE, @@ -746,6 +748,26 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables That Change Behavior"); cm->DefineProperty + ("CMAKE_FIND_PACKAGE_WARN_NO_MODULE", cmProperty::VARIABLE, + "Tell find_package to warn if called without an explicit mode.", + "If find_package is called without an explicit mode option " + "(MODULE, CONFIG or NO_MODULE) and no Find<pkg>.cmake module is " + "in CMAKE_MODULE_PATH then CMake implicitly assumes that the " + "caller intends to search for a package configuration file. " + "If no package configuration file is found then the wording " + "of the failure message must account for both the case that the " + "package is really missing and the case that the project has a " + "bug and failed to provide the intended Find module. " + "If instead the caller specifies an explicit mode option then " + "the failure message can be more specific." + "\n" + "Set CMAKE_FIND_PACKAGE_WARN_NO_MODULE to TRUE to tell find_package " + "to warn when it implicitly assumes Config mode. " + "This helps developers enforce use of an explicit mode in all calls " + "to find_package within a project.", false, + "Variables That Change Behavior"); + + cm->DefineProperty ("CMAKE_USER_MAKE_RULES_OVERRIDE", cmProperty::VARIABLE, "Specify a CMake file that overrides platform information.", "CMake loads the specified file while enabling support for each " @@ -895,7 +917,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) cm->DefineProperty ("BORLAND", cmProperty::VARIABLE, - "True of the borland compiler is being used.", + "True if the borland compiler is being used.", "This is set to true if the Borland compiler is being used.",false, "Variables That Describe the System"); @@ -1181,6 +1203,20 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_SKIP_INSTALL_RPATH", cmProperty::VARIABLE, + "Do not include RPATHs in the install tree.", + "Normally CMake uses the build tree for the RPATH when building " + "executables etc on systems that use RPATH. When the software " + "is installed the executables etc are relinked by CMake to have " + "the install RPATH. If this variable is set to true then the software " + "is always installed without RPATH, even if RPATH is enabled when " + "building. This can be useful for example to allow running tests from " + "the build directory with RPATH enabled before the installation step. " + "To omit RPATH in both the build and install steps, use " + "CMAKE_SKIP_RPATH instead.",false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_EXE_LINKER_FLAGS", cmProperty::VARIABLE, "Linker flags used to create executables.", "Flags used by the linker when creating an executable.",false, @@ -1258,6 +1294,22 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "See that target property for additional information.", false, "Variables that Control the Build"); + cm->DefineProperty + ("CMAKE_WIN32_EXECUTABLE", cmProperty::VARIABLE, + "Default value for WIN32_EXECUTABLE of targets.", + "This variable is used to initialize the " + "WIN32_EXECUTABLE property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + cm->DefineProperty + ("CMAKE_MACOSX_BUNDLE", cmProperty::VARIABLE, + "Default value for MACOSX_BUNDLE of targets.", + "This variable is used to initialize the " + "MACOSX_BUNDLE property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); // Variables defined when the a language is enabled These variables will // also be defined whenever CMake has loaded its support for compiling (LANG) diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 07683d0..904a157 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -14,7 +14,9 @@ #include "cmSystemTools.h" #include "cmVersion.h" #include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> +#include <algorithm> //---------------------------------------------------------------------------- static const char *cmDocumentationStandardOptions[][3] = @@ -220,55 +222,7 @@ cmDocumentation::cmDocumentation() :CurrentFormatter(0) { this->SetForm(TextForm); - - cmDocumentationSection *sec; - - sec = new cmDocumentationSection("Author","AUTHOR"); - sec->Append(cmDocumentationEntry - (0, - "This manual page was generated by the \"--help-man\" option.", - 0)); - this->AllSections["Author"] = sec; - - sec = new cmDocumentationSection("Copyright","COPYRIGHT"); - sec->Append(cmDocumentationCopyright); - this->AllSections["Copyright"] = sec; - - sec = new cmDocumentationSection("See Also","SEE ALSO"); - sec->Append(cmDocumentationStandardSeeAlso); - this->AllSections["Standard See Also"] = sec; - - sec = new cmDocumentationSection("Options","OPTIONS"); - sec->Append(cmDocumentationStandardOptions); - this->AllSections["Options"] = sec; - - sec = new cmDocumentationSection("Properties","PROPERTIES"); - sec->Append(cmPropertiesDocumentationDescription); - this->AllSections["Properties Description"] = sec; - - sec = new cmDocumentationSection("Generators","GENERATORS"); - sec->Append(cmDocumentationGeneratorsHeader); - this->AllSections["Generators"] = sec; - - sec = new cmDocumentationSection("Compatibility Commands", - "COMPATIBILITY COMMANDS"); - sec->Append(cmCompatCommandsDocumentationDescription); - this->AllSections["Compatibility Commands"] = sec; - - - this->PropertySections.push_back("Properties of Global Scope"); - this->PropertySections.push_back("Properties on Directories"); - this->PropertySections.push_back("Properties on Targets"); - this->PropertySections.push_back("Properties on Tests"); - this->PropertySections.push_back("Properties on Source Files"); - this->PropertySections.push_back("Properties on Cache Entries"); - - this->VariableSections.push_back("Variables that Provide Information"); - this->VariableSections.push_back("Variables That Change Behavior"); - this->VariableSections.push_back("Variables That Describe the System"); - this->VariableSections.push_back("Variables that Control the Build"); - this->VariableSections.push_back("Variables for Languages"); - + this->addCommonStandardDocSections(); this->ShowGenerators = true; } @@ -559,6 +513,8 @@ bool cmDocumentation::CreateSingleModule(const char* fname, { if(line.size() && line[0] == '#') { + /* line beginnings with ## are mark-up ignore them */ + if (line.size()>=2 && line[1] == '#') continue; // blank line if(line.size() <= 2) { @@ -710,6 +666,423 @@ cmDocumentation::Form cmDocumentation::GetFormFromFilename( } //---------------------------------------------------------------------------- +void cmDocumentation::addCommonStandardDocSections() +{ + cmDocumentationSection *sec; + + sec = new cmDocumentationSection("Author","AUTHOR"); + sec->Append(cmDocumentationEntry + (0, + "This manual page was generated by the \"--help-man\" option.", + 0)); + this->AllSections["Author"] = sec; + + sec = new cmDocumentationSection("Copyright","COPYRIGHT"); + sec->Append(cmDocumentationCopyright); + this->AllSections["Copyright"] = sec; + + sec = new cmDocumentationSection("See Also","SEE ALSO"); + sec->Append(cmDocumentationStandardSeeAlso); + this->AllSections["Standard See Also"] = sec; + + sec = new cmDocumentationSection("Options","OPTIONS"); + sec->Append(cmDocumentationStandardOptions); + this->AllSections["Options"] = sec; + + sec = new cmDocumentationSection("Compatibility Commands", + "COMPATIBILITY COMMANDS"); + sec->Append(cmCompatCommandsDocumentationDescription); + this->AllSections["Compatibility Commands"] = sec; +} + +//---------------------------------------------------------------------------- +void cmDocumentation::addCMakeStandardDocSections() +{ + cmDocumentationSection *sec; + + sec = new cmDocumentationSection("Properties","PROPERTIES"); + sec->Append(cmPropertiesDocumentationDescription); + this->AllSections["Properties Description"] = sec; + + sec = new cmDocumentationSection("Generators","GENERATORS"); + sec->Append(cmDocumentationGeneratorsHeader); + this->AllSections["Generators"] = sec; + + this->PropertySections.push_back("Properties of Global Scope"); + this->PropertySections.push_back("Properties on Directories"); + this->PropertySections.push_back("Properties on Targets"); + this->PropertySections.push_back("Properties on Tests"); + this->PropertySections.push_back("Properties on Source Files"); + this->PropertySections.push_back("Properties on Cache Entries"); + + this->VariableSections.push_back("Variables that Provide Information"); + this->VariableSections.push_back("Variables That Change Behavior"); + this->VariableSections.push_back("Variables That Describe the System"); + this->VariableSections.push_back("Variables that Control the Build"); + this->VariableSections.push_back("Variables for Languages"); + +} + +//---------------------------------------------------------------------------- +void cmDocumentation::addCTestStandardDocSections() +{ + // This is currently done for backward compatibility reason + // We may suppress some of these. + addCMakeStandardDocSections(); +} + +//---------------------------------------------------------------------------- +void cmDocumentation::addCPackStandardDocSections() +{ + cmDocumentationSection *sec; + + sec = new cmDocumentationSection("Generators","GENERATORS"); + sec->Append(cmDocumentationGeneratorsHeader); + this->AllSections["Generators"] = sec; + + this->VariableSections.push_back( + "Variables common to all CPack generators"); +} + +void cmDocumentation::addAutomaticVariableSections(const std::string& section) +{ + std::vector<std::string>::iterator it; + it = std::find(this->VariableSections.begin(), + this->VariableSections.end(), + section); + /* if the section does not exist then add it */ + if (it==this->VariableSections.end()) + { + this->VariableSections.push_back(section); + } +} +//---------------------------------------------------------------------------- +int cmDocumentation::getDocumentedModulesListInDir( + std::string path, + std::string globExpr, + documentedModulesList_t& docedModuleList) +{ + cmsys::Glob gl; + std::string findExpr; + std::vector<std::string> files; + std::string line; + documentedModuleSectionPair_t docPair; + int nbDocumentedModules = 0; + + findExpr = path + "/" + globExpr; + if (gl.FindFiles(findExpr)) + { + files = gl.GetFiles(); + for (std::vector<std::string>::iterator itf=files.begin(); + itf!=files.end();++itf) + { + std::ifstream fin((*itf).c_str()); + // file access trouble ignore it (ignore this kind of error) + if (!fin) continue; + /* read first line in order to get doc section */ + if (cmSystemTools::GetLineFromStream(fin, line)) + { + /* Doc section indicates that + * this file has structured doc in it. + */ + if (line.find("##section")!=std::string::npos) + { + // ok found one more documented module + ++nbDocumentedModules; + docPair.first = *itf; + // 10 is the size of '##section' + 1 + docPair.second = line.substr(10,std::string::npos); + docedModuleList.push_back(docPair); + } + // No else if no section is found (undocumented module) + } + // No else cannot read first line (ignore this kind of error) + line = ""; + } + } + if (nbDocumentedModules>0) + { + return 0; + } + else + { + return 1; + } +} + +//---------------------------------------------------------------------------- +static void trim(std::string& s) +{ + std::string::size_type pos = s.find_last_not_of(' '); + if(pos != std::string::npos) + { + s.erase(pos + 1); + pos = s.find_first_not_of(' '); + if(pos != std::string::npos) s.erase(0, pos); + } + else + { + s.erase(s.begin(), s.end()); + } +} + +int cmDocumentation::GetStructuredDocFromFile( + const char* fname, + std::vector<cmDocumentationEntry>& commands, + cmake* cm) +{ + typedef enum sdoce { + SDOC_NONE, SDOC_MODULE, SDOC_MACRO, SDOC_FUNCTION, SDOC_VARIABLE, + SDOC_SECTION, + SDOC_UNKNOWN} sdoc_t; + int nbDocItemFound = 0; + int docCtxIdx = 0; + std::vector<int> docContextStack(60); + docContextStack[docCtxIdx]=SDOC_NONE; + cmDocumentationEntry e; + std::ifstream fin(fname); + if(!fin) + { + return nbDocItemFound; + } + std::string section; + std::string name; + std::string full; + std::string brief; + std::string line; + bool newCtx = false; /* we've just entered ##<beginkey> context */ + bool inBrief = false; /* we are currently parsing brief desc. */ + bool inFullFirstParagraph = false; /* we are currently parsing full + desc. first paragraph */ + brief = ""; + full = ""; + bool newParagraph = true; + while ( fin && cmSystemTools::GetLineFromStream(fin, line) ) + { + if(line.size() && line[0] == '#') + { + /* handle structured doc context */ + if ((line.size()>=2) && line[1]=='#') + { + /* markup word is following '##' stopping at first space + * Some markup word like 'section' may have more characters + * following but we don't handle those here. + */ + std::string mkword = line.substr(2,line.find(' ',2)-2); + if (mkword=="macro") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_MACRO; + newCtx = true; + } + else if (mkword=="variable") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_VARIABLE; + newCtx = true; + } + else if (mkword=="function") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_FUNCTION; + newCtx = true; + } + else if (mkword=="module") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_MODULE; + newCtx = true; + } + else if (mkword=="section") + { + docCtxIdx++; + docContextStack[docCtxIdx]=SDOC_SECTION; + // 10 is the size of '##section' + 1 + section = line.substr(10,std::string::npos); + /* drop the rest of the line */ + line = ""; + newCtx = true; + } + else if (mkword.substr(0,3)=="end") + { + switch (docContextStack[docCtxIdx]) { + case SDOC_MACRO: + /* for now MACRO and FUNCTION are handled in the same way */ + case SDOC_FUNCTION: + commands.push_back(cmDocumentationEntry(name.c_str(), + brief.c_str(),full.c_str())); + break; + case SDOC_VARIABLE: + this->addAutomaticVariableSections(section); + cm->DefineProperty + (name.c_str(), cmProperty::VARIABLE, + brief.c_str(), + full.c_str(),false, + section.c_str()); + break; + case SDOC_MODULE: + /* not implemented */ + break; + case SDOC_SECTION: + /* not implemented */ + break; + default: + /* ignore other cases */ + break; + } + docCtxIdx--; + newCtx = false; + ++nbDocItemFound; + } + else + { + // error out unhandled context + return nbDocItemFound; + } + /* context is set go to next doc line */ + continue; + } + + // Now parse the text attached to the context + + // The first line after the context mark-up contains:: + // name - brief until. (brief is dot terminated or + // followed by a blank line) + if (newCtx) + { + // no brief (for easy variable definition) + if (line.find("-")==std::string::npos) + { + name = line.substr(1,std::string::npos); + trim(name); + brief = ""; + inBrief = false; + full = ""; + } + // here we have a name and brief beginning + else + { + name = line.substr(1,line.find("-")-1); + trim(name); + // we are parsing the brief context + brief = line.substr(line.find("-")+1,std::string::npos); + trim(brief); + // Brief may already be terminated on the first line + if (brief.find('.')!=std::string::npos) + { + inBrief = false; + full = brief.substr(brief.find('.')+1,std::string::npos); + trim(full); + inFullFirstParagraph = true; + brief = brief.substr(0,brief.find('.')); + } + // brief is continued on following lines + else + { + inBrief = true; + full = ""; + } + } + newCtx = false; + continue; + } + // blank line + if(line.size() <= 2) + { + if (inBrief) { + inBrief = false; + full = ""; + } else { + if (full.length()>0) + { + full += "\n"; + } + // the first paragraph of full has ended + inFullFirstParagraph = false; + } + newParagraph = true; + } + // brief is terminated by '.' + else if (inBrief && (line.find('.')!=std::string::npos)) + { + /* the brief just ended */ + inBrief = false; + std::string endBrief = line.substr(1,line.find('.')); + trim(endBrief); + trim(brief); + brief += " " + endBrief; + full += line.substr(line.find('.')+1,std::string::npos); + trim(full); + inFullFirstParagraph = true; + } + // we handle full text or multi-line brief. + else + { + std::string* text; + if (inBrief) + { + text = &brief; + } + else + { + text = &full; + } + // two spaces + if(line[1] == ' ' && line[2] == ' ') + { + // there is no "full first paragraph at all." + if (line[3] == ' ') + { + inFullFirstParagraph = false; + } + + if(!newParagraph && !inFullFirstParagraph) + { + *text += "\n"; + newParagraph = true; + } + // Skip #, and leave space for pre-formatted + if (inFullFirstParagraph) + { + std::string temp = line.c_str()+1; + trim(temp); + *text += " " + temp; + } + else + { + *text += line.c_str()+1; + *text += "\n"; + } + } + else if(line[1] == ' ') + { + if(!newParagraph) + { + *text += " "; + } + newParagraph = false; + // skip # and space + *text += line.c_str()+2; + } + else + { + if(!newParagraph) + { + *text += " "; + } + newParagraph = false; + // skip # + *text += line.c_str()+1; + } + } + } + /* next line is not the first context line */ + newCtx = false; + } + return nbDocItemFound; +} + +//---------------------------------------------------------------------------- bool cmDocumentation::CheckOptions(int argc, const char* const* argv, const char* exitOpt) { diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index 34b83b1..11bef16 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -21,6 +21,7 @@ #include "cmDocumentationFormatterText.h" #include "cmDocumentationFormatterUsage.h" #include "cmDocumentationSection.h" +#include "cmake.h" namespace cmsys { @@ -34,6 +35,21 @@ public: cmDocumentation(); ~cmDocumentation(); + + /** + * An helper type pair for [structured] documented modules. + * The comment of those module contains structure markup + * which makes it possible to retrieve the documentation + * of variables, macros and functions defined in the module. + * - first is the filename of the module + * - second is the section of the doc the module belongs too + */ + typedef std::pair<std::string,std::string> documentedModuleSectionPair_t; + /** + * A list of documented module(s). + */ + typedef std::list<documentedModuleSectionPair_t> documentedModulesList_t; + // High-level interface for standard documents: /** @@ -119,6 +135,60 @@ public: static Form GetFormFromFilename(const std::string& filename); + /** Add common (to all tools) documentation section(s) */ + void addCommonStandardDocSections(); + + /** Add the CMake standard documentation section(s) */ + void addCMakeStandardDocSections(); + + /** Add the CTest standard documentation section(s) */ + void addCTestStandardDocSections(); + + /** Add the CPack standard documentation section(s) */ + void addCPackStandardDocSections(); + + /** Add automatic variables sections */ + void addAutomaticVariableSections(const std::string& section); + + /** + * Retrieve the list of documented module located in + * path which match the globing expression globExpr. + * @param[in] path, directory where to start the search + * we will recurse into it. + * @param[in] globExpr, the globing expression used to + * match the file in path. + * @param[out] the list of obtained pairs (may be empty) + * @return 0 on success 1 on error or empty list + */ + int getDocumentedModulesListInDir( + std::string path, + std::string globExpr, + documentedModulesList_t& docModuleList); + + /** + * Get the documentation of macros, functions and variable documented + * with CMake structured documentation in a CMake script. + * (in fact it may be in any file which follow the structured doc format) + * Structured documentation begin with + * ## (double sharp) in column 1 & 2 immediately followed + * by a markup. Those ## are ignored by the legacy module + * documentation parser @see CreateSingleModule. + * Current markup are ##section, ##module, + * ##macro, ##function, ##variable and ##end. + * ##end is closing either of the previous ones. + * @param[in] fname the script file name to be parsed for documentation + * @param[in,out] commands the vector of command/macros documentation + * entry found in the script file. + * @param[in,out] the cmake object instance to which variable documentation + * will be attached (using @see cmake::DefineProperty) + * @param[in] the documentation section in which the property will be + * inserted. + * @return the number of documented items (command and variable) + * found in the file. + */ + int GetStructuredDocFromFile(const char* fname, + std::vector<cmDocumentationEntry>& commands, + cmake* cm); private: void SetForm(Form f); void SetDocName(const char* docname); diff --git a/Source/cmElseCommand.h b/Source/cmElseCommand.h index bbe31f4..5e8b790 100644 --- a/Source/cmElseCommand.h +++ b/Source/cmElseCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "else";} + virtual const char* GetName() const { return "else";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Starts the else portion of an if block."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " else(expression)\n" diff --git a/Source/cmElseIfCommand.h b/Source/cmElseIfCommand.h index cca5fb8..20cd81a 100644 --- a/Source/cmElseIfCommand.h +++ b/Source/cmElseIfCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "elseif";} + virtual const char* GetName() const { return "elseif";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Starts the elseif portion of an if block."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " elseif(expression)\n" diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h index e934119..5958e44 100644 --- a/Source/cmEnableLanguageCommand.h +++ b/Source/cmEnableLanguageCommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "enable_language";} + virtual const char* GetName() const {return "enable_language";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Enable a language (CXX/C/Fortran/etc)"; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " enable_language(languageName [OPTIONAL] )\n" diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h index 7361241..b607818 100644 --- a/Source/cmEnableTestingCommand.h +++ b/Source/cmEnableTestingCommand.h @@ -48,12 +48,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "enable_testing";} + virtual const char* GetName() const { return "enable_testing";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Enable testing for current directory and below."; } @@ -61,7 +61,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " enable_testing()\n" diff --git a/Source/cmEndForEachCommand.h b/Source/cmEndForEachCommand.h index 7ceb39d..37b2d2a 100644 --- a/Source/cmEndForEachCommand.h +++ b/Source/cmEndForEachCommand.h @@ -47,17 +47,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "endforeach";} + virtual const char* GetName() const { return "endforeach";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Ends a list of commands in a FOREACH block."; } @@ -65,7 +65,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " endforeach(expression)\n" diff --git a/Source/cmEndFunctionCommand.h b/Source/cmEndFunctionCommand.h index 2d58c9d..54ac068 100644 --- a/Source/cmEndFunctionCommand.h +++ b/Source/cmEndFunctionCommand.h @@ -47,17 +47,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "endfunction";} + virtual const char* GetName() const { return "endfunction";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Ends a list of commands in a function block."; } @@ -65,7 +65,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " endfunction(expression)\n" diff --git a/Source/cmEndIfCommand.h b/Source/cmEndIfCommand.h index f0af8c6..81d1b5f 100644 --- a/Source/cmEndIfCommand.h +++ b/Source/cmEndIfCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "endif";} + virtual const char* GetName() const { return "endif";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Ends a list of commands in an if block."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " endif(expression)\n" diff --git a/Source/cmEndMacroCommand.h b/Source/cmEndMacroCommand.h index 52b7e82..25e86b7 100644 --- a/Source/cmEndMacroCommand.h +++ b/Source/cmEndMacroCommand.h @@ -47,17 +47,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "endmacro";} + virtual const char* GetName() const { return "endmacro";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Ends a list of commands in a macro block."; } @@ -65,7 +65,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " endmacro(expression)\n" diff --git a/Source/cmEndWhileCommand.cxx b/Source/cmEndWhileCommand.cxx index bb4d40a..abb9e5e 100644 --- a/Source/cmEndWhileCommand.cxx +++ b/Source/cmEndWhileCommand.cxx @@ -12,12 +12,21 @@ #include "cmEndWhileCommand.h" bool cmEndWhileCommand -::InvokeInitialPass(std::vector<cmListFileArgument> const&, +::InvokeInitialPass(std::vector<cmListFileArgument> const& args, cmExecutionStatus &) { - this->SetError("An ENDWHILE command was found outside of a proper " - "WHILE ENDWHILE structure. Or its arguments did not " - "match the opening WHILE command."); + if (args.empty()) + { + this->SetError("An ENDWHILE command was found outside of a proper " + "WHILE ENDWHILE structure."); + } + else + { + this->SetError("An ENDWHILE command was found outside of a proper " + "WHILE ENDWHILE structure. Or its arguments did not " + "match the opening WHILE command."); + } + return false; } diff --git a/Source/cmEndWhileCommand.h b/Source/cmEndWhileCommand.h index 8e0b488..635ad5a 100644 --- a/Source/cmEndWhileCommand.h +++ b/Source/cmEndWhileCommand.h @@ -34,7 +34,7 @@ public: * Override cmCommand::InvokeInitialPass to get arguments before * expansion. */ - virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const&, + virtual bool InvokeInitialPass(std::vector<cmListFileArgument> const& args, cmExecutionStatus &status); /** @@ -47,17 +47,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "endwhile";} + virtual const char* GetName() const { return "endwhile";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Ends a list of commands in a while block."; } @@ -65,7 +65,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " endwhile(expression)\n" diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h index ef3a732..7233860 100644 --- a/Source/cmExecProgramCommand.h +++ b/Source/cmExecProgramCommand.h @@ -42,18 +42,18 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() + virtual const char* GetName() const {return "exec_program";} /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the execute_process() command instead."; @@ -62,7 +62,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "Run an executable program during the processing of the CMakeList.txt" @@ -84,7 +84,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h index 3cd8f01..0e20a4b 100644 --- a/Source/cmExecuteProcessCommand.h +++ b/Source/cmExecuteProcessCommand.h @@ -41,18 +41,18 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() + virtual const char* GetName() const {return "execute_process";} /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Execute one or more child processes."; } @@ -60,7 +60,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " execute_process(COMMAND <cmd1> [args1...]]\n" diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index cb614d4..1cc1754 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -124,6 +124,14 @@ bool cmExportCommand { targets.push_back(target); } + else if(target->GetType() == cmTarget::OBJECT_LIBRARY) + { + cmOStringStream e; + e << "given OBJECT library \"" << *currentTarget + << "\" which may not be exported."; + this->SetError(e.str().c_str()); + return false; + } else { cmOStringStream e; diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h index eb19d2e..ae67b47 100644 --- a/Source/cmExportCommand.h +++ b/Source/cmExportCommand.h @@ -45,12 +45,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "export";} + virtual const char* GetName() const { return "export";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Export targets from the build tree for use by outside projects."; @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " export(TARGETS [target1 [target2 [...]]] [NAMESPACE <namespace>]\n" diff --git a/Source/cmExportLibraryDependencies.h b/Source/cmExportLibraryDependencies.h index 32c262f..2a2ff21 100644 --- a/Source/cmExportLibraryDependencies.h +++ b/Source/cmExportLibraryDependencies.h @@ -48,12 +48,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "export_library_dependencies";} + virtual const char* GetName() const { return "export_library_dependencies";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use INSTALL(EXPORT) or EXPORT command."; } @@ -61,7 +61,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command generates an old-style library dependencies file. " @@ -83,7 +83,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index ee37352..7728d74 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -30,12 +30,6 @@ cmExprParserHelper::~cmExprParserHelper() this->CleanupParser(); } -void cmExprParserHelper::SetLineFile(long line, const char* file) -{ - this->FileLine = line; - this->FileName = file; -} - int cmExprParserHelper::ParseString(const char* str, int verb) { if ( !str) diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h index 0c36b44..690426d 100644 --- a/Source/cmExprParserHelper.h +++ b/Source/cmExprParserHelper.h @@ -46,8 +46,6 @@ public: int GetResult() { return this->Result; } - void SetLineFile(long line, const char* file); - const char* GetError() { return this->ErrorString.c_str(); } private: @@ -55,7 +53,6 @@ private: cmStdString InputBuffer; std::vector<char> OutputBuffer; int CurrentLine; - int UnionsAvailable; int Verbose; void Print(const char* place, const char* str); diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 38002ec..ccb17f0 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -392,10 +392,6 @@ void cmExtraCodeBlocksGenerator make.c_str(), makefile, compiler.c_str()); } break; - // ignore these: - case cmTarget::INSTALL_FILES: - case cmTarget::INSTALL_PROGRAMS: - case cmTarget::INSTALL_DIRECTORY: default: break; } @@ -600,16 +596,17 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, // the include directories for this target std::set<std::string> uniqIncludeDirs; - const std::vector<std::string>& incDirs = - target->GetMakefile()->GetIncludeDirectories(); - for(std::vector<std::string>::const_iterator dirIt=incDirs.begin(); - dirIt != incDirs.end(); + + std::vector<std::string> includes; + target->GetMakefile()->GetLocalGenerator()-> + GetIncludeDirectories(includes, target); + for(std::vector<std::string>::const_iterator dirIt=includes.begin(); + dirIt != includes.end(); ++dirIt) { uniqIncludeDirs.insert(*dirIt); } - std::string systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 07549e9..ebd7c7f 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -893,9 +893,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) { - const std::vector<std::string>& includeDirs - = (*it)->GetMakefile()->GetIncludeDirectories(); - this->AppendIncludeDirectories(fout, includeDirs, emmited); + cmTargets & targets = (*it)->GetMakefile()->GetTargets(); + for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + { + std::vector<std::string> includeDirs; + (*it)->GetIncludeDirectories(includeDirs, &l->second); + this->AppendIncludeDirectories(fout, includeDirs, emmited); + } } // now also the system include directories, in case we found them in // CMakeSystemSpecificInformation.cmake. This makes Eclipse find the @@ -1045,10 +1049,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } } break; - // ignore these: - case cmTarget::INSTALL_FILES: - case cmTarget::INSTALL_PROGRAMS: - case cmTarget::INSTALL_DIRECTORY: default: break; } diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h index 6ecdbcc..cb0f9d5 100644 --- a/Source/cmFLTKWrapUICommand.h +++ b/Source/cmFLTKWrapUICommand.h @@ -52,12 +52,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "fltk_wrap_ui";} + virtual const char* GetName() const { return "fltk_wrap_ui";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Create FLTK user interfaces Wrappers."; } @@ -65,7 +65,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " fltk_wrap_ui(resultingLibraryName source1\n" diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 6df5ab3..3f14fa1 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -12,6 +12,7 @@ #include "cmFileCommand.h" #include "cmake.h" #include "cmHexFileConverter.h" +#include "cmInstallType.h" #include "cmFileTimeComparison.h" #include "cmCryptoHash.h" @@ -1690,7 +1691,7 @@ struct cmFileInstaller: public cmFileCopier { cmFileInstaller(cmFileCommand* command): cmFileCopier(command, "INSTALL"), - InstallType(cmTarget::INSTALL_FILES), + InstallType(cmInstallType_FILES), Optional(false), DestDirLength(0) { @@ -1711,7 +1712,7 @@ struct cmFileInstaller: public cmFileCopier } protected: - cmTarget::TargetType InstallType; + cmInstallType InstallType; bool Optional; int DestDirLength; std::string Rename; @@ -1745,7 +1746,7 @@ protected: virtual bool Install(const char* fromFile, const char* toFile) { // Support installing from empty source to make a directory. - if(this->InstallType == cmTarget::INSTALL_DIRECTORY && !*fromFile) + if(this->InstallType == cmInstallType_DIRECTORY && !*fromFile) { return this->InstallDirectory(fromFile, toFile, MatchProperties()); } @@ -1767,14 +1768,14 @@ protected: // Add execute permissions based on the target type. switch(this->InstallType) { - case cmTarget::SHARED_LIBRARY: - case cmTarget::MODULE_LIBRARY: + case cmInstallType_SHARED_LIBRARY: + case cmInstallType_MODULE_LIBRARY: if(this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE")) { break; } - case cmTarget::EXECUTABLE: - case cmTarget::INSTALL_PROGRAMS: + case cmInstallType_EXECUTABLE: + case cmInstallType_PROGRAMS: this->FilePermissions |= mode_owner_execute; this->FilePermissions |= mode_group_execute; this->FilePermissions |= mode_world_execute; @@ -1796,8 +1797,8 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args) if(!this->Rename.empty()) { - if(this->InstallType != cmTarget::INSTALL_FILES && - this->InstallType != cmTarget::INSTALL_PROGRAMS) + if(this->InstallType != cmInstallType_FILES && + this->InstallType != cmInstallType_PROGRAMS) { this->FileCommand->SetError("INSTALL option RENAME may be used " "only with FILES or PROGRAMS."); @@ -1936,31 +1937,31 @@ bool cmFileInstaller { if ( stype == "EXECUTABLE" ) { - this->InstallType = cmTarget::EXECUTABLE; + this->InstallType = cmInstallType_EXECUTABLE; } else if ( stype == "FILE" ) { - this->InstallType = cmTarget::INSTALL_FILES; + this->InstallType = cmInstallType_FILES; } else if ( stype == "PROGRAM" ) { - this->InstallType = cmTarget::INSTALL_PROGRAMS; + this->InstallType = cmInstallType_PROGRAMS; } else if ( stype == "STATIC_LIBRARY" ) { - this->InstallType = cmTarget::STATIC_LIBRARY; + this->InstallType = cmInstallType_STATIC_LIBRARY; } else if ( stype == "SHARED_LIBRARY" ) { - this->InstallType = cmTarget::SHARED_LIBRARY; + this->InstallType = cmInstallType_SHARED_LIBRARY; } else if ( stype == "MODULE" ) { - this->InstallType = cmTarget::MODULE_LIBRARY; + this->InstallType = cmInstallType_MODULE_LIBRARY; } else if ( stype == "DIRECTORY" ) { - this->InstallType = cmTarget::INSTALL_DIRECTORY; + this->InstallType = cmInstallType_DIRECTORY; } else { diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 9e2ed0f..3b368fa 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -41,17 +41,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "file";} + virtual const char* GetName() const { return "file";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "File manipulation command."; } @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " file(WRITE filename \"message to write\"... )\n" diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 183da4a..fb8bcf7 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -108,11 +108,11 @@ void cmFindBase::GenerateDocumentation() } //---------------------------------------------------------------------------- -const char* cmFindBase::GetFullDocumentation() +const char* cmFindBase::GetFullDocumentation() const { if(this->GenericDocumentation.empty()) { - this->GenerateDocumentation(); + const_cast<cmFindBase *>(this)->GenerateDocumentation(); } return this->GenericDocumentation.c_str(); } diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index de319b1..37ab2ec 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -31,7 +31,7 @@ public: virtual bool ParseArguments(std::vector<std::string> const& args); cmTypeMacro(cmFindBase, cmFindCommon); - virtual const char* GetFullDocumentation(); + virtual const char* GetFullDocumentation() const; protected: virtual void GenerateDocumentation(); diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h index dd2e01d..7d349d3 100644 --- a/Source/cmFindFileCommand.h +++ b/Source/cmFindFileCommand.h @@ -33,12 +33,12 @@ public: { return new cmFindFileCommand; } - virtual const char* GetName() { return "find_file";} + virtual const char* GetName() const { return "find_file";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Find the full path to a file."; } diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 2fa2cca..a726849 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -354,13 +354,23 @@ void cmFindLibraryHelper::RegexFromList(std::string& out, //---------------------------------------------------------------------------- bool cmFindLibraryHelper::HasValidSuffix(std::string const& name) { - // Check if the given name ends in a valid library suffix. for(std::vector<std::string>::const_iterator si = this->Suffixes.begin(); si != this->Suffixes.end(); ++si) { - std::string const& suffix = *si; - if(name.length() > suffix.length() && - name.substr(name.size()-suffix.length()) == suffix) + std::string suffix = *si; + if(name.length() <= suffix.length()) + { + continue; + } + // Check if the given name ends in a valid library suffix. + if(name.substr(name.size()-suffix.length()) == suffix) + { + return true; + } + // Check if a valid library suffix is somewhere in the name, + // this may happen e.g. for versioned shared libraries: libfoo.so.2 + suffix += "."; + if(name.find(suffix) != name.npos) { return true; } diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h index 7930f52..b880be2 100644 --- a/Source/cmFindLibraryCommand.h +++ b/Source/cmFindLibraryCommand.h @@ -44,17 +44,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "find_library";} + virtual const char* GetName() const {return "find_library";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Find a library."; } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 7d3f09b..f17002e 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -57,7 +57,8 @@ cmFindPackageCommand::cmFindPackageCommand() this->NoUserRegistry = false; this->NoSystemRegistry = false; this->NoBuilds = false; - this->NoModule = false; + this->UseConfigFiles = true; + this->UseFindModules = true; this->DebugMode = false; this->UseLib64Paths = false; this->PolicyScope = true; @@ -72,6 +73,7 @@ cmFindPackageCommand::cmFindPackageCommand() this->VersionFoundPatch = 0; this->VersionFoundTweak = 0; this->VersionFoundCount = 0; + this->RequiredCMakeVersion = 0; } //---------------------------------------------------------------------------- @@ -86,7 +88,7 @@ void cmFindPackageCommand::GenerateDocumentation() cmSystemTools::ReplaceString(this->GenericDocumentationPathsOrder, "FIND_XXX", "find_package"); this->CommandDocumentation = - " find_package(<package> [version] [EXACT] [QUIET]\n" + " find_package(<package> [version] [EXACT] [QUIET] [MODULE]\n" " [[REQUIRED|COMPONENTS] [components...]]\n" " [NO_POLICY_SCOPE])\n" "Finds and loads settings from an external project. " @@ -94,6 +96,7 @@ void cmFindPackageCommand::GenerateDocumentation() "When the package is found package-specific information is provided " "through variables documented by the package itself. " "The QUIET option disables messages if the package cannot be found. " + "The MODULE option disables the second signature documented below. " "The REQUIRED option stops processing with an error message if the " "package cannot be found. " "A package-specific list of components may be listed after the " @@ -124,10 +127,12 @@ void cmFindPackageCommand::GenerateDocumentation() "and producing any needed messages. " "Many find-modules provide limited or no support for versioning; " "check the module documentation. " - "If no module is found the command proceeds to Config mode.\n" + "If no module is found and the MODULE option is not given the command " + "proceeds to Config mode.\n" "The complete Config mode command signature is:\n" " find_package(<package> [version] [EXACT] [QUIET]\n" - " [[REQUIRED|COMPONENTS] [components...]] [NO_MODULE]\n" + " [[REQUIRED|COMPONENTS] [components...]]\n" + " [CONFIG|NO_MODULE]\n" " [NO_POLICY_SCOPE]\n" " [NAMES name1 [name2 ...]]\n" " [CONFIGS config1 [config2 ...]]\n" @@ -145,9 +150,10 @@ void cmFindPackageCommand::GenerateDocumentation() " [CMAKE_FIND_ROOT_PATH_BOTH |\n" " ONLY_CMAKE_FIND_ROOT_PATH |\n" " NO_CMAKE_FIND_ROOT_PATH])\n" - "The NO_MODULE option may be used to skip Module mode explicitly. " - "It is also implied by use of options not specified in the reduced " - "signature. " + "The CONFIG option may be used to skip Module mode explicitly and " + "switch to Config mode. It is synonymous to using NO_MODULE. " + "Config mode is also implied by use of options not specified in the " + "reduced signature. " "\n" "Config mode attempts to locate a configuration file provided by the " "package to be found. A cache entry called <package>_DIR is created to " @@ -192,7 +198,7 @@ void cmFindPackageCommand::GenerateDocumentation() "If no such version file is available then the configuration file " "is assumed to not be compatible with any requested version. " "A basic version file containing generic version matching code can be " - "created using the macro write_basic_config_version_file(), see its " + "created using the macro write_basic_package_version_file(), see its " "documentation for more details. " "When a version file is found it is loaded to check the requested " "version number. " @@ -348,11 +354,11 @@ void cmFindPackageCommand::GenerateDocumentation() } //---------------------------------------------------------------------------- -const char* cmFindPackageCommand::GetFullDocumentation() +const char* cmFindPackageCommand::GetFullDocumentation() const { if(this->CommandDocumentation.empty()) { - this->GenerateDocumentation(); + const_cast<cmFindPackageCommand *>(this)->GenerateDocumentation(); } return this->CommandDocumentation.c_str(); } @@ -367,6 +373,15 @@ bool cmFindPackageCommand return false; } + // Lookup required version of CMake. + if(const char* rv = + this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) + { + unsigned int v[3] = {0,0,0}; + sscanf(rv, "%u.%u.%u", &v[0], &v[1], &v[2]); + this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0],v[1],v[2]); + } + // Check for debug mode. this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE"); @@ -410,6 +425,8 @@ bool cmFindPackageCommand Doing doing = DoingNone; cmsys::RegularExpression version("^[0-9.]+$"); bool haveVersion = false; + std::set<unsigned int> configArgs; + std::set<unsigned int> moduleArgs; for(unsigned int i=1; i < args.size(); ++i) { if(args[i] == "QUIET") @@ -423,9 +440,19 @@ bool cmFindPackageCommand this->Compatibility_1_6 = false; doing = DoingNone; } + else if(args[i] == "MODULE") + { + moduleArgs.insert(i); + doing = DoingNone; + } + else if(args[i] == "CONFIG") + { + configArgs.insert(i); + doing = DoingNone; + } else if(args[i] == "NO_MODULE") { - this->NoModule = true; + configArgs.insert(i); doing = DoingNone; } else if(args[i] == "REQUIRED") @@ -440,31 +467,31 @@ bool cmFindPackageCommand } else if(args[i] == "NAMES") { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingNames; } else if(args[i] == "PATHS") { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingPaths; } else if(args[i] == "HINTS") { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingHints; } else if(args[i] == "PATH_SUFFIXES") { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingPathSuffixes; } else if(args[i] == "CONFIGS") { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingConfigs; } @@ -477,27 +504,27 @@ bool cmFindPackageCommand else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY") { this->NoUserRegistry = true; - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY") { this->NoSystemRegistry = true; - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "NO_CMAKE_BUILDS_PATH") { this->NoBuilds = true; - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingNone; } else if(this->CheckCommonArgument(args[i])) { - this->NoModule = true; + configArgs.insert(i); this->Compatibility_1_6 = false; doing = DoingNone; } @@ -538,6 +565,7 @@ bool cmFindPackageCommand e << "given CONFIGS option followed by invalid file name \"" << args[i] << "\". The names given must be file names without " << "a path and with a \".cmake\" extension."; + this->SetError(e.str().c_str()); return false; } this->Configs.push_back(args[i]); @@ -556,6 +584,29 @@ bool cmFindPackageCommand } } + // Maybe choose one mode exclusively. + this->UseFindModules = configArgs.empty(); + this->UseConfigFiles = moduleArgs.empty(); + if(!this->UseFindModules && !this->UseConfigFiles) + { + cmOStringStream e; + e << "given options exclusive to Module mode:\n"; + for(std::set<unsigned int>::const_iterator si = moduleArgs.begin(); + si != moduleArgs.end(); ++si) + { + e << " " << args[*si] << "\n"; + } + e << "and options exclusive to Config mode:\n"; + for(std::set<unsigned int>::const_iterator si = configArgs.begin(); + si != configArgs.end(); ++si) + { + e << " " << args[*si] << "\n"; + } + e << "The options are incompatible."; + this->SetError(e.str().c_str()); + return false; + } + // Ignore EXACT with no version. if(this->Version.empty() && this->VersionExact) { @@ -635,7 +686,7 @@ bool cmFindPackageCommand this->SetModuleVariables(components); // See if there is a Find<package>.cmake module. - if(!this->NoModule) + if(this->UseFindModules) { bool foundModule = false; if(!this->FindModule(foundModule)) @@ -650,6 +701,37 @@ bool cmFindPackageCommand } } + if(this->UseFindModules && this->UseConfigFiles && + this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) + { + cmOStringStream aw; + if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8)) + { + aw << "find_package called without either MODULE or CONFIG option and " + "no Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. " + "Add MODULE to exclusively request Module mode and fail if " + "Find" << this->Name << ".cmake is missing. " + "Add CONFIG to exclusively request Config mode and search for a " + "package configuration file provided by " << this->Name << + " (" << this->Name << "Config.cmake or " << + cmSystemTools::LowerCase(this->Name) << "-config.cmake). "; + } + else + { + aw << "find_package called without NO_MODULE option and no " + "Find" << this->Name << ".cmake module is in CMAKE_MODULE_PATH. " + "Add NO_MODULE to exclusively request Config mode and search for a " + "package configuration file provided by " << this->Name << + " (" << this->Name << "Config.cmake or " << + cmSystemTools::LowerCase(this->Name) << "-config.cmake). " + "Otherwise make Find" << this->Name << ".cmake available in " + "CMAKE_MODULE_PATH."; + } + aw << "\n" + "(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.)"; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str()); + } + // No find module. Assume the project has a CMake config file. Use // a <package>_DIR cache variable to locate it. this->Variable = this->Name; @@ -830,41 +912,44 @@ bool cmFindPackageCommand::HandlePackageMode() // Try to load the config file if the directory is known bool fileFound = false; - if(!cmSystemTools::IsOff(def)) + if (this->UseConfigFiles) { - // Get the directory from the variable value. - std::string dir = def; - cmSystemTools::ConvertToUnixSlashes(dir); - - // Treat relative paths with respect to the current source dir. - if(!cmSystemTools::FileIsFullPath(dir.c_str())) + if(!cmSystemTools::IsOff(def)) { - dir = "/" + dir; - dir = this->Makefile->GetCurrentDirectory() + dir; + // Get the directory from the variable value. + std::string dir = def; + cmSystemTools::ConvertToUnixSlashes(dir); + + // Treat relative paths with respect to the current source dir. + if(!cmSystemTools::FileIsFullPath(dir.c_str())) + { + dir = "/" + dir; + dir = this->Makefile->GetCurrentDirectory() + dir; + } + // The file location was cached. Look for the correct file. + std::string file; + if (this->FindConfigFile(dir, file)) + { + this->FileFound = file; + fileFound = true; + } + def = this->Makefile->GetDefinition(this->Variable.c_str()); } - // The file location was cached. Look for the correct file. - std::string file; - if (this->FindConfigFile(dir, file)) + + // Search for the config file if it is not already found. + if(cmSystemTools::IsOff(def) || !fileFound) { - this->FileFound = file; - fileFound = true; + fileFound = this->FindConfig(); + def = this->Makefile->GetDefinition(this->Variable.c_str()); } - def = this->Makefile->GetDefinition(this->Variable.c_str()); - } - - // Search for the config file if it is not already found. - if(cmSystemTools::IsOff(def) || !fileFound) - { - fileFound = this->FindConfig(); - def = this->Makefile->GetDefinition(this->Variable.c_str()); - } - // Sanity check. - if(fileFound && this->FileFound.empty()) - { - this->Makefile->IssueMessage( - cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!"); - fileFound = false; + // Sanity check. + if(fileFound && this->FileFound.empty()) + { + this->Makefile->IssueMessage( + cmake::INTERNAL_ERROR, "fileFound is true but FileFound is empty!"); + fileFound = false; + } } // If the directory for the config file was found, try to read the file. @@ -892,6 +977,7 @@ bool cmFindPackageCommand::HandlePackageMode() { // The variable is not set. cmOStringStream e; + cmOStringStream aw; // If there are files in ConsideredConfigs, it means that FooConfig.cmake // have been found, but they didn't have appropriate versions. if (this->ConsideredConfigs.size() > 0) @@ -911,41 +997,80 @@ bool cmFindPackageCommand::HandlePackageMode() } else { - e << "Could not find "; - if(!this->NoModule) + std::string requestedVersionString; + if(!this->Version.empty()) { - e << "module Find" << this->Name << ".cmake or "; + requestedVersionString = " (requested version "; + requestedVersionString += this->Version; + requestedVersionString += ")"; } - e << "a configuration file for package " << this->Name << ".\n"; - if(!this->NoModule) - { - e << "Adjust CMAKE_MODULE_PATH to find Find" - << this->Name << ".cmake or set "; - } - else - { - e << "Set "; - } - e << this->Variable << " to the directory containing a CMake " - << "configuration file for " << this->Name << ". "; - if(this->Configs.size() == 1) - { - e << "The file will be called " << this->Configs[0]; - } - else + + if (this->UseConfigFiles) { - e << "The file will have one of the following names:\n"; - for(std::vector<std::string>::const_iterator ci=this->Configs.begin(); - ci != this->Configs.end(); ++ci) + if(this->UseFindModules) { - e << " " << *ci << "\n"; + e << "By not providing \"Find" << this->Name << ".cmake\" in " + "CMAKE_MODULE_PATH this project has asked CMake to find a " + "package configuration file provided by \""<<this->Name<< "\", " + "but CMake did not find one.\n"; } + + if(this->Configs.size() == 1) + { + e << "Could not find a package configuration file named \"" + << this->Configs[0] << "\" provided by package \"" + << this->Name << "\"" << requestedVersionString <<".\n"; + } + else + { + e << "Could not find a package configuration file provided by \"" + << this->Name << "\"" << requestedVersionString + << " with any of the following names:\n"; + for(std::vector<std::string>::const_iterator ci = + this->Configs.begin(); + ci != this->Configs.end(); ++ci) + { + e << " " << *ci << "\n"; + } + } + + e << "Add the installation prefix of \"" << this->Name << "\" to " + "CMAKE_PREFIX_PATH or set \"" << this->Variable << "\" to a " + "directory containing one of the above files. " + "If \"" << this->Name << "\" provides a separate development " + "package or SDK, be sure it has been installed."; + } + else // if(!this->UseFindModules && !this->UseConfigFiles) + { + e << "No \"Find" << this->Name << ".cmake\" found in " + << "CMAKE_MODULE_PATH."; + + aw<< "Find"<< this->Name <<".cmake must either be part of this " + "project itself, in this case adjust CMAKE_MODULE_PATH so that " + "it points to the correct location inside its source tree.\n" + "Or it must be installed by a package which has already been " + "found via find_package(). In this case make sure that " + "package has indeed been found and adjust CMAKE_MODULE_PATH to " + "contain the location where that package has installed " + "Find" << this->Name << ".cmake. This must be a location " + "provided by that package. This error in general means that " + "the buildsystem of this project is relying on a Find-module " + "without ensuring that it is actually available.\n"; } } this->Makefile->IssueMessage( this->Required? cmake::FATAL_ERROR : cmake::WARNING, e.str()); + if (this->Required) + { + cmSystemTools::SetFatalErrorOccured(); + } + + if (!aw.str().empty()) + { + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,aw.str()); + } } // Set a variable marking whether the package was found. @@ -1226,6 +1351,15 @@ void cmFindPackageCommand::AppendSuccessInformation() } this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(), versionInfo.c_str()); + if (this->Required) + { + std::string requiredInfoPropName = "_CMAKE_"; + requiredInfoPropName += this->Name; + requiredInfoPropName += "_TYPE"; + this->Makefile->GetCMakeInstance()->SetProperty( + requiredInfoPropName.c_str(), "REQUIRED"); + } + // Restore original state of "_FIND_" variables we set. this->RestoreFindDefinitions(); diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index e736352..edb70a6 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -44,17 +44,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "find_package";} + virtual const char* GetName() const { return "find_package";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Load settings for an external project."; } @@ -62,7 +62,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation(); + virtual const char* GetFullDocumentation() const; cmTypeMacro(cmFindPackageCommand, cmFindCommon); protected: @@ -130,10 +130,12 @@ private: unsigned int VersionFoundPatch; unsigned int VersionFoundTweak; unsigned int VersionFoundCount; + unsigned int RequiredCMakeVersion; bool Quiet; bool Required; bool Compatibility_1_6; - bool NoModule; + bool UseConfigFiles; + bool UseFindModules; bool NoUserRegistry; bool NoSystemRegistry; bool NoBuilds; diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h index bd94779..a612990 100644 --- a/Source/cmFindPathCommand.h +++ b/Source/cmFindPathCommand.h @@ -44,17 +44,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "find_path";} + virtual const char* GetName() const {return "find_path";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Find the directory containing a file."; } diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 7c56ad7..00f5419 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -175,6 +175,8 @@ std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath) // And finally to a c++ string executable = bundlePath + "/Contents/MacOS/" + std::string(buffer); + // Only release CFURLRef if it's not null + CFRelease( executableURL ); } // Any CF objects returned from functions with "create" or @@ -182,7 +184,6 @@ std::string cmFindProgramCommand::GetBundleExecutable(std::string bundlePath) CFRelease( bundlePathCFS ); CFRelease( bundleURL ); CFRelease( appBundle ); - CFRelease( executableURL ); #endif return executable; diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h index 654e834..c1b14f9 100644 --- a/Source/cmFindProgramCommand.h +++ b/Source/cmFindProgramCommand.h @@ -43,17 +43,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "find_program";} + virtual const char* GetName() const { return "find_program";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Find an executable program."; } diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h index 026fd31..ae50005 100644 --- a/Source/cmForEachCommand.h +++ b/Source/cmForEachCommand.h @@ -16,11 +16,6 @@ #include "cmFunctionBlocker.h" #include "cmListFileCache.h" -/** \class cmForEachFunctionBlocker - * \brief subclass of function blocker - * - * - */ class cmForEachFunctionBlocker : public cmFunctionBlocker { public: @@ -37,11 +32,7 @@ private: int Depth; }; -/** \class cmForEachCommand - * \brief starts an if block - * - * cmForEachCommand starts an if block - */ +/// Starts foreach() ... endforeach() block class cmForEachCommand : public cmCommand { public: @@ -63,17 +54,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "foreach";} + virtual const char* GetName() const { return "foreach";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Evaluate a group of commands for each value in a list."; } @@ -81,7 +72,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " foreach(loop_var arg1 arg2 ...)\n" diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h index c3b29e1..9ee0b5c 100644 --- a/Source/cmFunctionBlocker.h +++ b/Source/cmFunctionBlocker.h @@ -17,11 +17,6 @@ #include "cmListFileCache.h" class cmMakefile; -/** \class cmFunctionBlocker - * \brief A class that defines an interface for blocking cmake functions - * - * This is the superclass for any classes that need to block a cmake function - */ class cmFunctionBlocker { public: diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index ec4fd16..ce36145 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -23,6 +23,17 @@ public: ~cmFunctionHelperCommand() {}; /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() const + { + return false; + } + + /** * This is a virtual constructor for the command. */ virtual cmCommand* Clone() @@ -38,7 +49,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * This is called when the command is first encountered in @@ -53,12 +64,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return this->Args[0].c_str(); } + virtual const char* GetName() const { return this->Args[0].c_str(); } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { std::string docs = "Function named: "; docs += this->GetName(); @@ -68,7 +79,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return this->GetTerseDocumentation(); } diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h index a169244..43c8e29 100644 --- a/Source/cmFunctionCommand.h +++ b/Source/cmFunctionCommand.h @@ -15,11 +15,6 @@ #include "cmCommand.h" #include "cmFunctionBlocker.h" -/** \class cmFunctionFunctionBlocker - * \brief subclass of function blocker - * - * - */ class cmFunctionFunctionBlocker : public cmFunctionBlocker { public: @@ -35,11 +30,7 @@ public: int Depth; }; -/** \class cmFunctionCommand - * \brief starts an if block - * - * cmFunctionCommand starts an if block - */ +/// Starts function() ... endfunction() block class cmFunctionCommand : public cmCommand { public: @@ -61,17 +52,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "function";} + virtual const char* GetName() const { return "function";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Start recording a function for later invocation as a command."; } @@ -79,7 +70,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " function(<name> [arg1 [arg2 [arg3 ...]]])\n" diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx new file mode 100644 index 0000000..369eb5c --- /dev/null +++ b/Source/cmGeneratorTarget.cxx @@ -0,0 +1,95 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + 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 "cmGeneratorTarget.h" + +#include "cmTarget.h" +#include "cmMakefile.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" +#include "cmSourceFile.h" + +//---------------------------------------------------------------------------- +cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) +{ + this->Makefile = this->Target->GetMakefile(); + this->LocalGenerator = this->Makefile->GetLocalGenerator(); + this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); + this->ClassifySources(); +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ClassifySources() +{ + bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY; + std::vector<cmSourceFile*> badObjLib; + std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles(); + for(std::vector<cmSourceFile*>::const_iterator si = sources.begin(); + si != sources.end(); ++si) + { + cmSourceFile* sf = *si; + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(sf); + if(sf->GetCustomCommand()) + { + this->CustomCommands.push_back(sf); + } + else if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + this->OSXContent.push_back(sf); + if(isObjLib) { badObjLib.push_back(sf); } + } + else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY")) + { + this->HeaderSources.push_back(sf); + } + else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT")) + { + this->ExternalObjects.push_back(sf); + if(isObjLib) { badObjLib.push_back(sf); } + } + else if(cmSystemTools::LowerCase(sf->GetExtension()) == "def") + { + this->ModuleDefinitionFile = sf->GetFullPath(); + if(isObjLib) { badObjLib.push_back(sf); } + } + else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str())) + { + // We only get here if a source file is not an external object + // and has an extension that is listed as an ignored file type. + // No message or diagnosis should be given. + } + else if(sf->GetLanguage()) + { + this->ObjectSources.push_back(sf); + } + else + { + this->ExtraSources.push_back(sf); + if(isObjLib) { badObjLib.push_back(sf); } + } + } + + if(!badObjLib.empty()) + { + cmOStringStream e; + e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n"; + for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin(); + i != badObjLib.end(); ++i) + { + e << " " << (*i)->GetLocation().GetName() << "\n"; + } + e << "but may contain only headers and sources that compile."; + this->GlobalGenerator->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str(), + this->Target->GetBacktrace()); + } +} diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h new file mode 100644 index 0000000..b083ba1 --- /dev/null +++ b/Source/cmGeneratorTarget.h @@ -0,0 +1,58 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + 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 cmGeneratorTarget_h +#define cmGeneratorTarget_h + +#include "cmStandardIncludes.h" + +class cmCustomCommand; +class cmGlobalGenerator; +class cmLocalGenerator; +class cmMakefile; +class cmSourceFile; +class cmTarget; + +class cmGeneratorTarget +{ +public: + cmGeneratorTarget(cmTarget*); + + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + cmGlobalGenerator* GlobalGenerator; + + /** Sources classified by purpose. */ + std::vector<cmSourceFile*> CustomCommands; + std::vector<cmSourceFile*> ExtraSources; + std::vector<cmSourceFile*> HeaderSources; + std::vector<cmSourceFile*> ObjectSources; + std::vector<cmSourceFile*> ExternalObjects; + std::vector<cmSourceFile*> OSXContent; + std::string ModuleDefinitionFile; + + std::map<cmSourceFile const*, std::string> Objects; + std::set<cmSourceFile const*> ExplicitObjectName; + + /** Full path with trailing slash to the top-level directory + holding object files for this target. Includes the build + time config name placeholder if needed for the generator. */ + std::string ObjectDirectory; + +private: + void ClassifySources(); + + cmGeneratorTarget(cmGeneratorTarget const&); + void operator=(cmGeneratorTarget const&); +}; + +#endif diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h index d82be70..0a5917c 100644 --- a/Source/cmGetCMakePropertyCommand.h +++ b/Source/cmGetCMakePropertyCommand.h @@ -32,17 +32,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_cmake_property";} + virtual const char* GetName() const { return "get_cmake_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property of the CMake instance."; } @@ -50,7 +50,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_cmake_property(VAR property)\n" diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h index b7a5f71..901b90c 100644 --- a/Source/cmGetDirectoryPropertyCommand.h +++ b/Source/cmGetDirectoryPropertyCommand.h @@ -32,17 +32,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_directory_property";} + virtual const char* GetName() const { return "get_directory_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property of DIRECTORY scope."; } @@ -50,7 +50,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)\n" diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h index aff4d7e..0c8e57a 100644 --- a/Source/cmGetFilenameComponentCommand.h +++ b/Source/cmGetFilenameComponentCommand.h @@ -41,17 +41,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_filename_component";} + virtual const char* GetName() const { return "get_filename_component";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a specific component of a full filename."; } @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_filename_component(<VAR> FileName\n" diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h index d318b19..dca2627 100644 --- a/Source/cmGetPropertyCommand.h +++ b/Source/cmGetPropertyCommand.h @@ -34,17 +34,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_property";} + virtual const char* GetName() const { return "get_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property."; } @@ -52,7 +52,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_property(<variable>\n" diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h index 56469f8..6d52503 100644 --- a/Source/cmGetSourceFilePropertyCommand.h +++ b/Source/cmGetSourceFilePropertyCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_source_file_property";} + virtual const char* GetName() const { return "get_source_file_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property for a source file."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_source_file_property(VAR file property)\n" diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h index 71c75ef..b60abea 100644 --- a/Source/cmGetTargetPropertyCommand.h +++ b/Source/cmGetTargetPropertyCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_target_property";} + virtual const char* GetName() const { return "get_target_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property from a target."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_target_property(VAR target property)\n" diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h index d9f5d9b..af6bafa 100644 --- a/Source/cmGetTestPropertyCommand.h +++ b/Source/cmGetTestPropertyCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "get_test_property";} + virtual const char* GetName() const { return "get_test_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Get a property of the test."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " get_test_property(test property VAR)\n" diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 8dce053..545f9e8 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -24,6 +24,7 @@ #include "cmExportInstallFileGenerator.h" #include "cmComputeTargetDepends.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorTarget.h" #include <cmsys/Directory.hxx> @@ -74,6 +75,7 @@ cmGlobalGenerator::~cmGlobalGenerator() delete this->ExtraGenerator; } + this->ClearGeneratorTargets(); this->ClearExportSets(); } @@ -807,6 +809,7 @@ bool cmGlobalGenerator::IsDependedOn(const char* project, void cmGlobalGenerator::Configure() { this->FirstTimeProgress = 0.0f; + this->ClearGeneratorTargets(); this->ClearExportSets(); // Delete any existing cmLocalGenerators unsigned int i; @@ -947,6 +950,9 @@ void cmGlobalGenerator::Generate() this->LocalGenerators[i]->GenerateTargetManifest(); } + // Create per-target generator information. + this->CreateGeneratorTargets(); + // Compute the inter-target dependencies. if(!this->ComputeTargetDepends()) { @@ -1056,6 +1062,55 @@ void cmGlobalGenerator::CreateAutomocTargets() #endif } +//---------------------------------------------------------------------------- +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(); + for(cmTargets::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + cmTarget* t = &ti->second; + cmGeneratorTarget* gt = new cmGeneratorTarget(t); + this->GeneratorTargets[t] = gt; + this->ComputeTargetObjects(gt); + } + } +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::ClearGeneratorTargets() +{ + for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); + i != this->GeneratorTargets.end(); ++i) + { + delete i->second; + } + this->GeneratorTargets.clear(); +} + +//---------------------------------------------------------------------------- +cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const +{ + GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t); + if(ti == this->GeneratorTargets.end()) + { + this->CMakeInstance->IssueMessage( + cmake::INTERNAL_ERROR, "Missing cmGeneratorTarget instance!", + cmListFileBacktrace()); + return 0; + } + return ti->second; +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const +{ + // Implemented in generator subclasses that need this. +} void cmGlobalGenerator::CheckLocalGenerators() { @@ -1067,9 +1122,9 @@ void cmGlobalGenerator::CheckLocalGenerators() { manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); this->LocalGenerators[i]->ConfigureFinalPass(); - const cmTargets & targets = + cmTargets & targets = this->LocalGenerators[i]->GetMakefile()->GetTargets(); - for (cmTargets::const_iterator l = targets.begin(); + for (cmTargets::iterator l = targets.begin(); l != targets.end(); l++) { const cmTarget::LinkLibraryVectorType& libs = @@ -1095,27 +1150,28 @@ void cmGlobalGenerator::CheckLocalGenerators() notFoundMap[varName] = text; } } - } - const std::vector<std::string>& incs = - this->LocalGenerators[i]->GetMakefile()->GetIncludeDirectories(); + std::vector<std::string> incs; + this->LocalGenerators[i]->GetIncludeDirectories(incs, &l->second); - for( std::vector<std::string>::const_iterator incDir = incs.begin(); - incDir != incs.end(); ++incDir) - { - if(incDir->size() > 9 && - cmSystemTools::IsNOTFOUND(incDir->c_str())) + for( std::vector<std::string>::const_iterator incDir = incs.begin(); + incDir != incs.end(); ++incDir) { - std::string varName = incDir->substr(0, incDir->size()-9); - cmCacheManager::CacheIterator it = - manager->GetCacheIterator(varName.c_str()); - if(it.GetPropertyAsBool("ADVANCED")) + if(incDir->size() > 9 && + cmSystemTools::IsNOTFOUND(incDir->c_str())) { - varName += " (ADVANCED)"; + std::string varName = incDir->substr(0, incDir->size()-9); + cmCacheManager::CacheIterator it = + manager->GetCacheIterator(varName.c_str()); + if(it.GetPropertyAsBool("ADVANCED")) + { + varName += " (ADVANCED)"; + } + std::string text = notFoundMap[varName]; + text += "\n used as include directory in directory "; + text += this->LocalGenerators[i] + ->GetMakefile()->GetCurrentDirectory(); + notFoundMap[varName] = text; } - std::string text = notFoundMap[varName]; - text += "\n used as include directory in directory "; - text += this->LocalGenerators[i]->GetMakefile()->GetCurrentDirectory(); - notFoundMap[varName] = text; } } this->CMakeInstance->UpdateProgress @@ -1713,7 +1769,7 @@ void cmGlobalGenerator::SetCMakeInstance(cmake* cm) void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) { cmMakefile* mf = this->LocalGenerators[0]->GetMakefile(); - const char* cmakeCfgIntDir = this->GetCMakeCFGInitDirectory(); + const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir(); const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND"); // CPack diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 1a0e41a..80b948b 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -19,6 +19,7 @@ #include "cmTargetDepend.h" // For cmTargetDependSet #include "cmSystemTools.h" // for cmSystemTools::OutputOption class cmake; +class cmGeneratorTarget; class cmMakefile; class cmLocalGenerator; class cmExternalMakefileProjectGenerator; @@ -183,7 +184,7 @@ public: const char* GetLanguageOutputExtension(cmSourceFile const&); ///! What is the configurations directory variable called? - virtual const char* GetCMakeCFGInitDirectory() { return "."; } + virtual const char* GetCMakeCFGIntDir() const { return "."; } /** Get whether the generator should use a script for link commands. */ bool GetUseLinkScript() const { return this->UseLinkScript; } @@ -251,6 +252,9 @@ public: // via a target_link_libraries or add_dependencies TargetDependSet const& GetTargetDirectDepends(cmTarget & target); + /** Get per-target generator information. */ + cmGeneratorTarget* GetGeneratorTarget(cmTarget*) const; + const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap() const {return this->ProjectMap;} @@ -370,6 +374,13 @@ private: typedef std::map<cmTarget *, TargetDependSet> TargetDependMap; TargetDependMap TargetDependencies; + // Per-target generator information. + typedef std::map<cmTarget*, cmGeneratorTarget*> GeneratorTargetsType; + GeneratorTargetsType GeneratorTargets; + void CreateGeneratorTargets(); + void ClearGeneratorTargets(); + virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; + // Cache directory content and target files to be built. struct DirectoryContent: public std::set<cmStdString> { diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx new file mode 100644 index 0000000..7c1529b --- /dev/null +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -0,0 +1,792 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmGlobalNinjaGenerator.h" +#include "cmLocalNinjaGenerator.h" +#include "cmMakefile.h" +#include "cmGeneratedFileStream.h" +#include "cmVersion.h" + +const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja"; +const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja"; +const char* cmGlobalNinjaGenerator::INDENT = " "; + +void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count) +{ + for(int i = 0; i < count; ++i) + os << cmGlobalNinjaGenerator::INDENT; +} + +void cmGlobalNinjaGenerator::WriteDivider(std::ostream& os) +{ + os + << "# ======================================" + << "=======================================\n"; +} + +void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, + const std::string& comment) +{ + if (comment.empty()) + return; + + std::string replace = comment; + std::string::size_type lpos = 0; + std::string::size_type rpos; + while((rpos = replace.find('\n', lpos)) != std::string::npos) + { + os << "# " << replace.substr(lpos, rpos - lpos) << "\n"; + lpos = rpos + 1; + } + os << "# " << replace.substr(lpos) << "\n"; +} + +static bool IsIdentChar(char c) +{ + return + ('a' <= c && c <= 'z') || + ('+' <= c && c <= '9') || // +,-./ and numbers + ('A' <= c && c <= 'Z') || + (c == '_') || (c == '$') || (c == '\\') || + (c == ' ') || (c == ':'); +} + +std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident, + std::ostream &vars) { + if (std::find_if(ident.begin(), ident.end(), + std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) { + static unsigned VarNum = 0; + std::ostringstream names; + names << "ident" << VarNum++; + vars << names.str() << " = " << ident << "\n"; + return "$" + names.str(); + } else { + std::string result = ident; + cmSystemTools::ReplaceString(result, " ", "$ "); + cmSystemTools::ReplaceString(result, ":", "$:"); + return result; + } +} + +std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string &lit) +{ + std::string result = lit; + cmSystemTools::ReplaceString(result, "$", "$$"); + return result; +} + +std::string cmGlobalNinjaGenerator::EncodePath(const std::string &path) +{ + std::string result = path; +#ifdef _WIN32 + cmSystemTools::ReplaceString(result, "/", "\\"); +#endif + return EncodeLiteral(result); +} + +void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, + const std::string& comment, + const std::string& rule, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps, + const cmNinjaDeps& orderOnlyDeps, + const cmNinjaVars& variables) +{ + // Make sure there is a rule. + if(rule.empty()) + { + cmSystemTools::Error("No rule for WriteBuildStatement! called " + "with comment: ", + comment.c_str()); + return; + } + + // Make sure there is at least one output file. + if(outputs.empty()) + { + cmSystemTools::Error("No output files for WriteBuildStatement! called " + "with comment: ", + comment.c_str()); + return; + } + + cmGlobalNinjaGenerator::WriteComment(os, comment); + + std::ostringstream builds; + + // TODO: Better formatting for when there are multiple input/output files. + + // Write outputs files. + builds << "build"; + for(cmNinjaDeps::const_iterator i = outputs.begin(); + i != outputs.end(); + ++i) + builds << " " << EncodeIdent(EncodePath(*i), os); + builds << ":"; + + // Write the rule. + builds << " " << rule; + + // Write explicit dependencies. + for(cmNinjaDeps::const_iterator i = explicitDeps.begin(); + i != explicitDeps.end(); + ++i) + builds << " " << EncodeIdent(EncodePath(*i), os); + + // Write implicit dependencies. + if(!implicitDeps.empty()) + { + builds << " |"; + for(cmNinjaDeps::const_iterator i = implicitDeps.begin(); + i != implicitDeps.end(); + ++i) + builds << " " << EncodeIdent(EncodePath(*i), os); + } + + // Write order-only dependencies. + if(!orderOnlyDeps.empty()) + { + builds << " ||"; + for(cmNinjaDeps::const_iterator i = orderOnlyDeps.begin(); + i != orderOnlyDeps.end(); + ++i) + builds << " " << EncodeIdent(EncodePath(*i), os); + } + + builds << "\n"; + + os << builds.str(); + + // Write the variables bound to this build statement. + for(cmNinjaVars::const_iterator i = variables.begin(); + i != variables.end(); + ++i) + cmGlobalNinjaGenerator::WriteVariable(os, i->first, i->second, "", 1); +} + +void cmGlobalNinjaGenerator::WritePhonyBuild(std::ostream& os, + const std::string& comment, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps, + const cmNinjaDeps& orderOnlyDeps, + const cmNinjaVars& variables) +{ + cmGlobalNinjaGenerator::WriteBuild(os, + comment, + "phony", + outputs, + explicitDeps, + implicitDeps, + orderOnlyDeps, + variables); +} + +void cmGlobalNinjaGenerator::AddCustomCommandRule() +{ + this->AddRule("CUSTOM_COMMAND", + "$COMMAND", + "$DESC", + "Rule for running custom commands.", + /*depfile*/ "", + /*restat*/ true); +} + +void +cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, + const std::string& description, + const std::string& comment, + const cmNinjaDeps& outputs, + const cmNinjaDeps& deps, + const cmNinjaDeps& orderOnlyDeps) +{ + this->AddCustomCommandRule(); + + cmNinjaVars vars; + vars["COMMAND"] = command; + vars["DESC"] = EncodeLiteral(description); + + cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, + comment, + "CUSTOM_COMMAND", + outputs, + deps, + cmNinjaDeps(), + orderOnlyDeps, + vars); +} + +void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, + const std::string& name, + const std::string& command, + const std::string& description, + const std::string& comment, + const std::string& depfile, + bool restat, + bool generator) +{ + // Make sure the rule has a name. + if(name.empty()) + { + cmSystemTools::Error("No name given for WriteRuleStatement! called " + "with comment: ", + comment.c_str()); + return; + } + + // Make sure a command is given. + if(command.empty()) + { + cmSystemTools::Error("No command given for WriteRuleStatement! called " + "with comment: ", + comment.c_str()); + return; + } + + cmGlobalNinjaGenerator::WriteComment(os, comment); + + // Write the rule. + os << "rule " << name << "\n"; + + // Write the depfile if any. + if(!depfile.empty()) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "depfile = " << depfile << "\n"; + } + + // Write the command. + cmGlobalNinjaGenerator::Indent(os, 1); + os << "command = " << command << "\n"; + + // Write the description if any. + if(!description.empty()) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "description = " << description << "\n"; + } + + if(restat) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "restat = 1\n"; + } + + if(generator) + { + cmGlobalNinjaGenerator::Indent(os, 1); + os << "generator = 1\n"; + } +} + +void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os, + const std::string& name, + const std::string& value, + const std::string& comment, + int indent) +{ + // Make sure we have a name. + if(name.empty()) + { + cmSystemTools::Error("No name given for WriteVariable! called " + "with comment: ", + comment.c_str()); + return; + } + + // Do not add a variable if the value is empty. + std::string val = cmSystemTools::TrimWhitespace(value); + if(val.empty()) + { + return; + } + + cmGlobalNinjaGenerator::WriteComment(os, comment); + cmGlobalNinjaGenerator::Indent(os, indent); + os << name << " = " << val << "\n"; +} + +void cmGlobalNinjaGenerator::WriteInclude(std::ostream& os, + const std::string& filename, + const std::string& comment) +{ + cmGlobalNinjaGenerator::WriteComment(os, comment); + os << "include " << filename << "\n"; +} + +void cmGlobalNinjaGenerator::WriteDefault(std::ostream& os, + const cmNinjaDeps& targets, + const std::string& comment) +{ + cmGlobalNinjaGenerator::WriteComment(os, comment); + os << "default"; + for(cmNinjaDeps::const_iterator i = targets.begin(); i != targets.end(); ++i) + os << " " << *i; + os << "\n"; +} + + +cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() + : cmGlobalGenerator() + , BuildFileStream(0) + , RulesFileStream(0) + , Rules() + , AllDependencies() +{ + // // Ninja is not ported to non-Unix OS yet. + // this->ForceUnixPaths = true; + this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake"; +} + +//---------------------------------------------------------------------------- +// Virtual public methods. + +cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator() +{ + cmLocalGenerator* lg = new cmLocalNinjaGenerator; + lg->SetGlobalGenerator(this); + return lg; +} + +void cmGlobalNinjaGenerator +::GetDocumentation(cmDocumentationEntry& entry) const +{ + entry.Name = this->GetName(); + entry.Brief = "Generates build.ninja files (experimental)."; + entry.Full = + "A build.ninja file is generated into the build tree. Recent " + "versions of the ninja program can build the project through the " + "\"all\" target. An \"install\" target is also provided."; +} + +// Implemented in all cmGlobaleGenerator sub-classes. +// Used in: +// Source/cmLocalGenerator.cxx +// Source/cmake.cxx +void cmGlobalNinjaGenerator::Generate() +{ + this->OpenBuildFileStream(); + this->OpenRulesFileStream(); + + this->cmGlobalGenerator::Generate(); + + this->WriteAssumedSourceDependencies(); + this->WriteTargetAliases(*this->BuildFileStream); + this->WriteBuiltinTargets(*this->BuildFileStream); + + this->CloseRulesFileStream(); + this->CloseBuildFileStream(); +} + +// Implemented in all cmGlobaleGenerator sub-classes. +// Used in: +// Source/cmMakefile.cxx: +void cmGlobalNinjaGenerator +::EnableLanguage(std::vector<std::string>const& languages, + cmMakefile *mf, + bool optional) +{ + this->cmGlobalGenerator::EnableLanguage(languages, mf, optional); + std::string path; + for(std::vector<std::string>::const_iterator l = languages.begin(); + l != languages.end(); ++l) + { + if(*l == "NONE") + { + continue; + } + if(*l == "Fortran") + { + std::string message = "The \""; + message += this->GetName(); + message += "\" generator does not support the language \""; + message += *l; + message += "\" yet."; + cmSystemTools::Error(message.c_str()); + } + this->ResolveLanguageCompiler(*l, mf, optional); + } +} + +// Implemented by: +// cmGlobalUnixMakefileGenerator3 +// cmGlobalVisualStudio10Generator +// cmGlobalVisualStudio6Generator +// cmGlobalVisualStudio7Generator +// cmGlobalXCodeGenerator +// Called by: +// cmGlobalGenerator::Build() +std::string cmGlobalNinjaGenerator +::GenerateBuildCommand(const char* makeProgram, + const char* projectName, + const char* additionalOptions, + const char* targetName, + const char* config, + bool ignoreErrors, + bool fast) +{ + // Project name and config are not used yet. + (void)projectName; + (void)config; + // Ninja does not have -i equivalent option yet. + (void)ignoreErrors; + // We do not handle fast build yet. + (void)fast; + + std::string makeCommand = + cmSystemTools::ConvertToUnixOutputPath(makeProgram); + + if(additionalOptions) + { + makeCommand += " "; + makeCommand += additionalOptions; + } + if(targetName) + { + if(strcmp(targetName, "clean") == 0) + { + makeCommand += " -t clean"; + } + else + { + makeCommand += " "; + makeCommand += targetName; + } + } + + return makeCommand; +} + +//---------------------------------------------------------------------------- +// Non-virtual public methods. + +void cmGlobalNinjaGenerator::AddRule(const std::string& name, + const std::string& command, + const std::string& description, + const std::string& comment, + const std::string& depfile, + bool restat, + bool generator) +{ + // Do not add the same rule twice. + if (this->HasRule(name)) + return; + + this->Rules.insert(name); + cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, + name, + command, + description, + comment, + depfile, + restat, + generator); +} + +bool cmGlobalNinjaGenerator::HasRule(const std::string &name) +{ + RulesSetType::const_iterator rule = this->Rules.find(name); + return (rule != this->Rules.end()); +} + +//---------------------------------------------------------------------------- +// Private methods + +void cmGlobalNinjaGenerator::OpenBuildFileStream() +{ + // Compute Ninja's build file path. + std::string buildFilePath = + this->GetCMakeInstance()->GetHomeOutputDirectory(); + buildFilePath += "/"; + buildFilePath += cmGlobalNinjaGenerator::NINJA_BUILD_FILE; + + // Get a stream where to generate things. + if (!this->BuildFileStream) + { + this->BuildFileStream = new cmGeneratedFileStream(buildFilePath.c_str()); + if (!this->BuildFileStream) + { + // An error message is generated by the constructor if it cannot + // open the file. + return; + } + } + + // Write the do not edit header. + this->WriteDisclaimer(*this->BuildFileStream); + + // Write a comment about this file. + *this->BuildFileStream + << "# This file contains all the build statements describing the\n" + << "# compilation DAG.\n\n" + ; +} + +void cmGlobalNinjaGenerator::CloseBuildFileStream() +{ + if (this->BuildFileStream) + { + delete this->BuildFileStream; + this->BuildFileStream = 0; + } + else + { + cmSystemTools::Error("Build file stream was not open."); + } +} + +void cmGlobalNinjaGenerator::OpenRulesFileStream() +{ + // Compute Ninja's build file path. + std::string rulesFilePath = + this->GetCMakeInstance()->GetHomeOutputDirectory(); + rulesFilePath += "/"; + rulesFilePath += cmGlobalNinjaGenerator::NINJA_RULES_FILE; + + // Get a stream where to generate things. + if (!this->RulesFileStream) + { + this->RulesFileStream = new cmGeneratedFileStream(rulesFilePath.c_str()); + if (!this->RulesFileStream) + { + // An error message is generated by the constructor if it cannot + // open the file. + return; + } + } + + // Write the do not edit header. + this->WriteDisclaimer(*this->RulesFileStream); + + // Write comment about this file. + *this->RulesFileStream + << "# This file contains all the rules used to get the outputs files\n" + << "# built from the input files.\n" + << "# It is included in the main '" << NINJA_BUILD_FILE << "'.\n\n" + ; +} + +void cmGlobalNinjaGenerator::CloseRulesFileStream() +{ + if (this->RulesFileStream) + { + delete this->RulesFileStream; + this->RulesFileStream = 0; + } + else + { + cmSystemTools::Error("Rules file stream was not open."); + } +} + +void cmGlobalNinjaGenerator::WriteDisclaimer(std::ostream& os) +{ + os + << "# CMAKE generated file: DO NOT EDIT!\n" + << "# Generated by \"" << this->GetName() << "\"" + << " Generator, CMake Version " + << cmVersion::GetMajorVersion() << "." + << cmVersion::GetMinorVersion() << "\n\n"; +} + +void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target) +{ + this->AppendTargetOutputs(target, this->AllDependencies); +} + +void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() +{ + for (std::map<std::string, std::set<std::string> >::iterator + i = this->AssumedSourceDependencies.begin(); + i != this->AssumedSourceDependencies.end(); ++i) { + cmNinjaDeps deps; + std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps)); + WriteCustomCommandBuild(/*command=*/"", /*description=*/"", + "Assume dependencies for generated source file.", + cmNinjaDeps(1, i->first), deps); + } +} + +void +cmGlobalNinjaGenerator +::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs) +{ + const char* configName = + target->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE"); + cmLocalNinjaGenerator *ng = + static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]); + + switch (target->GetType()) { + case cmTarget::EXECUTABLE: + case cmTarget::SHARED_LIBRARY: + case cmTarget::STATIC_LIBRARY: + case cmTarget::MODULE_LIBRARY: + outputs.push_back(ng->ConvertToNinjaPath( + target->GetFullPath(configName).c_str())); + break; + + case cmTarget::UTILITY: { + std::string path = ng->ConvertToNinjaPath( + target->GetMakefile()->GetStartOutputDirectory()); + if (path.empty() || path == ".") + outputs.push_back(target->GetName()); + else { + path += "/"; + path += target->GetName(); + outputs.push_back(path); + } + break; + } + + case cmTarget::GLOBAL_TARGET: + // Always use the target in HOME instead of an unused duplicate in a + // subdirectory. + outputs.push_back(target->GetName()); + break; + + default: + return; + } +} + +void +cmGlobalNinjaGenerator +::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs) +{ + if (target->GetType() == cmTarget::GLOBAL_TARGET) { + // Global targets only depend on other utilities, which may not appear in + // the TargetDepends set (e.g. "all"). + std::set<cmStdString> const& utils = target->GetUtilities(); + std::copy(utils.begin(), utils.end(), std::back_inserter(outputs)); + } else { + cmTargetDependSet const& targetDeps = + this->GetTargetDirectDepends(*target); + for (cmTargetDependSet::const_iterator i = targetDeps.begin(); + i != targetDeps.end(); ++i) { + this->AppendTargetOutputs(*i, outputs); + } + } +} + +void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias, + cmTarget* target) { + cmNinjaDeps outputs; + this->AppendTargetOutputs(target, outputs); + // Mark the target's outputs as ambiguous to ensure that no other target uses + // the output as an alias. + for (cmNinjaDeps::iterator i = outputs.begin(); i != outputs.end(); ++i) + TargetAliases[*i] = 0; + + // Insert the alias into the map. If the alias was already present in the + // map and referred to another target, mark it as ambiguous. + std::pair<TargetAliasMap::iterator, bool> newAlias = + TargetAliases.insert(make_pair(alias, target)); + if (newAlias.second && newAlias.first->second != target) + newAlias.first->second = 0; +} + +void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + os << "# Target aliases.\n\n"; + + for (TargetAliasMap::iterator i = TargetAliases.begin(); + i != TargetAliases.end(); ++i) { + // Don't write ambiguous aliases. + if (!i->second) + continue; + + cmNinjaDeps deps; + this->AppendTargetOutputs(i->second, deps); + + cmGlobalNinjaGenerator::WritePhonyBuild(os, + "", + cmNinjaDeps(1, i->first), + deps); + } +} + +void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os) +{ + // Write headers. + cmGlobalNinjaGenerator::WriteDivider(os); + os << "# Built-in targets\n\n"; + + this->WriteTargetAll(os); + this->WriteTargetRebuildManifest(os); +} + +void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os) +{ + cmNinjaDeps outputs; + outputs.push_back("all"); + + cmGlobalNinjaGenerator::WritePhonyBuild(os, + "The main all target.", + outputs, + this->AllDependencies); + + cmGlobalNinjaGenerator::WriteDefault(os, + outputs, + "Make the all target the default."); +} + +void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) +{ + cmLocalGenerator *lg = this->LocalGenerators[0]; + cmMakefile* mfRoot = lg->GetMakefile(); + + std::ostringstream cmd; + cmd << lg->ConvertToOutputFormat( + mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL) + << " -H" + << lg->ConvertToOutputFormat(mfRoot->GetHomeDirectory(), + cmLocalGenerator::SHELL) + << " -B" + << lg->ConvertToOutputFormat(mfRoot->GetHomeOutputDirectory(), + cmLocalGenerator::SHELL); + WriteRule(*this->RulesFileStream, + "RERUN_CMAKE", + cmd.str(), + "Re-running CMake...", + "Rule for re-running cmake.", + /*depfile=*/ "", + /*restat=*/ false, + /*generator=*/ true); + + cmNinjaDeps implicitDeps; + for (std::vector<cmLocalGenerator *>::const_iterator i = + this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) { + const std::vector<std::string>& lf = (*i)->GetMakefile()->GetListFiles(); + implicitDeps.insert(implicitDeps.end(), lf.begin(), lf.end()); + } + std::sort(implicitDeps.begin(), implicitDeps.end()); + implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()), + implicitDeps.end()); + implicitDeps.push_back("CMakeCache.txt"); + + WriteBuild(os, + "Re-run CMake if any of its inputs changed.", + "RERUN_CMAKE", + /*outputs=*/ cmNinjaDeps(1, NINJA_BUILD_FILE), + /*explicitDeps=*/ cmNinjaDeps(), + implicitDeps, + /*orderOnlyDeps=*/ cmNinjaDeps(), + /*variables=*/ cmNinjaVars()); + + WritePhonyBuild(os, + "A missing CMake input file is not an error.", + implicitDeps, + cmNinjaDeps()); +} diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h new file mode 100644 index 0000000..39df826 --- /dev/null +++ b/Source/cmGlobalNinjaGenerator.h @@ -0,0 +1,332 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGlobalNinjaGenerator_h +# define cmGlobalNinjaGenerator_h + +# include "cmGlobalGenerator.h" +# include "cmNinjaTypes.h" + +class cmLocalGenerator; +class cmGeneratedFileStream; + +/** + * \class cmGlobalNinjaGenerator + * \brief Write a build.ninja file. + * + * The main differences between this generator and the UnixMakefile + * generator family are: + * - We don't care about VERBOSE variable or RULE_MESSAGES property since + * it is handle by Ninja's -v option. + * - We don't care about computing any progress status since Ninja manages + * it itself. + * - We don't care about generating a clean target since Ninja already have + * a clean tool. + * - We generate one build.ninja and one rules.ninja per project. + * - We try to minimize the number of generated rules: one per target and + * language. + * - We use Ninja special variable $in and $out to produce nice output. + * - We extensively use Ninja variable overloading system to minimize the + * number of generated rules. + */ +class cmGlobalNinjaGenerator : public cmGlobalGenerator +{ +public: + /// The default name of Ninja's build file. Typically: build.ninja. + static const char* NINJA_BUILD_FILE; + + /// The default name of Ninja's rules file. Typically: rules.ninja. + /// It is included in the main build.ninja file. + static const char* NINJA_RULES_FILE; + + /// The indentation string used when generating Ninja's build file. + static const char* INDENT; + + /// Write @a count times INDENT level to output stream @a os. + static void Indent(std::ostream& os, int count); + + /// Write a divider in the given output stream @a os. + static void WriteDivider(std::ostream& os); + + static std::string EncodeIdent(const std::string &ident, std::ostream &vars); + static std::string EncodeLiteral(const std::string &lit); + static std::string EncodePath(const std::string &path); + + /** + * Write the given @a comment to the output stream @a os. It + * handles new line character properly. + */ + static void WriteComment(std::ostream& os, const std::string& comment); + + /** + * Write a build statement to @a os with the @a comment using + * the @a rule the list of @a outputs files and inputs. + * It also writes the variables bound to this build statement. + * @warning no escaping of any kind is done here. + */ + static void WriteBuild(std::ostream& os, + const std::string& comment, + const std::string& rule, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps, + const cmNinjaDeps& orderOnlyDeps, + const cmNinjaVars& variables); + + /** + * Helper to write a build statement with the special 'phony' rule. + */ + static void WritePhonyBuild(std::ostream& os, + const std::string& comment, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& implicitDeps = cmNinjaDeps(), + const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(), + const cmNinjaVars& variables = cmNinjaVars()); + + void WriteCustomCommandBuild(const std::string& command, + const std::string& description, + const std::string& comment, + const cmNinjaDeps& outputs, + const cmNinjaDeps& deps = cmNinjaDeps(), + const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + + /** + * Write a rule statement named @a name to @a os with the @a comment, + * the mandatory @a command, the @a depfile and the @a description. + * It also writes the variables bound to this rule statement. + * @warning no escaping of any kind is done here. + */ + static void WriteRule(std::ostream& os, + const std::string& name, + const std::string& command, + const std::string& description, + const std::string& comment = "", + const std::string& depfile = "", + bool restat = false, + bool generator = false); + + /** + * Write a variable named @a name to @a os with value @a value and an + * optional @a comment. An @a indent level can be specified. + * @warning no escaping of any kind is done here. + */ + static void WriteVariable(std::ostream& os, + const std::string& name, + const std::string& value, + const std::string& comment = "", + int indent = 0); + + /** + * Write an include statement including @a filename with an optional + * @a comment to the @a os stream. + */ + static void WriteInclude(std::ostream& os, + const std::string& filename, + const std::string& comment = ""); + + /** + * Write a default target statement specifying @a targets as + * the default targets. + */ + static void WriteDefault(std::ostream& os, + const cmNinjaDeps& targets, + const std::string& comment = ""); + +public: + /// Default constructor. + cmGlobalNinjaGenerator(); + + /// Convenience method for creating an instance of this class. + static cmGlobalGenerator* New() { + return new cmGlobalNinjaGenerator; } + + /// Destructor. + virtual ~cmGlobalNinjaGenerator() { } + + /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator() + virtual cmLocalGenerator* CreateLocalGenerator(); + + /// Overloaded methods. @see cmGlobalGenerator::GetName(). + virtual const char* GetName() const { + return cmGlobalNinjaGenerator::GetActualName(); } + + /// @return the name of this generator. + static const char* GetActualName() { return "Ninja"; } + + /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation() + virtual void GetDocumentation(cmDocumentationEntry& entry) const; + + /// Overloaded methods. @see cmGlobalGenerator::Generate() + virtual void Generate(); + + /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage() + virtual void EnableLanguage(std::vector<std::string>const& languages, + cmMakefile* mf, + bool optional); + + /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand() + virtual std::string GenerateBuildCommand(const char* makeProgram, + const char* projectName, + const char* additionalOptions, + const char* targetName, + const char* config, + bool ignoreErrors, + bool fast); + + // Setup target names + virtual const char* GetAllTargetName() const { return "all"; } + virtual const char* GetInstallTargetName() const { return "install"; } + virtual const char* GetInstallLocalTargetName() const { + return "install/local"; + } + virtual const char* GetInstallStripTargetName() const { + return "install/strip"; + } + virtual const char* GetTestTargetName() const { return "test"; } + virtual const char* GetPackageTargetName() const { return "package"; } + virtual const char* GetPackageSourceTargetName() const { + return "package_source"; + } + virtual const char* GetEditCacheTargetName() const { + return "edit_cache"; + } + virtual const char* GetRebuildCacheTargetName() const { + return "rebuild_cache"; + } + virtual const char* GetCleanTargetName() const { return "clean"; } + +public: + cmGeneratedFileStream* GetBuildFileStream() const + { return this->BuildFileStream; } + + cmGeneratedFileStream* GetRulesFileStream() const + { return this->RulesFileStream; } + + /** + * Add a rule to the generated build system. + * Call WriteRule() behind the scene but perform some check before like: + * - Do not add twice the same rule. + */ + void AddRule(const std::string& name, + const std::string& command, + const std::string& description, + const std::string& comment = "", + const std::string& depfile = "", + bool restat = false, + bool generator = false); + + bool HasRule(const std::string& name); + + void AddCustomCommandRule(); + +protected: + + /// Overloaded methods. + /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() + virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; } + +private: + // In order to access the AddDependencyToAll() functions and co. + friend class cmLocalNinjaGenerator; + + // In order to access the SeenCustomCommand() function. + friend class cmNinjaTargetGenerator; + friend class cmNinjaNormalTargetGenerator; + friend class cmNinjaUtilityTargetGenerator; + +private: + void OpenBuildFileStream(); + void CloseBuildFileStream(); + + void OpenRulesFileStream(); + void CloseRulesFileStream(); + + /// Write the common disclaimer text at the top of each build file. + void WriteDisclaimer(std::ostream& os); + + void AddDependencyToAll(cmTarget* target); + + void WriteAssumedSourceDependencies(); + + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); + void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); + + void AddTargetAlias(const std::string& alias, cmTarget* target); + void WriteTargetAliases(std::ostream& os); + + void WriteBuiltinTargets(std::ostream& os); + void WriteTargetAll(std::ostream& os); + void WriteTargetRebuildManifest(std::ostream& os); + + /// Called when we have seen the given custom command. Returns true + /// if we has seen it before. + bool SeenCustomCommand(cmCustomCommand const *cc) { + return !this->CustomCommands.insert(cc).second; + } + + /// Called when we have seen the given custom command output. + void SeenCustomCommandOutput(const std::string &output) { + this->CustomCommandOutputs.insert(output); + // We don't need the assumed dependencies anymore, because we have + // an output. + this->AssumedSourceDependencies.erase(output); + } + + bool HasCustomCommandOutput(const std::string &output) { + return this->CustomCommandOutputs.find(output) != + this->CustomCommandOutputs.end(); + } + + void AddAssumedSourceDependencies(const std::string &source, + const cmNinjaDeps &deps) { + std::set<std::string> &ASD = this->AssumedSourceDependencies[source]; + // Because we may see the same source file multiple times (same source + // specified in multiple targets), compute the union of any assumed + // dependencies. + ASD.insert(deps.begin(), deps.end()); + } + +private: + /// The file containing the build statement. (the relation ship of the + /// compilation DAG). + cmGeneratedFileStream* BuildFileStream; + /// The file containing the rule statements. (The action attached to each + /// edge of the compilation DAG). + cmGeneratedFileStream* RulesFileStream; + + /// The type used to store the set of rules added to the generated build + /// system. + typedef std::set<std::string> RulesSetType; + + /// The set of rules added to the generated build system. + RulesSetType Rules; + + /// The set of dependencies to add to the "all" target. + cmNinjaDeps AllDependencies; + + /// The set of custom commands we have seen. + std::set<cmCustomCommand const*> CustomCommands; + + /// The set of custom command outputs we have seen. + std::set<std::string> CustomCommandOutputs; + + /// The mapping from source file to assumed dependencies. + std::map<std::string, std::set<std::string> > AssumedSourceDependencies; + + typedef std::map<std::string, cmTarget*> TargetAliasMap; + TargetAliasMap TargetAliases; + + static cmLocalGenerator* LocalGenerator; +}; + +#endif // ! cmGlobalNinjaGenerator_h diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index a23c0d8..e63de9c 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -17,6 +17,7 @@ #include "cmGeneratedFileStream.h" #include "cmSourceFile.h" #include "cmTarget.h" +#include "cmGeneratorTarget.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() { @@ -71,6 +72,38 @@ void cmGlobalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- +void +cmGlobalUnixMakefileGenerator3 +::ComputeTargetObjects(cmGeneratorTarget* gt) const +{ + cmTarget* target = gt->Target; + cmLocalUnixMakefileGenerator3* lg = + static_cast<cmLocalUnixMakefileGenerator3*>(gt->LocalGenerator); + + // Compute full path to object file directory for this target. + std::string dir_max; + dir_max += gt->Makefile->GetCurrentOutputDirectory(); + dir_max += "/"; + dir_max += gt->LocalGenerator->GetTargetDirectory(*target); + dir_max += "/"; + gt->ObjectDirectory = dir_max; + + // Compute the name of each object file. + for(std::vector<cmSourceFile*>::iterator + si = gt->ObjectSources.begin(); + si != gt->ObjectSources.end(); ++si) + { + cmSourceFile* sf = *si; + bool hasSourceExtension = true; + std::string objectName = gt->LocalGenerator + ->GetObjectFileNameWithoutTarget(*sf, dir_max, + &hasSourceExtension); + gt->Objects[sf] = objectName; + lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension); + } +} + +//---------------------------------------------------------------------------- std::string EscapeJSON(const std::string& s) { std::string result; for (std::string::size_type i = 0; i < s.size(); ++i) { @@ -378,6 +411,7 @@ void cmGlobalUnixMakefileGenerator3 (l->second.GetType() == cmTarget::STATIC_LIBRARY) || (l->second.GetType() == cmTarget::SHARED_LIBRARY) || (l->second.GetType() == cmTarget::MODULE_LIBRARY) || + (l->second.GetType() == cmTarget::OBJECT_LIBRARY) || (l->second.GetType() == cmTarget::UTILITY)) { std::string tname = lg->GetRelativeTargetDirectory(l->second); @@ -413,6 +447,7 @@ cmGlobalUnixMakefileGenerator3 (l->second.GetType() == cmTarget::STATIC_LIBRARY) || (l->second.GetType() == cmTarget::SHARED_LIBRARY) || (l->second.GetType() == cmTarget::MODULE_LIBRARY) || + (l->second.GetType() == cmTarget::OBJECT_LIBRARY) || (l->second.GetType() == cmTarget::UTILITY)) { // Add this to the list of depends rules in this directory. @@ -587,6 +622,7 @@ cmGlobalUnixMakefileGenerator3 (t->second.GetType() == cmTarget::STATIC_LIBRARY) || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY))) { // Add a rule to build the target by name. @@ -673,6 +709,7 @@ cmGlobalUnixMakefileGenerator3 || (t->second.GetType() == cmTarget::STATIC_LIBRARY) || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) + || (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY))) { std::string makefileName; @@ -982,6 +1019,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule (t->second.GetType() == cmTarget::STATIC_LIBRARY) || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || (t->second.GetType() == cmTarget::GLOBAL_TARGET) || (t->second.GetType() == cmTarget::UTILITY)) { diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 9663b55..e6dd09d 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -182,6 +182,8 @@ protected: size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg); cmGeneratedFileStream *CommandDatabase; +private: + virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; }; #endif diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 18b483d..750b89c 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -72,7 +72,7 @@ public: * Studio? */ virtual std::string GetUserMacrosRegKeyBase(); - virtual const char* GetCMakeCFGInitDirectory() + virtual const char* GetCMakeCFGIntDir() const { return "$(Configuration)";} bool Find64BitTools(cmMakefile* mf); protected: diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index 77d5370..da08a12 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -82,7 +82,7 @@ public: std::string& dir); ///! What is the configurations directory variable called? - virtual const char* GetCMakeCFGInitDirectory() { return "$(IntDir)"; } + virtual const char* GetCMakeCFGIntDir() const { return "$(IntDir)"; } protected: virtual const char* GetIDEVersion() { return "6.0"; } diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index adfb757..c92998e 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -87,7 +87,7 @@ public: std::string& dir); ///! What is the configurations directory variable called? - virtual const char* GetCMakeCFGInitDirectory() { return "$(OutDir)"; } + virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; } /** Return true if the target project file should have the option LinkLibraryDependencies and link to .sln dependencies. */ diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 449d090..7da4f86 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -12,8 +12,10 @@ #include "cmGlobalVisualStudioGenerator.h" #include "cmCallVisualStudioMacro.h" -#include "cmLocalGenerator.h" +#include "cmGeneratorTarget.h" +#include "cmLocalVisualStudioGenerator.h" #include "cmMakefile.h" +#include "cmSourceFile.h" #include "cmTarget.h" //---------------------------------------------------------------------------- @@ -98,6 +100,64 @@ void cmGlobalVisualStudioGenerator::Generate() } //---------------------------------------------------------------------------- +void +cmGlobalVisualStudioGenerator +::ComputeTargetObjects(cmGeneratorTarget* gt) const +{ + cmLocalVisualStudioGenerator* lg = + static_cast<cmLocalVisualStudioGenerator*>(gt->LocalGenerator); + std::string dir_max = lg->ComputeLongestObjectDirectory(*gt->Target); + + // Count the number of object files with each name. Note that + // windows file names are not case sensitive. + std::map<cmStdString, int> counts; + for(std::vector<cmSourceFile*>::const_iterator + si = gt->ObjectSources.begin(); + si != gt->ObjectSources.end(); ++si) + { + cmSourceFile* sf = *si; + std::string objectNameLower = cmSystemTools::LowerCase( + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())); + objectNameLower += ".obj"; + counts[objectNameLower] += 1; + } + + // For all source files producing duplicate names we need unique + // object name computation. + for(std::vector<cmSourceFile*>::const_iterator + si = gt->ObjectSources.begin(); + si != gt->ObjectSources.end(); ++si) + { + cmSourceFile* sf = *si; + std::string objectName = + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); + objectName += ".obj"; + if(counts[cmSystemTools::LowerCase(objectName)] > 1) + { + gt->ExplicitObjectName.insert(sf); + objectName = lg->GetObjectFileNameWithoutTarget(*sf, dir_max); + } + gt->Objects[sf] = objectName; + } + + std::string dir = gt->Makefile->GetCurrentOutputDirectory(); + dir += "/"; + std::string tgtDir = lg->GetTargetDirectory(*gt->Target); + if(!tgtDir.empty()) + { + dir += tgtDir; + dir += "/"; + } + const char* cd = this->GetCMakeCFGIntDir(); + if(cd && *cd) + { + dir += cd; + dir += "/"; + } + gt->ObjectDirectory = dir; +} + +//---------------------------------------------------------------------------- bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile, const std::string& regKeyBase, std::string& nextAvailableSubKeyName); @@ -315,6 +375,12 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends() } //---------------------------------------------------------------------------- +static bool VSLinkable(cmTarget* t) +{ + return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY; +} + +//---------------------------------------------------------------------------- void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) { if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end()) @@ -398,7 +464,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) di != utilDepends.end(); ++di) { cmTarget* dep = *di; - if(allowLinkable || !dep->IsLinkable() || linked.count(dep)) + if(allowLinkable || !VSLinkable(dep) || linked.count(dep)) { // Direct dependency allowed. vsTargetDepend.insert(dep->GetName()); diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index bc96f4e..b62ba22 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -97,6 +97,8 @@ protected: typedef std::map<cmTarget*, cmStdString> UtilityDependsMap; UtilityDependsMap UtilityDepends; private: + void ComputeTargetObjects(cmGeneratorTarget* gt) const; + void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked); class TargetSetMap: public std::map<cmTarget*, TargetSet> {}; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 859503f..a6a9200 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -179,8 +179,6 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const& mf->AddDefinition("CMAKE_GENERATOR_CC", "gcc"); mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++"); mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1"); - // initialize Architectures so it can be used by - // GetTargetObjectFileDirectories this->cmGlobalGenerator::EnableLanguage(lang, mf, optional); const char* osxArch = mf->GetDefinition("CMAKE_OSX_ARCHITECTURES"); @@ -1811,7 +1809,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, BuildObjectListOrString dirs(this, this->XcodeVersion >= 30); BuildObjectListOrString fdirs(this, this->XcodeVersion >= 30); std::vector<std::string> includes; - this->CurrentLocalGenerator->GetIncludeDirectories(includes); + this->CurrentLocalGenerator->GetIncludeDirectories(includes, &target); std::set<cmStdString> emitted; emitted.insert("/System/Library/Frameworks"); for(std::vector<std::string>::iterator i = includes.begin(); @@ -3285,7 +3283,7 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout, } //---------------------------------------------------------------------------- -const char* cmGlobalXCodeGenerator::GetCMakeCFGInitDirectory() +const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const { return this->XcodeVersion >= 21 ? "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : "."; @@ -3363,37 +3361,6 @@ std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p) } //---------------------------------------------------------------------------- -void cmGlobalXCodeGenerator:: -GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs) -{ - std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory(); - dir += "/"; - dir += this->CurrentMakefile->GetProjectName(); - dir += ".build/"; - dir += this->GetCMakeCFGInitDirectory(); - dir += "/"; - dir += target->GetName(); - dir += ".build/Objects-normal/"; - std::string dirsave = dir; - if(this->Architectures.size()) - { - for(std::vector<std::string>::iterator i = this->Architectures.begin(); - i != this->Architectures.end(); ++i) - { - dir += *i; - dirs.push_back(dir); - dir = dirsave; - } - } - else - { - dirs.push_back(dir); - } -} - -//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator ::AppendDirectoryForConfig(const char* prefix, diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index ed54be3..b9cf775 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -74,11 +74,8 @@ public: std::string& dir); ///! What is the configurations directory variable called? - virtual const char* GetCMakeCFGInitDirectory(); + virtual const char* GetCMakeCFGIntDir() const; - void GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs); void SetCurrentLocalGenerator(cmLocalGenerator*); /** Return true if the generated build tree may contain multiple builds. diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h index 4996bc4..83ea8a4 100644 --- a/Source/cmIfCommand.h +++ b/Source/cmIfCommand.h @@ -15,11 +15,6 @@ #include "cmCommand.h" #include "cmFunctionBlocker.h" -/** \class cmIfFunctionBlocker - * \brief subclass of function blocker - * - * - */ class cmIfFunctionBlocker : public cmFunctionBlocker { public: @@ -39,11 +34,7 @@ public: unsigned int ScopeDepth; }; -/** \class cmIfCommand - * \brief starts an if block - * - * cmIfCommand starts an if block - */ +/// Starts an if block class cmIfCommand : public cmCommand { public: @@ -72,12 +63,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "if";} + virtual const char* GetName() const { return "if";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Conditionally execute a group of commands."; } @@ -85,12 +76,12 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " if(expression)\n" diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h index d933ef3..c46c02d 100644 --- a/Source/cmIncludeCommand.h +++ b/Source/cmIncludeCommand.h @@ -43,17 +43,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "include";} + virtual const char* GetName() const {return "include";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Read CMake listfile code from the given file."; } @@ -61,7 +61,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]\n" diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h index 3b35d55..dcc116a 100644 --- a/Source/cmIncludeDirectoryCommand.h +++ b/Source/cmIncludeDirectoryCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "include_directories";} + virtual const char* GetName() const { return "include_directories";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Add include directories to the build."; } @@ -54,17 +54,25 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n" - "Add the given directories to those searched by the compiler for " - "include files. By default the directories are appended onto " - "the current list of directories. This default behavior can be " - "changed by setting CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. " - "By using BEFORE or AFTER you can select between appending and " - "prepending, independent from the default. " - "If the SYSTEM option is given the compiler will be told that the " + "Add the given directories to those the compiler uses to search " + "for include files. " + "These directories are added to the directory property " + "INCLUDE_DIRECTORIES for the current CMakeLists file. " + "They are also added to the target property INCLUDE_DIRECTORIES " + "for each target in the current CMakeLists file. " + "The target property values are the ones used by the generators." + "\n" + "By default the directories are appended onto the current list of " + "directories. " + "This default behavior can be changed by setting " + "CMAKE_INCLUDE_DIRECTORIES_BEFORE to ON. " + "By using AFTER or BEFORE explicitly, you can select between " + "appending and prepending, independent of the default. " + "If the SYSTEM option is given, the compiler will be told the " "directories are meant as system include directories on some " "platforms."; } diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h index 5269041..911a772 100644 --- a/Source/cmIncludeExternalMSProjectCommand.h +++ b/Source/cmIncludeExternalMSProjectCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "include_external_msproject";} + virtual const char* GetName() const {return "include_external_msproject";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Include an external Microsoft project file in a workspace."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " include_external_msproject(projectname location\n" diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h index 6ddbbed..7c633c0 100644 --- a/Source/cmIncludeRegularExpressionCommand.h +++ b/Source/cmIncludeRegularExpressionCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "include_regular_expression";} + virtual const char* GetName() const {return "include_regular_expression";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set the regular expression used for dependency checking."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " include_regular_expression(regex_match [regex_complain])\n" diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index dca528d..c656487 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -357,7 +357,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if(target->GetType() != cmTarget::EXECUTABLE && target->GetType() != cmTarget::STATIC_LIBRARY && target->GetType() != cmTarget::SHARED_LIBRARY && - target->GetType() != cmTarget::MODULE_LIBRARY) + target->GetType() != cmTarget::MODULE_LIBRARY && + target->GetType() != cmTarget::OBJECT_LIBRARY) { cmOStringStream e; e << "TARGETS given target \"" << (*targetIt) @@ -365,6 +366,14 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) this->SetError(e.str().c_str()); return false; } + else if(target->GetType() == cmTarget::OBJECT_LIBRARY) + { + cmOStringStream e; + e << "TARGETS given OBJECT library \"" << (*targetIt) + << "\" which may not be installed."; + this->SetError(e.str().c_str()); + return false; + } // Store the target in the list to be installed. targets.push_back(target); } diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index 377b43a..3403c38 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "install";} + virtual const char* GetName() const { return "install";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Specify rules to run at install time."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command generates installation rules for a project. " diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index ab32f94..ddf7d08 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -42,7 +42,7 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os, { // Write code to install the directories. const char* no_rename = 0; - this->AddInstallRule(os, cmTarget::INSTALL_DIRECTORY, + this->AddInstallRule(os, cmInstallType_DIRECTORY, this->Directories, this->Optional, this->FilePermissions.c_str(), diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 69e3f2c..28a19d7 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -16,7 +16,6 @@ #include "cmake.h" #include "cmInstallTargetGenerator.h" #include "cmGeneratedFileStream.h" -#include "cmTarget.h" #include "cmMakefile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" @@ -186,7 +185,7 @@ cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os, files.push_back(i->second); std::string config_test = this->CreateConfigTest(i->first.c_str()); os << indent << "IF(" << config_test << ")\n"; - this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, + this->AddInstallRule(os, cmInstallType_FILES, files, false, this->FilePermissions.c_str(), 0, 0, 0, indent.Next()); os << indent << "ENDIF(" << config_test << ")\n"; @@ -225,6 +224,6 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, // Install the main export file. std::vector<std::string> files; files.push_back(this->MainImportFile); - this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, + this->AddInstallRule(os, cmInstallType_FILES, files, false, this->FilePermissions.c_str(), 0, 0, 0, indent); } diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h index da43920..d3c7ed6 100644 --- a/Source/cmInstallFilesCommand.h +++ b/Source/cmInstallFilesCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "install_files";} + virtual const char* GetName() const { return "install_files";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the install(FILES ) command instead."; } @@ -63,7 +63,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command has been superceded by the install command. It " @@ -92,7 +92,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 28f055f..ec02bc7 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -11,8 +11,6 @@ ============================================================================*/ #include "cmInstallFilesGenerator.h" -#include "cmTarget.h" - //---------------------------------------------------------------------------- cmInstallFilesGenerator ::cmInstallFilesGenerator(std::vector<std::string> const& files, @@ -43,8 +41,8 @@ void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os, const char* no_dir_permissions = 0; this->AddInstallRule(os, (this->Programs - ? cmTarget::INSTALL_PROGRAMS - : cmTarget::INSTALL_FILES), + ? cmInstallType_PROGRAMS + : cmInstallType_FILES), this->Files, this->Optional, this->FilePermissions.c_str(), no_dir_permissions, diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index d7505dc..807168e 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -12,7 +12,6 @@ #include "cmInstallGenerator.h" #include "cmSystemTools.h" -#include "cmTarget.h" //---------------------------------------------------------------------------- cmInstallGenerator @@ -35,7 +34,7 @@ cmInstallGenerator void cmInstallGenerator ::AddInstallRule( std::ostream& os, - int type, + cmInstallType type, std::vector<std::string> const& files, bool optional /* = false */, const char* permissions_file /* = 0 */, @@ -49,14 +48,13 @@ void cmInstallGenerator std::string stype; switch(type) { - case cmTarget::INSTALL_DIRECTORY:stype = "DIRECTORY"; break; - case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break; - case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break; - case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break; - case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break; - case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break; - case cmTarget::INSTALL_FILES: - default: stype = "FILE"; break; + case cmInstallType_DIRECTORY: stype = "DIRECTORY"; break; + case cmInstallType_PROGRAMS: stype = "PROGRAM"; break; + case cmInstallType_EXECUTABLE: stype = "EXECUTABLE"; break; + case cmInstallType_STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break; + case cmInstallType_SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break; + case cmInstallType_MODULE_LIBRARY: stype = "MODULE"; break; + case cmInstallType_FILES: stype = "FILE"; break; } os << indent; std::string dest = this->GetInstallDestination(); diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index aa9a47c..c89ab8a 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -12,6 +12,7 @@ #ifndef cmInstallGenerator_h #define cmInstallGenerator_h +#include "cmInstallType.h" #include "cmScriptGenerator.h" class cmLocalGenerator; @@ -29,7 +30,7 @@ public: virtual ~cmInstallGenerator(); void AddInstallRule( - std::ostream& os, int type, + std::ostream& os, cmInstallType type, std::vector<std::string> const& files, bool optional = false, const char* permissions_file = 0, diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h index 1d0d25e..29c84a0 100644 --- a/Source/cmInstallProgramsCommand.h +++ b/Source/cmInstallProgramsCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "install_programs";} + virtual const char* GetName() const { return "install_programs";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the install(PROGRAMS ) command instead."; } @@ -64,7 +64,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command has been superceded by the install command. It " @@ -89,7 +89,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index ac1c949..5f9b658 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -82,8 +82,23 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, std::vector<std::string> filesFrom; std::vector<std::string> filesTo; std::string literal_args; - cmTarget::TargetType type = this->Target->GetType(); - if(type == cmTarget::EXECUTABLE) + cmTarget::TargetType targetType = this->Target->GetType(); + cmInstallType type = cmInstallType(); + switch(targetType) + { + case cmTarget::EXECUTABLE: type = cmInstallType_EXECUTABLE; break; + case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break; + case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break; + case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break; + case cmTarget::OBJECT_LIBRARY: + case cmTarget::UTILITY: + case cmTarget::GLOBAL_TARGET: + case cmTarget::UNKNOWN_LIBRARY: + this->Target->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, + "cmInstallTargetGenerator created with non-installable target."); + return; + } + if(targetType == cmTarget::EXECUTABLE) { // There is a bug in cmInstallCommand if this fails. assert(this->NamelinkMode == NamelinkModeNone); @@ -110,7 +125,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, } // An import library looks like a static library. - type = cmTarget::STATIC_LIBRARY; + type = cmInstallType_STATIC_LIBRARY; } else { @@ -121,7 +136,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, if(this->Target->IsAppBundleOnApple()) { // Install the whole app bundle directory. - type = cmTarget::INSTALL_DIRECTORY; + type = cmInstallType_DIRECTORY; literal_args += " USE_SOURCE_PERMISSIONS"; from1 += ".app"; @@ -173,7 +188,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, } // An import library looks like a static library. - type = cmTarget::STATIC_LIBRARY; + type = cmInstallType_STATIC_LIBRARY; } else if(this->Target->IsFrameworkOnApple()) { @@ -181,7 +196,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, assert(this->NamelinkMode == NamelinkModeNone); // Install the whole framework directory. - type = cmTarget::INSTALL_DIRECTORY; + type = cmInstallType_DIRECTORY; literal_args += " USE_SOURCE_PERMISSIONS"; std::string from1 = fromDirConfig + targetName + ".framework"; diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h index 32641f8..e05462f 100644 --- a/Source/cmInstallTargetsCommand.h +++ b/Source/cmInstallTargetsCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "install_targets";} + virtual const char* GetName() const { return "install_targets";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the install(TARGETS ) command instead."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command has been superceded by the install command. It " @@ -69,7 +69,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmInstallType.h b/Source/cmInstallType.h new file mode 100644 index 0000000..a837368 --- /dev/null +++ b/Source/cmInstallType.h @@ -0,0 +1,29 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + 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 cmInstallType_h +#define cmInstallType_h + +/** + * Enumerate types known to file(INSTALL). + */ +enum cmInstallType +{ + cmInstallType_EXECUTABLE, + cmInstallType_STATIC_LIBRARY, + cmInstallType_SHARED_LIBRARY, + cmInstallType_MODULE_LIBRARY, + cmInstallType_FILES, + cmInstallType_PROGRAMS, + cmInstallType_DIRECTORY +}; + +#endif diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h index aa13589..a7cd583 100644 --- a/Source/cmLinkDirectoriesCommand.h +++ b/Source/cmLinkDirectoriesCommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "link_directories";} + virtual const char* GetName() const { return "link_directories";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Specify directories in which the linker will look for libraries."; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " link_directories(directory1 directory2 ...)\n" diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h index e435126..2c0212c 100644 --- a/Source/cmLinkLibrariesCommand.h +++ b/Source/cmLinkLibrariesCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "link_libraries";} + virtual const char* GetName() const { return "link_libraries";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the target_link_libraries() command instead."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "Link libraries to all targets added later.\n" @@ -70,7 +70,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h index d215295..f20aa8a 100644 --- a/Source/cmListCommand.h +++ b/Source/cmListCommand.h @@ -39,17 +39,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "list";} + virtual const char* GetName() const { return "list";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "List operations."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " list(LENGTH <list> <output variable>)\n" diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h index 8ecee4a..ac50f8d 100644 --- a/Source/cmLoadCacheCommand.h +++ b/Source/cmLoadCacheCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "load_cache";} + virtual const char* GetName() const { return "load_cache";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Load in the values from another project's CMake cache."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " load_cache(pathToCacheFile READ_WITH_PREFIX\n" diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 98de411..3a0115c 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -69,12 +69,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return info.Name; } + virtual const char* GetName() const { return info.Name; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { if (this->info.GetTerseDocumentation) { @@ -123,7 +123,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { if (this->info.GetFullDocumentation) { diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h index db18428..6517019 100644 --- a/Source/cmLoadCommandCommand.h +++ b/Source/cmLoadCommandCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "load_command";} + virtual const char* GetName() const {return "load_command";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Load a command into a running CMake."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " load_command(COMMAND_NAME <loc1> [loc2 ...])\n" diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index ffbeb48..13ede5d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -556,7 +556,7 @@ void cmLocalGenerator::GenerateTargetManifest() void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, const char* lang, cmSourceFile& source, - cmTarget& ) + cmTarget& target) { std::string objectDir = cmSystemTools::GetFilenamePath(std::string(ofname)); objectDir = this->Convert(objectDir.c_str(),START_OUTPUT,SHELL); @@ -574,7 +574,11 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, std::string flags; flags += this->Makefile->GetSafeDefinition(varString.c_str()); flags += " "; - flags += this->GetIncludeFlags(lang); + { + std::vector<std::string> includes; + this->GetIncludeDirectories(includes, &target, lang); + flags += this->GetIncludeFlags(includes, lang); + } flags += this->Makefile->GetDefineFlags(); // Construct the command lines. @@ -1192,24 +1196,16 @@ cmLocalGenerator::ConvertToIncludeReference(std::string const& path) } //---------------------------------------------------------------------------- -const char* cmLocalGenerator::GetIncludeFlags(const char* lang, - bool forResponseFile) +std::string cmLocalGenerator::GetIncludeFlags( + const std::vector<std::string> &includes, + const char* lang, bool forResponseFile) { if(!lang) { return ""; } - std::string key = lang; - key += forResponseFile? "@" : ""; - if(this->LanguageToIncludeFlags.count(key)) - { - return this->LanguageToIncludeFlags[key].c_str(); - } cmOStringStream includeFlags; - std::vector<std::string> includes; - this->GetIncludeDirectories(includes, lang); - std::vector<std::string>::iterator i; std::string flagVar = "CMAKE_INCLUDE_FLAG_"; flagVar += lang; @@ -1251,6 +1247,7 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang, #ifdef __APPLE__ emitted.insert("/System/Library/Frameworks"); #endif + std::vector<std::string>::const_iterator i; for(i = includes.begin(); i != includes.end(); ++i) { if(this->Makefile->IsOn("APPLE") @@ -1311,16 +1308,12 @@ const char* cmLocalGenerator::GetIncludeFlags(const char* lang, { flags[flags.size()-1] = ' '; } - this->LanguageToIncludeFlags[key] = flags; - - // Use this temorary variable for the return value to work-around a - // bogus GCC 2.95 warning. - const char* ret = this->LanguageToIncludeFlags[key].c_str(); - return ret; + return flags; } //---------------------------------------------------------------------------- void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, + cmTarget* target, const char* lang) { // Need to decide whether to automatically include the source and @@ -1375,8 +1368,12 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, // Store the automatic include paths. if(includeBinaryDir) { - dirs.push_back(this->Makefile->GetStartOutputDirectory()); - emitted.insert(this->Makefile->GetStartOutputDirectory()); + if(emitted.find( + this->Makefile->GetStartOutputDirectory()) == emitted.end()) + { + dirs.push_back(this->Makefile->GetStartOutputDirectory()); + emitted.insert(this->Makefile->GetStartOutputDirectory()); + } } if(includeSourceDir) { @@ -1402,9 +1399,12 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } } - // Get the project-specified include directories. - std::vector<std::string>& includes = - this->Makefile->GetIncludeDirectories(); + // Get the target-specific include directories. + std::vector<std::string> includes; + if(target) + { + includes = target->GetIncludeDirectories(); + } // Support putting all the in-project include directories first if // it is requested by the project. @@ -1412,7 +1412,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, { const char* topSourceDir = this->Makefile->GetHomeDirectory(); const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory(); - for(std::vector<std::string>::iterator i = includes.begin(); + for(std::vector<std::string>::const_iterator i = includes.begin(); i != includes.end(); ++i) { // Emit this directory only if it is a subdirectory of the @@ -1431,7 +1431,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } // Construct the final ordered include directory list. - for(std::vector<std::string>::iterator i = includes.begin(); + for(std::vector<std::string>::const_iterator i = includes.begin(); i != includes.end(); ++i) { if(emitted.insert(*i).second) @@ -1503,7 +1503,7 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, linkFlags += this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG"); linkFlags += this->Convert(sf->GetFullPath().c_str(), - START_OUTPUT, SHELL); + FULL, SHELL); linkFlags += " "; } } @@ -1583,6 +1583,16 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, this->Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE"); linkFlags += " "; } + if (target.IsExecutableWithExports()) + { + std::string exportFlagVar = "CMAKE_EXE_EXPORTS_"; + exportFlagVar += linkLanguage; + exportFlagVar += "_FLAG"; + + linkFlags += + this->Makefile->GetSafeDefinition(exportFlagVar.c_str()); + linkFlags += " "; + } const char* targetLinkFlags = target.GetProperty("LINK_FLAGS"); if(targetLinkFlags) { @@ -1902,24 +1912,17 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: case cmTarget::UNKNOWN_LIBRARY: - { - // Get the location of the target's output file and depend on it. - if(const char* location = target->GetLocation(config)) - { - dep = location; - return true; - } - } - break; + dep = target->GetLocation(config); + return true; + case cmTarget::OBJECT_LIBRARY: + // An object library has no single file on which to depend. + // This was listed to get the target-level dependency. + return false; case cmTarget::UTILITY: case cmTarget::GLOBAL_TARGET: // A utility target has no file on which to depend. This was listed // only to get the target-level dependency. return false; - case cmTarget::INSTALL_FILES: - case cmTarget::INSTALL_PROGRAMS: - case cmTarget::INSTALL_DIRECTORY: - break; } } @@ -2974,17 +2977,6 @@ cmLocalGenerator::GetTargetDirectory(cmTarget const&) const return ""; } - -//---------------------------------------------------------------------------- -void -cmLocalGenerator::GetTargetObjectFileDirectories(cmTarget* , - std::vector<std::string>& - ) -{ - cmSystemTools::Error("GetTargetObjectFileDirectories" - " called on cmLocalGenerator"); -} - //---------------------------------------------------------------------------- unsigned int cmLocalGenerator::GetBackwardsCompatibility() { diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0c5b9d0..124747b 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -146,8 +146,8 @@ public: ///! Append flags to a string. virtual void AppendFlags(std::string& flags, const char* newFlags); ///! Get the include flags for the current makefile and language - const char* GetIncludeFlags(const char* lang, - bool forResponseFile = false); + std::string GetIncludeFlags(const std::vector<std::string> &includes, + const char* lang, bool forResponseFile = false); /** * Encode a list of preprocessor definitions for the compiler @@ -160,15 +160,18 @@ public: void AppendFeatureOptions(std::string& flags, const char* lang, const char* feature); - /** Translate a dependency as given in CMake code to the name to - appear in a generated build file. If the given name is that of - a utility target, returns false. If the given name is that of - a CMake target it will be transformed to the real output - location of that target for the given configuration. If the - given name is the full path to a file it will be returned. - Otherwise the name is treated as a relative path with respect to - the source directory of this generator. This should only be - used for dependencies of custom commands. */ + /** \brief Get absolute path to dependency \a name + * + * Translate a dependency as given in CMake code to the name to + * appear in a generated build file. + * - If \a name is a utility target, returns false. + * - If \a name is a CMake target, it will be transformed to the real output + * location of that target for the given configuration. + * - If \a name is the full path to a file, it will be returned. + * - Otherwise \a name is treated as a relative path with respect to + * the source directory of this generator. This should only be + * used for dependencies of custom commands. + */ bool GetRealDependency(const char* name, const char* config, std::string& dep); @@ -195,6 +198,7 @@ public: /** Get the include flags for the current makefile and language. */ void GetIncludeDirectories(std::vector<std::string>& dirs, + cmTarget* target, const char* lang = "C"); /** Compute the language used to compile the given source file. */ @@ -257,14 +261,6 @@ public: }; FortranFormat GetFortranFormat(const char* value); - /** Return the directories into which object files will be put. - * There maybe more than one for fat binary systems like OSX. - */ - virtual void - GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs); - /** * Convert the given remote path to a relative path with respect to * the given local path. The local path must be given in component @@ -392,7 +388,6 @@ protected: std::vector<std::string> StartOutputDirectoryComponents; cmLocalGenerator* Parent; std::vector<cmLocalGenerator*> Children; - std::map<cmStdString, cmStdString> LanguageToIncludeFlags; std::map<cmStdString, cmStdString> UniqueObjectNamesMap; std::string::size_type ObjectPathMax; std::set<cmStdString> ObjectMaxPathViolations; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx new file mode 100644 index 0000000..78072b5 --- /dev/null +++ b/Source/cmLocalNinjaGenerator.cxx @@ -0,0 +1,424 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmLocalNinjaGenerator.h" +#include "cmCustomCommandGenerator.h" +#include "cmMakefile.h" +#include "cmGlobalNinjaGenerator.h" +#include "cmNinjaTargetGenerator.h" +#include "cmGeneratedFileStream.h" +#include "cmSourceFile.h" +#include "cmComputeLinkInformation.h" +#include "cmake.h" + +#include <assert.h> + +cmLocalNinjaGenerator::cmLocalNinjaGenerator() + : cmLocalGenerator() + , ConfigName("") + , HomeRelativeOutputPath("") +{ + this->IsMakefileGenerator = true; +#ifdef _WIN32 + this->WindowsShell = true; +#endif + this->TargetImplib = "$TARGET_IMPLIB"; +} + +//---------------------------------------------------------------------------- +// Virtual public methods. + +cmLocalNinjaGenerator::~cmLocalNinjaGenerator() +{ +} + +void cmLocalNinjaGenerator::Generate() +{ + this->SetConfigName(); + + this->WriteProcessedMakefile(this->GetBuildFileStream()); + this->WriteProcessedMakefile(this->GetRulesFileStream()); + + this->WriteBuildFileTop(); + + cmTargets& targets = this->GetMakefile()->GetTargets(); + for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) + { + cmNinjaTargetGenerator* tg = cmNinjaTargetGenerator::New(&t->second); + if(tg) + { + tg->Generate(); + // Add the target to "all" if required. + if (!this->GetGlobalNinjaGenerator()->IsExcluded( + this->GetGlobalNinjaGenerator()->LocalGenerators[0], + t->second)) + this->GetGlobalNinjaGenerator()->AddDependencyToAll(&t->second); + delete tg; + } + } + + this->WriteCustomCommandBuildStatements(); +} + +// Implemented in: +// cmLocalUnixMakefileGenerator3. +// Used in: +// Source/cmMakefile.cxx +// Source/cmGlobalGenerator.cxx +void cmLocalNinjaGenerator::Configure() +{ + // Compute the path to use when referencing the current output + // directory from the top output directory. + this->HomeRelativeOutputPath = + this->Convert(this->Makefile->GetStartOutputDirectory(), HOME_OUTPUT); + if(this->HomeRelativeOutputPath == ".") + { + this->HomeRelativeOutputPath = ""; + } + this->cmLocalGenerator::Configure(); + +} + +// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it. +std::string cmLocalNinjaGenerator +::GetTargetDirectory(cmTarget const& target) const +{ + std::string dir = cmake::GetCMakeFilesDirectoryPostSlash(); + dir += target.GetName(); +#if defined(__VMS) + dir += "_dir"; +#else + dir += ".dir"; +#endif + return dir; +} + +//---------------------------------------------------------------------------- +// Non-virtual public methods. + +const cmGlobalNinjaGenerator* +cmLocalNinjaGenerator::GetGlobalNinjaGenerator() const +{ + return + static_cast<const cmGlobalNinjaGenerator*>(this->GetGlobalGenerator()); +} + +cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator() +{ + return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator()); +} + +// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it. +std::string +cmLocalNinjaGenerator +::GetObjectFileName(const cmTarget& target, + const cmSourceFile& source) +{ + // Make sure we never hit this old case. + if(source.GetProperty("MACOSX_PACKAGE_LOCATION")) + { + std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: "; + msg += source.GetFullPath(); + this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, + msg.c_str()); + } + + // Start with the target directory. + std::string obj = this->GetTargetDirectory(target); + obj += "/"; + + // Get the object file name without the target directory. + std::string dir_max; + dir_max += this->Makefile->GetCurrentOutputDirectory(); + dir_max += "/"; + dir_max += obj; + std::string objectName = + this->GetObjectFileNameWithoutTarget(source, dir_max, 0); + // Append the object name to the target directory. + obj += objectName; + return obj; +} + +//---------------------------------------------------------------------------- +// Virtual protected methods. + +std::string +cmLocalNinjaGenerator::ConvertToLinkReference(std::string const& lib) +{ + return this->Convert(lib.c_str(), HOME_OUTPUT, SHELL); +} + +std::string +cmLocalNinjaGenerator::ConvertToIncludeReference(std::string const& path) +{ + return this->Convert(path.c_str(), HOME_OUTPUT, SHELL); +} + +//---------------------------------------------------------------------------- +// Private methods. + +cmGeneratedFileStream& cmLocalNinjaGenerator::GetBuildFileStream() const +{ + return *this->GetGlobalNinjaGenerator()->GetBuildFileStream(); +} + +cmGeneratedFileStream& cmLocalNinjaGenerator::GetRulesFileStream() const +{ + return *this->GetGlobalNinjaGenerator()->GetRulesFileStream(); +} + +const cmake* cmLocalNinjaGenerator::GetCMakeInstance() const +{ + return this->GetGlobalGenerator()->GetCMakeInstance(); +} + +cmake* cmLocalNinjaGenerator::GetCMakeInstance() +{ + return this->GetGlobalGenerator()->GetCMakeInstance(); +} + +bool cmLocalNinjaGenerator::isRootMakefile() const +{ + return (strcmp(this->Makefile->GetCurrentDirectory(), + this->GetCMakeInstance()->GetHomeDirectory()) == 0); +} + +void cmLocalNinjaGenerator::WriteBuildFileTop() +{ + // We do that only once for the top CMakeLists.txt file. + if(!this->isRootMakefile()) + return; + + // For the build file. + this->WriteProjectHeader(this->GetBuildFileStream()); + this->WriteNinjaFilesInclusion(this->GetBuildFileStream()); + + // For the rule file. + this->WriteProjectHeader(this->GetRulesFileStream()); +} + +void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + os + << "# Project: " << this->GetMakefile()->GetProjectName() << std::endl + << "# Configuration: " << this->ConfigName << std::endl + ; + cmGlobalNinjaGenerator::WriteDivider(os); +} + +void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + os + << "# Include auxiliary files.\n" + << "\n" + ; + cmGlobalNinjaGenerator::WriteInclude(os, + cmGlobalNinjaGenerator::NINJA_RULES_FILE, + "Include rules file."); + os << "\n"; +} + +void cmLocalNinjaGenerator::SetConfigName() +{ + // Store the configuration name that will be generated. + if(const char* config = + this->GetMakefile()->GetDefinition("CMAKE_BUILD_TYPE")) + { + // Use the build type given by the user. + this->ConfigName = config; + } + else + { + // No configuration type given. + this->ConfigName = ""; + } +} + +void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os) +{ + cmGlobalNinjaGenerator::WriteDivider(os); + os + << "# Write statements declared in CMakeLists.txt:" << std::endl + << "# " << this->Makefile->GetCurrentListFile() << std::endl + ; + if(this->isRootMakefile()) + os << "# Which is the root file." << std::endl; + cmGlobalNinjaGenerator::WriteDivider(os); + os << std::endl; +} + +std::string cmLocalNinjaGenerator::ConvertToNinjaPath(const char *path) +{ + std::string convPath = this->Convert(path, cmLocalGenerator::HOME_OUTPUT); +#ifdef _WIN32 + cmSystemTools::ReplaceString(convPath, "/", "\\"); +#endif + return convPath; +} + +void +cmLocalNinjaGenerator +::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs) +{ + this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs); +} + +void +cmLocalNinjaGenerator +::AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs) +{ + this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs); +} + +void cmLocalNinjaGenerator::AppendCustomCommandDeps(const cmCustomCommand *cc, + cmNinjaDeps &ninjaDeps) +{ + const std::vector<std::string> &deps = cc->GetDepends(); + for (std::vector<std::string>::const_iterator i = deps.begin(); + i != deps.end(); ++i) { + std::string dep; + if (this->GetRealDependency(i->c_str(), this->GetConfigName(), dep)) + ninjaDeps.push_back(ConvertToNinjaPath(dep.c_str())); + } +} + +std::string cmLocalNinjaGenerator::BuildCommandLine( + const std::vector<std::string> &cmdLines) +{ + // If we have no commands but we need to build a command anyway, use ":". + // This happens when building a POST_BUILD value for link targets that + // don't use POST_BUILD. + if (cmdLines.empty()) +#ifdef _WIN32 + return "cd."; +#else + return ":"; +#endif + + // TODO: This will work only on Unix platforms. I don't + // want to use a link.txt file because I will lose the benefit of the + // $in variables. A discussion about dealing with multiple commands in + // a rule is started here: + // groups.google.com/group/ninja-build/browse_thread/thread/d515f23a78986008 + std::ostringstream cmd; + for (std::vector<std::string>::const_iterator li = cmdLines.begin(); + li != cmdLines.end(); ++li) { + if (li != cmdLines.begin()) + cmd << " && "; + cmd << *li; + } + return cmd.str(); +} + +void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc, + std::vector<std::string> &cmdLines) +{ + cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile); + if (ccg.GetNumberOfCommands() > 0) { + const char* wd = cc->GetWorkingDirectory(); + if (!wd) + wd = this->GetMakefile()->GetStartOutputDirectory(); + + std::ostringstream cdCmd; + cdCmd << "cd " << this->ConvertToOutputFormat(wd, SHELL); + cmdLines.push_back(cdCmd.str()); + } + for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) { + cmdLines.push_back(this->ConvertToOutputFormat(ccg.GetCommand(i).c_str(), + SHELL)); + std::string& cmd = cmdLines.back(); + ccg.AppendArguments(i, cmd); + } +} + +void +cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( + cmCustomCommand const *cc, const cmNinjaDeps& orderOnlyDeps) +{ + if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc)) + return; + + const std::vector<std::string> &outputs = cc->GetOutputs(); + cmNinjaDeps ninjaOutputs(outputs.size()), ninjaDeps; + + std::transform(outputs.begin(), outputs.end(), + ninjaOutputs.begin(), MapToNinjaPath()); + this->AppendCustomCommandDeps(cc, ninjaDeps); + + for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end(); + ++i) + this->GetGlobalNinjaGenerator()->SeenCustomCommandOutput(*i); + + std::vector<std::string> cmdLines; + this->AppendCustomCommandLines(cc, cmdLines); + + if (cmdLines.empty()) { + cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), + "Phony custom command for " + + ninjaOutputs[0], + ninjaOutputs, + ninjaDeps, + cmNinjaDeps(), + orderOnlyDeps, + cmNinjaVars()); + } else { + this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild( + this->BuildCommandLine(cmdLines), + this->ConstructComment(*cc), + "Custom command for " + ninjaOutputs[0], + ninjaOutputs, + ninjaDeps, + orderOnlyDeps); + } +} + +void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc, + cmTarget* target) +{ + this->CustomCommandTargets[cc].insert(target); +} + +void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements() +{ + for (CustomCommandTargetMap::iterator i = this->CustomCommandTargets.begin(); + i != this->CustomCommandTargets.end(); ++i) { + // A custom command may appear on multiple targets. However, some build + // systems exist where the target dependencies on some of the targets are + // overspecified, leading to a dependency cycle. If we assume all target + // dependencies are a superset of the true target dependencies for this + // custom command, we can take the set intersection of all target + // dependencies to obtain a correct dependency list. + // + // FIXME: This won't work in certain obscure scenarios involving indirect + // dependencies. + std::set<cmTarget*>::iterator j = i->second.begin(); + assert(j != i->second.end()); + std::vector<std::string> ccTargetDeps; + this->AppendTargetDepends(*j, ccTargetDeps); + std::sort(ccTargetDeps.begin(), ccTargetDeps.end()); + ++j; + + for (; j != i->second.end(); ++j) { + std::vector<std::string> jDeps, depsIntersection; + this->AppendTargetDepends(*j, jDeps); + std::sort(jDeps.begin(), jDeps.end()); + std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(), + jDeps.begin(), jDeps.end(), + std::back_inserter(depsIntersection)); + ccTargetDeps = depsIntersection; + } + + this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps); + } +} diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h new file mode 100644 index 0000000..28b431d --- /dev/null +++ b/Source/cmLocalNinjaGenerator.h @@ -0,0 +1,136 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmLocalNinjaGenerator_h +# define cmLocalNinjaGenerator_h + +# include "cmLocalGenerator.h" +# include "cmNinjaTypes.h" + +class cmGlobalNinjaGenerator; +class cmGeneratedFileStream; +class cmake; + +/** + * \class cmLocalNinjaGenerator + * \brief Write a local build.ninja file. + * + * cmLocalNinjaGenerator produces a local build.ninja file from its + * member Makefile. + */ +class cmLocalNinjaGenerator : public cmLocalGenerator +{ +public: + /// Default constructor. + cmLocalNinjaGenerator(); + + /// Destructor. + virtual ~cmLocalNinjaGenerator(); + + /// Overloaded methods. @see cmLocalGenerator::Generate() + virtual void Generate(); + + /// Overloaded methods. @see cmLocalGenerator::Configure() + virtual void Configure(); + + /// Overloaded methods. @see cmLocalGenerator::GetTargetDirectory() + virtual std::string GetTargetDirectory(cmTarget const& target) const; + +public: + const cmGlobalNinjaGenerator* GetGlobalNinjaGenerator() const; + cmGlobalNinjaGenerator* GetGlobalNinjaGenerator(); + + /** + * Shortcut to get the cmake instance throw the global generator. + * @return an instance of the cmake object. + */ + const cmake* GetCMakeInstance() const; + cmake* GetCMakeInstance(); + + const char* GetConfigName() const + { return this->ConfigName.c_str(); } + + std::string GetObjectFileName(const cmTarget& target, + const cmSourceFile& source); + + /// @return whether we are processing the top CMakeLists.txt file. + bool isRootMakefile() const; + + /// @returns the relative path between the HomeOutputDirectory and this + /// local generators StartOutputDirectory. + std::string GetHomeRelativeOutputPath() const + { return this->HomeRelativeOutputPath; } + +protected: + virtual std::string ConvertToLinkReference(std::string const& lib); + virtual std::string ConvertToIncludeReference(std::string const& path); + +private: + friend class cmGlobalNinjaGenerator; + + // In order to access to protected member of the local generator. + friend class cmNinjaTargetGenerator; + friend class cmNinjaNormalTargetGenerator; + friend class cmNinjaUtilityTargetGenerator; + +private: + cmGeneratedFileStream& GetBuildFileStream() const; + cmGeneratedFileStream& GetRulesFileStream() const; + + void WriteBuildFileTop(); + void WriteProjectHeader(std::ostream& os); + void WriteNinjaFilesInclusion(std::ostream& os); + void WriteProcessedMakefile(std::ostream& os); + + void SetConfigName(); + + std::string ConvertToNinjaPath(const char *path); + + struct map_to_ninja_path; + friend struct map_to_ninja_path; + struct map_to_ninja_path { + cmLocalNinjaGenerator *LocalGenerator; + map_to_ninja_path(cmLocalNinjaGenerator *LocalGen) + : LocalGenerator(LocalGen) {} + std::string operator()(const std::string &path) { + return LocalGenerator->ConvertToNinjaPath(path.c_str()); + } + }; + map_to_ninja_path MapToNinjaPath() { + return map_to_ninja_path(this); + } + + void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs); + void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs); + + void AppendCustomCommandDeps(const cmCustomCommand *cc, + cmNinjaDeps &ninjaDeps); + std::string BuildCommandLine(const std::vector<std::string> &cmdLines); + void AppendCustomCommandLines(const cmCustomCommand *cc, + std::vector<std::string> &cmdLines); + void WriteCustomCommandRule(); + void WriteCustomCommandBuildStatement(cmCustomCommand const *cc, + const cmNinjaDeps& orderOnlyDeps); + + void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target); + void WriteCustomCommandBuildStatements(); + +private: + std::string ConfigName; + std::string HomeRelativeOutputPath; + + typedef std::map<cmCustomCommand const*, std::set<cmTarget*> > + CustomCommandTargetMap; + CustomCommandTargetMap CustomCommandTargets; +}; + +#endif // ! cmLocalNinjaGenerator_h diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 70dcfd5..a645303 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -145,6 +145,20 @@ void cmLocalUnixMakefileGenerator3::Generate() } //---------------------------------------------------------------------------- +void cmLocalUnixMakefileGenerator3::AddLocalObjectFile( + cmTarget* target, cmSourceFile* sf, std::string objNoTargetDir, + bool hasSourceExtension) +{ + if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str())) + { + objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir); + } + LocalObjectInfo& info = this->LocalObjectFiles[objNoTargetDir]; + info.HasSourceExtension = hasSourceExtension; + info.push_back(LocalObjectEntry(target, sf->GetLanguage())); +} + +//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets (std::vector<std::string>& targets) { @@ -344,6 +358,7 @@ void cmLocalUnixMakefileGenerator3 (t->second.GetType() == cmTarget::STATIC_LIBRARY) || (t->second.GetType() == cmTarget::SHARED_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) || + (t->second.GetType() == cmTarget::OBJECT_LIBRARY) || (t->second.GetType() == cmTarget::UTILITY)) { emitted.insert(t->second.GetName()); @@ -452,28 +467,6 @@ void cmLocalUnixMakefileGenerator3::WriteDirectoryInformationFile() << "\n"; } - // Store the include search path for this directory. - infoFileStream - << "# The C and CXX include file search paths:\n"; - infoFileStream - << "SET(CMAKE_C_INCLUDE_PATH\n"; - std::vector<std::string> includeDirs; - this->GetIncludeDirectories(includeDirs); - for(std::vector<std::string>::iterator i = includeDirs.begin(); - i != includeDirs.end(); ++i) - { - infoFileStream - << " \"" << this->Convert(i->c_str(),HOME_OUTPUT).c_str() << "\"\n"; - } - infoFileStream - << " )\n"; - infoFileStream - << "SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH})\n"; - infoFileStream - << "SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH})\n"; - infoFileStream - << "SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH})\n"; - // Store the include regular expressions for this directory. infoFileStream << "\n" @@ -562,6 +555,21 @@ cmLocalUnixMakefileGenerator3 space = " "; } + // Warn about paths not supported by Make tools. + std::string::size_type pos = tgt.find_first_of("="); + if(pos != std::string::npos) + { + cmOStringStream m; + m << + "Make rule for\n" + " " << tgt << "\n" + "has '=' on left hand side. " + "The make tool may not support this."; + cmListFileBacktrace bt; + this->GlobalGenerator->GetCMakeInstance() + ->IssueMessage(cmake::WARNING, m.str(), bt); + } + // Mark the rule as symbolic if requested. if(symbolic) { @@ -2002,45 +2010,6 @@ void cmLocalUnixMakefileGenerator3 } //---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3 -::GetObjectFileName(cmTarget& target, - const cmSourceFile& source, - std::string* nameWithoutTargetDir, - bool* hasSourceExtension) -{ - // Make sure we never hit this old case. - if(source.GetProperty("MACOSX_PACKAGE_LOCATION")) - { - std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: "; - msg += source.GetFullPath(); - this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, - msg.c_str()); - } - - // Start with the target directory. - std::string obj = this->GetTargetDirectory(target); - obj += "/"; - - // Get the object file name without the target directory. - std::string dir_max; - dir_max += this->Makefile->GetCurrentOutputDirectory(); - dir_max += "/"; - dir_max += obj; - std::string objectName = - this->GetObjectFileNameWithoutTarget(source, dir_max, - hasSourceExtension); - if(nameWithoutTargetDir) - { - *nameWithoutTargetDir = objectName; - } - - // Append the object name to the target directory. - obj += objectName; - return obj; -} - -//---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os) { os @@ -2274,14 +2243,3 @@ void cmLocalUnixMakefileGenerator3 } } } - - -void cmLocalUnixMakefileGenerator3 -::GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& dirs) -{ - std::string dir = this->Makefile->GetCurrentOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(*target); - dirs.push_back(dir); -} diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 45ac21d..e374959 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -225,24 +225,9 @@ public: // write the target rules for the local Makefile into the stream void WriteLocalAllRules(std::ostream& ruleFileStream); - struct LocalObjectEntry - { - cmTarget* Target; - std::string Language; - LocalObjectEntry(): Target(0), Language() {} - LocalObjectEntry(cmTarget* t, const char* lang): - Target(t), Language(lang) {} - }; - struct LocalObjectInfo: public std::vector<LocalObjectEntry> - { - bool HasSourceExtension; - bool HasPreprocessRule; - bool HasAssembleRule; - LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false), - HasAssembleRule(false) {} - }; - std::map<cmStdString, LocalObjectInfo> const& GetLocalObjectFiles() - { return this->LocalObjectFiles;} + void AddLocalObjectFile(cmTarget* target, cmSourceFile* sf, + std::string objNoTargetDir, + bool hasSourceExtension); std::vector<cmStdString> const& GetLocalHelp() { return this->LocalHelp; } @@ -257,9 +242,6 @@ public: { return !this->SkipAssemblySourceRules; } - // Get the directories into which the .o files will go for this target - void GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& dirs); // Fill the vector with the target names for the object files, // preprocessed files and assembly files. Currently only used by the @@ -301,14 +283,6 @@ protected: void WriteTargetRequiresRule(std::ostream& ruleFileStream, cmTarget& target, const std::vector<std::string>& objects); - void WriteObjectConvenienceRule(std::ostream& ruleFileStream, - const char* comment, const char* output, - LocalObjectInfo const& info); - - std::string GetObjectFileName(cmTarget& target, - const cmSourceFile& source, - std::string* nameWithoutTargetDir = 0, - bool* hasSourceExtension = 0); void AppendRuleDepend(std::vector<std::string>& depends, const char* ruleFileName); @@ -378,7 +352,27 @@ private: bool SkipPreprocessedSourceRules; bool SkipAssemblySourceRules; + struct LocalObjectEntry + { + cmTarget* Target; + std::string Language; + LocalObjectEntry(): Target(0), Language() {} + LocalObjectEntry(cmTarget* t, const char* lang): + Target(t), Language(lang) {} + }; + struct LocalObjectInfo: public std::vector<LocalObjectEntry> + { + bool HasSourceExtension; + bool HasPreprocessRule; + bool HasAssembleRule; + LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false), + HasAssembleRule(false) {} + }; std::map<cmStdString, LocalObjectInfo> LocalObjectFiles; + void WriteObjectConvenienceRule(std::ostream& ruleFileStream, + const char* comment, const char* output, + LocalObjectInfo const& info); + std::vector<cmStdString> LocalHelp; /* does the work for each target */ diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 1dfcbea..f53ad0e 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -15,6 +15,7 @@ #include "cmSystemTools.h" #include "cmSourceFile.h" #include "cmCacheManager.h" +#include "cmGeneratorTarget.h" #include "cmake.h" #include "cmComputeLinkInformation.h" @@ -103,52 +104,9 @@ void cmLocalVisualStudio6Generator::OutputDSPFile() } } - // Setup /I and /LIBPATH options for the resulting DSP file. VS 6 - // truncates long include paths so make it as short as possible if - // the length threatens this problem. - unsigned int maxIncludeLength = 3000; - bool useShortPath = false; - for(int j=0; j < 2; ++j) - { - std::vector<std::string> includes; - this->GetIncludeDirectories(includes); - std::vector<std::string>::iterator i; - for(i = includes.begin(); i != includes.end(); ++i) - { - std::string tmp = - this->ConvertToOptionallyRelativeOutputPath(i->c_str()); - if(useShortPath) - { - cmSystemTools::GetShortPath(tmp.c_str(), tmp); - } - this->IncludeOptions += " /I "; - - // quote if not already quoted - if (tmp[0] != '"') - { - this->IncludeOptions += "\""; - this->IncludeOptions += tmp; - this->IncludeOptions += "\""; - } - else - { - this->IncludeOptions += tmp; - } - } - if(j == 0 && this->IncludeOptions.size() > maxIncludeLength) - { - this->IncludeOptions = ""; - useShortPath = true; - } - else - { - break; - } - } - // Create the DSP or set of DSP's for libraries and executables - cmTargets &tgts = this->Makefile->GetTargets(); + cmTargets &tgts = this->Makefile->GetTargets(); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { @@ -169,6 +127,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile() switch(l->second.GetType()) { case cmTarget::STATIC_LIBRARY: + case cmTarget::OBJECT_LIBRARY: this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second); break; case cmTarget::SHARED_LIBRARY: @@ -379,9 +338,6 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, } } - // Compute which sources need unique object computation. - this->ComputeObjectNameRequirements(sourceGroups); - // Write the DSP file's header. this->WriteDSPHeader(fout, libName, target, sourceGroups); @@ -401,6 +357,8 @@ void cmLocalVisualStudio6Generator ::WriteGroup(const cmSourceGroup *sg, cmTarget& target, std::ostream &fout, const char *libName) { + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); const std::vector<const cmSourceFile *> &sourceFiles = sg->GetSourceFiles(); // If the group is empty, don't write it at all. @@ -417,28 +375,6 @@ void cmLocalVisualStudio6Generator this->WriteDSPBeginGroup(fout, name.c_str(), ""); } - // Compute the maximum length configuration name. - std::string config_max; - for(std::vector<std::string>::iterator i = this->Configurations.begin(); - i != this->Configurations.end(); ++i) - { - // Strip the subdirectory name out of the configuration name. - std::string config = this->GetConfigName(*i); - if(config.size() > config_max.size()) - { - config_max = config; - } - } - - // Compute the maximum length full path to the intermediate - // files directory for any configuration. This is used to construct - // object file names that do not produce paths that are too long. - std::string dir_max; - dir_max += this->Makefile->GetCurrentOutputDirectory(); - dir_max += "/"; - dir_max += config_max; - dir_max += "/"; - // Loop through each source in the source group. for(std::vector<const cmSourceFile *>::const_iterator sf = sourceFiles.begin(); sf != sourceFiles.end(); ++sf) @@ -449,11 +385,9 @@ void cmLocalVisualStudio6Generator std::string compileFlags; std::vector<std::string> depends; std::string objectNameDir; - if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end()) + if(gt->ExplicitObjectName.find(*sf) != gt->ExplicitObjectName.end()) { - objectNameDir = - cmSystemTools::GetFilenamePath( - this->GetObjectFileNameWithoutTarget(*(*sf), dir_max)); + objectNameDir = cmSystemTools::GetFilenamePath(gt->Objects[*sf]); } // Add per-source file flags. @@ -895,6 +829,61 @@ inline std::string removeQuotes(const std::string& s) return s; } + +std::string +cmLocalVisualStudio6Generator::GetTargetIncludeOptions(cmTarget &target) +{ + std::string includeOptions; + + // Setup /I and /LIBPATH options for the resulting DSP file. VS 6 + // truncates long include paths so make it as short as possible if + // the length threatens this problem. + unsigned int maxIncludeLength = 3000; + bool useShortPath = false; + for(int j=0; j < 2; ++j) + { + std::vector<std::string> includes; + this->GetIncludeDirectories(includes, &target); + + std::vector<std::string>::iterator i; + for(i = includes.begin(); i != includes.end(); ++i) + { + std::string tmp = + this->ConvertToOptionallyRelativeOutputPath(i->c_str()); + if(useShortPath) + { + cmSystemTools::GetShortPath(tmp.c_str(), tmp); + } + includeOptions += " /I "; + + // quote if not already quoted + if (tmp[0] != '"') + { + includeOptions += "\""; + includeOptions += tmp; + includeOptions += "\""; + } + else + { + includeOptions += tmp; + } + } + + if(j == 0 && includeOptions.size() > maxIncludeLength) + { + includeOptions = ""; + useShortPath = true; + } + else + { + break; + } + } + + return includeOptions; +} + + // Code in blocks surrounded by a test for this definition is needed // only for compatibility with user project's replacement DSP // templates. The CMake templates no longer use them. @@ -1132,6 +1121,9 @@ void cmLocalVisualStudio6Generator } #endif + // Get include options for this target. + std::string includeOptions = this->GetTargetIncludeOptions(target); + // Get extra linker options for this target type. std::string extraLinkOptions; std::string extraLinkOptionsDebug; @@ -1249,8 +1241,18 @@ void cmLocalVisualStudio6Generator outputNameMinSizeRel = target.GetFullName("MinSizeRel"); outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo"); } + else if(target.GetType() == cmTarget::OBJECT_LIBRARY) + { + outputName = target.GetName(); + outputName += ".lib"; + outputNameDebug = outputName; + outputNameRelease = outputName; + outputNameMinSizeRel = outputName; + outputNameRelWithDebInfo = outputName; + } // Compute the output directory for the target. + std::string outputDirOld; std::string outputDirDebug; std::string outputDirRelease; std::string outputDirMinSizeRel; @@ -1260,6 +1262,11 @@ void cmLocalVisualStudio6Generator target.GetType() == cmTarget::SHARED_LIBRARY || target.GetType() == cmTarget::MODULE_LIBRARY) { +#ifdef CM_USE_OLD_VS6 + outputDirOld = + removeQuotes(this->ConvertToOptionallyRelativeOutputPath + (target.GetDirectory().c_str())); +#endif outputDirDebug = removeQuotes(this->ConvertToOptionallyRelativeOutputPath( target.GetDirectory("Debug").c_str())); @@ -1273,6 +1280,14 @@ void cmLocalVisualStudio6Generator removeQuotes(this->ConvertToOptionallyRelativeOutputPath( target.GetDirectory("RelWithDebInfo").c_str())); } + else if(target.GetType() == cmTarget::OBJECT_LIBRARY) + { + std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash(); + outputDirDebug = outputDir + "Debug"; + outputDirRelease = outputDir + "Release"; + outputDirMinSizeRel = outputDir + "MinSizeRel"; + outputDirRelWithDebInfo = outputDir + "RelWithDebInfo"; + } // Compute the proper link information for the target. std::string optionsDebug; @@ -1441,7 +1456,8 @@ void cmLocalVisualStudio6Generator libnameExports.c_str()); cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG", mfcFlag); - if(target.GetType() == cmTarget::STATIC_LIBRARY ) + if(target.GetType() == cmTarget::STATIC_LIBRARY || + target.GetType() == cmTarget::OBJECT_LIBRARY) { cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG", staticLibOptionsDebug.c_str()); @@ -1510,7 +1526,7 @@ void cmLocalVisualStudio6Generator optionsRelWithDebInfo.c_str()); cmSystemTools::ReplaceString(line, "BUILD_INCLUDES", - this->IncludeOptions.c_str()); + includeOptions.c_str()); cmSystemTools::ReplaceString(line, "TARGET_VERSION_FLAG", targetVersionFlag.c_str()); cmSystemTools::ReplaceString(line, "TARGET_IMPLIB_FLAG_DEBUG", @@ -1540,7 +1556,7 @@ void cmLocalVisualStudio6Generator (exePath.c_str())).c_str()); #endif - if(targetBuilds) + if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY) { cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG", outputDirDebug.c_str()); @@ -1550,13 +1566,11 @@ void cmLocalVisualStudio6Generator outputDirMinSizeRel.c_str()); cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO", outputDirRelWithDebInfo.c_str()); -#ifdef CM_USE_OLD_VS6 - std::string outPath = target.GetDirectory(); - cmSystemTools::ReplaceString - (line, "OUTPUT_DIRECTORY", - removeQuotes(this->ConvertToOptionallyRelativeOutputPath - (outPath.c_str())).c_str()); -#endif + if(!outputDirOld.empty()) + { + cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY", + outputDirOld.c_str()); + } } cmSystemTools::ReplaceString(line, @@ -1605,11 +1619,13 @@ void cmLocalVisualStudio6Generator flagsDebugRel = this->Makefile->GetSafeDefinition(flagVar.c_str()); flagsDebugRel += " -DCMAKE_INTDIR=\\\"RelWithDebInfo\\\" "; } - - // if unicode is not found, then add -D_MBCS + + // if _UNICODE and _SBCS are not found, then add -D_MBCS std::string defs = this->Makefile->GetDefineFlags(); if(flags.find("D_UNICODE") == flags.npos && - defs.find("D_UNICODE") == flags.npos) + defs.find("D_UNICODE") == flags.npos && + flags.find("D_SBCS") == flags.npos && + defs.find("D_SBCS") == flags.npos) { flags += " /D \"_MBCS\""; } @@ -1778,15 +1794,34 @@ cmLocalVisualStudio6Generator return ""; } -void cmLocalVisualStudio6Generator -::GetTargetObjectFileDirectories(cmTarget* , - std::vector<std::string>& - dirs) +//---------------------------------------------------------------------------- +std::string +cmLocalVisualStudio6Generator +::ComputeLongestObjectDirectory(cmTarget&) const { - std::string dir = this->Makefile->GetCurrentOutputDirectory(); - dir += "/"; - dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory(); - dirs.push_back(dir); + // Compute the maximum length configuration name. + std::string config_max; + for(std::vector<std::string>::const_iterator + i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) + { + // Strip the subdirectory name out of the configuration name. + std::string config = this->GetConfigName(*i); + if(config.size() > config_max.size()) + { + config_max = config; + } + } + + // Compute the maximum length full path to the intermediate + // files directory for any configuration. This is used to construct + // object file names that do not produce paths that are too long. + std::string dir_max; + dir_max += this->Makefile->GetCurrentOutputDirectory(); + dir_max += "/"; + dir_max += config_max; + dir_max += "/"; + return dir_max; } std::string diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h index 195d654..d36d633 100644 --- a/Source/cmLocalVisualStudio6Generator.h +++ b/Source/cmLocalVisualStudio6Generator.h @@ -50,9 +50,7 @@ public: void SetBuildType(BuildType, const char* libName, cmTarget&); virtual std::string GetTargetDirectory(cmTarget const& target) const; - void GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs); + virtual std::string ComputeLongestObjectDirectory(cmTarget&) const; private: std::string DSPHeaderTemplate; std::string DSPFooterTemplate; @@ -89,7 +87,7 @@ private: void ComputeLinkOptions(cmTarget& target, const char* configName, const std::string extraOptions, std::string& options); - std::string IncludeOptions; + std::string GetTargetIncludeOptions(cmTarget &target); std::vector<std::string> Configurations; std::string GetConfigName(std::string const& configuration) const; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 11a0387..2f145a6 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -17,6 +17,7 @@ #include "cmSystemTools.h" #include "cmSourceFile.h" #include "cmCacheManager.h" +#include "cmGeneratorTarget.h" #include "cmake.h" #include "cmComputeLinkInformation.h" @@ -641,6 +642,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, bool targetBuilds = true; switch(target.GetType()) { + case cmTarget::OBJECT_LIBRARY: + targetBuilds = false; // TODO: PDB for object library? case cmTarget::STATIC_LIBRARY: projectType = "typeStaticLibrary"; configType = "4"; @@ -774,6 +777,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, { fout << "\t\t\tCharacterSet=\"1\">\n"; } + else if(targetOptions.UsingSBCS()) + { + fout << "\t\t\tCharacterSet=\"0\">\n"; + } else { fout << "\t\t\tCharacterSet=\"2\">\n"; @@ -807,7 +814,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n"); fout << "\t\t\t\tAdditionalIncludeDirectories=\""; std::vector<std::string> includes; - this->GetIncludeDirectories(includes); + this->GetIncludeDirectories(includes, &target); std::vector<std::string>::iterator i = includes.begin(); for(;i != includes.end(); ++i) { @@ -996,6 +1003,22 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, } switch(target.GetType()) { + case cmTarget::OBJECT_LIBRARY: + { + std::string libpath = this->GetTargetDirectory(target); + libpath += "/"; + libpath += configName; + libpath += "/"; + libpath += target.GetName(); + libpath += ".lib"; + const char* tool = + this->FortranProject? "VFLibrarianTool":"VCLibrarianTool"; + fout << "\t\t\t<Tool\n" + << "\t\t\t\tName=\"" << tool << "\"\n"; + fout << "\t\t\t\tOutputFile=\"" + << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n"; + break; + } case cmTarget::STATIC_LIBRARY: { std::string targetNameFull = target.GetFullName(configName); @@ -1306,9 +1329,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, sourceGroup.AssignSource(*i); } - // Compute which sources need unique object computation. - this->ComputeObjectNameRequirements(sourceGroups); - // open the project this->WriteProjectStart(fout, libName, target, sourceGroups); // write the configuration information @@ -1348,8 +1368,7 @@ public: cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg, cmTarget& target, cmSourceFile const& sf, - std::vector<std::string>* configs, - std::string const& dir_max); + std::vector<std::string>* configs); std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap; }; @@ -1357,13 +1376,14 @@ cmLocalVisualStudio7GeneratorFCInfo ::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg, cmTarget& target, cmSourceFile const& sf, - std::vector<std::string>* configs, - std::string const& dir_max) + std::vector<std::string>* configs) { + cmGeneratorTarget* gt = + lg->GetGlobalGenerator()->GetGeneratorTarget(&target); std::string objectName; - if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end()) + if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end()) { - objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max); + objectName = gt->Objects[&sf]; } // Compute per-source, per-config information. @@ -1474,11 +1494,11 @@ cmLocalVisualStudio7GeneratorFCInfo } } - -void cmLocalVisualStudio7Generator -::ComputeMaxDirectoryLength(std::string& maxdir, - cmTarget& target) -{ +//---------------------------------------------------------------------------- +std::string +cmLocalVisualStudio7Generator +::ComputeLongestObjectDirectory(cmTarget& target) const +{ std::vector<std::string> *configs = static_cast<cmGlobalVisualStudio7Generator *> (this->GlobalGenerator)->GetConfigurations(); @@ -1503,7 +1523,7 @@ void cmLocalVisualStudio7Generator dir_max += "/"; dir_max += config_max; dir_max += "/"; - maxdir = dir_max; + return dir_max; } void cmLocalVisualStudio7Generator @@ -1526,19 +1546,13 @@ void cmLocalVisualStudio7Generator this->WriteVCProjBeginGroup(fout, name.c_str(), ""); } - // Compute the maximum length full path to the intermediate - // files directory for any configuration. This is used to construct - // object file names that do not produce paths that are too long. - std::string dir_max; - this->ComputeMaxDirectoryLength(dir_max, target); - // Loop through each source in the source group. std::string objectName; for(std::vector<const cmSourceFile *>::const_iterator sf = sourceFiles.begin(); sf != sourceFiles.end(); ++sf) { std::string source = (*sf)->GetFullPath(); - FCInfo fcinfo(this, target, *(*sf), configs, dir_max); + FCInfo fcinfo(this, target, *(*sf), configs); if (source != libName || target.GetType() == cmTarget::UTILITY || target.GetType() == cmTarget::GLOBAL_TARGET ) @@ -2114,19 +2128,6 @@ std::string cmLocalVisualStudio7Generator return dir; } -void cmLocalVisualStudio7Generator:: -GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs) -{ - std::string dir = this->Makefile->GetCurrentOutputDirectory(); - dir += "/"; - dir += this->GetTargetDirectory(*target); - dir += "/"; - dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory(); - dirs.push_back(dir); -} - //---------------------------------------------------------------------------- #include <windows.h> static bool cmLVS6G_IsFAT(const char* dir) diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 5b634b8..9d3a9f2 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -54,20 +54,13 @@ public: void SetBuildType(BuildType,const char *name); void SetPlatformName(const char* n) { this->PlatformName = n;} - void GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs); void SetExtraFlagTable(cmVS7FlagTable const* table) { this->ExtraFlagTable = table; } virtual std::string GetTargetDirectory(cmTarget const&) const; cmSourceFile* CreateVCProjBuildRule(); void WriteStampFiles(); - // Compute the maximum length full path to the intermediate - // files directory for any configuration. This is used to construct - // object file names that do not produce paths that are too long. - void ComputeMaxDirectoryLength(std::string& maxdir, - cmTarget& target); + virtual std::string ComputeLongestObjectDirectory(cmTarget&) const; virtual void ReadAndStoreExternalGUID(const char* name, const char* path); diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index de1ac30..4bcf4de 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -65,96 +65,6 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, } //---------------------------------------------------------------------------- -bool cmLocalVisualStudioGenerator::SourceFileCompiles(const cmSourceFile* sf) -{ - // Identify the language of the source file. - if(const char* lang = this->GetSourceFileLanguage(*sf)) - { - // Check whether this source will actually be compiled. - return (!sf->GetCustomCommand() && - !sf->GetPropertyAsBool("HEADER_FILE_ONLY") && - !sf->GetPropertyAsBool("EXTERNAL_OBJECT")); - } - else - { - // Unknown source file language. Assume it will not be compiled. - return false; - } -} - -//---------------------------------------------------------------------------- -void cmLocalVisualStudioGenerator::CountObjectNames( - const std::vector<cmSourceGroup>& groups, - std::map<cmStdString, int>& counts) -{ - for(unsigned int i = 0; i < groups.size(); ++i) - { - cmSourceGroup sg = groups[i]; - std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles(); - for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin(); - s != srcs.end(); ++s) - { - const cmSourceFile* sf = *s; - if(this->SourceFileCompiles(sf)) - { - std::string objectName = cmSystemTools::LowerCase( - cmSystemTools::GetFilenameWithoutLastExtension( - sf->GetFullPath())); - objectName += ".obj"; - counts[objectName] += 1; - } - } - this->CountObjectNames(sg.GetGroupChildren(), counts); - } -} - -//---------------------------------------------------------------------------- -void cmLocalVisualStudioGenerator::InsertNeedObjectNames( - const std::vector<cmSourceGroup>& groups, - std::map<cmStdString, int>& count) -{ - for(unsigned int i = 0; i < groups.size(); ++i) - { - cmSourceGroup sg = groups[i]; - std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles(); - for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin(); - s != srcs.end(); ++s) - { - const cmSourceFile* sf = *s; - if(this->SourceFileCompiles(sf)) - { - std::string objectName = cmSystemTools::LowerCase( - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath())); - objectName += ".obj"; - if(count[objectName] > 1) - { - this->NeedObjectName.insert(sf); - } - } - } - this->InsertNeedObjectNames(sg.GetGroupChildren(), count); - } -} - - -//---------------------------------------------------------------------------- -void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements -(std::vector<cmSourceGroup> const& sourceGroups) -{ - // Clear the current set of requirements. - this->NeedObjectName.clear(); - - // Count the number of object files with each name. Note that - // windows file names are not case sensitive. - std::map<cmStdString, int> objectNameCounts; - this->CountObjectNames(sourceGroups, objectNameCounts); - - // For all source files producing duplicate names we need unique - // object name computation. - this->InsertNeedObjectNames(sourceGroups, objectNameCounts); -} - -//---------------------------------------------------------------------------- const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const { return ":VCReportError"; diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index fcf1f21..410cc9a 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h @@ -56,6 +56,8 @@ public: /** Version of Visual Studio. */ VSVersion GetVersion() const { return this->Version; } + virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0; + protected: virtual const char* ReportErrorLabel() const; virtual bool CustomCommandUseLocal() const { return false; } @@ -64,16 +66,6 @@ protected: cmsys::auto_ptr<cmCustomCommand> MaybeCreateImplibDir(cmTarget& target, const char* config, bool isFortran); - // Safe object file name generation. - void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&); - bool SourceFileCompiles(const cmSourceFile* sf); - void CountObjectNames(const std::vector<cmSourceGroup>& groups, - std::map<cmStdString, int>& count); - void InsertNeedObjectNames(const std::vector<cmSourceGroup>& groups, - std::map<cmStdString, int>& count); - std::set<const cmSourceFile*> NeedObjectName; - friend class cmVisualStudio10TargetGenerator; - VSVersion Version; }; diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index b989870..551ebd3 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -33,16 +33,3 @@ cmLocalXCodeGenerator::GetTargetDirectory(cmTarget const&) const // No per-target directory for this generator (yet). return ""; } - -//---------------------------------------------------------------------------- -void cmLocalXCodeGenerator:: -GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs) -{ - cmGlobalXCodeGenerator* g = - (cmGlobalXCodeGenerator*)this->GetGlobalGenerator(); - g->SetCurrentLocalGenerator(this); - g->GetTargetObjectFileDirectories(target, - dirs); -} diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h index 1ab805d..eab228f 100644 --- a/Source/cmLocalXCodeGenerator.h +++ b/Source/cmLocalXCodeGenerator.h @@ -27,9 +27,6 @@ public: cmLocalXCodeGenerator(); virtual ~cmLocalXCodeGenerator(); - void GetTargetObjectFileDirectories(cmTarget* target, - std::vector<std::string>& - dirs); virtual std::string GetTargetDirectory(cmTarget const& target) const; private: diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 774f32b..2599227 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -23,6 +23,17 @@ public: ~cmMacroHelperCommand() {}; /** + * This is used to avoid including this command + * in documentation. This is mainly used by + * cmMacroHelperCommand and cmFunctionHelperCommand + * which cannot provide appropriate documentation. + */ + virtual bool ShouldAppearInDocumentation() const + { + return false; + } + + /** * This is a virtual constructor for the command. */ virtual cmCommand* Clone() @@ -39,7 +50,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * This is called when the command is first encountered in @@ -54,12 +65,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return this->Args[0].c_str(); } + virtual const char* GetName() const { return this->Args[0].c_str(); } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { std::string docs = "Macro named: "; docs += this->GetName(); @@ -69,7 +80,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return this->GetTerseDocumentation(); } diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 93e10b2..36e4b2f 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -15,11 +15,6 @@ #include "cmCommand.h" #include "cmFunctionBlocker.h" -/** \class cmMacroFunctionBlocker - * \brief subclass of function blocker - * - * - */ class cmMacroFunctionBlocker : public cmFunctionBlocker { public: @@ -35,11 +30,7 @@ public: int Depth; }; -/** \class cmMacroCommand - * \brief starts an if block - * - * cmMacroCommand starts an if block - */ +/// Starts macro() ... endmacro() block class cmMacroCommand : public cmCommand { public: @@ -61,17 +52,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "macro";} + virtual const char* GetName() const { return "macro";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Start recording a macro for later invocation as a command."; } @@ -79,7 +70,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " macro(<name> [arg1 [arg2 [arg3 ...]]])\n" diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 0b4eea5..6055c55 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -54,16 +54,33 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) this->Makefile->IncludeFileRegularExpression.c_str()); this->ComplainFileRegularExpression.compile( this->Makefile->ComplainFileRegularExpression.c_str()); - - // Now extract any include paths from the makefile flags - const std::vector<std::string>& includes = - this->Makefile->GetIncludeDirectories(); - for(std::vector<std::string>::const_iterator j = includes.begin(); - j != includes.end(); ++j) + + // Now extract any include paths from the targets + std::set<std::string> uniqueIncludes; + std::vector<std::string> orderedAndUniqueIncludes; + cmTargets & targets = this->Makefile->GetTargets(); + for (cmTargets::iterator l = targets.begin(); l != targets.end(); ++l) + { + const std::vector<std::string>& includes = + l->second.GetIncludeDirectories(); + for(std::vector<std::string>::const_iterator j = includes.begin(); + j != includes.end(); ++j) + { + std::string path = *j; + this->Makefile->ExpandVariablesInString(path); + if(uniqueIncludes.insert(path).second) + { + orderedAndUniqueIncludes.push_back(path); + } + } + } + + for(std::vector<std::string>::const_iterator + it = orderedAndUniqueIncludes.begin(); + it != orderedAndUniqueIncludes.end(); + ++it) { - std::string path = *j; - this->Makefile->ExpandVariablesInString(path); - this->AddSearchPath(path.c_str()); + this->AddSearchPath(it->c_str()); } } diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h index 63b91d1..4e6e1d5 100644 --- a/Source/cmMakeDirectoryCommand.h +++ b/Source/cmMakeDirectoryCommand.h @@ -44,17 +44,17 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "make_directory";} + virtual const char* GetName() const { return "make_directory";} /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the file(MAKE_DIRECTORY ) command instead."; } @@ -62,7 +62,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " make_directory(directory)\n" @@ -72,7 +72,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index fdf5b31..aba2e38 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -116,7 +116,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->Targets = mf.Targets; this->SourceFiles = mf.SourceFiles; this->Tests = mf.Tests; - this->IncludeDirectories = mf.IncludeDirectories; this->LinkDirectories = mf.LinkDirectories; this->SystemIncludeDirectories = mf.SystemIncludeDirectories; this->ListFiles = mf.ListFiles; @@ -210,9 +209,9 @@ cmMakefile::~cmMakefile() { delete *i; } - for(unsigned int i=0; i < this->UsedCommands.size(); i++) + for(unsigned int i=0; i < this->FinalPassCommands.size(); i++) { - delete this->UsedCommands[i]; + delete this->FinalPassCommands[i]; } std::vector<cmFunctionBlocker*>::iterator pos; for (pos = this->FunctionBlockers.begin(); @@ -278,8 +277,6 @@ void cmMakefile::Print() this->cmHomeDirectory.c_str() << std::endl; std::cout << " this->ProjectName; " << this->ProjectName.c_str() << std::endl; - this->PrintStringVector("this->IncludeDirectories;", - this->IncludeDirectories); this->PrintStringVector("this->LinkDirectories", this->LinkDirectories); #if defined(CMAKE_BUILD_WITH_CMAKE) for( std::vector<cmSourceGroup>::const_iterator i = @@ -421,7 +418,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff, else if(pcmd->HasFinalPass()) { // use the command - this->UsedCommands.push_back(pcmd.release()); + this->FinalPassCommands.push_back(pcmd.release()); } } else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE @@ -813,8 +810,8 @@ void cmMakefile::FinalPass() // give all the commands a chance to do something // after the file has been parsed before generation - for(std::vector<cmCommand*>::iterator i = this->UsedCommands.begin(); - i != this->UsedCommands.end(); ++i) + for(std::vector<cmCommand*>::iterator i = this->FinalPassCommands.begin(); + i != this->FinalPassCommands.end(); ++i) { (*i)->FinalPass(); } @@ -856,6 +853,14 @@ cmMakefile::AddCustomCommandToTarget(const char* target, cmTargets::iterator ti = this->Targets.find(target); if(ti != this->Targets.end()) { + if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY) + { + cmOStringStream e; + e << "Target \"" << target << "\" is an OBJECT library " + "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; + this->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; cmCustomCommand cc(this, no_output, depends, @@ -948,7 +953,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, outName += ".rule"; const char* dir = this->LocalGenerator->GetGlobalGenerator()-> - GetCMakeCFGInitDirectory(); + GetCMakeCFGIntDir(); if(dir && dir[0] == '$') { cmSystemTools::ReplaceString(outName, dir, @@ -1478,7 +1483,8 @@ void cmMakefile::InitializeFromParent() this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); // copy include paths - this->IncludeDirectories = parent->IncludeDirectories; + this->SetProperty("INCLUDE_DIRECTORIES", + parent->GetProperty("INCLUDE_DIRECTORIES")); this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags @@ -1603,42 +1609,61 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath, } } -void cmMakefile::AddIncludeDirectory(const char* inc, bool before) +//---------------------------------------------------------------------------- +void AddStringToProperty(cmProperty *prop, const char* name, const char* s, + bool before) { - // if there is a newline then break it into multiple arguments - if (!inc) + if (!prop) { return; } - // Don't add an include directory that is already present. Yes, - // this linear search results in n^2 behavior, but n won't be - // getting much bigger than 20. We cannot use a set because of - // order dependency of the include path. - std::vector<std::string>::iterator i = - std::find(this->IncludeDirectories.begin(), - this->IncludeDirectories.end(), inc); - if(i == this->IncludeDirectories.end()) + // Don't worry about duplicates at this point. We eliminate them when + // we convert the property to a vector in GetIncludeDirectories. + + if (before) { - if (before) + const char *val = prop->GetValue(); + cmOStringStream oss; + + if(val && *val) { - // WARNING: this *is* expensive (linear time) since it's a vector - this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc); + oss << s << ";" << val; } else { - this->IncludeDirectories.push_back(inc); + oss << s; } + + std::string newVal = oss.str(); + prop->Set(name, newVal.c_str()); } else { - if(before) - { - // if this before and already in the path then remove it - this->IncludeDirectories.erase(i); - // WARNING: this *is* expensive (linear time) since it's a vector - this->IncludeDirectories.insert(this->IncludeDirectories.begin(), inc); - } + prop->Append(name, s); + } +} + +//---------------------------------------------------------------------------- +void cmMakefile::AddIncludeDirectory(const char* inc, bool before) +{ + if (!inc) + { + return; + } + + // Directory property: + cmProperty *prop = + this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); + AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before); + + // Property on each target: + for (cmTargets::iterator l = this->Targets.begin(); + l != this->Targets.end(); ++l) + { + cmTarget &t = l->second; + prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); + AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before); } } @@ -1895,8 +1920,11 @@ cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, // wrong type ? default to STATIC if ( (type != cmTarget::STATIC_LIBRARY) && (type != cmTarget::SHARED_LIBRARY) - && (type != cmTarget::MODULE_LIBRARY)) + && (type != cmTarget::MODULE_LIBRARY) + && (type != cmTarget::OBJECT_LIBRARY)) { + this->IssueMessage(cmake::INTERNAL_ERROR, + "cmMakefile::AddLibrary given invalid target type."); type = cmTarget::STATIC_LIBRARY; } @@ -2093,17 +2121,37 @@ void cmMakefile::AddExtraDirectory(const char* dir) } -// expance CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the +// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the // include and library directories. void cmMakefile::ExpandVariables() { // Now expand variables in the include and link strings - for(std::vector<std::string>::iterator d = this->IncludeDirectories.begin(); - d != this->IncludeDirectories.end(); ++d) + + // May not be necessary anymore... But may need a policy for strict + // backwards compatibility + const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); + if (includeDirs) { - this->ExpandVariablesInString(*d, true, true); + std::string dirs = includeDirs; + this->ExpandVariablesInString(dirs, true, true); + this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); } + + // Also for each target's INCLUDE_DIRECTORIES property: + for (cmTargets::iterator l = this->Targets.begin(); + l != this->Targets.end(); ++l) + { + cmTarget &t = l->second; + includeDirs = t.GetProperty("INCLUDE_DIRECTORIES"); + if (includeDirs) + { + std::string dirs = includeDirs; + this->ExpandVariablesInString(dirs, true, true); + t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); + } + } + for(std::vector<std::string>::iterator d = this->LinkDirectories.begin(); d != this->LinkDirectories.end(); ++d) { @@ -2828,7 +2876,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const & lang, { this->AddDefinition("CMAKE_CFG_INTDIR", this->LocalGenerator->GetGlobalGenerator() - ->GetCMakeCFGInitDirectory()); + ->GetCMakeCFGIntDir()); this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this, optional); } @@ -3317,16 +3365,6 @@ void cmMakefile::SetProperty(const char* prop, const char* value) // handle special props std::string propname = prop; - if ( propname == "INCLUDE_DIRECTORIES" ) - { - std::vector<std::string> varArgsExpanded; - if(value) - { - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - } - this->SetIncludeDirectories(varArgsExpanded); - return; - } if ( propname == "LINK_DIRECTORIES" ) { @@ -3368,17 +3406,6 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, // handle special props std::string propname = prop; - if ( propname == "INCLUDE_DIRECTORIES" ) - { - std::vector<std::string> varArgsExpanded; - cmSystemTools::ExpandListArgument(value, varArgsExpanded); - for(std::vector<std::string>::const_iterator vi = varArgsExpanded.begin(); - vi != varArgsExpanded.end(); ++vi) - { - this->AddIncludeDirectory(vi->c_str()); - } - return; - } if ( propname == "LINK_DIRECTORIES" ) { @@ -3474,23 +3501,6 @@ const char *cmMakefile::GetProperty(const char* prop, output += this->DefineFlagsOrig; return output.c_str(); } - else if (!strcmp("INCLUDE_DIRECTORIES",prop) ) - { - cmOStringStream str; - for (std::vector<std::string>::const_iterator - it = this->GetIncludeDirectories().begin(); - it != this->GetIncludeDirectories().end(); - ++ it ) - { - if ( it != this->GetIncludeDirectories().begin()) - { - str << ";"; - } - str << it->c_str(); - } - output = str.str(); - return output.c_str(); - } else if (!strcmp("LINK_DIRECTORIES",prop)) { cmOStringStream str; @@ -3861,9 +3871,22 @@ void cmMakefile::DefineProperties(cmake *cm) cm->DefineProperty ("INCLUDE_DIRECTORIES", cmProperty::DIRECTORY, "List of preprocessor include file search directories.", - "This read-only property specifies the list of directories given " - "so far to the include_directories command. " - "It is intended for debugging purposes.", false); + "This property specifies the list of directories given " + "so far to the include_directories command. " + "This property exists on directories and targets. " + "In addition to accepting values from the include_directories " + "command, values may be set directly on any directory or any " + "target using the set_property command. " + "A target gets its initial value for this property from the value " + "of the directory property. " + "A directory gets its initial value from its parent directory if " + "it has one. " + "Both directory and target property values are adjusted by calls " + "to the include_directories command." + "\n" + "The target property values are used by the generators to set " + "the include paths for the compiler. " + "See also the include_directories command."); cm->DefineProperty ("LINK_DIRECTORIES", cmProperty::DIRECTORY, diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1c46a73..960ba39 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -522,22 +522,6 @@ public: cmTarget* FindTargetToUse(const char* name); /** - * Get a list of include directories in the build. - */ - std::vector<std::string>& GetIncludeDirectories() - { - return this->IncludeDirectories; - } - const std::vector<std::string>& GetIncludeDirectories() const - { - return this->IncludeDirectories; - } - void SetIncludeDirectories(const std::vector<std::string>& vec) - { - this->IncludeDirectories = vec; - } - - /** * Mark include directories as system directories. */ void AddSystemIncludeDirectory(const char* dir); @@ -620,12 +604,6 @@ public: */ bool CanIWriteThisFile(const char* fileName); - /** - * Get the vector of used command instances. - */ - const std::vector<cmCommand*>& GetUsedCommands() const - {return this->UsedCommands;} - #if defined(CMAKE_BUILD_WITH_CMAKE) /** * Get the vector source groups. @@ -880,9 +858,7 @@ protected: // Tests std::map<cmStdString, cmTest*> Tests; - // The include and link-library paths. These may have order - // dependency, so they must be vectors (not set). - std::vector<std::string> IncludeDirectories; + // The link-library paths. Order matters, use std::vector (not std::set). std::vector<std::string> LinkDirectories; // The set of include directories that are marked as system include @@ -913,7 +889,7 @@ protected: std::vector<cmSourceGroup> SourceGroups; #endif - std::vector<cmCommand*> UsedCommands; + std::vector<cmCommand*> FinalPassCommands; cmLocalGenerator* LocalGenerator; bool IsFunctionBlocked(const cmListFileFunction& lff, cmExecutionStatus &status); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index b4174cc..38aa59d 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -101,6 +101,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles() this->WriteModuleLibraryRules(true); } break; + case cmTarget::OBJECT_LIBRARY: + this->WriteObjectLibraryRules(); + break; default: // If language is not known, this is an error. cmSystemTools::Error("Unknown Library Type"); @@ -122,6 +125,29 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles() } //---------------------------------------------------------------------------- +void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules() +{ + std::vector<std::string> commands; + std::vector<std::string> depends; + + // Add post-build rules. + this->LocalGenerator-> + AppendCustomCommands(commands, this->Target->GetPostBuildCommands(), + this->Target); + + // Depend on the object files. + this->AppendObjectDepends(depends); + + // Write the rule. + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, + this->Target->GetName(), + depends, commands, true); + + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(this->Target->GetName(), false); +} + +//---------------------------------------------------------------------------- void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() { const char* linkLanguage = diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index f3c47db..e6a5867 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -25,6 +25,7 @@ public: virtual void WriteRuleFiles(); protected: + void WriteObjectLibraryRules(); void WriteStaticLibraryRules(); void WriteSharedLibraryRules(bool relink); void WriteModuleLibraryRules(bool relink); diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a3a832b..d0cfd99 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmMakefileTargetGenerator.h" +#include "cmGeneratorTarget.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" #include "cmGlobalUnixMakefileGenerator3.h" @@ -42,6 +43,7 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target) this->GlobalGenerator = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()); + this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target); cmake* cm = this->GlobalGenerator->GetCMakeInstance(); this->NoRuleMessages = false; if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES")) @@ -63,6 +65,7 @@ cmMakefileTargetGenerator::New(cmTarget *tgt) case cmTarget::STATIC_LIBRARY: case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + case cmTarget::OBJECT_LIBRARY: result = new cmMakefileLibraryTargetGenerator(tgt); break; case cmTarget::UTILITY: @@ -131,58 +134,46 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // First generate the object rule files. Save a list of all object // files for this target. - const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); - source != sources.end(); ++source) + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->CustomCommands.begin(); + si != this->GeneratorTarget->CustomCommands.end(); ++si) { - cmTarget::SourceFileFlags tsFlags = - this->Target->GetTargetSourceFileFlags(*source); - if(cmCustomCommand* cc = (*source)->GetCustomCommand()) - { - this->GenerateCustomRuleFile(*cc); - if (clean) - { - const std::vector<std::string>& outputs = cc->GetOutputs(); - for(std::vector<std::string>::const_iterator o = outputs.begin(); - o != outputs.end(); ++o) - { - this->CleanFiles.push_back - (this->Convert(o->c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::UNCHANGED)); - } - } - } - else if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + cmCustomCommand const* cc = (*si)->GetCustomCommand(); + this->GenerateCustomRuleFile(*cc); + if (clean) { - this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder); - } - else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY")) - { - if(!this->GlobalGenerator->IgnoreFile - ((*source)->GetExtension().c_str())) - { - // Generate this object file's rule file. - this->WriteObjectRuleFiles(*(*source)); - } - else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT")) - { - // This is an external object file. Just add it. - this->ExternalObjects.push_back((*source)->GetFullPath()); - } - else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF") - { - this->ModuleDefinitionFile = (*source)->GetFullPath(); - } - else + const std::vector<std::string>& outputs = cc->GetOutputs(); + for(std::vector<std::string>::const_iterator o = outputs.begin(); + o != outputs.end(); ++o) { - // We only get here if a source file is not an external object - // and has an extension that is listed as an ignored file type - // for this language. No message or diagnosis should be - // given. + this->CleanFiles.push_back + (this->Convert(o->c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::UNCHANGED)); } } } + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->OSXContent.begin(); + si != this->GeneratorTarget->OSXContent.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + this->WriteMacOSXContentRules(**si, tsFlags.MacFolder); + } + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ExternalObjects.begin(); + si != this->GeneratorTarget->ExternalObjects.end(); ++si) + { + this->ExternalObjects.push_back((*si)->GetFullPath()); + } + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ObjectSources.begin(); + si != this->GeneratorTarget->ObjectSources.end(); ++si) + { + // Generate this object file's rule file. + this->WriteObjectRuleFiles(**si); + } } @@ -428,12 +419,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) } // Get the full path name of the object file. - bool hasSourceExtension; - std::string objNoTargetDir; - std::string obj = - this->LocalGenerator->GetObjectFileName(*this->Target, source, - &objNoTargetDir, - &hasSourceExtension); + std::string const& objectName = this->GeneratorTarget->Objects[&source]; + std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target); + obj += "/"; + obj += objectName; // Avoid generating duplicate rules. if(this->ObjectFiles.find(obj) == this->ObjectFiles.end()) @@ -487,18 +476,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) AddImplicitDepends(*this->Target, lang, objFullPath.c_str(), srcFullPath.c_str()); - - // add this to the list of objects for this local generator - if(cmSystemTools::FileIsFullPath(objNoTargetDir.c_str())) - { - objNoTargetDir = cmSystemTools::GetFilenameName(objNoTargetDir); - } - cmLocalUnixMakefileGenerator3::LocalObjectInfo& info = - this->LocalGenerator->LocalObjectFiles[objNoTargetDir]; - info.HasSourceExtension = hasSourceExtension; - info.push_back( - cmLocalUnixMakefileGenerator3::LocalObjectEntry(this->Target, lang) - ); } //---------------------------------------------------------------------------- @@ -1069,6 +1046,35 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n"; } + // Target-specific include directories: + *this->InfoFileStream + << "\n" + << "# The include file search paths:\n"; + *this->InfoFileStream + << "SET(CMAKE_C_TARGET_INCLUDE_PATH\n"; + std::vector<std::string> includes; + this->LocalGenerator->GetIncludeDirectories(includes, this->Target); + for(std::vector<std::string>::iterator i = includes.begin(); + i != includes.end(); ++i) + { + *this->InfoFileStream + << " \"" + << this->LocalGenerator->Convert(i->c_str(), + cmLocalGenerator::HOME_OUTPUT) + << "\"\n"; + } + *this->InfoFileStream + << " )\n"; + *this->InfoFileStream + << "SET(CMAKE_CXX_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + *this->InfoFileStream + << "SET(CMAKE_Fortran_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + *this->InfoFileStream + << "SET(CMAKE_ASM_TARGET_INCLUDE_PATH " + << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; + // and now write the rule to use it std::vector<std::string> depends; std::vector<std::string> commands; @@ -1534,7 +1540,7 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() emitted.insert("/System/Library/Frameworks"); #endif std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes); + this->LocalGenerator->GetIncludeDirectories(includes, this->Target); std::vector<std::string>::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework @@ -1591,7 +1597,7 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void cmMakefileTargetGenerator -::AppendLinkDepends(std::vector<std::string>& depends) +::AppendObjectDepends(std::vector<std::string>& depends) { // Add dependencies on the compiled object files. std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath(); @@ -1604,25 +1610,32 @@ void cmMakefileTargetGenerator depends.push_back(objTarget); } - // Add dependencies on targets that must be built first. - this->AppendTargetDepends(depends); + // Add dependencies on the external object files. + for(std::vector<std::string>::const_iterator obj + = this->ExternalObjects.begin(); + obj != this->ExternalObjects.end(); ++obj) + { + depends.push_back(*obj); + } // Add a dependency on the rule file itself. this->LocalGenerator->AppendRuleDepend(depends, this->BuildFileNameFull.c_str()); +} - // Add a dependency on the link definitions file, if any. - if(!this->ModuleDefinitionFile.empty()) - { - depends.push_back(this->ModuleDefinitionFile); - } +//---------------------------------------------------------------------------- +void cmMakefileTargetGenerator +::AppendLinkDepends(std::vector<std::string>& depends) +{ + this->AppendObjectDepends(depends); - // Add dependencies on the external object files. - for(std::vector<std::string>::const_iterator obj - = this->ExternalObjects.begin(); - obj != this->ExternalObjects.end(); ++obj) + // Add dependencies on targets that must be built first. + this->AppendTargetDepends(depends); + + // Add a dependency on the link definitions file, if any. + if(!this->GeneratorTarget->ModuleDefinitionFile.empty()) { - depends.push_back(*obj); + depends.push_back(this->GeneratorTarget->ModuleDefinitionFile); } // Add user-specified dependencies. @@ -1829,8 +1842,12 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags, responseVar += "_USE_RESPONSE_FILE_FOR_INCLUDES"; bool useResponseFile = this->Makefile->IsOn(responseVar.c_str()); + + std::vector<std::string> includes; + this->LocalGenerator->GetIncludeDirectories(includes, this->Target, lang); + std::string includeFlags = - this->LocalGenerator->GetIncludeFlags(lang, useResponseFile); + this->LocalGenerator->GetIncludeFlags(includes, lang, useResponseFile); if(includeFlags.empty()) { return; @@ -1930,7 +1947,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) { std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes); + this->LocalGenerator->GetIncludeDirectories(includes, this->Target); for(std::vector<std::string>::const_iterator idi = includes.begin(); idi != includes.end(); ++idi) { @@ -1946,7 +1963,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags) //---------------------------------------------------------------------------- void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) { - if(this->ModuleDefinitionFile.empty()) + if(this->GeneratorTarget->ModuleDefinitionFile.empty()) { return; } @@ -1963,7 +1980,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags) // vs6's "cl -link" pass it to the linker. std::string flag = defFileFlag; flag += (this->LocalGenerator->ConvertToLinkReference( - this->ModuleDefinitionFile.c_str())); + this->GeneratorTarget->ModuleDefinitionFile.c_str())); this->LocalGenerator->AppendFlags(flags, flag.c_str()); } diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 8fba13f..e1e554b 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -17,6 +17,7 @@ class cmCustomCommand; class cmDependInformation; class cmDepends; +class cmGeneratorTarget; class cmGeneratedFileStream; class cmGlobalUnixMakefileGenerator3; class cmLocalUnixMakefileGenerator3; @@ -117,6 +118,9 @@ protected: // append intertarget dependencies void AppendTargetDepends(std::vector<std::string>& depends); + // Append object file dependencies. + void AppendObjectDepends(std::vector<std::string>& depends); + // Append link rule dependencies (objects, etc.). void AppendLinkDepends(std::vector<std::string>& depends); @@ -157,6 +161,7 @@ protected: void RemoveForbiddenFlags(const char* flagVar, const char* linkLang, std::string& linkFlags); cmTarget *Target; + cmGeneratorTarget* GeneratorTarget; cmLocalUnixMakefileGenerator3 *LocalGenerator; cmGlobalUnixMakefileGenerator3 *GlobalGenerator; cmMakefile *Makefile; @@ -198,9 +203,6 @@ protected: std::vector<std::string> Objects; std::vector<std::string> ExternalObjects; - // The windows module definition source file (.def), if any. - std::string ModuleDefinitionFile; - // Set of object file names that will be built in this directory. std::set<cmStdString> ObjectFiles; diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h index 26e0a07..3658dbb 100644 --- a/Source/cmMarkAsAdvancedCommand.h +++ b/Source/cmMarkAsAdvancedCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "mark_as_advanced";} + virtual const char* GetName() const {return "mark_as_advanced";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Mark cmake cached variables as advanced."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " mark_as_advanced([CLEAR|FORCE] VAR VAR2 VAR...)\n" @@ -75,7 +75,7 @@ public: * make many of the modules usable in cmake/ctest scripts, (among them * FindUnixMake.cmake used by the CTEST_BUILD command. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } cmTypeMacro(cmMarkAsAdvancedCommand, cmCommand); }; diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h index d31f34b..d622904 100644 --- a/Source/cmMathCommand.h +++ b/Source/cmMathCommand.h @@ -14,10 +14,7 @@ #include "cmCommand.h" -/** \class cmMathCommand - * \brief Common string operations - * - */ +/// Mathematical expressions: math(EXPR ...) command. class cmMathCommand : public cmCommand { public: @@ -39,17 +36,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "math";} + virtual const char* GetName() const { return "math";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Mathematical expressions."; } @@ -57,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " math(EXPR <output variable> <math expression>)\n" diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h index 932ee77..03ab94b 100644 --- a/Source/cmMessageCommand.h +++ b/Source/cmMessageCommand.h @@ -39,17 +39,17 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "message";} + virtual const char* GetName() const { return "message";} /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Display a message to the user."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]\n" diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx new file mode 100644 index 0000000..9242181 --- /dev/null +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -0,0 +1,469 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmNinjaNormalTargetGenerator.h" +#include "cmLocalNinjaGenerator.h" +#include "cmGlobalNinjaGenerator.h" +#include "cmSourceFile.h" +#include "cmGeneratedFileStream.h" +#include "cmMakefile.h" + +#include <assert.h> + +cmNinjaNormalTargetGenerator:: +cmNinjaNormalTargetGenerator(cmTarget* target) + : cmNinjaTargetGenerator(target) + , TargetNameOut() + , TargetNameSO() + , TargetNameReal() + , TargetNameImport() + , TargetNamePDB() +{ + this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); + if (target->GetType() == cmTarget::EXECUTABLE) + target->GetExecutableNames(this->TargetNameOut, + this->TargetNameReal, + this->TargetNameImport, + this->TargetNamePDB, + GetLocalGenerator()->GetConfigName()); + else + target->GetLibraryNames(this->TargetNameOut, + this->TargetNameSO, + this->TargetNameReal, + this->TargetNameImport, + this->TargetNamePDB, + GetLocalGenerator()->GetConfigName()); + + // on Windows the output dir is already needed at compile time + // ensure the directory exists (OutDir test) + std::string outpath = target->GetDirectory(this->GetConfigName()); + cmSystemTools::MakeDirectory(outpath.c_str()); +} + +cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() +{ +} + +void cmNinjaNormalTargetGenerator::Generate() +{ + if (!this->TargetLinkLanguage) { + cmSystemTools::Error("CMake can not determine linker language for target:", + this->GetTarget()->GetName()); + return; + } + + // Write the rules for each language. + this->WriteLanguagesRules(); + + // Write the build statements + this->WriteObjectBuildStatements(); + + this->WriteLinkRule(); + this->WriteLinkStatement(); + + this->GetBuildFileStream() << "\n"; + this->GetRulesFileStream() << "\n"; +} + +void cmNinjaNormalTargetGenerator::WriteLanguagesRules() +{ + cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream()); + this->GetRulesFileStream() + << "# Rules for each languages for " + << cmTarget::GetTargetTypeName(this->GetTarget()->GetType()) + << " target " + << this->GetTargetName() + << "\n\n"; + + std::set<cmStdString> languages; + this->GetTarget()->GetLanguages(languages); + for(std::set<cmStdString>::const_iterator l = languages.begin(); + l != languages.end(); + ++l) + this->WriteLanguageRules(*l); +} + +const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const +{ + switch (this->GetTarget()->GetType()) { + case cmTarget::STATIC_LIBRARY: + return "static library"; + case cmTarget::SHARED_LIBRARY: + return "shared library"; + case cmTarget::MODULE_LIBRARY: + return "shared module"; + case cmTarget::EXECUTABLE: + return "executable"; + default: + return 0; + } +} + +std::string +cmNinjaNormalTargetGenerator +::LanguageLinkerRule() const +{ + return std::string(this->TargetLinkLanguage) + + "_" + + cmTarget::GetTargetTypeName(this->GetTarget()->GetType()) + + "_LINKER"; +} + +void +cmNinjaNormalTargetGenerator +::WriteLinkRule() +{ + cmTarget::TargetType targetType = this->GetTarget()->GetType(); + std::string ruleName = this->LanguageLinkerRule(); + + if (!this->GetGlobalGenerator()->HasRule(ruleName)) { + cmLocalGenerator::RuleVariables vars; + vars.RuleLauncher = "RULE_LAUNCH_LINK"; + vars.CMTarget = this->GetTarget(); + vars.Language = this->TargetLinkLanguage; + vars.Objects = "$in"; + std::string objdir = cmake::GetCMakeFilesDirectoryPostSlash(); + objdir += this->GetTargetName(); + objdir += ".dir"; + objdir = this->GetLocalGenerator()->Convert(objdir.c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL); + vars.ObjectDir = objdir.c_str(); + vars.Target = "$out"; + vars.TargetSOName = "$SONAME"; + vars.TargetInstallNameDir = "$INSTALLNAME_DIR"; + vars.TargetPDB = "$TARGET_PDB"; + + // Setup the target version. + std::string targetVersionMajor; + std::string targetVersionMinor; + { + cmOStringStream majorStream; + cmOStringStream minorStream; + int major; + int minor; + this->GetTarget()->GetTargetVersion(major, minor); + majorStream << major; + minorStream << minor; + targetVersionMajor = majorStream.str(); + targetVersionMinor = minorStream.str(); + } + vars.TargetVersionMajor = targetVersionMajor.c_str(); + vars.TargetVersionMinor = targetVersionMinor.c_str(); + + vars.LinkLibraries = "$LINK_LIBRARIES"; + vars.Flags = "$FLAGS"; + vars.LinkFlags = "$LINK_FLAGS"; + + std::string langFlags; + this->GetLocalGenerator()->AddLanguageFlags(langFlags, + this->TargetLinkLanguage, + this->GetConfigName()); + if (targetType != cmTarget::EXECUTABLE) + langFlags += " $ARCH_FLAGS"; + vars.LanguageCompileFlags = langFlags.c_str(); + + // Rule for linking library. + std::vector<std::string> linkCmds = this->ComputeLinkCmd(); + for(std::vector<std::string>::iterator i = linkCmds.begin(); + i != linkCmds.end(); + ++i) + { + this->GetLocalGenerator()->ExpandRuleVariables(*i, vars); + } + linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); + linkCmds.push_back("$POST_BUILD"); + std::string linkCmd = + this->GetLocalGenerator()->BuildCommandLine(linkCmds); + + // Write the linker rule. + std::ostringstream comment; + comment << "Rule for linking " << this->TargetLinkLanguage << " " + << this->GetVisibleTypeName() << "."; + std::ostringstream description; + description << "Linking " << this->TargetLinkLanguage << " " + << this->GetVisibleTypeName() << " $out"; + this->GetGlobalGenerator()->AddRule(ruleName, + linkCmd, + description.str(), + comment.str()); + } + + if (this->TargetNameOut != this->TargetNameReal) { + std::string cmakeCommand = + this->GetLocalGenerator()->ConvertToOutputFormat( + this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL); + if (targetType == cmTarget::EXECUTABLE) + this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_EXECUTABLE", + cmakeCommand + + " -E cmake_symlink_executable" + " $in $out && $POST_BUILD", + "Creating executable symlink $out", + "Rule for creating executable symlink."); + else + this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY", + cmakeCommand + + " -E cmake_symlink_library" + " $in $SONAME $out && $POST_BUILD", + "Creating library symlink $out", + "Rule for creating library symlink."); + } +} + +std::vector<std::string> +cmNinjaNormalTargetGenerator +::ComputeLinkCmd() +{ + std::vector<std::string> linkCmds; + cmTarget::TargetType targetType = this->GetTarget()->GetType(); + switch (targetType) { + case cmTarget::STATIC_LIBRARY: { + // Check if you have a non archive way to create the static library. + { + std::string linkCmdVar = "CMAKE_"; + linkCmdVar += this->TargetLinkLanguage; + linkCmdVar += "_CREATE_STATIC_LIBRARY"; + if (const char *linkCmd = + this->GetMakefile()->GetDefinition(linkCmdVar.c_str())) + { + cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + return linkCmds; + } + } + + // We have archive link commands set. First, delete the existing archive. + std::string cmakeCommand = + this->GetLocalGenerator()->ConvertToOutputFormat( + this->GetMakefile()->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL); + linkCmds.push_back(cmakeCommand + " -E remove $out"); + + // TODO: Use ARCHIVE_APPEND for archives over a certain size. + { + std::string linkCmdVar = "CMAKE_"; + linkCmdVar += this->TargetLinkLanguage; + linkCmdVar += "_ARCHIVE_CREATE"; + const char *linkCmd = + this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str()); + cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + } + { + std::string linkCmdVar = "CMAKE_"; + linkCmdVar += this->TargetLinkLanguage; + linkCmdVar += "_ARCHIVE_FINISH"; + const char *linkCmd = + this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str()); + cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + } + return linkCmds; + } + case cmTarget::SHARED_LIBRARY: + case cmTarget::MODULE_LIBRARY: + case cmTarget::EXECUTABLE: { + std::string linkCmdVar = "CMAKE_"; + linkCmdVar += this->TargetLinkLanguage; + switch (targetType) { + case cmTarget::SHARED_LIBRARY: + linkCmdVar += "_CREATE_SHARED_LIBRARY"; + break; + case cmTarget::MODULE_LIBRARY: + linkCmdVar += "_CREATE_SHARED_MODULE"; + break; + case cmTarget::EXECUTABLE: + linkCmdVar += "_LINK_EXECUTABLE"; + break; + default: + assert(0 && "Unexpected target type"); + } + + const char *linkCmd = + this->GetMakefile()->GetRequiredDefinition(linkCmdVar.c_str()); + cmSystemTools::ExpandListArgument(linkCmd, linkCmds); + return linkCmds; + } + default: + assert(0 && "Unexpected target type"); + } + return std::vector<std::string>(); +} + +void cmNinjaNormalTargetGenerator::WriteLinkStatement() +{ + cmTarget::TargetType targetType = this->GetTarget()->GetType(); + + // Write comments. + cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); + this->GetBuildFileStream() + << "# Link build statements for " + << cmTarget::GetTargetTypeName(targetType) + << " target " + << this->GetTargetName() + << "\n\n"; + + cmNinjaDeps emptyDeps; + cmNinjaVars vars; + + std::string targetOutput = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName()).c_str()); + std::string targetOutputReal = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/false, + /*realpath=*/true).c_str()); + std::string targetOutputImplib = ConvertToNinjaPath( + this->GetTarget()->GetFullPath(this->GetConfigName(), + /*implib=*/true).c_str()); + + // Compute the comment. + std::ostringstream comment; + comment << "Link the " << this->GetVisibleTypeName() << " " + << targetOutputReal; + + // Compute outputs. + cmNinjaDeps outputs; + outputs.push_back(targetOutputReal); + + // Compute specific libraries to link with. + cmNinjaDeps explicitDeps = this->GetObjects(), + implicitDeps = this->ComputeLinkDeps(); + + this->GetLocalGenerator()->GetTargetFlags(vars["LINK_LIBRARIES"], + vars["FLAGS"], + vars["LINK_FLAGS"], + *this->GetTarget()); + + this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); + + // Compute architecture specific link flags. Yes, these go into a different + // variable for executables, probably due to a mistake made when duplicating + // code between the Makefile executable and library generators. + this->GetLocalGenerator() + ->AddArchitectureFlags(targetType == cmTarget::EXECUTABLE + ? vars["FLAGS"] + : vars["ARCH_FLAGS"], + this->GetTarget(), + this->TargetLinkLanguage, + this->GetConfigName()); + vars["SONAME"] = this->TargetNameSO; + + if (targetType == cmTarget::SHARED_LIBRARY) { + std::string install_name_dir = + this->GetTarget()->GetInstallNameDirForBuildTree(this->GetConfigName()); + + if (!install_name_dir.empty()) { + vars["INSTALLNAME_DIR"] = + this->GetLocalGenerator()->Convert(install_name_dir.c_str(), + cmLocalGenerator::NONE, + cmLocalGenerator::SHELL, false); + } + } + + if (!this->TargetNameImport.empty()) { + vars["TARGET_IMPLIB"] = this->GetLocalGenerator()->ConvertToOutputFormat( + targetOutputImplib.c_str(), cmLocalGenerator::SHELL); + } + + vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( + this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL); + + std::vector<cmCustomCommand> *cmdLists[3] = { + &this->GetTarget()->GetPreBuildCommands(), + &this->GetTarget()->GetPreLinkCommands(), + &this->GetTarget()->GetPostBuildCommands() + }; + + std::vector<std::string> preLinkCmdLines, postBuildCmdLines; + std::vector<std::string> *cmdLineLists[3] = { + &preLinkCmdLines, + &preLinkCmdLines, + &postBuildCmdLines + }; + + for (unsigned i = 0; i != 3; ++i) { + for (std::vector<cmCustomCommand>::const_iterator + ci = cmdLists[i]->begin(); + ci != cmdLists[i]->end(); ++ci) { + this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, + *cmdLineLists[i]); + } + } + + // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for + // the link commands. + if (!preLinkCmdLines.empty()) { + std::string path = this->GetLocalGenerator()->ConvertToOutputFormat( + this->GetMakefile()->GetHomeOutputDirectory(), + cmLocalGenerator::SHELL); + preLinkCmdLines.push_back("cd " + path); + } + + vars["PRE_LINK"] = + this->GetLocalGenerator()->BuildCommandLine(preLinkCmdLines); + std::string postBuildCmdLine = + this->GetLocalGenerator()->BuildCommandLine(postBuildCmdLines); + + cmNinjaVars symlinkVars; + if (targetOutput == targetOutputReal) { + vars["POST_BUILD"] = postBuildCmdLine; + } else { + vars["POST_BUILD"] = ":"; + symlinkVars["POST_BUILD"] = postBuildCmdLine; + } + + // Write the build statement for this target. + cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), + comment.str(), + this->LanguageLinkerRule(), + outputs, + explicitDeps, + implicitDeps, + emptyDeps, + vars); + + if (targetOutput != targetOutputReal) { + if (targetType == cmTarget::EXECUTABLE) { + cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), + "Create executable symlink " + targetOutput, + "CMAKE_SYMLINK_EXECUTABLE", + cmNinjaDeps(1, targetOutput), + cmNinjaDeps(1, targetOutputReal), + emptyDeps, + emptyDeps, + symlinkVars); + } else { + symlinkVars["SONAME"] = this->GetTargetFilePath(this->TargetNameSO); + cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), + "Create library symlink " + targetOutput, + "CMAKE_SYMLINK_LIBRARY", + cmNinjaDeps(1, targetOutput), + cmNinjaDeps(1, targetOutputReal), + emptyDeps, + emptyDeps, + symlinkVars); + } + } + + if (!this->TargetNameImport.empty()) { + // Since using multiple outputs would mess up the $out variable, use an + // alias for the import library. + cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), + "Alias for import library.", + cmNinjaDeps(1, targetOutputImplib), + cmNinjaDeps(1, targetOutputReal)); + } + + // Add aliases for the file name and the target name. + this->GetGlobalGenerator()->AddTargetAlias(this->TargetNameOut, + this->GetTarget()); + this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), + this->GetTarget()); +} diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h new file mode 100644 index 0000000..99f5a13 --- /dev/null +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -0,0 +1,47 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmNinjaNormalTargetGenerator_h +# define cmNinjaNormalTargetGenerator_h + +# include "cmNinjaTargetGenerator.h" +# include "cmNinjaTypes.h" + +class cmSourceFile; + +class cmNinjaNormalTargetGenerator : public cmNinjaTargetGenerator +{ +public: + cmNinjaNormalTargetGenerator(cmTarget* target); + ~cmNinjaNormalTargetGenerator(); + + void Generate(); + +private: + std::string LanguageLinkerRule() const; + const char* GetVisibleTypeName() const; + void WriteLanguagesRules(); + void WriteLinkRule(); + void WriteLinkStatement(); + std::vector<std::string> ComputeLinkCmd(); + +private: + // Target name info. + std::string TargetNameOut; + std::string TargetNameSO; + std::string TargetNameReal; + std::string TargetNameImport; + std::string TargetNamePDB; + const char *TargetLinkLanguage; +}; + +#endif // ! cmNinjaNormalTargetGenerator_h diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx new file mode 100644 index 0000000..3f7c925 --- /dev/null +++ b/Source/cmNinjaTargetGenerator.cxx @@ -0,0 +1,505 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmNinjaTargetGenerator.h" +#include "cmGlobalNinjaGenerator.h" +#include "cmLocalNinjaGenerator.h" +#include "cmGeneratedFileStream.h" +#include "cmGeneratorTarget.h" +#include "cmNinjaNormalTargetGenerator.h" +#include "cmNinjaUtilityTargetGenerator.h" +#include "cmSystemTools.h" +#include "cmMakefile.h" +#include "cmComputeLinkInformation.h" +#include "cmSourceFile.h" +#include "cmCustomCommandGenerator.h" + +#include <algorithm> + +cmNinjaTargetGenerator * +cmNinjaTargetGenerator::New(cmTarget* target) +{ + switch (target->GetType()) + { + case cmTarget::EXECUTABLE: + case cmTarget::SHARED_LIBRARY: + case cmTarget::STATIC_LIBRARY: + case cmTarget::MODULE_LIBRARY: + return new cmNinjaNormalTargetGenerator(target); + + case cmTarget::UTILITY: + return new cmNinjaUtilityTargetGenerator(target);; + + case cmTarget::GLOBAL_TARGET: { + // We only want to process global targets that live in the home + // (i.e. top-level) directory. CMake creates copies of these targets + // in every directory, which we don't need. + cmMakefile *mf = target->GetMakefile(); + if (strcmp(mf->GetStartDirectory(), mf->GetHomeDirectory()) == 0) + return new cmNinjaUtilityTargetGenerator(target); + // else fallthrough + } + + default: + return 0; + } +} + +cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) + : Target(target), + Makefile(target->GetMakefile()), + LocalGenerator( + static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())), + Objects() +{ + this->GeneratorTarget = + this->GetGlobalGenerator()->GetGeneratorTarget(target); +} + +cmNinjaTargetGenerator::~cmNinjaTargetGenerator() +{ +} + +cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const +{ + return *this->GetGlobalGenerator()->GetBuildFileStream(); +} + +cmGeneratedFileStream& cmNinjaTargetGenerator::GetRulesFileStream() const +{ + return *this->GetGlobalGenerator()->GetRulesFileStream(); +} + +cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const +{ + return this->LocalGenerator->GetGlobalNinjaGenerator(); +} + +const char* cmNinjaTargetGenerator::GetConfigName() const +{ + return this->LocalGenerator->ConfigName.c_str(); +} + +// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. +const char* cmNinjaTargetGenerator::GetFeature(const char* feature) +{ + return this->Target->GetFeature(feature, this->GetConfigName()); +} + +// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. +bool cmNinjaTargetGenerator::GetFeatureAsBool(const char* feature) +{ + return cmSystemTools::IsOn(this->GetFeature(feature)); +} + +// TODO: Picked up from cmMakefileTargetGenerator. Refactor it. +void cmNinjaTargetGenerator::AddFeatureFlags(std::string& flags, + const char* lang) +{ + // Add language-specific flags. + this->LocalGenerator->AddLanguageFlags(flags, lang, this->GetConfigName()); + + if(this->GetFeatureAsBool("INTERPROCEDURAL_OPTIMIZATION")) + { + this->LocalGenerator->AppendFeatureOptions(flags, lang, "IPO"); + } +} + +// TODO: Most of the code is picked up from +// void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink), +// void cmMakefileTargetGenerator::WriteTargetLanguageFlags() +// Refactor it. +std::string +cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, + const std::string& language) +{ + std::string flags; + + this->AddFeatureFlags(flags, language.c_str()); + + this->GetLocalGenerator()->AddArchitectureFlags(flags, + this->GetTarget(), + language.c_str(), + this->GetConfigName()); + + // TODO: Fortran support. + // // Fortran-specific flags computed for this target. + // if(*l == "Fortran") + // { + // this->AddFortranFlags(flags); + // } + + // Add shared-library flags if needed. + { + bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) || + (this->Target->GetType() == cmTarget::MODULE_LIBRARY)); + this->GetLocalGenerator()->AddSharedFlags(flags, language.c_str(), shared); + } + + // TODO: Handle response file. + // Add include directory flags. + { + std::vector<std::string> includes; + this->LocalGenerator->GetIncludeDirectories(includes, this->Target, + language.c_str()); + std::string includeFlags = + this->LocalGenerator->GetIncludeFlags(includes, language.c_str(), false); + this->LocalGenerator->AppendFlags(flags, includeFlags.c_str()); + } + + // Append old-style preprocessor definition flags. + this->LocalGenerator->AppendFlags(flags, this->Makefile->GetDefineFlags()); + + // Add target-specific and source-specific flags. + this->LocalGenerator->AppendFlags(flags, + this->Target->GetProperty("COMPILE_FLAGS")); + this->LocalGenerator->AppendFlags(flags, + source->GetProperty("COMPILE_FLAGS")); + + // TODO: Handle Apple frameworks. + + return flags; +} + +// TODO: Refactor with +// void cmMakefileTargetGenerator::WriteTargetLanguageFlags(). +std::string +cmNinjaTargetGenerator:: +ComputeDefines(cmSourceFile *source, const std::string& language) +{ + std::string defines; + + // Add the export symbol definition for shared library objects. + if(const char* exportMacro = this->Target->GetExportMacro()) + { + this->LocalGenerator->AppendDefines(defines, exportMacro, + language.c_str()); + } + + // Add preprocessor definitions for this target and configuration. + this->LocalGenerator->AppendDefines + (defines, + this->Makefile->GetProperty("COMPILE_DEFINITIONS"), + language.c_str()); + this->LocalGenerator->AppendDefines + (defines, + this->Target->GetProperty("COMPILE_DEFINITIONS"), + language.c_str()); + this->LocalGenerator->AppendDefines + (defines, + source->GetProperty("COMPILE_DEFINITIONS"), + language.c_str()); + { + std::string defPropName = "COMPILE_DEFINITIONS_"; + defPropName += cmSystemTools::UpperCase(this->GetConfigName()); + this->LocalGenerator->AppendDefines + (defines, + this->Makefile->GetProperty(defPropName.c_str()), + language.c_str()); + this->LocalGenerator->AppendDefines + (defines, + this->Target->GetProperty(defPropName.c_str()), + language.c_str()); + this->LocalGenerator->AppendDefines + (defines, + source->GetProperty(defPropName.c_str()), + language.c_str()); + } + + return defines; +} + +cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const +{ + // Static libraries never depend on other targets for linking. + if (this->Target->GetType() == cmTarget::STATIC_LIBRARY) + return cmNinjaDeps(); + + cmComputeLinkInformation* cli = + this->Target->GetLinkInformation(this->GetConfigName()); + if(!cli) + return cmNinjaDeps(); + + const std::vector<std::string> &deps = cli->GetDepends(); + cmNinjaDeps result(deps.size()); + std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath()); + + // Add a dependency on the link definitions file, if any. + if(!this->ModuleDefinitionFile.empty()) + { + result.push_back(this->ModuleDefinitionFile); + } + + return result; +} + +std::string +cmNinjaTargetGenerator +::GetSourceFilePath(cmSourceFile* source) const +{ + return ConvertToNinjaPath(source->GetFullPath().c_str()); +} + +std::string +cmNinjaTargetGenerator +::GetObjectFilePath(cmSourceFile* source) const +{ + std::string path = this->LocalGenerator->GetHomeRelativeOutputPath(); + if(!path.empty()) + path += "/"; + path += this->LocalGenerator->GetObjectFileName(*this->Target, *source); + return path; +} + +std::string cmNinjaTargetGenerator::GetTargetOutputDir() const +{ + std::string dir = this->Target->GetDirectory(this->GetConfigName()); + return ConvertToNinjaPath(dir.c_str()); +} + +std::string +cmNinjaTargetGenerator +::GetTargetFilePath(const std::string& name) const +{ + std::string path = this->GetTargetOutputDir(); + if (path.empty() || path == ".") + return name; + path += "/"; + path += name; + return path; +} + +std::string cmNinjaTargetGenerator::GetTargetName() const +{ + return this->Target->GetName(); +} + +std::string cmNinjaTargetGenerator::GetTargetPDB() const +{ + std::string targetFullPathPDB; + if(this->Target->GetType() == cmTarget::EXECUTABLE || + this->Target->GetType() == cmTarget::STATIC_LIBRARY || + this->Target->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->GetType() == cmTarget::MODULE_LIBRARY) + { + targetFullPathPDB = this->Target->GetDirectory(this->GetConfigName()); + targetFullPathPDB += "/"; + targetFullPathPDB += this->Target->GetPDBName(this->GetConfigName()); + } + + return ConvertToNinjaPath(targetFullPathPDB.c_str()); +} + + +void +cmNinjaTargetGenerator +::WriteLanguageRules(const std::string& language) +{ + this->GetRulesFileStream() + << "# Rules for language " << language << "\n\n"; + this->WriteCompileRule(language); + this->GetRulesFileStream() << "\n"; +} + +void +cmNinjaTargetGenerator +::WriteCompileRule(const std::string& language) +{ + cmLocalGenerator::RuleVariables vars; + vars.RuleLauncher = "RULE_LAUNCH_COMPILE"; + vars.CMTarget = this->GetTarget(); + std::string lang = language; + vars.Language = lang.c_str(); + vars.Source = "$in"; + vars.Object = "$out"; + std::string flags = "$FLAGS"; + vars.Defines = "$DEFINES"; + vars.TargetPDB = "$TARGET_PDB"; + + std::string depfile; + std::string depfileFlagsName = "CMAKE_DEPFILE_FLAGS_" + language; + const char *depfileFlags = + this->GetMakefile()->GetDefinition(depfileFlagsName.c_str()); + if (depfileFlags) { + std::string depfileFlagsStr = depfileFlags; + depfile = "$out.d"; + cmSystemTools::ReplaceString(depfileFlagsStr, "<DEPFILE>", + depfile.c_str()); + flags += " " + depfileFlagsStr; + } + vars.Flags = flags.c_str(); + + + // Rule for compiling object file. + std::string compileCmdVar = "CMAKE_"; + compileCmdVar += language; + compileCmdVar += "_COMPILE_OBJECT"; + std::string compileCmd = + this->GetMakefile()->GetRequiredDefinition(compileCmdVar.c_str()); + std::vector<std::string> compileCmds; + cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + + for (std::vector<std::string>::iterator i = compileCmds.begin(); + i != compileCmds.end(); ++i) + this->GetLocalGenerator()->ExpandRuleVariables(*i, vars); + + std::string cmdLine = + this->GetLocalGenerator()->BuildCommandLine(compileCmds); + + // Write the rule for compiling file of the given language. + std::ostringstream comment; + comment << "Rule for compiling " << language << " files."; + std::ostringstream description; + description << "Building " << language << " object $out"; + this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(language), + cmdLine, + description.str(), + comment.str(), + depfile); +} + +void +cmNinjaTargetGenerator +::WriteObjectBuildStatements() +{ + // Write comments. + cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); + this->GetBuildFileStream() + << "# Object build statements for " + << cmTarget::GetTargetTypeName(this->GetTarget()->GetType()) + << " target " + << this->GetTargetName() + << "\n\n"; + + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->CustomCommands.begin(); + si != this->GeneratorTarget->CustomCommands.end(); ++si) + { + cmCustomCommand const* cc = (*si)->GetCustomCommand(); + this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); + } + // TODO: this->GeneratorTarget->OSXContent + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ExternalObjects.begin(); + si != this->GeneratorTarget->ExternalObjects.end(); ++si) + { + this->Objects.push_back(this->GetSourceFilePath(*si)); + } + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->ObjectSources.begin(); + si != this->GeneratorTarget->ObjectSources.end(); ++si) + { + this->WriteObjectBuildStatement(*si); + } + if(!this->GeneratorTarget->ModuleDefinitionFile.empty()) + { + this->ModuleDefinitionFile = this->ConvertToNinjaPath( + this->GeneratorTarget->ModuleDefinitionFile.c_str()); + } + + this->GetBuildFileStream() << "\n"; +} + +void +cmNinjaTargetGenerator +::WriteObjectBuildStatement(cmSourceFile* source) +{ + cmNinjaDeps emptyDeps; + + std::string comment; + const char* language = source->GetLanguage(); + std::string rule = this->LanguageCompilerRule(language); + + cmNinjaDeps outputs; + std::string objectFileName = this->GetObjectFilePath(source); + outputs.push_back(objectFileName); + // Add this object to the list of object files. + this->Objects.push_back(objectFileName); + + cmNinjaDeps explicitDeps; + std::string sourceFileName = this->GetSourceFilePath(source); + explicitDeps.push_back(sourceFileName); + + // Ensure that the target dependencies are built before any source file in + // the target, using order-only dependencies. + cmNinjaDeps orderOnlyDeps; + this->GetLocalGenerator()->AppendTargetDepends(this->Target, orderOnlyDeps); + + if(const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) { + std::vector<std::string> depList; + cmSystemTools::ExpandListArgument(objectDeps, depList); + std::transform(depList.begin(), depList.end(), + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + } + + // Add order-only dependencies on custom command outputs. + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->CustomCommands.begin(); + si != this->GeneratorTarget->CustomCommands.end(); ++si) + { + cmCustomCommand const* cc = (*si)->GetCustomCommand(); + const std::vector<std::string>& ccoutputs = cc->GetOutputs(); + std::transform(ccoutputs.begin(), ccoutputs.end(), + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + } + + // If the source file is GENERATED and does not have a custom command + // (either attached to this source file or another one), assume that one of + // the target dependencies, OBJECT_DEPENDS or header file custom commands + // will rebuild the file. + if (source->GetPropertyAsBool("GENERATED") && !source->GetCustomCommand() && + !this->GetGlobalGenerator()->HasCustomCommandOutput(sourceFileName)) { + this->GetGlobalGenerator()->AddAssumedSourceDependencies(sourceFileName, + orderOnlyDeps); + } + + cmNinjaVars vars; + vars["FLAGS"] = this->ComputeFlagsForObject(source, language); + vars["DEFINES"] = this->ComputeDefines(source, language); + vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( + this->GetTargetPDB().c_str(), cmLocalGenerator::SHELL); + + cmGlobalNinjaGenerator::WriteBuild(this->GetBuildFileStream(), + comment, + rule, + outputs, + explicitDeps, + emptyDeps, + orderOnlyDeps, + vars); +} + +//---------------------------------------------------------------------------- +void +cmNinjaTargetGenerator +::AddModuleDefinitionFlag(std::string& flags) +{ + if(this->ModuleDefinitionFile.empty()) + { + return; + } + + // TODO: Create a per-language flag variable. + const char* defFileFlag = + this->Makefile->GetDefinition("CMAKE_LINK_DEF_FILE_FLAG"); + if(!defFileFlag) + { + return; + } + + // Append the flag and value. Use ConvertToLinkReference to help + // vs6's "cl -link" pass it to the linker. + std::string flag = defFileFlag; + flag += (this->LocalGenerator->ConvertToLinkReference( + this->ModuleDefinitionFile.c_str())); + this->LocalGenerator->AppendFlags(flags, flag.c_str()); +} diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h new file mode 100644 index 0000000..b64ce1e --- /dev/null +++ b/Source/cmNinjaTargetGenerator.h @@ -0,0 +1,126 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmNinjaTargetGenerator_h +#define cmNinjaTargetGenerator_h + +#include "cmStandardIncludes.h" +#include "cmNinjaTypes.h" +#include "cmLocalNinjaGenerator.h" + +class cmTarget; +class cmGlobalNinjaGenerator; +class cmGeneratedFileStream; +class cmGeneratorTarget; +class cmMakefile; +class cmSourceFile; +class cmCustomCommand; + +class cmNinjaTargetGenerator +{ +public: + /// Create a cmNinjaTargetGenerator according to the @a target's type. + static cmNinjaTargetGenerator* New(cmTarget* target); + + /// Build a NinjaTargetGenerator. + cmNinjaTargetGenerator(cmTarget* target); + + /// Destructor. + virtual ~cmNinjaTargetGenerator(); + + virtual void Generate() = 0; + + std::string GetTargetPDB() const; + std::string GetTargetName() const; + +protected: + cmGeneratedFileStream& GetBuildFileStream() const; + cmGeneratedFileStream& GetRulesFileStream() const; + + cmTarget* GetTarget() const + { return this->Target; } + + cmLocalNinjaGenerator* GetLocalGenerator() const + { return this->LocalGenerator; } + + cmGlobalNinjaGenerator* GetGlobalGenerator() const; + + cmMakefile* GetMakefile() const + { return this->Makefile; } + + const char* GetConfigName() const; + + std::string LanguageCompilerRule(const std::string& lang) const + { return lang + "_COMPILER"; } + + const char* GetFeature(const char* feature); + bool GetFeatureAsBool(const char* feature); + void AddFeatureFlags(std::string& flags, const char* lang); + + /** + * Compute the flags for compilation of object files for a given @a language. + * @note Generally it is the value of the variable whose name is computed + * by LanguageFlagsVarName(). + */ + std::string ComputeFlagsForObject(cmSourceFile *source, + const std::string& language); + + std::string ComputeDefines(cmSourceFile *source, + const std::string& language); + + std::string ConvertToNinjaPath(const char *path) const { + return this->GetLocalGenerator()->ConvertToNinjaPath(path); + } + cmLocalNinjaGenerator::map_to_ninja_path MapToNinjaPath() const { + return this->GetLocalGenerator()->MapToNinjaPath(); + } + + /// @return the list of link dependency for the given target @a target. + cmNinjaDeps ComputeLinkDeps() const; + + /// @return the source file path for the given @a source. + std::string GetSourceFilePath(cmSourceFile* source) const; + + /// @return the object file path for the given @a source. + std::string GetObjectFilePath(cmSourceFile* source) const; + + /// @return the file path where the target named @a name is generated. + std::string GetTargetFilePath(const std::string& name) const; + + /// @return the output path for the target. + virtual std::string GetTargetOutputDir() const; + + void WriteLanguageRules(const std::string& language); + void WriteCompileRule(const std::string& language); + void WriteObjectBuildStatements(); + void WriteObjectBuildStatement(cmSourceFile* source); + void WriteCustomCommandBuildStatement(cmCustomCommand *cc); + + cmNinjaDeps GetObjects() const + { return this->Objects; } + + // Helper to add flag for windows .def file. + void AddModuleDefinitionFlag(std::string& flags); + +private: + cmTarget* Target; + cmGeneratorTarget* GeneratorTarget; + cmMakefile* Makefile; + cmLocalNinjaGenerator* LocalGenerator; + /// List of object files for this target. + cmNinjaDeps Objects; + + // The windows module definition source file (.def), if any. + std::string ModuleDefinitionFile; +}; + +#endif // ! cmNinjaTargetGenerator_h diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h new file mode 100644 index 0000000..498f6b6 --- /dev/null +++ b/Source/cmNinjaTypes.h @@ -0,0 +1,19 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmNinjaTypes_h +# define cmNinjaTypes_h + +typedef std::vector<std::string> cmNinjaDeps; +typedef std::map<std::string, std::string> cmNinjaVars; + +#endif // ! cmNinjaTypes_h diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx new file mode 100644 index 0000000..8eeca77 --- /dev/null +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -0,0 +1,108 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmNinjaUtilityTargetGenerator.h" +#include "cmCustomCommand.h" +#include "cmGeneratedFileStream.h" +#include "cmGlobalNinjaGenerator.h" +#include "cmMakefile.h" +#include "cmSourceFile.h" +#include "cmTarget.h" + +cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(cmTarget *target) + : cmNinjaTargetGenerator(target) {} + +cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {} + +void cmNinjaUtilityTargetGenerator::Generate() +{ + std::vector<std::string> commands; + cmNinjaDeps deps, outputs; + + const std::vector<cmCustomCommand> *cmdLists[2] = { + &this->GetTarget()->GetPreBuildCommands(), + &this->GetTarget()->GetPostBuildCommands() + }; + + for (unsigned i = 0; i != 2; ++i) { + for (std::vector<cmCustomCommand>::const_iterator + ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) { + this->GetLocalGenerator()->AppendCustomCommandDeps(&*ci, deps); + this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, commands); + } + } + + const std::vector<cmSourceFile*>& sources = + this->GetTarget()->GetSourceFiles(); + for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); + source != sources.end(); ++source) + { + if(cmCustomCommand* cc = (*source)->GetCustomCommand()) + { + this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); + + // Depend on all custom command outputs. + const std::vector<std::string>& ccOutputs = cc->GetOutputs(); + std::transform(ccOutputs.begin(), ccOutputs.end(), + std::back_inserter(deps), MapToNinjaPath()); + } + } + + this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs); + this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), deps); + + if (commands.empty()) { + cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), + "Utility command for " + + this->GetTargetName(), + outputs, + deps); + } else { + std::string command = + this->GetLocalGenerator()->BuildCommandLine(commands); + const char *echoStr = this->GetTarget()->GetProperty("EchoString"); + std::string desc; + if (echoStr) + desc = echoStr; + else + desc = "Running utility command for " + this->GetTargetName(); + + // TODO: fix problematic global targets. For now, search and replace the + // makefile vars. + cmSystemTools::ReplaceString(command, "$(CMAKE_SOURCE_DIR)", + this->GetTarget()->GetMakefile()->GetHomeDirectory()); + cmSystemTools::ReplaceString(command, "$(CMAKE_BINARY_DIR)", + this->GetTarget()->GetMakefile()->GetHomeOutputDirectory()); + cmSystemTools::ReplaceString(command, "$(ARGS)", ""); + + if (command.find('$') != std::string::npos) + return; + + std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash(); + utilCommandName += this->GetTargetName() + ".util"; + + this->GetGlobalGenerator()->WriteCustomCommandBuild( + command, + desc, + "Utility command for " + this->GetTargetName(), + cmNinjaDeps(1, utilCommandName), + deps); + + cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(), + "", + outputs, + cmNinjaDeps(1, utilCommandName)); + } + + this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), + this->GetTarget()); +} diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h new file mode 100644 index 0000000..8b82ce4 --- /dev/null +++ b/Source/cmNinjaUtilityTargetGenerator.h @@ -0,0 +1,30 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2011 Peter Collingbourne <peter@pcc.me.uk> + Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmNinjaUtilityTargetGenerator_h +# define cmNinjaUtilityTargetGenerator_h + +# include "cmNinjaTargetGenerator.h" +# include "cmNinjaTypes.h" + +class cmSourceFile; + +class cmNinjaUtilityTargetGenerator : public cmNinjaTargetGenerator +{ +public: + cmNinjaUtilityTargetGenerator(cmTarget* target); + ~cmNinjaUtilityTargetGenerator(); + + void Generate(); +}; + +#endif // ! cmNinjaUtilityTargetGenerator_h diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h index fa5abd8..da31332 100644 --- a/Source/cmOptionCommand.h +++ b/Source/cmOptionCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "option";} + virtual const char* GetName() const {return "option";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Provides an option that the user can optionally select."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " option(<option_variable> \"help string describing option\"\n" @@ -68,7 +68,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } cmTypeMacro(cmOptionCommand, cmCommand); }; diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index 6038472..85d9095 100644 --- a/Source/cmOutputRequiredFilesCommand.h +++ b/Source/cmOutputRequiredFilesCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "output_required_files";} + virtual const char* GetName() const { return "output_required_files";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Approximate C preprocessor dependency scanning."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "This command exists only because ancient CMake versions provided it. " @@ -67,7 +67,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 2160f37..3106248 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -21,8 +21,9 @@ class cmPolicy; /** \class cmPolicies * \brief Handles changes in CMake behavior and policies * - * See the cmake wiki section on policies for an overview of this class's - * purpose + * See the cmake wiki section on + * <a href="http://www.cmake.org/Wiki/CMake/Policies">policies</a> + * for an overview of this class's purpose */ class cmPolicies { @@ -30,32 +31,46 @@ public: cmPolicies(); ~cmPolicies(); - enum PolicyStatus { OLD, WARN, NEW, REQUIRED_IF_USED, REQUIRED_ALWAYS }; + /// Status of a policy + enum PolicyStatus { + OLD, ///< Use old behavior + WARN, ///< Use old behavior but issue a warning + NEW, ///< Use new behavior + /// Issue an error if user doesn't set policy status to NEW and hits the + /// check + REQUIRED_IF_USED, + REQUIRED_ALWAYS ///< Issue an error unless user sets policy status to NEW. + }; static const char* PolicyStatusNames[]; + /// Policy identifiers enum PolicyID { - CMP0000, // Policy version specification - CMP0001, // Ignore old compatibility variable - CMP0002, // Target names must be unique - CMP0003, // Linking does not include extra -L paths - CMP0004, // Libraries linked may not have leading or trailing whitespace - CMP0005, // Definition value escaping - CMP0006, // BUNDLE install rules needed for MACOSX_BUNDLE targets - CMP0007, // list command handling of empty elements - CMP0008, // Full-path libraries must be a valid library file name - CMP0009, // GLOB_RECURSE should not follow symlinks by default - CMP0010, // Bad variable reference syntax is an error - CMP0011, // Strong policy scope for include and find_package - CMP0012, // Recognize numbers and boolean constants in if() - CMP0013, // Duplicate binary directories not allowed - CMP0014, // Input directories must have CMakeLists.txt - CMP0015, // link_directories() treats paths relative to source dir - CMP0016, // target_link_libraries() fails if only argument is not a target - CMP0017, // Prefer files in CMAKE_ROOT when including from CMAKE_ROOT - - // Always the last entry. Useful mostly to avoid adding a comma - // the last policy when adding a new one. + CMP0000, ///< Policy version specification + CMP0001, ///< Ignore old compatibility variable + CMP0002, ///< Target names must be unique + CMP0003, ///< Linking does not include extra -L paths + CMP0004, ///< Libraries linked may not have leading or trailing whitespace + CMP0005, ///< Definition value escaping + CMP0006, ///< BUNDLE install rules needed for MACOSX_BUNDLE targets + CMP0007, ///< list command handling of empty elements + CMP0008, ///< Full-path libraries must be a valid library file name + CMP0009, ///< GLOB_RECURSE should not follow symlinks by default + CMP0010, ///< Bad variable reference syntax is an error + CMP0011, ///< Strong policy scope for include and find_package + CMP0012, ///< Recognize numbers and boolean constants in if() + CMP0013, ///< Duplicate binary directories not allowed + CMP0014, ///< Input directories must have CMakeLists.txt + CMP0015, ///< link_directories() treats paths relative to source dir + /// target_link_libraries() fails if only argument is not a target + CMP0016, + CMP0017, ///< Prefer files in CMAKE_ROOT when including from CMAKE_ROOT + + /** \brief Always the last entry. + * + * Useful mostly to avoid adding a comma the last policy when adding a new + * one. + */ CMPCOUNT }; diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 6e3b6af..fcf0a49 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -77,6 +77,24 @@ bool cmProjectCommand languages.push_back("CXX"); } this->Makefile->EnableLanguage(languages, false); + std::string extraInclude = "CMAKE_PROJECT_" + args[0] + "_INCLUDE"; + const char* include = this->Makefile->GetDefinition(extraInclude.c_str()); + if(include) + { + std::string fullFilePath; + bool readit = + this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(), + include); + if(!readit && !cmSystemTools::GetFatalErrorOccured()) + { + std::string m = + "could not find file:\n" + " "; + m += include; + this->SetError(m.c_str()); + return false; + } + } return true; } diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h index fc2b7a2..4b051af 100644 --- a/Source/cmProjectCommand.h +++ b/Source/cmProjectCommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "project";} + virtual const char* GetName() const {return "project";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set a name for the entire project."; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " project(<projectname> [languageName1 languageName2 ... ] )\n" @@ -68,7 +68,10 @@ public: "By default C and CXX are enabled. E.g. if you do not have a " "C++ compiler, you can disable the check for it by explicitly listing " "the languages you want to support, e.g. C. By using the special " - "language \"NONE\" all checks for any language can be disabled."; + "language \"NONE\" all checks for any language can be disabled. " + "If a variable exists called CMAKE_PROJECT_<projectName>_INCLUDE_FILE, " + "the file pointed to by that variable will be included as the last step " + "of the project command."; } cmTypeMacro(cmProjectCommand, cmCommand); diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h index f68db87..16bd148 100644 --- a/Source/cmPropertyDefinition.h +++ b/Source/cmPropertyDefinition.h @@ -14,45 +14,56 @@ #include "cmProperty.h" -class cmPropertyDefinition +/** \class cmPropertyDefinition + * \brief Property meta-information + * + * This class contains the following meta-information about property: + * - Name; + * - Various documentation strings; + * - The scope of the property; + * - If the property is chained. + */ +class cmPropertyDefinition { public: - // Define this property + /// Define this property void DefineProperty(const char *name, cmProperty::ScopeType scope, const char *ShortDescription, const char *FullDescription, const char *DocumentationSection, bool chained); - // get the documentation string + /// Get the documentation string cmDocumentationEntry GetDocumentation() const; - // basic constructor + /// Default constructor cmPropertyDefinition() { this->Chained = false; }; - // is it chained? - bool IsChained() {return this->Chained; }; + /// Is the property chained? + bool IsChained() const { return this->Chained; }; - // Get the section if any + /// Get the section if any const std::string &GetDocumentationSection() const { return this->DocumentationSection; }; - - // get the scope + + /// Get the scope cmProperty::ScopeType GetScope() const { return this->Scope; }; - // get the docs + /// Get the documentation (short version) const std::string &GetShortDescription() const { - return this->ShortDescription; }; + return this->ShortDescription; }; + + /// Get the documentation (full version) const std::string &GetFullDescription() const { return this->FullDescription; }; - + protected: std::string Name; std::string ShortDescription; std::string FullDescription; std::string DocumentationSection; - cmProperty::ScopeType Scope; + cmProperty::ScopeType Scope; bool Chained; }; diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h index f972e10..0184927 100644 --- a/Source/cmQTWrapCPPCommand.h +++ b/Source/cmQTWrapCPPCommand.h @@ -45,12 +45,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "qt_wrap_cpp";} + virtual const char* GetName() const { return "qt_wrap_cpp";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Create Qt Wrappers."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " qt_wrap_cpp(resultingLibraryName DestName\n" diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h index 67e914f..744ae98 100644 --- a/Source/cmQTWrapUICommand.h +++ b/Source/cmQTWrapUICommand.h @@ -43,12 +43,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "qt_wrap_ui";} + virtual const char* GetName() const { return "qt_wrap_ui";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Create Qt user interfaces Wrappers."; } @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " qt_wrap_ui(resultingLibraryName HeadersDestName\n" diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h index bae2ee1..c62d58f 100644 --- a/Source/cmRemoveCommand.h +++ b/Source/cmRemoveCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "remove";} + virtual const char* GetName() const {return "remove";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the list(REMOVE_ITEM ) command instead."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " remove(VAR VALUE VALUE ...)\n" @@ -68,7 +68,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h index 519bc42..f0e906d 100644 --- a/Source/cmRemoveDefinitionsCommand.h +++ b/Source/cmRemoveDefinitionsCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "remove_definitions";} + virtual const char* GetName() const {return "remove_definitions";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Removes -D define flags added by add_definitions."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " remove_definitions(-DFOO -DBAR ...)\n" diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h index 3739e83..690ab79 100644 --- a/Source/cmReturnCommand.h +++ b/Source/cmReturnCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "return";} + virtual const char* GetName() const {return "return";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Return from a file, directory or function."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " return()\n" diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h index 736f066..6a51a92 100644 --- a/Source/cmSeparateArgumentsCommand.h +++ b/Source/cmSeparateArgumentsCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "separate_arguments";} + virtual const char* GetName() const {return "separate_arguments";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Parse space-separated arguments into a semicolon-separated list."; @@ -59,7 +59,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " separate_arguments(<var> <UNIX|WINDOWS>_COMMAND \"<args>\")\n" diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h index 2990d24..66b129e 100644 --- a/Source/cmSetCommand.h +++ b/Source/cmSetCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "set";} + virtual const char* GetName() const {return "set";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set a CMAKE variable to a given value."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set(<variable> <value>\n" diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h index 227571f..ee40158 100644 --- a/Source/cmSetDirectoryPropertiesCommand.h +++ b/Source/cmSetDirectoryPropertiesCommand.h @@ -32,17 +32,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "set_directory_properties";} + virtual const char* GetName() const { return "set_directory_properties";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set a property of the directory."; } @@ -58,7 +58,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set_directory_properties(PROPERTIES prop1 value1 prop2 value2)\n" diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index 3a0169e..830299d 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -34,12 +34,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "set_property";} + virtual const char* GetName() const { return "set_property";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set a named property in a given scope."; } @@ -47,7 +47,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set_property(<GLOBAL |\n" @@ -86,7 +86,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } cmTypeMacro(cmSetPropertyCommand, cmCommand); diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h index 392f168..2a67bc0 100644 --- a/Source/cmSetSourceFilesPropertiesCommand.h +++ b/Source/cmSetSourceFilesPropertiesCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "set_source_files_properties";} + virtual const char* GetName() const { return "set_source_files_properties";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Source files can have properties that affect how they are built."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set_source_files_properties([file1 [file2 [...]]]\n" diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index f001a11..1bc429c 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "set_target_properties";} + virtual const char* GetName() const { return "set_target_properties";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Targets can have properties that affect how they are built."; } @@ -52,7 +52,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set_target_properties(target1 target2 ...\n" diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h index fbc8ac1..10df17d 100644 --- a/Source/cmSetTestsPropertiesCommand.h +++ b/Source/cmSetTestsPropertiesCommand.h @@ -32,12 +32,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "set_tests_properties";} + virtual const char* GetName() const { return "set_tests_properties";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set a property of the tests."; } @@ -45,7 +45,7 @@ public: /** * Longer documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2" diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h index ac7f426..532710c 100644 --- a/Source/cmSiteNameCommand.h +++ b/Source/cmSiteNameCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "site_name";} + virtual const char* GetName() const {return "site_name";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Set the given variable to the name of the computer."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " site_name(variable)\n"; diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 19ae8fc..2b34f2b 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -120,12 +120,6 @@ const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const } //---------------------------------------------------------------------------- -std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() -{ - return this->SourceFiles; -} - -//---------------------------------------------------------------------------- void cmSourceGroup::AddChild(cmSourceGroup child) { this->Internal->GroupChildren.push_back(child); diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 71ccb51..641dcbd 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -100,7 +100,6 @@ public: * source group. */ const std::vector<const cmSourceFile*>& GetSourceFiles() const; - std::vector<const cmSourceFile*>& GetSourceFiles(); std::vector<cmSourceGroup> const& GetGroupChildren() const; private: diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h index 31508ce..6a29fc8 100644 --- a/Source/cmSourceGroupCommand.h +++ b/Source/cmSourceGroupCommand.h @@ -41,12 +41,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "source_group";} + virtual const char* GetName() const {return "source_group";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Define a grouping for sources in the makefile."; } @@ -54,7 +54,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " source_group(name [REGULAR_EXPRESSION regex] " diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 452f4a1..3e585a5 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -45,17 +45,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "string";} + virtual const char* GetName() const { return "string";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "String operations."; } @@ -63,7 +63,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " string(REGEX MATCH <regular_expression>\n" diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h index 3dad67d..eedbfff 100644 --- a/Source/cmSubdirCommand.h +++ b/Source/cmSubdirCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "subdirs";} + virtual const char* GetName() const { return "subdirs";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the add_subdirectory() command instead."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "Add a list of subdirectories to the build.\n" @@ -79,7 +79,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h index 347f97a..daf97cd 100644 --- a/Source/cmSubdirDependsCommand.h +++ b/Source/cmSubdirDependsCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "subdir_depends";} + virtual const char* GetName() const { return "subdir_depends";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Does nothing."; } @@ -55,7 +55,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " subdir_depends(subdir dep1 dep2 ...)\n" @@ -64,7 +64,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 02060ca..1376a48 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -131,6 +131,8 @@ void (*cmSystemTools::s_ErrorCallback)(const char*, const char*, void (*cmSystemTools::s_StdoutCallback)(const char*, int len, void*); void* cmSystemTools::s_ErrorCallbackClientData = 0; void* cmSystemTools::s_StdoutCallbackClientData = 0; +bool (*cmSystemTools::s_InterruptCallback)(void*); +void* cmSystemTools::s_InterruptCallbackClientData = 0; // replace replace with with as many times as it shows up in source. // write the result into source. @@ -196,6 +198,20 @@ std::string cmSystemTools::EscapeQuotes(const char* str) return result; } +std::string cmSystemTools::TrimWhitespace(const std::string& s) +{ + std::string::const_iterator start = s.begin(); + while(start != s.end() && *start == ' ') + ++start; + if (start == s.end()) + return ""; + + std::string::const_iterator stop = s.end()-1; + while(*stop == ' ') + --stop; + return std::string(start, stop+1); +} + void cmSystemTools::Error(const char* m1, const char* m2, const char* m3, const char* m4) { @@ -220,6 +236,20 @@ void cmSystemTools::Error(const char* m1, const char* m2, cmSystemTools::Message(message.c_str(),"Error"); } +void cmSystemTools::SetInterruptCallback(InterruptCallback f, void* clientData) +{ + s_InterruptCallback = f; + s_InterruptCallbackClientData = clientData; +} + +bool cmSystemTools::GetInterruptFlag() +{ + if(s_InterruptCallback) + { + return (*s_InterruptCallback)(s_InterruptCallbackClientData); + } + return false; +} void cmSystemTools::SetErrorCallback(ErrorCallback f, void* clientData) { diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 2137340..5f21de2 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -49,6 +49,11 @@ public: ///! Escape quotes in a string. static std::string EscapeQuotes(const char* str); + /** + * Returns a string that has whitespace removed from the start and the end. + */ + static std::string TrimWhitespace(const std::string& s); + typedef void (*ErrorCallback)(const char*, const char*, bool&, void*); /** * Set the function used by GUI's to display error messages @@ -78,6 +83,11 @@ public: ///! Send a string to stderr. Stdout callbacks will not be invoced. static void Stderr(const char* s, int length); + + typedef bool (*InterruptCallback)(void*); + static void SetInterruptCallback(InterruptCallback f, void* clientData=0); + static bool GetInterruptFlag(); + ///! Return true if there was an error at any point. static bool GetErrorOccuredFlag() { @@ -96,7 +106,7 @@ public: ///! Return true if there was an error at any point. static bool GetFatalErrorOccured() { - return cmSystemTools::s_FatalErrorOccured; + return cmSystemTools::s_FatalErrorOccured || GetInterruptFlag(); } ///! Set the error occured flag and fatal error back to false @@ -467,8 +477,10 @@ private: static bool s_DisableRunCommandOutput; static ErrorCallback s_ErrorCallback; static StdoutCallback s_StdoutCallback; + static InterruptCallback s_InterruptCallback; static void* s_ErrorCallbackClientData; static void* s_StdoutCallbackClientData; + static void* s_InterruptCallbackClientData; static std::string s_Windows9xComspecSubstitute; }; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1a68cee..9e86681 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -37,18 +37,14 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType) return "MODULE_LIBRARY"; case cmTarget::SHARED_LIBRARY: return "SHARED_LIBRARY"; + case cmTarget::OBJECT_LIBRARY: + return "OBJECT_LIBRARY"; case cmTarget::EXECUTABLE: return "EXECUTABLE"; case cmTarget::UTILITY: return "UTILITY"; case cmTarget::GLOBAL_TARGET: return "GLOBAL_TARGET"; - case cmTarget::INSTALL_FILES: - return "INSTALL_FILES"; - case cmTarget::INSTALL_PROGRAMS: - return "INSTALL_PROGRAMS"; - case cmTarget::INSTALL_DIRECTORY: - return "INSTALL_DIRECTORY"; case cmTarget::UNKNOWN_LIBRARY: return "UNKNOWN_LIBRARY"; } @@ -486,6 +482,26 @@ void cmTarget::DefineProperties(cmake *cm) "undefined behavior."); cm->DefineProperty + ("INCLUDE_DIRECTORIES", cmProperty::TARGET, + "List of preprocessor include file search directories.", + "This property specifies the list of directories given " + "so far to the include_directories command. " + "This property exists on directories and targets. " + "In addition to accepting values from the include_directories " + "command, values may be set directly on any directory or any " + "target using the set_property command. " + "A target gets its initial value for this property from the value " + "of the directory property. " + "A directory gets its initial value from its parent directory if " + "it has one. " + "Both directory and target property values are adjusted by calls " + "to the include_directories command." + "\n" + "The target property values are used by the generators to set " + "the include paths for the compiler. " + "See also the include_directories command."); + + cm->DefineProperty ("INSTALL_NAME_DIR", cmProperty::TARGET, "Mac OSX directory name for installed targets.", "INSTALL_NAME_DIR is a string specifying the " @@ -867,7 +883,9 @@ void cmTarget::DefineProperties(cmake *cm) "of of just main()." "This makes it a GUI executable instead of a console application. " "See the CMAKE_MFC_FLAG variable documentation to configure use " - "of MFC for WinMain executables."); + "of MFC for WinMain executables. " + "This property is initialized by the value of the variable " + "CMAKE_WIN32_EXECUTABLE if it is set when a target is created."); cm->DefineProperty ("MACOSX_BUNDLE", cmProperty::TARGET, @@ -877,7 +895,9 @@ void cmTarget::DefineProperties(cmake *cm) "This makes it a GUI executable that can be launched from " "the Finder. " "See the MACOSX_BUNDLE_INFO_PLIST target property for information " - "about creation of the Info.plist file for the application bundle."); + "about creation of the Info.plist file for the application bundle. " + "This property is initialized by the value of the variable " + "CMAKE_MACOSX_BUNDLE if it is set when a target is created."); cm->DefineProperty ("MACOSX_BUNDLE_INFO_PLIST", cmProperty::TARGET, @@ -1047,10 +1067,10 @@ void cmTarget::DefineProperties(cmake *cm) "Can be set to one or more UUIDs recognized by Visual Studio " "to indicate the type of project. This value is copied " "verbatim into the generated project file. Example for a " - "managed C++ unit testing project: \"" - "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};" - "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\". UUIDs are " - "semicolon-delimited."); + "managed C++ unit testing project:\n" + " {3AC096D0-A1C2-E12C-1390-A8335801FDAB};" + "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\n" + "UUIDs are semicolon-delimited."); cm->DefineProperty ("VS_GLOBAL_KEYWORD", cmProperty::TARGET, "Visual Studio project keyword.", @@ -1065,6 +1085,16 @@ void cmTarget::DefineProperties(cmake *cm) "generated Visual Studio project. For example, \"System;" "System.Windows.Forms\"."); cm->DefineProperty + ("VS_WINRT_EXTENSIONS", cmProperty::TARGET, + "Visual Studio project C++/CX language extensions for Windows Runtime", + "Can be set to enable C++/CX language extensions."); + cm->DefineProperty + ("VS_WINRT_REFERENCES", cmProperty::TARGET, + "Visual Studio project Windows Runtime Metadata references", + "Adds one or more semicolon-delimited WinRT references to a " + "generated Visual Studio project. For example, \"Windows;" + "Windows.UI.Core\"."); + cm->DefineProperty ("VS_GLOBAL_<variable>", cmProperty::TARGET, "Visual Studio project-specific global variable.", "Tell the Visual Studio generator to set the global variable " @@ -1073,17 +1103,6 @@ void cmTarget::DefineProperties(cmake *cm) "better if VS_GLOBAL_QtVersion is set to the version " "FindQt4.cmake found. For example, \"4.7.3\""); -#if 0 - cm->DefineProperty - ("OBJECT_FILES", cmProperty::TARGET, - "Used to get the resulting list of object files that make up a " - "target.", - "This can be used to put object files from one library " - "into another library. It is a read only property. It " - "converts the source list for the target into a list of full " - "paths to object names that will be produced by the target."); -#endif - #define CM_TARGET_FILE_TYPES_DOC \ "There are three kinds of target files that may be built: " \ "archive, library, and runtime. " \ @@ -1174,16 +1193,6 @@ void cmTarget::DefineProperties(cmake *cm) void cmTarget::SetType(TargetType type, const char* name) { this->Name = name; - if(type == cmTarget::INSTALL_FILES || - type == cmTarget::INSTALL_PROGRAMS || - type == cmTarget::INSTALL_DIRECTORY) - { - this->Makefile-> - IssueMessage(cmake::INTERNAL_ERROR, - "SetType called on cmTarget for INSTALL_FILES, " - "INSTALL_PROGRAMS, or INSTALL_DIRECTORY "); - return; - } // only add dependency information for library targets this->TargetTypeValue = type; if(this->TargetTypeValue >= STATIC_LIBRARY @@ -1230,6 +1239,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("AUTOMOC", 0); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); + this->SetPropertyDefault("WIN32_EXECUTABLE", 0); + this->SetPropertyDefault("MACOSX_BUNDLE", 0); // Collect the set of configuration types. std::vector<std::string> configNames; @@ -1269,6 +1280,11 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Save the backtrace of target construction. this->Makefile->GetBacktrace(this->Internal->Backtrace); + // Initialize the INCLUDE_DIRECTORIES property based on the current value + // of the same directory property: + this->SetProperty("INCLUDE_DIRECTORIES", + this->Makefile->GetProperty("INCLUDE_DIRECTORIES")); + // Record current policies for later use. this->PolicyStatusCMP0003 = this->Makefile->GetPolicyStatus(cmPolicies::CMP0003); @@ -2588,54 +2604,6 @@ const char *cmTarget::GetProperty(const char* prop) } //---------------------------------------------------------------------------- -void cmTarget::ComputeObjectFiles() -{ - if (this->IsImported()) - { - return; - } -#if 0 - std::vector<std::string> dirs; - this->Makefile->GetLocalGenerator()-> - GetTargetObjectFileDirectories(this, - dirs); - std::string objectFiles; - std::string objExtensionLookup1 = "CMAKE_"; - std::string objExtensionLookup2 = "_OUTPUT_EXTENSION"; - - for(std::vector<std::string>::iterator d = dirs.begin(); - d != dirs.end(); ++d) - { - for(std::vector<cmSourceFile*>::iterator s = this->SourceFiles.begin(); - s != this->SourceFiles.end(); ++s) - { - cmSourceFile* sf = *s; - if(const char* lang = sf->GetLanguage()) - { - std::string lookupObj = objExtensionLookup1 + lang; - lookupObj += objExtensionLookup2; - const char* obj = this->Makefile->GetDefinition(lookupObj.c_str()); - if(obj) - { - if(objectFiles.size()) - { - objectFiles += ";"; - } - std::string objFile = *d; - objFile += "/"; - objFile += this->Makefile->GetLocalGenerator()-> - GetSourceObjectName(*sf); - objFile += obj; - objectFiles += objFile; - } - } - } - } - this->SetProperty("OBJECT_FILES", objectFiles.c_str()); -#endif -} - -//---------------------------------------------------------------------------- const char *cmTarget::GetProperty(const char* prop, cmProperty::ScopeType scope) { @@ -3592,7 +3560,8 @@ bool cmTarget::HaveBuildTreeRPATH() bool cmTarget::HaveInstallTreeRPATH() { const char* install_rpath = this->GetProperty("INSTALL_RPATH"); - return install_rpath && *install_rpath; + return (install_rpath && *install_rpath) && + !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH"); } //---------------------------------------------------------------------------- @@ -3699,7 +3668,8 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, { std::string dir; - if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH")) + if(!this->Makefile->IsOn("CMAKE_SKIP_RPATH") && + !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH")) { const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR"); if(install_name_dir && *install_name_dir) @@ -4666,6 +4636,30 @@ cmTarget::GetLinkInformation(const char* config) } //---------------------------------------------------------------------------- +std::vector<std::string> cmTarget::GetIncludeDirectories() +{ + std::vector<std::string> includes; + const char *prop = this->GetProperty("INCLUDE_DIRECTORIES"); + if(prop) + { + cmSystemTools::ExpandListArgument(prop, includes); + } + + std::set<std::string> uniqueIncludes; + std::vector<std::string> orderedAndUniqueIncludes; + for(std::vector<std::string>::const_iterator + li = includes.begin(); li != includes.end(); ++li) + { + if(uniqueIncludes.insert(*li).second) + { + orderedAndUniqueIncludes.push_back(*li); + } + } + + return orderedAndUniqueIncludes; +} + +//---------------------------------------------------------------------------- cmTargetLinkInformationMap ::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 59f0184..e2502f0 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -59,8 +59,8 @@ class cmTarget public: cmTarget(); enum TargetType { EXECUTABLE, STATIC_LIBRARY, - SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET, - INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY, + SHARED_LIBRARY, MODULE_LIBRARY, + OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET, UNKNOWN_LIBRARY}; static const char* GetTargetTypeName(TargetType targetType); enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD }; @@ -404,9 +404,6 @@ public: // Define the properties static void DefineProperties(cmake *cm); - // Compute the OBJECT_FILES property only when requested - void ComputeObjectFiles(); - /** Get the macro to define when building sources in this target. If no macro should be defined null is returned. */ const char* GetExportMacro(); @@ -458,6 +455,9 @@ public: directory. */ bool UsesDefaultOutputDir(const char* config, bool implib); + /** Get the include directories for this target. */ + std::vector<std::string> GetIncludeDirectories(); + private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 36c4ca8..dbea1c3 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -84,6 +84,16 @@ bool cmTargetLinkLibrariesCommand return true; } + if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY) + { + cmOStringStream e; + e << "Object library target \"" << args[0] << "\" " + << "may not link to anything."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + // but we might not have any libs after variable expansion if(args.size() < 2) { diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h index 8df4ac0..be866c3 100644 --- a/Source/cmTargetLinkLibrariesCommand.h +++ b/Source/cmTargetLinkLibrariesCommand.h @@ -42,12 +42,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "target_link_libraries";} + virtual const char* GetName() const { return "target_link_libraries";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Link a target to given libraries."; @@ -56,7 +56,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " target_link_libraries(<target> [item1 [item2 [...]]]\n" diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h index 0d57633..68ec666 100644 --- a/Source/cmTryCompileCommand.h +++ b/Source/cmTryCompileCommand.h @@ -40,19 +40,19 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "try_compile";} + virtual const char* GetName() const { return "try_compile";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Try building some code."; } /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " try_compile(RESULT_VAR <bindir> <srcdir>\n" diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h index f86d863..06a9118 100644 --- a/Source/cmTryRunCommand.h +++ b/Source/cmTryRunCommand.h @@ -40,12 +40,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "try_run";} + virtual const char* GetName() const { return "try_run";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Try compiling and then running some code."; } @@ -53,7 +53,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " try_run(RUN_RESULT_VAR COMPILE_RESULT_VAR\n" diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h index 28f8cf4..9cf95d9 100644 --- a/Source/cmUnsetCommand.h +++ b/Source/cmUnsetCommand.h @@ -40,17 +40,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() {return "unset";} + virtual const char* GetName() const {return "unset";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Unset a variable, cache variable, or environment variable."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " unset(<variable> [CACHE])\n" diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h index fec2265..2f52960 100644 --- a/Source/cmUseMangledMesaCommand.h +++ b/Source/cmUseMangledMesaCommand.h @@ -45,12 +45,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "use_mangled_mesa";} + virtual const char* GetName() const { return "use_mangled_mesa";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Copy mesa headers for use in combination with system GL."; } @@ -58,7 +58,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " use_mangled_mesa(PATH_TO_MESA OUTPUT_DIRECTORY)\n" @@ -71,10 +71,10 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h index 6c23814..32afdda 100644 --- a/Source/cmUtilitySourceCommand.h +++ b/Source/cmUtilitySourceCommand.h @@ -44,12 +44,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "utility_source";} + virtual const char* GetName() const { return "utility_source";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Specify the source tree of a third-party utility."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " utility_source(cache_entry executable_name\n" @@ -76,7 +76,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h index f165f39..91c351e 100644 --- a/Source/cmVariableRequiresCommand.h +++ b/Source/cmVariableRequiresCommand.h @@ -39,12 +39,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "variable_requires";} + virtual const char* GetName() const { return "variable_requires";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the if() command instead."; } @@ -52,7 +52,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return "Assert satisfaction of an option's required variables.\n" @@ -70,7 +70,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h index e2fb934..cb80736 100644 --- a/Source/cmVariableWatchCommand.h +++ b/Source/cmVariableWatchCommand.h @@ -49,7 +49,7 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** This command does not really have a final pass but it needs to stay alive since it owns variable watch callback information. */ @@ -58,12 +58,12 @@ public: /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "variable_watch";} + virtual const char* GetName() const { return "variable_watch";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Watch the CMake variable for change."; } @@ -71,7 +71,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " variable_watch(<variable name> [<command to execute>])\n" diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 449adc1..db37dfc 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmVisualStudio10TargetGenerator.h" #include "cmGlobalVisualStudio10Generator.h" +#include "cmGeneratorTarget.h" #include "cmTarget.h" #include "cmComputeLinkInformation.h" #include "cmGeneratedFileStream.h" @@ -62,6 +63,7 @@ cmVisualStudio10TargetGenerator(cmTarget* target, { this->GlobalGenerator = gg; this->Target = target; + this->GeneratorTarget = gg->GetGeneratorTarget(target); this->Makefile = target->GetMakefile(); this->LocalGenerator = (cmLocalVisualStudio7Generator*) @@ -70,7 +72,6 @@ cmVisualStudio10TargetGenerator(cmTarget* target, this->GlobalGenerator->CreateGUID(this->Name.c_str()); this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str()); this->Platform = gg->GetPlatformName(); - this->ComputeObjectNames(); this->BuildFileStream = 0; } @@ -147,7 +148,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str()); this->Target->SetProperty("GENERATOR_FILE_NAME_EXT", ".vcxproj"); - if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY) + if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY) { if(!this->ComputeClOptions()) { @@ -255,6 +256,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteObjSources(); this->WriteCLSources(); this->WriteDotNetReferences(); + this->WriteWinRTReferences(); this->WriteProjectReferences(); this->WriteString( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\"" @@ -268,33 +270,49 @@ void cmVisualStudio10TargetGenerator::Generate() void cmVisualStudio10TargetGenerator::WriteDotNetReferences() { - const char* vsDotNetReferences - = this->Target->GetProperty("VS_DOTNET_REFERENCES"); - if(vsDotNetReferences) + std::vector<std::string> references; + if(const char* vsDotNetReferences = + this->Target->GetProperty("VS_DOTNET_REFERENCES")) + { + cmSystemTools::ExpandListArgument(vsDotNetReferences, references); + } + if(!references.empty()) { - std::string references(vsDotNetReferences); - std::string::size_type position = 0; - this->WriteString("<ItemGroup>\n", 1); - while(references.length() > 0) + for(std::vector<std::string>::iterator ri = references.begin(); + ri != references.end(); ++ri) { - if((position = references.find(";")) == std::string::npos) - { - position = references.length() + 1; - } - this->WriteString("<Reference Include=\"", 2); - (*this->BuildFileStream) << - cmVS10EscapeXML(references.substr(0, position)) << "\">\n"; + (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n"; this->WriteString("<CopyLocalSatelliteAssemblies>true" "</CopyLocalSatelliteAssemblies>\n", 3); this->WriteString("<ReferenceOutputAssembly>true" "</ReferenceOutputAssembly>\n", 3); this->WriteString("</Reference>\n", 2); - - references.erase(0, position + 1); } + this->WriteString("</ItemGroup>\n", 1); + } +} +void cmVisualStudio10TargetGenerator::WriteWinRTReferences() +{ + std::vector<std::string> references; + if(const char* vsWinRTReferences = + this->Target->GetProperty("VS_WINRT_REFERENCES")) + { + cmSystemTools::ExpandListArgument(vsWinRTReferences, references); + } + if(!references.empty()) + { + this->WriteString("<ItemGroup>\n", 1); + for(std::vector<std::string>::iterator ri = references.begin(); + ri != references.end(); ++ri) + { + this->WriteString("<Reference Include=\"", 2); + (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n"; + this->WriteString("<IsWinMDFile>true</IsWinMDFile>\n", 3); + this->WriteString("</Reference>\n", 2); + } this->WriteString("</ItemGroup>\n", 1); } } @@ -341,6 +359,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() case cmTarget::MODULE_LIBRARY: configType += "DynamicLibrary"; break; + case cmTarget::OBJECT_LIBRARY: case cmTarget::STATIC_LIBRARY: configType += "StaticLibrary"; break; @@ -371,11 +390,17 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() mfcLine += useOfMfcValue + "</UseOfMfc>\n"; this->WriteString(mfcLine.c_str(), 2); - if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY && - this->ClOptions[*i]->UsingUnicode()) + if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY && + this->ClOptions[*i]->UsingUnicode() || + this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2); } + else if (this->Target->GetType() <= cmTarget::MODULE_LIBRARY && + this->ClOptions[*i]->UsingSBCS()) + { + this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2); + } else { this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2); @@ -387,6 +412,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() pts += "</PlatformToolset>\n"; this->WriteString(pts.c_str(), 2); } + if(this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) + { + this->WriteString("<Immersive>true</Immersive>\n", 2); + } this->WriteString("</PropertyGroup>\n", 1); } } @@ -394,12 +423,11 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() void cmVisualStudio10TargetGenerator::WriteCustomCommands() { this->SourcesVisited.clear(); - std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator source = sources.begin(); - source != sources.end(); ++source) + for(std::vector<cmSourceFile*>::const_iterator + si = this->GeneratorTarget->CustomCommands.begin(); + si != this->GeneratorTarget->CustomCommands.end(); ++si) { - cmSourceFile* sf = *source; - this->WriteCustomCommand(sf); + this->WriteCustomCommand(*si); } } @@ -848,47 +876,17 @@ void cmVisualStudio10TargetGenerator::WriteCLSources() this->WriteString("</ItemGroup>\n", 1); } -void cmVisualStudio10TargetGenerator::ComputeObjectNames() -{ - // We may be modifying the source groups temporarily, so make a copy. - std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); - - // get the classes from the source lists then add them to the groups - std::vector<cmSourceFile*>const & classes = this->Target->GetSourceFiles(); - for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); - i != classes.end(); i++) - { - // Add the file to the list of sources. - std::string source = (*i)->GetFullPath(); - if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF") - { - this->ModuleDefinitionFile = (*i)->GetFullPath(); - } - cmSourceGroup& sourceGroup = - this->Makefile->FindSourceGroup(source.c_str(), sourceGroups); - sourceGroup.AssignSource(*i); - } - - // Compute which sources need unique object computation. - this->LocalGenerator->ComputeObjectNameRequirements(sourceGroups); -} - bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( cmSourceFile* source) { cmSourceFile& sf = *source; cmLocalVisualStudio7Generator* lg = this->LocalGenerator; - // Compute the maximum length full path to the intermediate - // files directory for any configuration. This is used to construct - // object file names that do not produce paths that are too long. - std::string dir_max; - lg->ComputeMaxDirectoryLength(dir_max, *this->Target); - std::string objectName; - if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end()) + if(this->GeneratorTarget->ExplicitObjectName.find(&sf) + != this->GeneratorTarget->ExplicitObjectName.end()) { - objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max); + objectName = this->GeneratorTarget->Objects[&sf]; } std::string flags; std::string defines; @@ -1009,20 +1007,29 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() } else { - std::string targetNameFull = - this->Target->GetFullName(config->c_str()); std::string intermediateDir = this->LocalGenerator-> GetTargetDirectory(*this->Target); intermediateDir += "/"; intermediateDir += *config; intermediateDir += "/"; + std::string outDir; + std::string targetNameFull; + if(ttype == cmTarget::OBJECT_LIBRARY) + { + outDir = intermediateDir; + targetNameFull = this->Target->GetName(); + targetNameFull += ".lib"; + } + else + { + outDir = this->Target->GetDirectory(config->c_str()) + "/"; + targetNameFull = this->Target->GetFullName(config->c_str()); + } this->ConvertToWindowsSlash(intermediateDir); - std::string outDir = this->Target->GetDirectory(config->c_str()); this->ConvertToWindowsSlash(outDir); this->WritePlatformConfigTag("OutDir", config->c_str(), 3); *this->BuildFileStream << outDir - << "\\" << "</OutDir>\n"; this->WritePlatformConfigTag("IntDir", config->c_str(), 3); @@ -1256,11 +1263,15 @@ void cmVisualStudio10TargetGenerator::WriteClOptions( *this->BuildFileStream << configName << "</AssemblerListingLocation>\n"; this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); - this->WriteString("<ProgramDataBaseFileName>", 3); - *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) - << "/" - << this->Target->GetPDBName(configName.c_str()) - << "</ProgramDataBaseFileName>\n"; + if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY) + { + // TODO: PDB for object library? + this->WriteString("<ProgramDataBaseFileName>", 3); + *this->BuildFileStream << this->Target->GetDirectory(configName.c_str()) + << "/" + << this->Target->GetPDBName(configName.c_str()) + << "</ProgramDataBaseFileName>\n"; + } this->WriteString("</ClCompile>\n", 2); } @@ -1492,10 +1503,10 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& linkOptions.AddFlag("ImportLibrary", imLib.c_str()); linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str()); linkOptions.Parse(flags.c_str()); - if(!this->ModuleDefinitionFile.empty()) + if(!this->GeneratorTarget->ModuleDefinitionFile.empty()) { linkOptions.AddFlag("ModuleDefinitionFile", - this->ModuleDefinitionFile.c_str()); + this->GeneratorTarget->ModuleDefinitionFile.c_str()); } linkOptions.RemoveFlag("GenerateManifest"); @@ -1564,14 +1575,14 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() static_cast<cmGlobalVisualStudio7Generator *> (this->GlobalGenerator)->GetConfigurations(); std::vector<std::string> includes; - this->LocalGenerator->GetIncludeDirectories(includes); + this->LocalGenerator->GetIncludeDirectories(includes, this->Target); for(std::vector<std::string>::iterator i = configs->begin(); i != configs->end(); ++i) { this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1); *this->BuildFileStream << "\n"; // output cl compile flags <ClCompile></ClCompile> - if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY) + if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY) { this->WriteClOptions(*i, includes); // output rc compile flags <ResourceCompile></ResourceCompile> diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 6702509..64fb124 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -15,6 +15,7 @@ class cmTarget; class cmMakefile; +class cmGeneratorTarget; class cmGeneratedFileStream; class cmGlobalVisualStudio10Generator; class cmSourceFile; @@ -48,6 +49,7 @@ private: void WriteProjectConfigurationValues(); void WriteCLSources(); void WriteDotNetReferences(); + void WriteWinRTReferences(); void WriteObjSources(); void WritePathAndIncrementalLinkOptions(); void WriteItemDefinitionGroups(); @@ -74,7 +76,6 @@ private: void WriteEvents(std::string const& configName); void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands, std::string const& configName); - void ComputeObjectNames(); void WriteGroupSources(const char* name, std::vector<cmSourceFile*> const& sources, std::vector<cmSourceGroup>& ); @@ -86,9 +87,9 @@ private: typedef cmVisualStudioGeneratorOptions Options; typedef std::map<cmStdString, Options*> OptionsMap; OptionsMap ClOptions; - std::string ModuleDefinitionFile; std::string PathToVcxproj; cmTarget* Target; + cmGeneratorTarget* GeneratorTarget; cmMakefile* Makefile; std::string Platform; std::string GUID; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 41230e7..9369af6 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -117,6 +117,20 @@ bool cmVisualStudioGeneratorOptions::UsingUnicode() } return false; } +//---------------------------------------------------------------------------- +bool cmVisualStudioGeneratorOptions::UsingSBCS() +{ + // Look for the a _SBCS definition. + for(std::vector<std::string>::const_iterator di = this->Defines.begin(); + di != this->Defines.end(); ++di) + { + if(*di == "_SBCS") + { + return true; + } + } + return false; +} //---------------------------------------------------------------------------- void cmVisualStudioGeneratorOptions::Parse(const char* flags) diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 51a1362..a1a55da 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -48,6 +48,7 @@ public: // Check for specific options. bool UsingUnicode(); + bool UsingSBCS(); bool IsDebug(); // Write options to output. diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 7eafda2..4000345 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -25,7 +25,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endwhile")) { // if this is the endwhile for this while loop then execute - if (!this->Depth) + if (!this->Depth) { // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> @@ -33,16 +33,16 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, if(!fb.get()) { return false; } std::string errorString; - + std::vector<std::string> expandedArguments; mf.ExpandArguments(this->Args, expandedArguments); cmake::MessageType messageType; - bool isTrue = + bool isTrue = cmIfCommand::IsTrue(expandedArguments,errorString, &mf, messageType); while (isTrue) - { + { if (errorString.size()) { std::string err = "had incorrect arguments: "; @@ -86,7 +86,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, } expandedArguments.clear(); mf.ExpandArguments(this->Args, expandedArguments); - isTrue = + isTrue = cmIfCommand::IsTrue(expandedArguments,errorString, &mf, messageType); } @@ -101,7 +101,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // record the command this->Functions.push_back(lff); - + // always return true return true; } @@ -123,7 +123,7 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& ) } bool cmWhileCommand -::InvokeInitialPass(const std::vector<cmListFileArgument>& args, +::InvokeInitialPass(const std::vector<cmListFileArgument>& args, cmExecutionStatus &) { if(args.size() < 1) @@ -131,12 +131,12 @@ bool cmWhileCommand this->SetError("called with incorrect number of arguments"); return false; } - + // create a function blocker cmWhileFunctionBlocker *f = new cmWhileFunctionBlocker(); f->Args = args; this->Makefile->AddFunctionBlocker(f); - + return true; } diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h index 04649a3..e111ae4 100644 --- a/Source/cmWhileCommand.h +++ b/Source/cmWhileCommand.h @@ -16,11 +16,6 @@ #include "cmFunctionBlocker.h" #include "cmListFileCache.h" -/** \class cmWhileFunctionBlocker - * \brief subclass of function blocker - * - * - */ class cmWhileFunctionBlocker : public cmFunctionBlocker { public: @@ -37,11 +32,7 @@ private: int Depth; }; -/** \class cmWhileCommand - * \brief starts a while loop - * - * cmWhileCommand starts a while loop - */ +/// \brief Starts a while loop class cmWhileCommand : public cmCommand { public: @@ -70,17 +61,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "while";} + virtual const char* GetName() const { return "while";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Evaluate a group of commands while a condition is true"; } @@ -88,7 +79,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " while(condition)\n" diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h index 97ec727..8808d32 100644 --- a/Source/cmWriteFileCommand.h +++ b/Source/cmWriteFileCommand.h @@ -39,17 +39,17 @@ public: /** * This determines if the command is invoked when in script mode. */ - virtual bool IsScriptable() { return true; } + virtual bool IsScriptable() const { return true; } /** * The name of the command as specified in CMakeList.txt. */ - virtual const char* GetName() { return "write_file";} + virtual const char* GetName() const { return "write_file";} /** * Succinct documentation. */ - virtual const char* GetTerseDocumentation() + virtual const char* GetTerseDocumentation() const { return "Deprecated. Use the file(WRITE ) command instead."; } @@ -57,7 +57,7 @@ public: /** * More documentation. */ - virtual const char* GetFullDocumentation() + virtual const char* GetFullDocumentation() const { return " write_file(filename \"message to write\"... [APPEND])\n" @@ -73,7 +73,7 @@ public: } /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() + virtual bool IsDiscouraged() const { return true; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d691f46..846aef5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -84,6 +84,10 @@ #endif #include "cmGlobalUnixMakefileGenerator3.h" +#ifdef CMAKE_USE_NINJA +# include "cmGlobalNinjaGenerator.h" +#endif + #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" #endif @@ -131,7 +135,7 @@ void cmNeedBackwardsCompatibility(const std::string& variable, " that has not been defined. Some variables were always defined " "by CMake in versions prior to 1.6. To fix this you might need to set " "the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If " - "you are writing a CMakeList file, (or have already set " + "you are writing a CMakeLists file, (or have already set " "CMAKE_BACKWARDS_COMPATABILITY to 1.4 or less) then you probably need " "to include a CMake module to test for the feature this variable " "defines."; @@ -598,14 +602,10 @@ bool cmake::FindPackage(const std::vector<std::string>& args) std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS"); std::vector<std::string> includeDirs; cmSystemTools::ExpandListArgument(includes, includeDirs); - for(std::vector<std::string>::const_iterator dirIt=includeDirs.begin(); - dirIt != includeDirs.end(); - ++dirIt) - { - mf->AddIncludeDirectory(dirIt->c_str(), false); - } - std::string includeFlags = lg->GetIncludeFlags(language.c_str(), false); + std::string includeFlags = lg->GetIncludeFlags(includeDirs, + language.c_str(), false); + std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS"); printf("%s %s\n", includeFlags.c_str(), definitions.c_str()); } @@ -1433,7 +1433,7 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args) // Command to start progress for a build else if (args[1] == "cmake_progress_start" && args.size() == 4) { - // bascially remove the directory + // basically remove the directory std::string dirName = args[2]; dirName += "/Progress"; cmSystemTools::RemoveADirectory(dirName.c_str()); @@ -1930,7 +1930,7 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator *gg) { delete this->GlobalGenerator; // restore the original environment variables CXX and CC - // Restor CC + // Restore CC std::string env = "CC="; if(this->CCEnvironment.size()) { @@ -2126,32 +2126,8 @@ int cmake::Configure() } -bool cmake::RejectUnsupportedPaths(const char* desc, std::string const& path) -{ - // Some characters are not well-supported by native build systems. - std::string::size_type pos = path.find_first_of("="); - if(pos == std::string::npos) - { - return false; - } - cmOStringStream e; - e << "The path to the " << desc << " directory:\n" - << " " << path << "\n" - << "contains unsupported character '" << path[pos] << "'.\n" - << "Please use a different " << desc << " directory name."; - cmListFileBacktrace bt; - this->IssueMessage(cmake::FATAL_ERROR, e.str(), bt); - return true; -} - int cmake::ActualConfigure() { - if(this->RejectUnsupportedPaths("source", this->cmHomeDirectory) || - this->RejectUnsupportedPaths("binary", this->HomeOutputDirectory)) - { - return 1; - } - // Construct right now our path conversion table before it's too late: this->UpdateConversionPathTable(); this->CleanupCommandsAndMacros(); @@ -2204,8 +2180,11 @@ int cmake::ActualConfigure() std::string installedCompiler; // Try to find the newest VS installed on the computer and // use that as a default if -G is not specified - std::string vsregBase = - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\"; + const std::string vsregBase = + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\"; + std::vector<std::string> vsVerions; + vsVerions.push_back("VisualStudio\\"); + vsVerions.push_back("VCExpress\\"); struct VSRegistryEntryName { const char* MSVersion; @@ -2219,14 +2198,18 @@ int cmake::ActualConfigure() {"9.0", "Visual Studio 9 2008"}, {"10.0", "Visual Studio 10"}, {0, 0}}; - for(int i =0; version[i].MSVersion != 0; i++) + for(size_t b=0; b < vsVerions.size() && installedCompiler.empty(); b++) { - std::string reg = vsregBase + version[i].MSVersion; - reg += ";InstallDir]"; - cmSystemTools::ExpandRegistryValues(reg); - if (!(reg == "/registry")) + for(int i =0; version[i].MSVersion != 0; i++) { - installedCompiler = version[i].GeneratorName; + std::string reg = vsregBase + vsVerions[b] + version[i].MSVersion; + reg += ";InstallDir]"; + cmSystemTools::ExpandRegistryValues(reg, + cmSystemTools::KeyWOW64_32); + if (!(reg == "/registry")) + { + installedCompiler = version[i].GeneratorName; + } } } cmGlobalGenerator* gen @@ -2614,6 +2597,10 @@ void cmake::AddDefaultGenerators() #endif this->Generators[cmGlobalUnixMakefileGenerator3::GetActualName()] = &cmGlobalUnixMakefileGenerator3::New; +#ifdef CMAKE_USE_NINJA + this->Generators[cmGlobalNinjaGenerator::GetActualName()] = + &cmGlobalNinjaGenerator::New; +#endif #ifdef CMAKE_USE_XCODE this->Generators[cmGlobalXCodeGenerator::GetActualName()] = &cmGlobalXCodeGenerator::New; @@ -2625,7 +2612,7 @@ int cmake::LoadCache() // could we not read the cache if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory())) { - // if it does exist, but isn;t readable then warn the user + // if it does exist, but isn't readable then warn the user std::string cacheFile = this->GetHomeOutputDirectory(); cacheFile += "/CMakeCache.txt"; if(cmSystemTools::FileExists(cacheFile.c_str())) @@ -2677,7 +2664,9 @@ void cmake::GetCommandDocumentation(std::vector<cmDocumentationEntry>& v, j != this->Commands.end(); ++j) { if ((( withCompatCommands == false) && ( (*j).second->IsDiscouraged())) - || ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged()))) + || ((withCurrentCommands == false) && (!(*j).second->IsDiscouraged())) + || (!((*j).second->ShouldAppearInDocumentation())) + ) { continue; } @@ -3384,19 +3373,21 @@ void cmake::DefineProperties(cmake *cm) cm->DefineProperty ("ENABLED_FEATURES", cmProperty::GLOBAL, "List of features which are enabled during the CMake run.", - "List of features which are enabled during the CMake run. Be default " + "List of features which are enabled during the CMake run. By default " "it contains the names of all packages which were found. This is " "determined using the <NAME>_FOUND variables. Packages which are " "searched QUIET are not listed. A project can add its own features to " - "this list.This property is used by the macros in FeatureSummary.cmake."); + "this list. " + "This property is used by the macros in FeatureSummary.cmake."); cm->DefineProperty ("DISABLED_FEATURES", cmProperty::GLOBAL, "List of features which are disabled during the CMake run.", - "List of features which are disabled during the CMake run. Be default " + "List of features which are disabled during the CMake run. By default " "it contains the names of all packages which were not found. This is " "determined using the <NAME>_FOUND variables. Packages which are " "searched QUIET are not listed. A project can add its own features to " - "this list.This property is used by the macros in FeatureSummary.cmake."); + "this list. " + "This property is used by the macros in FeatureSummary.cmake."); cm->DefineProperty ("PACKAGES_FOUND", cmProperty::GLOBAL, "List of packages which were found during the CMake run.", diff --git a/Source/cmake.h b/Source/cmake.h index ae56e85..161e656 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -9,28 +9,6 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -// This class represents a cmake invocation. It is the top level class when -// running cmake. Most cmake based GUIS should primarily create an instance -// of this class and communicate with it. -// -// The basic process for a GUI is as follows: -// -// 1) Create a cmake instance -// 2) Set the Home & Start directories, generator, and cmake command. this -// can be done using the Set methods or by using SetArgs and passing in -// command line arguments. -// 3) Load the cache by calling LoadCache (duh) -// 4) if you are using command line arguments with -D or -C flags then -// call SetCacheArgs (or if for some other reason you want to modify the -// cache, do it now. -// 5) Finally call Configure -// 6) Let the user change values and go back to step 5 -// 7) call Generate -// -// If your GUI allows the user to change the start & home directories then -// you must at a minimum redo steps 2 through 7. -// - #ifndef cmake_h #define cmake_h @@ -53,6 +31,30 @@ class cmListFileBacktrace; class cmTarget; class cmGeneratedFileStream; +/** \brief Represents a cmake invocation. + * + * This class represents a cmake invocation. It is the top level class when + * running cmake. Most cmake based GUIS should primarily create an instance + * of this class and communicate with it. + * + * The basic process for a GUI is as follows: + * + * -# Create a cmake instance + * -# Set the Home & Start directories, generator, and cmake command. this + * can be done using the Set methods or by using SetArgs and passing in + * command line arguments. + * -# Load the cache by calling LoadCache (duh) + * -# if you are using command line arguments with -D or -C flags then + * call SetCacheArgs (or if for some other reason you want to modify the + * cache), do it now. + * -# Finally call Configure + * -# Let the user change values and go back to step 5 + * -# call Generate + + * If your GUI allows the user to change the start & home directories then + * you must at a minimum redo steps 2 through 7. + */ + class cmake { public: @@ -66,31 +68,33 @@ class cmake }; - /** Describes the working modes of cmake. - * NORMAL_MODE: cmake runs to create project files - * SCRIPT_MODE: in script mode there is no generator and no cache. Also, - * language are not enabled, so add_executable and things do - * not do anything. Started by using -P - * FIND_PACKAGE_MODE: cmake runs in pkg-config like mode, i.e. it just - * searches for a package and prints the results to stdout. - * This is similar to SCRIPT_MODE, but commands like - * add_library() work too, since they may be used e.g. in - * exported target files. Started via --find-package - */ + /** \brief Describes the working modes of cmake */ enum WorkingMode { - NORMAL_MODE, + NORMAL_MODE, ///< Cmake runs to create project files + /** \brief Script mode (started by using -P). + * + * In script mode there is no generator and no cache. Also, + * languages are not enabled, so add_executable and things do + * nothing. + */ SCRIPT_MODE, + /** \brief A pkg-config like mode + * + * In this mode cmake just searches for a package and prints the results to + * stdout. This is similar to SCRIPT_MODE, but commands like add_library() + * work too, since they may be used e.g. in exported target files. Started + * via --find-package. + */ FIND_PACKAGE_MODE }; typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap; - ///! construct an instance of cmake + /// Default constructor cmake(); - ///! destruct an instance of cmake + /// Destructor ~cmake(); - ///! construct an instance of cmake static const char *GetCMakeFilesDirectory() {return "/CMakeFiles";}; static const char *GetCMakeFilesDirectoryPostSlash() { return "CMakeFiles/";}; @@ -164,12 +168,6 @@ class cmake int Configure(); int ActualConfigure(); - /** - * Configure the cmMakefiles. This routine will create a GlobalGenerator if - * one has not already been set. It will then Call Configure on the - * GlobalGenerator. This in turn will read in an process all the CMakeList - * files for the tree. It will not produce any actual Makefiles, or - * workspaces. Generate does that. */ int LoadCache(); void PreLoadCMakeFiles(); @@ -468,8 +466,6 @@ protected: ///! Find the full path to one of the cmake programs like ctest, cpack, etc. std::string FindCMakeProgram(const char* name) const; - - bool RejectUnsupportedPaths(const char* desc, std::string const& path); private: cmake(const cmake&); // Not implemented. void operator=(const cmake&); // Not implemented. diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 436236d..c3de8ca 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -355,6 +355,7 @@ int do_cmake(int ac, char** av) #ifdef CMAKE_BUILD_WITH_CMAKE cmDocumentation doc; + doc.addCMakeStandardDocSections(); if(doc.CheckOptions(ac, av, "-E") || nocwd) { // Construct and print requested documentation. diff --git a/Source/cmakexbuild.cxx b/Source/cmakexbuild.cxx index 89d0ec5..8eaae47 100644 --- a/Source/cmakexbuild.cxx +++ b/Source/cmakexbuild.cxx @@ -15,7 +15,7 @@ // This is a wrapper program for xcodebuild // it calls xcodebuild, and does two things -// it removes much of the output, all the setevn +// it removes much of the output, all the setenv // stuff. Also, it checks for the text file busy // error, and re-runs xcodebuild until that error does // not show up. diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 85cecea..d41627e 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -291,6 +291,7 @@ int main (int argc, char *argv[]) << "*********************************" << std::endl); } cmDocumentation doc; + doc.addCTestStandardDocSections(); if(doc.CheckOptions(argc, argv) || nocwd) { // Construct and print requested documentation. diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 664bf6f..b00f782 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -15,7 +15,7 @@ SET(KWSYS_DATE_STAMP_YEAR 2012) # KWSys version date month component. Format is MM. -SET(KWSYS_DATE_STAMP_MONTH 02) +SET(KWSYS_DATE_STAMP_MONTH 03) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 02) +SET(KWSYS_DATE_STAMP_DAY 09) diff --git a/Templates/CPackConfig.cmake.in b/Templates/CPackConfig.cmake.in index 7150feb..79b8d93 100644 --- a/Templates/CPackConfig.cmake.in +++ b/Templates/CPackConfig.cmake.in @@ -1,29 +1,12 @@ # This file will be configured to contain variables for CPack. These variables # should be set in the CMake list file of the project before CPack module is -# included. Example variables are: -# CPACK_GENERATOR - Generator used to create package -# CPACK_INSTALL_CMAKE_PROJECTS - For each project (path, name, component) -# CPACK_CMAKE_GENERATOR - CMake Generator used for the projects -# CPACK_INSTALL_COMMANDS - Extra commands to install components -# CPACK_INSTALLED_DIRECTORIES - Extra directories to install -# CPACK_PACKAGE_DESCRIPTION_FILE - Description file for the package -# CPACK_PACKAGE_DESCRIPTION_SUMMARY - Summary of the package -# CPACK_PACKAGE_EXECUTABLES - List of pairs of executables and labels -# CPACK_PACKAGE_FILE_NAME - Name of the package generated -# CPACK_PACKAGE_ICON - Icon used for the package -# CPACK_PACKAGE_INSTALL_DIRECTORY - Name of directory for the installer -# CPACK_PACKAGE_NAME - Package project name -# CPACK_PACKAGE_VENDOR - Package project vendor -# CPACK_PACKAGE_VERSION - Package project version -# CPACK_PACKAGE_VERSION_MAJOR - Package project version (major) -# CPACK_PACKAGE_VERSION_MINOR - Package project version (minor) -# CPACK_PACKAGE_VERSION_PATCH - Package project version (patch) - -# There are certain generator specific ones - -# NSIS Generator: -# CPACK_PACKAGE_INSTALL_REGISTRY_KEY - Name of the registry key for the installer -# CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS - Extra commands used during uninstall -# CPACK_NSIS_EXTRA_INSTALL_COMMANDS - Extra commands used during install +# included. The list of available CPACK_xxx variables and their associated +# documentation may be obtained using +# cpack --help-variable-list +# +# Some variables are common to all generators (e.g. CPACK_PACKAGE_NAME) +# and some are specific to a generator +# (e.g. CPACK_NSIS_EXTRA_INSTALL_COMMANDS). The generator specific variables +# usually begin with CPACK_<GENNAME>_xxxx. @_CPACK_OTHER_VARIABLES_@ diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt index 31392b5..aa32d67 100644 --- a/Tests/BuildDepends/CMakeLists.txt +++ b/Tests/BuildDepends/CMakeLists.txt @@ -40,6 +40,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Make") endif() list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}") +list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1") + file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project) message("Creating Project/foo.cxx") write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx diff --git a/Tests/CMakeCommands/build_command/RunCMake.cmake b/Tests/CMakeCommands/build_command/RunCMake.cmake deleted file mode 100644 index 55d9359..0000000 --- a/Tests/CMakeCommands/build_command/RunCMake.cmake +++ /dev/null @@ -1,86 +0,0 @@ -if(NOT DEFINED CMake_SOURCE_DIR) - message(FATAL_ERROR "CMake_SOURCE_DIR not defined") -endif() - -if(NOT DEFINED dir) - message(FATAL_ERROR "dir not defined") -endif() - -if(NOT DEFINED gen) - message(FATAL_ERROR "gen not defined") -endif() - -message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") - -# Run cmake: -# -function(run_cmake build_dir extra_args expected_result expected_output expected_error) - message(STATUS "run_cmake build_dir='${build_dir}' extra_args='${extra_args}'") - - # Ensure build_dir exists: - # - execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${build_dir}) - - # Run cmake: - # - execute_process(COMMAND ${CMAKE_COMMAND} - ${extra_args} - -G ${gen} ${CMake_SOURCE_DIR}/Tests/CMakeCommands/build_command - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr - WORKING_DIRECTORY ${build_dir} - ) - - message(STATUS "result='${result}'") - message(STATUS "stdout='${stdout}'") - message(STATUS "stderr='${stderr}'") - message(STATUS "") - - # Verify result and output match expectations: - # - if("0" STREQUAL "${expected_result}") - if(NOT "${result}" STREQUAL "0") - message(FATAL_ERROR - "error: result='${result}' is non-zero and different than expected_result='${expected_result}'") - endif() - else() - if("${result}" STREQUAL "0") - message(FATAL_ERROR - "error: result='${result}' is zero and different than expected_result='${expected_result}'") - endif() - endif() - - foreach(e ${expected_output}) - if(NOT stdout MATCHES "${e}") - message(FATAL_ERROR - "error: stdout does not match expected_output item e='${e}'") - else() - message(STATUS "info: stdout matches '${e}'") - endif() - endforeach() - - foreach(e ${expected_error}) - if(NOT stderr MATCHES "${e}") - message(FATAL_ERROR - "error: stderr does not match expected_error item e='${e}'") - else() - message(STATUS "info: stderr matches '${e}'") - endif() - endforeach() - - message(STATUS "result, stdout and stderr match all expectations: test passes") - message(STATUS "") -endfunction() - - -# Expect this case to succeed: -run_cmake("${dir}/b1" "" 0 - "Build files have been written to:" - "skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF") - - -# Expect this one to fail: -run_cmake("${dir}/b2" "-DTEST_ERROR_CONDITIONS:BOOL=ON" 1 - "Configuring incomplete, errors occurred!" - "build_command requires at least one argument naming a CMake variable;build_command unknown argument ") diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2c5acd9..5f125a4 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -16,6 +16,11 @@ MACRO(ADD_TEST_MACRO NAME COMMAND) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}") ENDMACRO(ADD_TEST_MACRO) +MACRO(REGEX_ESCAPE_STRING _OUT _IN) + # Escape special regex metacharacters with a backslash + string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" ${_OUT} "${_IN}") +ENDMACRO(REGEX_ESCAPE_STRING _OUT _IN) + INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/CheckFortran.cmake) # Fake a user home directory to avoid polluting the real one. @@ -48,6 +53,7 @@ IF(BUILD_TESTING) ADD_SUBDIRECTORY(CMakeLib) ADD_SUBDIRECTORY(CMakeOnly) + ADD_SUBDIRECTORY(RunCMake) ADD_SUBDIRECTORY(FindPackageModeMakefileTest) @@ -163,6 +169,32 @@ IF(BUILD_TESTING) IF(CMAKE_Fortran_COMPILER) ADD_TEST_MACRO(FortranOnly FortranOnly) ENDIF() + # test Visual Studio GNU Fortran mixing with cmake_add_fortran_subdirectory + # run this project if we have a working fortran compiler or + # the test is enabled with CMAKE_TEST_CMAKE_ADD_FORTRAN cache variable. + # If you enable the test, CMake should find the MinGW fortran install, + # or in some cases you might need to set the PATH so that cmake can find + # the gfortran from mingw. + IF(CMAKE_Fortran_COMPILER OR CMAKE_TEST_CMAKE_ADD_FORTRAN) + SET(CMAKE_SKIP_VSGNUFortran FALSE) + # disable test for apple builds using ifort if they are building + # more than one architecture, as ifort does not support that. + IF(APPLE AND (CMAKE_Fortran_COMPILER MATCHES ifort)) + LIST(LENGTH CMAKE_OSX_ARCHITECTURES len) + IF("${len}" GREATER 1) + MESSAGE(STATUS "Skip VSGNUFortran for ifort dual cpu mac build") + SET(CMAKE_SKIP_VSGNUFortran TRUE) + ENDIF() + ENDIF() + IF((CMAKE_C_COMPILER MATCHES lsb) + AND (CMAKE_Fortran_COMPILER MATCHES ifort)) + MESSAGE(STATUS "Skip VSGNUFortran for ifort and lsb compilers") + SET(CMAKE_SKIP_VSGNUFortran TRUE) + ENDIF() + IF(NOT CMAKE_SKIP_VSGNUFortran) + ADD_TEST_MACRO(VSGNUFortran ${CMAKE_COMMAND} -P runtest.cmake) + ENDIF() + ENDIF() ADD_TEST_MACRO(COnly COnly) ADD_TEST_MACRO(CxxOnly CxxOnly) ADD_TEST_MACRO(IPO COnly/COnly) @@ -201,12 +233,35 @@ IF(BUILD_TESTING) LIST(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX}) + IF(NOT QT4_FOUND) + FIND_PACKAGE(Qt4) + ENDIF(NOT QT4_FOUND) + + IF(QT4_FOUND) + # test whether the Qt4 which has been found works, on some machines + # which run nightly builds there were errors like "wrong file format" + # for libQtCore.so. So first check it works, and only if it does add + # the automoc test. + INCLUDE(CheckCXXSourceCompiles) + SET(_save_CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") + SET(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + SET(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES}) + SET(CMAKE_REQUIRED_LIBRARIES ${QT_QTCORE_LIBRARIES}) + + CHECK_CXX_SOURCE_COMPILES("#include <QCoreApplication>\n int main() {return (qApp == 0 ? 0 : 1); }\n" + QT4_WORKS) + + SET(CMAKE_REQUIRED_INCLUDES "${_save_CMAKE_REQUIRED_INCLUDES}") + SET(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}") + ENDIF() # run test for BundleUtilities on supported platforms/compilers if(MSVC OR CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin") if(NOT "${CMAKE_TEST_GENERATOR}" STREQUAL "Watcom WMake") + ADD_TEST(BundleUtilities ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/BundleUtilities" @@ -216,6 +271,24 @@ IF(BUILD_TESTING) --build-project BundleUtilities ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities") + + # run test for DeployQt4 on supported platforms/compilers (which depends on BundleUtilities) + # this test also depends on the existence of the standard qtiff plugin + if(QT4_WORKS AND QT_QTSQL_FOUND) + ADD_TEST(Qt4Deploy ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Qt4Deploy" + "${CMake_BINARY_DIR}/Tests/Qt4Deploy" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-project Qt4Deploy + --build-options + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Deploy") + endif() + endif() endif() @@ -334,6 +407,15 @@ IF(BUILD_TESTING) --build-target car --test-command car ) + + IF(${CMAKE_TEST_GENERATOR} MATCHES "Ninja") + # The Ninja generator does not create a recursive build system. Start + # from the root directory. + SET(SubProject_SUBDIR) + ELSE() + SET(SubProject_SUBDIR "/foo") + ENDIF() + # For stage 2, do not run cmake again. # Then build the foo sub project which should build # the bar library which should be referenced because @@ -341,13 +423,14 @@ IF(BUILD_TESTING) # directly in the foo sub project ADD_TEST(SubProject-Stage2 ${CMAKE_CTEST_COMMAND} --build-and-test - "${CMake_SOURCE_DIR}/Tests/SubProject/foo" - "${CMake_BINARY_DIR}/Tests/SubProject/foo" + "${CMake_SOURCE_DIR}/Tests/SubProject${SubProject_SUBDIR}" + "${CMake_BINARY_DIR}/Tests/SubProject${SubProject_SUBDIR}" --build-generator ${CMAKE_TEST_GENERATOR} --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-nocmake --build-project foo --build-target foo + --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubProject/foo" --test-command foo ) SET_TESTS_PROPERTIES ( SubProject-Stage2 PROPERTIES DEPENDS SubProject) @@ -559,6 +642,14 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ set(CTEST_package_X11_TEST ${CTEST_TEST_CPACK}) set(CTEST_RUN_CPackComponentsForAll ${CTEST_TEST_CPACK}) + if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*") + find_program(RPMBUILD NAMES rpmbuild) + endif(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES ".* .*") + # Do not try to build RPM + if (NOT RPMBUILD) + set(CPACK_BINARY_RPM OFF) + endif(NOT RPMBUILD) + find_program(NSIS_MAKENSIS_EXECUTABLE NAMES makensis PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS] DOC "makensis program location" @@ -765,56 +856,36 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig") - # Como does not seem to support shared libraries. - GET_FILENAME_COMPONENT(CMAKE_BASE_NAME ${CMAKE_CXX_COMPILER} NAME_WE) - IF(CMAKE_BASE_NAME MATCHES "^como$") - SET(COMPILER_IS_COMO 1) - ENDIF(CMAKE_BASE_NAME MATCHES "^como$") - IF(NOT COMPILER_IS_COMO) - ADD_TEST(complex ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/Complex" - "${CMake_BINARY_DIR}/Tests/Complex" - --build-two-config - --build-config-sample "${CMAKE_CTEST_COMMAND}" - --build-generator ${CMAKE_TEST_GENERATOR} - --build-project Complex - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin" - --build-options - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - --test-command complex - ) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Complex") + ADD_TEST(complex ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Complex" + "${CMake_BINARY_DIR}/Tests/Complex" + --build-two-config + --build-config-sample "${CMAKE_CTEST_COMMAND}" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project Complex + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin" + --build-options + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + --test-command complex + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Complex") - ADD_TEST(complexOneConfig ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/ComplexOneConfig" - "${CMake_BINARY_DIR}/Tests/ComplexOneConfig" - --build-generator ${CMAKE_TEST_GENERATOR} - --build-project Complex - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin" - --build-options - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - --test-command complex) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ComplexOneConfig") - # because of the registry write these tests depend on each other - SET_TESTS_PROPERTIES ( complex PROPERTIES DEPENDS complexOneConfig) - -# This fails on VS 70 -# works on Xcode and makefiles -# ADD_TEST(ConvLibrary ${CMAKE_CTEST_COMMAND} -# --build-and-test -# "${CMake_SOURCE_DIR}/Tests/ConvLibrary" -# "${CMake_BINARY_DIR}/Tests/ConvLibrary" -# --build-two-config -# --build-generator ${CMAKE_TEST_GENERATOR} -# --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} -# --build-project ConvLibrary -# --test-command bartest) - - ENDIF(NOT COMPILER_IS_COMO) + ADD_TEST(complexOneConfig ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/ComplexOneConfig" + "${CMake_BINARY_DIR}/Tests/ComplexOneConfig" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project Complex + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin" + --build-options + -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + --test-command complex) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ComplexOneConfig") + # because of the registry write these tests depend on each other + SET_TESTS_PROPERTIES ( complex PROPERTIES DEPENDS complexOneConfig) ADD_TEST(Example ${CMAKE_CTEST_COMMAND} --build-and-test @@ -841,43 +912,20 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment") - IF(NOT QT4_FOUND) - FIND_PACKAGE(Qt4) - ENDIF(NOT QT4_FOUND) - - IF(QT4_FOUND) - # test whether the Qt4 which has been found works, on some machines - # which run nightly builds there were errors like "wrong file format" - # for libQtCore.so. So first check it works, and only if it does add - # the automoc test. - INCLUDE(CheckCXXSourceCompiles) - SET(_save_CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") - SET(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") - - SET(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES}) - SET(CMAKE_REQUIRED_LIBRARIES ${QT_QTCORE_LIBRARIES}) - - CHECK_CXX_SOURCE_COMPILES("#include <QCoreApplication>\n int main() {return (qApp == 0 ? 0 : 1); }\n" - QT4_WORKS_FOR_AUTOMOC_TEST) - - SET(CMAKE_REQUIRED_INCLUDES "${_save_CMAKE_REQUIRED_INCLUDES}") - SET(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}") - - IF(QT4_WORKS_FOR_AUTOMOC_TEST) - ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/QtAutomoc" - "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --build-generator ${CMAKE_TEST_GENERATOR} - --build-project QtAutomoc - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --force-new-ctest-process - --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} - --test-command ${CMAKE_CTEST_COMMAND} -V - ) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") - ENDIF() + IF(QT4_WORKS AND QT_QTGUI_FOUND) + ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutomoc" + "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project QtAutomoc + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --force-new-ctest-process + --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") ENDIF() ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND} @@ -1300,6 +1348,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ endif() IF(${CMAKE_TEST_GENERATOR} MATCHES "Visual Studio") + IF(NOT MSVC60) + ADD_TEST_MACRO(SBCS SBCS) + ENDIF(NOT MSVC60) + ADD_TEST(VSExternalInclude ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/VSExternalInclude" @@ -1632,9 +1684,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/test1.cmake" -V --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir1/testOut1.log" ) + REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_SOURCE_DIR "${CMake_SOURCE_DIR}") SET_TESTS_PROPERTIES(CTestTestConfigFileInBuildDir1 PROPERTIES DEPENDS CTestTestNoBuild PASS_REGULAR_EXPRESSION - "Reading ctest configuration file: ${CMake_SOURCE_DIR}.Tests.CTestTestConfigFileInBuildDir.CTestConfig.cmake") + "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_SOURCE_DIR}.Tests.CTestTestConfigFileInBuildDir.CTestConfig.cmake") CONFIGURE_FILE( "${CMake_SOURCE_DIR}/Tests/CTestTestConfigFileInBuildDir/test2.cmake.in" @@ -1648,10 +1701,11 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ -S "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/test2.cmake" -V --output-log "${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/testOut2.log" ) + REGEX_ESCAPE_STRING(CTEST_TEST_ESCAPED_BINARY_DIR "${CMake_BINARY_DIR}") SET_TESTS_PROPERTIES(CTestTestConfigFileInBuildDir2 PROPERTIES DEPENDS CTestTestNoBuild REQUIRED_FILES ${CMake_BINARY_DIR}/Tests/CTestTestConfigFileInBuildDir2/CTestConfig.cmake PASS_REGULAR_EXPRESSION - "Reading ctest configuration file: ${CMake_BINARY_DIR}.Tests.CTestTestConfigFileInBuildDir2.CTestConfig.cmake") + "Reading ctest configuration file: ${CTEST_TEST_ESCAPED_BINARY_DIR}.Tests.CTestTestConfigFileInBuildDir2.CTestConfig.cmake") # Use macro, not function so that build can still be driven by CMake 2.4. # After 2.6 is required, this could be a function without the extra 'set' @@ -1689,13 +1743,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ add_config_tests(Release) add_config_tests(RelWithDebInfo) - add_test(CMakeCommands.build_command ${CMAKE_CMAKE_COMMAND} - -DCMake_SOURCE_DIR=${CMake_SOURCE_DIR} - -Ddir=${CMake_BINARY_DIR}/Tests/CMakeCommands/build_command - -Dgen=${CMAKE_TEST_GENERATOR} - -P "${CMake_SOURCE_DIR}/Tests/CMakeCommands/build_command/RunCMake.cmake" - ) - ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) CONFIGURE_FILE( diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt index 8a38f06..22b1b7b 100644 --- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt +++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt @@ -15,25 +15,61 @@ macro(do_find MODULE_NAME) find_package(${MODULE_NAME}) endmacro(do_find) +# It is only possible to use either Qt3 or Qt4 in one project. +# Since FindQt will complain if both are found we explicitly request Qt4 here +# and filter out FindQt3. FindKDE3 also depends on Qt3 and +# is therefore also blocked +set(DESIRED_QT_VERSION 4) +set(NO_QT4_MODULES "Qt3" "KDE3") + +# These modules are named Find*.cmake, but are nothing that works in +# find_package(). +set(NO_FIND_MODULES "PackageHandleStandardArgs" "PackageMessage") + foreach(FIND_MODULE ${FIND_MODULES}) string(REGEX REPLACE ".*/Find(.*)\\.cmake$" "\\1" MODULE_NAME "${FIND_MODULE}") - # It is only possible to use either Qt3 or Qt4 in one project. - # Since FindQt will complain if both are found we explicitely - # filter out this and FindQt3. FindKDE3 also depends on Qt3 and - # is therefore also blocked - - if (NOT MODULE_NAME STREQUAL "Qt" AND - NOT MODULE_NAME STREQUAL "Qt3" AND - NOT MODULE_NAME STREQUAL "KDE3") + list(FIND NO_QT4_MODULES ${MODULE_NAME} NO_QT4_INDEX) + list(FIND NO_FIND_MODULES ${MODULE_NAME} NO_FIND_INDEX) + if (NO_QT4_INDEX EQUAL -1 AND NO_FIND_INDEX EQUAL -1) do_find(${MODULE_NAME}) endif () endforeach(FIND_MODULE) # Qt4 is not present, so we can check Qt3 -if(NOT QT4_FOUND) - foreach(FIND_MODULE "Qt3" "Qt" "KDE3") +if (NOT QT4_FOUND) + set(DESIRED_QT_VERSION 3) + foreach(FIND_MODULE ${NO_QT4_MODULES} "Qt") do_find(${FIND_MODULE}) endforeach(FIND_MODULE) -endif(NOT QT4_FOUND) +endif (NOT QT4_FOUND) + +macro(check_version_string MODULE_NAME VERSION_VAR) + if (${MODULE_NAME}_FOUND) + if (DEFINED ${VERSION_VAR}) + if (NOT ${VERSION_VAR} MATCHES "^[0-9][0-9\\.]*[-A-Za-z_\\+]*[0-9\\.]*$") + message(SEND_ERROR "${VERSION_VAR} has unexpected content ${${VERSION_VAR}}") + endif() + else() + message(SEND_ERROR "${MODULE_NAME}_FOUND is set but no version number is defined") + endif() + endif () +endmacro(check_version_string) + +# If any of these modules reported that it was found a version number should have been +# reported. + +foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HSPELL + JASPER LIBXML2 LIBXSLT PERL PostgreSQL TIFF ZLIB) + check_version_string(${VTEST} ${VTEST}_VERSION_STRING) +endforeach(VTEST) + +foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2 LibArchive OPENSCENEGRAPH + RUBY SWIG) + check_version_string(${VTEST} ${VTEST}_VERSION) +endforeach(VTEST) + +check_version_string(PYTHONINTERP PYTHON_VERSION_STRING) +check_version_string(SUBVERSION Subversion_VERSION_SVN) +check_version_string(PKGCONFIG PKG_CONFIG_VERSION_STRING) diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt index 33c426a..a1551ca 100644 --- a/Tests/CMakeOnly/CMakeLists.txt +++ b/Tests/CMakeOnly/CMakeLists.txt @@ -17,6 +17,14 @@ add_CMakeOnly_test(CheckCXXSymbolExists) add_CMakeOnly_test(CheckCXXCompilerFlag) +add_CMakeOnly_test(CheckLanguage) + add_CMakeOnly_test(AllFindModules) add_CMakeOnly_test(TargetScope) + +add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND} + -DTEST=ProjectInclude + -DCMAKE_ARGS=-DCMAKE_PROJECT_ProjectInclude_INCLUDE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectInclude/include.cmake + -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake + ) diff --git a/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt new file mode 100644 index 0000000..f5336dc --- /dev/null +++ b/Tests/CMakeOnly/CheckLanguage/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required (VERSION 2.8) +project(CheckLanguage NONE) +include(CheckLanguage) + +set(langs ) +set(expect_C 1) +set(expect_CXX 1) +unset(expect_Fortran) +set(expect_NoSuchLanguage 0) +foreach(lang C CXX Fortran NoSuchLanguage) + check_language(${lang}) + if(NOT DEFINED CMAKE_${lang}_COMPILER) + message(FATAL_ERROR "check_language(${lang}) did not set result") + endif() + if(DEFINED expect_${lang}) + if(expect_${lang} AND NOT CMAKE_${lang}_COMPILER) + message(FATAL_ERROR "check_language(${lang}) should not fail!") + elseif(NOT expect_${lang} AND CMAKE_${lang}_COMPILER) + message(FATAL_ERROR "check_language(${lang}) should not succeed!") + endif() + endif() +endforeach() diff --git a/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt b/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt new file mode 100644 index 0000000..a9abb4a --- /dev/null +++ b/Tests/CMakeOnly/ProjectInclude/CMakeLists.txt @@ -0,0 +1,4 @@ +project(ProjectInclude) +if(NOT AUTO_INCLUDE) + message(FATAL_ERROR "include file not found") +endif() diff --git a/Tests/CMakeOnly/ProjectInclude/include.cmake b/Tests/CMakeOnly/ProjectInclude/include.cmake new file mode 100644 index 0000000..527ebe7 --- /dev/null +++ b/Tests/CMakeOnly/ProjectInclude/include.cmake @@ -0,0 +1 @@ +set(AUTO_INCLUDE TRUE) diff --git a/Tests/CMakeOnly/Test.cmake.in b/Tests/CMakeOnly/Test.cmake.in index aa2d093..42af068 100644 --- a/Tests/CMakeOnly/Test.cmake.in +++ b/Tests/CMakeOnly/Test.cmake.in @@ -3,7 +3,8 @@ set(binary_dir "@CMAKE_CURRENT_BINARY_DIR@/${TEST}-build") file(REMOVE_RECURSE "${binary_dir}") file(MAKE_DIRECTORY "${binary_dir}") execute_process( - COMMAND ${CMAKE_COMMAND} "${source_dir}" -G "@CMAKE_TEST_GENERATOR@" + COMMAND ${CMAKE_COMMAND} ${CMAKE_ARGS} + "${source_dir}" -G "@CMAKE_TEST_GENERATOR@" WORKING_DIRECTORY "${binary_dir}" RESULT_VARIABLE result ) diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt index fc1426e..c42c490 100644 --- a/Tests/CMakeTests/CMakeLists.txt +++ b/Tests/CMakeTests/CMakeLists.txt @@ -22,6 +22,7 @@ AddCMakeTest(ConfigureFile "") AddCMakeTest(SeparateArguments "") AddCMakeTest(ImplicitLinkInfo "") AddCMakeTest(ModuleNotices "") +AddCMakeTest(GetProperty "") AddCMakeTest(If "") AddCMakeTest(String "") AddCMakeTest(Math "") @@ -29,6 +30,7 @@ AddCMakeTest(CMakeMinimumRequired "") AddCMakeTest(CompilerIdVendor "") AddCMakeTest(ProcessorCount "") AddCMakeTest(PushCheckState "") +AddCMakeTest(While "") AddCMakeTest(FileDownload "") set_property(TEST CMake.FileDownload PROPERTY @@ -55,14 +57,13 @@ AddCMakeTest(GetPrerequisites "${GetPrerequisites_PreArgs}") # suite. It detects if any changes have been made to the CMake source tree # by any previous configure, build or test steps. # -if(do_cvs_tests OR GIT_EXECUTABLE) +if(GIT_EXECUTABLE) string(REPLACE "\\" "/" ENV_HOME "$ENV{HOME}") set(CheckSourceTree_PreArgs "-DCMake_BINARY_DIR:PATH=${CMake_BINARY_DIR}" "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}" - "-DCVS_EXECUTABLE:STRING=${CVS_EXECUTABLE}" "-DGIT_EXECUTABLE:STRING=${GIT_EXECUTABLE}" "-DHOME:STRING=${ENV_HOME}" ) AddCMakeTest(CheckSourceTree "${CheckSourceTree_PreArgs}") -endif(do_cvs_tests OR GIT_EXECUTABLE) +endif() diff --git a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in index 73f8b01..59b2890 100644 --- a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in +++ b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in @@ -5,7 +5,6 @@ message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") message("") message("CMake_BINARY_DIR='${CMake_BINARY_DIR}'") message("CMake_SOURCE_DIR='${CMake_SOURCE_DIR}'") -message("CVS_EXECUTABLE='${CVS_EXECUTABLE}'") message("GIT_EXECUTABLE='${GIT_EXECUTABLE}'") message("HOME='${HOME}'") message("ENV{DASHBOARD_TEST_FROM_CTEST}='$ENV{DASHBOARD_TEST_FROM_CTEST}'") @@ -43,7 +42,7 @@ message("in_source_build='${in_source_build}'") message("") -# If this does not appear to be a git or CVS checkout, just pass the test here +# If this does not appear to be a git checkout, just pass the test here # and now. (Do not let the test fail if it is run in a tree *exported* from a # repository or unpacked from a .zip file source installer...) # @@ -52,29 +51,13 @@ if(EXISTS "${CMake_SOURCE_DIR}/.git") set(is_git_checkout 1) endif() -set(is_cvs_checkout 0) -if(EXISTS "${CMake_SOURCE_DIR}/CVS/Root") - set(is_cvs_checkout 1) -endif() - message("is_git_checkout='${is_git_checkout}'") -message("is_cvs_checkout='${is_cvs_checkout}'") message("") -if(NOT is_cvs_checkout) if(NOT is_git_checkout) - message("source tree is neither git nor CVS checkout... test passes by early return...") + message("source tree is not a git checkout... test passes by early return...") return() endif() -endif() - -if(is_cvs_checkout) -if(is_git_checkout) - message("warning: source tree has both git *and* CVS file system bits???") - # should this condition be a FATAL_ERROR test failure...? -endif() -endif() - # This test looks for the following types of changes in the source tree: # @@ -83,51 +66,13 @@ set(conflicts 0) set(modifications 0) set(nonadditions 0) -# ov == output variable... conditionally filled in by either cvs or git below: +# ov == output variable... conditionally filled in by either git below: # set(cmd "") set(ov "") set(ev "") set(rv "") - -if(is_cvs_checkout AND CVS_EXECUTABLE) - # Check with "cvs -q -n up -dP" if there are any local modifications to the - # CMake source tree: - # - message("=============================================================================") - message("This is a cvs checkout, using cvs to verify source tree....") - message("") - - execute_process(COMMAND ${CVS_EXECUTABLE} --version - WORKING_DIRECTORY ${CMake_SOURCE_DIR} - OUTPUT_VARIABLE version_output - OUTPUT_STRIP_TRAILING_WHITESPACE) - message("=== output of 'cvs --version' ===") - message("${version_output}") - message("=== end output ===") - message("") - - file(READ "${CMake_SOURCE_DIR}/CVS/Root" contents) - message("=== content of CVS/Root ===") - message("${contents}") - message("=== end content ===") - message("") - - file(READ "${CMake_SOURCE_DIR}/CVS/Repository" contents) - message("=== content of CVS/Repository ===") - message("${contents}") - message("=== end content ===") - message("") - - message("Copy/paste this command to reproduce:") - message("cd \"${CMake_SOURCE_DIR}\" && \"${CVS_EXECUTABLE}\" -q -n up -dP") - message("") - - set(cmd ${CVS_EXECUTABLE} -q -n up -dP) -endif() - - # If no GIT_EXECUTABLE, see if we can figure out which git was used # for the ctest_update step on this dashboard... # @@ -268,8 +213,8 @@ endif() if(cmd) - # Use the HOME value passed in to the script for calling cvs/git so it can - # find its .cvspass or user/global config settings... + # Use the HOME value passed in to the script for calling git so it can + # find its user/global config settings... # set(original_ENV_HOME "$ENV{HOME}") set(ENV{HOME} "${HOME}") @@ -322,28 +267,6 @@ if(NOT ov STREQUAL "") endif() if(consider) - if(is_cvs_checkout) - if(line MATCHES "^A ") - message(" locally added file/directory detected...") - set(additions 1) - endif() - - if(line MATCHES "^C ") - message(" conflict detected...") - set(conflicts 1) - endif() - - if(line MATCHES "^M ") - message(" locally modified file detected...") - set(modifications 1) - endif() - - if(line MATCHES "^\\? ") - message(" locally non-added file/directory detected...") - set(nonadditions 1) - endif() - endif() - if(is_git_checkout) if(line MATCHES "^#[ \t]*modified:") message(" locally modified file detected...") diff --git a/Tests/CMakeTests/GetProperty-Bad-Argument.cmake b/Tests/CMakeTests/GetProperty-Bad-Argument.cmake new file mode 100644 index 0000000..382dabb --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Bad-Argument.cmake @@ -0,0 +1 @@ +get_property(FOO GLOBAL PROPERTY FOO FOO) diff --git a/Tests/CMakeTests/GetProperty-Bad-Directory.cmake b/Tests/CMakeTests/GetProperty-Bad-Directory.cmake new file mode 100644 index 0000000..cdbfa80 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Bad-Directory.cmake @@ -0,0 +1 @@ +get_property(FOO DIRECTORY NonExistentSubDir PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-Bad-Scope.cmake b/Tests/CMakeTests/GetProperty-Bad-Scope.cmake new file mode 100644 index 0000000..ea8566b --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Bad-Scope.cmake @@ -0,0 +1 @@ +get_property(FOO FOO FOO) diff --git a/Tests/CMakeTests/GetProperty-Bad-Target.cmake b/Tests/CMakeTests/GetProperty-Bad-Target.cmake new file mode 100644 index 0000000..9992dab --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Bad-Target.cmake @@ -0,0 +1 @@ +get_property(FOO TARGET FOO PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-Bad-Test.cmake b/Tests/CMakeTests/GetProperty-Bad-Test.cmake new file mode 100644 index 0000000..44bf3eb --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Bad-Test.cmake @@ -0,0 +1 @@ +get_property(FOO TEST FOO PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-Doc-Properties.cmake b/Tests/CMakeTests/GetProperty-Doc-Properties.cmake new file mode 100644 index 0000000..6c2c362 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Doc-Properties.cmake @@ -0,0 +1,10 @@ +get_property(FOO_BRIEF GLOBAL PROPERTY FOO BRIEF_DOCS) +get_property(FOO_FULL GLOBAL PROPERTY FOO FULL_DOCS) + +if (NOT FOO_BRIEF STREQUAL "NOTFOUND") + message(SEND_ERROR "property FOO has BRIEF_DOCS set to '${FOO_BRIEF}'") +endif () + +if (NOT FOO_FULL STREQUAL "NOTFOUND") + message(SEND_ERROR "property FOO has FULL_DOCS set to '${FOO_FULL}'") +endif () diff --git a/Tests/CMakeTests/GetProperty-Global-Name.cmake b/Tests/CMakeTests/GetProperty-Global-Name.cmake new file mode 100644 index 0000000..497700c --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Global-Name.cmake @@ -0,0 +1 @@ +get_property(FOO GLOBAL FOO PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-Missing-Argument.cmake b/Tests/CMakeTests/GetProperty-Missing-Argument.cmake new file mode 100644 index 0000000..f0d004d --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Missing-Argument.cmake @@ -0,0 +1 @@ +get_property() diff --git a/Tests/CMakeTests/GetProperty-No-Cache.cmake b/Tests/CMakeTests/GetProperty-No-Cache.cmake new file mode 100644 index 0000000..9719fe7 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-No-Cache.cmake @@ -0,0 +1 @@ +get_property(FOO CACHE PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-No-Property.cmake b/Tests/CMakeTests/GetProperty-No-Property.cmake new file mode 100644 index 0000000..bee230d --- /dev/null +++ b/Tests/CMakeTests/GetProperty-No-Property.cmake @@ -0,0 +1 @@ +get_property(FOO GLOBAL PROPERTY) diff --git a/Tests/CMakeTests/GetProperty-No-Source.cmake b/Tests/CMakeTests/GetProperty-No-Source.cmake new file mode 100644 index 0000000..89773c8 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-No-Source.cmake @@ -0,0 +1 @@ +get_property(FOO SOURCE PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-No-Target.cmake b/Tests/CMakeTests/GetProperty-No-Target.cmake new file mode 100644 index 0000000..8f1fa23 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-No-Target.cmake @@ -0,0 +1 @@ +get_property(FOO TARGET PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-No-Test.cmake b/Tests/CMakeTests/GetProperty-No-Test.cmake new file mode 100644 index 0000000..045bd56 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-No-Test.cmake @@ -0,0 +1 @@ +get_property(FOO TEST PROPERTY FOO) diff --git a/Tests/CMakeTests/GetProperty-Variable-Name.cmake b/Tests/CMakeTests/GetProperty-Variable-Name.cmake new file mode 100644 index 0000000..9190f80 --- /dev/null +++ b/Tests/CMakeTests/GetProperty-Variable-Name.cmake @@ -0,0 +1 @@ +get_property(FOO VARIABLE FOO PROPERTY FOO) diff --git a/Tests/CMakeTests/GetPropertyTest.cmake.in b/Tests/CMakeTests/GetPropertyTest.cmake.in new file mode 100644 index 0000000..ab96e5b --- /dev/null +++ b/Tests/CMakeTests/GetPropertyTest.cmake.in @@ -0,0 +1,98 @@ +include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") + +set(Missing-Argument-RESULT 1) +set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Missing-Argument.cmake:1 \\(get_property\\):.*get_property called with incorrect number of arguments.*") + +check_cmake_test(GetProperty + Missing-Argument +) + +set(Bad-Scope-RESULT 1) +set(Bad-Scope-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Scope.cmake:1 \\(get_property\\):.*get_property given invalid scope FOO\\..*") + +check_cmake_test(GetProperty + Bad-Scope +) + +set(Bad-Argument-RESULT 1) +set(Bad-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Argument.cmake:1 \\(get_property\\):.*get_property given invalid argument \"FOO\"\\..*") + +check_cmake_test(GetProperty + Bad-Argument +) + +set(No-Property-RESULT 1) +set(No-Property-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Property.cmake:1 \\(get_property\\):.*get_property not given a PROPERTY <name> argument\\..*") + +check_cmake_test(GetProperty + No-Property +) + +set(Doc-Properties-RESULT 0) + +check_cmake_test(GetProperty + Doc-Properties +) + +set(Global-Name-RESULT 1) +set(Global-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Global-Name.cmake:1 \\(get_property\\):.*get_property given name for GLOBAL scope\\..*") + +check_cmake_test(GetProperty + Global-Name +) + +set(Bad-Directory-RESULT 1) +set(Bad-Directory-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Directory.cmake:1 \\(get_property\\):.*get_property DIRECTORY scope provided but requested directory was not.*found\\..*") + +check_cmake_test(GetProperty + Bad-Directory +) + +set(No-Target-RESULT 1) +set(No-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Target.cmake:1 \\(get_property\\):.*get_property not given name for TARGET scope\\..*") + +check_cmake_test(GetProperty + No-Target +) + +set(Bad-Target-RESULT 1) +set(Bad-Target-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Target.cmake:1 \\(get_property\\):.*get_property could not find TARGET FOO\\..*") + +check_cmake_test(GetProperty + Bad-Target +) + +set(No-Source-RESULT 1) +set(No-Source-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Source.cmake:1 \\(get_property\\):.*get_property not given name for SOURCE scope\\..*") + +check_cmake_test(GetProperty + No-Source +) + +set(No-Test-RESULT 1) +set(No-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Test.cmake:1 \\(get_property\\):.*get_property not given name for TEST scope\\..*") + +check_cmake_test(GetProperty + No-Test +) + +set(Bad-Test-RESULT 1) +set(Bad-Test-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Bad-Test.cmake:1 \\(get_property\\):.*get_property given TEST name that does not exist: FOO.*") + +check_cmake_test(GetProperty + Bad-Test +) + +set(Variable-Name-RESULT 1) +set(Variable-Name-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-Variable-Name.cmake:1 \\(get_property\\):.*get_property given name for VARIABLE scope\\..*") + +check_cmake_test(GetProperty + Variable-Name +) + +set(No-Cache-RESULT 1) +set(No-Cache-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?GetProperty-No-Cache.cmake:1 \\(get_property\\):.*get_property not given name for CACHE scope\\..*") + +check_cmake_test(GetProperty + No-Cache +) diff --git a/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake b/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake new file mode 100644 index 0000000..886d98c --- /dev/null +++ b/Tests/CMakeTests/While-Endwhile-Alone-Args.cmake @@ -0,0 +1 @@ +endwhile(a) diff --git a/Tests/CMakeTests/While-Endwhile-Alone.cmake b/Tests/CMakeTests/While-Endwhile-Alone.cmake new file mode 100644 index 0000000..82c09a0 --- /dev/null +++ b/Tests/CMakeTests/While-Endwhile-Alone.cmake @@ -0,0 +1 @@ +endwhile() diff --git a/Tests/CMakeTests/While-Endwhile-Mismatch.cmake b/Tests/CMakeTests/While-Endwhile-Mismatch.cmake new file mode 100644 index 0000000..5c338d6 --- /dev/null +++ b/Tests/CMakeTests/While-Endwhile-Mismatch.cmake @@ -0,0 +1,2 @@ +while(a) +endwhile(b) diff --git a/Tests/CMakeTests/While-Missing-Argument.cmake b/Tests/CMakeTests/While-Missing-Argument.cmake new file mode 100644 index 0000000..32eaa26 --- /dev/null +++ b/Tests/CMakeTests/While-Missing-Argument.cmake @@ -0,0 +1 @@ +while() diff --git a/Tests/CMakeTests/While-Missing-Endwhile.cmake b/Tests/CMakeTests/While-Missing-Endwhile.cmake new file mode 100644 index 0000000..1abaaaf --- /dev/null +++ b/Tests/CMakeTests/While-Missing-Endwhile.cmake @@ -0,0 +1 @@ +while(a) diff --git a/Tests/CMakeTests/WhileTest.cmake.in b/Tests/CMakeTests/WhileTest.cmake.in new file mode 100644 index 0000000..4693f2d --- /dev/null +++ b/Tests/CMakeTests/WhileTest.cmake.in @@ -0,0 +1,53 @@ +set(NUMBERS "") +set(COUNT 0) + +while(COUNT LESS 200) + set(NUMBERS "${NUMBERS} ${COUNT}") + set(COUNT "2${COUNT}") + + set(NCOUNT 3) + while(NCOUNT LESS 31) + set(NUMBERS "${NUMBERS} ${NCOUNT}") + set(NCOUNT "${NCOUNT}0") + endwhile() +endwhile(COUNT LESS 200) + +if(NOT NUMBERS STREQUAL " 0 3 30 20 3 30") + message(SEND_ERROR "while loop nesting error, result: '${NUMBERS}'") +endif() + +set(Missing-Argument-RESULT 1) +set(Missing-Argument-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Argument.cmake:1 \\(while\\):.*while called with incorrect number of arguments.*") + +include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") +check_cmake_test(While + Missing-Argument +) + +set(Missing-Endwhile-RESULT 1) +set(Missing-Endwhile-STDERR ".*CMake Error in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Missing-Endwhile.cmake:1 \\(while\\).*is not closed\\..*") + +check_cmake_test(While + Missing-Endwhile +) + +set(Endwhile-Mismatch-RESULT 0) +set(Endwhile-Mismatch-STDERR ".*CMake Warning \\(dev\\) in (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:.*A logical block opening on the line.*(@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Mismatch.cmake:1 \\(while\\).*with mis-matching arguments\\..*") + +check_cmake_test(While + Endwhile-Mismatch +) + +set(Endwhile-Alone-RESULT 1) +set(Endwhile-Alone-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\.\n.*$") + +check_cmake_test(While + Endwhile-Alone +) + +set(Endwhile-Alone-Args-RESULT 1) +set(Endwhile-Alone-Args-STDERR ".*CMake Error at (@CMAKE_CURRENT_SOURCE_DIR@/)?While-Endwhile-Alone-Args.cmake:1 \\(endwhile\\):.*An ENDWHILE command was found outside of a proper WHILE ENDWHILE.*structure\\. Or its arguments did not.*$") + +check_cmake_test(While + Endwhile-Alone-Args +) diff --git a/Tests/COnly/CMakeLists.txt b/Tests/COnly/CMakeLists.txt index 7742055..5ef0f1e 100644 --- a/Tests/COnly/CMakeLists.txt +++ b/Tests/COnly/CMakeLists.txt @@ -19,3 +19,5 @@ if("${LANG}" STREQUAL "C") else("${LANG}" STREQUAL "C") message(FATAL_ERROR "Bad language for file conly.c") endif("${LANG}" STREQUAL "C") + +add_library(testCModule MODULE testCModule.c) diff --git a/Tests/COnly/testCModule.c b/Tests/COnly/testCModule.c new file mode 100644 index 0000000..1a89292 --- /dev/null +++ b/Tests/COnly/testCModule.c @@ -0,0 +1,6 @@ +#ifdef _WIN32 +# define TEST_EXPORT __declspec(dllexport) +#else +# define TEST_EXPORT +#endif +TEST_EXPORT int testCModule(void) { return 0; } diff --git a/Tests/CTestUpdateCVS.cmake.in b/Tests/CTestUpdateCVS.cmake.in index a04673e..f7f5db6 100644 --- a/Tests/CTestUpdateCVS.cmake.in +++ b/Tests/CTestUpdateCVS.cmake.in @@ -18,6 +18,19 @@ set(CVS "@CVS_EXECUTABLE@") message(" cvs = ${CVS}") set(REPO ${TOP}/repo) + +# The MSYS cvs tool interprets "c:/" as a "machine:" name for SSH. +# Detect the MSYS cvs and convert the repo path to an MSYS path. +if(WIN32) + if(EXISTS "${CVS}") + file(STRINGS "${CVS}" cvs_is_msys LIMIT_COUNT 1 REGEX "[Mm][Ss][Yy][Ss]") + if(cvs_is_msys) + message(" '${CVS}' is from MSYS (contains '${cvs_is_msys}')") + string(REGEX REPLACE "^([A-Za-z]):" "/\\1" REPO "${REPO}") + endif() + endif() +endif() + set(CVSCMD ${CVS} -d${REPO}) # CVSNT requires an extra option to 'cvs init'. diff --git a/Tests/CTestUpdateHG.cmake.in b/Tests/CTestUpdateHG.cmake.in index 543ddd9..5a9daae 100644 --- a/Tests/CTestUpdateHG.cmake.in +++ b/Tests/CTestUpdateHG.cmake.in @@ -28,7 +28,7 @@ run_child( WORKING_DIRECTORY ${TOP}/repo.hg COMMAND ${HG} init ) -set(REPO file://${TOP}/repo.hg) +set(REPO file:///${TOP}/repo.hg) #----------------------------------------------------------------------------- # Import initial content into the repository. diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt index b505019..ec3ad39 100644 --- a/Tests/Complex/CMakeLists.txt +++ b/Tests/Complex/CMakeLists.txt @@ -199,7 +199,9 @@ CONFIGURE_FILE( ${Complex_SOURCE_DIR}/Library/dummy ${Complex_BINARY_DIR}/Library/dummylib.lib COPYONLY IMMEDIATE) -FOREACH (ext ${CMAKE_SHLIB_SUFFIX};.so;.a;.sl) +FOREACH (ext ${CMAKE_SHLIB_SUFFIX};.so;.a;.sl + ${CMAKE_SHARED_LIBRARY_SUFFIX}.2 + ${CMAKE_STATIC_LIBRARY_SUFFIX}.2) CONFIGURE_FILE( ${Complex_SOURCE_DIR}/Library/dummy ${Complex_BINARY_DIR}/Library/libdummylib${ext} @@ -216,6 +218,34 @@ FIND_LIBRARY(FIND_DUMMY_LIB PATHS ${Complex_BINARY_DIR}/Library DOC "find dummy lib") +# This doesn't work for platforms that have a shared library and an import +# library, like Windows with .dll and .lib. Limit is to ".so" now because it's +# known to work there. +IF(CMAKE_SHARED_LIBRARY_SUFFIX STREQUAL ".so") + FIND_LIBRARY(FIND_DUMMY_SHLIB_VERSIONED + NAMES libdummylib${CMAKE_SHARED_LIBRARY_SUFFIX}.2 + PATHS ${Complex_BINARY_DIR}/Library + DOC "find versioned dummy shared lib" + NO_DEFAULT_PATH) + + IF(NOT FIND_DUMMY_SHLIB_VERSIONED MATCHES "/libdummylib${CMAKE_SHARED_LIBRARY_SUFFIX}.2") + MESSAGE(SEND_ERROR "FIND_DUMMY_SHLIB_VERSIONED is not set correctly: " + "${FIND_DUMMY_SHLIB_VERSIONED}") + ENDIF() +ENDIF() + +# Static library, should work everywhere +FIND_LIBRARY(FIND_DUMMY_STLIB_VERSIONED + NAMES libdummylib${CMAKE_STATIC_LIBRARY_SUFFIX}.2 + PATHS ${Complex_BINARY_DIR}/Library + DOC "find versioned dummy static lib" + NO_DEFAULT_PATH) + +IF(NOT FIND_DUMMY_STLIB_VERSIONED MATCHES "/libdummylib${CMAKE_STATIC_LIBRARY_SUFFIX}.2") + MESSAGE(SEND_ERROR "FIND_DUMMY_STLIB_VERSIONED is not set correctly: " + "${FIND_DUMMY_STLIB_VERSIONED}") +ENDIF() + # # Test SET_SOURCE_FILES_PROPERTIES # diff --git a/Tests/Contracts/Trilinos-10-6/Patch.cmake b/Tests/Contracts/Trilinos-10-6/Patch.cmake index a7aae27..76051eb 100644 --- a/Tests/Contracts/Trilinos-10-6/Patch.cmake +++ b/Tests/Contracts/Trilinos-10-6/Patch.cmake @@ -2,6 +2,7 @@ if(NOT DEFINED source_dir) message(FATAL_ERROR "variable 'source_dir' not defined") endif() + if(NOT EXISTS "${source_dir}/CMakeLists.txt") message(FATAL_ERROR "error: No CMakeLists.txt file to patch!") endif() @@ -18,3 +19,20 @@ MESSAGE(\"Trilinos_WARNINGS_AS_ERRORS_FLAGS='\${Trilinos_WARNINGS_AS_ERRORS_FLAG ") file(APPEND "${source_dir}/CMakeLists.txt" "${text}") + + +if(NOT EXISTS "${source_dir}/CTestConfig.cmake") + message(FATAL_ERROR "error: No CTestConfig.cmake file to patch!") +endif() + +set(text " + +# +# Use newer than 10.6.1 CTestConfig settings from the Trilinos project. +# Send the Trilinos dashboards to the new Trilinos CDash server instance. +# +SET(CTEST_NIGHTLY_START_TIME \"04:00:00 UTC\") # 10 PM MDT or 9 PM MST +SET(CTEST_DROP_SITE \"testing.sandia.gov\") +") + +file(APPEND "${source_dir}/CTestConfig.cmake" "${text}") diff --git a/Tests/ConvLibrary/CMakeLists.txt b/Tests/ConvLibrary/CMakeLists.txt deleted file mode 100644 index afc1cb6..0000000 --- a/Tests/ConvLibrary/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project(ConvLibrary) - -# create a source list -set(foo_sources foo.cxx bar.c sub1/car.cxx) -# create a library foo from the sources -add_library(foo ${foo_sources}) -# get the object files from the target -get_target_property(OBJECT_FILES foo OBJECT_FILES) -message("${OBJECT_FILES}") -# set the object files as generated -set_source_files_properties(${OBJECT_FILES} PROPERTIES GENERATED true) -# create a library bar that contains the object files from foo -add_library(bar ${OBJECT_FILES}) -# set the linker language since bar only has .obj -set_target_properties(bar PROPERTIES LINKER_LANGUAGE CXX) -# make sure foo is built before bar -add_dependencies(bar foo) -add_executable(bartest bartest.cxx) -target_link_libraries(bartest bar) diff --git a/Tests/ConvLibrary/bar.c b/Tests/ConvLibrary/bar.c deleted file mode 100644 index d063082..0000000 --- a/Tests/ConvLibrary/bar.c +++ /dev/null @@ -1,4 +0,0 @@ -int bar() -{ - return 20; -} diff --git a/Tests/ConvLibrary/bartest.cxx b/Tests/ConvLibrary/bartest.cxx deleted file mode 100644 index ab95773..0000000 --- a/Tests/ConvLibrary/bartest.cxx +++ /dev/null @@ -1,37 +0,0 @@ -extern "C" int bar(); -int foo(); -int car(); - -#include <stdio.h> -int main() -{ - if(foo() == 10) - { - printf("foo is 10!\n"); - } - else - { - printf("foo is not 10 error!\n"); - return -1; - } - if(bar() == 20) - { - printf("bar is 20!\n"); - } - else - { - printf("bar is not 20 error!\n"); - return -1; - } - if(car() == 30) - { - printf("car is 30!\n"); - } - else - { - printf("car is not 30 error!\n"); - return -1; - } - printf("Test past\n"); - return 0; -} diff --git a/Tests/ConvLibrary/foo.cxx b/Tests/ConvLibrary/foo.cxx deleted file mode 100644 index 1f46ef4..0000000 --- a/Tests/ConvLibrary/foo.cxx +++ /dev/null @@ -1,4 +0,0 @@ -int foo() -{ - return 10; -} diff --git a/Tests/ConvLibrary/sub1/car.cxx b/Tests/ConvLibrary/sub1/car.cxx deleted file mode 100644 index aa66726..0000000 --- a/Tests/ConvLibrary/sub1/car.cxx +++ /dev/null @@ -1,4 +0,0 @@ -int car() -{ - return 30; -} diff --git a/Tests/CxxOnly/CMakeLists.txt b/Tests/CxxOnly/CMakeLists.txt index 5d27890..e62f3c7 100644 --- a/Tests/CxxOnly/CMakeLists.txt +++ b/Tests/CxxOnly/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(testcxx1.my STATIC libcxx1.cxx ${EXTRA_SRCS}) add_library(testcxx2 SHARED libcxx2.cxx) add_executable (CxxOnly cxxonly.cxx) target_link_libraries(CxxOnly testcxx1.my testcxx2) + +add_library(testCxxModule MODULE testCxxModule.cxx) diff --git a/Tests/CxxOnly/testCxxModule.cxx b/Tests/CxxOnly/testCxxModule.cxx new file mode 100644 index 0000000..dd16d2b --- /dev/null +++ b/Tests/CxxOnly/testCxxModule.cxx @@ -0,0 +1,6 @@ +#ifdef _WIN32 +# define TEST_EXPORT __declspec(dllexport) +#else +# define TEST_EXPORT +#endif +TEST_EXPORT int testCxxModule(void) { return 0; } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index e65e362..a21e1b0 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -137,3 +137,14 @@ add_library(imp_lib1 STATIC imp_lib1.c) target_link_libraries(imp_lib1 exp_testLib2) add_library(imp_lib1b STATIC imp_lib1.c) target_link_libraries(imp_lib1b bld_testLib2) + +#----------------------------------------------------------------------------- +# Test that handling imported targets, including transitive dependencies, +# works in CheckFunctionExists (...and hopefully all other try_compile() checks +include(CheckFunctionExists) +unset(HAVE_TESTLIB1_FUNCTION CACHE) +set(CMAKE_REQUIRED_LIBRARIES exp_testLib2) +check_function_exists(testLib1 HAVE_TESTLIB1_FUNCTION) +if (NOT HAVE_TESTLIB1_FUNCTION) + message(SEND_ERROR "Using imported target testLib2 in check_function_exists() failed !") +endif() diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index ac70129..7a76261 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -280,6 +280,18 @@ if(do_cvs_tests) set_property(TARGET ${proj} PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing") + # The MSYS cvs tool interprets "c:/" as a "machine:" name for SSH. + # Detect the MSYS cvs and convert the repo path to an MSYS path. + if(WIN32) + if(EXISTS "${CVS_EXECUTABLE}") + file(STRINGS "${CVS_EXECUTABLE}" cvs_is_msys LIMIT_COUNT 1 REGEX "[Mm][Ss][Yy][Ss]") + if(cvs_is_msys) + message(STATUS "'${CVS_EXECUTABLE}' is from MSYS (contains '${cvs_is_msys}')") + string(REGEX REPLACE "^([A-Za-z]):" "/\\1" local_cvs_repo "${local_cvs_repo}") + endif() + endif() + endif() + # CVS by date stamp: # set(proj TutorialStep1-CVS-20090626) diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt index 9a4bdfe..a4f213b 100644 --- a/Tests/FindPackageTest/CMakeLists.txt +++ b/Tests/FindPackageTest/CMakeLists.txt @@ -305,13 +305,39 @@ STRING(REGEX REPLACE "-.*$" "" version ${CMAKE_VERSION}) FIND_PACKAGE(CMakeTestExportPackage 1.${version} EXACT REQUIRED) #----------------------------------------------------------------------------- -# Test write_basic_config_version_file(). +# Test configure_package_config_file(). -include(WriteBasicConfigVersionFile) +include(CMakePackageConfigHelpers) -write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake - VERSION 1.2.3 - COMPATIBILITY AnyNewerVersion) +set(INCLUDE_INSTALL_DIR include ) +set(SHARE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/" ) +set(CURRENT_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}" ) + +configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}" + PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR + ) + +include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake") + +if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include") + message(SEND_ERROR "RELOC_INCLUDE_DIR set by configure_package_config_file() is set to \"${RELOC_INCLUDE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/include\")") +endif() + +if(NOT "${RELOC_SHARE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/share/") + message(SEND_ERROR "RELOC_SHARE_DIR set by configure_package_config_file() is set to \"${RELOC_SHARE_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}/share/\")") +endif() + +if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}") + message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")") +endif() + +#----------------------------------------------------------------------------- +# Test write_basic_config_version_file(). + +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake + VERSION 1.2.3 + COMPATIBILITY AnyNewerVersion) set(PACKAGE_FIND_VERSION 2.3.4) include(${CMAKE_CURRENT_BINARY_DIR}/Foo123ConfigVersion.cmake) @@ -345,6 +371,7 @@ endif() ####################### +include(WriteBasicConfigVersionFile) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/Boo123ConfigVersion.cmake VERSION 1.2.3 diff --git a/Tests/FindPackageTest/RelocatableConfig.cmake.in b/Tests/FindPackageTest/RelocatableConfig.cmake.in new file mode 100644 index 0000000..7a34b2f --- /dev/null +++ b/Tests/FindPackageTest/RelocatableConfig.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +set(RELOC_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +set(RELOC_SHARE_DIR "@PACKAGE_SHARE_INSTALL_DIR@") +set_and_check(RELOC_BUILD_DIR "@PACKAGE_CURRENT_BUILD_DIR@") diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt index 60b8c22..60f5e5e 100644 --- a/Tests/IncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/CMakeLists.txt @@ -45,3 +45,5 @@ else() set_target_properties(IncludeDirectories PROPERTIES COMPILE_FLAGS "-ITarProp") endif() + +add_subdirectory(TargetIncludeDirectories) diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt new file mode 100644 index 0000000..2cf36f5 --- /dev/null +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -0,0 +1,26 @@ + +cmake_minimum_required(VERSION 2.8) + +project(TargetIncludeDirectories) + +macro(create_header _name) + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_name}") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_name}/${_name}.h" + "//${_name}.h + ") +endmacro() + +create_header(bar) +create_header(bat) +create_header(foo) +create_header(baz) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +include_directories("${CMAKE_CURRENT_BINARY_DIR}/bar") + +add_executable(TargetIncludeDirectories main.cpp) +set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bat") +set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo") + +include_directories("${CMAKE_CURRENT_BINARY_DIR}/baz") diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp new file mode 100644 index 0000000..8aa3532 --- /dev/null +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/main.cpp @@ -0,0 +1,10 @@ + +#include "bar.h" +#include "bat.h" +#include "foo.h" +#include "baz.h" + +int main(int, char**) +{ + return 0; +} diff --git a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt index c7cc090..c362e79 100644 --- a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt +++ b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt @@ -24,6 +24,12 @@ IF ("${PROJECT_SOURCE_DIR}" STREQUAL "${ANOTHER_PROJ_SOURCE_DIR}") MATH(EXPR MAXPATH "${MAXPATH} - 46") ENDIF() + # Ninja imposes a maximum path component count of 30. Permit more + # path components in the source path. + IF(${CMAKE_GENERATOR} MATCHES "Ninja") + MATH(EXPR MAXPATH "${MAXPATH} - 44") + ENDIF() + # MAXPATH less 25 for last /and/deeper/simple.cxx part and small safety MATH(EXPR MAXPATH "${MAXPATH} - 25") STRING(LENGTH "${DEEPDIR}" DEEPDIR_LEN) diff --git a/Tests/Qt4Deploy/CMakeLists.txt b/Tests/Qt4Deploy/CMakeLists.txt new file mode 100644 index 0000000..646ea9f --- /dev/null +++ b/Tests/Qt4Deploy/CMakeLists.txt @@ -0,0 +1,70 @@ +cmake_minimum_required(VERSION 2.8) + +project(Qt4Deploy) +set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/install) + +find_package(Qt4 REQUIRED QtMain QtCore QtSql) +include(${QT_USE_FILE}) + +add_executable(testdeploy MACOSX_BUNDLE testdeploy.cpp) +target_link_libraries(testdeploy ${QT_LIBRARIES}) +set_target_properties(testdeploy PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}") + +if(CMAKE_CONFIGURATION_TYPES AND QT_QTCORE_LIBRARY_RELEASE AND QT_QTCORE_LIBRARY_DEBUG) + # note: installing debug Qt libraries from a Qt installation configured with + # -debug-and-release not yet supported (very low priority). + install(CODE " + if(\"\${CMAKE_INSTALL_CONFIG_NAME}\" MATCHES \"^([Dd][Ee][Bb][Uu][Gg])$\") + return() + endif() + ") +endif() + +# install the Qt4 app with qsqlite plugin +install(CODE "file(REMOVE_RECURSE \"${CMAKE_INSTALL_PREFIX}\")") +install(TARGETS testdeploy DESTINATION .) +include(../../Modules/DeployQt4.cmake) +if(APPLE) + install_qt4_executable(testdeploy.app "qsqlite") +elseif(WIN32) + install_qt4_executable(testdeploy.exe "qsqlite") +else() + install_qt4_executable(testdeploy "qsqlite") +endif() + + +# test depends on standard qsqlite plugin +if(QT_QSQLITE_PLUGIN_DEBUG OR QT_QSQLITE_PLUGIN_RELEASE) + + # test the deployed Qt application + if(APPLE) + install(CODE " + message(STATUS \"executing: ${CMAKE_INSTALL_PREFIX}/testdeploy.app/Contents/MacOS/testdeploy\") + execute_process(COMMAND \"${CMAKE_INSTALL_PREFIX}/testdeploy.app/Contents/MacOS/testdeploy\" + RESULT_VARIABLE result) + if(NOT result STREQUAL \"0\") + message(FATAL_ERROR \"error running testdeploy app\") + endif() + ") + else() + install(CODE " + message(STATUS \"executing: ${CMAKE_INSTALL_PREFIX}/testdeploy\") + execute_process(COMMAND \"${CMAKE_INSTALL_PREFIX}/testdeploy\" + RESULT_VARIABLE result) + if(NOT result STREQUAL \"0\") + message(FATAL_ERROR \"error running testdeploy app\") + endif() + ") + endif() + + # custom target to install and test the installation at build time + if(CMAKE_CONFIGURATION_TYPES) + set(install_config "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}") + endif() + + add_custom_target(testdeploy_test ALL + COMMAND ${CMAKE_COMMAND} ${install_config} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake + COMMENT "${CMAKE_COMMAND} ${install_config} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake" + DEPENDS testdeploy) + +endif() diff --git a/Tests/Qt4Deploy/testdeploy.cpp b/Tests/Qt4Deploy/testdeploy.cpp new file mode 100644 index 0000000..8b9c8d6 --- /dev/null +++ b/Tests/Qt4Deploy/testdeploy.cpp @@ -0,0 +1,29 @@ +#include <QCoreApplication> +#include <QSqlDatabase> +#include <QLibraryInfo> +#include <QDebug> +#include <QStringList> + +int main(int argc, char** argv) +{ + QCoreApplication app(argc, argv); + + qDebug() << "App path:" << app.applicationDirPath(); + qDebug() << "Plugin path:" << QLibraryInfo::location(QLibraryInfo::PluginsPath); + + bool foundSqlite = false; + + qDebug() << "Supported Database Drivers:"; + foreach(const QString &sqlDriver, QSqlDatabase::drivers()) + { + qDebug() << " " << sqlDriver; + if(sqlDriver == "QSQLITE") + foundSqlite = true; + } + + if(foundSqlite) + qDebug() << "Found sqlite support from plugin."; + else + qDebug() << "Could not find sqlite support from plugin."; + return foundSqlite ? 0 : 1; +} diff --git a/Tests/README b/Tests/README new file mode 100644 index 0000000..8b2fda8 --- /dev/null +++ b/Tests/README @@ -0,0 +1,39 @@ +If you think about adding a new testcase then here is a small checklist you +can run through to find a proper place for it. Go through the list from the +beginning and stop once you find something that matches your tests needs, +i.e. if you will test a module and only need the configure mode use the +instructions from section 2, not 3. + +1. Your testcase can run in CMake script mode, i.e. "cmake -P something" + +Put your test in Tests/CMakeTests/ directory as a .cmake.in file. It will be +put into the test binary directory by configure_file(... @ONLY) and run from +there. Use the AddCMakeTest() macro in Tests/CMakeTests/CMakeLists.txt to add +your test to the test runs. + +2. Your test needs CMake to run in configure mode, but will not build anything + +This includes tests that will build something using try_compile() and friends, +but nothing that expects add_executable(), add_library(), or add_test() to run. + +If the test configures the project only once and it must succeed then put it +into the Tests/CMakeOnly/ directory. Create a subdirectory named like your +test and write the CMakeLists.txt you need into that subdirectory. Use the +add_CMakeOnly_test() macro from Tests/CMakeOnly/CMakeLists.txt to add your +test to the test runs. + +If the test configures the project with multiple variations and verifies +success or failure each time then put it into the Tests/RunCMake/ directory. +Read the instructions in Tests/RunCMake/CMakeLists.txt to add a test. + +3. If you are testing something from the Modules directory + +Put your test in the Tests/Modules/ directory. Create a subdirectory there +named after your test. Use the ADD_TEST_MACRO macro from Tests/CMakeLists.txt +to add your test to the test run. If you have put your stuff in +Tests/Modules/Foo then you call it using ADD_TEST_MACRO(Module.Foo Foo). + +4. You are doing other stuff. + +Find a good place ;) In doubt mail to cmake-developers@cmake.org and ask for +advise. diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt new file mode 100644 index 0000000..63fc9f8 --- /dev/null +++ b/Tests/RunCMake/CMakeLists.txt @@ -0,0 +1,44 @@ +# This directory contains tests that run CMake to configure a project +# but do not actually build anything. To add a test: +# +# 1.) Add a subdirectory named for the test. +# +# 2.) Call add_RunCMake_test and pass the test directory name. +# +# 3.) Create a RunCMakeTest.cmake script in the directory containing +# include(RunCMake) +# run_cmake(SubTest1) +# ... +# run_cmake(SubTestN) +# where SubTest1..SubTestN are sub-test names each corresponding to +# an independent CMake run and project configuration. +# +# 3.) Create a CMakeLists.txt file in the directory containing +# cmake_minimum_required(...) +# project(${RunCMake_TEST} NONE) # or languages needed +# include(${RunCMake_TEST}.cmake) +# where "${RunCMake_TEST}" is literal. A value for RunCMake_TEST +# will be passed to CMake by the run_cmake macro when running each +# sub-test. +# +# 4.) Create a <SubTest>.cmake file for each sub-test named above +# containing the actual test code. Optionally create files +# containing expected test results: +# <SubTest>-result.txt = Process result expected if not "0" +# <SubTest>-stdout.txt = Regex matching expected stdout content +# <SubTest>-stderr.txt = Regex matching expected stderr content +# Note that trailing newlines will be stripped from actual test +# output before matching against the stdout and stderr expressions. + +macro(add_RunCMake_test test) + add_test(RunCMake.${test} ${CMAKE_CMAKE_COMMAND} + -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR} + -DRunCMake_GENERATOR=${CMAKE_TEST_GENERATOR} + -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test} + -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test} + -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake" + ) +endmacro() + +add_RunCMake_test(build_command) +add_RunCMake_test(find_package) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake new file mode 100644 index 0000000..2639463 --- /dev/null +++ b/Tests/RunCMake/RunCMake.cmake @@ -0,0 +1,69 @@ +foreach(arg + RunCMake_GENERATOR + RunCMake_SOURCE_DIR + RunCMake_BINARY_DIR + ) + if(NOT DEFINED ${arg}) + message(FATAL_ERROR "${arg} not given!") + endif() +endforeach() + +function(run_cmake test) + set(top_src "${RunCMake_SOURCE_DIR}") + set(top_bin "${RunCMake_BINARY_DIR}") + if(EXISTS ${top_src}/${test}-result.txt) + file(READ ${top_src}/${test}-result.txt expect_result) + string(REGEX REPLACE "\n+$" "" expect_result "${expect_result}") + else() + set(expect_result 0) + endif() + foreach(o out err) + if(EXISTS ${top_src}/${test}-std${o}.txt) + file(READ ${top_src}/${test}-std${o}.txt expect_std${o}) + string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") + else() + unset(expect_std${o}) + endif() + endforeach() + set(source_dir "${top_src}") + set(binary_dir "${top_bin}/${test}-build") + file(REMOVE_RECURSE "${binary_dir}") + file(MAKE_DIRECTORY "${binary_dir}") + execute_process( + COMMAND ${CMAKE_COMMAND} "${source_dir}" + -G "${RunCMake_GENERATOR}" -DRunCMake_TEST=${test} + WORKING_DIRECTORY "${binary_dir}" + OUTPUT_VARIABLE actual_stdout + ERROR_VARIABLE actual_stderr + RESULT_VARIABLE actual_result + ) + set(msg "") + if(NOT "${actual_result}" STREQUAL "${expect_result}") + set(msg "${msg}Result is [${actual_result}], not [${expect_result}].\n") + endif() + foreach(o out err) + string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}") + set(expect_${o} "") + if(DEFINED expect_std${o}) + if(NOT "${actual_std${o}}" MATCHES "${expect_std${o}}") + string(REGEX REPLACE "\n" "\n expect-${o}> " expect_${o} + " expect-${o}> ${expect_std${o}}") + set(expect_${o} "Expected std${o} to match:\n${expect_${o}}\n") + set(msg "${msg}std${o} does not match that expected.\n") + endif() + endif() + endforeach() + if(msg) + string(REGEX REPLACE "\n" "\n actual-out> " actual_out " actual-out> ${actual_stdout}") + string(REGEX REPLACE "\n" "\n actual-err> " actual_err " actual-err> ${actual_stderr}") + message(SEND_ERROR "${test} - FAILED:\n" + "${msg}" + "${expect_out}" + "Actual stdout:\n${actual_out}\n" + "${expect_err}" + "Actual stderr:\n${actual_err}\n" + ) + else() + message(STATUS "${test} - PASSED") + endif() +endfunction() diff --git a/Tests/CMakeCommands/build_command/CMakeLists.txt b/Tests/RunCMake/build_command/CMakeLists.txt index 990ac90..0fbb948 100644 --- a/Tests/CMakeCommands/build_command/CMakeLists.txt +++ b/Tests/RunCMake/build_command/CMakeLists.txt @@ -1,3 +1,7 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) + # This CMakeLists file is *sometimes expected* to result in a configure error. # # expect this to succeed: @@ -12,12 +16,9 @@ # ...even purposefully calling it with known-bad argument lists to cover # error handling code. # -cmake_minimum_required(VERSION 2.8) -project(test_build_command) set(cmd "initial") -message("CTEST_FULL_OUTPUT") message("0. begin") if(TEST_ERROR_CONDITIONS) diff --git a/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt b/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt new file mode 100644 index 0000000..331885b --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsOFF-stderr.txt @@ -0,0 +1 @@ +skipping cases 1, 2 and 3 because TEST_ERROR_CONDITIONS is OFF diff --git a/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt b/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt new file mode 100644 index 0000000..cf66a9d --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsOFF-stdout.txt @@ -0,0 +1 @@ +Build files have been written to: diff --git a/Tests/RunCMake/build_command/ErrorsOFF.cmake b/Tests/RunCMake/build_command/ErrorsOFF.cmake new file mode 100644 index 0000000..a243fab --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsOFF.cmake @@ -0,0 +1 @@ +set(TEST_ERROR_CONDITIONS OFF) diff --git a/Tests/RunCMake/build_command/ErrorsON-result.txt b/Tests/RunCMake/build_command/ErrorsON-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsON-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/build_command/ErrorsON-stderr.txt b/Tests/RunCMake/build_command/ErrorsON-stderr.txt new file mode 100644 index 0000000..0be7475 --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsON-stderr.txt @@ -0,0 +1,12 @@ +CMake Error at CMakeLists.txt:[0-9]+ \(build_command\): + build_command requires at least one argument naming a CMake variable + ++ +1. cmd='initial' +CMake Error at CMakeLists.txt:[0-9]+ \(build_command\): + build_command unknown argument "BOGUS" + ++ +2. cmd='initial' +CMake Error at CMakeLists.txt:[0-9]+ \(build_command\): + build_command unknown argument "STUFF" diff --git a/Tests/RunCMake/build_command/ErrorsON-stdout.txt b/Tests/RunCMake/build_command/ErrorsON-stdout.txt new file mode 100644 index 0000000..841dd0d --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsON-stdout.txt @@ -0,0 +1 @@ +Configuring incomplete, errors occurred! diff --git a/Tests/RunCMake/build_command/ErrorsON.cmake b/Tests/RunCMake/build_command/ErrorsON.cmake new file mode 100644 index 0000000..27814bf --- /dev/null +++ b/Tests/RunCMake/build_command/ErrorsON.cmake @@ -0,0 +1 @@ +set(TEST_ERROR_CONDITIONS ON) diff --git a/Tests/RunCMake/build_command/RunCMakeTest.cmake b/Tests/RunCMake/build_command/RunCMakeTest.cmake new file mode 100644 index 0000000..4525c57 --- /dev/null +++ b/Tests/RunCMake/build_command/RunCMakeTest.cmake @@ -0,0 +1,4 @@ +include(RunCMake) + +run_cmake(ErrorsOFF) +run_cmake(ErrorsON) diff --git a/Tests/RunCMake/find_package/CMakeLists.txt b/Tests/RunCMake/find_package/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/find_package/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/find_package/MissingConfig-stderr.txt b/Tests/RunCMake/find_package/MissingConfig-stderr.txt new file mode 100644 index 0000000..1eae0bb --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfig-stderr.txt @@ -0,0 +1,19 @@ +CMake Warning at MissingConfig.cmake:1 \(find_package\): + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Warning at MissingConfig.cmake:2 \(message\): + This warning must be reachable. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/find_package/MissingConfig.cmake b/Tests/RunCMake/find_package/MissingConfig.cmake new file mode 100644 index 0000000..238e7e4 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfig.cmake @@ -0,0 +1,2 @@ +find_package(NotHere CONFIG) +message(WARNING "This warning must be reachable.") diff --git a/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt b/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt new file mode 100644 index 0000000..10e71fa --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning at MissingConfigOneName.cmake:1 \(find_package\): + Could not find a package configuration file named "NotHereConfig.cmake" + provided by package "NotHere". + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MissingConfigOneName.cmake b/Tests/RunCMake/find_package/MissingConfigOneName.cmake new file mode 100644 index 0000000..11676a9 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigOneName.cmake @@ -0,0 +1 @@ +find_package(NotHere CONFIGS NotHereConfig.cmake) diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-result.txt b/Tests/RunCMake/find_package/MissingConfigRequired-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigRequired-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt new file mode 100644 index 0000000..2ba774a --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt @@ -0,0 +1,13 @@ +CMake Error at MissingConfigRequired.cmake:1 \(find_package\): + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/find_package/MissingConfigRequired.cmake b/Tests/RunCMake/find_package/MissingConfigRequired.cmake new file mode 100644 index 0000000..0ae6702 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigRequired.cmake @@ -0,0 +1,2 @@ +find_package(NotHere CONFIG REQUIRED) +message(FATAL_ERROR "This error must not be reachable.") diff --git a/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt b/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt new file mode 100644 index 0000000..2f5086e --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt @@ -0,0 +1,13 @@ +CMake Warning at MissingConfigVersion.cmake:1 \(find_package\): + Could not find a package configuration file provided by "NotHere" + \(requested version 1\.2\) with any of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MissingConfigVersion.cmake b/Tests/RunCMake/find_package/MissingConfigVersion.cmake new file mode 100644 index 0000000..ac35a79 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigVersion.cmake @@ -0,0 +1 @@ +find_package(NotHere 1.2 CONFIG) diff --git a/Tests/RunCMake/find_package/MissingModule-stderr.txt b/Tests/RunCMake/find_package/MissingModule-stderr.txt new file mode 100644 index 0000000..2ad460f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingModule-stderr.txt @@ -0,0 +1,26 @@ +CMake Warning at MissingModule.cmake:1 \(find_package\): + No "FindNotHere.cmake" found in CMAKE_MODULE_PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Warning \(dev\) at MissingModule.cmake:1 \(find_package\): + FindNotHere.cmake must either be part of this project itself, in this case + adjust CMAKE_MODULE_PATH so that it points to the correct location inside + its source tree. + + Or it must be installed by a package which has already been found via + find_package\(\). In this case make sure that package has indeed been found + and adjust CMAKE_MODULE_PATH to contain the location where that package has + installed FindNotHere.cmake. This must be a location provided by that + package. This error in general means that the buildsystem of this project + is relying on a Find-module without ensuring that it is actually available. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning at MissingModule.cmake:2 \(message\): + This warning must be reachable. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/find_package/MissingModule.cmake b/Tests/RunCMake/find_package/MissingModule.cmake new file mode 100644 index 0000000..76bcef2 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingModule.cmake @@ -0,0 +1,2 @@ +find_package(NotHere MODULE) +message(WARNING "This warning must be reachable.") diff --git a/Tests/RunCMake/find_package/MissingModuleRequired-result.txt b/Tests/RunCMake/find_package/MissingModuleRequired-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingModuleRequired-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt b/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt new file mode 100644 index 0000000..fec05f1 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingModuleRequired-stderr.txt @@ -0,0 +1,21 @@ +CMake Error at MissingModuleRequired.cmake:1 \(find_package\): + No "FindNotHere.cmake" found in CMAKE_MODULE_PATH. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Warning \(dev\) at MissingModuleRequired.cmake:1 \(find_package\): + FindNotHere.cmake must either be part of this project itself, in this case + adjust CMAKE_MODULE_PATH so that it points to the correct location inside + its source tree. + + Or it must be installed by a package which has already been found via + find_package\(\). In this case make sure that package has indeed been found + and adjust CMAKE_MODULE_PATH to contain the location where that package has + installed FindNotHere.cmake. This must be a location provided by that + package. This error in general means that the buildsystem of this project + is relying on a Find-module without ensuring that it is actually available. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/find_package/MissingModuleRequired.cmake b/Tests/RunCMake/find_package/MissingModuleRequired.cmake new file mode 100644 index 0000000..897eda6 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingModuleRequired.cmake @@ -0,0 +1,2 @@ +find_package(NotHere MODULE REQUIRED) +message(FATAL_ERROR "This error must not be reachable.") diff --git a/Tests/RunCMake/find_package/MissingNormal-stderr.txt b/Tests/RunCMake/find_package/MissingNormal-stderr.txt new file mode 100644 index 0000000..f4c6fba --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormal-stderr.txt @@ -0,0 +1,23 @@ +CMake Warning at MissingNormal.cmake:1 \(find_package\): + By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has + asked CMake to find a package configuration file provided by "NotHere", but + CMake did not find one. + + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Warning at MissingNormal.cmake:2 \(message\): + This warning must be reachable. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/find_package/MissingNormal.cmake b/Tests/RunCMake/find_package/MissingNormal.cmake new file mode 100644 index 0000000..fb90e01 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormal.cmake @@ -0,0 +1,2 @@ +find_package(NotHere) +message(WARNING "This warning must be reachable.") diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-result.txt b/Tests/RunCMake/find_package/MissingNormalRequired-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalRequired-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt new file mode 100644 index 0000000..7bb7902 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at MissingNormalRequired.cmake:1 \(find_package\): + By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has + asked CMake to find a package configuration file provided by "NotHere", but + CMake did not find one. + + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/find_package/MissingNormalRequired.cmake b/Tests/RunCMake/find_package/MissingNormalRequired.cmake new file mode 100644 index 0000000..33353d8 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalRequired.cmake @@ -0,0 +1,2 @@ +find_package(NotHere REQUIRED) +message(FATAL_ERROR "This error must not be reachable.") diff --git a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt new file mode 100644 index 0000000..36de800 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt @@ -0,0 +1,17 @@ +CMake Warning at MissingNormalVersion.cmake:1 \(find_package\): + By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has + asked CMake to find a package configuration file provided by "NotHere", but + CMake did not find one. + + Could not find a package configuration file provided by "NotHere" + \(requested version 1\.2\) with any of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MissingNormalVersion.cmake b/Tests/RunCMake/find_package/MissingNormalVersion.cmake new file mode 100644 index 0000000..2d9ce4e --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalVersion.cmake @@ -0,0 +1 @@ +find_package(NotHere 1.2) diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt new file mode 100644 index 0000000..d34f23c --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt @@ -0,0 +1,30 @@ +CMake Warning \(dev\) at MissingNormalWarnNoModuleNew.cmake:3 \(find_package\): + find_package called without either MODULE or CONFIG option and no + FindNotHere.cmake module is in CMAKE_MODULE_PATH. Add MODULE to + exclusively request Module mode and fail if FindNotHere.cmake is missing. + Add CONFIG to exclusively request Config mode and search for a package + configuration file provided by NotHere \(NotHereConfig.cmake or + nothere-config.cmake\). + + \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.\) +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning at MissingNormalWarnNoModuleNew.cmake:3 \(find_package\): + By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has + asked CMake to find a package configuration file provided by "NotHere", but + CMake did not find one. + + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake new file mode 100644 index 0000000..0211249 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew.cmake @@ -0,0 +1,3 @@ +set(CMAKE_FIND_PACKAGE_WARN_NO_MODULE 1) +set(CMAKE_MINIMUM_REQUIRED_VERSION 2.8.8) +find_package(NotHere) diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt new file mode 100644 index 0000000..b336b56 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt @@ -0,0 +1,29 @@ +CMake Warning \(dev\) at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\): + find_package called without NO_MODULE option and no FindNotHere.cmake + module is in CMAKE_MODULE_PATH. Add NO_MODULE to exclusively request + Config mode and search for a package configuration file provided by NotHere + \(NotHereConfig.cmake or nothere-config.cmake\). Otherwise make + FindNotHere.cmake available in CMAKE_MODULE_PATH. + + \(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this warning.\) +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning at MissingNormalWarnNoModuleOld.cmake:2 \(find_package\): + By not providing "FindNotHere.cmake" in CMAKE_MODULE_PATH this project has + asked CMake to find a package configuration file provided by "NotHere", but + CMake did not find one. + + Could not find a package configuration file provided by "NotHere" with any + of the following names: + + NotHereConfig.cmake + nothere-config.cmake + + Add the installation prefix of "NotHere" to CMAKE_PREFIX_PATH or set + "NotHere_DIR" to a directory containing one of the above files. If + "NotHere" provides a separate development package or SDK, be sure it has + been installed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake new file mode 100644 index 0000000..1c4a775 --- /dev/null +++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld.cmake @@ -0,0 +1,2 @@ +set(CMAKE_FIND_PACKAGE_WARN_NO_MODULE 1) +find_package(NotHere) diff --git a/Tests/RunCMake/find_package/MixedModeOptions-result.txt b/Tests/RunCMake/find_package/MixedModeOptions-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/find_package/MixedModeOptions-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt b/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt new file mode 100644 index 0000000..b867022 --- /dev/null +++ b/Tests/RunCMake/find_package/MixedModeOptions-stderr.txt @@ -0,0 +1,14 @@ +CMake Error at MixedModeOptions.cmake:1 \(find_package\): + find_package given options exclusive to Module mode: + + MODULE + + and options exclusive to Config mode: + + CONFIG + CONFIGS + NO_DEFAULT_PATH + + The options are incompatible. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/MixedModeOptions.cmake b/Tests/RunCMake/find_package/MixedModeOptions.cmake new file mode 100644 index 0000000..7f78ee0 --- /dev/null +++ b/Tests/RunCMake/find_package/MixedModeOptions.cmake @@ -0,0 +1 @@ +find_package(NotHere MODULE CONFIG CONFIGS NotHereConfig.cmake NO_DEFAULT_PATH) diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake new file mode 100644 index 0000000..ba57f99 --- /dev/null +++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake @@ -0,0 +1,14 @@ +include(RunCMake) + +run_cmake(MissingNormal) +run_cmake(MissingNormalRequired) +run_cmake(MissingNormalVersion) +run_cmake(MissingNormalWarnNoModuleOld) +run_cmake(MissingNormalWarnNoModuleNew) +run_cmake(MissingModule) +run_cmake(MissingModuleRequired) +run_cmake(MissingConfig) +run_cmake(MissingConfigOneName) +run_cmake(MissingConfigRequired) +run_cmake(MissingConfigVersion) +run_cmake(MixedModeOptions) diff --git a/Tests/SBCS/CMakeLists.txt b/Tests/SBCS/CMakeLists.txt new file mode 100644 index 0000000..b3c3c2c --- /dev/null +++ b/Tests/SBCS/CMakeLists.txt @@ -0,0 +1,6 @@ +# a SBCS test case +project (SBCS) + +add_definitions(-D_SBCS) + +add_executable (SBCS SBCS.cxx) diff --git a/Tests/SBCS/SBCS.cxx b/Tests/SBCS/SBCS.cxx new file mode 100644 index 0000000..6ce2c9f --- /dev/null +++ b/Tests/SBCS/SBCS.cxx @@ -0,0 +1,22 @@ +// Test to verify that _SBCS being defined causes CharacterSet to be set to 0 (Single Byte Character Set) + +int main () +{ +#ifdef _UNICODE + bool UnicodeSet=true; +#else + bool UnicodeSet=false; +#endif + +#ifdef _MBCS + bool MBCSSet=true; +#else + bool MBCSSet=false; +#endif + + // if neither _UNICODE nor _MBCS is set, CharacterSet must be set to SBCS. + bool SBCSSet=(!UnicodeSet && !MBCSSet); + + // Reverse boolean to indicate error case correctly + return !SBCSSet; +} diff --git a/Tests/VSGNUFortran/CMakeLists.txt b/Tests/VSGNUFortran/CMakeLists.txt new file mode 100644 index 0000000..229c315 --- /dev/null +++ b/Tests/VSGNUFortran/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.8) +project(VSGNUFortran) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") + +# force the executable to be put out of Debug/Release dir +# because gmake build of fortran will not be in a config +# directory, and for easier testing we want the exe and .dll +# to be in the same directory. +if(CMAKE_CONFIGURATION_TYPES) + foreach(config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER "${config}" config) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config} + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + endforeach() +endif() + +add_subdirectory(subdir) +include_directories(${VSGNUFortran_BINARY_DIR}/subdir/fortran) +add_subdirectory(c_code) +# use a cmake script to run the executable so that PATH +# can be set with the MinGW/bin in it, and the fortran +# runtime libraries can be found. +configure_file(runtest.cmake.in runtest.cmake @ONLY) diff --git a/Tests/VSGNUFortran/c_code/CMakeLists.txt b/Tests/VSGNUFortran/c_code/CMakeLists.txt new file mode 100644 index 0000000..27d22fd --- /dev/null +++ b/Tests/VSGNUFortran/c_code/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(c_using_fortran main.c) +target_link_libraries(c_using_fortran hello) diff --git a/Tests/VSGNUFortran/c_code/main.c b/Tests/VSGNUFortran/c_code/main.c new file mode 100644 index 0000000..391bf26 --- /dev/null +++ b/Tests/VSGNUFortran/c_code/main.c @@ -0,0 +1,7 @@ +#include <HelloWorldFCMangle.h> // created by FortranCInterface +extern void FC_hello(void); +int main() +{ + FC_hello(); + return 0; +} diff --git a/Tests/VSGNUFortran/runtest.cmake.in b/Tests/VSGNUFortran/runtest.cmake.in new file mode 100644 index 0000000..987207b --- /dev/null +++ b/Tests/VSGNUFortran/runtest.cmake.in @@ -0,0 +1,23 @@ +get_filename_component(MINGW_PATH "@MINGW_GFORTRAN@" PATH) +if(NOT EXISTS "${MINGW_PATH}") + set(test_exe + "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran@CMAKE_EXECUTABLE_SUFFIX@") + message("run: ${test_exe}") + execute_process(COMMAND "${test_exe}" + RESULT_VARIABLE res) + if(NOT "${res}" EQUAL 0) + message(FATAL_ERROR "${test_exe} returned a non 0 value") + endif() + return() +endif() +file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH) +string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}") +message("${MINGW_PATH}") +set(test_exe "@VSGNUFortran_BINARY_DIR@/bin/c_using_fortran.exe") +set(ENV{PATH} "${MINGW_PATH}";$ENV{PATH}) +message("run ${test_exe}") +execute_process(COMMAND "${test_exe}" + RESULT_VARIABLE res) +if(NOT "${res}" EQUAL 0) + message(FATAL_ERROR "${test_exe} returned a non 0 value") +endif() diff --git a/Tests/VSGNUFortran/subdir/CMakeLists.txt b/Tests/VSGNUFortran/subdir/CMakeLists.txt new file mode 100644 index 0000000..0b99199 --- /dev/null +++ b/Tests/VSGNUFortran/subdir/CMakeLists.txt @@ -0,0 +1,16 @@ +include(CMakeAddFortranSubdirectory) +# add the fortran subdirectory as a fortran project +# the subdir is fortran, the project is FortranHello +cmake_add_fortran_subdirectory(fortran + PROJECT FortranHello # project name in toplevel CMakeLists.txt + ARCHIVE_DIR ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + RUNTIME_DIR bin # ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + LIBRARIES hello world # target libraries created + CMAKE_COMMAND_LINE + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} + -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY} + LINK_LIBRARIES # link interface libraries + LINK_LIBS hello world # hello needs world to link + NO_EXTERNAL_INSTALL + ) diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt new file mode 100644 index 0000000..3ee1855 --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 2.8) +project(FortranHello Fortran C) + +# add a function to test for -lsunquad on sunpro sun systems. +function(test_sunquad result) + set( TEST_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/sunq") + file(WRITE "${TEST_DIR}/testsunq.f" " + PROGRAM TEST + END + ") + file(WRITE ${TEST_DIR}/CMakeLists.txt " +project(sunq Fortran) +add_library(sunq SHARED testsunq.f) +target_link_libraries(sunq sunquad) +") + message(STATUS "looking for -lsunquad") + try_compile(RESULT "${TEST_DIR}" "${TEST_DIR}" sunq OUTPUT_VARIABLE OUT) + if("${RESULT}") + message(STATUS "-lsunquad found") + else() + message(STATUS "-lsunquad not found") + endif() + message(STATUS + "looking for sunquad:\nRESULT=[${RESULT}]\nOUTPUT=[\n${OUT}\n]") + set(${result} "${RESULT}" PARENT_SCOPE) +endfunction() + +# check for the fortran c interface mangling +include(FortranCInterface) +FortranCInterface_HEADER(HelloWorldFCMangle.h + MACRO_NAMESPACE "FC_" + SYMBOL_NAMESPACE "FC_" + SYMBOLS hello world) +add_library(hello SHARED hello.f) +add_library(world SHARED world.f) +target_link_libraries(hello world) +if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) + target_link_libraries(hello fsu) + if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS) + target_link_libraries(hello sunmath m) + test_sunquad(CMAKE_HAS_SUNQUAD) + if(CMAKE_HAS_SUNQUAD) + target_link_libraries(hello sunquad) + endif() + endif() +endif() diff --git a/Tests/VSGNUFortran/subdir/fortran/hello.f b/Tests/VSGNUFortran/subdir/fortran/hello.f new file mode 100644 index 0000000..e52119a --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/hello.f @@ -0,0 +1,7 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: HELLO + SUBROUTINE HELLO + + PRINT *, 'Hello' + CALL WORLD + + END diff --git a/Tests/VSGNUFortran/subdir/fortran/world.f b/Tests/VSGNUFortran/subdir/fortran/world.f new file mode 100644 index 0000000..0598eee --- /dev/null +++ b/Tests/VSGNUFortran/subdir/fortran/world.f @@ -0,0 +1,6 @@ +!DEC$ ATTRIBUTES DLLEXPORT :: WORLD + SUBROUTINE WORLD + + PRINT *, 'World!' + + END diff --git a/Utilities/KWIML/ABI.h.in b/Utilities/KWIML/ABI.h.in index e95a4ff..e85a1c5 100644 --- a/Utilities/KWIML/ABI.h.in +++ b/Utilities/KWIML/ABI.h.in @@ -380,7 +380,15 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. #elif defined(__m68k__) || defined(M68000) # define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG -/* MIPS */ +/* MIPSel (MIPS little endian) */ +#elif defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE + +/* MIPSeb (MIPS big endian) */ +#elif defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG + +/* MIPS (fallback, big endian) */ #elif defined(__mips) || defined(__mips__) || defined(__MIPS__) # define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG diff --git a/Utilities/Release/Cygwin/cygwin-setup.hint.in b/Utilities/Release/Cygwin/cygwin-setup.hint.in index 9706c0d..a2532fc 100644 --- a/Utilities/Release/Cygwin/cygwin-setup.hint.in +++ b/Utilities/Release/Cygwin/cygwin-setup.hint.in @@ -1,5 +1,5 @@ # CMake setup.hint file for cygwin setup.exe program -category: Devel -requires: @CMAKE_NCURSES_VERSION@ cygwin -sdesc: "A cross platform build manager" -ldesc: "CMake is a cross platform build manager. It allows you to specify build parameters for C and C++ programs in a cross platform manner. For cygwin Makefiles will be generated. CMake is also capable of generating microsoft project files, nmake, and borland makefiles. CMake can also perform system inspection operations like finding installed libraries and header files." +category: Devel +requires: libgcc1 libidn11 @CMAKE_NCURSES_VERSION@ libstdc++6 +sdesc: "A cross platform build manager" +ldesc: "CMake is a cross platform build manager. It allows you to specify build parameters for C and C++ programs in a cross platform manner. For cygwin Makefiles will be generated. CMake is also capable of generating microsoft project files, nmake, and borland makefiles. CMake can also perform system inspection operations like finding installed libraries and header files." diff --git a/Utilities/Release/dashmacmini5_release.cmake b/Utilities/Release/dashmacmini5_release.cmake index 9bb3a98..bd93a87 100644 --- a/Utilities/Release/dashmacmini5_release.cmake +++ b/Utilities/Release/dashmacmini5_release.cmake @@ -14,7 +14,7 @@ CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.5 CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE CPACK_SYSTEM_NAME:STRING=Darwin64-universal BUILD_QtDialog:BOOL=TRUE -QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.7.4/install/bin/qmake +QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake ") get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH) include(${path}/release_cmake.cmake) diff --git a/Utilities/Release/magrathea_release.cmake b/Utilities/Release/magrathea_release.cmake index 549460e..1b2ae02 100644 --- a/Utilities/Release/magrathea_release.cmake +++ b/Utilities/Release/magrathea_release.cmake @@ -10,7 +10,7 @@ CURSES_INCLUDE_PATH:PATH=/usr/i686-gcc-332s/include/ncurses FORM_LIBRARY:FILEPATH=/usr/i686-gcc-332s/lib/libform.a CPACK_SYSTEM_NAME:STRING=Linux-i386 BUILD_QtDialog:BOOL:=TRUE -QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-x11-opensource-src-4.3.3-install/bin/qmake +QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.43-install/bin/qmake ") get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH) include(${path}/release_cmake.cmake) diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 7030b2e..caa44f1 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -33,12 +33,7 @@ INCLUDE (CheckIncludeFile) INCLUDE (CheckIncludeFiles) INCLUDE (CheckLibraryExists) INCLUDE (CheckSymbolExists) -IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4 - AND CMake_SOURCE_DIR) - INCLUDE (${CMake_SOURCE_DIR}/Modules/CheckTypeSize.cmake) -ELSE() - INCLUDE (CheckTypeSize) -ENDIF() +INCLUDE (CheckTypeSize) SET(libCurl_SRCS # amigaos.c - does not build on AmigaOS @@ -131,15 +126,15 @@ IF(CURL_MALLOC_DEBUG) ENDIF(CURL_MALLOC_DEBUG) # On windows preload settings -IF(WIN32) +IF(WIN32 AND NOT MINGW) INCLUDE(${LIBCURL_SOURCE_DIR}/Platforms/WindowsCache.cmake) -ENDIF(WIN32) +ENDIF() # This macro checks if the symbol exists in the library and if it # does, it appends library to the list. SET(CURL_LIBS "") MACRO(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE) - CHECK_LIBRARY_EXISTS("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "" + CHECK_LIBRARY_EXISTS("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "" ${VARIABLE}) IF(${VARIABLE}) SET(CURL_LIBS ${CURL_LIBS} ${LIBRARY}) @@ -180,7 +175,7 @@ IF(CMAKE_USE_OPENSSL) SET(USE_SSLEAY TRUE) SET(USE_OPENSSL TRUE) IF(WIN32) - FIND_PATH(SSLINCLUDE openssl/crypto.h + FIND_PATH(SSLINCLUDE openssl/crypto.h PATHS c:/hoffman/Tools/openssl_w32vc6-0.9.8g/inc32) INCLUDE_DIRECTORIES(${SSLINCLUDE}) FIND_LIBRARY(LIBEAY NAMES libeay32) @@ -190,6 +185,11 @@ IF(CMAKE_USE_OPENSSL) CHECK_LIBRARY_EXISTS_CONCAT("crypto" CRYPTO_lock HAVE_LIBCRYPTO) CHECK_LIBRARY_EXISTS_CONCAT("ssl" SSL_connect HAVE_LIBSSL) ENDIF(WIN32) + SET(CURL_CA_BUNDLE "" CACHE FILEPATH "Path to SSL CA Certificate Bundle") + MARK_AS_ADVANCED(CURL_CA_BUNDLE) + IF(CURL_CA_BUNDLE) + ADD_DEFINITIONS(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}") + ENDIF(CURL_CA_BUNDLE) ENDIF(CMAKE_USE_OPENSSL) # Check for idn @@ -221,7 +221,7 @@ IF(HAVE_FEATURES_H) getenv.c hash.c http.c - if2ip.c + if2ip.c mprintf.c multi.c sendf.c @@ -287,9 +287,9 @@ ENDIF(NOT CURL_SPECIAL_LIBZ) CHECK_INCLUDE_FILE_CONCAT("sys/socket.h" HAVE_SYS_SOCKET_H) CHECK_INCLUDE_FILE_CONCAT("netinet/in.h" HAVE_NETINET_IN_H) CHECK_INCLUDE_FILE_CONCAT("net/if.h" HAVE_NET_IF_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/if_ether.h" +CHECK_INCLUDE_FILE_CONCAT("netinet/if_ether.h" HAVE_NETINET_IF_ETHER_H) -CHECK_INCLUDE_FILE_CONCAT("netinet/tcp.h" +CHECK_INCLUDE_FILE_CONCAT("netinet/tcp.h" HAVE_NETINET_TCP_H) CHECK_INCLUDE_FILE_CONCAT("sys/select.h" HAVE_SYS_SELECT_H) CHECK_INCLUDE_FILE_CONCAT("utime.h" HAVE_UTIME_H) @@ -421,7 +421,7 @@ IF(CMAKE_USE_OPENSSL) CHECK_SYMBOL_EXISTS(RAND_status "${CURL_INCLUDES}" HAVE_RAND_STATUS) CHECK_SYMBOL_EXISTS(RAND_screen "${CURL_INCLUDES}" HAVE_RAND_SCREEN) CHECK_SYMBOL_EXISTS(RAND_egd "${CURL_INCLUDES}" HAVE_RAND_EGD) - CHECK_SYMBOL_EXISTS(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}" + CHECK_SYMBOL_EXISTS(CRYPTO_cleanup_all_ex_data "${CURL_INCLUDES}" HAVE_CRYPTO_CLEANUP_ALL_EX_DATA) ENDIF(CMAKE_USE_OPENSSL) CHECK_SYMBOL_EXISTS(gmtime_r "${CURL_INCLUDES}" HAVE_GMTIME_R) @@ -485,7 +485,7 @@ ENDIF(NOT HAVE_SIGSETJMP) # For other curl specific tests, use this macro. MACRO(CURL_INTERNAL_TEST CURL_TEST) IF("${CURL_TEST}" MATCHES "^${CURL_TEST}$") - SET(MACRO_CHECK_FUNCTION_DEFINITIONS + SET(MACRO_CHECK_FUNCTION_DEFINITIONS "-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}") IF(CMAKE_REQUIRED_LIBRARIES) SET(CURL_TEST_ADD_LIBRARIES @@ -502,18 +502,18 @@ MACRO(CURL_INTERNAL_TEST CURL_TEST) IF(${CURL_TEST}) SET(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}") MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Success") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Performing Curl Test ${CURL_TEST} passed with the following output:\n" "${OUTPUT}\n") ELSE(${CURL_TEST}) MESSAGE(STATUS "Performing Curl Test ${CURL_TEST} - Failed") SET(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}") - FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Performing Curl Test ${CURL_TEST} failed with the following output:\n" "${OUTPUT}\n") ENDIF(${CURL_TEST}) ENDIF("${CURL_TEST}" MATCHES "^${CURL_TEST}$") -ENDMACRO(CURL_INTERNAL_TEST) +ENDMACRO(CURL_INTERNAL_TEST) # Do curl specific tests #OPTION(CURL_HAVE_DISABLED_NONBLOCKING "Disable non-blocking socket detection" OFF) @@ -527,7 +527,7 @@ IF(NOT CURL_HAVE_DISABLED_NONBLOCKING) HAVE_SO_NONBLOCK ) ENDIF(NOT CURL_HAVE_DISABLED_NONBLOCKING) -FOREACH(CURL_TEST +FOREACH(CURL_TEST ${CURL_NONBLOCKING_TESTS} TIME_WITH_SYS_TIME HAVE_O_NONBLOCKHAVE_GETHOSTBYADDR_R_5 @@ -627,12 +627,12 @@ SET(CMAKE_REQUIRED_FLAGS) # Check for nonblocking SET(HAVE_DISABLED_NONBLOCKING 1) -IF(HAVE_FIONBIO OR +IF(HAVE_FIONBIO OR HAVE_IOCTLSOCKET OR HAVE_IOCTLSOCKET_CASE OR HAVE_O_NONBLOCK) SET(HAVE_DISABLED_NONBLOCKING) -ENDIF(HAVE_FIONBIO OR +ENDIF(HAVE_FIONBIO OR HAVE_IOCTLSOCKET OR HAVE_IOCTLSOCKET_CASE OR HAVE_O_NONBLOCK) diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h index ce2f482..cdd9c7c 100644 --- a/Utilities/cmlibarchive/libarchive/archive_platform.h +++ b/Utilities/cmlibarchive/libarchive/archive_platform.h @@ -76,6 +76,11 @@ #define __FBSDID(a) struct _undefined_hack #endif +/* Old glibc mbsnrtowcs fails assertions in our use case. */ +#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ <= 1 +# undef HAVE_MBSNRTOWCS +#endif + /* Try to get standard C99-style integer type definitions. */ #if HAVE_INTTYPES_H #include <inttypes.h> @@ -127,10 +127,20 @@ fi cmake_bootstrap_dir="${cmake_binary_dir}/Bootstrap${_cmk}" # Helper function to fix windows paths. -cmake_fix_slashes () -{ - echo "$1" | sed 's/\\/\//g' -} +case "${cmake_system}" in +*MINGW*) + cmake_fix_slashes() + { + cmd //c echo "$(echo "$1" | sed 's/\\/\//g')" | sed 's/^"//;s/" *$//' + } + ;; +*) + cmake_fix_slashes() + { + echo "$1" | sed 's/\\/\//g' + } + ;; +esac # Choose the default install prefix. if ${cmake_system_mingw}; then @@ -198,6 +208,7 @@ CMAKE_CXX_SOURCES="\ cmExportInstallFileGenerator \ cmInstallDirectoryGenerator \ cmGeneratedFileStream \ + cmGeneratorTarget \ cmGeneratorExpression \ cmGlobalGenerator \ cmLocalGenerator \ diff --git a/cmake.1 b/cmake.1 deleted file mode 100644 index c7695b4..0000000 --- a/cmake.1 +++ /dev/null @@ -1,112 +0,0 @@ -.\" Hey, EMACS: -*- nroff -*- -.\" First parameter, NAME, should be all caps -.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -.\" other parameters are allowed: see man(7), man(1) -.TH CMAKE 1 "August 8, 2002" -.\" Please adjust this date whenever revising the manpage. -.\" -.\" Some roff macros, for reference: -.\" .nh disable hyphenation -.\" .hy enable hyphenation -.\" .ad l left justify -.\" .ad b justify to both left and right margins -.\" .nf disable filling -.\" .fi enable filling -.\" .br insert line break -.\" .sp <n> insert n+1 empty lines -.\" for manpage-specific macros, see man(7) -.SH NAME -cmake \- Cross-platform Makefile generator. -.SH SYNOPSIS -.B cmake -.RI < path-to-source > " " [ options ] -.br -.B ccmake -.RI < path-to-source > -.br -.B ctest -.RI [ -R " " < regex > ] -.br -.B cmaketest -.RI < test-src-dir > " " < test-bin-dir > " " < test-executable > -.SH DESCRIPTION - -This manual page documents briefly the \fBcmake\fP, \fBccmake\fP, -\fBctest\fP and \fBcmaketest\fP commands. It is not intended to aid -authors of CMakeLists.txt files or to describe all advanced options -available. For full documentation, please visit -\fBhttp://www.cmake.org\fP. - -.PP -.\" TeX users may be more comfortable with the \fB<whatever>\fP and -.\" \fI<whatever>\fP escape sequences to invode bold face and italics, -.\" respectively. - -CMake provides developers with a means of building their project on -multiple platforms while writing only one build system configuration. -The developer writes a set of CMakeLists.txt files that are read by -CMake and used to generate a native build system for the current -environment. On unix platforms, Makefiles are generated. - -.PP - -\fBcmake\fP is used to generate the makefiles for a project from its -source. The first argument should specify a path to the source tree. -The current directory will be used as the build tree for the project. -Both in-source and out-of-source builds are supported, but -out-of-source builds are preferred. CMake provides functionality for -tailoring the build to user preferences through settings in the cmake -cache. Options may be set interactively using the -i option (or -\fBccmake\fP). Once CMake has generated the makefiles in the build -tree, one may use the standard \fBmake\fP tool to build the project. - -.PP - -\fBccmake\fP provides a curses interface front-end for \fBcmake\fP. -The interface allows users to interactively configure the build -options stored in the cmake cache. This is the preferred interface -for interactive builds. Build scripts should use \fBcmake\fP -directly. - -.PP - -\fBctest\fP runs tests found in the project's build tree after it has -been compiled and displays a summary of test results. Use the -R -option to specify a regular expression of test names to match. - -\fBcmaketest\fP is provided to simplify project testing scripts. It -allows a CMake project to be compiled and tested from a single command -line. - -.SH OPTIONS - -.TP -.B \-\-help -Available for \fBcmake\fP , \fBccmake\fP and \fBcmaketest\fP. -.br -Show version number and summary of options. - -.TP -.B -R regex -Available for \fBctest\fP. -.br -Run only tests matching the given regular expression. - -.TP -.B -i -Available for \fBcmake\fP. -.br -Run cmake in an interactive wizard mode to configure the build. - -.SH SEE ALSO -.BR Dart (1), -.BR VTK (1). - -.SH MAILING LIST -For help using cmake, a mailing list is provided at -\fBcmake@www.cmake.org\fP. Please first read the full documentation -at \fBhttp://www.cmake.org\fP before posting questions to the list. - -.SH AUTHOR -This manual page was written by CMake authors at Kitware -<kitware@kitware.com>. |