diff options
144 files changed, 3039 insertions, 1143 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 38cc0d8..ec25596 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -119,6 +119,7 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG /prop_tgt/ARCHIVE_OUTPUT_NAME + /prop_tgt/AUTOGEN_BUILD_DIR /prop_tgt/AUTOGEN_TARGET_DEPENDS /prop_tgt/AUTOMOC_DEPEND_FILTERS /prop_tgt/AUTOMOC_MOC_OPTIONS diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 3b95b05..9f3968c 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -68,14 +68,24 @@ be included by the user in the C++ implementation file with a preprocessor ``#include``. Included ``moc_*.cpp`` and ``*.moc`` files will be generated in the -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory which is +``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. + Not included ``moc_<basename>.cpp`` files will be generated in custom folders to avoid name collisions and included in a separate -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/moc_compilation.cpp`` -file which is compiled into the target. +``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file which is compiled +into the target. + +* For multi configuration generators, except Xcode, the file is + ``<AUTOGEN_BUILD_DIR>/mocs_compilation_<CONFIG>.cpp``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. The ``moc`` command line will consume the :prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`INCLUDE_DIRECTORIES` target properties from the target it is being @@ -109,10 +119,15 @@ searched for first in the vicinity of including file and afterwards in the optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. The generated generated ``ui_*.h`` files are placed in the -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory which is +``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. + The :prop_tgt:`AUTOUIC` target property may be pre-set for all following targets by setting the :variable:`CMAKE_AUTOUIC` variable. The :prop_tgt:`AUTOUIC_OPTIONS` target property may be populated to set options diff --git a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst new file mode 100644 index 0000000..8db6ede --- /dev/null +++ b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst @@ -0,0 +1,17 @@ +AUTOGEN_BUILD_DIR +----------------- + +Directory where :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC` +generate files for the target. + +The directory is created on demand and automatically added to the +:prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES`. + +When unset or empty the directory ``<dir>/<target-name>_autogen`` is used where +``<dir>`` is :variable:`CMAKE_CURRENT_BINARY_DIR` and ``<target-name>`` +is :prop_tgt:`NAME`. + +By default :prop_tgt:`AUTOGEN_BUILD_DIR` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 7e10fde..81eff82 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -13,13 +13,17 @@ source files at build time and invoke moc accordingly. * If an ``#include`` statement like ``#include "moc_<basename>.cpp"`` is found, the ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in an otherwise empty - line of the ``<basename>.h(xx)`` header file. ``moc`` is run on the header file to - generate ``moc_<basename>.cpp`` in the - ``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory - which is automatically added to the target's - :prop_tgt:`INCLUDE_DIRECTORIES`. This allows the compiler to find the - included ``moc_<basename>.cpp`` file regardless of the location the - original source. + line of the ``<basename>.h(xx)`` header file. ``moc`` is run on the header + file to generate ``moc_<basename>.cpp`` in the + ``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added + to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + This allows the compiler to find the included ``moc_<basename>.cpp`` file + regardless of the location the original source. + + * For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. * If an ``#include`` statement like ``#include "<basename>.moc"`` is found, then ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in the current source @@ -28,10 +32,19 @@ source files at build time and invoke moc accordingly. * Header files that are not included by an ``#include "moc_<basename>.cpp"`` statement are nonetheless scanned for ``Q_OBJECT`` or ``Q_GADGET`` macros. The resulting ``moc_<basename>.cpp`` files are generated in custom - directories and automatically included in the generated - ``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/moc_compilation.cpp`` file, - which is compiled as part of the target. The custom directories help to - avoid name collisions for moc files with the same ``<basename>``. + directories and automatically included in a generated + ``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file, + which is compiled as part of the target. + + * For multi configuration generators, except Xcode, the file names are + ``moc_<basename>_<CONFIG>.cpp`` and + ``<AUTOGEN_BUILD_DIR>/mocs_compilation_<CONFIG>.cpp``. + + * The custom directories with checksum + based names help to avoid name collisions for moc files with the same + ``<basename>``. + + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. * Additionally, header files with the same base name as a source file, (like ``<basename>.h``) or ``_p`` appended to the base name (like diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 91d95e5..4a08072 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -14,8 +14,13 @@ and invoke ``uic`` accordingly. If an ``#include`` statement like searched for first in the vicinity of ``source.cpp`` and afterwards in the optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. ``uic`` is run on the ``foo.ui`` file to generate ``ui_foo.h`` in the directory -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include``, -which is added to the target's :prop_tgt:`INCLUDE_DIRECTORIES` automatically. +``<AUTOGEN_BUILD_DIR>/include``, +which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` variable if it is set when a target is created. diff --git a/Help/release/dev/Autogen_build_dir.rst b/Help/release/dev/Autogen_build_dir.rst new file mode 100644 index 0000000..d11c00b --- /dev/null +++ b/Help/release/dev/Autogen_build_dir.rst @@ -0,0 +1,6 @@ +AutoGen build dir +----------------- + +* The new target property :prop_tgt:`AUTOGEN_BUILD_DIR` was introduced which + allows to set a custom output directory for + :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC`. diff --git a/Help/release/dev/FindProtobuf-export-macro.rst b/Help/release/dev/FindProtobuf-export-macro.rst new file mode 100644 index 0000000..43d9223 --- /dev/null +++ b/Help/release/dev/FindProtobuf-export-macro.rst @@ -0,0 +1,6 @@ +FindProtobuf-export-macro +------------------------- + +* The :module:`FindProtobuf` module :command:`protobuf_generate_cpp` + command gained an ``EXPORT_MACRO`` option to specify the name of + a DLL export markup macro. diff --git a/Help/release/dev/doxygen-improvements.rst b/Help/release/dev/doxygen-improvements.rst new file mode 100644 index 0000000..fd86536 --- /dev/null +++ b/Help/release/dev/doxygen-improvements.rst @@ -0,0 +1,10 @@ +doxygen-improvements +-------------------- + +* The :module:`FindDoxygen` module learned to control Doxygen behavior using + CMake variables and generate documentation via the newly added + :command:`doxygen_add_docs` function. The Doxygen input file (``Doxyfile``) + is automatically generated and doxygen is run as part of a custom target. + A number of doxygen-related variables have been deprecated. Additional + components can be specified to find optional tools: ``dot``, ``mscgen`` + and ``dia``. diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 5e945bc..4e85474 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -1,12 +1,10 @@ -# Target names -set(AM_TARGET_NAME @_autogen_target_name@) -set(AM_ORIGIN_TARGET_NAME @_origin_target_name@) # Directories and files set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") +set(AM_BUILD_DIR @_autogen_build_dir@) set(AM_SOURCES @_sources@) set(AM_HEADERS @_headers@) # Qt environment diff --git a/Modules/CMakeFindDependencyMacro.cmake b/Modules/CMakeFindDependencyMacro.cmake index 61f74ef..81606ce 100644 --- a/Modules/CMakeFindDependencyMacro.cmake +++ b/Modules/CMakeFindDependencyMacro.cmake @@ -7,38 +7,20 @@ # # :: # -# find_dependency(<dep> [<version> [EXACT]]) +# find_dependency(<dep> [...]) # # # ``find_dependency()`` wraps a :command:`find_package` call for a package # dependency. It is designed to be used in a <package>Config.cmake file, and it -# forwards the correct parameters for EXACT, QUIET and REQUIRED which were -# passed to the original :command:`find_package` call. It also sets an -# informative diagnostic message if the dependency could not be found. +# forwards the correct parameters for QUIET and REQUIRED which were passed to +# the original :command:`find_package` call. It also sets an informative +# diagnostic message if the dependency could not be found. +# +# Any additional arguments specified are forwarded to :command:`find_package`. # macro(find_dependency dep) if (NOT ${dep}_FOUND) - set(cmake_fd_version) - if (${ARGC} GREATER 1) - if ("${ARGV1}" STREQUAL "") - message(FATAL_ERROR "Invalid arguments to find_dependency. VERSION is empty") - endif() - if ("${ARGV1}" STREQUAL EXACT) - message(FATAL_ERROR "Invalid arguments to find_dependency. EXACT may only be specified if a VERSION is specified") - endif() - set(cmake_fd_version ${ARGV1}) - endif() - set(cmake_fd_exact_arg) - if(${ARGC} GREATER 2) - if (NOT "${ARGV2}" STREQUAL EXACT) - message(FATAL_ERROR "Invalid arguments to find_dependency") - endif() - set(cmake_fd_exact_arg EXACT) - endif() - if(${ARGC} GREATER 3) - message(FATAL_ERROR "Invalid arguments to find_dependency") - endif() set(cmake_fd_quiet_arg) if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) set(cmake_fd_quiet_arg QUIET) @@ -52,10 +34,9 @@ macro(find_dependency dep) _CMAKE_${dep}_TRANSITIVE_DEPENDENCY ) - find_package(${dep} ${cmake_fd_version} - ${cmake_fd_exact_arg} - ${cmake_fd_quiet_arg} - ${cmake_fd_required_arg} + find_package(${dep} ${ARGN} + ${cmake_fd_quiet_arg} + ${cmake_fd_required_arg} ) if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive) @@ -67,7 +48,6 @@ macro(find_dependency dep) set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) return() endif() - set(cmake_fd_version) set(cmake_fd_required_arg) set(cmake_fd_quiet_arg) set(cmake_fd_exact_arg) diff --git a/Modules/Compiler/IAR-C.cmake b/Modules/Compiler/IAR-C.cmake index f1b6ff7..f65b0c7 100644 --- a/Modules/Compiler/IAR-C.cmake +++ b/Modules/Compiler/IAR-C.cmake @@ -7,7 +7,7 @@ set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <I set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") -set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "-f") +set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "-f ") set(CMAKE_DEPFILE_FLAGS_C "--dependencies=ns <DEPFILE>") # The toolchains for ARM and AVR are quite different: diff --git a/Modules/Compiler/IAR-CXX.cmake b/Modules/Compiler/IAR-CXX.cmake index ffb144f..f49968e 100644 --- a/Modules/Compiler/IAR-CXX.cmake +++ b/Modules/Compiler/IAR-CXX.cmake @@ -7,7 +7,7 @@ set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> --preprocess=cnl <PREPROCESSED_SOURCE>") set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <SOURCE> <DEFINES> <INCLUDES> <FLAGS> -lAH <ASSEMBLY_SOURCE> -o <OBJECT>.dummy") -set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "-f") +set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "-f ") set(CMAKE_DEPFILE_FLAGS_CXX "--dependencies=ns <DEPFILE>") if("${IAR_TARGET_ARCHITECTURE}" STREQUAL "ARM") diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake index d583dba..20e29e2 100644 --- a/Modules/Compiler/Intel-C.cmake +++ b/Modules/Compiler/Intel-C.cmake @@ -8,30 +8,34 @@ string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG") set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <OBJECT> -MF <DEPFILE>") if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") - set(_std -Qstd) - set(_ext c) + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 16.0.0) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-Qstd=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-Qstd=c11") endif() + + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.0) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-Qstd=c89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-Qstd=c89") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-Qstd=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-Qstd=c99") + endif() + else() - set(_std -std) - set(_ext gnu) + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0.0) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") endif() -endif() -if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.0) - set(CMAKE_C90_STANDARD_COMPILE_OPTION "${_std}=c89") - set(CMAKE_C90_EXTENSION_COMPILE_OPTION "${_std}=${_ext}89") - set(CMAKE_C99_STANDARD_COMPILE_OPTION "${_std}=c99") - set(CMAKE_C99_EXTENSION_COMPILE_OPTION "${_std}=${_ext}99") -endif() + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 12.0) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89") + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + endif() -unset(_std) -unset(_ext) +endif() __compiler_check_default_language_standard(C 12.1 90 15.0.0 11) diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake index 4aef30a..08d23fc 100644 --- a/Modules/Compiler/Intel-CXX.cmake +++ b/Modules/Compiler/Intel-CXX.cmake @@ -8,16 +8,27 @@ string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG") set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <OBJECT> -MF <DEPFILE>") if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") - set(_std -Qstd) - set(_ext c++) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0) set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-Qstd=c++14") - # todo: there is no gnu++14 value supported; figure out what to do set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-Qstd=c++14") endif() + + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-Qstd=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-Qstd=c++11") + elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-Qstd=c++0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-Qstd=c++0x") + endif() + + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") + endif() + else() - set(_std -std) - set(_ext gnu++) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0.2) set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") # todo: there is no gnu++14 value supported; figure out what to do @@ -27,28 +38,21 @@ else() # todo: there is no gnu++14 value supported; figure out what to do set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=c++1y") endif() -endif() -if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) - set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "${_std}=c++11") - set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "${_std}=${_ext}11") -elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) - set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "${_std}=c++0x") - set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "${_std}=${_ext}0x") -endif() + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") + elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x") + endif() -if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) - if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") - set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "") - set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "") - else() - set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "${_std}=c++98") - set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "${_std}=gnu++98") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.1) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") endif() -endif() -unset(_std) -unset(_ext) +endif() __compiler_check_default_language_standard(CXX 12.1 98) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index b2fb4b7..cc273e0 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -208,6 +208,10 @@ # # Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. +# Save project's policies +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + #------------------------------------------------------------------------------- # Before we go searching, check whether boost-cmake is available, unless the # user specifically asked NOT to search for boost-cmake. @@ -865,14 +869,12 @@ function(_Boost_MISSING_DEPENDENCIES componentvar extravar) list(APPEND _boost_processed_components ${_boost_unprocessed_components}) foreach(component ${_boost_unprocessed_components}) string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES) set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) - list(FIND _boost_processed_components "${componentdep}" _boost_component_found) - list(FIND _boost_new_components "${componentdep}" _boost_component_new) - if (_boost_component_found EQUAL -1 AND _boost_component_new EQUAL -1) + if (NOT ("${componentdep}" IN_LIST _boost_processed_components OR "${componentdep}" IN_LIST _boost_new_components)) list(APPEND _boost_new_components ${componentdep}) endif() endforeach() @@ -1499,8 +1501,7 @@ endif() _Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) # If thread is required, get the thread libs as a dependency -list(FIND Boost_FIND_COMPONENTS thread _Boost_THREAD_DEPENDENCY_LIBS) -if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1) +if("thread" IN_LIST Boost_FIND_COMPONENTS) include(CMakeFindDependencyMacro) find_dependency(Threads) endif() @@ -1925,3 +1926,6 @@ list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) list(SORT _Boost_COMPONENTS_SEARCHED) set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}" CACHE INTERNAL "Components requested for this build tree.") + +# Restore project's policies +cmake_policy(POP) diff --git a/Modules/FindCygwin.cmake b/Modules/FindCygwin.cmake index 90cbd52..b2ed703 100644 --- a/Modules/FindCygwin.cmake +++ b/Modules/FindCygwin.cmake @@ -8,13 +8,13 @@ # this module looks for Cygwin if (WIN32) - find_path(CYGWIN_INSTALL_PATH + find_program(CYGWIN_INSTALL_PATH cygwin.bat "C:/Cygwin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup;rootdir]" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/;native]" ) - + get_filename_component(CYGWIN_INSTALL_PATH "${CYGWIN_INSTALL_PATH}" DIRECTORY) mark_as_advanced( CYGWIN_INSTALL_PATH ) diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake index 8275ac8..76456a0 100644 --- a/Modules/FindDoxygen.cmake +++ b/Modules/FindDoxygen.cmake @@ -1,161 +1,1034 @@ # Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file Copyright.txt or https://cmake.org/licensing for details. -#.rst: -# FindDoxygen -# ----------- -# -# This module looks for Doxygen and the path to Graphviz's dot -# -# Doxygen is a documentation generation tool. Please see -# http://www.doxygen.org -# -# This module accepts the following optional variables: -# -# :: -# -# DOXYGEN_SKIP_DOT = If true this module will skip trying to find Dot -# (an optional component often used by Doxygen) -# -# -# -# This modules defines the following variables: -# -# :: -# -# DOXYGEN_EXECUTABLE = The path to the doxygen command. -# DOXYGEN_FOUND = Was Doxygen found or not? -# DOXYGEN_VERSION = The version reported by doxygen --version -# -# -# -# :: -# -# DOXYGEN_DOT_EXECUTABLE = The path to the dot program used by doxygen. -# DOXYGEN_DOT_FOUND = Was Dot found or not? -# -# For compatibility with older versions of CMake, the now-deprecated -# variable ``DOXYGEN_DOT_PATH`` is set to the path to the directory -# containing ``dot`` as reported in ``DOXYGEN_DOT_EXECUTABLE``. -# The path may have forward slashes even on Windows and is not -# suitable for direct substitution into a ``Doxyfile.in`` template. -# If you need this value, use :command:`get_filename_component` -# to compute it from ``DOXYGEN_DOT_EXECUTABLE`` directly, and -# perhaps the :command:`file(TO_NATIVE_PATH)` command to prepare -# the path for a Doxygen configuration file. +#[=======================================================================[.rst: +FindDoxygen +----------- + +Doxygen is a documentation generation tool (see http://www.doxygen.org). +This module looks for Doxygen and some optional tools it supports. These +tools are enabled as components in the :command:`find_package` command: + +``dot`` + `Graphviz <http://graphviz.org>`_ ``dot`` utility used to render various + graphs. +``mscgen`` + `Message Chart Generator <http://www.mcternan.me.uk/mscgen/>`_ utility used + by Doxygen's ``\msc`` and ``\mscfile`` commands. +``dia`` + `Dia <https://wiki.gnome.org/Apps/Dia>`_ the diagram editor used by Doxygen's + ``\diafile`` command. + +Examples: + +.. code-block:: cmake + + # Require dot, treat the other components as optional + find_package(Doxygen + REQUIRED dot + OPTIONAL_COMPONENTS mscgen dia) + +The following variables are defined by this module: + +.. variable:: DOXYGEN_FOUND + + True if the ``doxygen`` executable was found. + +.. variable:: DOXYGEN_VERSION + + The version reported by ``doxygen --version``. + +The module defines ``IMPORTED`` targets for Doxygen and each component found. +These can be used as part of custom commands, etc. and should be preferred over +old-style (and now deprecated) variables like ``DOXYGEN_EXECUTABLE``. The +following import targets are defined if their corresponding executable could be +found (the component import targets will only be defined if that component was +requested): + +:: + + Doxygen::doxygen + Doxygen::dot + Doxygen::mscgen + Doxygen::dia + + +Functions +^^^^^^^^^ + +.. command:: doxygen_add_docs + + This function is intended as a convenience for adding a target for generating + documentation with Doxygen. It aims to provide sensible defaults so that + projects can generally just provide the input files and directories and that + will be sufficient to give sensible results. The function supports the + ability to customize the Doxygen configuration used to build the + documentation. + + :: + + doxygen_add_docs(targetName + [filesOrDirs...] + [WORKING_DIRECTORY dir] + [COMMENT comment]) + + The function constructs a ``Doxyfile`` and defines a custom target that runs + Doxygen on that generated file. The listed files and directories are used as + the ``INPUT`` of the generated ``Doxyfile`` and they can contain wildcards. + Any files that are listed explicitly will also be added as ``SOURCES`` of the + custom target so they will show up in an IDE project's source list. + + So that relative input paths work as expected, by default the working + directory of the Doxygen command will be the current source directory (i.e. + :variable:`CMAKE_CURRENT_SOURCE_DIR`). This can be overridden with the + ``WORKING_DIRECTORY`` option to change the directory used as the relative + base point. Note also that Doxygen's default behavior is to strip the working + directory from relative paths in the generated documentation (see the + ``STRIP_FROM_PATH`` `Doxygen config option + <http://www.doxygen.org/manual/config.html>`_ for details). + + If provided, the optional ``comment`` will be passed as the ``COMMENT`` for + the :command:`add_custom_target` command used to create the custom target + internally. + + The contents of the generated ``Doxyfile`` can be customized by setting CMake + variables before calling ``doxygen_add_docs()``. Any variable with a name of + the form ``DOXYGEN_<tag>`` will have its value substituted for the + corresponding ``<tag>`` configuration option in the ``Doxyfile``. See the + `Doxygen documentation <http://www.doxygen.org/manual/config.html>`_ for the + full list of supported configuration options. + + Some of Doxygen's defaults are overridden to provide more appropriate + behavior for a CMake project. Each of the following will be explicitly set + unless the variable already has a value before ``doxygen_add_docs()`` is + called (with some exceptions noted): + + .. variable:: DOXYGEN_HAVE_DOT + + Set to ``YES`` if the ``dot`` component was requested and it was found, + ``NO`` otherwise. Any existing value of ``DOXYGEN_HAVE_DOT`` is ignored. + + .. variable:: DOXYGEN_DOT_MULTI_TARGETS + + Set to ``YES`` by this module (note that this requires a ``dot`` version + newer than 1.8.10). This option is only meaningful if ``DOXYGEN_HAVE_DOT`` + is also set to ``YES``. + + .. variable:: DOXYGEN_GENERATE_LATEX + + Set to ``NO`` by this module. + + .. variable:: DOXYGEN_WARN_FORMAT + + For Visual Studio based generators, this is set to the form recognized by + the Visual Studio IDE: ``$file($line) : $text``. For all other generators, + Doxygen's default value is not overridden. + + .. variable:: DOXYGEN_PROJECT_NAME + + Populated with the name of the current project (i.e. + :variable:`PROJECT_NAME`). + + .. variable:: DOXYGEN_PROJECT_NUMBER + + Populated with the version of the current project (i.e. + :variable:`PROJECT_VERSION`). + + .. variable:: DOXYGEN_PROJECT_BRIEF + + Populated with the description of the current project (i.e. + :variable:`PROJECT_DESCRIPTION`). + + .. variable:: DOXYGEN_INPUT + + Projects should not set this variable. It will be populated with the set of + files and directories passed to ``doxygen_add_docs()``, thereby providing + consistent behavior with the other built-in commands like + :command:`add_executable`, :command:`add_library` and + :command:`add_custom_target`. If a variable named ``DOXYGEN_INPUT`` is set + by the project, it will be ignored and a warning will be issued. + + .. variable:: DOXYGEN_RECURSIVE + + Set to ``YES`` by this module. + + .. variable:: DOXYGEN_EXCLUDE_PATTERNS + + If the set of inputs includes directories, this variable will specify + patterns used to exclude files from them. The following patterns are added + by ``doxygen_add_docs()`` to ensure CMake-specific files and directories + are not included in the input. If the project sets + ``DOXYGEN_EXCLUDE_PATTERNS``, those contents are merged with these + additional patterns rather than replacing them: + + :: + + */.git/* + */.svn/* + */.hg/* + */CMakeFiles/* + */_CPack_Packages/* + DartConfiguration.tcl + CMakeLists.txt + CMakeCache.txt + + .. variable:: DOXYGEN_OUTPUT_DIRECTORY + + Set to :variable:`CMAKE_CURRENT_BINARY_DIR` by this module. Note that if + the project provides its own value for this and it is a relative path, it + will be converted to an absolute path relative to the current binary + directory. This is necessary because doxygen will normally be run from a + directory within the source tree so that relative source paths work as + expected. + +To change any of these defaults or override any other Doxygen config option, +set relevant variables before calling ``doxygen_add_docs()``. For example: + + .. code-block:: cmake + + set(DOXYGEN_GENERATE_HTML NO) + set(DOXYGEN_GENERATE_MAN YES) + + doxygen_add_docs( + doxygen + ${PROJECT_SOURCE_DIR} + COMMENT "Generate man pages" + ) + +A number of Doxygen config options accept lists of values, but Doxygen requires +them to be separated by whitespace. CMake variables hold lists as a string with +items separated by semi-colons, so a conversion needs to be performed. The +``doxygen_add_docs()`` command specifically checks the following Doxygen config +options and will convert their associated CMake variable's contents into the +required form if set. + +:: + + ABBREVIATE_BRIEF + ALIASES + CITE_BIB_FILES + DIAFILE_DIRS + DOTFILE_DIRS + DOT_FONTPATH + ENABLED_SECTIONS + EXAMPLE_PATH + EXAMPLE_PATTERNS + EXCLUDE + EXCLUDE_PATTERNS + EXCLUDE_SYMBOLS + EXPAND_AS_DEFINED + EXTENSION_MAPPING + EXTRA_PACKAGES + EXTRA_SEARCH_MAPPINGS + FILE_PATTERNS + FILTER_PATTERNS + FILTER_SOURCE_PATTERNS + HTML_EXTRA_FILES + HTML_EXTRA_STYLESHEET + IGNORE_PREFIX + IMAGE_PATH + INCLUDE_FILE_PATTERNS + INCLUDE_PATH + INPUT + LATEX_EXTRA_FILES + LATEX_EXTRA_STYLESHEET + MATHJAX_EXTENSIONS + MSCFILE_DIRS + PLANTUML_INCLUDE_PATH + PREDEFINED + QHP_CUST_FILTER_ATTRS + QHP_SECT_FILTER_ATTRS + STRIP_FROM_INC_PATH + STRIP_FROM_PATH + TAGFILES + TCL_SUBST + +The following single value Doxygen options would be quoted automatically +if they contain at least one space: + +:: + + CHM_FILE + DIA_PATH + DOCBOOK_OUTPUT + DOCSET_FEEDNAME + DOCSET_PUBLISHER_NAME + DOT_FONTNAME + DOT_PATH + EXTERNAL_SEARCH_ID + FILE_VERSION_FILTER + GENERATE_TAGFILE + HHC_LOCATION + HTML_FOOTER + HTML_HEADER + HTML_OUTPUT + HTML_STYLESHEET + INPUT_FILTER + LATEX_FOOTER + LATEX_HEADER + LATEX_OUTPUT + LAYOUT_FILE + MAN_OUTPUT + MAN_SUBDIR + MATHJAX_CODEFILE + MSCGEN_PATH + OUTPUT_DIRECTORY + PERL_PATH + PLANTUML_JAR_PATH + PROJECT_BRIEF + PROJECT_LOGO + PROJECT_NAME + QCH_FILE + QHG_LOCATION + QHP_CUST_FILTER_NAME + QHP_VIRTUAL_FOLDER + RTF_EXTENSIONS_FILE + RTF_OUTPUT + RTF_STYLESHEET_FILE + SEARCHDATA_FILE + USE_MDFILE_AS_MAINPAGE + WARN_FORMAT + WARN_LOGFILE + XML_OUTPUT + +Deprecated Result Variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For compatibility with previous versions of CMake, the following variables +are also defined but they are deprecated and should no longer be used: + +.. variable:: DOXYGEN_EXECUTABLE + + The path to the ``doxygen`` command. If projects need to refer to the + ``doxygen`` executable directly, they should use the ``Doxygen::doxygen`` + import target instead. + +.. variable:: DOXYGEN_DOT_FOUND + + True if the ``dot`` executable was found. + +.. variable:: DOXYGEN_DOT_EXECUTABLE + + The path to the ``dot`` command. If projects need to refer to the ``dot`` + executable directly, they should use the ``Doxygen::dot`` import target + instead. + +.. variable:: DOXYGEN_DOT_PATH + + The path to the directory containing the ``dot`` executable as reported in + ``DOXYGEN_DOT_EXECUTABLE``. The path may have forward slashes even on Windows + and is not suitable for direct substitution into a ``Doxyfile.in`` template. + If you need this value, get the :prop_tgt:`IMPORTED_LOCATION` property of the + ``Doxygen::dot`` target and use :command:`get_filename_component` to extract + the directory part of that path. You may also want to consider using + :command:`file(TO_NATIVE_PATH)` to prepare the path for a Doxygen + configuration file. + + +Deprecated Hint Variables +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. variable:: DOXYGEN_SKIP_DOT + + This variable has no any effect for component form of ``find_package``. + In backward compatibility mode (i.e. without components list) it prevents + the finder module from searching for Graphviz's ``dot`` utility. + +#]=======================================================================] # For backwards compatibility support if(Doxygen_FIND_QUIETLY) - set(DOXYGEN_FIND_QUIETLY TRUE) + set(DOXYGEN_FIND_QUIETLY TRUE) endif() # ===== Rationale for OS X AppBundle mods below ===== -# With the OS X GUI version, Doxygen likes to be installed to /Applications and -# it contains the doxygen executable in the bundle. In the versions I've -# seen, it is located in Resources, but in general, more often binaries are -# located in MacOS. -# -# NOTE: The official Doxygen.app that is distributed for OS X uses non-standard -# conventions. Instead of the command-line "doxygen" tool being placed in -# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and -# "doxygen" is placed in Contents/Resources. This is most likely done -# so that something happens when people double-click on the Doxygen.app -# package. Unfortunately, CMake gets confused by this as when it sees the -# bundle it uses "Doxywizard" as the executable to use instead of -# "doxygen". Therefore to work-around this issue we temporarily disable -# the app-bundle feature, just for this CMake module: +# With the OS X GUI version, Doxygen likes to be installed to /Applications +# and it contains the doxygen executable in the bundle. In the versions I've +# seen, it is located in Resources, but in general, more often binaries are +# located in MacOS. +# +# NOTE: The official Doxygen.app distributed for OS X uses non-standard +# conventions. Instead of the command-line "doxygen" tool being placed in +# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and +# "doxygen" is placed in Contents/Resources. This is most likely done +# so that something happens when people double-click on the Doxygen.app +# package. Unfortunately, CMake gets confused by this as when it sees the +# bundle it uses "Doxywizard" as the executable to use instead of +# "doxygen". Therefore to work-around this issue we temporarily disable +# the app-bundle feature, just for this CMake module: +# if(APPLE) - # Save the old setting + # Save the old setting set(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}) # Disable the App-bundle detection feature set(CMAKE_FIND_APPBUNDLE "NEVER") endif() -# FYI: -# In the older versions of OS X Doxygen, dot was included with the -# Doxygen bundle. But the new versions require you to download -# Graphviz.app which contains "dot" in it's bundle. +# FYI: +# In older versions of OS X Doxygen, dot was included with the Doxygen bundle, +# but newer versions require you to download Graphviz.app which contains "dot" +# or use something like homebrew. # ============== End OSX stuff ================ # # Find Doxygen... # +macro(_Doxygen_find_doxygen) + find_program( + DOXYGEN_EXECUTABLE + NAMES doxygen + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin" + /Applications/Doxygen.app/Contents/Resources + /Applications/Doxygen.app/Contents/MacOS + DOC "Doxygen documentation generation tool (http://www.doxygen.org)" + ) + mark_as_advanced(DOXYGEN_EXECUTABLE) -find_program(DOXYGEN_EXECUTABLE - NAMES doxygen - PATHS - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin" - /Applications/Doxygen.app/Contents/Resources - /Applications/Doxygen.app/Contents/MacOS - DOC "Doxygen documentation generation tool (http://www.doxygen.org)" -) + if(DOXYGEN_EXECUTABLE) + execute_process( + COMMAND "${DOXYGEN_EXECUTABLE}" --version + OUTPUT_VARIABLE DOXYGEN_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE result + ) + if(result) + message(WARNING "Unable to determine doxygen version: ${result}") + endif() -if(DOXYGEN_EXECUTABLE) - execute_process(COMMAND ${DOXYGEN_EXECUTABLE} "--version" OUTPUT_VARIABLE DOXYGEN_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) -endif() + # Create an imported target for Doxygen + add_executable(Doxygen::doxygen IMPORTED GLOBAL) + set_target_properties(Doxygen::doxygen PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_EXECUTABLE}" + ) + endif() +endmacro() -include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Doxygen REQUIRED_VARS DOXYGEN_EXECUTABLE VERSION_VAR DOXYGEN_VERSION) - -# -# Find Dot... -# - -set(_x86 "(x86)") -file(GLOB _Doxygen_GRAPHVIZ_BIN_DIRS - "$ENV{ProgramFiles}/Graphviz*/bin" - "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" - ) -unset(_x86) - -if(NOT DOXYGEN_SKIP_DOT) - find_program(DOXYGEN_DOT_EXECUTABLE - NAMES dot - PATHS - ${_Doxygen_GRAPHVIZ_BIN_DIRS} - "$ENV{ProgramFiles}/ATT/Graphviz/bin" - "C:/Program Files/ATT/Graphviz/bin" - [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin - /Applications/Graphviz.app/Contents/MacOS - /Applications/Doxygen.app/Contents/Resources - /Applications/Doxygen.app/Contents/MacOS - DOC "Graphviz Dot tool for using Doxygen" - ) - - if(DOXYGEN_DOT_EXECUTABLE) - set(DOXYGEN_DOT_FOUND TRUE) - # The Doxyfile wants the path to Dot, not the entire path and executable - get_filename_component(DOXYGEN_DOT_PATH "${DOXYGEN_DOT_EXECUTABLE}" PATH) - endif() +# +# Find Diagram Editor... +# +macro(_Doxygen_find_dia) + set(_x86 "(x86)") + find_program( + DOXYGEN_DIA_EXECUTABLE + NAMES dia + PATHS + "$ENV{ProgramFiles}/Dia" + "$ENV{ProgramFiles${_x86}}/Dia" + DOC "Diagram Editor tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_DIA_EXECUTABLE) + + if(DOXYGEN_DIA_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_DIA_PATH + "${DOXYGEN_DIA_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_DIA_PATH}" DOXYGEN_DIA_PATH) + endif() + + # Create an imported target for component + add_executable(Doxygen::dia IMPORTED GLOBAL) + set_target_properties(Doxygen::dia PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_DIA_EXECUTABLE}" + ) + endif() + + unset(_x86) +endmacro() + +# +# Find Graphviz Dot... +# +macro(_Doxygen_find_dot) + set(_x86 "(x86)") + file( + GLOB _Doxygen_GRAPHVIZ_BIN_DIRS + "$ENV{ProgramFiles}/Graphviz*/bin" + "$ENV{ProgramFiles${_x86}}/Graphviz*/bin" + ) + find_program( + DOXYGEN_DOT_EXECUTABLE + NAMES dot + PATHS + ${_Doxygen_GRAPHVIZ_BIN_DIRS} + "$ENV{ProgramFiles}/ATT/Graphviz/bin" + "C:/Program Files/ATT/Graphviz/bin" + [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin + /Applications/Graphviz.app/Contents/MacOS + /Applications/Doxygen.app/Contents/Resources + /Applications/Doxygen.app/Contents/MacOS + DOC "Dot tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_DOT_EXECUTABLE) + + if(DOXYGEN_DOT_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_DOT_PATH + "${DOXYGEN_DOT_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_DOT_PATH}" DOXYGEN_DOT_PATH) + endif() + + # Create an imported target for component + add_executable(Doxygen::dot IMPORTED GLOBAL) + set_target_properties(Doxygen::dot PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_DOT_EXECUTABLE}" + ) + endif() + unset(_Doxygen_GRAPHVIZ_BIN_DIRS) + unset(_x86) +endmacro() + +# +# Find Message Sequence Chart... +# +macro(_Doxygen_find_mscgen) + set(_x86 "(x86)") + find_program( + DOXYGEN_MSCGEN_EXECUTABLE + NAMES mscgen + PATHS + "$ENV{ProgramFiles}/Mscgen" + "$ENV{ProgramFiles${_x86}}/Mscgen" + DOC "Message sequence chart tool for use with Doxygen" + ) + mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE) + + if(DOXYGEN_MSCGEN_EXECUTABLE) + # The Doxyfile wants the path to the utility, not the entire path + # including file name + get_filename_component(DOXYGEN_MSCGEN_PATH + "${DOXYGEN_MSCGEN_EXECUTABLE}" + DIRECTORY) + if(WIN32) + file(TO_NATIVE_PATH "${DOXYGEN_MSCGEN_PATH}" DOXYGEN_MSCGEN_PATH) + endif() + + # Create an imported target for component + add_executable(Doxygen::mscgen IMPORTED GLOBAL) + set_target_properties(Doxygen::mscgen PROPERTIES + IMPORTED_LOCATION "${DOXYGEN_MSCGEN_EXECUTABLE}" + ) + endif() + + unset(_x86) +endmacro() + +# Make sure `doxygen` is one of the components to find +set(_Doxygen_keep_backward_compat FALSE) +if(NOT Doxygen_FIND_COMPONENTS) + # Search at least for `doxygen` executable + set(Doxygen_FIND_COMPONENTS doxygen) + # Preserve backward compatibility: + # search for `dot` also if `DOXYGEN_SKIP_DOT` is not explicitly disable this. + if(NOT DOXYGEN_SKIP_DOT) + list(APPEND Doxygen_FIND_COMPONENTS dot) + endif() + set(_Doxygen_keep_backward_compat TRUE) +elseif(NOT doxygen IN_LIST Doxygen_FIND_COMPONENTS) + list(INSERT Doxygen_FIND_COMPONENTS 0 doxygen) endif() # -# Backwards compatibility... +# Find all requested components of Doxygen... # +foreach(_comp IN LISTS Doxygen_FIND_COMPONENTS) + if(_comp STREQUAL "doxygen") + _Doxygen_find_doxygen() + elseif(_comp STREQUAL "dia") + _Doxygen_find_dia() + elseif(_comp STREQUAL "dot") + _Doxygen_find_dot() + elseif(_comp STREQUAL "mscgen") + _Doxygen_find_mscgen() + else() + message(WARNING "${_comp} is not a valid Doxygen component") + set(Doxygen_${_comp}_FOUND FALSE) + continue() + endif() + + if(TARGET Doxygen::${_comp}) + set(Doxygen_${_comp}_FOUND TRUE) + else() + set(Doxygen_${_comp}_FOUND FALSE) + endif() +endforeach() +unset(_comp) + +# Verify find results +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args( + Doxygen + REQUIRED_VARS DOXYGEN_EXECUTABLE + VERSION_VAR DOXYGEN_VERSION + HANDLE_COMPONENTS +) +# +# Backwards compatibility... +# if(APPLE) - # Restore the old app-bundle setting setting - set(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE}) + # Restore the old app-bundle setting + set(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE}) endif() -# Maintain the _FOUND variables as "YES" or "NO" for backwards compatibility -# (allows people to stuff them directly into Doxyfile with configure_file()) +# Maintain the _FOUND variables as "YES" or "NO" for backwards +# compatibility. This allows people to substitute them directly into +# Doxyfile with configure_file(). if(DOXYGEN_FOUND) - set(DOXYGEN_FOUND "YES") + set(DOXYGEN_FOUND "YES") else() - set(DOXYGEN_FOUND "NO") + set(DOXYGEN_FOUND "NO") endif() -if(DOXYGEN_DOT_FOUND) - set(DOXYGEN_DOT_FOUND "YES") -else() - set(DOXYGEN_DOT_FOUND "NO") +if(_Doxygen_keep_backward_compat) + if(DOXYGEN_DOT_FOUND) + set(DOXYGEN_DOT_FOUND "YES") + else() + set(DOXYGEN_DOT_FOUND "NO") + endif() + + # For backwards compatibility support for even older CMake versions + set(DOXYGEN ${DOXYGEN_EXECUTABLE}) + set(DOT ${DOXYGEN_DOT_EXECUTABLE}) + + # No need to keep any backward compatibility for `DOXYGEN_MSCGEN_XXX` + # and `DOXYGEN_DIA_XXX` since they were not supported before component + # support was added endif() +unset(_Doxygen_keep_backward_compat) -# For backwards compatibility support -set (DOXYGEN ${DOXYGEN_EXECUTABLE} ) -set (DOT ${DOXYGEN_DOT_EXECUTABLE} ) +# +# Allow full control of Doxygen from CMakeLists.txt +# + +# Prepare a template Doxyfile and Doxygen's default values CMake file +if(TARGET Doxygen::doxygen) + # If doxygen was found, use it to generate a minimal default Doxyfile. + # We will delete this file after we have finished using it below to + # generate the other files that doxygen_add_docs() will use. + set(_Doxygen_tpl "${PROJECT_BINARY_DIR}/CMakeDoxyfile.tpl") + execute_process( + COMMAND "${DOXYGEN_EXECUTABLE}" -s -g "${_Doxygen_tpl}" + OUTPUT_QUIET + RESULT_VARIABLE result + ) + if(result) + message(FATAL_ERROR + "Unable to generate Doxyfile template: ${result}") + elseif(NOT EXISTS "${_Doxygen_tpl}") + message(FATAL_ERROR + "Doxygen has failed to generate a Doxyfile template") + endif() + + # Write a do-not-edit header to files we are going to generate... + set(_Doxygen_dne_header +[[ +# +# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE! +# + +]] + ) + # We only need one copy of these across the whole build, since their + # content is only dependent on the version of Doxygen being used. Therefore + # we always put them at the top of the build tree so that they are in a + # predictable location. + set(_doxyfile_in "${PROJECT_BINARY_DIR}/CMakeDoxyfile.in") + set(_doxyfile_defaults "${PROJECT_BINARY_DIR}/CMakeDoxygenDefaults.cmake") + + file(WRITE "${_doxyfile_in}" ${_Doxygen_dne_header}) + file(WRITE "${_doxyfile_defaults}" ${_Doxygen_dne_header}) + + # Get strings containing a configuration key from the template Doxyfile + # we obtained from this version of Doxygen. Because some options are split + # across multiple lines by ending lines with backslashes, we cannot just + # use file(STRINGS...) with a REGEX. Instead, read lines without a REGEX + # so that file(STRINGS...) handles the trailing backslash as a line + # continuation. It stores multi-lines as lists, so we then have to replace + # the ";" list separator with backslashed newlines again so that we get the + # original content stored back as the value part. + file(STRINGS "${_Doxygen_tpl}" _file_lines) + unset(_Doxygen_tpl_params) + foreach(_line IN LISTS _file_lines) + if(_line MATCHES "([A-Z][A-Z0-9_]+)( *=)(.*)") + set(_key "${CMAKE_MATCH_1}") + set(_eql "${CMAKE_MATCH_2}") + string(REPLACE ";" "\\\n" _value "${CMAKE_MATCH_3}") + list(APPEND _Doxygen_tpl_params "${_key}${_eql}${_value}") + endif() + endforeach() + + # Build up a Doxyfile that provides @configVar@ substitutions for each + # Doxygen config option as well as a separate CMake script which provides + # the default value for each of those options if the project doesn't supply + # them. Each config option will support substitution of a CMake variable + # of the same name except with DOXYGEN_ prepended. + foreach(_Doxygen_param IN LISTS _Doxygen_tpl_params) + if(_Doxygen_param MATCHES "([A-Z][A-Z0-9_]+)( *)=( (.*))?") + # Ok, this is a config key with a value + if(CMAKE_MATCH_COUNT EQUAL 4) + file(APPEND "${_doxyfile_in}" + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") + # Remove the backslashes we had to preserve to handle newlines + string(REPLACE "\\\n" "\n" _value "${CMAKE_MATCH_4}") + file(APPEND "${_doxyfile_defaults}" +"if(NOT DEFINED DOXYGEN_${CMAKE_MATCH_1}) + set(DOXYGEN_${CMAKE_MATCH_1} ${_value}) +endif() +") + # Ok, this is a config key with empty default value + elseif(CMAKE_MATCH_COUNT EQUAL 2) + file(APPEND "${_doxyfile_in}" + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n") + else() + message(AUTHOR_WARNING +"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") + endif() + else() + message(AUTHOR_WARNING +"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}") + endif() + endforeach() + + # Ok, dumped defaults are not needed anymore... + file(REMOVE "${_Doxygen_tpl}") + + unset(_Doxygen_param) + unset(_Doxygen_tpl_params) + unset(_Doxygen_dne_header) + unset(_Doxygen_tpl) + +endif() + +function(doxygen_quote_value VARIABLE) + # Quote a value of the given variable if: + # - variable parameter was really given + # - a variable it points is defined + # - a value doesn't quoted already + # - and it has spaces + if(VARIABLE AND DEFINED ${VARIABLE} AND + NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " ") + set(${VARIABLE} "\"${${VARIABLE}}\"" PARENT_SCOPE) + endif() +endfunction() + +function(doxygen_list_to_quoted_strings LIST_VARIABLE) + if(LIST_VARIABLE AND DEFINED ${LIST_VARIABLE}) + unset(_inputs) + unset(_sep) + foreach(_in IN LISTS ${LIST_VARIABLE}) + doxygen_quote_value(_in) + string(APPEND _inputs "${_sep}${_in}") + set(_sep " ") + endforeach() + set(${LIST_VARIABLE} "${_inputs}" PARENT_SCOPE) + endif() +endfunction() + +function(doxygen_add_docs targetName) + set(_options) + set(_one_value_args WORKING_DIRECTORY COMMENT) + set(_multi_value_args) + cmake_parse_arguments(_args + "${_options}" + "${_one_value_args}" + "${_multi_value_args}" + ${ARGN}) + + if(NOT _args_COMMENT) + set(_args_COMMENT "Generate API documentation for ${targetName}") + endif() + + if(NOT _args_WORKING_DIRECTORY) + set(_args_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + + if(DEFINED DOXYGEN_INPUT) + message(WARNING +"DOXYGEN_INPUT is set but it will be ignored. Pass the files and directories \ +directly to the doxygen_add_docs() command instead.") + endif() + set(DOXYGEN_INPUT ${_args_UNPARSED_ARGUMENTS}) + + if(NOT TARGET Doxygen::doxygen) + message(FATAL_ERROR "Doxygen was not found, needed by \ +doxygen_add_docs() for target ${targetName}") + endif() + + # If not already defined, set some relevant defaults based on the + # assumption that the documentation is for the whole project. Details + # specified in the project() command will be used to populate a number of + # these defaults. + + if(NOT DEFINED DOXYGEN_PROJECT_NAME) + # The PROJECT_NAME tag is a single word (or a sequence of words + # surrounded by double-quotes, unless you are using Doxywizard) that + # should identify the project for which the documentation is generated. + # This name is used in the title of most generated pages and in a few + # other places. The default value is: My Project. + set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME}) + endif() + + if(NOT DEFINED DOXYGEN_PROJECT_NUMBER) + # The PROJECT_NUMBER tag can be used to enter a project or revision + # number. This could be handy for archiving the generated documentation + # or if some version control system is used. + set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION}) + endif() + + if(NOT DEFINED DOXYGEN_PROJECT_BRIEF) + # Using the PROJECT_BRIEF tag one can provide an optional one line + # description for a project that appears at the top of each page and + # should give viewer a quick idea about the purpose of the project. + # Keep the description short. + set(DOXYGEN_PROJECT_BRIEF "${PROJECT_DESCRIPTION}") + endif() + + if(NOT DEFINED DOXYGEN_RECURSIVE) + # The RECURSIVE tag can be used to specify whether or not + # subdirectories should be searched for input files as well. CMake + # projects generally evolve to span multiple directories, so it makes + # more sense for this to be on by default. Doxygen's default value + # has this setting turned off, so we override it. + set(DOXYGEN_RECURSIVE YES) + endif() + + if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY) + # The OUTPUT_DIRECTORY tag is used to specify the (relative or + # absolute) path into which the generated documentation will be + # written. If a relative path is used, Doxygen will interpret it as + # being relative to the location where doxygen was started, but we need + # to run Doxygen in the source tree so that relative input paths work + # intuitively. Therefore, we ensure that the output directory is always + # an absolute path and if the project provided a relative path, we + # treat it as relative to the current BINARY directory so that output + # is not generated inside the source tree. + set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + elseif(NOT IS_ABSOLUTE "${DOXYGEN_OUTPUT_DIRECTORY}") + get_filename_component(DOXYGEN_OUTPUT_DIRECTORY + "${DOXYGEN_OUTPUT_DIRECTORY}" + ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + if(NOT DEFINED DOXYGEN_HAVE_DOT) + # If you set the HAVE_DOT tag to YES then doxygen will assume the dot + # tool is available from the path. This tool is part of Graphviz (see: + # http://www.graphviz.org/), a graph visualization toolkit from AT&T + # and Lucent Bell Labs. The other options in this section have no + # effect if this option is set to NO. + # Doxygen's default value is: NO. + set(DOXYGEN_HAVE_DOT ${DOXYGEN_DOT_FOUND}) + endif() + + if(NOT DEFINED DOXYGEN_DOT_MULTI_TARGETS) + # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate + # multiple output files in one run (i.e. multiple -o and -T options on + # the command line). This makes dot run faster, but since only newer + # versions of dot (>1.8.10) support this, Doxygen disables this feature + # by default. + # This tag requires that the tag HAVE_DOT is set to YES. + set(DOXYGEN_DOT_MULTI_TARGETS YES) + endif() + + if(NOT DEFINED DOXYGEN_GENERATE_LATEX) + # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX + # output. We only want the HTML output enabled by default, so we turn + # this off if the project hasn't specified it. + set(DOXYGEN_GENERATE_LATEX NO) + endif() + + if(NOT DEFINED DOXYGEN_WARN_FORMAT) + if(CMAKE_VS_MSBUILD_COMMAND OR CMAKE_VS_DEVENV_COMMAND) + # The WARN_FORMAT tag determines the format of the warning messages + # that doxygen can produce. The string should contain the $file, + # $line and $text tags, which will be replaced by the file and line + # number from which the warning originated and the warning text. + # Optionally, the format may contain $version, which will be + # replaced by the version of the file (if it could be obtained via + # FILE_VERSION_FILTER). + # Doxygen's default value is: $file:$line: $text + set(DOXYGEN_WARN_FORMAT "$file($line) : $text ") + endif() + endif() + + if(DEFINED DOXYGEN_WARN_LOGFILE AND NOT IS_ABSOLUTE "${DOXYGEN_WARN_LOGFILE}") + # The WARN_LOGFILE tag can be used to specify a file to which warning and error + # messages should be written. If left blank the output is written to standard + # error (stderr). + get_filename_component(DOXYGEN_WARN_LOGFILE + "${DOXYGEN_WARN_LOGFILE}" + ABSOLUTE + BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + # Any files from the INPUT that match any of the EXCLUDE_PATTERNS will be + # excluded from the set of input files. We provide some additional patterns + # to prevent commonly unwanted things from CMake builds being pulled in. + # + # Note that the wildcards are matched against the file with absolute path, + # so to exclude all test directories for example use the pattern */test/* + list( + APPEND + DOXYGEN_EXCLUDE_PATTERNS + "*/.git/*" + "*/.svn/*" + "*/.hg/*" + "*/CMakeFiles/*" + "*/_CPack_Packages/*" + "DartConfiguration.tcl" + "CMakeLists.txt" + "CMakeCache.txt" + ) + + # Now bring in Doxgen's defaults for those things the project has not + # already set and we have not provided above + include("${PROJECT_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL) + + # Cleanup built HTMLs on "make clean" + # TODO Any other dirs? + if(DOXYGEN_GENERATE_HTML) + if(IS_ABSOLUTE "${DOXYGEN_HTML_OUTPUT}") + set(_args_clean_html_dir "${DOXYGEN_HTML_OUTPUT}") + else() + set(_args_clean_html_dir + "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}") + endif() + set_property(DIRECTORY APPEND PROPERTY + ADDITIONAL_MAKE_CLEAN_FILES "${_args_clean_html_dir}") + endif() + + # Build up a list of files we can identify from the inputs so we can list + # them as SOURCES in the custom target (makes them display in IDEs). We + # must do this before we transform the various DOXYGEN_... variables below + # because we need to process DOXYGEN_INPUT as a list first. + unset(_sources) + foreach(_item IN LISTS DOXYGEN_INPUT) + get_filename_component(_abs_item "${_item}" ABSOLUTE + BASE_DIR "${_args_WORKING_DIRECTORY}") + if(EXISTS "${_abs_item}" AND + NOT IS_DIRECTORY "${_abs_item}" AND + NOT IS_SYMLINK "${_abs_item}") + list(APPEND _sources "${_abs_item}") + endif() + endforeach() + if(_sources) + list(INSERT _sources 0 SOURCES) + endif() + + # Transform known list type options into space separated strings. + set(_doxygen_list_options + ABBREVIATE_BRIEF + ALIASES + CITE_BIB_FILES + DIAFILE_DIRS + DOTFILE_DIRS + DOT_FONTPATH + ENABLED_SECTIONS + EXAMPLE_PATH + EXAMPLE_PATTERNS + EXCLUDE + EXCLUDE_PATTERNS + EXCLUDE_SYMBOLS + EXPAND_AS_DEFINED + EXTENSION_MAPPING + EXTRA_PACKAGES + EXTRA_SEARCH_MAPPINGS + FILE_PATTERNS + FILTER_PATTERNS + FILTER_SOURCE_PATTERNS + HTML_EXTRA_FILES + HTML_EXTRA_STYLESHEET + IGNORE_PREFIX + IMAGE_PATH + INCLUDE_FILE_PATTERNS + INCLUDE_PATH + INPUT + LATEX_EXTRA_FILES + LATEX_EXTRA_STYLESHEET + MATHJAX_EXTENSIONS + MSCFILE_DIRS + PLANTUML_INCLUDE_PATH + PREDEFINED + QHP_CUST_FILTER_ATTRS + QHP_SECT_FILTER_ATTRS + STRIP_FROM_INC_PATH + STRIP_FROM_PATH + TAGFILES + TCL_SUBST + ) + foreach(_item IN LISTS _doxygen_list_options) + doxygen_list_to_quoted_strings(DOXYGEN_${_item}) + endforeach() + + # Transform known single value variables which may contain spaces, such as + # paths or description strings. + set(_doxygen_quoted_options + CHM_FILE + DIA_PATH + DOCBOOK_OUTPUT + DOCSET_FEEDNAME + DOCSET_PUBLISHER_NAME + DOT_FONTNAME + DOT_PATH + EXTERNAL_SEARCH_ID + FILE_VERSION_FILTER + GENERATE_TAGFILE + HHC_LOCATION + HTML_FOOTER + HTML_HEADER + HTML_OUTPUT + HTML_STYLESHEET + INPUT_FILTER + LATEX_FOOTER + LATEX_HEADER + LATEX_OUTPUT + LAYOUT_FILE + MAN_OUTPUT + MAN_SUBDIR + MATHJAX_CODEFILE + MSCGEN_PATH + OUTPUT_DIRECTORY + PERL_PATH + PLANTUML_JAR_PATH + PROJECT_BRIEF + PROJECT_LOGO + PROJECT_NAME + QCH_FILE + QHG_LOCATION + QHP_CUST_FILTER_NAME + QHP_VIRTUAL_FOLDER + RTF_EXTENSIONS_FILE + RTF_OUTPUT + RTF_STYLESHEET_FILE + SEARCHDATA_FILE + USE_MDFILE_AS_MAINPAGE + WARN_FORMAT + WARN_LOGFILE + XML_OUTPUT + ) + foreach(_item IN LISTS _doxygen_quoted_options) + doxygen_quote_value(DOXYGEN_${_item}) + endforeach() + + # Prepare doxygen configuration file + set(_doxyfile_template "${PROJECT_BINARY_DIR}/CMakeDoxyfile.in") + set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}") + configure_file("${_doxyfile_template}" "${_target_doxyfile}") + + # Add the target + add_custom_target( + ${targetName} + COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}" + WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}" + DEPENDS "${_target_doxyfile}" + COMMENT "${_args_COMMENT}" + ${_sources} + ) -mark_as_advanced( - DOXYGEN_EXECUTABLE - DOXYGEN_DOT_EXECUTABLE - ) +endfunction() diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake index 0561a3d..7d5534b 100644 --- a/Modules/FindImageMagick.cmake +++ b/Modules/FindImageMagick.cmake @@ -102,7 +102,7 @@ function(FIND_IMAGEMAGICK_API component header) ${ImageMagick_INCLUDE_DIRS} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include" PATH_SUFFIXES - ImageMagick ImageMagick-6 + ImageMagick ImageMagick-6 ImageMagick-7 DOC "Path to the ImageMagick arch-independent include dir." ) find_path(ImageMagick_${component}_ARCH_INCLUDE_DIR @@ -114,7 +114,7 @@ function(FIND_IMAGEMAGICK_API component header) ${ImageMagick_INCLUDE_DIRS} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]/include" PATH_SUFFIXES - ImageMagick ImageMagick-6 + ImageMagick ImageMagick-6 ImageMagick-7 DOC "Path to the ImageMagick arch-specific include dir." ) find_library(ImageMagick_${component}_LIBRARY @@ -195,17 +195,26 @@ foreach(component ${ImageMagick_FIND_COMPONENTS} ) if(component STREQUAL "Magick++") FIND_IMAGEMAGICK_API(Magick++ Magick++.h - Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8 Magick++-6.Q16HDRI Magick++-Q16HDRI Magick++-6.Q8HDRI Magick++-Q8HDRI + Magick++ CORE_RL_Magick++_ + Magick++-Q8 Magick++-Q16 Magick++-Q16HDRI Magick++-Q8HDRI + Magick++-6.Q16 Magick++-6.Q8 Magick++-6.Q16HDRI Magick++-6.Q8HDRI + Magick++-7.Q16 Magick++-7.Q8 Magick++-7.Q16HDRI Magick++-7.Q8HDRI ) list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_Magick++_LIBRARY) elseif(component STREQUAL "MagickWand") - FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h - Wand MagickWand CORE_RL_wand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI + FIND_IMAGEMAGICK_API(MagickWand "wand/MagickWand.h;MagickWand/MagickWand.h" + Wand MagickWand CORE_RL_wand_ + MagickWand-Q16 MagickWand-Q8 MagickWand-Q16HDRI MagickWand-Q8HDRI + MagickWand-6.Q16 MagickWand-6.Q8 MagickWand-6.Q16HDRI MagickWand-6.Q8HDRI + MagickWand-7.Q16 MagickWand-7.Q8 MagickWand-7.Q16HDRI MagickWand-7.Q8HDRI ) list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickWand_LIBRARY) elseif(component STREQUAL "MagickCore") - FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h - Magick MagickCore CORE_RL_magick_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8 MagickCore-6.Q16HDRI MagickCore-Q16HDRI MagickCore-6.Q8HDRI MagickCore-Q8HDRI + FIND_IMAGEMAGICK_API(MagickCore "magick/MagickCore.h;MagickCore/MagickCore.h" + Magick MagickCore CORE_RL_magick_ + MagickCore-Q16 MagickCore-Q8 MagickCore-Q16HDRI MagickCore-Q8HDRI + MagickCore-6.Q16 MagickCore-6.Q8 MagickCore-6.Q16HDRI MagickCore-6.Q8HDRI + MagickCore-7.Q16 MagickCore-7.Q8 MagickCore-7.Q16HDRI MagickCore-7.Q8HDRI ) list(APPEND ImageMagick_REQUIRED_VARS ImageMagick_MagickCore_LIBRARY) else() diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 6dc0444..33262f3 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -42,11 +42,11 @@ # # The following :prop_tgt:`IMPORTED` targets are also defined: # -# ``Protobuf::protobuf`` +# ``protobuf::libprotobuf`` # The protobuf library. -# ``Protobuf::protobuf-lite`` +# ``protobuf::libprotobuf-lite`` # The protobuf lite library. -# ``Protobuf::protoc`` +# ``protobuf::libprotoc`` # The protoc library. # # The following cache variables are also available to set or use: @@ -76,6 +76,7 @@ # include_directories(${Protobuf_INCLUDE_DIRS}) # include_directories(${CMAKE_CURRENT_BINARY_DIR}) # protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto) +# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto) # protobuf_generate_python(PROTO_PY foo.proto) # add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) # target_link_libraries(bar ${Protobuf_LIBRARIES}) @@ -89,12 +90,15 @@ # # Add custom commands to process ``.proto`` files to C++:: # -# protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...]) +# protobuf_generate_cpp (<SRCS> <HDRS> [EXPORT_MACRO <MACRO>] [<ARGN>...]) # # ``SRCS`` # Variable to define with autogenerated source files # ``HDRS`` # Variable to define with autogenerated header files +# ``EXPORT_MACRO`` +# is a macro which should expand to ``__declspec(dllexport)`` or +# ``__declspec(dllimport)`` depending on what is being compiled. # ``ARGN`` # ``.proto`` files # @@ -110,14 +114,21 @@ # ``.proto`` filess function(PROTOBUF_GENERATE_CPP SRCS HDRS) - if(NOT ARGN) + cmake_parse_arguments(protobuf "" "EXPORT_MACRO" "" ${ARGN}) + + set(PROTO_FILES "${protobuf_UNPARSED_ARGUMENTS}") + if(NOT PROTO_FILES) message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") return() endif() + if(protobuf_EXPORT_MACRO) + set(DLL_EXPORT_DECL "dllexport_decl=${protobuf_EXPORT_MACRO}:") + endif() + if(PROTOBUF_GENERATE_CPP_APPEND_PATH) # Create an include path for each file specified - foreach(FIL ${ARGN}) + foreach(FIL ${PROTO_FILES}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(ABS_PATH ${ABS_FIL} PATH) list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) @@ -145,7 +156,7 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) set(${SRCS}) set(${HDRS}) - foreach(FIL ${ARGN}) + foreach(FIL ${PROTO_FILES}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH) @@ -162,7 +173,7 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" COMMAND ${Protobuf_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} + ARGS "--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_BINARY_DIR}" ${_protobuf_include_path} ${ABS_FIL} DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE} COMMENT "Running C++ protocol buffer compiler on ${FIL}" VERBATIM ) @@ -420,72 +431,72 @@ if(Protobuf_INCLUDE_DIR) endif() if(Protobuf_LIBRARY) - if(NOT TARGET Protobuf::protobuf) - add_library(Protobuf::protobuf UNKNOWN IMPORTED) - set_target_properties(Protobuf::protobuf PROPERTIES + if(NOT TARGET protobuf::libprotobuf) + add_library(protobuf::libprotobuf UNKNOWN IMPORTED) + set_target_properties(protobuf::libprotobuf PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}") if(EXISTS "${Protobuf_LIBRARY}") - set_target_properties(Protobuf::protobuf PROPERTIES + set_target_properties(protobuf::libprotobuf PROPERTIES IMPORTED_LOCATION "${Protobuf_LIBRARY}") endif() if(EXISTS "${Protobuf_LIBRARY_RELEASE}") - set_property(TARGET Protobuf::protobuf APPEND PROPERTY + set_property(TARGET protobuf::libprotobuf APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(Protobuf::protobuf PROPERTIES + set_target_properties(protobuf::libprotobuf PROPERTIES IMPORTED_LOCATION_RELEASE "${Protobuf_LIBRARY_RELEASE}") endif() if(EXISTS "${Protobuf_LIBRARY_DEBUG}") - set_property(TARGET Protobuf::protobuf APPEND PROPERTY + set_property(TARGET protobuf::libprotobuf APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(Protobuf::protobuf PROPERTIES + set_target_properties(protobuf::libprotobuf PROPERTIES IMPORTED_LOCATION_DEBUG "${Protobuf_LIBRARY_DEBUG}") endif() endif() endif() if(Protobuf_LITE_LIBRARY) - if(NOT TARGET Protobuf::protobuf-lite) - add_library(Protobuf::protobuf-lite UNKNOWN IMPORTED) - set_target_properties(Protobuf::protobuf-lite PROPERTIES + if(NOT TARGET protobuf::libprotobuf-lite) + add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED) + set_target_properties(protobuf::libprotobuf-lite PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}") if(EXISTS "${Protobuf_LITE_LIBRARY}") - set_target_properties(Protobuf::protobuf-lite PROPERTIES + set_target_properties(protobuf::libprotobuf-lite PROPERTIES IMPORTED_LOCATION "${Protobuf_LITE_LIBRARY}") endif() if(EXISTS "${Protobuf_LITE_LIBRARY_RELEASE}") - set_property(TARGET Protobuf::protobuf-lite APPEND PROPERTY + set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(Protobuf::protobuf-lite PROPERTIES + set_target_properties(protobuf::libprotobuf-lite PROPERTIES IMPORTED_LOCATION_RELEASE "${Protobuf_LITE_LIBRARY_RELEASE}") endif() if(EXISTS "${Protobuf_LITE_LIBRARY_DEBUG}") - set_property(TARGET Protobuf::protobuf-lite APPEND PROPERTY + set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(Protobuf::protobuf-lite PROPERTIES + set_target_properties(protobuf::libprotobuf-lite PROPERTIES IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}") endif() endif() endif() if(Protobuf_PROTOC_LIBRARY) - if(NOT TARGET Protobuf::protoc) - add_library(Protobuf::protoc UNKNOWN IMPORTED) - set_target_properties(Protobuf::protoc PROPERTIES + if(NOT TARGET protobuf::libprotoc) + add_library(protobuf::libprotoc UNKNOWN IMPORTED) + set_target_properties(protobuf::libprotoc PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}") if(EXISTS "${Protobuf_PROTOC_LIBRARY}") - set_target_properties(Protobuf::protoc PROPERTIES + set_target_properties(protobuf::libprotoc PROPERTIES IMPORTED_LOCATION "${Protobuf_PROTOC_LIBRARY}") endif() if(EXISTS "${Protobuf_PROTOC_LIBRARY_RELEASE}") - set_property(TARGET Protobuf::protoc APPEND PROPERTY + set_property(TARGET protobuf::libprotoc APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_target_properties(Protobuf::protoc PROPERTIES + set_target_properties(protobuf::libprotoc PROPERTIES IMPORTED_LOCATION_RELEASE "${Protobuf_PROTOC_LIBRARY_RELEASE}") endif() if(EXISTS "${Protobuf_PROTOC_LIBRARY_DEBUG}") - set_property(TARGET Protobuf::protoc APPEND PROPERTY + set_property(TARGET protobuf::libprotoc APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) - set_target_properties(Protobuf::protoc PROPERTIES + set_target_properties(protobuf::libprotoc PROPERTIES IMPORTED_LOCATION_DEBUG "${Protobuf_PROTOC_LIBRARY_DEBUG}") endif() endif() diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake index dd9dffc..f0b2583 100644 --- a/Modules/FindXMLRPC.cmake +++ b/Modules/FindXMLRPC.cmake @@ -36,13 +36,13 @@ find_program(XMLRPC_C_CONFIG NAMES xmlrpc-c-config) # Check whether we found anything. if(XMLRPC_C_CONFIG) - set(XMLRPC_FOUND 1) + set(XMLRPC_C_FOUND 1) else() - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() # Lookup the include directories needed for the components requested. -if(XMLRPC_FOUND) +if(XMLRPC_C_FOUND) # Use the newer EXECUTE_PROCESS command if it is available. if(COMMAND EXECUTE_PROCESS) execute_process( @@ -74,12 +74,12 @@ if(XMLRPC_FOUND) endforeach() else() message("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]") - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() endif() # Lookup the libraries needed for the components requested. -if(XMLRPC_FOUND) +if(XMLRPC_C_FOUND) # Use the newer EXECUTE_PROCESS command if it is available. if(COMMAND EXECUTE_PROCESS) execute_process( @@ -123,7 +123,7 @@ if(XMLRPC_FOUND) # If any library is not found then the whole package is not found. if(NOT XMLRPC_${name}_LIBRARY) - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() # Build an ordered list of all the libraries needed. @@ -131,19 +131,13 @@ if(XMLRPC_FOUND) endforeach() else() message("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]") - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() endif() # Report the results. -if(NOT XMLRPC_FOUND) - set(XMLRPC_DIR_MESSAGE - "XMLRPC was not found. Make sure the entries XMLRPC_* are set.") - if(NOT XMLRPC_FIND_QUIETLY) - message(STATUS "${XMLRPC_DIR_MESSAGE}") - else() - if(XMLRPC_FIND_REQUIRED) - message(FATAL_ERROR "${XMLRPC_DIR_MESSAGE}") - endif() - endif() -endif() +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + XMLRPC + REQUIRED_VARS XMLRPC_C_FOUND XMLRPC_LIBRARIES XMLRPC_INCLUDE_DIRS + FAIL_MESSAGE "XMLRPC was not found. Make sure the entries XMLRPC_* are set.") diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 50477a4..cfb325b 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -144,10 +144,23 @@ macro(__windows_compiler_gnu_abi lang) if(CMAKE_GNUtoMS AND NOT CMAKE_GNUtoMS_LIB) # Find MS development environment setup script for this architecture. + # We need to use the MS Librarian tool (lib.exe). + # Find the most recent version available. + + # Query the VS Installer tool for locations of VS 2017 and above. + set(_vs_installer_paths "") + foreach(vs RANGE 15 15 -1) # change the first number to the largest supported version + cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) + if(_vs_dir) + list(APPEND _vs_installer_paths "${_vs_dir}/VC/Auxiliary/Build") + endif() + endforeach(vs) + if("${CMAKE_SIZEOF_VOID_P}" EQUAL 4) find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars32.bat DOC "Visual Studio vcvars32.bat" PATHS + ${_vs_installer_paths} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin" @@ -162,6 +175,7 @@ macro(__windows_compiler_gnu_abi lang) find_program(CMAKE_GNUtoMS_VCVARS NAMES vcvars64.bat vcvarsamd64.bat DOC "Visual Studio vcvarsamd64.bat" PATHS + ${_vs_installer_paths} "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0\\Setup\\VC;ProductDir]/bin/amd64" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VC;ProductDir]/bin/amd64" @@ -171,6 +185,7 @@ macro(__windows_compiler_gnu_abi lang) ) set(CMAKE_GNUtoMS_ARCH amd64) endif() + unset(_vs_installer_paths) set_property(CACHE CMAKE_GNUtoMS_VCVARS PROPERTY ADVANCED 1) if(CMAKE_GNUtoMS_VCVARS) # Create helper script to run lib.exe from MS environment. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index c7015ed..42be644 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 8) -set(CMake_VERSION_PATCH 20170522) +set(CMake_VERSION_PATCH 20170528) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h index 96c5882..10deda4 100644 --- a/Source/CPack/cmCPackLog.h +++ b/Source/CPack/cmCPackLog.h @@ -85,12 +85,12 @@ public: //! Set the various prefixes for the logging. SetPrefix sets the generic // prefix that overwrittes missing ones. - void SetPrefix(std::string pfx) { this->Prefix = pfx; } - void SetOutputPrefix(std::string pfx) { this->OutputPrefix = pfx; } - void SetVerbosePrefix(std::string pfx) { this->VerbosePrefix = pfx; } - void SetDebugPrefix(std::string pfx) { this->DebugPrefix = pfx; } - void SetWarningPrefix(std::string pfx) { this->WarningPrefix = pfx; } - void SetErrorPrefix(std::string pfx) { this->ErrorPrefix = pfx; } + void SetPrefix(std::string const& pfx) { this->Prefix = pfx; } + void SetOutputPrefix(std::string const& pfx) { this->OutputPrefix = pfx; } + void SetVerbosePrefix(std::string const& pfx) { this->VerbosePrefix = pfx; } + void SetDebugPrefix(std::string const& pfx) { this->DebugPrefix = pfx; } + void SetWarningPrefix(std::string const& pfx) { this->WarningPrefix = pfx; } + void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; } private: bool Verbose; diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 0d01493..5db6e09 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -24,7 +24,7 @@ bool cmAddCustomTargetCommand::InitialPass( return false; } - std::string targetName = args[0]; + std::string const& targetName = args[0]; // Check the target name. if (targetName.find_first_of("/\\") != targetName.npos) { diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index e49d5d5..a73b57e 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -19,7 +19,7 @@ bool cmAddDependenciesCommand::InitialPass( return false; } - std::string target_name = args[0]; + std::string const& target_name = args[0]; if (this->Makefile->IsAlias(target_name)) { std::ostringstream e; e << "Cannot add target-level dependencies to alias target \"" diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index aae1085..1d0376f 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -24,7 +24,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, } std::vector<std::string>::const_iterator s = args.begin(); - std::string exename = *s; + std::string const& exename = *s; ++s; bool use_win32 = false; diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 0bdf963..ebf1763 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -37,7 +37,7 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string>::const_iterator s = args.begin(); - std::string libName = *s; + std::string const& libName = *s; ++s; diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index dbd4dd1..1727ca5 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -20,7 +20,7 @@ bool cmAddSubDirectoryCommand::InitialPass( } // store the binpath - std::string srcArg = args[0]; + std::string const& srcArg = args[0]; std::string binArg; bool excludeFromAll = false; diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index c92c47b..847a416 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -18,13 +18,13 @@ class cmExecutionStatus; bool cmAuxSourceDirectoryCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) { - if (args.size() < 2 || args.size() > 2) { + if (args.size() != 2) { this->SetError("called with incorrect number of arguments"); return false; } std::string sourceListValue; - std::string templateDirectory = args[0]; + std::string const& templateDirectory = args[0]; std::string tdir; if (!cmSystemTools::FileIsFullPath(templateDirectory.c_str())) { tdir = this->Makefile->GetCurrentSourceDirectory(); @@ -54,7 +54,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass( std::string ext = file.substr(dotpos + 1); std::string base = file.substr(0, dotpos); // Process only source files - std::vector<std::string> srcExts = + std::vector<std::string> const& srcExts = this->Makefile->GetCMakeInstance()->GetSourceExtensions(); if (!base.empty() && std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end()) { diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 6836151..fd87600 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -32,7 +32,7 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) } // The cmake variable in which to store the result. - const char* variable = args[0].c_str(); + std::string const& variable = args[0]; // Parse remaining arguments. std::string configuration; @@ -104,7 +104,7 @@ bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args) return false; } - const char* define = args[0].c_str(); + std::string const& define = args[0]; const char* cacheValue = this->Makefile->GetDefinition(define); std::string configType; diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index e135ac6..4475c5a 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -26,7 +26,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( return false; } - std::string variable = args[current_index + 1]; + std::string const& variable = args[current_index + 1]; current_index += 2; if (args.size() < (current_index + 2) || args[current_index] != "QUERY") { @@ -41,7 +41,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( std::string result_list; for (size_t i = current_index + 1; i < args.size(); ++i) { - std::string key = args[i]; + std::string const& key = args[i]; if (i != current_index + 1) { result_list += ";"; } diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index b9c7549..18005f2 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -19,7 +19,7 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, return false; } - const char* inFile = args[0].c_str(); + std::string const& inFile = args[0]; if (!cmSystemTools::FileIsFullPath(inFile)) { this->InputFile = this->Makefile->GetCurrentSourceDirectory(); this->InputFile += "/"; @@ -38,7 +38,7 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, return false; } - const char* outFile = args[1].c_str(); + std::string const& outFile = args[1]; if (!cmSystemTools::FileIsFullPath(outFile)) { this->OutputFile = this->Makefile->GetCurrentBinaryDirectory(); this->OutputFile += "/"; diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx index 9a097f3..86a83da 100644 --- a/Source/cmDefinePropertyCommand.cxx +++ b/Source/cmDefinePropertyCommand.cxx @@ -20,23 +20,25 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args, // Get the scope in which to define the property. cmProperty::ScopeType scope; - if (args[0] == "GLOBAL") { + std::string const& scope_arg = args[0]; + + if (scope_arg == "GLOBAL") { scope = cmProperty::GLOBAL; - } else if (args[0] == "DIRECTORY") { + } else if (scope_arg == "DIRECTORY") { scope = cmProperty::DIRECTORY; - } else if (args[0] == "TARGET") { + } else if (scope_arg == "TARGET") { scope = cmProperty::TARGET; - } else if (args[0] == "SOURCE") { + } else if (scope_arg == "SOURCE") { scope = cmProperty::SOURCE_FILE; - } else if (args[0] == "TEST") { + } else if (scope_arg == "TEST") { scope = cmProperty::TEST; - } else if (args[0] == "VARIABLE") { + } else if (scope_arg == "VARIABLE") { scope = cmProperty::VARIABLE; - } else if (args[0] == "CACHED_VARIABLE") { + } else if (scope_arg == "CACHED_VARIABLE") { scope = cmProperty::CACHED_VARIABLE; } else { std::ostringstream e; - e << "given invalid scope " << args[0] << ". " + e << "given invalid scope " << scope_arg << ". " << "Valid scopes are " << "GLOBAL, DIRECTORY, TARGET, SOURCE, " << "TEST, VARIABLE, CACHED_VARIABLE."; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 2dffcaa..5b7b827 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -353,7 +353,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( all_files_map_t allFiles; std::vector<std::string> cFiles; - std::vector<std::string> srcExts = + std::vector<std::string> const& srcExts = this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions(); for (std::vector<cmLocalGenerator*>::const_iterator lg = lgs.begin(); @@ -387,7 +387,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( bool isCFile = false; std::string lang = (*si)->GetLanguage(); if (lang == "C" || lang == "CXX") { - std::string srcext = (*si)->GetExtension(); + std::string const& srcext = (*si)->GetExtension(); for (std::vector<std::string>::const_iterator ext = srcExts.begin(); ext != srcExts.end(); ++ext) { @@ -398,7 +398,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( } } - std::string fullPath = (*si)->GetFullPath(); + std::string const& fullPath = (*si)->GetFullPath(); if (isCFile) { cFiles.push_back(fullPath); @@ -414,7 +414,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( } } - std::vector<std::string> headerExts = + std::vector<std::string> const& headerExts = this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); // The following loop tries to add header files matching to implementation diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 98eebe6..adab061 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -240,7 +240,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( bool isCFile = false; std::string lang = (*si)->GetLanguage(); if (lang == "C" || lang == "CXX") { - std::string srcext = (*si)->GetExtension(); + std::string const& srcext = (*si)->GetExtension(); for (std::vector<std::string>::const_iterator ext = srcExts.begin(); ext != srcExts.end(); ++ext) { if (srcext == *ext) { @@ -600,9 +600,6 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( // which may have an acompanying header, one for all other files std::string projectType; - std::vector<std::string> headerExts = - this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); - std::map<std::string, cmSourceFile*> cFiles; std::set<std::string> otherFiles; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 8d1adc7..2a6ce98 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -453,7 +453,7 @@ void cmExtraEclipseCDT4Generator::WriteGroups( for (std::vector<const cmSourceFile*>::const_iterator fileIt = sFiles.begin(); fileIt != sFiles.end(); ++fileIt) { - std::string fullPath = (*fileIt)->GetFullPath(); + std::string const& fullPath = (*fileIt)->GetFullPath(); if (!cmSystemTools::FileIsDirectory(fullPath)) { std::string linkName4 = linkName3; @@ -508,7 +508,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml) for (std::vector<cmSourceFile*>::const_iterator sfIt = files.begin(); sfIt != files.end(); sfIt++) { // Add the file to the list of sources. - std::string source = (*sfIt)->GetFullPath(); + std::string const& source = (*sfIt)->GetFullPath(); cmSourceGroup* sourceGroup = makefile->FindSourceGroup(source.c_str(), sourceGroups); sourceGroup->AssignSource(*sfIt); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index ff6e2b7..32a539c 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -110,7 +110,7 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args, this->SetError("must be called with at least two arguments."); return false; } - std::string subCommand = args[0]; + std::string const& subCommand = args[0]; if (subCommand == "WRITE") { return this->HandleWriteCommand(args, false); } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 6f6a3f6..f67f353 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -731,104 +731,118 @@ bool cmFindPackageCommand::HandlePackageMode() } } - if (result && !found && (!this->Quiet || this->Required)) { - // The variable is not set. - std::ostringstream e; - std::ostringstream aw; - if (configFileSetFOUNDFalse) { - /* clang-format off */ - e << "Found package configuration file:\n" - " " << this->FileFound << "\n" - "but it set " << foundVar << " to FALSE so package \"" << - this->Name << "\" is considered to be NOT FOUND."; - /* clang-format on */ - if (!notFoundMessage.empty()) { - e << " Reason given by package: \n" << notFoundMessage << "\n"; - } - } - // If there are files in ConsideredConfigs, it means that FooConfig.cmake - // have been found, but they didn't have appropriate versions. - else if (!this->ConsideredConfigs.empty()) { - std::vector<ConfigFileInfo>::const_iterator duplicate_end = - cmRemoveDuplicates(this->ConsideredConfigs); - e << "Could not find a configuration file for package \"" << this->Name - << "\" that " - << (this->VersionExact ? "exactly matches" : "is compatible with") - << " requested version \"" << this->Version << "\".\n" - << "The following configuration files were considered but not " - "accepted:\n"; - for (std::vector<ConfigFileInfo>::const_iterator i = - this->ConsideredConfigs.begin(); - i != duplicate_end; ++i) { - e << " " << i->filename << ", version: " << i->version << "\n"; - } - } else { - std::string requestedVersionString; - if (!this->Version.empty()) { - requestedVersionString = " (requested version "; - requestedVersionString += this->Version; - requestedVersionString += ")"; + // package not found + if (result && !found) { + // warn if package required or neither quiet nor in config mode + if (this->Required || + !(this->Quiet || (this->UseConfigFiles && !this->UseFindModules))) { + // The variable is not set. + std::ostringstream e; + std::ostringstream aw; + if (configFileSetFOUNDFalse) { + /* clang-format off */ + e << "Found package configuration file:\n" + " " << this->FileFound << "\n" + "but it set " << foundVar << " to FALSE so package \"" << + this->Name << "\" is considered to be NOT FOUND."; + /* clang-format on */ + if (!notFoundMessage.empty()) { + e << " Reason given by package: \n" << notFoundMessage << "\n"; + } } - - if (this->UseConfigFiles) { - if (this->UseFindModules) { - 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 there are files in ConsideredConfigs, it means that FooConfig.cmake + // have been found, but they didn't have appropriate versions. + else if (!this->ConsideredConfigs.empty()) { + std::vector<ConfigFileInfo>::const_iterator duplicate_end = + cmRemoveDuplicates(this->ConsideredConfigs); + e << "Could not find a configuration file for package \"" << this->Name + << "\" that " + << (this->VersionExact ? "exactly matches" : "is compatible with") + << " requested version \"" << this->Version << "\".\n" + << "The following configuration files were considered but not " + "accepted:\n"; + for (std::vector<ConfigFileInfo>::const_iterator i = + this->ConsideredConfigs.begin(); + i != duplicate_end; ++i) { + e << " " << i->filename << ", version: " << i->version << "\n"; + } + } else { + std::string requestedVersionString; + if (!this->Version.empty()) { + requestedVersionString = " (requested version "; + requestedVersionString += this->Version; + requestedVersionString += ")"; } - 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" - << cmWrap(" ", this->Configs, "", "\n") << "\n"; + if (this->UseConfigFiles) { + if (this->UseFindModules) { + 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" + << cmWrap(" ", this->Configs, "", "\n") << "\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"; } + } - 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(); } - } - 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()); + } } - - if (!aw.str().empty()) { - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, aw.str()); + // output result if in config mode but not in quiet mode + else if (!this->Quiet) { + std::ostringstream aw; + aw << "Could NOT find " << this->Name << " (missing: " << this->Name + << "_DIR)"; + this->Makefile->DisplayStatus(aw.str().c_str(), -1); } } @@ -924,7 +938,7 @@ bool cmFindPackageCommand::FindConfig() bool cmFindPackageCommand::FindPrefixedConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator pi = prefixes.begin(); pi != prefixes.end(); ++pi) { if (this->SearchPrefix(*pi)) { @@ -936,7 +950,7 @@ bool cmFindPackageCommand::FindPrefixedConfig() bool cmFindPackageCommand::FindFrameworkConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator i = prefixes.begin(); i != prefixes.end(); ++i) { if (this->SearchFrameworkPrefix(*i)) { @@ -948,7 +962,7 @@ bool cmFindPackageCommand::FindFrameworkConfig() bool cmFindPackageCommand::FindAppBundleConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator i = prefixes.begin(); i != prefixes.end(); ++i) { if (this->SearchAppBundlePrefix(*i)) { diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 7962da6..5ba3326 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -20,7 +20,7 @@ bool cmGetCMakePropertyCommand::InitialPass( return false; } - std::string variable = args[0]; + std::string const& variable = args[0]; std::string output = "NOTFOUND"; if (args[1] == "VARIABLES") { diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 920e1a0..6cb8e19 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -20,7 +20,7 @@ bool cmGetDirectoryPropertyCommand::InitialPass( } std::vector<std::string>::const_iterator i = args.begin(); - std::string variable = *i; + std::string const& variable = *i; ++i; // get the directory argument if there is one diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 509ef95..1a5f08e 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -15,8 +15,8 @@ bool cmGetSourceFilePropertyCommand::InitialPass( this->SetError("called with incorrect number of arguments"); return false; } - const char* var = args[0].c_str(); - const char* file = args[1].c_str(); + std::string const& var = args[0]; + std::string const& file = args[1]; cmSourceFile* sf = this->Makefile->GetSource(file); // for the location we must create a source file first diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 2379292..0910a53 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -22,8 +22,8 @@ bool cmGetTargetPropertyCommand::InitialPass( this->SetError("called with incorrect number of arguments"); return false; } - std::string var = args[0]; - const std::string& targetName = args[1]; + std::string const& var = args[0]; + std::string const& targetName = args[1]; std::string prop; bool prop_exists = false; diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index a8a44b7..6424515 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -16,8 +16,8 @@ bool cmGetTestPropertyCommand::InitialPass( return false; } - std::string testName = args[0]; - std::string var = args[2]; + std::string const& testName = args[0]; + std::string const& var = args[2]; cmTest* test = this->Makefile->GetTest(testName); if (test) { const char* prop = CM_NULLPTR; diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index a958a17..e72c6e3 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -101,7 +101,7 @@ bool cmGlobalKdevelopGenerator::CreateFilelistFile( std::set<std::string> files; std::string tmp; - std::vector<std::string> hdrExts = + std::vector<std::string> const& hdrExts = this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); for (std::vector<cmLocalGenerator*>::const_iterator it = lgs.begin(); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 88fcb12..e1e165c 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -56,7 +56,7 @@ void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count) void cmGlobalNinjaGenerator::WriteDivider(std::ostream& os) { os << "# ======================================" - << "=======================================\n"; + "=======================================\n"; } void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index ba554aa..93e467c 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -75,29 +75,31 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args, this->DefaultComponentName = "Unspecified"; } + std::string const& mode = args[0]; + // Switch among the command modes. - if (args[0] == "SCRIPT") { + if (mode == "SCRIPT") { return this->HandleScriptMode(args); } - if (args[0] == "CODE") { + if (mode == "CODE") { return this->HandleScriptMode(args); } - if (args[0] == "TARGETS") { + if (mode == "TARGETS") { return this->HandleTargetsMode(args); } - if (args[0] == "FILES") { + if (mode == "FILES") { return this->HandleFilesMode(args); } - if (args[0] == "PROGRAMS") { + if (mode == "PROGRAMS") { return this->HandleFilesMode(args); } - if (args[0] == "DIRECTORY") { + if (mode == "DIRECTORY") { return this->HandleDirectoryMode(args); } - if (args[0] == "EXPORT") { + if (mode == "EXPORT") { return this->HandleExportMode(args); } - if (args[0] == "EXPORT_ANDROID_MK") { + if (mode == "EXPORT_ANDROID_MK") { return this->HandleExportAndroidMKMode(args); } @@ -165,7 +167,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) script.c_str(), false, component.c_str(), exclude_from_all)); } else if (doing_code) { doing_code = false; - std::string code = args[i]; + std::string const& code = args[i]; this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( code.c_str(), true, component.c_str(), exclude_from_all)); } diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 86fd46d..4a3b620 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -54,7 +54,7 @@ void cmInstallFilesCommand::FinalPass() } std::string testf; - std::string ext = this->FinalArgs[0]; + std::string const& ext = this->FinalArgs[0]; // two different options if (this->FinalArgs.size() > 1) { @@ -64,7 +64,7 @@ void cmInstallFilesCommand::FinalPass() // for each argument, get the files for (; s != this->FinalArgs.end(); ++s) { // replace any variables - std::string temps = *s; + std::string const& temps = *s; if (!cmSystemTools::GetFilenamePath(temps).empty()) { testf = cmSystemTools::GetFilenamePath(temps) + "/" + cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext; @@ -78,7 +78,7 @@ void cmInstallFilesCommand::FinalPass() } else // reg exp list { std::vector<std::string> files; - std::string regex = this->FinalArgs[0]; + std::string const& regex = this->FinalArgs[0]; cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex, files); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 307024a..e48378d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2258,7 +2258,7 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( { // Construct the object file name using the full path to the source // file which is its only unique identification. - const char* fullPath = source.GetFullPath().c_str(); + std::string const& fullPath = source.GetFullPath(); // Try referencing the source relative to the source tree. std::string relFromSource = diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index a8350b3..266710c 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -213,7 +213,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) std::vector<std::string> pools; cmSystemTools::ExpandListArgument(jobpools, pools); for (size_t i = 0; i < pools.size(); ++i) { - const std::string pool = pools[i]; + std::string const& pool = pools[i]; const std::string::size_type eq = pool.find('='); unsigned int jobs; if (eq != std::string::npos && diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index b2f0d22..14fd96f 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -30,7 +30,7 @@ bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args, i = 1; } for (; i < args.size(); ++i) { - std::string variable = args[i]; + std::string const& variable = args[i]; cmState* state = this->Makefile->GetState(); if (!state->GetCacheEntryValue(variable)) { this->Makefile->GetCMakeInstance()->AddCacheEntry( diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index 55451ff..5500eba 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -23,7 +23,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, if (args[i] == "NEWLINE_STYLE") { size_t const styleIndex = i + 1; if (args.size() > styleIndex) { - const std::string eol = args[styleIndex]; + std::string const& eol = args[styleIndex]; if (eol == "LF" || eol == "UNIX") { NewLineStyle = LF; return true; diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 332fa83..beddc6e 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -48,8 +48,6 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, cmSystemTools::MakeDirectory(out.c_str()); this->Makefile->AddCMakeOutputFile(out); - std::string newoutpath = out; - // Configure the Info.plist file. Note that it needs the executable name // to be set. std::string plist = outpath; @@ -60,7 +58,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist.c_str()); this->Makefile->AddCMakeOutputFile(plist); - outpath = newoutpath; + outpath = out; } void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index d47a047..d72c790 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -22,11 +22,14 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, this->SetError("PROJECT called with incorrect number of arguments"); return false; } - this->Makefile->SetProjectName(args[0]); - std::string bindir = args[0]; + std::string const& projectName = args[0]; + + this->Makefile->SetProjectName(projectName); + + std::string bindir = projectName; bindir += "_BINARY_DIR"; - std::string srcdir = args[0]; + std::string srcdir = projectName; srcdir += "_SOURCE_DIR"; this->Makefile->AddCacheDefinition( @@ -44,7 +47,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, this->Makefile->AddDefinition(srcdir, this->Makefile->GetCurrentSourceDirectory()); - this->Makefile->AddDefinition("PROJECT_NAME", args[0].c_str()); + this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str()); // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands @@ -54,10 +57,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, // will work. if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") || (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str()); - this->Makefile->AddCacheDefinition("CMAKE_PROJECT_NAME", args[0].c_str(), - "Value Computed by CMake", - cmStateEnums::STATIC); + this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str()); + this->Makefile->AddCacheDefinition( + "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake", + cmStateEnums::STATIC); } bool haveVersion = false; @@ -163,19 +166,19 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } std::string vv; - vv = args[0] + "_VERSION"; + vv = projectName + "_VERSION"; this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str()); this->Makefile->AddDefinition(vv, vs.c_str()); - vv = args[0] + "_VERSION_MAJOR"; + vv = projectName + "_VERSION_MAJOR"; this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]); this->Makefile->AddDefinition(vv, vb[0]); - vv = args[0] + "_VERSION_MINOR"; + vv = projectName + "_VERSION_MINOR"; this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]); this->Makefile->AddDefinition(vv, vb[1]); - vv = args[0] + "_VERSION_PATCH"; + vv = projectName + "_VERSION_PATCH"; this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]); this->Makefile->AddDefinition(vv, vb[2]); - vv = args[0] + "_VERSION_TWEAK"; + vv = projectName + "_VERSION_TWEAK"; this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]); this->Makefile->AddDefinition(vv, vb[3]); } else if (cmp0048 != cmPolicies::OLD) { @@ -186,11 +189,11 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, vv.push_back("PROJECT_VERSION_MINOR"); vv.push_back("PROJECT_VERSION_PATCH"); vv.push_back("PROJECT_VERSION_TWEAK"); - vv.push_back(args[0] + "_VERSION"); - vv.push_back(args[0] + "_VERSION_MAJOR"); - vv.push_back(args[0] + "_VERSION_MINOR"); - vv.push_back(args[0] + "_VERSION_PATCH"); - vv.push_back(args[0] + "_VERSION_TWEAK"); + vv.push_back(projectName + "_VERSION"); + vv.push_back(projectName + "_VERSION_MAJOR"); + vv.push_back(projectName + "_VERSION_MINOR"); + vv.push_back(projectName + "_VERSION_PATCH"); + vv.push_back(projectName + "_VERSION_TWEAK"); std::string vw; for (std::vector<std::string>::iterator i = vv.begin(); i != vv.end(); ++i) { @@ -234,7 +237,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, languages.push_back("CXX"); } this->Makefile->EnableLanguage(languages, false); - std::string extraInclude = "CMAKE_PROJECT_" + args[0] + "_INCLUDE"; + std::string extraInclude = "CMAKE_PROJECT_" + projectName + "_INCLUDE"; const char* include = this->Makefile->GetDefinition(extraInclude); if (include) { bool readit = this->Makefile->ReadDependentFile(include); diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 239b18d..e82665b 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -7,6 +7,7 @@ #include "cmCustomCommandLines.h" #include "cmFilePathChecksum.h" #include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -67,17 +68,19 @@ static std::string GetAutogenTargetFilesDir(cmGeneratorTarget const* target) targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); targetDir += "/"; targetDir += GetAutogenTargetName(target); - targetDir += ".dir/"; + targetDir += ".dir"; return targetDir; } static std::string GetAutogenTargetBuildDir(cmGeneratorTarget const* target) { - cmMakefile* makefile = target->Target->GetMakefile(); - std::string targetDir = makefile->GetCurrentBinaryDirectory(); - targetDir += "/"; - targetDir += GetAutogenTargetName(target); - targetDir += "/"; + std::string targetDir = GetSafeProperty(target, "AUTOGEN_BUILD_DIR"); + if (targetDir.empty()) { + cmMakefile* makefile = target->Target->GetMakefile(); + targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + } return targetDir; } @@ -151,6 +154,50 @@ static void GetCompileDefinitionsAndDirectories( } } +static bool IsMultiConfig(cmGlobalGenerator* globalGen) +{ + // FIXME: Xcode does not support per-config sources, yet. + // (EXCLUDED_SOURCE_FILE_NAMES) + // Treat it as a single configuration generator meanwhile. + if (globalGen->GetName().find("Xcode") != std::string::npos) { + return false; + } + return globalGen->IsMultiConfig(); +} + +static std::vector<std::string> GetConfigurations( + cmMakefile* makefile, std::string* config = CM_NULLPTR) +{ + std::vector<std::string> configs; + { + std::string cfg = makefile->GetConfigurations(configs); + if (config != CM_NULLPTR) { + *config = cfg; + } + } + // Add empty configuration on demand + if (configs.empty()) { + configs.push_back(""); + } + return configs; +} + +static std::vector<std::string> GetConfigurationSuffixes(cmMakefile* makefile) +{ + std::vector<std::string> suffixes; + if (IsMultiConfig(makefile->GetGlobalGenerator())) { + makefile->GetConfigurations(suffixes); + for (std::vector<std::string>::iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + it->insert(0, "_"); + } + } + if (suffixes.empty()) { + suffixes.push_back(""); + } + return suffixes; +} + static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, const std::string& value) { @@ -220,6 +267,17 @@ static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, return true; } +static void AddGeneratedSource(cmMakefile* makefile, + const std::string& filename, + cmQtAutoGeneratorCommon::GeneratorType genType) +{ + cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); + gFile->SetProperty("GENERATED", "1"); + gFile->SetProperty("SKIP_AUTOGEN", "On"); + + AddToSourceGroup(makefile, filename, genType); +} + static void AcquireScanFiles(cmGeneratorTarget const* target, std::vector<std::string>& mocUicSources, std::vector<std::string>& mocUicHeaders, @@ -276,10 +334,11 @@ static void AcquireScanFiles(cmGeneratorTarget const* target, static void MocSetupAutoTarget( cmGeneratorTarget const* target, const std::string& autogenTargetName, - const std::string& qtMajorVersion, + std::string const& qtMajorVersion, std::string const& config, + std::vector<std::string> const& configs, std::vector<std::string> const& mocSkipList, - std::map<std::string, std::string>& configIncludes, - std::map<std::string, std::string>& configDefines) + std::map<std::string, std::string>& configMocIncludes, + std::map<std::string, std::string>& configMocDefines) { cmLocalGenerator* lg = target->GetLocalGenerator(); cmMakefile* makefile = target->Target->GetMakefile(); @@ -301,35 +360,26 @@ static void MocSetupAutoTarget( } // Moc includes and compile definitions { - std::string _moc_incs; - std::string _moc_compile_defs; - std::vector<std::string> configs; - { - const std::string& config = makefile->GetConfigurations(configs); - GetCompileDefinitionsAndDirectories(target, config, _moc_incs, - _moc_compile_defs); - AddDefinitionEscaped(makefile, "_moc_incs", _moc_incs); - AddDefinitionEscaped(makefile, "_moc_compile_defs", _moc_compile_defs); - } + // Default settings + std::string incs; + std::string compileDefs; + GetCompileDefinitionsAndDirectories(target, config, incs, compileDefs); + AddDefinitionEscaped(makefile, "_moc_incs", incs); + AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); + + // Configuration specific settings for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) { - std::string config_moc_incs; - std::string config_moc_compile_defs; - GetCompileDefinitionsAndDirectories(target, *li, config_moc_incs, - config_moc_compile_defs); - if (config_moc_incs != _moc_incs) { - configIncludes[*li] = - cmOutputConverter::EscapeForCMake(config_moc_incs); - if (_moc_incs.empty()) { - _moc_incs = config_moc_incs; - } + std::string configIncs; + std::string configCompileDefs; + GetCompileDefinitionsAndDirectories(target, *li, configIncs, + configCompileDefs); + if (configIncs != incs) { + configMocIncludes[*li] = cmOutputConverter::EscapeForCMake(configIncs); } - if (config_moc_compile_defs != _moc_compile_defs) { - configDefines[*li] = - cmOutputConverter::EscapeForCMake(config_moc_compile_defs); - if (_moc_compile_defs.empty()) { - _moc_compile_defs = config_moc_compile_defs; - } + if (configCompileDefs != compileDefs) { + configMocDefines[*li] = + cmOutputConverter::EscapeForCMake(configCompileDefs); } } } @@ -375,7 +425,8 @@ static void UicGetOpts(cmGeneratorTarget const* target, } static void UicSetupAutoTarget( - cmGeneratorTarget const* target, const std::string& qtMajorVersion, + cmGeneratorTarget const* target, std::string const& qtMajorVersion, + std::string const& config, std::vector<std::string> const& configs, std::vector<std::string> const& uicSkipList, std::map<std::string, std::string>& configUicOptions) { @@ -396,25 +447,21 @@ static void UicSetupAutoTarget( } AddDefinitionEscaped(makefile, "_uic_search_paths", uicSearchPaths); } - // Uic target options { - std::string _uic_opts; - std::vector<std::string> configs; - UicGetOpts(target, makefile->GetConfigurations(configs), _uic_opts); - - AddDefinitionEscaped(makefile, "_uic_target_options", _uic_opts); + // Default settings + std::string uicOpts; + UicGetOpts(target, config, uicOpts); + AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts); + // Configuration specific settings for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) { - std::string config_uic_opts; - UicGetOpts(target, *li, config_uic_opts); - if (config_uic_opts != _uic_opts) { + std::string configUicOpts; + UicGetOpts(target, *li, configUicOpts); + if (configUicOpts != uicOpts) { configUicOptions[*li] = - cmOutputConverter::EscapeForCMake(config_uic_opts); - if (_uic_opts.empty()) { - _uic_opts = config_uic_opts; - } + cmOutputConverter::EscapeForCMake(configUicOpts); } } } @@ -623,14 +670,24 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenSources( { if (target->GetPropertyAsBool("AUTOMOC")) { cmMakefile* makefile = target->Target->GetMakefile(); - std::string mocCppFile = GetAutogenTargetBuildDir(target); - mocCppFile += "moc_compilation.cpp"; - { - cmSourceFile* gFile = makefile->GetOrCreateSource(mocCppFile, true); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + const std::vector<std::string> suffixes = + GetConfigurationSuffixes(makefile); + // Get build directory + const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); + // Register all compilation files as generated + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string mcFile = autogenBuildDir + "/mocs_compilation"; + mcFile += *it; + mcFile += ".cpp"; + AddGeneratedSource(makefile, mcFile, cmQtAutoGeneratorCommon::MOC); + } + // Mocs compilation file + if (IsMultiConfig(target->GetGlobalGenerator())) { + target->AddSource(autogenBuildDir + "/mocs_compilation_$<CONFIG>.cpp"); + } else { + target->AddSource(autogenBuildDir + "/mocs_compilation.cpp"); } - target->AddSource(mocCppFile); - AddToSourceGroup(makefile, mocCppFile, cmQtAutoGeneratorCommon::MOC); } } @@ -643,21 +700,30 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); + const bool multiConfig = IsMultiConfig(target->GetGlobalGenerator()); const std::string autogenTargetName = GetAutogenTargetName(target); const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); const std::string workingDirectory = cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); const std::string qtMajorVersion = GetQtMajorVersion(target); const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); + const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile); std::vector<std::string> autogenDepends; std::vector<std::string> autogenProvides; + // Remove build directories on cleanup + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + autogenBuildDir.c_str(), false); + // Remove old settings on cleanup { - std::string fname = GetAutogenTargetFilesDir(target); - fname += "/AutogenOldSettings.cmake"; - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fname.c_str(), - false); + std::string base = GetAutogenTargetFilesDir(target); + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string fname = base + "/AutogenOldSettings" + *it + ".cmake"; + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fname.c_str(), + false); + } } // Compose command lines @@ -698,22 +764,26 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( autogenComment = "Automatic " + tools + " for target " + target->GetName(); } - // Create autogen target build directory and add it to the clean files - cmSystemTools::MakeDirectory(autogenBuildDir); - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - autogenBuildDir.c_str(), false); + // Add moc compilation to generated files list + if (mocEnabled) { + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string mcFile = autogenBuildDir + "/mocs_compilation"; + mcFile += *it; + mcFile += ".cpp"; + autogenProvides.push_back(mcFile); + } + } - // Create autogen target includes directory and - // add it to the origin target INCLUDE_DIRECTORIES + // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES if (mocEnabled || uicEnabled) { - const std::string incsDir = autogenBuildDir + "include"; - cmSystemTools::MakeDirectory(incsDir); - target->AddIncludeDirectory(incsDir, true); - } + if (multiConfig) { + target->AddIncludeDirectory(autogenBuildDir + "/include_$<CONFIG>", + true); - // Register moc compilation file as generated - if (mocEnabled) { - autogenProvides.push_back(autogenBuildDir + "moc_compilation.cpp"); + } else { + target->AddIncludeDirectory(autogenBuildDir + "/include", true); + } } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -755,7 +825,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; if (!PropertyEnabled(sf, "SKIP_AUTOGEN")) { - const std::string ext = sf->GetExtension(); + std::string const& ext = sf->GetExtension(); // Add generated file that will be scanned by moc or uic to // the dependencies if (mocEnabled || uicEnabled) { @@ -784,23 +854,29 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Compose rcc output file name { - std::string rccOut = autogenBuildDir; - rccOut += fpathCheckSum.getPart(absFile); - rccOut += "/qrc_"; - rccOut += + std::string rccOutBase = autogenBuildDir + "/"; + rccOutBase += fpathCheckSum.getPart(absFile); + rccOutBase += "/qrc_"; + rccOutBase += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); - rccOut += ".cpp"; - - // Register rcc output file as generated - autogenProvides.push_back(rccOut); + // Register rcc ouput file as generated + for (std::vector<std::string>::const_iterator it = + suffixes.begin(); + it != suffixes.end(); ++it) { + std::string rccOutCfg = rccOutBase; + rccOutCfg += *it; + rccOutCfg += ".cpp"; + AddGeneratedSource(makefile, rccOutCfg, + cmQtAutoGeneratorCommon::RCC); + autogenProvides.push_back(rccOutCfg); + } // Add rcc output file to origin target sources - { - cmSourceFile* gFile = makefile->GetOrCreateSource(rccOut, true); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + if (multiConfig) { + target->AddSource(rccOutBase + "_$<CONFIG>.cpp"); + } else { + target->AddSource(rccOutBase + ".cpp"); } - target->AddSource(rccOut); - AddToSourceGroup(makefile, rccOut, cmQtAutoGeneratorCommon::RCC); } if (PropertyEnabled(sf, "GENERATED")) { @@ -889,9 +965,25 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( cmMakefile::ScopePushPop varScope(makefile); static_cast<void>(varScope); + // Get configurations + std::string config; + const std::vector<std::string> configs(GetConfigurations(makefile, &config)); + + // Configurations settings buffers + std::map<std::string, std::string> configSuffix; std::map<std::string, std::string> configMocIncludes; std::map<std::string, std::string> configMocDefines; std::map<std::string, std::string> configUicOptions; + + // Configuration suffix + if (IsMultiConfig(target->GetGlobalGenerator())) { + for (std::vector<std::string>::const_iterator it = configs.begin(); + it != configs.end(); ++it) { + configSuffix[*it] = "_" + *it; + } + } + + // Basic setup { const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); @@ -899,45 +991,46 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( const std::string autogenTargetName = GetAutogenTargetName(target); const std::string qtMajorVersion = GetQtMajorVersion(target); - std::vector<std::string> _sources; - std::vector<std::string> _headers; + std::vector<std::string> sources; + std::vector<std::string> headers; if (mocEnabled || uicEnabled || rccEnabled) { std::vector<std::string> mocSkipList; std::vector<std::string> uicSkipList; - AcquireScanFiles(target, _sources, _headers, mocSkipList, uicSkipList); + AcquireScanFiles(target, sources, headers, mocSkipList, uicSkipList); if (mocEnabled) { - MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, - mocSkipList, configMocIncludes, configMocDefines); + MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, config, + configs, mocSkipList, configMocIncludes, + configMocDefines); } if (uicEnabled) { - UicSetupAutoTarget(target, qtMajorVersion, uicSkipList, - configUicOptions); + UicSetupAutoTarget(target, qtMajorVersion, config, configs, + uicSkipList, configUicOptions); } if (rccEnabled) { RccSetupAutoTarget(target, qtMajorVersion); } } - AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName); - AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName()); + AddDefinitionEscaped(makefile, "_autogen_build_dir", + GetAutogenTargetBuildDir(target)); AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion); - AddDefinitionEscaped(makefile, "_sources", _sources); - AddDefinitionEscaped(makefile, "_headers", _headers); + AddDefinitionEscaped(makefile, "_sources", sources); + AddDefinitionEscaped(makefile, "_headers", headers); } - // Generate config file - std::string inputFile = cmSystemTools::GetCMakeRoot(); - inputFile += "/Modules/AutogenInfo.cmake.in"; - std::string outputFile = GetAutogenTargetFilesDir(target); - outputFile += "/AutogenInfo.cmake"; - - makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, - false); + // Generate info file + std::string infoFile = GetAutogenTargetFilesDir(target); + infoFile += "/AutogenInfo.cmake"; + { + std::string inf = cmSystemTools::GetCMakeRoot(); + inf += "/Modules/AutogenInfo.cmake.in"; + makefile->ConfigureFile(inf.c_str(), infoFile.c_str(), false, true, false); + } - // Append custom config definitions to info file - if (!configMocDefines.empty() || !configMocIncludes.empty() || - !configUicOptions.empty()) { + // Append custom definitions to info file on demand + if (!configSuffix.empty() || !configMocDefines.empty() || + !configMocIncludes.empty() || !configUicOptions.empty()) { // Ensure we have write permission in case .in was read-only. mode_t perm = 0; @@ -946,46 +1039,49 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( #else mode_t mode_write = S_IWUSR; #endif - cmSystemTools::GetPermissions(outputFile, perm); + cmSystemTools::GetPermissions(infoFile, perm); if (!(perm & mode_write)) { - cmSystemTools::SetPermissions(outputFile, perm | mode_write); + cmSystemTools::SetPermissions(infoFile, perm | mode_write); } - cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app); - if (!infoFile) { - std::string error = "Internal CMake error when trying to open file: "; - error += outputFile; - error += " for writing."; - cmSystemTools::Error(error.c_str()); - } else { - infoFile << "# Configuration specific options\n"; - if (!configMocDefines.empty()) { - for (std::map<std::string, std::string>::iterator - it = configMocDefines.begin(), - end = configMocDefines.end(); - it != end; ++it) { - infoFile << "set(AM_MOC_DEFINITIONS_" << it->first << " " - << it->second << ")\n"; - } + // Open and write file + cmsys::ofstream ofs(infoFile.c_str(), std::ios::app); + if (ofs) { + ofs << "# Configuration specific options\n"; + for (std::map<std::string, std::string>::iterator + it = configSuffix.begin(), + end = configSuffix.end(); + it != end; ++it) { + ofs << "set(AM_CONFIG_SUFFIX_" << it->first << " " << it->second + << ")\n"; } - if (!configMocIncludes.empty()) { - for (std::map<std::string, std::string>::iterator - it = configMocIncludes.begin(), - end = configMocIncludes.end(); - it != end; ++it) { - infoFile << "set(AM_MOC_INCLUDES_" << it->first << " " << it->second - << ")\n"; - } + for (std::map<std::string, std::string>::iterator + it = configMocDefines.begin(), + end = configMocDefines.end(); + it != end; ++it) { + ofs << "set(AM_MOC_DEFINITIONS_" << it->first << " " << it->second + << ")\n"; } - if (!configUicOptions.empty()) { - for (std::map<std::string, std::string>::iterator - it = configUicOptions.begin(), - end = configUicOptions.end(); - it != end; ++it) { - infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first << " " - << it->second << ")\n"; - } + for (std::map<std::string, std::string>::iterator + it = configMocIncludes.begin(), + end = configMocIncludes.end(); + it != end; ++it) { + ofs << "set(AM_MOC_INCLUDES_" << it->first << " " << it->second + << ")\n"; + } + for (std::map<std::string, std::string>::iterator + it = configUicOptions.begin(), + end = configUicOptions.end(); + it != end; ++it) { + ofs << "set(AM_UIC_TARGET_OPTIONS_" << it->first << " " << it->second + << ")\n"; } + } else { + // File open error + std::string error = "Internal CMake error when trying to open file: "; + error += cmQtAutoGeneratorCommon::Quoted(infoFile); + error += " for writing."; + cmSystemTools::Error(error.c_str()); } } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index d40e809..27e4928 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -78,8 +78,8 @@ static void InfoGet(cmMakefile* makefile, const char* key, cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); } -static void InfoGet(cmMakefile* makefile, const char* key, - const std::string& config, std::vector<std::string>& list) +static void InfoGetConfig(cmMakefile* makefile, const char* key, + const std::string& config, std::string& value) { const char* valueConf = CM_NULLPTR; { @@ -93,7 +93,16 @@ static void InfoGet(cmMakefile* makefile, const char* key, if (valueConf == CM_NULLPTR) { valueConf = makefile->GetSafeDefinition(key); } - cmSystemTools::ExpandListArgument(valueConf, list); + value = valueConf; +} + +static void InfoGetConfig(cmMakefile* makefile, const char* key, + const std::string& config, + std::vector<std::string>& list) +{ + std::string value; + InfoGetConfig(makefile, key, config, value); + cmSystemTools::ExpandListArgument(value, list); } inline static bool SettingsMatch(cmMakefile* makefile, const char* key, @@ -270,6 +279,7 @@ cmQtAutoGenerators::cmQtAutoGenerators() } } + // Moc macro filters this->MocMacroFilters[0].first = "Q_OBJECT"; this->MocMacroFilters[0].second.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); this->MocMacroFilters[1].first = "Q_GADGET"; @@ -358,12 +368,13 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( { this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); cmSystemTools::ConvertToUnixSlashes(this->SettingsFile); - this->SettingsFile += "/AutogenOldSettings.cmake"; + this->SettingsFile += "/AutogenOldSettings"; + this->SettingsFile += this->ConfigSuffix; + this->SettingsFile += ".cmake"; } - // - Target names - InfoGet(makefile, "AM_TARGET_NAME", this->AutogenTargetName); - InfoGet(makefile, "AM_ORIGIN_TARGET_NAME", this->OriginTargetName); + // -- Meta + InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); // - Files and directories InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir); @@ -372,6 +383,11 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_CMAKE_CURRENT_BINARY_DIR", this->CurrentBinaryDir); InfoGet(makefile, "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", this->IncludeProjectDirsBefore); + InfoGet(makefile, "AM_BUILD_DIR", this->AutogenBuildDir); + if (this->AutogenBuildDir.empty()) { + this->LogError("AutoGen: Error: Missing autogen build directory "); + return false; + } InfoGet(makefile, "AM_SOURCES", this->Sources); InfoGet(makefile, "AM_HEADERS", this->Headers); @@ -395,7 +411,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // - Moc if (this->MocEnabled()) { InfoGet(makefile, "AM_MOC_SKIP", this->MocSkipList); - InfoGet(makefile, "AM_MOC_DEFINITIONS", config, this->MocDefinitions); + InfoGetConfig(makefile, "AM_MOC_DEFINITIONS", config, + this->MocDefinitions); #ifdef _WIN32 { const std::string win32("WIN32"); @@ -404,7 +421,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } } #endif - InfoGet(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths); + InfoGetConfig(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths); InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions); InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode); { @@ -439,7 +456,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( if (this->UicEnabled()) { InfoGet(makefile, "AM_UIC_SKIP", this->UicSkipList); InfoGet(makefile, "AM_UIC_SEARCH_PATHS", this->UicSearchPaths); - InfoGet(makefile, "AM_UIC_TARGET_OPTIONS", config, this->UicTargetOptions); + InfoGetConfig(makefile, "AM_UIC_TARGET_OPTIONS", config, + this->UicTargetOptions); { std::vector<std::string> uicFilesVec; std::vector<std::string> uicOptionsVec; @@ -615,18 +633,23 @@ bool cmQtAutoGenerators::SettingsFileWrite() void cmQtAutoGenerators::Init(cmMakefile* makefile) { - this->AutogenBuildSubDir = this->AutogenTargetName; - this->AutogenBuildSubDir += "/"; - - this->MocCppFilenameRel = this->AutogenBuildSubDir; - this->MocCppFilenameRel += "moc_compilation.cpp"; - - this->MocCppFilenameAbs = this->CurrentBinaryDir + this->MocCppFilenameRel; + // Mocs compilation file + this->MocCompFileRel = "mocs_compilation"; + this->MocCompFileRel += this->ConfigSuffix; + this->MocCompFileRel += ".cpp"; + this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, this->MocCompFileRel); + + // Mocs include directory + this->AutogenIncludeDir = "include"; + this->AutogenIncludeDir += this->ConfigSuffix; + this->AutogenIncludeDir += "/"; // Moc predefs file if (!this->MocPredefsCmd.empty()) { - this->MocPredefsFileRel = this->AutogenBuildSubDir + "moc_predefs.h"; - this->MocPredefsFileAbs = this->CurrentBinaryDir + this->MocPredefsFileRel; + this->MocPredefsFileRel = "moc_predefs.h"; + this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, this->MocPredefsFileRel); } // Init file path checksum generator @@ -699,10 +722,10 @@ bool cmQtAutoGenerators::RunAutogen() // the program goes through all .cpp files to see which moc files are // included. It is not really interesting how the moc file is named, but // what file the moc is created from. Once a moc is included the same moc - // may not be included in the moc_compilation.cpp file anymore. OTOH if - // there's a header containing Q_OBJECT where no corresponding moc file - // is included anywhere a moc_<filename>.cpp file is created and included - // in the moc_compilation.cpp file. + // may not be included in the mocs_compilation_$<CONFIG>.cpp file anymore. + // OTOH if there's a header containing Q_OBJECT where no corresponding + // moc file is included anywhere a moc_<filename>.cpp file is created and + // included in the mocs_compilation_$<CONFIG>.cpp file. // key = moc source filepath, value = moc output filepath std::map<std::string, std::string> mocsIncluded; @@ -1107,7 +1130,7 @@ void cmQtAutoGenerators::MocParseHeaderContent( if (this->MocRequired(contentText)) { // Register moc job mocsNotIncluded[absFilename] = - this->ChecksumedPath(absFilename, "moc_", ".cpp"); + this->ChecksumedPath(absFilename, "moc_", this->ConfigSuffix + ".cpp"); this->MocFindDepends(absFilename, contentText, mocDepends); } } @@ -1257,37 +1280,31 @@ bool cmQtAutoGenerators::MocGenerateAll( } // Generate moc files that are included by source files. - { - const std::string subDir = "include/"; - for (std::map<std::string, std::string>::const_iterator it = - mocsIncluded.begin(); - it != mocsIncluded.end(); ++it) { - if (!this->MocGenerateFile(it->first, it->second, subDir, mocDepends)) { - if (this->MocRunFailed) { - return false; - } + for (std::map<std::string, std::string>::const_iterator it = + mocsIncluded.begin(); + it != mocsIncluded.end(); ++it) { + if (!this->MocGenerateFile(it->first, it->second, mocDepends, true)) { + if (this->MocRunFailed) { + return false; } } } // Generate moc files that are _not_ included by source files. bool mocCompFileGenerated = false; - { - const std::string subDir; - for (std::map<std::string, std::string>::const_iterator it = - mocsNotIncluded.begin(); - it != mocsNotIncluded.end(); ++it) { - if (this->MocGenerateFile(it->first, it->second, subDir, mocDepends)) { - mocCompFileGenerated = true; - } else { - if (this->MocRunFailed) { - return false; - } + for (std::map<std::string, std::string>::const_iterator it = + mocsNotIncluded.begin(); + it != mocsNotIncluded.end(); ++it) { + if (this->MocGenerateFile(it->first, it->second, mocDepends, false)) { + mocCompFileGenerated = true; + } else { + if (this->MocRunFailed) { + return false; } } } - // Compose moc_compilation.cpp content + // Compose mocs compilation file content std::string automocSource; { std::ostringstream ost; @@ -1306,18 +1323,18 @@ bool cmQtAutoGenerators::MocGenerateAll( automocSource = ost.str(); } - if (this->FileDiffers(this->MocCppFilenameAbs, automocSource)) { - // Actually write moc_compilation.cpp - this->LogBold("Generating MOC compilation " + this->MocCppFilenameRel); - if (!this->FileWrite("AutoMoc", this->MocCppFilenameAbs, automocSource)) { + if (this->FileDiffers(this->MocCompFileAbs, automocSource)) { + // Actually write mocs compilation file + this->LogBold("Generating MOC compilation " + this->MocCompFileRel); + if (!this->FileWrite("AutoMoc", this->MocCompFileAbs, automocSource)) { return false; } } else if (mocCompFileGenerated) { - // Only touch moc_compilation.cpp + // Only touch mocs compilation file if (this->Verbose) { - this->LogInfo("Touching MOC compilation " + this->MocCppFilenameRel); + this->LogInfo("Touching MOC compilation " + this->MocCompFileRel); } - cmSystemTools::Touch(this->MocCppFilenameAbs, false); + cmSystemTools::Touch(this->MocCompFileAbs, false); } return true; @@ -1328,15 +1345,16 @@ bool cmQtAutoGenerators::MocGenerateAll( */ bool cmQtAutoGenerators::MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDir, - const std::map<std::string, std::set<std::string> >& mocDepends) + const std::map<std::string, std::set<std::string> >& mocDepends, + bool included) { bool mocGenerated = false; bool generateMoc = this->MocSettingsChanged || this->MocPredefsChanged; const std::string mocFileRel = - this->AutogenBuildSubDir + subDir + mocFileName; - const std::string mocFileAbs = this->CurrentBinaryDir + mocFileRel; + included ? (this->AutogenIncludeDir + mocFileName) : mocFileName; + const std::string mocFileAbs = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, mocFileRel); if (!generateMoc) { // Test if the source file is newer that the build file @@ -1524,9 +1542,9 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, bool uicGenerated = false; bool generateUic = this->UicSettingsChanged; - const std::string uicFileRel = - this->AutogenBuildSubDir + "include/" + uiOutputFile; - const std::string uicFileAbs = this->CurrentBinaryDir + uicFileRel; + const std::string uicFileRel = this->AutogenIncludeDir + uiOutputFile; + const std::string uicFileAbs = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, uicFileRel); if (!generateUic) { // Test if the source file is newer that the build file @@ -1590,12 +1608,17 @@ bool cmQtAutoGenerators::RccGenerateAll() // generate single map with input / output names std::map<std::string, std::string> qrcGenMap; - for (std::vector<std::string>::const_iterator si = this->RccSources.begin(); - si != this->RccSources.end(); ++si) { - const std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si); - if (ext == ".qrc") { - qrcGenMap[*si] = - this->AutogenBuildSubDir + this->ChecksumedPath(*si, "qrc_", ".cpp"); + { + const std::string qrcPrefix = "qrc_"; + const std::string qrcSuffix = this->ConfigSuffix + ".cpp"; + for (std::vector<std::string>::const_iterator si = + this->RccSources.begin(); + si != this->RccSources.end(); ++si) { + const std::string ext = + cmsys::SystemTools::GetFilenameLastExtension(*si); + if (ext == ".qrc") { + qrcGenMap[*si] = this->ChecksumedPath(*si, qrcPrefix, qrcSuffix); + } } } @@ -1636,7 +1659,8 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, bool rccGenerated = false; bool generateRcc = this->RccSettingsChanged; - const std::string rccBuildFile = this->CurrentBinaryDir + rccOutputFile; + const std::string rccBuildFile = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile); if (!generateRcc) { // Test if the resources list file is newer than build file @@ -1827,9 +1851,9 @@ bool cmQtAutoGenerators::NameCollisionTest( * @brief Generates a file path based on the checksum of the source file path * @return The path */ -std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile, - const char* basePrefix, - const char* baseSuffix) const +std::string cmQtAutoGenerators::ChecksumedPath( + const std::string& sourceFile, const std::string& basePrefix, + const std::string& baseSuffix) const { std::string res = FPathChecksum.getPart(sourceFile); res += "/"; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 987110f..b525364 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -107,8 +107,8 @@ private: const std::map<std::string, std::set<std::string> >& mocDepends); bool MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDir, - const std::map<std::string, std::set<std::string> >& mocDepends); + const std::map<std::string, std::set<std::string> >& mocDepends, + bool included); // -- Uic file generation bool UicFindIncludedFile(std::string& absFile, const std::string& sourceFile, @@ -139,8 +139,8 @@ private: const std::map<std::string, std::string>& genFiles, std::multimap<std::string, std::string>& collisions) const; std::string ChecksumedPath(const std::string& sourceFile, - const char* basePrefix, - const char* baseSuffix) const; + const std::string& basePrefix, + const std::string& baseSuffix) const; bool MakeParentDirectory(const char* logPrefix, const std::string& filename) const; bool FileDiffers(const std::string& filename, const std::string& content); @@ -157,15 +157,15 @@ private: bool MocFindIncludedFile(std::string& absFile, const std::string& sourceFile, const std::string& includeString) const; - // -- Target names - std::string OriginTargetName; - std::string AutogenTargetName; + // -- Meta + std::string ConfigSuffix; // -- Directories std::string ProjectSourceDir; std::string ProjectBinaryDir; std::string CurrentSourceDir; std::string CurrentBinaryDir; - std::string AutogenBuildSubDir; + std::string AutogenBuildDir; + std::string AutogenIncludeDir; // -- Qt environment std::string QtMajorVersion; std::string MocExecutable; @@ -189,8 +189,8 @@ private: bool MocPredefsChanged; bool MocRelaxedMode; bool MocRunFailed; - std::string MocCppFilenameRel; - std::string MocCppFilenameAbs; + std::string MocCompFileRel; + std::string MocCompFileAbs; std::string MocPredefsFileRel; std::string MocPredefsFileAbs; std::vector<std::string> MocSkipList; diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index 5a52927..1db8441 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -15,7 +15,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, return true; } - const char* variable = args[0].c_str(); // VAR is always first + std::string const& variable = args[0]; // VAR is always first // get the old value const char* cacheValue = this->Makefile->GetDefinition(variable); diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx index 19bdd45..7fc6ed7 100644 --- a/Source/cmServer.cxx +++ b/Source/cmServer.cxx @@ -147,7 +147,7 @@ void cmServer::reportProgress(const char* msg, float progress, void* data) { const cmServerRequest* request = static_cast<const cmServerRequest*>(data); assert(request); - if (progress < 0.0 || progress > 1.0) { + if (progress < 0.0f || progress > 1.0f) { request->ReportMessage(msg, ""); } else { request->ReportProgress(0, static_cast<int>(progress * 1000), 1000, msg); diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 60c198a..b57f62a 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -138,7 +138,7 @@ bool cmSetPropertyCommand::HandleGlobalMode() // Set or append the property. cmake* cm = this->Makefile->GetCMakeInstance(); - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -188,7 +188,7 @@ bool cmSetPropertyCommand::HandleDirectoryMode() } // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -229,7 +229,7 @@ bool cmSetPropertyCommand::HandleTargetMode() bool cmSetPropertyCommand::HandleTarget(cmTarget* target) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -268,7 +268,7 @@ bool cmSetPropertyCommand::HandleSourceMode() bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -316,7 +316,7 @@ bool cmSetPropertyCommand::HandleTestMode() bool cmSetPropertyCommand::HandleTest(cmTest* test) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -383,7 +383,7 @@ bool cmSetPropertyCommand::HandleCacheMode() bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); cmState* state = this->Makefile->GetState(); if (this->Remove) { diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index d6907e3..7a097ba 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -128,7 +128,7 @@ bool cmStringCommand::HandleToUpperLowerCommand( return false; } - std::string outvar = args[2]; + std::string const& outvar = args[2]; std::string output; if (toUpper) { @@ -149,7 +149,7 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args) return false; } std::string::size_type cc; - std::string outvar = args[args.size() - 1]; + std::string const& outvar = args[args.size() - 1]; std::string output; for (cc = 1; cc < args.size() - 1; cc++) { int ch = atoi(args[cc].c_str()); @@ -212,7 +212,7 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args) this->SetError("sub-command REGEX requires a mode to be specified."); return false; } - std::string mode = args[1]; + std::string const& mode = args[1]; if (mode == "MATCH") { if (args.size() < 5) { this->SetError("sub-command REGEX, mode MATCH needs " @@ -247,8 +247,8 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) { //"STRING(REGEX MATCH <regular_expression> <output variable> // <input> [<input>...])\n"; - std::string regex = args[2]; - std::string outvar = args[3]; + std::string const& regex = args[2]; + std::string const& outvar = args[3]; this->Makefile->ClearMatches(); // Compile the regular expression. @@ -288,8 +288,8 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) { //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input> // [<input>...])\n"; - std::string regex = args[2]; - std::string outvar = args[3]; + std::string const& regex = args[2]; + std::string const& outvar = args[3]; this->Makefile->ClearMatches(); // Compile the regular expression. @@ -334,9 +334,9 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) { //"STRING(REGEX REPLACE <regular_expression> <replace_expression> // <output variable> <input> [<input>...])\n" - std::string regex = args[2]; - std::string replace = args[3]; - std::string outvar = args[4]; + std::string const& regex = args[2]; + std::string const& replace = args[3]; + std::string const& outvar = args[4]; // Pull apart the replace expression to find the escaped [0-9] values. std::vector<RegexReplacement> replacement; @@ -502,7 +502,7 @@ bool cmStringCommand::HandleCompareCommand( this->SetError("sub-command COMPARE requires a mode to be specified."); return false; } - std::string mode = args[1]; + std::string const& mode = args[1]; if ((mode == "EQUAL") || (mode == "NOTEQUAL") || (mode == "LESS") || (mode == "LESS_EQUAL") || (mode == "GREATER") || (mode == "GREATER_EQUAL")) { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 8978e18..dc7034e 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -196,7 +196,6 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, while (regEntry.find(source)) { // the arguments are the second match std::string key = regEntry.match(1); - std::string val; std::string reg = "["; reg += key + "]"; cmSystemTools::ReplaceString(source, reg.c_str(), "/registry"); @@ -348,12 +347,12 @@ bool cmSystemTools::IsInternallyOn(const char* val) if (!val) { return false; } - std::basic_string<char> v = val; + std::string v = val; if (v.size() > 4) { return false; } - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return v == "I_ON"; @@ -368,7 +367,7 @@ bool cmSystemTools::IsOn(const char* val) if (len > 4) { return false; } - std::basic_string<char> v(val, len); + std::string v(val, len); static std::set<std::string> onValues; if (onValues.empty()) { @@ -378,7 +377,7 @@ bool cmSystemTools::IsOn(const char* val) onValues.insert("TRUE"); onValues.insert("Y"); } - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return (onValues.count(v) > 0); @@ -413,8 +412,8 @@ bool cmSystemTools::IsOff(const char* val) offValues.insert("IGNORE"); } // Try and avoid toupper(). - std::basic_string<char> v(val, len); - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + std::string v(val, len); + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return (offValues.count(v) > 0); diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 9a5c1da..45fe430 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -78,7 +78,7 @@ bool cmTargetPropCommandBase::ProcessContentArgs( std::vector<std::string> const& args, unsigned int& argIndex, bool prepend, bool system) { - const std::string scope = args[argIndex]; + std::string const& scope = args[argIndex]; if (scope != "PUBLIC" && scope != "PRIVATE" && scope != "INTERFACE") { this->SetError("called with invalid arguments"); diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index 37d8bfb..eabd7ef 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -23,7 +23,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string>::const_iterator arg = args.begin(); // The first argument is the cache entry name. - std::string cacheEntry = *arg++; + std::string const& cacheEntry = *arg++; const char* cacheValue = this->Makefile->GetDefinition(cacheEntry); // If it exists already and appears up to date then we are done. If // the string contains "(IntDir)" but that is not the @@ -57,11 +57,11 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // The second argument is the utility's executable name, which will be // needed later. - std::string utilityName = *arg++; + std::string const& utilityName = *arg++; // The third argument specifies the relative directory of the source // of the utility. - std::string relativeSource = *arg++; + std::string const& relativeSource = *arg++; std::string utilitySource = this->Makefile->GetCurrentSourceDirectory(); utilitySource = utilitySource + "/" + relativeSource; diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 10b0a88..06ca53c 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -17,11 +17,11 @@ bool cmVariableRequiresCommand::InitialPass( return false; } - std::string testVariable = args[0]; + std::string const& testVariable = args[0]; if (!this->Makefile->IsOn(testVariable)) { return true; } - std::string resultVariable = args[1]; + std::string const& resultVariable = args[1]; bool requirementsMet = true; std::string notSet; bool hasAdvanced = false; diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 90b0b28..281850e 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -106,7 +106,7 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, this->SetError("must be called with at least one argument."); return false; } - std::string variable = args[0]; + std::string const& variable = args[0]; std::string command; if (args.size() > 1) { command = args[1]; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4fcf5dc..e174f13 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -982,19 +982,21 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( const char* mfcFlag = this->GeneratorTarget->Target->GetMakefile()->GetDefinition( "CMAKE_MFC_FLAG"); - std::string mfcFlagValue = mfcFlag ? mfcFlag : "0"; + if (mfcFlag) { + std::string const mfcFlagValue = mfcFlag; - std::string useOfMfcValue = "false"; - if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) { - if (mfcFlagValue == "1") { - useOfMfcValue = "Static"; - } else if (mfcFlagValue == "2") { - useOfMfcValue = "Dynamic"; + std::string useOfMfcValue = "false"; + if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) { + if (mfcFlagValue == "1") { + useOfMfcValue = "Static"; + } else if (mfcFlagValue == "2") { + useOfMfcValue = "Dynamic"; + } } + std::string mfcLine = "<UseOfMfc>"; + mfcLine += useOfMfcValue + "</UseOfMfc>\n"; + this->WriteString(mfcLine.c_str(), 2); } - std::string mfcLine = "<UseOfMfc>"; - mfcLine += useOfMfcValue + "</UseOfMfc>\n"; - this->WriteString(mfcLine.c_str(), 2); if ((this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY && this->ClOptions[config]->UsingUnicode()) || @@ -2072,15 +2074,15 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() return; } - this->WriteString("<PropertyGroup>\n", 2); + this->WriteString("<PropertyGroup>\n", 1); this->WriteString("<_ProjectFileVersion>10.0.20506.1" "</_ProjectFileVersion>\n", - 3); + 2); for (std::vector<std::string>::const_iterator config = this->Configurations.begin(); config != this->Configurations.end(); ++config) { if (ttype >= cmStateEnums::UTILITY) { - this->WritePlatformConfigTag("IntDir", config->c_str(), 3); + this->WritePlatformConfigTag("IntDir", config->c_str(), 2); *this->BuildFileStream << "$(Platform)\\$(Configuration)\\$(ProjectName)\\" << "</IntDir>\n"; @@ -2103,24 +2105,24 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() this->ConvertToWindowsSlash(intermediateDir); this->ConvertToWindowsSlash(outDir); - this->WritePlatformConfigTag("OutDir", config->c_str(), 3); + this->WritePlatformConfigTag("OutDir", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(outDir) << "</OutDir>\n"; - this->WritePlatformConfigTag("IntDir", config->c_str(), 3); + this->WritePlatformConfigTag("IntDir", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(intermediateDir) << "</IntDir>\n"; if (const char* workingDir = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_WORKING_DIRECTORY")) { this->WritePlatformConfigTag("LocalDebuggerWorkingDirectory", - config->c_str(), 3); + config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(workingDir) << "</LocalDebuggerWorkingDirectory>\n"; } std::string name = cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull); - this->WritePlatformConfigTag("TargetName", config->c_str(), 3); + this->WritePlatformConfigTag("TargetName", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(name) << "</TargetName>\n"; std::string ext = @@ -2130,13 +2132,13 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() // A single "." appears to be treated as an empty extension. ext = "."; } - this->WritePlatformConfigTag("TargetExt", config->c_str(), 3); + this->WritePlatformConfigTag("TargetExt", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(ext) << "</TargetExt>\n"; this->OutputLinkIncremental(*config); } } - this->WriteString("</PropertyGroup>\n", 2); + this->WriteString("</PropertyGroup>\n", 1); } void cmVisualStudio10TargetGenerator::OutputLinkIncremental( @@ -2157,13 +2159,13 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( Options& linkOptions = *(this->LinkOptions[configName]); const char* incremental = linkOptions.GetFlag("LinkIncremental"); - this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3); + this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 2); *this->BuildFileStream << (incremental ? incremental : "true") << "</LinkIncremental>\n"; linkOptions.RemoveFlag("LinkIncremental"); const char* manifest = linkOptions.GetFlag("GenerateManifest"); - this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3); + this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 2); *this->BuildFileStream << (manifest ? manifest : "true") << "</GenerateManifest>\n"; linkOptions.RemoveFlag("GenerateManifest"); @@ -2174,7 +2176,7 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( for (const char** f = flags; *f; ++f) { const char* flag = *f; if (const char* value = linkOptions.GetFlag(flag)) { - this->WritePlatformConfigTag(flag, configName.c_str(), 3); + this->WritePlatformConfigTag(flag, configName.c_str(), 2); *this->BuildFileStream << value << "</" << flag << ">\n"; linkOptions.RemoveFlag(flag); } diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index f569e80..fc5fd21 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -21,7 +21,7 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args, std::string message; std::vector<std::string>::const_iterator i = args.begin(); - std::string fileName = *i; + std::string const& fileName = *i; bool overwrite = true; i++; diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx index fcd1e48..cf55741 100644 --- a/Source/cm_codecvt.cxx +++ b/Source/cm_codecvt.cxx @@ -1,18 +1,23 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cm_codecvt.hxx" -#include <limits> #if defined(_WIN32) +#include <assert.h> +#include <string.h> #include <windows.h> #undef max #include "cmsys/Encoding.hxx" #endif +#if defined(_WIN32) +/* Number of leading ones before a zero in the byte (see cm_utf8.c). */ +extern "C" unsigned char const cm_utf8_ones[256]; +#endif + codecvt::codecvt(Encoding e) - : m_lastState(0) #if defined(_WIN32) - , m_codepage(0) + : m_codepage(0) #endif { switch (e) { @@ -45,76 +50,68 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, const char*& from_next, char* to, char* to_end, char*& to_next) const { + from_next = from; + to_next = to; if (m_noconv) { - return noconv; + return std::codecvt_base::noconv; } - std::codecvt_base::result res = error; #if defined(_WIN32) - from_next = from; - to_next = to; - bool convert = true; - size_t count = from_end - from; - const char* data = from; - unsigned int& stateId = reinterpret_cast<unsigned int&>(state); - if (count == 0) { - return codecvt::ok; - } else if (count == 1) { - if (stateId == 0) { - // decode first byte for UTF-8 - if ((*from & 0xF8) == 0xF0 || // 1111 0xxx; 4 bytes for codepoint - (*from & 0xF0) == 0xE0 || // 1110 xxxx; 3 bytes for codepoint - (*from & 0xE0) == 0xC0) // 110x xxxx; 2 bytes for codepoint - { - stateId = findStateId(); - codecvt::State& s = m_states.at(stateId - 1); - s.bytes[0] = *from; - convert = false; - if ((*from & 0xF8) == 0xF0) { - s.totalBytes = 4; - } else if ((*from & 0xF0) == 0xE0) { - s.totalBytes = 3; - } else if ((*from & 0xE0) == 0xC0) { - s.totalBytes = 2; - } - s.bytesLeft = s.totalBytes - 1; - }; - // else 1 byte for codepoint - } else { - codecvt::State& s = m_states.at(stateId - 1); - s.bytes[s.totalBytes - s.bytesLeft] = *from; - s.bytesLeft--; - data = s.bytes; - count = s.totalBytes - s.bytesLeft; - if ((*from & 0xC0) == 0x80) { // 10xx xxxx - convert = s.bytesLeft == 0; - } else { - // invalid multi-byte - convert = true; - } - if (convert) { - s.used = false; - if (stateId == m_lastState) { - m_lastState--; - } - stateId = 0; - } + // Use a const view of the state because we should not modify it until we + // have fully processed and consume a byte (with sufficient space in the + // output buffer). We call helpers to re-cast and modify the state + State const& lstate = reinterpret_cast<State&>(state); + + while (from_next != from_end) { + // Count leading ones in the bits of the next byte. + unsigned char const ones = + cm_utf8_ones[static_cast<unsigned char>(*from_next)]; + + if (ones != 1 && lstate.buffered != 0) { + // We have a buffered partial codepoint that we never completed. + return std::codecvt_base::error; + } else if (ones == 1 && lstate.buffered == 0) { + // This is a continuation of a codepoint that never started. + return std::codecvt_base::error; + } + + // Compute the number of bytes in the current codepoint. + int need = 0; + switch (ones) { + case 0: // 0xxx xxxx: new codepoint of size 1 + need = 1; + break; + case 1: // 10xx xxxx: continues a codepoint + assert(lstate.size != 0); + need = lstate.size; + break; + case 2: // 110x xxxx: new codepoint of size 2 + need = 2; + break; + case 3: // 1110 xxxx: new codepoint of size 3 + need = 3; + break; + case 4: // 1111 0xxx: new codepoint of size 4 + need = 4; + break; + default: // invalid byte + return std::codecvt_base::error; } - if (convert) { - std::wstring wide = cmsys::Encoding::ToWide(std::string(data, count)); - int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(), - static_cast<int>(wide.size()), to, - to_end - to, NULL, NULL); - if (r > 0) { - from_next = from_end; - to_next = to + r; - res = ok; + assert(need > 0); + + if (lstate.buffered + 1 == need) { + // This byte completes a codepoint. + std::codecvt_base::result decode_result = + this->Decode(state, need, from_next, to_next, to_end); + if (decode_result != std::codecvt_base::ok) { + return decode_result; } } else { - res = partial; - from_next = from_end; - to_next = to; + // This byte does not complete a codepoint. + this->BufferPartial(state, need, from_next); } } + + return std::codecvt_base::ok; #else static_cast<void>(state); static_cast<void>(from); @@ -123,46 +120,118 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, static_cast<void>(to); static_cast<void>(to_end); static_cast<void>(to_next); - res = codecvt::noconv; + return std::codecvt_base::noconv; #endif - return res; }; std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to, char* to_end, char*& to_next) const { - std::codecvt_base::result res = error; to_next = to; + if (m_noconv) { + return std::codecvt_base::noconv; + } #if defined(_WIN32) - unsigned int& stateId = reinterpret_cast<unsigned int&>(state); - if (stateId > 0) { - codecvt::State& s = m_states.at(stateId - 1); - s.used = false; - if (stateId == m_lastState) { - m_lastState--; - } - stateId = 0; - std::wstring wide = cmsys::Encoding::ToWide( - std::string(s.bytes, s.totalBytes - s.bytesLeft)); - int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(), - static_cast<int>(wide.size()), to, to_end - to, - NULL, NULL); - if (r > 0) { - to_next = to + r; - res = ok; - } - } else { - res = ok; + State& lstate = reinterpret_cast<State&>(state); + if (lstate.buffered != 0) { + return this->DecodePartial(state, to_next, to_end); } + return std::codecvt_base::ok; #else static_cast<void>(state); static_cast<void>(to_end); - res = ok; + return std::codecvt_base::ok; #endif - return res; }; +#if defined(_WIN32) +std::codecvt_base::result codecvt::Decode(mbstate_t& state, int size, + const char*& from_next, + char*& to_next, char* to_end) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Collect all the bytes for this codepoint. + char buf[4]; + memcpy(buf, lstate.partial, lstate.buffered); + buf[lstate.buffered] = *from_next; + + // Convert the encoding. + wchar_t wbuf[2]; + int wlen = + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buf, size, wbuf, 2); + if (wlen <= 0) { + return std::codecvt_base::error; + } + + int tlen = WideCharToMultiByte(m_codepage, 0, wbuf, wlen, to_next, + to_end - to_next, NULL, NULL); + if (tlen <= 0) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return std::codecvt_base::partial; + } + return std::codecvt_base::error; + } + + // Move past the now-consumed byte in the input buffer. + ++from_next; + + // Move past the converted codepoint in the output buffer. + to_next += tlen; + + // Re-initialize the state for the next codepoint to start. + lstate = State(); + + return std::codecvt_base::ok; +} + +std::codecvt_base::result codecvt::DecodePartial(mbstate_t& state, + char*& to_next, + char* to_end) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Try converting the partial codepoint. + wchar_t wbuf[2]; + int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, lstate.partial, + lstate.buffered, wbuf, 2); + if (wlen <= 0) { + return std::codecvt_base::error; + } + + int tlen = WideCharToMultiByte(m_codepage, 0, wbuf, wlen, to_next, + to_end - to_next, NULL, NULL); + if (tlen <= 0) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return std::codecvt_base::partial; + } + return std::codecvt_base::error; + } + + // Move past the converted codepoint in the output buffer. + to_next += tlen; + + // Re-initialize the state for the next codepoint to start. + lstate = State(); + + return std::codecvt_base::ok; +} + +void codecvt::BufferPartial(mbstate_t& state, int size, + const char*& from_next) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Save the byte in our buffer for later. + lstate.partial[lstate.buffered++] = *from_next; + lstate.size = size; + + // Move past the now-consumed byte in the input buffer. + ++from_next; +} +#endif + int codecvt::do_max_length() const throw() { return 4; @@ -172,44 +241,3 @@ int codecvt::do_encoding() const throw() { return 0; }; - -unsigned int codecvt::findStateId() const -{ - unsigned int stateId = 0; - bool add = false; - const unsigned int maxSize = std::numeric_limits<unsigned int>::max(); - if (m_lastState >= maxSize) { - m_lastState = 0; - } - if (m_states.size() <= m_lastState) { - add = true; - } else { - unsigned int i = m_lastState; - while (i < maxSize) { - codecvt::State& s = m_states.at(i); - i++; - if (!s.used) { - m_lastState = i; - stateId = m_lastState; - s.used = true; - s.totalBytes = 0; - s.bytesLeft = 0; - break; - } - if (i >= m_states.size()) { - i = 0; - } - if (i == m_lastState) { - add = true; - break; - } - } - }; - if (add) { - codecvt::State s = { true, 0, 0, { 0, 0, 0, 0 } }; - m_states.push_back(s); - m_lastState = (unsigned int)m_states.size(); - stateId = m_lastState; - } - return stateId; -}; diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx index b9b52ec..30c6d54 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -6,7 +6,6 @@ #include "cmConfigure.h" #include <locale> -#include <vector> #include <wchar.h> class codecvt : public std::codecvt<char, char, mbstate_t> @@ -35,21 +34,30 @@ protected: int do_encoding() const throw() CM_OVERRIDE; private: - typedef struct + // The mbstate_t argument to do_out and do_unshift is responsible + // for storing state between calls. We cannot control the type + // since we want to imbue on standard streams. However, we do + // know that it is a trivial type. Define our own type to overlay + // on it safely with no alignment requirements. + struct State { - bool used; - unsigned char totalBytes; - unsigned char bytesLeft; - char bytes[4]; - } State; + // Buffer bytes we have consumed from a partial codepoint. + char partial[3]; - unsigned int findStateId() const; + // Number of bytes we have buffered from a partial codepoint. + unsigned char buffered : 4; + + // Size of the current codepoint in bytes. + unsigned char size : 4; + }; bool m_noconv; - mutable std::vector<State> m_states; - mutable unsigned int m_lastState; #if defined(_WIN32) unsigned int m_codepage; + result Decode(mbstate_t& state, int need, const char*& from_next, + char*& to_next, char* to_end) const; + result DecodePartial(mbstate_t& state, char*& to_next, char* to_end) const; + void BufferPartial(mbstate_t& state, int need, const char*& from_next) const; #endif #endif diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c index 6c49b52..52af4a6 100644 --- a/Source/cm_utf8.c +++ b/Source/cm_utf8.c @@ -15,7 +15,7 @@ */ /* Number of leading ones before a zero in the byte. */ -static unsigned char const cm_utf8_ones[256] = { +unsigned char const cm_utf8_ones[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 53e9ab0..6894393 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -301,7 +301,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) { bool findPackageMode = false; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-D", 0) == 0) { std::string entry = arg.substr(2); if (entry.empty()) { @@ -617,7 +617,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, bool haveToolset = false; bool havePlatform = false; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-H", 0) == 0) { directoriesSet = true; std::string path = arg.substr(2); @@ -2146,7 +2146,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // process the arguments bool writeToStdout = true; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-G", 0) == 0) { std::string value = arg.substr(2); if (value.empty()) { diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index dc267e7..9f2e8b7 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -663,7 +663,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Command to change directory and run a program. if (args[1] == "chdir" && args.size() >= 4) { - std::string directory = args[2]; + std::string const& directory = args[2]; if (!cmSystemTools::FileExists(directory.c_str())) { cmSystemTools::Error("Directory does not exist for chdir command: ", args[2].c_str()); @@ -883,8 +883,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if (args[1] == "tar" && args.size() > 3) { const char* knownFormats[] = { "7zip", "gnutar", "pax", "paxr", "zip" }; - std::string flags = args[2]; - std::string outFile = args[3]; + std::string const& flags = args[2]; + std::string const& outFile = args[3]; std::vector<std::string> files; std::string mtime; std::string format; @@ -1077,9 +1077,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) int cmcmd::SymlinkLibrary(std::vector<std::string>& args) { int result = 0; - std::string realName = args[2]; - std::string soName = args[3]; - std::string name = args[4]; + std::string const& realName = args[2]; + std::string const& soName = args[3]; + std::string const& name = args[4]; if (soName != realName) { if (!cmcmd::SymlinkInternal(realName, soName)) { cmSystemTools::ReportLastSystemError("cmake_symlink_library"); @@ -1098,8 +1098,8 @@ int cmcmd::SymlinkLibrary(std::vector<std::string>& args) int cmcmd::SymlinkExecutable(std::vector<std::string>& args) { int result = 0; - std::string realName = args[2]; - std::string name = args[3]; + std::string const& realName = args[2]; + std::string const& name = args[3]; if (name != realName) { if (!cmcmd::SymlinkInternal(realName, name)) { cmSystemTools::ReportLastSystemError("cmake_symlink_executable"); diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst index d71832a..70a313e 100644 --- a/Source/kwsys/CONTRIBUTING.rst +++ b/Source/kwsys/CONTRIBUTING.rst @@ -27,10 +27,12 @@ copies of KWSys within dependent projects can be updated to get the changes. Code Style ========== -We use `clang-format`_ to define our style for C++ code in the KWSys source -tree. See the `.clang-format`_ configuration file for our style settings. -Use ``clang-format`` version 3.8 or higher to format source files. -See also the `clang-format.bash`_ script. +We use `clang-format`_ version **3.8** to define our style for C++ code in +the KWSys source tree. See the `.clang-format`_ configuration file for +our style settings. Use the `clang-format.bash`_ script to format source +code. It automatically runs ``clang-format`` on the set of source files +for which we enforce style. The script also has options to format only +a subset of files, such as those that are locally modified. .. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html .. _`.clang-format`: .clang-format diff --git a/Source/kwsys/ConsoleBuf.hxx.in b/Source/kwsys/ConsoleBuf.hxx.in index 32e680c..46d65a8 100644 --- a/Source/kwsys/ConsoleBuf.hxx.in +++ b/Source/kwsys/ConsoleBuf.hxx.in @@ -338,7 +338,7 @@ private: } bool decodeInputBuffer(const std::string buffer, std::wstring& wbuffer) { - int length = int(buffer.length()); + size_t length = buffer.length(); if (length == 0) { wbuffer = std::wstring(); return true; @@ -353,11 +353,12 @@ private: data += BOMsize; length -= BOMsize; } - const int wlength = - MultiByteToWideChar(actualCodepage, 0, data, length, NULL, 0); + const size_t wlength = static_cast<size_t>(MultiByteToWideChar( + actualCodepage, 0, data, static_cast<int>(length), NULL, 0)); wchar_t* wbuf = new wchar_t[wlength]; const bool success = - MultiByteToWideChar(actualCodepage, 0, data, length, wbuf, wlength) > 0 + MultiByteToWideChar(actualCodepage, 0, data, static_cast<int>(length), + wbuf, static_cast<int>(wlength)) > 0 ? true : false; wbuffer = std::wstring(wbuf, wlength); diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 6b00fc6..bfc895e 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -845,30 +845,6 @@ void SystemInformation::RunMemoryCheck() #define CLASSICAL_CPU_FREQ_LOOP 10000000 #define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 -#define MMX_FEATURE 0x00000001 -#define MMX_PLUS_FEATURE 0x00000002 -#define SSE_FEATURE 0x00000004 -#define SSE2_FEATURE 0x00000008 -#define AMD_3DNOW_FEATURE 0x00000010 -#define AMD_3DNOW_PLUS_FEATURE 0x00000020 -#define IA64_FEATURE 0x00000040 -#define MP_CAPABLE 0x00000080 -#define HYPERTHREAD_FEATURE 0x00000100 -#define SERIALNUMBER_FEATURE 0x00000200 -#define APIC_FEATURE 0x00000400 -#define SSE_FP_FEATURE 0x00000800 -#define SSE_MMX_FEATURE 0x00001000 -#define CMOV_FEATURE 0x00002000 -#define MTRR_FEATURE 0x00004000 -#define L1CACHE_FEATURE 0x00008000 -#define L2CACHE_FEATURE 0x00010000 -#define L3CACHE_FEATURE 0x00020000 -#define ACPI_FEATURE 0x00040000 -#define THERMALMONITOR_FEATURE 0x00080000 -#define TEMPSENSEDIODE_FEATURE 0x00100000 -#define FREQUENCYID_FEATURE 0x00200000 -#define VOLTAGEID_FREQUENCY 0x00400000 - // Status Flag #define HT_NOT_CAPABLE 0 #define HT_ENABLED 1 @@ -1867,11 +1843,11 @@ int SystemInformationImplementation::GetProcessorCacheSize() int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID) { switch (dwCacheID) { - case L1CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L1CACHE: return this->Features.L1CacheSize; - case L2CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L2CACHE: return this->Features.L2CacheSize; - case L3CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L3CACHE: return this->Features.L3CacheSize; } return -1; @@ -1882,104 +1858,121 @@ bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature) bool bHasFeature = false; // Check for MMX instructions. - if (((dwFeature & MMX_FEATURE) != 0) && this->Features.HasMMX) + if (((dwFeature & SystemInformation::CPU_FEATURE_MMX) != 0) && + this->Features.HasMMX) bHasFeature = true; // Check for MMX+ instructions. - if (((dwFeature & MMX_PLUS_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_MMX_PLUS) != 0) && this->Features.ExtendedFeatures.HasMMXPlus) bHasFeature = true; // Check for SSE FP instructions. - if (((dwFeature & SSE_FEATURE) != 0) && this->Features.HasSSE) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE) != 0) && + this->Features.HasSSE) bHasFeature = true; // Check for SSE FP instructions. - if (((dwFeature & SSE_FP_FEATURE) != 0) && this->Features.HasSSEFP) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_FP) != 0) && + this->Features.HasSSEFP) bHasFeature = true; // Check for SSE MMX instructions. - if (((dwFeature & SSE_MMX_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_MMX) != 0) && this->Features.ExtendedFeatures.HasSSEMMX) bHasFeature = true; // Check for SSE2 instructions. - if (((dwFeature & SSE2_FEATURE) != 0) && this->Features.HasSSE2) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE2) != 0) && + this->Features.HasSSE2) bHasFeature = true; // Check for 3DNow! instructions. - if (((dwFeature & AMD_3DNOW_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW) != 0) && this->Features.ExtendedFeatures.Has3DNow) bHasFeature = true; // Check for 3DNow+ instructions. - if (((dwFeature & AMD_3DNOW_PLUS_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS) != 0) && this->Features.ExtendedFeatures.Has3DNowPlus) bHasFeature = true; // Check for IA64 instructions. - if (((dwFeature & IA64_FEATURE) != 0) && this->Features.HasIA64) + if (((dwFeature & SystemInformation::CPU_FEATURE_IA64) != 0) && + this->Features.HasIA64) bHasFeature = true; // Check for MP capable. - if (((dwFeature & MP_CAPABLE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_MP_CAPABLE) != 0) && this->Features.ExtendedFeatures.SupportsMP) bHasFeature = true; // Check for a serial number for the processor. - if (((dwFeature & SERIALNUMBER_FEATURE) != 0) && this->Features.HasSerial) + if (((dwFeature & SystemInformation::CPU_FEATURE_SERIALNUMBER) != 0) && + this->Features.HasSerial) bHasFeature = true; // Check for a local APIC in the processor. - if (((dwFeature & APIC_FEATURE) != 0) && this->Features.HasAPIC) + if (((dwFeature & SystemInformation::CPU_FEATURE_APIC) != 0) && + this->Features.HasAPIC) bHasFeature = true; // Check for CMOV instructions. - if (((dwFeature & CMOV_FEATURE) != 0) && this->Features.HasCMOV) + if (((dwFeature & SystemInformation::CPU_FEATURE_CMOV) != 0) && + this->Features.HasCMOV) bHasFeature = true; // Check for MTRR instructions. - if (((dwFeature & MTRR_FEATURE) != 0) && this->Features.HasMTRR) + if (((dwFeature & SystemInformation::CPU_FEATURE_MTRR) != 0) && + this->Features.HasMTRR) bHasFeature = true; // Check for L1 cache size. - if (((dwFeature & L1CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L1CACHE) != 0) && (this->Features.L1CacheSize != -1)) bHasFeature = true; // Check for L2 cache size. - if (((dwFeature & L2CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L2CACHE) != 0) && (this->Features.L2CacheSize != -1)) bHasFeature = true; // Check for L3 cache size. - if (((dwFeature & L3CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L3CACHE) != 0) && (this->Features.L3CacheSize != -1)) bHasFeature = true; // Check for ACPI capability. - if (((dwFeature & ACPI_FEATURE) != 0) && this->Features.HasACPI) + if (((dwFeature & SystemInformation::CPU_FEATURE_ACPI) != 0) && + this->Features.HasACPI) bHasFeature = true; // Check for thermal monitor support. - if (((dwFeature & THERMALMONITOR_FEATURE) != 0) && this->Features.HasThermal) + if (((dwFeature & SystemInformation::CPU_FEATURE_THERMALMONITOR) != 0) && + this->Features.HasThermal) bHasFeature = true; // Check for temperature sensing diode support. - if (((dwFeature & TEMPSENSEDIODE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_TEMPSENSEDIODE) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode) bHasFeature = true; // Check for frequency ID support. - if (((dwFeature & FREQUENCYID_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_FREQUENCYID) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID) bHasFeature = true; // Check for voltage ID support. - if (((dwFeature & VOLTAGEID_FREQUENCY) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_VOLTAGEID_FREQUENCY) != + 0) && this->Features.ExtendedFeatures.PowerManagement.HasVoltageID) bHasFeature = true; + // Check for FPU support. + if (((dwFeature & SystemInformation::CPU_FEATURE_FPU) != 0) && + this->Features.HasFPU) + bHasFeature = true; + return bHasFeature; } diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index 54e7fc1..516c505 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -26,6 +26,33 @@ class @KWSYS_NAMESPACE@_EXPORT SystemInformation SystemInformationImplementation* Implementation; public: + // possible parameter values for DoesCPUSupportFeature() + static const long int CPU_FEATURE_MMX = 1 << 0; + static const long int CPU_FEATURE_MMX_PLUS = 1 << 1; + static const long int CPU_FEATURE_SSE = 1 << 2; + static const long int CPU_FEATURE_SSE2 = 1 << 3; + static const long int CPU_FEATURE_AMD_3DNOW = 1 << 4; + static const long int CPU_FEATURE_AMD_3DNOW_PLUS = 1 << 5; + static const long int CPU_FEATURE_IA64 = 1 << 6; + static const long int CPU_FEATURE_MP_CAPABLE = 1 << 7; + static const long int CPU_FEATURE_HYPERTHREAD = 1 << 8; + static const long int CPU_FEATURE_SERIALNUMBER = 1 << 9; + static const long int CPU_FEATURE_APIC = 1 << 10; + static const long int CPU_FEATURE_SSE_FP = 1 << 11; + static const long int CPU_FEATURE_SSE_MMX = 1 << 12; + static const long int CPU_FEATURE_CMOV = 1 << 13; + static const long int CPU_FEATURE_MTRR = 1 << 14; + static const long int CPU_FEATURE_L1CACHE = 1 << 15; + static const long int CPU_FEATURE_L2CACHE = 1 << 16; + static const long int CPU_FEATURE_L3CACHE = 1 << 17; + static const long int CPU_FEATURE_ACPI = 1 << 18; + static const long int CPU_FEATURE_THERMALMONITOR = 1 << 19; + static const long int CPU_FEATURE_TEMPSENSEDIODE = 1 << 20; + static const long int CPU_FEATURE_FREQUENCYID = 1 << 21; + static const long int CPU_FEATURE_VOLTAGEID_FREQUENCY = 1 << 22; + static const long int CPU_FEATURE_FPU = 1 << 23; + +public: SystemInformation(); ~SystemInformation(); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4b335bd..335267a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1385,6 +1385,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindBZip2) endif() + if(CMake_TEST_FindDoxygen) + add_subdirectory(FindDoxygen) + endif() + if(CMake_TEST_FindGSL) add_subdirectory(FindGSL) endif() diff --git a/Tests/FindDoxygen/CMakeLists.txt b/Tests/FindDoxygen/CMakeLists.txt new file mode 100644 index 0000000..daceaa3 --- /dev/null +++ b/Tests/FindDoxygen/CMakeLists.txt @@ -0,0 +1,20 @@ +add_test(NAME FindDoxygen.SimpleTest COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindDoxygen/SimpleTest" + "${CMake_BINARY_DIR}/Tests/FindDoxygen/SimpleTest" + --build-target allDocTargets + ${build_generator_args} + --build-options ${build_options} +) + +if(CMake_TEST_FindDoxygen_Dot) + add_test(NAME FindDoxygen.DotComponentTest COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindDoxygen/DotComponentTestTest" + "${CMake_BINARY_DIR}/Tests/FindDoxygen/DotComponentTestTest" + ${build_generator_args} + --build-options ${build_options} + ) +endif() diff --git a/Tests/FindDoxygen/DotComponentTestTest/CMakeLists.txt b/Tests/FindDoxygen/DotComponentTestTest/CMakeLists.txt new file mode 100644 index 0000000..586f0ff --- /dev/null +++ b/Tests/FindDoxygen/DotComponentTestTest/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.8) +project(TestFindDoxygenDot VERSION 1.0 LANGUAGES NONE) + +# Testing a new signature w/ components +find_package(Doxygen REQUIRED COMPONENTS dot) + +# No backwards compatibility expected when component form is used +if(TARGET Doxygen::doxygen) + if(DOXYGEN) + message(FATAL_ERROR "DOXYGEN unexpectedly defined with component form") + endif() +else() + message(FATAL_ERROR "Import target Doxygen::doxygen not defined") +endif() + +if(NOT TARGET Doxygen::dot) + message(FATAL_ERROR "Import target Doxygen::dot not defined") +endif() diff --git a/Tests/FindDoxygen/SimpleTest/CMakeLists.txt b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt new file mode 100644 index 0000000..332cecc --- /dev/null +++ b/Tests/FindDoxygen/SimpleTest/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.8) +project(TestFindDoxygen VERSION 1.0 LANGUAGES NONE) + +# Testing backward compatible signature +find_package(Doxygen REQUIRED) + +if(TARGET Doxygen::doxygen) + # Check backward compatibility + if(NOT DOXYGEN_EXECUTABLE) + message(FATAL_ERROR "Backward compatibility broken: DOXYGEN_EXECUTABLE not set") + endif() + if(NOT DOXYGEN) + message(FATAL_ERROR "Backward compatibility broken: DOXYGEN not set") + endif() + # Check presence of expected generated files + foreach(file CMakeDoxyfile.in CMakeDoxygenDefaults.cmake) + if(NOT EXISTS "${PROJECT_BINARY_DIR}/${file}") + message(FATAL_ERROR "Missing generated file: ${file}") + endif() + endforeach() +else() + message(FATAL_ERROR "Import target Doxygen::doxygen not defined") +endif() + +doxygen_add_docs(docsNoArgs) +if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsNoArgs") + message(FATAL_ERROR "Missing generated file: Doxyfile.docsNoArgs") +endif() +if(NOT TARGET docsNoArgs) + message(FATAL_ERROR "Target docsNoArgs not created") +endif() + +configure_file(spaces_in_name.cpp.in "spaces in name.cpp" COPYONLY) +doxygen_add_docs(docsWithArgs + "${CMAKE_CURRENT_BINARY_DIR}/spaces in name.cpp" + main.cpp +) +if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsWithArgs") + message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithArgs") +endif() +if(NOT TARGET docsWithArgs) + message(FATAL_ERROR "Target docsWithArgs not created") +endif() +# Note that CMake inserts at least one entry into SOURCES when a COMMAND or +# DEPENDS option is given to add_custom_target(), so rather than looking for an +# exact match, we only verify that the files we expect to be there are present +get_target_property(srcList docsWithArgs SOURCES) +set(expectedList + "${CMAKE_CURRENT_BINARY_DIR}/spaces in name.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" +) +foreach(f IN LISTS expectedList) + if(NOT f IN_LIST srcList) + message(FATAL_ERROR "SOURCES missing file: ${f}") + endif() +endforeach() + +add_custom_target(allDocTargets) +add_dependencies(allDocTargets docsNoArgs docsWithArgs) diff --git a/Tests/FindDoxygen/SimpleTest/main.cpp b/Tests/FindDoxygen/SimpleTest/main.cpp new file mode 100644 index 0000000..925f0af --- /dev/null +++ b/Tests/FindDoxygen/SimpleTest/main.cpp @@ -0,0 +1,4 @@ +/** + * \file + * \brief One C++ file w/ sample Doxygen comment just to produce any docs... + */ diff --git a/Tests/FindDoxygen/SimpleTest/spaces_in_name.cpp.in b/Tests/FindDoxygen/SimpleTest/spaces_in_name.cpp.in new file mode 100644 index 0000000..c1b9ffd --- /dev/null +++ b/Tests/FindDoxygen/SimpleTest/spaces_in_name.cpp.in @@ -0,0 +1,4 @@ +/** + * \file + * \brief This file name contains spaces + */ diff --git a/Tests/FindProtobuf/Test/CMakeLists.txt b/Tests/FindProtobuf/Test/CMakeLists.txt index d7a5081..8b6e38a 100644 --- a/Tests/FindProtobuf/Test/CMakeLists.txt +++ b/Tests/FindProtobuf/Test/CMakeLists.txt @@ -5,7 +5,7 @@ include(CTest) find_package(Protobuf REQUIRED) add_executable(test_tgt main.cxx) -target_link_libraries(test_tgt Protobuf::protobuf) +target_link_libraries(test_tgt protobuf::libprotobuf) add_test(NAME test_tgt COMMAND test_tgt) add_executable(test_var main.cxx) @@ -14,7 +14,7 @@ target_link_libraries(test_var PRIVATE ${Protobuf_LIBRARIES}) add_test(NAME test_var COMMAND test_var) add_executable(test_tgt_lite main.cxx) -target_link_libraries(test_tgt_lite Protobuf::protobuf-lite) +target_link_libraries(test_tgt_lite protobuf::libprotobuf-lite) add_test(NAME test_tgt_lite COMMAND test_tgt_lite) add_executable(test_var_lite main.cxx) @@ -23,7 +23,7 @@ target_link_libraries(test_var_lite PRIVATE ${Protobuf_LITE_LIBRARIES}) add_test(NAME test_var_lite COMMAND test_var_lite) add_executable(test_tgt_protoc main-protoc.cxx) -target_link_libraries(test_tgt_protoc Protobuf::protoc) +target_link_libraries(test_tgt_protoc protobuf::libprotoc) add_test(NAME test_tgt_protoc COMMAND test_tgt_protoc) add_executable(test_var_protoc main-protoc.cxx) diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt index 70175fb..3ea1294 100644 --- a/Tests/QtAutoUicInterface/CMakeLists.txt +++ b/Tests/QtAutoUicInterface/CMakeLists.txt @@ -53,6 +53,12 @@ set_property(TARGET KI18n APPEND PROPERTY # END upstream +if(${CMAKE_GENERATOR} MATCHES "Visual Studio") +set(INC_DIR "include_${CMAKE_BUILD_TYPE}" ) +else() +set(INC_DIR "include" ) +endif() + add_library(LibWidget libwidget.cpp) target_link_libraries(LibWidget KI18n ${QT_GUI_TARGET}) set_property(TARGET LibWidget PROPERTY NO_KUIT_SEMANTIC ON) @@ -64,6 +70,6 @@ target_link_libraries(MyWidget KI18n ${QT_GUI_TARGET}) add_executable(QtAutoUicInterface main.cpp) target_compile_definitions(QtAutoUicInterface PRIVATE - UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/LibWidget_autogen/include/ui_libwidget.h" - UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/MyWidget_autogen/include/ui_mywidget.h" + UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/LibWidget_autogen/${INC_DIR}/ui_libwidget.h" + UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/MyWidget_autogen/${INC_DIR}/ui_mywidget.h" ) diff --git a/Tests/RunCMake/find_dependency/CMakeLists.txt b/Tests/RunCMake/find_dependency/CMakeLists.txt index 04d09f2..12cd3c7 100644 --- a/Tests/RunCMake/find_dependency/CMakeLists.txt +++ b/Tests/RunCMake/find_dependency/CMakeLists.txt @@ -1,4 +1,3 @@ cmake_minimum_required(VERSION 2.8.4) project(${RunCMake_TEST} NONE) -set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}") include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt b/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/find_dependency/EXACT-no-version-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt b/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt deleted file mode 100644 index 348f8bb..0000000 --- a/Tests/RunCMake/find_dependency/EXACT-no-version-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\): - Invalid arguments to find_dependency. EXACT may only be specified if a - VERSION is specified -Call Stack \(most recent call first\): - EXACT-no-version.cmake:4 \(find_dependency\) - CMakeLists.txt:4 \(include\) diff --git a/Tests/RunCMake/find_dependency/EXACT-no-version.cmake b/Tests/RunCMake/find_dependency/EXACT-no-version.cmake deleted file mode 100644 index b05665b7..0000000 --- a/Tests/RunCMake/find_dependency/EXACT-no-version.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -include(CMakeFindDependencyMacro) - -find_dependency(Pack1 EXACT) diff --git a/Tests/RunCMake/find_dependency/RunCMakeTest.cmake b/Tests/RunCMake/find_dependency/RunCMakeTest.cmake index 9403136..a72d189 100644 --- a/Tests/RunCMake/find_dependency/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_dependency/RunCMakeTest.cmake @@ -1,7 +1,10 @@ include(RunCMake) -run_cmake(EXACT-no-version) -run_cmake(empty-version) -run_cmake(empty-arg-3) -run_cmake(invalid-arg-3) -run_cmake(extra-args) +# Success tests +run_cmake(realistic) +run_cmake(basic) + +# Failure tests +run_cmake(invalid-arg) +run_cmake(bad-version-fuzzy) +run_cmake(bad-version-exact) diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3-result.txt b/Tests/RunCMake/find_dependency/bad-version-exact-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/find_dependency/invalid-arg-3-result.txt +++ b/Tests/RunCMake/find_dependency/bad-version-exact-result.txt diff --git a/Tests/RunCMake/find_dependency/bad-version-exact-stderr.txt b/Tests/RunCMake/find_dependency/bad-version-exact-stderr.txt new file mode 100644 index 0000000..0929f84 --- /dev/null +++ b/Tests/RunCMake/find_dependency/bad-version-exact-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at .*/Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(find_package\): + Could not find a configuration file for package "Pack1" that exactly + matches requested version "1.1". + + The following configuration files were considered but not accepted: + + .*/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1Config.cmake, version: 1.3 + +Call Stack \(most recent call first\): + bad-version-exact.cmake:5 \(find_dependency\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_dependency/bad-version-exact.cmake b/Tests/RunCMake/find_dependency/bad-version-exact.cmake new file mode 100644 index 0000000..c4ca5e2 --- /dev/null +++ b/Tests/RunCMake/find_dependency/bad-version-exact.cmake @@ -0,0 +1,5 @@ +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}") + +include(CMakeFindDependencyMacro) + +find_dependency(Pack1 1.1 EXACT REQUIRED) diff --git a/Tests/RunCMake/find_dependency/extra-args-result.txt b/Tests/RunCMake/find_dependency/bad-version-fuzzy-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/find_dependency/extra-args-result.txt +++ b/Tests/RunCMake/find_dependency/bad-version-fuzzy-result.txt diff --git a/Tests/RunCMake/find_dependency/bad-version-fuzzy-stderr.txt b/Tests/RunCMake/find_dependency/bad-version-fuzzy-stderr.txt new file mode 100644 index 0000000..c63256f --- /dev/null +++ b/Tests/RunCMake/find_dependency/bad-version-fuzzy-stderr.txt @@ -0,0 +1,11 @@ +CMake Error at .*/Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(find_package\): + Could not find a configuration file for package "Pack1" that is compatible + with requested version "1.4". + + The following configuration files were considered but not accepted: + + .*/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1Config.cmake, version: 1.3 + +Call Stack \(most recent call first\): + bad-version-fuzzy.cmake:5 \(find_dependency\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_dependency/bad-version-fuzzy.cmake b/Tests/RunCMake/find_dependency/bad-version-fuzzy.cmake new file mode 100644 index 0000000..c7cf4ee --- /dev/null +++ b/Tests/RunCMake/find_dependency/bad-version-fuzzy.cmake @@ -0,0 +1,5 @@ +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}") + +include(CMakeFindDependencyMacro) + +find_dependency(Pack1 1.4 REQUIRED) diff --git a/Tests/RunCMake/find_dependency/basic.cmake b/Tests/RunCMake/find_dependency/basic.cmake new file mode 100644 index 0000000..c7795f2 --- /dev/null +++ b/Tests/RunCMake/find_dependency/basic.cmake @@ -0,0 +1,5 @@ +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}") + +include(CMakeFindDependencyMacro) + +find_dependency(Pack1 1.1) diff --git a/Tests/RunCMake/find_dependency/empty-arg-3-result.txt b/Tests/RunCMake/find_dependency/empty-arg-3-result.txt deleted file mode 100644 index d00491f..0000000 --- a/Tests/RunCMake/find_dependency/empty-arg-3-result.txt +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt b/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt deleted file mode 100644 index bf9b02b..0000000 --- a/Tests/RunCMake/find_dependency/empty-arg-3-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\): - Invalid arguments to find_dependency -Call Stack \(most recent call first\): - empty-arg-3.cmake:4 \(find_dependency\) - CMakeLists.txt:4 \(include\) diff --git a/Tests/RunCMake/find_dependency/empty-arg-3.cmake b/Tests/RunCMake/find_dependency/empty-arg-3.cmake deleted file mode 100644 index b08200a..0000000 --- a/Tests/RunCMake/find_dependency/empty-arg-3.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -include(CMakeFindDependencyMacro) - -find_dependency(Pack1 1.2 "") diff --git a/Tests/RunCMake/find_dependency/empty-version-stderr.txt b/Tests/RunCMake/find_dependency/empty-version-stderr.txt deleted file mode 100644 index b5e9f46..0000000 --- a/Tests/RunCMake/find_dependency/empty-version-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at .*/Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\): - Invalid arguments to find_dependency. VERSION is empty -Call Stack \(most recent call first\): - empty-version.cmake:4 \(find_dependency\) - CMakeLists.txt:4 \(include\) diff --git a/Tests/RunCMake/find_dependency/empty-version.cmake b/Tests/RunCMake/find_dependency/empty-version.cmake deleted file mode 100644 index e6f17cd..0000000 --- a/Tests/RunCMake/find_dependency/empty-version.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -include(CMakeFindDependencyMacro) - -find_dependency(Pack1 "") diff --git a/Tests/RunCMake/find_dependency/extra-args-stderr.txt b/Tests/RunCMake/find_dependency/extra-args-stderr.txt deleted file mode 100644 index 83a7f02..0000000 --- a/Tests/RunCMake/find_dependency/extra-args-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\): - Invalid arguments to find_dependency -Call Stack \(most recent call first\): - extra-args.cmake:4 \(find_dependency\) - CMakeLists.txt:4 \(include\) diff --git a/Tests/RunCMake/find_dependency/extra-args.cmake b/Tests/RunCMake/find_dependency/extra-args.cmake deleted file mode 100644 index 209645a..0000000 --- a/Tests/RunCMake/find_dependency/extra-args.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -include(CMakeFindDependencyMacro) - -find_dependency(Pack1 1.2 EXACT PATHS "${CMAKE_BINARY_DIR}") diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt b/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt deleted file mode 100644 index fee8d5d..0000000 --- a/Tests/RunCMake/find_dependency/invalid-arg-3-stderr.txt +++ /dev/null @@ -1,5 +0,0 @@ -CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(message\): - Invalid arguments to find_dependency -Call Stack \(most recent call first\): - invalid-arg-3.cmake:4 \(find_dependency\) - CMakeLists.txt:4 \(include\) diff --git a/Tests/RunCMake/find_dependency/empty-version-result.txt b/Tests/RunCMake/find_dependency/invalid-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/find_dependency/empty-version-result.txt +++ b/Tests/RunCMake/find_dependency/invalid-arg-result.txt diff --git a/Tests/RunCMake/find_dependency/invalid-arg-stderr.txt b/Tests/RunCMake/find_dependency/invalid-arg-stderr.txt new file mode 100644 index 0000000..16077b2 --- /dev/null +++ b/Tests/RunCMake/find_dependency/invalid-arg-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at .*Modules/CMakeFindDependencyMacro.cmake:[0-9]+ \(find_package\): + find_package called with invalid argument "EXACTYPO" +Call Stack \(most recent call first\): + invalid-arg.cmake:5 \(find_dependency\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_dependency/invalid-arg-3.cmake b/Tests/RunCMake/find_dependency/invalid-arg.cmake index 40ede07..daaf569 100644 --- a/Tests/RunCMake/find_dependency/invalid-arg-3.cmake +++ b/Tests/RunCMake/find_dependency/invalid-arg.cmake @@ -1,3 +1,4 @@ +set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}") include(CMakeFindDependencyMacro) diff --git a/Tests/RunCMake/find_dependency/realistic.cmake b/Tests/RunCMake/find_dependency/realistic.cmake new file mode 100644 index 0000000..e633a31 --- /dev/null +++ b/Tests/RunCMake/find_dependency/realistic.cmake @@ -0,0 +1,3 @@ +set(Pack2_DIR "${CMAKE_CURRENT_SOURCE_DIR}/share/cmake/Pack2") + +find_package(Pack2 1.2 REQUIRED) diff --git a/Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake b/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1Config.cmake index 7d55ef6..7d55ef6 100644 --- a/Tests/RunCMake/find_dependency/Pack1/Pack1Config.cmake +++ b/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1Config.cmake diff --git a/Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake b/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1ConfigVersion.cmake index dfb7b6c..dfb7b6c 100644 --- a/Tests/RunCMake/find_dependency/Pack1/Pack1ConfigVersion.cmake +++ b/Tests/RunCMake/find_dependency/share/cmake/Pack1/Pack1ConfigVersion.cmake diff --git a/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2Config.cmake b/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2Config.cmake new file mode 100644 index 0000000..7e8a60b --- /dev/null +++ b/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2Config.cmake @@ -0,0 +1,6 @@ +include(CMakeFindDependencyMacro) + +find_dependency(Pack1 PATHS ${CMAKE_CURRENT_LIST_DIR}/..) + +add_library(Pack2::Lib INTERFACE IMPORTED) +set_target_properties(Pack2::Lib PROPERTIES INTERFACE_LINK_LIBRARIES Pack1::Lib) diff --git a/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2ConfigVersion.cmake b/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2ConfigVersion.cmake new file mode 100644 index 0000000..dfb7b6c --- /dev/null +++ b/Tests/RunCMake/find_dependency/share/cmake/Pack2/Pack2ConfigVersion.cmake @@ -0,0 +1,11 @@ + +set(PACKAGE_VERSION "1.3") + +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/Tests/RunCMake/find_package/MissingConfig-stderr.txt b/Tests/RunCMake/find_package/MissingConfig-stderr.txt index 1eae0bb..33ff545 100644 --- a/Tests/RunCMake/find_package/MissingConfig-stderr.txt +++ b/Tests/RunCMake/find_package/MissingConfig-stderr.txt @@ -1,18 +1,3 @@ -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\): diff --git a/Tests/RunCMake/find_package/MissingConfig-stdout.txt b/Tests/RunCMake/find_package/MissingConfig-stdout.txt new file mode 100644 index 0000000..7af632b --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfig-stdout.txt @@ -0,0 +1 @@ +-- Could NOT find NotHere \(missing: NotHere_DIR\) diff --git a/Tests/RunCMake/find_package/MissingConfigNormal-stdout.txt b/Tests/RunCMake/find_package/MissingConfigNormal-stdout.txt new file mode 100644 index 0000000..7af632b --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigNormal-stdout.txt @@ -0,0 +1 @@ +-- Could NOT find NotHere \(missing: NotHere_DIR\) diff --git a/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt b/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt deleted file mode 100644 index 10e71fa..0000000 --- a/Tests/RunCMake/find_package/MissingConfigOneName-stderr.txt +++ /dev/null @@ -1,10 +0,0 @@ -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-stdout.txt b/Tests/RunCMake/find_package/MissingConfigOneName-stdout.txt new file mode 100644 index 0000000..7af632b --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigOneName-stdout.txt @@ -0,0 +1 @@ +-- Could NOT find NotHere \(missing: NotHere_DIR\) diff --git a/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt b/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt deleted file mode 100644 index 2f5086e..0000000 --- a/Tests/RunCMake/find_package/MissingConfigVersion-stderr.txt +++ /dev/null @@ -1,13 +0,0 @@ -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-stdout.txt b/Tests/RunCMake/find_package/MissingConfigVersion-stdout.txt new file mode 100644 index 0000000..7af632b --- /dev/null +++ b/Tests/RunCMake/find_package/MissingConfigVersion-stdout.txt @@ -0,0 +1 @@ +-- Could NOT find NotHere \(missing: NotHere_DIR\) diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt deleted file mode 100644 index 695f645..0000000 --- a/Tests/RunCMake/find_package/SetFoundFALSE-stderr.txt +++ /dev/null @@ -1,9 +0,0 @@ -CMake Warning at SetFoundFALSE.cmake:2 \(find_package\): - Found package configuration file: - - .*/Tests/RunCMake/find_package/SetFoundFALSEConfig.cmake - - but it set SetFoundFALSE_FOUND to FALSE so package "SetFoundFALSE" is - considered to be NOT FOUND. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt b/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt new file mode 100644 index 0000000..37e6e7e --- /dev/null +++ b/Tests/RunCMake/find_package/SetFoundFALSE-stdout.txt @@ -0,0 +1 @@ +-- Could NOT find SetFoundFALSE \(missing: SetFoundFALSE_DIR\) diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index a732c9c..3604c0d 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -53,6 +53,19 @@ # This will still correctly require "cm_auto_ptr.hxx" for CM_AUTO_PTR. { symbol: [ "cm::auto_ptr", private, "\"cmConfigure.h\"", public ] }, + # __decay_and_strip is used internally in the C++11 standard library. + # IWYU does not classify it as internal and suggests to add <type_traits>. + # To ignore it, we simply map it to a file that is included anyway. + # TODO: Can this be simplified with an @-expression? + #{ symbol: [ "@std::__decay_and_strip<.*>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<cmCommand *&>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<cmGeneratorTarget *&>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<cmFindCommon::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<const std::basic_string<char> &>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<cmFindPackageCommand::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::__decay_and_strip<__gnu_cxx::__normal_iterator<const cmCTestTestHandler::cmCTestTestProperties *, std::vector<cmCTestTestHandler::cmCTestTestProperties, std::allocator<cmCTestTestHandler::cmCTestTestProperties> > > &>::__type", private, "\"cmConfigure.h\"", public ] }, + # Wrappers for headers added in TR1 / C++11 # { include: [ "<array>", public, "\"cm_array.hxx\"", public ] }, # { include: [ "<functional>", public, "\"cm_functional.hxx\"", public ] }, diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index 618f79d..3252e3d 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -164,7 +164,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-inotify.c src/unix/linux-syscalls.c src/unix/linux-syscalls.h + src/unix/procfs-exepath.c src/unix/proctitle.c + src/unix/sysinfo-loadavg.c + src/unix/sysinfo-memory.c ) endif() @@ -249,6 +252,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ) endif() list(APPEND uv_sources + src/unix/no-proctitle.c src/unix/sunos.c ) endif() diff --git a/Utilities/cmlibuv/include/uv-posix.h b/Utilities/cmlibuv/include/uv-posix.h new file mode 100644 index 0000000..9a96634 --- /dev/null +++ b/Utilities/cmlibuv/include/uv-posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/Utilities/cmlibuv/include/uv-unix.h b/Utilities/cmlibuv/include/uv-unix.h index 5440729..d775450 100644 --- a/Utilities/cmlibuv/include/uv-unix.h +++ b/Utilities/cmlibuv/include/uv-unix.h @@ -60,6 +60,8 @@ defined(__OpenBSD__) || \ defined(__NetBSD__) # include "uv-bsd.h" +#elif defined(__CYGWIN__) || defined(__MSYS__) +# include "uv-posix.h" #endif #ifndef PTHREAD_BARRIER_SERIAL_THREAD diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index ce04875..38f5676 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -1082,6 +1082,8 @@ UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); UV_EXTERN int uv_os_setenv(const char* name, const char* value); UV_EXTERN int uv_os_unsetenv(const char* name); +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + typedef enum { UV_FS_UNKNOWN = -1, diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c index 0b5653d..4147894 100644 --- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c +++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c @@ -27,7 +27,9 @@ #include <ifaddrs.h> #include <net/if.h> +#if !defined(__CYGWIN__) && !defined(__MSYS__) #include <net/if_dl.h> +#endif static int uv__ifaddr_exclude(struct ifaddrs *ent) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) @@ -107,9 +109,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { for (i = 0; i < *count; i++) { if (strcmp(address->name, ent->ifa_name) == 0) { +#if defined(__CYGWIN__) || defined(__MSYS__) + memset(address->phys_addr, 0, sizeof(address->phys_addr)); +#else struct sockaddr_dl* sa_addr; sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); +#endif } address++; } diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 96495b8..30cdaef 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -28,6 +28,7 @@ #include <errno.h> #include <assert.h> #include <unistd.h> +#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -42,6 +43,7 @@ #include <pwd.h> #ifdef __sun +# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */ # include <sys/filio.h> # include <sys/types.h> # include <sys/wait.h> @@ -80,6 +82,11 @@ #include <sys/ioctl.h> #endif +/* Fallback for the maximum hostname length */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ @@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) { } +#if !defined(__CYGWIN__) && !defined(__MSYS__) int uv__cloexec_ioctl(int fd, int set) { int r; @@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) { return 0; } +#endif int uv__nonblock_fcntl(int fd, int set) { @@ -1285,3 +1294,33 @@ int uv_os_unsetenv(const char* name) { return 0; } + + +int uv_os_gethostname(char* buffer, size_t* size) { + /* + On some platforms, if the input buffer is not large enough, gethostname() + succeeds, but truncates the result. libuv can detect this and return ENOBUFS + instead by creating a large enough buffer and comparing the hostname length + to the size input. + */ + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + if (gethostname(buf, sizeof(buf)) != 0) + return -errno; + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/cygwin.c b/Utilities/cmlibuv/src/unix/cygwin.c new file mode 100644 index 0000000..5a887dd --- /dev/null +++ b/Utilities/cmlibuv/src/unix/cygwin.c @@ -0,0 +1,54 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <sys/sysinfo.h> +#include <unistd.h> + +int uv_uptime(double* uptime) { + struct sysinfo info; + + if (sysinfo(&info) < 0) + return -errno; + + *uptime = info.uptime; + return 0; +} + +int uv_resident_set_memory(size_t* rss) { + /* FIXME: read /proc/meminfo? */ + *rss = 0; + return UV_ENOSYS; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + /* FIXME: read /proc/stat? */ + *cpu_infos = NULL; + *count = 0; + return UV_ENOSYS; +} + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + (void)cpu_infos; + (void)count; +} diff --git a/Utilities/cmlibuv/src/unix/fsevents.c b/Utilities/cmlibuv/src/unix/fsevents.c index d331a13..643e233 100644 --- a/Utilities/cmlibuv/src/unix/fsevents.c +++ b/Utilities/cmlibuv/src/unix/fsevents.c @@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) { if (state->fsevent_stream == NULL) return; - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - /* Stop emitting events */ pFSEventStreamStop(state->fsevent_stream); diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c index 646be4f..2866e93 100644 --- a/Utilities/cmlibuv/src/unix/linux-core.c +++ b/Utilities/cmlibuv/src/unix/linux-core.c @@ -472,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) { } -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - n = *size - 1; - if (n > 0) - n = readlink("/proc/self/exe", buffer, n); - - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.freeram * info.mem_unit; - return 0; -} - - -uint64_t uv_get_total_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.totalram * info.mem_unit; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { char buf[1024]; const char* s; diff --git a/Utilities/cmlibuv/src/unix/no-fsevents.c b/Utilities/cmlibuv/src/unix/no-fsevents.c new file mode 100644 index 0000000..38fb6ab --- /dev/null +++ b/Utilities/cmlibuv/src/unix/no-fsevents.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <errno.h> + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return -ENOSYS; +} + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + return -ENOSYS; +} + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return -ENOSYS; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} diff --git a/Utilities/cmlibuv/src/unix/no-proctitle.c b/Utilities/cmlibuv/src/unix/no-proctitle.c new file mode 100644 index 0000000..a5c19fb --- /dev/null +++ b/Utilities/cmlibuv/src/unix/no-proctitle.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <errno.h> +#include <stddef.h> + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return -EINVAL; + + buffer[0] = '\0'; + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c index 7e4b253..56f0af1 100644 --- a/Utilities/cmlibuv/src/unix/openbsd.c +++ b/Utilities/cmlibuv/src/unix/openbsd.c @@ -30,7 +30,6 @@ #include <errno.h> #include <fcntl.h> -#include <kvm.h> #include <paths.h> #include <stdlib.h> #include <string.h> diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c index e9ba90c..2ba5abf 100644 --- a/Utilities/cmlibuv/src/unix/os390.c +++ b/Utilities/cmlibuv/src/unix/os390.c @@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { return 0; } - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, - const char* filename, unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - void uv__io_poll(uv_loop_t* loop, int timeout) { static const int max_safe_timeout = 1789569; struct epoll_event events[1024]; diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c index 023e965..7ba1bf8 100644 --- a/Utilities/cmlibuv/src/unix/pipe.c +++ b/Utilities/cmlibuv/src/unix/pipe.c @@ -179,6 +179,14 @@ void uv_pipe_connect(uv_connect_t* req, if (r == -1 && errno != EINPROGRESS) { err = -errno; +#if defined(__CYGWIN__) || defined(__MSYS__) + /* EBADF is supposed to mean that the socket fd is bad, but + Cygwin reports EBADF instead of ENOTSOCK when the file is + not a socket. We do not expect to see a bad fd here + (e.g. due to new_sock), so translate the error. */ + if (err == -EBADF) + err = -ENOTSOCK; +#endif goto out; } diff --git a/Utilities/cmlibuv/src/unix/posix-poll.c b/Utilities/cmlibuv/src/unix/posix-poll.c new file mode 100644 index 0000000..3fba96e --- /dev/null +++ b/Utilities/cmlibuv/src/unix/posix-poll.c @@ -0,0 +1,324 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +/* POSIX defines poll() as a portable way to wait on file descriptors. + * Here we maintain a dynamically sized array of file descriptors and + * events to pass as the first argument to poll(). + */ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <errno.h> +#include <unistd.h> + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->poll_fds = NULL; + loop->poll_fds_used = 0; + loop->poll_fds_size = 0; + loop->poll_fds_iterating = 0; + return 0; +} + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__free(loop->poll_fds); + loop->poll_fds = NULL; +} + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + +/* Allocate or dynamically resize our poll fds array. */ +static void uv__pollfds_maybe_resize(uv_loop_t* loop) { + size_t i; + size_t n; + struct pollfd* p; + + if (loop->poll_fds_used < loop->poll_fds_size) + return; + + n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64; + p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds)); + if (p == NULL) + abort(); + + loop->poll_fds = p; + for (i = loop->poll_fds_size; i < n; i++) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + loop->poll_fds_size = n; +} + +/* Primitive swap operation on poll fds array elements. */ +static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) { + struct pollfd pfd; + pfd = loop->poll_fds[l]; + loop->poll_fds[l] = loop->poll_fds[r]; + loop->poll_fds[r] = pfd; +} + +/* Add a watcher's fd to our poll fds array with its pending events. */ +static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { + size_t i; + struct pollfd* pe; + + /* If the fd is already in the set just update its events. */ + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == w->fd) { + loop->poll_fds[i].events = w->pevents; + return; + } + } + + /* Otherwise, allocate a new slot in the set for the fd. */ + uv__pollfds_maybe_resize(loop); + pe = &loop->poll_fds[loop->poll_fds_used++]; + pe->fd = w->fd; + pe->events = w->pevents; +} + +/* Remove a watcher's fd from our poll fds array. */ +static void uv__pollfds_del(uv_loop_t* loop, int fd) { + size_t i; + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == fd) { + /* swap to last position and remove */ + --loop->poll_fds_used; + uv__pollfds_swap(loop, i, loop->poll_fds_used); + loop->poll_fds[loop->poll_fds_used].fd = -1; + loop->poll_fds[loop->poll_fds_used].events = 0; + loop->poll_fds[loop->poll_fds_used].revents = 0; + return; + } + } +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + sigset_t* pset; + sigset_t set; + uint64_t time_base; + uint64_t time_diff; + QUEUE* q; + uv__io_t* w; + size_t i; + unsigned int nevents; + int nfds; + int have_signals; + struct pollfd* pe; + int fd; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + /* Take queued watchers and add their fds to our poll fds array. */ + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + uv__pollfds_add(loop, w); + + w->events = w->pevents; + } + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + time_base = loop->time; + + /* Loop calls to poll() and processing of results. If we get some + * results from poll() but they turn out not to be interesting to + * our caller then we need to loop around and poll() again. + */ + for (;;) { + if (pset != NULL) + if (pthread_sigmask(SIG_BLOCK, pset, NULL)) + abort(); + nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout); + if (pset != NULL) + if (pthread_sigmask(SIG_UNBLOCK, pset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + /* Tell uv__platform_invalidate_fd not to manipulate our array + * while we are iterating over it. + */ + loop->poll_fds_iterating = 1; + + /* Initialize a count of events that we care about. */ + nevents = 0; + have_signals = 0; + + /* Loop over the entire poll fds array looking for returned events. */ + for (i = 0; i < loop->poll_fds_used; i++) { + pe = loop->poll_fds + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd. */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, ignore. */ + uv__platform_invalidate_fd(loop, fd); + continue; + } + + /* Filter out events that user has not requested us to watch + * (e.g. POLLNVAL). + */ + pe->revents &= w->pevents | POLLERR | POLLHUP; + + if (pe->revents != 0) { + /* Run signal watchers last. */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + w->cb(loop, w, pe->revents); + } + + nevents++; + } + } + + if (have_signals != 0) + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + + loop->poll_fds_iterating = 0; + + /* Purge invalidated fds from our poll fds array. */ + uv__pollfds_del(loop, -1); + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) + return; + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + time_diff = loop->time - time_base; + if (time_diff >= (uint64_t) timeout) + return; + + timeout -= time_diff; + } +} + +/* Remove the given fd from our poll fds array because no one + * is interested in its events anymore. + */ +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + size_t i; + + if (loop->poll_fds_iterating) { + /* uv__io_poll is currently iterating. Just invalidate fd. */ + for (i = 0; i < loop->poll_fds_used; i++) + if (loop->poll_fds[i].fd == fd) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + } else { + /* uv__io_poll is not iterating. Delete fd from the set. */ + uv__pollfds_del(loop, fd); + } +} + +/* Check whether the given fd is supported by poll(). */ +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rv == -1) + return -errno; + + if (p[0].revents & POLLNVAL) + return -EINVAL; + + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/procfs-exepath.c b/Utilities/cmlibuv/src/unix/procfs-exepath.c new file mode 100644 index 0000000..5fdb611 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/procfs-exepath.c @@ -0,0 +1,45 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stddef.h> +#include <unistd.h> + +int uv_exepath(char* buffer, size_t* size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return -errno; + + buffer[n] = '\0'; + *size = n; + + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c index dbd04f2..7b23d16 100644 --- a/Utilities/cmlibuv/src/unix/stream.c +++ b/Utilities/cmlibuv/src/unix/stream.c @@ -390,7 +390,7 @@ failed_malloc: int uv__stream_open(uv_stream_t* stream, int fd, int flags) { -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) int enable; #endif @@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { return -errno; } -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) enable = 1; if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && errno != ENOTSOCK && @@ -1173,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) { uv__stream_osx_interrupt_select(stream); } stream->read_cb(stream, 0, &buf); +#if defined(__CYGWIN__) || defined(__MSYS__) + } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { + uv__stream_eof(stream, &buf); + return; +#endif } else { /* Error. User should call uv_close(). */ stream->read_cb(stream, -errno, &buf); @@ -1405,6 +1410,12 @@ int uv_write2(uv_write_t* req, */ if (uv__handle_fd((uv_handle_t*) send_handle) < 0) return -EBADF; + +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it. + See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */ + return -ENOSYS; +#endif } /* It's legal for write_queue_size > 0 even when the write_queue is empty; diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c index d100263..041f3f3 100644 --- a/Utilities/cmlibuv/src/unix/sunos.c +++ b/Utilities/cmlibuv/src/unix/sunos.c @@ -549,25 +549,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) { #endif /* defined(PORT_SOURCE_FILE) */ -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (buffer == NULL || size == 0) - return -EINVAL; - - buffer[0] = '\0'; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { psinfo_t psinfo; int err; diff --git a/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c b/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c new file mode 100644 index 0000000..ebad0e8 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <sys/sysinfo.h> + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/Utilities/cmlibuv/src/unix/sysinfo-memory.c b/Utilities/cmlibuv/src/unix/sysinfo-memory.c new file mode 100644 index 0000000..23b4fc6 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/sysinfo-memory.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <sys/sysinfo.h> + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.freeram * info.mem_unit; + return 0; +} + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.totalram * info.mem_unit; + return 0; +} diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c index 1d64d4c..d2e7f77 100644 --- a/Utilities/cmlibuv/src/win/util.c +++ b/Utilities/cmlibuv/src/win/util.c @@ -59,6 +59,14 @@ # define UNLEN 256 #endif +/* + Max hostname length. The Windows gethostname() documentation states that 256 + bytes will always be large enough to hold the null-terminated hostname. +*/ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + /* Maximum environment variable size, including the terminating null */ #define MAX_ENV_VAR_LENGTH 32767 @@ -1540,3 +1548,29 @@ int uv_os_unsetenv(const char* name) { return 0; } + + +int uv_os_gethostname(char* buffer, size_t* size) { + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv__once_init(); /* Initialize winsock */ + + if (gethostname(buf, sizeof(buf)) != 0) + return uv_translate_sys_error(WSAGetLastError()); + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} @@ -860,7 +860,7 @@ cmake_toolchains='' case "${cmake_system}" in *AIX*) cmake_toolchains='XL GNU' ;; *CYGWIN*) cmake_toolchains='GNU' ;; - *Darwin*) cmake_toolchains='GNU Clang' ;; + *Darwin*) cmake_toolchains='Clang GNU' ;; *Linux*) cmake_toolchains='GNU Clang XL PGI PathScale' ;; *MINGW*) cmake_toolchains='GNU' ;; esac |