diff options
1040 files changed, 20429 insertions, 5530 deletions
diff --git a/Auxiliary/cmake-indent.vim b/Auxiliary/cmake-indent.vim index a26dd06..6cee9c8 100644 --- a/Auxiliary/cmake-indent.vim +++ b/Auxiliary/cmake-indent.vim @@ -16,7 +16,7 @@ " Version: $Revision$ " " Licence: The CMake license applies to this file. See -" http://www.cmake.org/HTML/Copyright.html +" http://www.cmake.org/licensing " This implies that distribution with Vim is allowed if exists("b:did_indent") diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el index c8b9f8b..7458a66 100644 --- a/Auxiliary/cmake-mode.el +++ b/Auxiliary/cmake-mode.el @@ -202,7 +202,7 @@ the indentation. Otherwise it retains the same position on the line" ;; Keyword highlighting regex-to-face map. ;; (defconst cmake-font-lock-keywords - (list '("^[ \t]*\\(\\w+\\)[ \t]*(" 1 font-lock-function-name-face)) + (list '("^[ \t]*\\([[:word:]_]+\\)[ \t]*(" 1 font-lock-function-name-face)) "Highlighting expressions for CMAKE mode." ) @@ -241,7 +241,6 @@ the indentation. Otherwise it retains the same position on the line" ; Create the syntax table (setq cmake-mode-syntax-table (make-syntax-table)) (set-syntax-table cmake-mode-syntax-table) - (modify-syntax-entry ?_ "w" cmake-mode-syntax-table) (modify-syntax-entry ?\( "()" cmake-mode-syntax-table) (modify-syntax-entry ?\) ")(" cmake-mode-syntax-table) (modify-syntax-entry ?# "<" cmake-mode-syntax-table) @@ -322,8 +321,13 @@ and store the result as a list in LISTVAR." ) (require 'thingatpt) +(defun cmake-symbol-at-point () + (let ((symbol (symbol-at-point))) + (and (not (null symbol)) + (symbol-name symbol)))) + (defun cmake-help-type (type) - (let* ((default-entry (word-at-point)) + (let* ((default-entry (cmake-symbol-at-point)) (history (car (cdr (cdr (assoc type cmake-string-to-list-symbol))))) (input (completing-read (format "CMake %s: " type) ; prompt @@ -366,7 +370,7 @@ and store the result as a list in LISTVAR." (defun cmake-help () "Queries for any of the four available help topics and prints out the approriate page." (interactive) - (let* ((default-entry (word-at-point)) + (let* ((default-entry (cmake-symbol-at-point)) (command-list (cmake-get-list "command")) (variable-list (cmake-get-list "variable")) (module-list (cmake-get-list "module")) diff --git a/Auxiliary/cmake-syntax.vim b/Auxiliary/cmake-syntax.vim index 782130d..3e4a122 100644 --- a/Auxiliary/cmake-syntax.vim +++ b/Auxiliary/cmake-syntax.vim @@ -16,7 +16,7 @@ " Version: $Revision$ " " Licence: The CMake license applies to this file. See -" http://www.cmake.org/HTML/Copyright.html +" http://www.cmake.org/licensing " This implies that distribution with Vim is allowed " For version 5.x: Clear all syntax items diff --git a/CMakeLists.txt b/CMakeLists.txt index 58e0a1f..bdc160d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,16 @@ if("${CMake_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") endmacro() endif() +# Use most-recent available language dialects with GNU and Clang +if(NOT DEFINED CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) +endif() +if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + # option to set the internal encoding of CMake to UTF-8 -option(CMAKE_ENCODING_UTF8 "Use UTF-8 encoding internally (experimental)." OFF) +option(CMAKE_ENCODING_UTF8 "Use UTF-8 encoding internally." ON) mark_as_advanced(CMAKE_ENCODING_UTF8) if(CMAKE_ENCODING_UTF8) set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_UTF8) @@ -57,7 +65,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES) # Allow the user to enable/disable all system utility library options by # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}. - set(UTILITIES BZIP2 CURL EXPAT LIBARCHIVE LIBLZMA ZLIB) + set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA ZLIB) foreach(util ${UTILITIES}) if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util} AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES) @@ -95,6 +103,8 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES) "${CMAKE_USE_SYSTEM_LIBRARY_BZIP2}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON) CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma" "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON) + option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}") + option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}") # Mention to the user what system libraries are being used. foreach(util ${UTILITIES}) @@ -363,6 +373,27 @@ macro (CMAKE_BUILD_UTILITIES) endif() #--------------------------------------------------------------------- + # Build jsoncpp library. + if(CMAKE_USE_SYSTEM_JSONCPP) + if(EXISTS ${CMAKE_ROOT}/Modules/FindJsonCpp.cmake) + find_package(JsonCpp) + elseif(NOT CMAKE_VERSION VERSION_LESS 3.0) + include(${CMake_SOURCE_DIR}/Modules/FindJsonCpp.cmake) + else() + message(FATAL_ERROR "CMAKE_USE_SYSTEM_JSONCPP requires CMake >= 3.0") + endif() + if(NOT JsonCpp_FOUND) + message(FATAL_ERROR + "CMAKE_USE_SYSTEM_JSONCPP is ON but a JsonCpp is not found!") + endif() + set(CMAKE_JSONCPP_LIBRARIES JsonCpp::JsonCpp) + else() + set(CMAKE_JSONCPP_LIBRARIES cmjsoncpp) + add_subdirectory(Utilities/cmjsoncpp) + CMAKE_SET_TARGET_FOLDER(cmjsoncpp "Utilities/3rdParty") + endif() + + #--------------------------------------------------------------------- # Build XMLRPC library for CMake and CTest. if(CTEST_USE_XMLRPC) find_package(XMLRPC QUIET REQUIRED libwww-client) @@ -394,7 +425,11 @@ macro (CMAKE_BUILD_UTILITIES) set(BUILD_CursesDialog 0) endif () if(BUILD_CursesDialog) - add_subdirectory(Source/CursesDialog/form) + if(NOT CMAKE_USE_SYSTEM_FORM) + add_subdirectory(Source/CursesDialog/form) + elseif(NOT CURSES_FORM_LIBRARY) + message( FATAL_ERROR "CMAKE_USE_SYSTEM_FORM in ON but CURSES_FORM_LIBRARY is not set!" ) + endif() endif() endmacro () diff --git a/CompileFlags.cmake b/CompileFlags.cmake index 5d86876..3c053fa 100644 --- a/CompileFlags.cmake +++ b/CompileFlags.cmake @@ -16,9 +16,6 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio 7") set(CMAKE_SKIP_COMPATIBILITY_TESTS 1) endif() -if(CMAKE_GENERATOR MATCHES "Visual Studio 6") - set(CMAKE_SKIP_COMPATIBILITY_TESTS 1) -endif() if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel") set(_INTEL_WINDOWS 1) @@ -65,6 +62,24 @@ if(CMAKE_SYSTEM_NAME MATCHES "HP-UX" AND CMAKE_CXX_COMPILER_ID MATCHES "HP") endif() endif() +# Workaround for short jump tables on PA-RISC +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^parisc") + if(CMAKE_COMPILER_IS_GNUC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-calls") + endif() + if(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-calls") + endif() +endif() + +if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4") + endif() +endif() + # use the ansi CXX compile flag for building cmake if (CMAKE_ANSI_CXXFLAGS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_ANSI_CXXFLAGS}") @@ -73,11 +88,3 @@ endif () if (CMAKE_ANSI_CFLAGS) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}") endif () - -# avoid binutils problem with large binaries, e.g. when building CMake in debug mode -# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230 -if (CMAKE_SYSTEM_NAME STREQUAL Linux AND CMAKE_SYSTEM_PROCESSOR STREQUAL parisc) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--unique=.text._*") -endif () - -include (${CMAKE_ROOT}/Modules/CMakeBackwardCompatibilityCXX.cmake) diff --git a/Copyright.txt b/Copyright.txt index 214d7de..6c9fb09 100644 --- a/Copyright.txt +++ b/Copyright.txt @@ -1,5 +1,5 @@ CMake - Cross Platform Makefile Generator -Copyright 2000-2014 Kitware, Inc. +Copyright 2000-2015 Kitware, Inc. Copyright 2000-2011 Insight Software Consortium All rights reserved. diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst index 214f4be..3fe2a33 100644 --- a/Help/command/add_compile_options.rst +++ b/Help/command/add_compile_options.rst @@ -7,15 +7,16 @@ Adds options to the compilation of source files. add_compile_options(<option> ...) -Adds options to the compiler command line for sources in the current -directory and below. This command can be used to add any options, but -alternative commands exist to add preprocessor definitions -(:command:`target_compile_definitions` and :command:`add_definitions`) or -include directories (:command:`target_include_directories` and -:command:`include_directories`). See documentation of the -:prop_tgt:`directory <COMPILE_OPTIONS>` and +Adds options to the compiler command line for targets in the current +directory and below that are added after this command is invoked. +See documentation of the :prop_dir:`directory <COMPILE_OPTIONS>` and :prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties. +This command can be used to add any options, but alternative commands +exist to add preprocessor definitions (:command:`target_compile_definitions` +and :command:`add_definitions`) or include directories +(:command:`target_include_directories` and :command:`include_directories`). + Arguments to ``add_compile_options`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index e8b7cc8..1307a58 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -15,10 +15,12 @@ The first signature is for adding a custom command to produce an output:: [COMMAND command2 [ARGS] [args2...] ...] [MAIN_DEPENDENCY depend] [DEPENDS [depends...]] + [BYPRODUCTS [files...]] [IMPLICIT_DEPENDS <lang1> depend1 [<lang2> depend2] ...] [WORKING_DIRECTORY dir] - [COMMENT comment] [VERBATIM] [APPEND]) + [COMMENT comment] + [VERBATIM] [APPEND] [USES_TERMINAL]) This defines a command to generate specified ``OUTPUT`` file(s). A target created in the same directory (``CMakeLists.txt`` file) @@ -43,6 +45,27 @@ The options are: options are currently ignored when APPEND is given, but may be used in the future. +``BYPRODUCTS`` + Specify the files the command is expected to produce but whose + modification time may or may not be newer than the dependencies. + If a byproduct name is a relative path it will be interpreted + relative to the build tree directory corresponding to the + current source directory. + Each byproduct file will be marked with the :prop_sf:`GENERATED` + source file property automatically. + + Explicit specification of byproducts is supported by the + :generator:`Ninja` generator to tell the ``ninja`` build tool + how to regenerate byproducts when they are missing. It is + also useful when other build rules (e.g. custom commands) + depend on the byproducts. Ninja requires a build rule for any + generated file on which another rule depends even if there are + order-only dependencies to ensure the byproducts will be + available before their dependents build. + + The ``BYPRODUCTS`` option is ignored on non-Ninja generators + except to mark byproducts ``GENERATED``. + ``COMMAND`` Specify the command-line(s) to execute at build time. If more than one ``COMMAND`` is specified they will be executed in order, @@ -107,17 +130,25 @@ The options are: Specify the primary input source file to the command. This is treated just like any value given to the ``DEPENDS`` option but also suggests to Visual Studio generators where to hang - the custom command. + the custom command. At most one custom command may specify a + given source file as its main dependency. ``OUTPUT`` Specify the output files the command is expected to produce. If an output name is a relative path it will be interpreted relative to the build tree directory corresponding to the current source directory. + Each output file will be marked with the :prop_sf:`GENERATED` + source file property automatically. If the output of the custom command is not actually created as a file on disk it should be marked with the :prop_sf:`SYMBOLIC` source file property. +``USES_TERMINAL`` + The command will be given direct access to the terminal if possible. + With the :generator:`Ninja` generator, this places the command in + the ``console`` pool. + ``VERBATIM`` All arguments to the commands will be escaped properly for the build tool so that the invoked command receives each argument @@ -148,8 +179,10 @@ target is already built, the command will not execute. PRE_BUILD | PRE_LINK | POST_BUILD COMMAND command1 [ARGS] [args1...] [COMMAND command2 [ARGS] [args2...] ...] + [BYPRODUCTS [files...]] [WORKING_DIRECTORY dir] - [COMMENT comment] [VERBATIM]) + [COMMENT comment] + [VERBATIM] [USES_TERMINAL]) This defines a new command that will be associated with building the specified target. When the command will happen is determined by which diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst index 1bf70bf..5134a70 100644 --- a/Help/command/add_custom_target.rst +++ b/Help/command/add_custom_target.rst @@ -8,38 +8,104 @@ Add a target with no output so it will always be built. add_custom_target(Name [ALL] [command1 [args1...]] [COMMAND command2 [args2...] ...] [DEPENDS depend depend depend ... ] + [BYPRODUCTS [files...]] [WORKING_DIRECTORY dir] - [COMMENT comment] [VERBATIM] + [COMMENT comment] + [VERBATIM] [USES_TERMINAL] [SOURCES src1 [src2...]]) Adds a target with the given name that executes the given commands. -The target has no output file and is ALWAYS CONSIDERED OUT OF DATE +The target has no output file and is *always considered out of date* even if the commands try to create a file with the name of the target. -Use ADD_CUSTOM_COMMAND to generate a file with dependencies. By -default nothing depends on the custom target. Use ADD_DEPENDENCIES to -add dependencies to or from other targets. If the ALL option is -specified it indicates that this target should be added to the default -build target so that it will be run every time (the command cannot be -called ALL). The command and arguments are optional and if not -specified an empty target will be created. If WORKING_DIRECTORY is -set, then the command will be run in that directory. If it is a -relative path it will be interpreted relative to the build tree -directory corresponding to the current source directory. If COMMENT -is set, the value will be displayed as a message before the commands -are executed at build time. Dependencies listed with the DEPENDS -argument may reference files and outputs of custom commands created -with add_custom_command() in the same directory (CMakeLists.txt file). - -If VERBATIM is given then all arguments to the commands will be -escaped properly for the build tool so that the invoked command -receives each argument unchanged. Note that one level of escapes is -still used by the CMake language processor before add_custom_target -even sees the arguments. Use of VERBATIM is recommended as it enables -correct behavior. When VERBATIM is not given the behavior is platform -specific because there is no protection of tool-specific special -characters. - -The SOURCES option specifies additional source files to be included in -the custom target. Specified source files will be added to IDE -project files for convenience in editing even if they have not build -rules. +Use the :command:`add_custom_command` command to generate a file with +dependencies. By default nothing depends on the custom target. Use +the :command:`add_dependencies` command to add dependencies to or +from other targets. + +The options are: + +``ALL`` + Indicate that this target should be added to the default build + target so that it will be run every time (the command cannot be + called ``ALL``). + +``BYPRODUCTS`` + Specify the files the command is expected to produce but whose + modification time may or may not be updated on subsequent builds. + If a byproduct name is a relative path it will be interpreted + relative to the build tree directory corresponding to the + current source directory. + Each byproduct file will be marked with the :prop_sf:`GENERATED` + source file property automatically. + + Explicit specification of byproducts is supported by the + :generator:`Ninja` generator to tell the ``ninja`` build tool + how to regenerate byproducts when they are missing. It is + also useful when other build rules (e.g. custom commands) + depend on the byproducts. Ninja requires a build rule for any + generated file on which another rule depends even if there are + order-only dependencies to ensure the byproducts will be + available before their dependents build. + + The ``BYPRODUCTS`` option is ignored on non-Ninja generators + except to mark byproducts ``GENERATED``. + +``COMMAND`` + Specify the command-line(s) to execute at build time. + If more than one ``COMMAND`` is specified they will be executed in order, + but *not* necessarily composed into a stateful shell or batch script. + (To run a full script, use the :command:`configure_file` command or the + :command:`file(GENERATE)` command to create it, and then specify + a ``COMMAND`` to launch it.) + + If ``COMMAND`` specifies an executable target (created by the + :command:`add_executable` command) it will automatically be replaced + by the location of the executable created at build time. + Additionally a target-level dependency will be added so that the + executable target will be built before this custom target. + + Arguments to ``COMMAND`` may use + :manual:`generator expressions <cmake-generator-expressions(7)>`. + References to target names in generator expressions imply target-level + dependencies. + + The command and arguments are optional and if not specified an empty + target will be created. + +``COMMENT`` + Display the given message before the commands are executed at + build time. + +``DEPENDS`` + Reference files and outputs of custom commands created with + :command:`add_custom_command` command calls in the same directory + (``CMakeLists.txt`` file). They will be brought up to date when + the target is built. + + Use the :command:`add_dependencies` command to add dependencies + on other targets. + +``SOURCES`` + Specify additional source files to be included in the custom target. + Specified source files will be added to IDE project files for + convenience in editing even if they have no build rules. + +``VERBATIM`` + All arguments to the commands will be escaped properly for the + build tool so that the invoked command receives each argument + unchanged. Note that one level of escapes is still used by the + CMake language processor before ``add_custom_target`` even sees + the arguments. Use of ``VERBATIM`` is recommended as it enables + correct behavior. When ``VERBATIM`` is not given the behavior + is platform specific because there is no protection of + tool-specific special characters. + +``USES_TERMINAL`` + The command will be given direct access to the terminal if possible. + With the :generator:`Ninja` generator, this places the command in + the ``console`` pool. + +``WORKING_DIRECTORY`` + Execute the command with the given current working directory. + If it is a relative path it will be interpreted relative to the + build tree directory corresponding to the current source directory. diff --git a/Help/command/add_definitions.rst b/Help/command/add_definitions.rst index 2965c37..a04faf5 100644 --- a/Help/command/add_definitions.rst +++ b/Help/command/add_definitions.rst @@ -7,10 +7,12 @@ Adds -D define flags to the compilation of source files. add_definitions(-DFOO -DBAR ...) -Adds definitions to the compiler command line for sources in the current -directory and below. This command can be used to add any flags, but -it is intended to add preprocessor definitions. Flags -beginning in -D or /D that look like preprocessor definitions are +Adds definitions to the compiler command line for targets in the current +directory and below (whether added before or after this command is invoked). +This command can be used to add any flags, but it is intended to add +preprocessor definitions (see the :command:`add_compile_options` command +to add other flags). +Flags beginning in -D or /D that look like preprocessor definitions are automatically added to the :prop_dir:`COMPILE_DEFINITIONS` directory property for the current directory. Definitions with non-trivial values may be left in the set of flags instead of being converted for reasons of diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index f86f3c5..7c06203 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -35,7 +35,7 @@ variable :variable:`BUILD_SHARED_LIBS` is ``ON``. For ``SHARED`` and property is set to ``ON`` automatically. By default the library file will be created in the build tree directory -corresponding to the source tree directory in which thecommand was +corresponding to the source tree directory in which the command was invoked. See documentation of the :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`, :prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` target properties to change this @@ -133,14 +133,17 @@ Creates an :ref:`Interface Library <Interface Libraries>`. An ``INTERFACE`` library target does not directly create build output, though it may have properties set on it and it may be installed, exported and imported. Typically the ``INTERFACE_*`` properties are populated on -the interface target using the :command:`set_property`, -:command:`target_link_libraries(INTERFACE)`, -:command:`target_include_directories(INTERFACE)`, -:command:`target_compile_options(INTERFACE)`, -:command:`target_compile_definitions(INTERFACE)`, -and :command:`target_sources(INTERFACE)` commands, and then it -is used as an argument to :command:`target_link_libraries` like any other -target. +the interface target using the commands: + +* :command:`set_property`, +* :command:`target_link_libraries(INTERFACE)`, +* :command:`target_include_directories(INTERFACE)`, +* :command:`target_compile_options(INTERFACE)`, +* :command:`target_compile_definitions(INTERFACE)`, and +* :command:`target_sources(INTERFACE)`, + +and then it is used as an argument to :command:`target_link_libraries` +like any other target. An ``INTERFACE`` :ref:`Imported Target <Imported Targets>` may also be created with this signature. An ``IMPORTED`` library target references a diff --git a/Help/command/break.rst b/Help/command/break.rst index 8f1067b..fc2cd3c 100644 --- a/Help/command/break.rst +++ b/Help/command/break.rst @@ -8,3 +8,5 @@ Break from an enclosing foreach or while loop. break() Breaks from an enclosing foreach loop or while loop + +See also the :command:`continue` command. diff --git a/Help/command/continue.rst b/Help/command/continue.rst new file mode 100644 index 0000000..1c7d673 --- /dev/null +++ b/Help/command/continue.rst @@ -0,0 +1,12 @@ +continue +-------- + +Continue to the top of enclosing foreach or while loop. + +:: + + continue() + +The ``continue`` command allows a cmake script to abort the rest of a block +in a :command:`foreach` or :command:`while` loop, and start at the top of +the next iteration. See also the :command:`break` command. diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index d9b0b78..2b83ed9 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -37,3 +37,16 @@ timed-out submission before attempting to re-submit. The RETRY_COUNT option specifies how many times to retry a timed-out submission. + +Submit to CDash Upload API +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + ctest_submit(CDASH_UPLOAD <file> [CDASH_UPLOAD_TYPE <type>]) + +This second signature is used to upload files to CDash via the CDash +file upload API. The api first sends a request to upload to CDash along +with a content hash of the file. If CDash does not already have the file, +then it is uploaded. Along with the file, a CDash type string is specified +to tell CDash which handler to use to process the data. diff --git a/Help/command/file.rst b/Help/command/file.rst index dbc4149..b0d4792 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -247,7 +247,9 @@ the ``<format>`` and ``UTC`` options. :: - file(GENERATE <options>...) + file(GENERATE OUTPUT output-file + <INPUT input-file|CONTENT content> + [CONDITION expression]) Generate an output file for each build configuration supported by the current :manual:`CMake Generator <cmake-generators(7)>`. Evaluate @@ -305,3 +307,33 @@ status messages (subject to the :variable:`CMAKE_INSTALL_MESSAGE` variable), and ``NO_SOURCE_PERMISSIONS`` is default. Installation scripts generated by the :command:`install` command use this signature (with some undocumented options for internal use). + +------------------------------------------------------------------------------ + +:: + + file(LOCK <path> [DIRECTORY] [RELEASE] + [GUARD <FUNCTION|FILE|PROCESS>] + [RESULT_VARIABLE <variable>] + [TIMEOUT <seconds>]) + +Lock a file specified by ``<path>`` if no ``DIRECTORY`` option present and file +``<path>/cmake.lock`` otherwise. File will be locked for scope defined by +``GUARD`` option (default value is ``PROCESS``). ``RELEASE`` option can be used +to unlock file explicitly. If option ``TIMEOUT`` is not specified CMake will +wait until lock succeed or until fatal error occurs. If ``TIMEOUT`` is set to +``0`` lock will be tried once and result will be reported immediately. If +``TIMEOUT`` is not ``0`` CMake will try to lock file for the period specified +by ``<seconds>`` value. Any errors will be interpreted as fatal if there is no +``RESULT_VARIABLE`` option. Otherwise result will be stored in ``<variable>`` +and will be ``0`` on success or error message on failure. + +Note that lock is advisory - there is no guarantee that other processes will +respect this lock, i.e. lock synchronize two or more CMake instances sharing +some modifiable resources. Similar logic applied to ``DIRECTORY`` option - +locking parent directory doesn't prevent other ``LOCK`` commands to lock any +child directory or file. + +Trying to lock file twice is not allowed. Any intermediate directories and +file itself will be created if they not exist. ``GUARD`` and ``TIMEOUT`` +options ignored on ``RELEASE`` operation. diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst index 190d05c..7f518a6 100644 --- a/Help/command/find_package.rst +++ b/Help/command/find_package.rst @@ -312,6 +312,8 @@ When loading a find module or package configuration file ``find_package`` defines variables to provide information about the call arguments (and restores their original state before returning): +``CMAKE_FIND_PACKAGE_NAME`` + the ``<package>`` name which is searched for ``<package>_FIND_REQUIRED`` true if ``REQUIRED`` option was given ``<package>_FIND_QUIETLY`` diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst index c2937be..632ece6 100644 --- a/Help/command/get_property.rst +++ b/Help/command/get_property.rst @@ -10,6 +10,7 @@ Get a property. DIRECTORY [dir] | TARGET <target> | SOURCE <source> | + INSTALL <file> | TEST <test> | CACHE <entry> | VARIABLE> @@ -21,29 +22,40 @@ specifies the variable in which to store the result. The second argument determines the scope from which to get the property. It must be one of the following: -GLOBAL scope is unique and does not accept a name. +``GLOBAL`` + Scope is unique and does not accept a name. -DIRECTORY scope defaults to the current directory but another -directory (already processed by CMake) may be named by full or -relative path. +``DIRECTORY`` + Scope defaults to the current directory but another + directory (already processed by CMake) may be named by full or + relative path. -TARGET scope must name one existing target. +``TARGET`` + Scope must name one existing target. -SOURCE scope must name one source file. +``SOURCE`` + Scope must name one source file. -TEST scope must name one existing test. +``INSTALL`` + Scope must name one installed file path. -CACHE scope must name one cache entry. +``TEST`` + Scope must name one existing test. -VARIABLE scope is unique and does not accept a name. +``CACHE`` + Scope must name one cache entry. -The required PROPERTY option is immediately followed by the name of +``VARIABLE`` + Scope is unique and does not accept a name. + +The required ``PROPERTY`` option is immediately followed by the name of the property to get. If the property is not set an empty value is -returned. If the SET option is given the variable is set to a boolean -value indicating whether the property has been set. If the DEFINED +returned. If the ``SET`` option is given the variable is set to a boolean +value indicating whether the property has been set. If the ``DEFINED`` option is given the variable is set to a boolean value indicating -whether the property has been defined such as with define_property. -If BRIEF_DOCS or FULL_DOCS is given then the variable is set to a +whether the property has been defined such as with the +:command:`define_property` command. +If ``BRIEF_DOCS`` or ``FULL_DOCS`` is given then the variable is set to a string containing documentation for the requested property. If documentation is requested for a property that has not been defined -NOTFOUND is returned. +``NOTFOUND`` is returned. diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst index 2623755..391a32e 100644 --- a/Help/command/get_test_property.rst +++ b/Help/command/get_test_property.rst @@ -7,9 +7,9 @@ Get a property of the test. get_test_property(test property VAR) -Get a property from the Test. The value of the property is stored in -the variable VAR. If the property is not found, VAR will be set to -"NOTFOUND". For a list of standard properties you can type cmake ---help-property-list +Get a property from the test. The value of the property is stored in +the variable VAR. If the test or property is not found, VAR will be +set to "NOTFOUND". For a list of standard properties you can type cmake +--help-property-list. See also the more general get_property() command. diff --git a/Help/command/if.rst b/Help/command/if.rst index 79e5d21..d50b14c 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -42,11 +42,12 @@ Possible expressions are: or a non-zero number. False if the constant is ``0``, ``OFF``, ``NO``, ``FALSE``, ``N``, ``IGNORE``, ``NOTFOUND``, the empty string, or ends in the suffix ``-NOTFOUND``. Named boolean constants are - case-insensitive. If the argument is not one of these constants, it - is treated as a variable. + case-insensitive. If the argument is not one of these specific + constants, it is treated as a variable or string and the following + signature is used. -``if(<variable>)`` - True if the variable is defined to a value that is not a false +``if(<variable|string>)`` + True if given a variable that is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.) ``if(NOT <expression>)`` diff --git a/Help/command/install.rst b/Help/command/install.rst index 4c52abf..5dd5aaa 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -268,7 +268,8 @@ Custom Installation Logic :: - install([[SCRIPT <file>] [CODE <code>]] [...]) + install([[SCRIPT <file>] [CODE <code>]] + [COMPONENT <component>] [...]) The ``SCRIPT`` form will invoke the given CMake script files during installation. If the script file name is a relative path it will be diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst index 8cb963e..6200230 100644 --- a/Help/command/set_property.rst +++ b/Help/command/set_property.rst @@ -9,6 +9,7 @@ Set a named property in a given scope. DIRECTORY [dir] | TARGET [target1 [target2 ...]] | SOURCE [src1 [src2 ...]] | + INSTALL [file1 [file2 ...]] | TEST [test1 [test2 ...]] | CACHE [entry1 [entry2 ...]]> [APPEND] [APPEND_STRING] @@ -18,26 +19,48 @@ Set one property on zero or more objects of a scope. The first argument determines the scope in which the property is set. It must be one of the following: -GLOBAL scope is unique and does not accept a name. +``GLOBAL`` + Scope is unique and does not accept a name. -DIRECTORY scope defaults to the current directory but another -directory (already processed by CMake) may be named by full or -relative path. +``DIRECTORY`` + Scope defaults to the current directory but another + directory (already processed by CMake) may be named by full or + relative path. -TARGET scope may name zero or more existing targets. +``TARGET`` + Scope may name zero or more existing targets. -SOURCE scope may name zero or more source files. Note that source -file properties are visible only to targets added in the same -directory (CMakeLists.txt). +``SOURCE`` + Scope may name zero or more source files. Note that source + file properties are visible only to targets added in the same + directory (CMakeLists.txt). -TEST scope may name zero or more existing tests. +``INSTALL`` + Scope may name zero or more installed file paths. + These are made available to CPack to influence deployment. -CACHE scope must name zero or more cache existing entries. + Both the property key and value may use generator expressions. + Specific properties may apply to installed files and/or directories. -The required PROPERTY option is immediately followed by the name of + Path components have to be separated by forward slashes, + must be normalized and are case sensitive. + + To reference the installation prefix itself with a relative path use ".". + + Currently installed file properties are only defined for + the WIX generator where the given paths are relative + to the installation prefix. + +``TEST`` + Scope may name zero or more existing tests. + +``CACHE`` + Scope must name zero or more cache existing entries. + +The required ``PROPERTY`` option is immediately followed by the name of the property to set. Remaining arguments are used to compose the property value in the form of a semicolon-separated list. If the -APPEND option is given the list is appended to any existing property -value.If the APPEND_STRING option is given the string is append to any +``APPEND`` option is given the list is appended to any existing property +value. If the ``APPEND_STRING`` option is given the string is append to any existing property value as string, i.e. it results in a longer string and not a list of strings. diff --git a/Help/command/set_tests_properties.rst b/Help/command/set_tests_properties.rst index e29d690..afac847 100644 --- a/Help/command/set_tests_properties.rst +++ b/Help/command/set_tests_properties.rst @@ -7,7 +7,7 @@ Set a property of the tests. set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2 value2) -Set a property for the tests. If the property is not found, CMake +Set a property for the tests. If the test is not found, CMake will report an error. Generator expressions will be expanded the same as supported by the test's add_test call. The properties include: diff --git a/Help/command/string.rst b/Help/command/string.rst index 07d0ff3..351385b 100644 --- a/Help/command/string.rst +++ b/Help/command/string.rst @@ -73,8 +73,13 @@ TOUPPER/TOLOWER will convert string to upper/lower characters. LENGTH will return a given string's length. -SUBSTRING will return a substring of a given string. If length is -1 +SUBSTRING will return a substring of a given string. If length is -1 the remainder of the string starting at begin will be returned. +If string is shorter than length then end of string is used instead. + +.. note:: + CMake 3.1 and below reported an error if length pointed past + the end of string. STRIP will return a substring of a given string with leading and trailing spaces removed. diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst index 0fdeba6..3362c5d 100644 --- a/Help/command/target_compile_options.rst +++ b/Help/command/target_compile_options.rst @@ -12,8 +12,8 @@ Add compile options to a target. Specify compile options to use when compiling a given target. The named ``<target>`` must have been created by a command such as :command:`add_executable` or :command:`add_library` and must not be an -:prop_tgt:`IMPORTED Target`. If ``BEFORE`` is specified, the content will -be prepended to the property instead of being appended. +:ref:`IMPORTED Target <Imported Targets>`. If ``BEFORE`` is specified, +the content will be prepended to the property instead of being appended. This command can be used to add any options, but alternative commands exist to add preprocessor definitions diff --git a/Help/command/target_include_directories.rst b/Help/command/target_include_directories.rst index 581bace..1d236ce 100644 --- a/Help/command/target_include_directories.rst +++ b/Help/command/target_include_directories.rst @@ -9,8 +9,8 @@ Add include directories to a target. <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) -Specify include directories or targets to use when compiling a given -target. The named ``<target>`` must have been created by a command such +Specify include directories to use when compiling a given target. +The named ``<target>`` must have been created by a command such as :command:`add_executable` or :command:`add_library` and must not be an :prop_tgt:`IMPORTED` target. @@ -54,3 +54,6 @@ installation prefix. For example: $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib> $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib ) + +.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` +.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index 39537a7..e6a82b6 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -49,6 +49,9 @@ CMake will also propagate :ref:`usage requirements <Target Usage Requirements>` from linked library targets. Usage requirements of dependencies affect compilation of sources in the ``<target>``. +.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES` +.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt + If an ``<item>`` is a library in a Mac OX framework, the ``Headers`` directory of the framework will also be processed as a :ref:`usage requirement <Target Usage Requirements>`. This has the same diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst index ff756b4..832240a 100644 --- a/Help/command/target_sources.rst +++ b/Help/command/target_sources.rst @@ -12,7 +12,7 @@ Add sources to a target. Specify sources to use when compiling a given target. The named ``<target>`` must have been created by a command such as :command:`add_executable` or :command:`add_library` and must not be an -:prop_tgt:`IMPORTED Target`. +:ref:`IMPORTED Target <Imported Targets>`. The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC`` @@ -22,6 +22,10 @@ items will populate the :prop_tgt:`SOURCES` property of following arguments specify sources. Repeated calls for the same ``<target>`` append items in the order called. +Targets with :prop_tgt:`INTERFACE_SOURCES` may not be exported with the +:command:`export` or :command:`install(EXPORT)` commands. This limitation may be +lifted in a future version of CMake. + Arguments to ``target_sources`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` diff --git a/Help/generator/MSYS Makefiles.rst b/Help/generator/MSYS Makefiles.rst index 0b89126..f7cfa44 100644 --- a/Help/generator/MSYS Makefiles.rst +++ b/Help/generator/MSYS Makefiles.rst @@ -1,7 +1,11 @@ MSYS Makefiles -------------- -Generates MSYS makefiles. +Generates makefiles for use with MSYS ``make`` under the MSYS shell. -The makefiles use /bin/sh as the shell. They require msys to be -installed on the machine. +Use this generator in a MSYS shell prompt and using ``make`` as the build +tool. The generated makefiles use ``/bin/sh`` as the shell to launch build +rules. They are not compatible with a Windows command prompt. + +To build under a Windows command prompt, use the +:generator:`MinGW Makefiles` generator. diff --git a/Help/generator/MinGW Makefiles.rst b/Help/generator/MinGW Makefiles.rst index ed4ccdd..9fe5fe3 100644 --- a/Help/generator/MinGW Makefiles.rst +++ b/Help/generator/MinGW Makefiles.rst @@ -1,7 +1,12 @@ MinGW Makefiles --------------- -Generates a make file for use with mingw32-make. +Generates makefiles for use with ``mingw32-make`` under a Windows command +prompt. -The makefiles generated use cmd.exe as the shell. They do not require -msys or a unix shell. +Use this generator under a Windows command prompt with MinGW in the ``PATH`` +and using ``mingw32-make`` as the build tool. The generated makefiles use +``cmd.exe`` as the shell to launch build rules. They are not compatible with +MSYS or a unix shell. + +To build under the MSYS shell, use the :generator:`MSYS Makefiles` generator. diff --git a/Help/generator/Visual Studio 14.rst b/Help/generator/Visual Studio 14 2015.rst index d621b7e..b35997a 100644 --- a/Help/generator/Visual Studio 14.rst +++ b/Help/generator/Visual Studio 14 2015.rst @@ -1,7 +1,7 @@ -Visual Studio 14 ----------------- +Visual Studio 14 2015 +--------------------- -Generates Visual Studio 14 project files. +Generates Visual Studio 14 (VS 2015) project files. The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set to specify a target platform name. @@ -9,8 +9,8 @@ to specify a target platform name. For compatibility with CMake versions prior to 3.1, one may specify a target platform name optionally at the end of this generator name: -``Visual Studio 14 Win64`` +``Visual Studio 14 2015 Win64`` Specify target platform ``x64``. -``Visual Studio 14 ARM`` +``Visual Studio 14 2015 ARM`` Specify target platform ``ARM``. diff --git a/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt new file mode 100644 index 0000000..33f7183 --- /dev/null +++ b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt @@ -0,0 +1,30 @@ + +Note that it is not advisable to populate the ``INSTALL_INTERFACE`` of the +|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies. +That would hard-code into installed packages the include directory paths +for dependencies **as found on the machine the package was made on**. + +The ``INSTALL_INTERFACE`` of the |INTERFACE_PROPERTY_LINK| is only +suitable for specifying the required include directories of the target itself, +not its dependencies. + +That is, code like this is incorrect for targets which will be used to +generate :manual:`cmake-packages(7)`: + +.. code-block:: cmake + + target_include_directories(mylib INTERFACE + $<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}> + ) + +Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` +which have their own |INTERFACE_PROPERTY_LINK| populated +appropriately. Those :ref:`IMPORTED targets <Imported Targets>` may then be +used with the :command:`target_link_libraries` command for ``mylib``. + +That way, when a consumer uses the installed package, the +consumer will run the appropriate :command:`find_package` command to find +the dependencies on their own machine and populate the +:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See +:ref:`Creating Packages` for more. Note that many modules currently shipped +with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`. diff --git a/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt new file mode 100644 index 0000000..ceefa4d --- /dev/null +++ b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt @@ -0,0 +1,23 @@ + +Note that it is not advisable to populate the +|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies. +That would hard-code into installed packages the include directory paths +for dependencies **as found on the machine the package was made on**. + +That is, code like this is incorrect for targets which will be used to +generate :manual:`cmake-packages(7)`: + +.. code-block:: cmake + + target_link_libraries(mylib INTERFACE + ${Boost_LIBRARIES};${OtherDep_LIBRARIES} + ) + +Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` +which have their own :prop_tgt:`IMPORTED_LOCATION` populated +appropriately. That way, when a consumer uses the installed package, the +consumer will run the appropriate :command:`find_package` command to find +the dependencies on their own machine and populate the +:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See +:ref:`Creating Packages` for more. Note that many modules currently shipped +with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`. diff --git a/Help/manual/LINKS.txt b/Help/manual/LINKS.txt index f6f707d..38fd151 100644 --- a/Help/manual/LINKS.txt +++ b/Help/manual/LINKS.txt @@ -11,12 +11,12 @@ Frequently Asked Questions A Wiki is provided containing answers to frequently asked questions. Online Documentation - http://www.cmake.org/HTML/Documentation.html + http://www.cmake.org/documentation Links to available documentation may be found on this web page. Mailing List - http://www.cmake.org/HTML/MailingLists.html + http://www.cmake.org/mailing-lists For help and discussion about using cmake, a mailing list is provided at cmake@cmake.org. The list is member-post-only but one diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index 1ce9a7e..002f2c2 100644 --- a/Help/manual/cmake-buildsystem.7.rst +++ b/Help/manual/cmake-buildsystem.7.rst @@ -3,7 +3,7 @@ cmake-buildsystem(7) ******************** -.. only:: html or latex +.. only:: html .. contents:: @@ -270,7 +270,11 @@ be specified in the order ``lib3`` ``lib1`` ``lib2``: target_link_libraries(myExe lib1 lib2 lib3) target_include_directories(myExe - PRIVATE $<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES:lib3>) + PRIVATE $<TARGET_PROPERTY:lib3,INTERFACE_INCLUDE_DIRECTORIES>) + +Note that care must be taken when specifying usage requirements for targets +which will be exported for installation using the :command:`install(EXPORT)` +command. See :ref:`Creating Packages` for more. .. _`Compatible Interface Properties`: diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst index 8ff73a4..4616dd1 100644 --- a/Help/manual/cmake-commands.7.rst +++ b/Help/manual/cmake-commands.7.rst @@ -3,7 +3,7 @@ cmake-commands(7) ***************** -.. only:: html or latex +.. only:: html .. contents:: @@ -31,6 +31,7 @@ These commands may be used freely in CMake projects. /command/cmake_minimum_required /command/cmake_policy /command/configure_file + /command/continue /command/create_test_sourcelist /command/define_property /command/elseif diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst index 8e3dbb8..7a6c249 100644 --- a/Help/manual/cmake-compile-features.7.rst +++ b/Help/manual/cmake-compile-features.7.rst @@ -3,7 +3,7 @@ cmake-compile-features(7) ************************* -.. only:: html or latex +.. only:: html .. contents:: @@ -28,7 +28,7 @@ CMake knows are known to the compiler, regardless of language standard or compile flags needed to use them. Features known to CMake are named mostly following the same convention -as the Clang feature test macros. The are some execptions, such as +as the Clang feature test macros. The are some exceptions, such as CMake using ``cxx_final`` and ``cxx_override`` instead of the single ``cxx_override_control`` used by Clang. diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index eea5fc3..65b3a72 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -3,7 +3,7 @@ cmake-developer(7) ****************** -.. only:: html or latex +.. only:: html .. contents:: @@ -21,80 +21,6 @@ CMake is required to build with ancient C++ compilers and standard library implementations. Some common C++ constructs may not be used in CMake in order to build with such toolchains. -std::vector::at ---------------- - -The ``at()`` member function of ``std::vector`` may not be used. Use -``operator[]`` instead: - -.. code-block:: c++ - - std::vector<int> someVec = getVec(); - int i1 = someVec.at(5); // Wrong - int i2 = someVec[5]; // Ok - -std::string::append and std::string::clear ------------------------------------------- - -The ``append()`` and ``clear()`` member functions of ``std::string`` may not -be used. Use ``operator+=`` and ``operator=`` instead: - -.. code-block:: c++ - - std::string stringBuilder; - stringBuilder.append("chunk"); // Wrong - stringBuilder.clear(); // Wrong - stringBuilder += "chunk"; // Ok - stringBuilder = ""; // Ok - -std::set const iterators ------------------------- - -The ``find()`` member function of a ``const`` ``std::set`` instance may not be -used in a comparison with the iterator returned by ``end()``: - -.. code-block:: c++ - - const std::set<std::string>& someSet = getSet(); - if (someSet.find("needle") == someSet.end()) // Wrong - { - // ... - } - -The return value of ``find()`` must be assigned to an intermediate -``const_iterator`` for comparison: - -.. code-block:: c++ - - const std::set<std::string>& someSet; - const std::set<std::string>::const_iterator i = someSet.find("needle"); - if (i != propSet.end()) // Ok - { - // ... - } - -Char Array to ``string`` Conversions with Algorithms ----------------------------------------------------- - -In some implementations, algorithms operating on iterators to a container of -``std::string`` can not accept a ``const char*`` value: - -.. code-block:: c++ - - const char* dir = /*...*/; - std::vector<std::string> vec; - // ... - std::binary_search(vec.begin(), vec.end(), dir); // Wrong - -The ``std::string`` may need to be explicitly constructed: - -.. code-block:: c++ - - const char* dir = /*...*/; - std::vector<std::string> vec; - // ... - std::binary_search(vec.begin(), vec.end(), std::string(dir)); // Ok - std::auto_ptr ------------- @@ -102,53 +28,6 @@ Some implementations have a ``std::auto_ptr`` which can not be used as a return value from a function. ``std::auto_ptr`` may not be used. Use ``cmsys::auto_ptr`` instead. -std::vector::insert and std::set --------------------------------- - -Use of ``std::vector::insert`` with an iterator whose ``element_type`` requires -conversion is not allowed: - -.. code-block:: c++ - - std::set<const char*> theSet; - std::vector<std::string> theVector; - theVector.insert(theVector.end(), theSet.begin(), theSet.end()); // Wrong - -A loop must be used instead: - -.. code-block:: c++ - - std::set<const char*> theSet; - std::vector<std::string> theVector; - for(std::set<const char*>::iterator li = theSet.begin(); - li != theSet.end(); ++li) - { - theVector.push_back(*li); - } - -std::set::insert ----------------- - -Use of ``std::set::insert`` is not allowed with any source container: - -.. code-block:: c++ - - std::set<cmTarget*> theSet; - theSet.insert(targets.begin(), targets.end()); // Wrong - -A loop must be used instead: - -.. code-block:: c++ - - ConstIterator it = targets.begin(); - const ConstIterator end = targets.end(); - for ( ; it != end; ++it) - { - theSet.insert(*it); - } - -.. MSVC6, SunCC 5.9 - Template Parameter Defaults --------------------------- @@ -177,12 +56,6 @@ this does not work with other ancient compilers: and invoke it with the value ``0`` explicitly in all cases. -std::min and std::max ---------------------- - -``min`` and ``max`` are defined as macros on some systems. ``std::min`` and -``std::max`` may not be used. Use ``cmMinimum`` and ``cmMaximum`` instead. - size_t ------ @@ -191,12 +64,6 @@ assigning the result of ``.size()`` on a container for example, the result should be assigned to ``size_t`` not to ``std::size_t``, ``unsigned int`` or similar types. -Templates ---------- - -Some template code is permitted, but with some limitations. Member templates -may not be used, and template friends may not be used. - Adding Compile Features ======================= @@ -774,7 +641,9 @@ by the :command:`find_package` command when invoked for ``<package>``. The primary task of a find module is to determine whether a package exists on the system, set the ``<package>_FOUND`` variable to reflect this and provide any variables, macros and imported targets required to -use the package. +use the package. A find module is useful in cases where an upstream +library does not provide a +:ref:`config file package <Config File Packages>`. The traditional approach is to use variables for everything, including libraries and executables: see the `Standard Variable Names`_ section @@ -782,13 +651,9 @@ below. This is what most of the existing find modules provided by CMake do. The more modern approach is to behave as much like -``<package>Config.cmake`` files as possible, by providing imported -targets. As well as matching how ``*Config.cmake`` files work, the -libraries, include directories and compile definitions are all set just -by using the target in a :command:`target_link_libraries` call. The -disadvantage is that ``*Config.cmake`` files of projects that use -imported targets from find modules may require more work to make sure -those imported targets that are in the link interface are available. +:ref:`config file packages <Config File Packages>` files as possible, by +providing :ref:`imported target <Imported targets>`. This has the advantage +of propagating :ref:`Target Usage Requirements` to consumers. In either case (or even when providing both variables and imported targets), find modules should provide backwards compatibility with old @@ -932,7 +797,10 @@ To prevent users being overwhelmed with settings to configure, try to keep as many options as possible out of the cache, leaving at least one option which can be used to disable use of the module, or locate a not-found library (e.g. ``Xxx_ROOT_DIR``). For the same reason, mark -most cache options as advanced. +most cache options as advanced. For packages which provide both debug +and release binaries, it is common to create cache variables with a +``_LIBRARY_<CONFIG>`` suffix, such as ``Foo_LIBRARY_RELEASE`` and +``Foo_LIBRARY_DEBUG``. While these are the standard variable names, you should provide backwards compatibility for any old names that were actually in use. @@ -999,16 +867,6 @@ licence notice block # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -If the module is new to CMake, you may want to provide a warning for -projects that do not require a high enough CMake version. - -.. code-block:: cmake - - if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 3.0.0) - message(AUTHOR_WARNING - "Your project should require at least CMake 3.0.0 to use FindFoo.cmake") - endif() - Now the actual libraries and so on have to be found. The code here will obviously vary from module to module (dealing with that, after all, is the point of find modules), but there tends to be a common pattern for libraries. @@ -1115,16 +973,46 @@ not any of its dependencies. Instead, those dependencies should also be targets, and CMake should be told that they are dependencies of this target. CMake will then combine all the necessary information automatically. -We should also provide some information about the package, such as where to -download it. +The type of the :prop_tgt:`IMPORTED` target created in the +:command:`add_library` command can always be specified as ``UNKNOWN`` +type. This simplifies the code in cases where static or shared variants may +be found, and CMake will determine the type by inspecting the files. + +If the library is available with multiple configurations, the +:prop_tgt:`IMPORTED_CONFIGURATIONS` target property should also be +populated: .. code-block:: cmake - include(FeatureSummary) - set_package_properties(Foo PROPERTIES - URL "http://www.foo.example.com/" - DESCRIPTION "A library for doing useful things" - ) + if(Foo_FOUND) + if (NOT TARGET Foo::Foo) + add_library(Foo::Foo UNKNOWN IMPORTED) + endif() + if (Foo_LIBRARY_RELEASE) + set_property(TARGET Foo::Foo APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE + ) + set_target_properties(Foo::Foo PROPERTIES + IMPORTED_LOCATION_RELEASE "${Foo_LIBRARY_RELEASE}" + ) + endif() + if (Foo_LIBRARY_DEBUG) + set_property(TARGET Foo::Foo APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG + ) + set_target_properties(Foo::Foo PROPERTIES + IMPORTED_LOCATION_DEBUG "${Foo_LIBRARY_DEBUG}" + ) + endif() + set_target_properties(Foo::Foo PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_Foo_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}" + ) + endif() + +The ``RELEASE`` variant should be listed first in the property +so that that variant is chosen if the user uses a configuration which is +not an exact match for any listed ``IMPORTED_CONFIGURATIONS``. Most of the cache variables should be hidden in the ``ccmake`` interface unless the user explicitly asks to edit them. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 981bd84..c47a7c4 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -3,7 +3,7 @@ cmake-generator-expressions(7) ****************************** -.. only:: html or latex +.. only:: html .. contents:: diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst index 7f5093f..bda7eef 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -3,7 +3,7 @@ cmake-generators(7) ******************* -.. only:: html or latex +.. only:: html .. contents:: @@ -64,7 +64,7 @@ one may launch CMake from any environment. /generator/Visual Studio 10 2010 /generator/Visual Studio 11 2012 /generator/Visual Studio 12 2013 - /generator/Visual Studio 14 + /generator/Visual Studio 14 2015 /generator/Xcode Extra Generators diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index b83dcad..5ec5858f 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -3,7 +3,7 @@ cmake-language(7) ***************** -.. only:: html or latex +.. only:: html .. contents:: @@ -60,14 +60,16 @@ Syntax Encoding -------- -A CMake Language source file must be written in 7-bit ASCII text -to be portable across all supported platforms. Newlines may be +A CMake Language source file may be written in 7-bit ASCII text for +maximum portability across all supported platforms. Newlines may be encoded as either ``\n`` or ``\r\n`` but will be converted to ``\n`` as input files are read. Note that the implementation is 8-bit clean so source files may be encoded as UTF-8 on platforms with system APIs supporting this -encoding. Furthermore, CMake 3.0 and above allow a leading UTF-8 +encoding. In addition, CMake 3.2 and above support source files +encoded in UTF-8 on Windows (using UTF-16 to call system APIs). +Furthermore, CMake 3.0 and above allow a leading UTF-8 `Byte-Order Mark`_ in source files. .. _`Byte-Order Mark`: http://en.wikipedia.org/wiki/Byte_order_mark @@ -79,6 +81,10 @@ A CMake Language source file consists of zero or more `Command Invocations`_ separated by newlines and optionally spaces and `Comments`_: +.. raw:: latex + + \begin{small} + .. productionlist:: file: `file_element`* file_element: `command_invocation` `line_ending` | @@ -87,6 +93,10 @@ spaces and `Comments`_: space: <match '[ \t]+'> newline: <match '\n'> +.. raw:: latex + + \end{small} + Note that any source file line not inside `Command Arguments`_ or a `Bracket Comment`_ can end in a `Line Comment`_. @@ -98,6 +108,10 @@ Command Invocations A *command invocation* is a name followed by paren-enclosed arguments separated by whitespace: +.. raw:: latex + + \begin{small} + .. productionlist:: command_invocation: `space`* `identifier` `space`* '(' `arguments` ')' identifier: <match '[A-Za-z_][A-Za-z0-9_]*'> @@ -106,6 +120,10 @@ separated by whitespace: : `separation`* '(' `arguments` ')' separation: `space` | `line_ending` +.. raw:: latex + + \end{small} + For example: .. code-block:: cmake @@ -137,9 +155,17 @@ Command Arguments There are three types of arguments within `Command Invocations`_: +.. raw:: latex + + \begin{small} + .. productionlist:: argument: `bracket_argument` | `quoted_argument` | `unquoted_argument` +.. raw:: latex + + \end{small} + .. _`Bracket Argument`: Bracket Argument @@ -149,6 +175,10 @@ A *bracket argument*, inspired by `Lua`_ long bracket syntax, encloses content between opening and closing "brackets" of the same length: +.. raw:: latex + + \begin{small} + .. productionlist:: bracket_argument: `bracket_open` `bracket_content` `bracket_close` bracket_open: '[' '='{len} '[' @@ -156,6 +186,10 @@ same length: : of the same {len} as the `bracket_open`> bracket_close: ']' '='{len} ']' +.. raw:: latex + + \end{small} + An opening bracket of length *len >= 0* is written ``[`` followed by *len* ``=`` followed by ``[`` and the corresponding closing bracket is written ``]`` followed by *len* ``=`` followed by ``]``. @@ -197,6 +231,10 @@ Quoted Argument A *quoted argument* encloses content between opening and closing double-quote characters: +.. raw:: latex + + \begin{small} + .. productionlist:: quoted_argument: '"' `quoted_element`* '"' quoted_element: <any character except '\' or '"'> | @@ -204,6 +242,10 @@ double-quote characters: : `quoted_continuation` quoted_continuation: '\' `newline` +.. raw:: latex + + \end{small} + Quoted argument content consists of all text between opening and closing quotes. Both `Escape Sequences`_ and `Variable References`_ are evaluated. A quoted argument is always given to the command @@ -246,12 +288,20 @@ An *unquoted argument* is not enclosed by any quoting syntax. It may not contain any whitespace, ``(``, ``)``, ``#``, ``"``, or ``\`` except when escaped by a backslash: +.. raw:: latex + + \begin{small} + .. productionlist:: unquoted_argument: `unquoted_element`+ | `unquoted_legacy` unquoted_element: <any character except whitespace or one of '()#"\'> | : `escape_sequence` unquoted_legacy: <see note in text> +.. raw:: latex + + \end{small} + Unquoted argument content consists of all text in a contiguous block of allowed or escaped characters. Both `Escape Sequences`_ and `Variable References`_ are evaluated. The resulting value is divided @@ -294,12 +344,20 @@ Escape Sequences An *escape sequence* is a ``\`` followed by one character: +.. raw:: latex + + \begin{small} + .. productionlist:: escape_sequence: `escape_identity` | `escape_encoded` | `escape_semicolon` escape_identity: '\' <match '[^A-Za-z0-9;]'> escape_encoded: '\t' | '\r' | '\n' escape_semicolon: '\;' +.. raw:: latex + + \end{small} + A ``\`` followed by a non-alphanumeric character simply encodes the literal character without interpreting it as syntax. A ``\t``, ``\r``, or ``\n`` encodes a tab, carriage return, or newline character, respectively. A ``\;`` @@ -348,9 +406,17 @@ Bracket Comment A ``#`` immediately followed by a `Bracket Argument`_ forms a *bracket comment* consisting of the entire bracket enclosure: +.. raw:: latex + + \begin{small} + .. productionlist:: bracket_comment: '#' `bracket_argument` +.. raw:: latex + + \end{small} + For example: .. code-block:: cmake @@ -371,10 +437,18 @@ Line Comment A ``#`` not immediately followed by a `Bracket Argument`_ forms a *line comment* that runs until the end of the line: +.. raw:: latex + + \begin{small} + .. productionlist:: line_comment: '#' <any text not starting in a `bracket_argument` : and not containing a `newline`> +.. raw:: latex + + \end{small} + For example: .. code-block:: cmake @@ -397,8 +471,10 @@ Loops The :command:`foreach`/:command:`endforeach` and :command:`while`/:command:`endwhile` commands delimit code -blocks to be executed in a loop. The :command:`break` command -may be used inside such blocks to terminate the loop early. +blocks to be executed in a loop. Inside such blocks the +:command:`break` command may be used to terminate the loop +early whereas the :command:`continue` command may be used +to start with the next iteration immediately. Command Definitions ------------------- diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 61e4bb4..db56010 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -3,7 +3,7 @@ cmake-modules(7) **************** -.. only:: html or latex +.. only:: html .. contents:: @@ -63,6 +63,7 @@ All Modules /module/CPack /module/CPackWIX /module/CTest + /module/CTestCoverageCollectGCOV /module/CTestScriptMode /module/CTestUseLaunchers /module/Dart @@ -108,6 +109,7 @@ All Modules /module/FindGLUT /module/FindGnuplot /module/FindGnuTLS + /module/FindGSL /module/FindGTest /module/FindGTK2 /module/FindGTK @@ -118,11 +120,13 @@ All Modules /module/FindIce /module/FindIcotool /module/FindImageMagick + /module/FindIntl /module/FindITK /module/FindJasper /module/FindJava /module/FindJNI /module/FindJPEG + /module/FindJsonCpp /module/FindKDE3 /module/FindKDE4 /module/FindLAPACK @@ -208,7 +212,7 @@ All Modules /module/FindWish /module/FindwxWidgets /module/FindwxWindows - /module/FindXerces + /module/FindXercesC /module/FindX11 /module/FindXMLRPC /module/FindZLIB diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst index c4cca6d..fba1d61 100644 --- a/Help/manual/cmake-packages.7.rst +++ b/Help/manual/cmake-packages.7.rst @@ -3,7 +3,7 @@ cmake-packages(7) ***************** -.. only:: html or latex +.. only:: html .. contents:: @@ -76,6 +76,8 @@ By setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``, the ``PackageName`` package will not be searched, and will always be ``NOTFOUND``. +.. _`Config File Packages`: + Config-file Packages -------------------- @@ -260,6 +262,8 @@ The variables report the version of the package that was actually found. The ``<package>`` part of their name matches the argument given to the :command:`find_package` command. +.. _`Creating Packages`: + Creating Packages ================= @@ -282,7 +286,8 @@ shared library: generate_export_header(ClimbingStats) set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION}) set_property(TARGET ClimbingStats PROPERTY SOVERSION 3) - set_property(TARGET ClimbingStats PROPERTY INTERFACE_ClimbingStats_MAJOR_VERSION 3) + set_property(TARGET ClimbingStats PROPERTY + INTERFACE_ClimbingStats_MAJOR_VERSION 3) set_property(TARGET ClimbingStats APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION ) @@ -316,7 +321,7 @@ shared library: ) configure_file(cmake/ClimbingStatsConfig.cmake "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake" - COPY_ONLY + COPYONLY ) set(ConfigPackageLocation lib/cmake/ClimbingStats) @@ -368,6 +373,38 @@ attempt to use version 3 together with version 4. Packages can choose to employ such a pattern if different major versions of the package are designed to be incompatible. +Note that it is not advisable to populate any properties which may contain +paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and +:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevnt to dependencies. +That would hard-code into installed packages the include directory or library +paths for dependencies **as found on the machine the package was made on**. + +That is, code like this is incorrect for targets which will be used to +generate config file packages: + +.. code-block:: cmake + + target_link_libraries(ClimbingStats INTERFACE + ${Boost_LIBRARIES};${OtherDep_LIBRARIES}> + ) + target_include_directories(ClimbingStats INTERFACE + $<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}> + ) + +Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` +which have their own :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and +:prop_tgt:`IMPORTED_LOCATION` populated appropriately. Those +:ref:`IMPORTED targets <Imported Targets>` may then be +used with the :command:`target_link_libraries` command for ``ClimbingStats``. + +That way, when a consumer uses the installed package, the +consumer will run the appropriate :command:`find_package` command (via the +find_dependency macro described below) to find +the dependencies on their own machine and populate the +:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. Note that +many modules currently shipped with CMake do not currently provide +:ref:`IMPORTED targets <Imported Targets>`. + A ``NAMESPACE`` with double-colons is specified when exporting the targets for installation. This convention of double-colons gives CMake a hint that the name is an :prop_tgt:`IMPORTED` target when it is used by downstreams @@ -479,7 +516,7 @@ be true. This can be tested with logic in the package configuration file: foreach(_comp ${ClimbingStats_FIND_COMPONENTS}) if (NOT ";${_supported_components};" MATCHES _comp) set(ClimbingStats_FOUND False) - set(ClimbingStats_NOTFOUND_MESSAGE "Specified unsupported component: ${_comp}") + set(ClimbingStats_NOTFOUND_MESSAGE "Unsupported component: ${_comp}") endif() include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake") endforeach() diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 8edf708..96f39e6 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -3,7 +3,7 @@ cmake-policies(7) ***************** -.. only:: html or latex +.. only:: html .. contents:: @@ -112,3 +112,5 @@ All Policies /policy/CMP0052 /policy/CMP0053 /policy/CMP0054 + /policy/CMP0055 + /policy/CMP0056 diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 38bcd04..68954c5 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -3,7 +3,7 @@ cmake-properties(7) ******************* -.. only:: html or latex +.. only:: html .. contents:: @@ -80,6 +80,7 @@ Properties on Targets /prop_tgt/ALIASED_TARGET /prop_tgt/ANDROID_API + /prop_tgt/ANDROID_API_MIN /prop_tgt/ANDROID_GUI /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY_CONFIG /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY @@ -291,6 +292,9 @@ Properties on Source Files /prop_sf/OBJECT_OUTPUTS /prop_sf/SYMBOLIC /prop_sf/VS_DEPLOYMENT_CONTENT + /prop_sf/VS_DEPLOYMENT_LOCATION + /prop_sf/VS_SHADER_ENTRYPOINT + /prop_sf/VS_SHADER_MODEL /prop_sf/VS_SHADER_TYPE /prop_sf/WRAP_EXCLUDE /prop_sf/XCODE_EXPLICIT_FILE_TYPE diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index fe8d62d..e8a2c1e 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -3,7 +3,7 @@ cmake-qt(7) *********** -.. only:: html or latex +.. only:: html .. contents:: diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index fad5481..054438d 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -3,7 +3,7 @@ cmake-toolchains(7) ******************* -.. only:: html or latex +.. only:: html .. contents:: @@ -241,3 +241,21 @@ Windows Store may look like this: set(CMAKE_SYSTEM_NAME WindowsStore) set(CMAKE_SYSTEM_VERSION 8.1) + +Cross Compiling using NVIDIA Nsight Tegra +----------------------------------------- + +A toolchain file to configure a Visual Studio generator to +build using NVIDIA Nsight Tegra targeting Android may look +like this: + +.. code-block:: cmake + + set(CMAKE_SYSTEM_NAME Android) + +The :variable:`CMAKE_GENERATOR_TOOLSET` may be set to select +the Nsight Tegra "Toolchain Version" value. + +See the :prop_tgt:`ANDROID_API_MIN`, :prop_tgt:`ANDROID_API` +and :prop_tgt:`ANDROID_GUI` target properties to configure +targets within the project. diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 1deb8bb..c342dbe 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -3,7 +3,7 @@ cmake-variables(7) ****************** -.. only:: html or latex +.. only:: html .. contents:: @@ -36,6 +36,7 @@ Variables that Provide Information /variable/CMAKE_EXECUTABLE_SUFFIX /variable/CMAKE_EXTRA_GENERATOR /variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES + /variable/CMAKE_FIND_PACKAGE_NAME /variable/CMAKE_GENERATOR /variable/CMAKE_GENERATOR_PLATFORM /variable/CMAKE_GENERATOR_TOOLSET @@ -47,6 +48,7 @@ Variables that Provide Information /variable/CMAKE_LINK_LIBRARY_SUFFIX /variable/CMAKE_MAJOR_VERSION /variable/CMAKE_MAKE_PROGRAM + /variable/CMAKE_MATCH_COUNT /variable/CMAKE_MINIMUM_REQUIRED_VERSION /variable/CMAKE_MINOR_VERSION /variable/CMAKE_PARENT_LIST_FILE @@ -179,6 +181,7 @@ Variables that Describe the System /variable/CMAKE_SYSTEM_VERSION /variable/CYGWIN /variable/ENV + /variable/MINGW /variable/MSVC10 /variable/MSVC11 /variable/MSVC12 @@ -205,6 +208,7 @@ Variables that Control the Build :maxdepth: 1 /variable/CMAKE_ANDROID_API + /variable/CMAKE_ANDROID_API_MIN /variable/CMAKE_ANDROID_GUI /variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY /variable/CMAKE_AUTOMOC_MOC_OPTIONS diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index 03e86af..cc132c2 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -58,7 +58,7 @@ Options will have no effect. ``-j <jobs>, --parallel <jobs>`` - Run the tests in parallel using thegiven number of jobs. + Run the tests in parallel using the given number of jobs. This option tells ctest to run the tests in parallel using given number of jobs. This option can also be set by setting the diff --git a/Help/module/CTestCoverageCollectGCOV.rst b/Help/module/CTestCoverageCollectGCOV.rst new file mode 100644 index 0000000..4c5deca --- /dev/null +++ b/Help/module/CTestCoverageCollectGCOV.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CTestCoverageCollectGCOV.cmake diff --git a/Help/module/FindGSL.rst b/Help/module/FindGSL.rst new file mode 100644 index 0000000..baf2213 --- /dev/null +++ b/Help/module/FindGSL.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindGSL.cmake diff --git a/Help/module/FindIntl.rst b/Help/module/FindIntl.rst new file mode 100644 index 0000000..813e2df --- /dev/null +++ b/Help/module/FindIntl.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindIntl.cmake diff --git a/Help/module/FindJsonCpp.rst b/Help/module/FindJsonCpp.rst new file mode 100644 index 0000000..ba87ece --- /dev/null +++ b/Help/module/FindJsonCpp.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindJsonCpp.cmake diff --git a/Help/module/FindXerces.rst b/Help/module/FindXerces.rst deleted file mode 100644 index 166d8dd..0000000 --- a/Help/module/FindXerces.rst +++ /dev/null @@ -1 +0,0 @@ -.. cmake-module:: ../../Modules/FindXerces.cmake diff --git a/Help/module/FindXercesC.rst b/Help/module/FindXercesC.rst new file mode 100644 index 0000000..4818071 --- /dev/null +++ b/Help/module/FindXercesC.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindXercesC.cmake diff --git a/Help/policy/CMP0053.rst b/Help/policy/CMP0053.rst index fac430e..bb0ff8b 100644 --- a/Help/policy/CMP0053.rst +++ b/Help/policy/CMP0053.rst @@ -28,7 +28,7 @@ cleaned up to simplify the behavior. Specifically: so improper variable reference syntax is always an error. * More characters are allowed to be escaped in variable names. - Previously, only ``()#" \#@^`` were valid characters to + Previously, only ``()#" \@^`` were valid characters to escape. Now any non-alphanumeric, non-semicolon, non-NUL character may be escaped following the ``escape_identity`` production in the :ref:`Escape Sequences` section of the diff --git a/Help/policy/CMP0054.rst b/Help/policy/CMP0054.rst index dffee5e..39f0c40 100644 --- a/Help/policy/CMP0054.rst +++ b/Help/policy/CMP0054.rst @@ -3,15 +3,43 @@ CMP0054 Only interpret :command:`if` arguments as variables or keywords when unquoted. -CMake 3.1 and above no longer dereference variables or interpret keywords -in an :command:`if` command argument when it is a :ref:`Quoted Argument` -or a :ref:`Bracket Argument`. +CMake 3.1 and above no longer implicitly dereference variables or +interpret keywords in an :command:`if` command argument when +it is a :ref:`Quoted Argument` or a :ref:`Bracket Argument`. The ``OLD`` behavior for this policy is to dereference variables and interpret keywords even if they are quoted or bracketed. The ``NEW`` behavior is to not dereference variables or interpret keywords that have been quoted or bracketed. +Given the following partial example: + +:: + + set(MONKEY 1) + set(ANIMAL MONKEY) + + if("${ANIMAL}" STREQUAL "MONKEY") + +After explicit expansion of variables this gives: + +:: + + if("MONKEY" STREQUAL "MONKEY") + +With the policy set to ``OLD`` implicit expansion reduces this semantically to: + +:: + + if("1" STREQUAL "1") + +With the policy set to ``NEW`` the quoted arguments will not be +further dereferenced: + +:: + + if("MONKEY" STREQUAL "MONKEY") + This policy was introduced in CMake version 3.1. CMake version |release| warns when the policy is not set and uses ``OLD`` behavior. Use the :command:`cmake_policy` command to set diff --git a/Help/policy/CMP0055.rst b/Help/policy/CMP0055.rst new file mode 100644 index 0000000..fe7ab6f --- /dev/null +++ b/Help/policy/CMP0055.rst @@ -0,0 +1,17 @@ +CMP0055 +------- + +Strict checking for the :command:`break` command. + +CMake 3.1 and lower allowed calls to the :command:`break` command +outside of a loop context and also ignored any given arguments. +This was undefined behavior. + +The OLD behavior for this policy is to allow :command:`break` to be placed +outside of loop contexts and ignores any arguments. The NEW behavior for this +policy is to issue an error if a misplaced break or any arguments are found. + +This policy was introduced in CMake version 3.2. +CMake version |release| warns when the policy is not set and uses +OLD behavior. Use the cmake_policy command to set it to OLD or +NEW explicitly. diff --git a/Help/policy/CMP0056.rst b/Help/policy/CMP0056.rst new file mode 100644 index 0000000..3c75ff4 --- /dev/null +++ b/Help/policy/CMP0056.rst @@ -0,0 +1,32 @@ +CMP0056 +------- + +Honor link flags in :command:`try_compile` source-file signature. + +The :command:`try_compile` command source-file signature generates a +``CMakeLists.txt`` file to build the source file into an executable. +In order to compile the source the same way as it might be compiled +by the calling project, the generated project sets the value of the +:variable:`CMAKE_<LANG>_FLAGS` variable to that in the calling project. +The value of the :variable:`CMAKE_EXE_LINKER_FLAGS` variable may be +needed in some cases too, but CMake 3.1 and lower did not set it in +the generated project. CMake 3.2 and above prefer to set it so that +linker flags are honored as well as compiler flags. This policy +provides compatibility with the pre-3.2 behavior. + +The OLD behavior for this policy is to not set the value of the +:variable:`CMAKE_EXE_LINKER_FLAGS` variable in the generated test +project. The NEW behavior for this policy is to set the value of +the :variable:`CMAKE_EXE_LINKER_FLAGS` variable in the test project +to the same as it is in the calling project. + +If the project code does not set the policy explicitly, users may +set it on the command line by defining the +:variable:`CMAKE_POLICY_DEFAULT_CMP0056 <CMAKE_POLICY_DEFAULT_CMP<NNNN>>` +variable in the cache. + +This policy was introduced in CMake version 3.2. Unlike most policies, +CMake version |release| does *not* warn by default when this policy +is not set and simply uses OLD behavior. See documentation of the +:variable:`CMAKE_POLICY_WARNING_CMP0056 <CMAKE_POLICY_WARNING_CMP<NNNN>>` +variable to control the warning. diff --git a/Help/prop_dir/COMPILE_OPTIONS.rst b/Help/prop_dir/COMPILE_OPTIONS.rst index 5953059..5530860 100644 --- a/Help/prop_dir/COMPILE_OPTIONS.rst +++ b/Help/prop_dir/COMPILE_OPTIONS.rst @@ -6,9 +6,9 @@ List of options to pass to the compiler. This property specifies the list of options given so far to the :command:`add_compile_options` command. -This property is used to populate the :prop_tgt:`COMPILE_OPTIONS` target -property, which is used by the generators to set the options for the -compiler. +This property is used to initialize the :prop_tgt:`COMPILE_OPTIONS` target +property when a target is created, which is used by the generators to set +the options for the compiler. Contents of ``COMPILE_OPTIONS`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst index bdeabdb..163ae34 100644 --- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst @@ -130,9 +130,11 @@ The features known to this version of CMake are: .. _N1987: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm ``cxx_final`` - Override control ``final`` keyword, as defined in N2928_. + Override control ``final`` keyword, as defined in N2928_, N3206_ and N3272_. .. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm + .. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm + .. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm ``cxx_func_identifier`` Predefined ``__func__`` identifier, as defined in N2340_. @@ -145,7 +147,7 @@ The features known to this version of CMake are: .. _N2672: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm ``cxx_generic_lambdas`` - Generic lambdas, ss defined in N3649_. + Generic lambdas, as defined in N3649_. .. _N3649: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html @@ -195,9 +197,12 @@ The features known to this version of CMake are: .. _N2431: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf ``cxx_override`` - Override control ``override`` keyword, as defined in N2928_. + Override control ``override`` keyword, as defined in N2928_, N3206_ + and N3272_. .. _N2928: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm + .. _N3206: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm + .. _N3272: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm ``cxx_range_for`` Range-based for, as defined in N2930_. diff --git a/Help/prop_sf/AUTOUIC_OPTIONS.rst b/Help/prop_sf/AUTOUIC_OPTIONS.rst index 6dfabb0..bb48da9 100644 --- a/Help/prop_sf/AUTOUIC_OPTIONS.rst +++ b/Help/prop_sf/AUTOUIC_OPTIONS.rst @@ -6,7 +6,7 @@ Additional options for ``uic`` when using :prop_tgt:`AUTOUIC` This property holds additional command line options which will be used when ``uic`` is executed during the build via :prop_tgt:`AUTOUIC`, i.e. it is equivalent to the optional ``OPTIONS`` argument of the -:module:`qt4_wrap_ui()<FindQt4>` macro. +:module:`qt4_wrap_ui() <FindQt4>` macro. By default it is empty. diff --git a/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst new file mode 100644 index 0000000..303db95 --- /dev/null +++ b/Help/prop_sf/VS_DEPLOYMENT_LOCATION.rst @@ -0,0 +1,8 @@ +VS_DEPLOYMENT_LOCATION +---------------------- + +Specifies the deployment location for a content source file with a Windows +Phone or Windows Store application when built with a Visual Studio generator. +This property is only applicable when using :prop_sf:`VS_DEPLOYMENT_CONTENT`. +The value represent the path relative to the app package and applies to all +configurations. diff --git a/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst new file mode 100644 index 0000000..fe3471f --- /dev/null +++ b/Help/prop_sf/VS_SHADER_ENTRYPOINT.rst @@ -0,0 +1,5 @@ +VS_SHADER_ENTRYPOINT +-------------------- + +Specifies the name of the entry point for the shader of a ``.hlsl`` source +file. diff --git a/Help/prop_sf/VS_SHADER_MODEL.rst b/Help/prop_sf/VS_SHADER_MODEL.rst new file mode 100644 index 0000000..b1cf0df --- /dev/null +++ b/Help/prop_sf/VS_SHADER_MODEL.rst @@ -0,0 +1,5 @@ +VS_SHADER_MODEL +--------------- + +Specifies the shader model of a ``.hlsl`` source file. Some shader types can +only be used with recent shader models diff --git a/Help/prop_tgt/ANDROID_API_MIN.rst b/Help/prop_tgt/ANDROID_API_MIN.rst new file mode 100644 index 0000000..773ab3f --- /dev/null +++ b/Help/prop_tgt/ANDROID_API_MIN.rst @@ -0,0 +1,7 @@ +ANDROID_API_MIN +--------------- + +Set the Android MIN API version (e.g. ``9``). The version number +must be a positive decimal integer. This property is initialized by +the value of the :variable:`CMAKE_ANDROID_API_MIN` variable if it is set +when a target is created. Native code builds using this API version. diff --git a/Help/prop_tgt/ANDROID_GUI.rst b/Help/prop_tgt/ANDROID_GUI.rst index 90d2428..abdba7a 100644 --- a/Help/prop_tgt/ANDROID_GUI.rst +++ b/Help/prop_tgt/ANDROID_GUI.rst @@ -7,3 +7,7 @@ When this property is set to true the executable when built for Android will be created as an application package. This property is initialized by the value of the :variable:`CMAKE_ANDROID_GUI` variable if it is set when a target is created. + +Add the ``AndroidManifest.xml`` source file explicitly to the +target :command:`add_executable` command invocation to specify the +root directory of the application package source. diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst index b50cdf9..6329e34 100644 --- a/Help/prop_tgt/CXX_STANDARD.rst +++ b/Help/prop_tgt/CXX_STANDARD.rst @@ -7,7 +7,7 @@ This property specifies the C++ standard whose features are requested to build this target. For some compilers, this results in adding a flag such as ``-std=gnu++11`` to the compile line. -Supported values are ``98`` and ``11``. +Supported values are ``98``, ``11`` and ``14``. If the value requested does not result in a compile flag being added for the compiler in use, a previous standard flag will be added instead. This diff --git a/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt b/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt new file mode 100644 index 0000000..4188b8d --- /dev/null +++ b/Help/prop_tgt/INTERFACE_BUILD_PROPERTY.txt @@ -0,0 +1,16 @@ + +List of public |property_name| requirements for a library. + +Targets may populate this property to publish the |property_name| +required to compile against the headers for the target. The |command_name| +command populates this property with values given to the ``PUBLIC`` and +``INTERFACE`` keywords. Projects may also get and set the property directly. + +When target dependencies are specified using :command:`target_link_libraries`, +CMake will read this property from all target dependencies to determine the +build properties of the consumer. + +Contents of |PROPERTY_INTERFACE_NAME| may use "generator expressions" +with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +-manual for more on defining buildsystem properties. diff --git a/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst index 910b661..c74a319 100644 --- a/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst +++ b/Help/prop_tgt/INTERFACE_COMPILE_DEFINITIONS.rst @@ -1,15 +1,9 @@ INTERFACE_COMPILE_DEFINITIONS ----------------------------- -List of public compile definitions for a library. - -Targets may populate this property to publish the compile definitions -required to compile against the headers for the target. Consuming -targets can add entries to their own :prop_tgt:`COMPILE_DEFINITIONS` -property such as ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>`` -to use the compile definitions specified in the interface of ``foo``. - -Contents of ``INTERFACE_COMPILE_DEFINITIONS`` may use "generator expressions" -with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` -manual for available expressions. See the :manual:`cmake-buildsystem(7)` -manual for more on defining buildsystem properties. +.. |property_name| replace:: compile definitions +.. |command_name| replace:: :command:`target_compile_definitions` +.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_DEFINITIONS`` +.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_DEFINITIONS` +.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_DEFINITIONS>`` +.. include:: INTERFACE_BUILD_PROPERTY.txt diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst index 7abdecb..8dfec5f 100644 --- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst +++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst @@ -1,16 +1,12 @@ INTERFACE_COMPILE_FEATURES -------------------------- -List of public compile requirements for a library. +.. |property_name| replace:: compile features +.. |command_name| replace:: :command:`target_compile_features` +.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_FEATURES`` +.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_FEATURES` +.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_FEATURES>`` +.. include:: INTERFACE_BUILD_PROPERTY.txt -Targets may populate this property to publish the compiler features -required to compile against the headers for the target. Consuming -targets can add entries to their own :prop_tgt:`COMPILE_FEATURES` -property such as ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_FEATURES>`` -to require the features specified in the interface of ``foo``. - -Contents of ``INTERFACE_COMPILE_FEATURES`` may use "generator expressions" -with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` -manual for available expressions. See the -:manual:`cmake-compile-features(7)` manual for information on compile +See the :manual:`cmake-compile-features(7)` manual for information on compile features. diff --git a/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst index d0a38d6..7f0b385 100644 --- a/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst +++ b/Help/prop_tgt/INTERFACE_COMPILE_OPTIONS.rst @@ -1,15 +1,9 @@ INTERFACE_COMPILE_OPTIONS ------------------------- -List of interface options to pass to the compiler. - -Targets may populate this property to publish the compile options -required to compile against the headers for the target. Consuming -targets can add entries to their own :prop_tgt:`COMPILE_OPTIONS` property -such as ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS>`` to use the -compile options specified in the interface of ``foo``. - -Contents of ``INTERFACE_COMPILE_OPTIONS`` may use "generator expressions" -with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` -manual for available expressions. See the :manual:`cmake-buildsystem(7)` -manual for more on defining buildsystem properties. +.. |property_name| replace:: compile options +.. |command_name| replace:: :command:`target_compile_options` +.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_COMPILE_OPTIONS`` +.. |PROPERTY_LINK| replace:: :prop_tgt:`COMPILE_OPTIONS` +.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_COMPILE_OPTIONS>`` +.. include:: INTERFACE_BUILD_PROPERTY.txt diff --git a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst index 899e821..1cfd7a8 100644 --- a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst +++ b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst @@ -1,22 +1,12 @@ INTERFACE_INCLUDE_DIRECTORIES ----------------------------- -List of public include directories for a library. - -The :command:`target_include_directories` command populates this property -with values given to the ``PUBLIC`` and ``INTERFACE`` keywords. Projects -may also get and set the property directly. - -Targets may populate this property to publish the include directories -required to compile against the headers for the target. Consuming -targets can add entries to their own :prop_tgt:`INCLUDE_DIRECTORIES` -property such as ``$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>`` -to use the include directories specified in the interface of ``foo``. - -Contents of ``INTERFACE_INCLUDE_DIRECTORIES`` may use "generator expressions" -with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` -manual for available expressions. See the :manual:`cmake-buildsystem(7)` -manual for more on defining buildsystem properties. +.. |property_name| replace:: include directories +.. |command_name| replace:: :command:`target_include_directories` +.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_INCLUDE_DIRECTORIES`` +.. |PROPERTY_LINK| replace:: :prop_tgt:`INCLUDE_DIRECTORIES` +.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>`` +.. include:: INTERFACE_BUILD_PROPERTY.txt Include directories usage requirements commonly differ between the build-tree and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE`` @@ -27,7 +17,10 @@ installation prefix. For example: .. code-block:: cmake - set_property(TARGET mylib APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES + target_include_directories(mylib INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/mylib> $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib - ) + ) + +.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_INCLUDE_DIRECTORIES`` +.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index 8e4843b..55b7b8d 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst @@ -4,7 +4,8 @@ INTERFACE_LINK_LIBRARIES List public interface libraries for a library. This property contains the list of transitive link dependencies. When -the target is linked into another target the libraries listed (and +the target is linked into another target using the +:command:`target_link_libraries` command, the libraries listed (and recursively their link interface libraries) will be provided to the other target also. This property is overridden by the :prop_tgt:`LINK_INTERFACE_LIBRARIES` or @@ -15,3 +16,6 @@ Contents of ``INTERFACE_LINK_LIBRARIES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. + +.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_LINK_LIBRARIES`` +.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt diff --git a/Help/prop_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst index fb28231..696ee95 100644 --- a/Help/prop_tgt/INTERFACE_SOURCES.rst +++ b/Help/prop_tgt/INTERFACE_SOURCES.rst @@ -1,13 +1,20 @@ INTERFACE_SOURCES ----------------- -List of interface sources to pass to the compiler. +List of interface sources to compile into consuming targets. Targets may populate this property to publish the sources -for consuming targets to compile. Consuming -targets can add entries to their own :prop_tgt:`SOURCES` property -such as ``$<TARGET_PROPERTY:foo,INTERFACE_SOURCES>`` to use the -sources specified in the interface of ``foo``. +for consuming targets to compile. The :command:`target_sources` command +populates this property with values given to the ``PUBLIC`` and +``INTERFACE`` keywords. Projects may also get and set the property directly. + +When target dependencies are specified using :command:`target_link_libraries`, +CMake will read this property from all target dependencies to determine the +sources of the consumer. + +Targets with ``INTERFACE_SOURCES`` may not be exported with the +:command:`export` or :command:`install(EXPORT)` commands. This limitation may be +lifted in a future version of CMake. Contents of ``INTERFACE_SOURCES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` diff --git a/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst index 9e603ee..b54b6c1 100644 --- a/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst +++ b/Help/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES.rst @@ -5,8 +5,14 @@ List of public system include directories for a library. Targets may populate this property to publish the include directories which contain system headers, and therefore should not result in -compiler warnings. Consuming targets will then mark the same include -directories as system headers. +compiler warnings. The :command:`target_include_directories(SYSTEM)` +command signature populates this property with values given to the +``PUBLIC`` and ``INTERFACE`` keywords. Projects may also get and set the +property directly. + +When target dependencies are specified using :command:`target_link_libraries`, +CMake will read this property from all target dependencies to mark the +same include directories as containing system headers. Contents of ``INTERFACE_SYSTEM_INCLUDE_DIRECTORIES`` may use "generator expressions" with the syntax ``$<...>``. See the diff --git a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst index 435e25e..2e859eb 100644 --- a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst @@ -5,18 +5,24 @@ List public interface libraries for a shared library or executable. By default linking to a shared library target transitively links to targets with which the library itself was linked. For an executable -with exports (see the ENABLE_EXPORTS property) no default transitive -link dependencies are used. This property replaces the default +with exports (see the :prop_tgt:`ENABLE_EXPORTS` target property) no +default transitive link dependencies are used. This property replaces the default transitive link dependencies with an explicit list. When the target -is linked into another target the libraries listed (and recursively +is linked into another target using the :command:`target_link_libraries` +command, the libraries listed (and recursively their link interface libraries) will be provided to the other target also. If the list is empty then no transitive link dependencies will be incorporated when this target is linked into another target even if the default set is non-empty. This property is initialized by the -value of the variable CMAKE_LINK_INTERFACE_LIBRARIES if it is set when -a target is created. This property is ignored for STATIC libraries. +value of the :variable:`CMAKE_LINK_INTERFACE_LIBRARIES` variable if it is +set when a target is created. This property is ignored for ``STATIC`` +libraries. -This property is overridden by the INTERFACE_LINK_LIBRARIES property if -policy CMP0022 is NEW. +This property is overridden by the :prop_tgt:`INTERFACE_LINK_LIBRARIES` +property if policy :policy:`CMP0022` is ``NEW``. -This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead. +This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES` +instead. + +.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES`` +.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt diff --git a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst index 08bd650..7f2b5dd 100644 --- a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst +++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst @@ -4,10 +4,14 @@ LINK_INTERFACE_LIBRARIES_<CONFIG> Per-configuration list of public interface libraries for a target. This is the configuration-specific version of -LINK_INTERFACE_LIBRARIES. If set, this property completely overrides -the generic property for the named configuration. +:prop_tgt:`LINK_INTERFACE_LIBRARIES`. If set, this property completely +overrides the generic property for the named configuration. -This property is overridden by the INTERFACE_LINK_LIBRARIES property if -policy CMP0022 is NEW. +This property is overridden by the :prop_tgt:`INTERFACE_LINK_LIBRARIES` +property if policy :policy:`CMP0022` is ``NEW``. -This property is deprecated. Use INTERFACE_LINK_LIBRARIES instead. +This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES` +instead. + +.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES_<CONFIG>`` +.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt diff --git a/Help/prop_tgt/TYPE.rst b/Help/prop_tgt/TYPE.rst index 1951d46..5ac63cc 100644 --- a/Help/prop_tgt/TYPE.rst +++ b/Help/prop_tgt/TYPE.rst @@ -5,4 +5,5 @@ The type of the target. This read-only property can be used to test the type of the given target. It will be one of STATIC_LIBRARY, MODULE_LIBRARY, -SHARED_LIBRARY, EXECUTABLE or one of the internal target types. +SHARED_LIBRARY, INTERFACE_LIBRARY, EXECUTABLE or one of the internal +target types. diff --git a/Help/release/3.1.0.rst b/Help/release/3.1.0.rst index 652bcd3..97a63f9 100644 --- a/Help/release/3.1.0.rst +++ b/Help/release/3.1.0.rst @@ -18,7 +18,7 @@ New Features Generators ---------- -* A :generator:`Visual Studio 14` generator was added. +* The :generator:`Visual Studio 14 2015` generator was added. Windows Phone and Windows Store ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -69,9 +69,15 @@ Commands :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` variables to skip searching the package registries. +* The :command:`get_property` command learned a new ``INSTALL`` scope + for properties. + * The :command:`install` command learned a ``MESSAGE_NEVER`` option to avoid output during installation. +* The :command:`set_property` command learned a new ``INSTALL`` scope + for properties. + * The :command:`string` command learned a new ``GENEX_STRIP`` subcommand which removes :manual:`generator expression <cmake-generator-expressions(7)>`. @@ -159,6 +165,10 @@ Properties to tell the Visual Studio generators to mark content for deployment in Windows Phone and Windows Store projects. +* A :prop_sf:`VS_DEPLOYMENT_LOCATION` source file property was added + to tell the Visual Studio generators the relative location of content + marked for deployment in Windows Phone and Windows Store projects. + * The :prop_tgt:`VS_WINRT_COMPONENT` target property was created to tell Visual Studio generators to compile a shared library as a Windows Runtime (WinRT) component. @@ -230,17 +240,12 @@ Modules * The :module:`FindOpenCL` module was introduced. -* The :module:`FindOpenGL` module now provides imported targets - ``OpenGL::GL`` and ``OpenGL::GLU`` when the libraries are found. - * The :module:`FindOpenMP` module learned to support Fortran. * The :module:`FindPkgConfig` module learned to use the ``PKG_CONFIG`` environment variable value as the ``pkg-config`` executable, if set. -* The :module:`FindVTK` module dropped support for finding VTK 4.0. - It is now a thin-wrapper around ``find_package(VTK ... NO_MODULE)``. - This produces much clearer error messages when VTK is not found. +* The :module:`FindXercesC` module was introduced. * The :module:`FindZLIB` module now provides imported targets. @@ -314,8 +319,10 @@ Other * The Visual Studio generators learned to treat ``.hlsl`` source files as High Level Shading Language sources (using ``FXCompile`` - in ``.vcxproj`` files). A :prop_sf:`VS_SHADER_TYPE` source file - property was added to specify the Shader Type. + in ``.vcxproj`` files). Source file properties + :prop_sf:`VS_SHADER_TYPE`, :prop_sf:`VS_SHADER_MODEL`, and + :prop_sf:`VS_SHADER_ENTRYPOINT` were added added to specify the + shader type, model, and entry point name. New Diagnostics =============== @@ -346,6 +353,28 @@ Deprecated and Removed Features CMake 3.1 again requires the quotes for this to work correctly. +* Prior to CMake 3.1 the Makefile generators did not escape ``#`` + correctly inside make variable assignments used in generated + makefiles, causing them to be treated as comments. This made + code like:: + + add_compile_options(-Wno-#pragma-messages) + + not work in Makefile generators, but work in other generators. + Now it is escaped correctly, making the behavior consistent + across generators. However, some projects may have tried to + workaround the original bug with code like:: + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-\\#pragma-messages") + + This added the needed escape for Makefile generators but also + caused other generators to pass ``-Wno-\#pragma-messages`` to + the shell, which would work only in POSIX shells. + Unfortunately the escaping fix could not be made in a compatible + way so this platform- and generator-specific workaround no + longer works. Project code may test the :variable:`CMAKE_VERSION` + variable value to make the workaround version-specific too. + * Callbacks established by the :command:`variable_watch` command will no longer receive the ``ALLOWED_UNKNOWN_READ_ACCESS`` access type when the undocumented ``CMAKE_ALLOW_UNKNOWN_VARIABLE_READ_ACCESS`` variable is @@ -356,6 +385,17 @@ Deprecated and Removed Features it is deprecated and should not longer be used. Use the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable instead. +* The :module:`FindITK` module has been removed altogether. + It was a thin-wrapper around ``find_package(ITK ... NO_MODULE)``. + This produces much clearer error messages when ITK is not found. + +* The :module:`FindVTK` module has been removed altogether. + It was a thin-wrapper around ``find_package(VTK ... NO_MODULE)``. + This produces much clearer error messages when VTK is not found. + + The module also provided compatibility support for finding VTK 4.0. + This capability has been dropped. + Other Changes ============= @@ -379,3 +419,7 @@ Other Changes the Open Watcom external version numbering. The external version numbers are lower than the internal version number by 11. + +* The ``cmake-mode.el`` major Emacs editing mode no longer + treats ``_`` as part of words, making it more consistent + with other major modes. diff --git a/Help/release/dev/Apple-GNU-compiler-features.rst b/Help/release/dev/Apple-GNU-compiler-features.rst new file mode 100644 index 0000000..40c3712 --- /dev/null +++ b/Help/release/dev/Apple-GNU-compiler-features.rst @@ -0,0 +1,5 @@ +Apple-GNU-compiler-features +--------------------------- + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by GNU compilers on OS X. diff --git a/Help/release/dev/Apple-compiler-selection.rst b/Help/release/dev/Apple-compiler-selection.rst new file mode 100644 index 0000000..5ff5653 --- /dev/null +++ b/Help/release/dev/Apple-compiler-selection.rst @@ -0,0 +1,8 @@ +Apple-compiler-selection +------------------------ + +* On OS X with Makefile and Ninja generators, when a compiler is found + in ``/usr/bin`` it is now mapped to the corresponding compiler inside + the Xcode application folder, if any. This allows such build + trees to continue to work with their original compiler even when + ``xcode-select`` switches to a different Xcode installation. diff --git a/Help/release/dev/ExternalData-custom-download.rst b/Help/release/dev/ExternalData-custom-download.rst new file mode 100644 index 0000000..c40f4f7 --- /dev/null +++ b/Help/release/dev/ExternalData-custom-download.rst @@ -0,0 +1,7 @@ +ExternalData-custom-download +---------------------------- + +* The :module:`ExternalData` module learned to support + :ref:`Custom Fetch Scripts <ExternalData Custom Fetch Scripts>`. + This allows projects to specify custom ``.cmake`` scripts for + fetching data objects during the build. diff --git a/Help/release/dev/ExternalProject_CMAKE_CACHE_DEFAULT_ARGS.rst b/Help/release/dev/ExternalProject_CMAKE_CACHE_DEFAULT_ARGS.rst new file mode 100644 index 0000000..1838ab6 --- /dev/null +++ b/Help/release/dev/ExternalProject_CMAKE_CACHE_DEFAULT_ARGS.rst @@ -0,0 +1,6 @@ +ExternalProject_CMAKE_CACHE_DEFAULT_ARGS +---------------------------------------- + +* The :module:`ExternalProject` module ``ExternalProject_Add`` function + learned a new ``CMAKE_CACHE_DEFAULT_ARGS`` option to initialize cache + values in the external project without setting them on future builds. diff --git a/Help/release/dev/ExternalProject_TEST_EXCLUDE_FROM_MAIN.rst b/Help/release/dev/ExternalProject_TEST_EXCLUDE_FROM_MAIN.rst new file mode 100644 index 0000000..dfbf108 --- /dev/null +++ b/Help/release/dev/ExternalProject_TEST_EXCLUDE_FROM_MAIN.rst @@ -0,0 +1,6 @@ +ExternalProject_TEST_EXCLUDE_FROM_MAIN +-------------------------------------- + +* The :module:`ExternalProject` module :command:`ExternalProject_Add` + command learned a ``TEST_EXCLUDE_FROM_MAIN`` option to exclude tests + from the main build. diff --git a/Help/release/dev/ExternalProject_UPDATE_DISCONNECTED.rst b/Help/release/dev/ExternalProject_UPDATE_DISCONNECTED.rst new file mode 100644 index 0000000..bed4a89 --- /dev/null +++ b/Help/release/dev/ExternalProject_UPDATE_DISCONNECTED.rst @@ -0,0 +1,6 @@ +ExternalProject_UPDATE_DISCONNECTED +----------------------------------- + +* The :module:`ExternalProject` module ``ExternalProject_Add`` command + learned an ``UPDATE_DISCONNECTED`` option to avoid automatically + updating the source tree checkout from version control. diff --git a/Help/release/dev/ExternalProject_independent-step-targets.rst b/Help/release/dev/ExternalProject_independent-step-targets.rst new file mode 100644 index 0000000..02e8db8 --- /dev/null +++ b/Help/release/dev/ExternalProject_independent-step-targets.rst @@ -0,0 +1,6 @@ +ExternalProject_independent-step-targets +---------------------------------------- + +* The :module:`ExternalProject` module learned options to create + independent external project step targets that do not depend + on the builtin steps. diff --git a/Help/release/dev/FindGit-local-Github.rst b/Help/release/dev/FindGit-local-Github.rst new file mode 100644 index 0000000..3523e86 --- /dev/null +++ b/Help/release/dev/FindGit-local-Github.rst @@ -0,0 +1,5 @@ +FindGit-local-Github +-------------------- + +* The :module:`FindGit` module learned to find the ``git`` command-line tool + that comes with GitHub for Windows installed in user home directories. diff --git a/Help/release/dev/FindLATEX-components.rst b/Help/release/dev/FindLATEX-components.rst new file mode 100644 index 0000000..d161c1f --- /dev/null +++ b/Help/release/dev/FindLATEX-components.rst @@ -0,0 +1,4 @@ +FindLATEX-components +-------------------- + +* The :module:`FindLATEX` module learned to support components. diff --git a/Help/release/dev/FindOpenGL-no-X11.rst b/Help/release/dev/FindOpenGL-no-X11.rst new file mode 100644 index 0000000..dacf165 --- /dev/null +++ b/Help/release/dev/FindOpenGL-no-X11.rst @@ -0,0 +1,8 @@ +FindOpenGL-no-X11 +----------------- + +* The :module:`FindOpenGL` module no longer explicitly searches + for any dependency on X11 libraries with the :module:`FindX11` + module. Such dependencies should not need to be explicit. + Applications using X11 APIs themselves should find and link + to X11 libraries explicitly. diff --git a/Help/release/dev/FindOpenSSL-separate-libs.rst b/Help/release/dev/FindOpenSSL-separate-libs.rst new file mode 100644 index 0000000..96e3961 --- /dev/null +++ b/Help/release/dev/FindOpenSSL-separate-libs.rst @@ -0,0 +1,7 @@ +FindOpenSSL-separate-libs +------------------------- + +* The :module:`FindOpenSSL` module now reports ``crypto`` and ``ssl`` + libraries separately in ``OPENSSL_CRYPTO_LIBRARY`` and + ``OPENSSL_SSL_LIBRARY``, respectively, to allow applications to + link to one without the other. diff --git a/Help/release/dev/GNU-4.4-compile-features.rst b/Help/release/dev/GNU-4.4-compile-features.rst new file mode 100644 index 0000000..d5c1356 --- /dev/null +++ b/Help/release/dev/GNU-4.4-compile-features.rst @@ -0,0 +1,5 @@ +GNU-4.4-compile-features +------------------------ + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by GNU 4.4 to 4.6 compilers. diff --git a/Help/release/dev/SolarisStudio-compile-features.rst b/Help/release/dev/SolarisStudio-compile-features.rst new file mode 100644 index 0000000..83110cd --- /dev/null +++ b/Help/release/dev/SolarisStudio-compile-features.rst @@ -0,0 +1,5 @@ +SolarisStudio-compile-features +------------------------------ + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by Oracle SolarisStudio (``SunPro``). diff --git a/Help/release/dev/WCDH-thread_local.rst b/Help/release/dev/WCDH-thread_local.rst new file mode 100644 index 0000000..44516a7 --- /dev/null +++ b/Help/release/dev/WCDH-thread_local.rst @@ -0,0 +1,7 @@ +WriteCompilerDetectionHeader thread_local portability +----------------------------------------------------- + +* The :module:`WriteCompilerDetectionHeader` module learned to + create a define for portability of the cxx_thread_local feature. The define + expands to either the C++11 ``thread_local`` keyword, or a + pre-standardization compiler-specific equivalent, as appropriate. diff --git a/Help/release/dev/WriteCompilerDetectionHeader-multi-file-lang.rst b/Help/release/dev/WriteCompilerDetectionHeader-multi-file-lang.rst new file mode 100644 index 0000000..a8665da --- /dev/null +++ b/Help/release/dev/WriteCompilerDetectionHeader-multi-file-lang.rst @@ -0,0 +1,6 @@ +WriteCompilerDetectionHeader-multi-file +--------------------------------------- + +* The :module:`WriteCompilerDetectionHeader` module learned to create + multiple output files per compiler and per language, instead of creating + one large file. diff --git a/Help/release/dev/Xcode-clang-compile-features.rst b/Help/release/dev/Xcode-clang-compile-features.rst new file mode 100644 index 0000000..d93475f --- /dev/null +++ b/Help/release/dev/Xcode-clang-compile-features.rst @@ -0,0 +1,5 @@ +Xcode-clang-compile-features +---------------------------- + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by Apple Clang (``AppleClang``). diff --git a/Help/release/dev/add-FindGSL.rst b/Help/release/dev/add-FindGSL.rst new file mode 100644 index 0000000..47a0a25 --- /dev/null +++ b/Help/release/dev/add-FindGSL.rst @@ -0,0 +1,5 @@ +add-FindGSL +----------- + +* A :module:`FindGSL` module was introduced to find the + GNU Scientific Library. diff --git a/Help/release/dev/add-FindIntl.rst b/Help/release/dev/add-FindIntl.rst new file mode 100644 index 0000000..ac048c9 --- /dev/null +++ b/Help/release/dev/add-FindIntl.rst @@ -0,0 +1,5 @@ +add-FindIntl +------------ + +* The :module:`FindIntl` module was added to find the Gettext ``libintl`` + library. diff --git a/Help/release/dev/add-FindJsonCpp.rst b/Help/release/dev/add-FindJsonCpp.rst new file mode 100644 index 0000000..5d1cb18 --- /dev/null +++ b/Help/release/dev/add-FindJsonCpp.rst @@ -0,0 +1,5 @@ +add-FindJsonCpp +--------------- + +* A :module:`FindJsonCpp` module was introduced to find the + JsonCpp package. diff --git a/Help/release/dev/add-continue-command.rst b/Help/release/dev/add-continue-command.rst new file mode 100644 index 0000000..4995a8e --- /dev/null +++ b/Help/release/dev/add-continue-command.rst @@ -0,0 +1,6 @@ +add-continue-command +-------------------- + +* A new :command:`continue` command was added that can be called inside loop + contexts to end the current iteration and start the next one at the top of + the loop block. diff --git a/Help/release/dev/add-xz-support.rst b/Help/release/dev/add-xz-support.rst new file mode 100644 index 0000000..9bdf528 --- /dev/null +++ b/Help/release/dev/add-xz-support.rst @@ -0,0 +1,5 @@ +add-xz-support +-------------- + +* The :manual:`cmake(1)` ``-E tar`` command now supports creating + ``.xz``-compressed archives with the ``J`` flag. diff --git a/Help/release/dev/add_javascript_coverage_parser.rst b/Help/release/dev/add_javascript_coverage_parser.rst new file mode 100644 index 0000000..0d068ee --- /dev/null +++ b/Help/release/dev/add_javascript_coverage_parser.rst @@ -0,0 +1,4 @@ +add_javascript_coverage_parser +------------------------------ + +* The :command:`ctest_coverage` learned to support Javascript coverage. diff --git a/Help/release/dev/break-command-strictness.rst b/Help/release/dev/break-command-strictness.rst new file mode 100644 index 0000000..0723774 --- /dev/null +++ b/Help/release/dev/break-command-strictness.rst @@ -0,0 +1,6 @@ +break-command-strictness +------------------------ + +* The :command:`break` command now rejects calls outside of a loop + context or that pass arguments to the command. + See policy :policy:`CMP0055`. diff --git a/Help/release/dev/cached-regex-clear-fixed.rst b/Help/release/dev/cached-regex-clear-fixed.rst new file mode 100644 index 0000000..fbf08cc --- /dev/null +++ b/Help/release/dev/cached-regex-clear-fixed.rst @@ -0,0 +1,5 @@ +cached-regex-clear-fixed +------------------------ + +* Add :variable:`CMAKE_MATCH_COUNT` for the number of matches made in the last + regular expression. diff --git a/Help/release/dev/cmake-E-tar-mtime.rst b/Help/release/dev/cmake-E-tar-mtime.rst new file mode 100644 index 0000000..6496577 --- /dev/null +++ b/Help/release/dev/cmake-E-tar-mtime.rst @@ -0,0 +1,6 @@ +cmake-E-tar-mtime +----------------- + +* The :manual:`cmake(1)` ``-E tar`` command learned a new + ``--mtime=<date>`` option to specify the modification time + recorded in tarball entries. diff --git a/Help/release/dev/console-pool.rst b/Help/release/dev/console-pool.rst new file mode 100644 index 0000000..19c2f19 --- /dev/null +++ b/Help/release/dev/console-pool.rst @@ -0,0 +1,8 @@ +console-pool +------------ + +* The :command:`add_custom_command` and :command:`add_custom_target` + commands learned a new ``USES_TERMINAL`` option to request that + the command be given direct access to the terminal if possible. + The :generator:`Ninja` generator will places such commands in the + ``console`` pool. diff --git a/Help/release/dev/cpack-rpm-component-descriptions.rst b/Help/release/dev/cpack-rpm-component-descriptions.rst new file mode 100644 index 0000000..769a912 --- /dev/null +++ b/Help/release/dev/cpack-rpm-component-descriptions.rst @@ -0,0 +1,7 @@ +cpack-rpm-component-descriptions +-------------------------------- + +* The :module:`CPackRPM` module learned options to set per-component + descriptions and summaries. See the + :variable:`CPACK_RPM_<component>_PACKAGE_DESCRIPTION` and + :variable:`CPACK_RPM_<component>_PACKAGE_SUMMARY` variables. diff --git a/Help/release/dev/cpack-rpm-pre-post-install.rst b/Help/release/dev/cpack-rpm-pre-post-install.rst new file mode 100644 index 0000000..0909d94 --- /dev/null +++ b/Help/release/dev/cpack-rpm-pre-post-install.rst @@ -0,0 +1,12 @@ +cpack-rpm-pre-post-install +-------------------------- + +* The :module:`CPackRPM` module learned options to specify + requirements for pre- and post-install scripts. See the + :variable:`CPACK_RPM_PACKAGE_REQUIRES_PRE` and + :variable:`CPACK_RPM_PACKAGE_REQUIRES_POST` variables. + +* The :module:`CPackRPM` module learned options to specify + requirements for pre- and post-uninstall scripts. See the + :variable:`CPACK_RPM_PACKAGE_REQUIRES_PREUN` and + :variable:`CPACK_RPM_PACKAGE_REQUIRES_POSTUN` variables. diff --git a/Help/release/dev/ctest-delphi-coverage.rst b/Help/release/dev/ctest-delphi-coverage.rst new file mode 100644 index 0000000..efa97c9 --- /dev/null +++ b/Help/release/dev/ctest-delphi-coverage.rst @@ -0,0 +1,4 @@ +ctest-delphi-coverage +--------------------- + +* The :command:`ctest_coverage` learned to support Delphi coverage. diff --git a/Help/release/dev/curl-darwinssl.rst b/Help/release/dev/curl-darwinssl.rst new file mode 100644 index 0000000..3571bd1 --- /dev/null +++ b/Help/release/dev/curl-darwinssl.rst @@ -0,0 +1,9 @@ +curl-darwinssl +-------------- + +* On OS X, commands supporting network communication, such as + :command:`file(DOWNLOAD)`, :command:`file(UPLOAD)`, and + :command:`ctest_submit`, now support SSL/TLS even when CMake + is not built against OpenSSL. The OS X native SSL/TLS + implementation is used by default. OS-configured certificate + authorities will be trusted automatically. diff --git a/Help/release/dev/curl-winssl.rst b/Help/release/dev/curl-winssl.rst new file mode 100644 index 0000000..9a28f4f --- /dev/null +++ b/Help/release/dev/curl-winssl.rst @@ -0,0 +1,9 @@ +curl-winssl +----------- + +* On Windows, commands supporting network communication, such as + :command:`file(DOWNLOAD)`, :command:`file(UPLOAD)`, and + :command:`ctest_submit`, now support SSL/TLS even when CMake + is not built against OpenSSL. The Windows native SSL/TLS + implementation is used by default. OS-configured certificate + authorities will be trusted automatically. diff --git a/Help/release/dev/custom-command-byproducts.rst b/Help/release/dev/custom-command-byproducts.rst new file mode 100644 index 0000000..dc85fdb --- /dev/null +++ b/Help/release/dev/custom-command-byproducts.rst @@ -0,0 +1,7 @@ +custom-command-byproducts +------------------------- + +* The :command:`add_custom_command` and :command:`add_custom_target` + commands learned a new ``BYPRODUCTS`` option to specify files + produced as side effects of the custom commands. These are not + outputs because they do not always have to be newer than inputs. diff --git a/Help/release/dev/file-LOCK-command.rst b/Help/release/dev/file-LOCK-command.rst new file mode 100644 index 0000000..4b11e9e --- /dev/null +++ b/Help/release/dev/file-LOCK-command.rst @@ -0,0 +1,5 @@ +file-LOCK-command +----------------- + +* The :command:`file(LOCK)` subcommand was created to allow CMake + processes to synchronize through file and directory locks. diff --git a/Help/release/dev/find-msmpi.rst b/Help/release/dev/find-msmpi.rst new file mode 100644 index 0000000..6ece5c8 --- /dev/null +++ b/Help/release/dev/find-msmpi.rst @@ -0,0 +1,4 @@ +find-msmpi +---------- + +* The :module:`FindMPI` module learned to find MS-MPI on Windows. diff --git a/Help/release/dev/install-EXPORT-absolute-prefix.rst b/Help/release/dev/install-EXPORT-absolute-prefix.rst new file mode 100644 index 0000000..1b2a01c --- /dev/null +++ b/Help/release/dev/install-EXPORT-absolute-prefix.rst @@ -0,0 +1,9 @@ +install-EXPORT-absolute-prefix +------------------------------ + +* The :command:`install(EXPORT)` command now works with an absolute + ``DESTINATION`` even if targets in the export set are installed + with a destination or usage requirements specified relative to the + install prefix. The value of the :variable:`CMAKE_INSTALL_PREFIX` + variable is hard-coded into the installed export file as the base + for relative references. diff --git a/Help/release/dev/record-GNU-5-features.rst b/Help/release/dev/record-GNU-5-features.rst new file mode 100644 index 0000000..0da9e75 --- /dev/null +++ b/Help/release/dev/record-GNU-5-features.rst @@ -0,0 +1,5 @@ +record-GNU-5-features +--------------------- + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by GNU compiler version 5.0. diff --git a/Help/release/dev/try_compile-link-flags.rst b/Help/release/dev/try_compile-link-flags.rst new file mode 100644 index 0000000..d995e0b --- /dev/null +++ b/Help/release/dev/try_compile-link-flags.rst @@ -0,0 +1,6 @@ +try_compile-link-flags +---------------------- + +* The :command:`try_compile` command source file signature now honors + link flags (e.g. :variable:`CMAKE_EXE_LINKER_FLAGS`) in the generated + test project. See policy :policy:`CMP0056`. diff --git a/Help/release/dev/unsupported-compilers.rst b/Help/release/dev/unsupported-compilers.rst new file mode 100644 index 0000000..1f3e8c1 --- /dev/null +++ b/Help/release/dev/unsupported-compilers.rst @@ -0,0 +1,22 @@ +unsupported-compilers +--------------------- + +* The implementation of CMake relies on some C++ compiler features which are + not supported by some older compilers. As a result, those old compilers + can no longer be used to build CMake itself. CMake continues to be able to + generate Makefiles and project files for users of those old compilers + however. The compilers known to no longer be capable of building CMake + are: + + * MSVC 6 and 7.0 - superceded by VisualStudio 7.1 and newer compilers. + * GCC 2.95 - superceded by GCC 3 and newer compilers. + * Borland compilers - superceded by other Windows compilers. + * Compaq compilers - superceded by other compilers. + * Comeau compilers - superceded by other compilers. + * SGI compilers - IRIX was dropped as a host platform. + + When building using SolarisStudio 12, the default ``libCStd`` standard + library is not sufficient to build CMake. The SolarisStudio distribution + supports compiler options to use ``STLPort4`` or ``libstdc++``. An + appropriate option to select the standard library is now added + automatically when building CMake with SolarisStudio compilers. diff --git a/Help/release/dev/vs-nsight-tegra-min-api.rst b/Help/release/dev/vs-nsight-tegra-min-api.rst new file mode 100644 index 0000000..f8fa056 --- /dev/null +++ b/Help/release/dev/vs-nsight-tegra-min-api.rst @@ -0,0 +1,5 @@ +vs-nsight-tegra-min-api +----------------------- + +* A :prop_tgt:`ANDROID_API_MIN` target property was introduced to + specify the minimum version to be targeted by the toolchain. diff --git a/Help/release/dev/windows-utf-8.rst b/Help/release/dev/windows-utf-8.rst new file mode 100644 index 0000000..64cd616 --- /dev/null +++ b/Help/release/dev/windows-utf-8.rst @@ -0,0 +1,22 @@ +windows-utf-8 +------------- + +* On Windows, CMake learned to support international characters. + This allows use of characters from multiple (spoken) languages + in CMake code, paths to source files, configured files such as + ``.h.in`` files, and other files read and written by CMake. + Because CMake interoperates with many other tools, there may + still be some limitations when using certain international + characters. + + Files written in the :manual:`cmake-language(7)`, such as + ``CMakeLists.txt`` or ``*.cmake`` files, are expected to be + encoded as UTF-8. If files are already ASCII, they will be + compatible. If files were in a different encoding, including + Latin 1, they will need to be converted. + + The Visual Studio generators now write solution and project + files in UTF-8 instead of Windows-1252. Windows-1252 supported + Latin 1 languages such as those found in North and South America + and Western Europe. With UTF-8, additional languages are now + supported. diff --git a/Help/variable/CMAKE_ANDROID_API_MIN.rst b/Help/variable/CMAKE_ANDROID_API_MIN.rst new file mode 100644 index 0000000..0246c75 --- /dev/null +++ b/Help/variable/CMAKE_ANDROID_API_MIN.rst @@ -0,0 +1,5 @@ +CMAKE_ANDROID_API_MIN +--------------------- + +Default value for the :prop_tgt:`ANDROID_API_MIN` target property. +See that target property for additional information. diff --git a/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst new file mode 100644 index 0000000..bd1a30f --- /dev/null +++ b/Help/variable/CMAKE_FIND_PACKAGE_NAME.rst @@ -0,0 +1,6 @@ +CMAKE_FIND_PACKAGE_NAME +----------------------- + +Defined by the :command:`find_package` command while loading +a find module to record the caller-specified package name. +See command documentation for details. diff --git a/Help/variable/CMAKE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_INSTALL_PREFIX.rst index 72c8d41..ee9b615 100644 --- a/Help/variable/CMAKE_INSTALL_PREFIX.rst +++ b/Help/variable/CMAKE_INSTALL_PREFIX.rst @@ -27,3 +27,8 @@ which cannot be prepended with some other prefix. The installation prefix is also added to CMAKE_SYSTEM_PREFIX_PATH so that find_package, find_program, find_library, find_path, and find_file will search the prefix for other software. + +.. note:: + + Use the :module:`GNUInstallDirs` module to provide GNU-style + options for the layout of directories within the installation. diff --git a/Help/variable/CMAKE_MATCH_COUNT.rst b/Help/variable/CMAKE_MATCH_COUNT.rst new file mode 100644 index 0000000..8b1c036 --- /dev/null +++ b/Help/variable/CMAKE_MATCH_COUNT.rst @@ -0,0 +1,8 @@ +CMAKE_MATCH_COUNT +----------------- + +The number of matches with the last regular expression. + +When a regular expression match is used, CMake fills in ``CMAKE_MATCH_<n>`` +variables with the match contents. The ``CMAKE_MATCH_COUNT`` variable holds +the number of match expressions when these are filled. diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst index b563aea..a83c807 100644 --- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst +++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst @@ -9,6 +9,8 @@ warn by default: policy :policy:`CMP0025`. * ``CMAKE_POLICY_WARNING_CMP0047`` controls the warning for policy :policy:`CMP0047`. +* ``CMAKE_POLICY_WARNING_CMP0056`` controls the warning for + policy :policy:`CMP0056`. This variable should not be set by a project in CMake code. Project developers running CMake may set this variable in their cache to diff --git a/Help/variable/MINGW.rst b/Help/variable/MINGW.rst new file mode 100644 index 0000000..521d417 --- /dev/null +++ b/Help/variable/MINGW.rst @@ -0,0 +1,6 @@ +MINGW +----- + +True when using MinGW + +Set to true when the compiler is some version of MinGW. diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 0221cbd..09ae509 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -18,7 +18,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif #ifdef __QNXNTO__ -char const* qnxnto = "INFO" ":" "qnxnto"; +char const* qnxnto = "INFO" ":" "qnxnto[]"; #endif @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 9ece26d..cc3ab49 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -17,7 +17,7 @@ char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; #endif #ifdef __QNXNTO__ -char const* qnxnto = "INFO" ":" "qnxnto"; +char const* qnxnto = "INFO" ":" "qnxnto[]"; #endif @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@ diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake index 0ab3af6..85c8662 100644 --- a/Modules/CMakeDetermineCompiler.cmake +++ b/Modules/CMakeDetermineCompiler.cmake @@ -71,16 +71,31 @@ macro(_cmake_find_compiler lang) unset(_languages) # Look for a make tool provided by Xcode - if(CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND" AND CMAKE_HOST_APPLE) - foreach(comp ${CMAKE_${lang}_COMPILER_LIST}) - execute_process(COMMAND xcrun --find ${comp} + if(CMAKE_HOST_APPLE) + macro(_query_xcrun compiler_name result_var_keyword result_var) + if(NOT "x${result_var_keyword}" STREQUAL "xRESULT_VAR") + message(FATAL_ERROR "Bad arguments to macro") + endif() + execute_process(COMMAND xcrun --find ${compiler_name} OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_VARIABLE _xcrun_err) - if(_xcrun_out) - set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${_xcrun_out}") - break() - endif() - endforeach() + set("${result_var}" "${_xcrun_out}") + endmacro() + + set(xcrun_result) + if (CMAKE_${lang}_COMPILER MATCHES "^/usr/bin/(.+)$") + _query_xcrun("${CMAKE_MATCH_1}" RESULT_VAR xcrun_result) + elseif (CMAKE_${lang}_COMPILER STREQUAL "CMAKE_${lang}_COMPILER-NOTFOUND") + foreach(comp ${CMAKE_${lang}_COMPILER_LIST}) + _query_xcrun("${comp}" RESULT_VAR xcrun_result) + if(xcrun_result) + break() + endif() + endforeach() + endif() + if (xcrun_result) + set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${xcrun_result}") + endif() endif() endmacro() diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index 4bc42dd..344ae47 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -26,7 +26,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin") set(CMAKE_FLAGS ) if(DEFINED CMAKE_${lang}_VERBOSE_FLAG) - set(CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}") + set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}") endif() if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") # Avoid adding our own platform standard libraries for compilers diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 9ce99f9..dfed00e 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -270,11 +270,6 @@ Id flags: ${testflags} else() set(id_sdkroot "") endif() - if(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY) - set(id_code_sign_identity "CODE_SIGN_IDENTITY = \"${CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY}\";") - else() - set(id_code_sign_identity "") - endif() if(NOT ${XCODE_VERSION} VERSION_LESS 3) set(v 3) set(ext xcodeproj) @@ -307,7 +302,7 @@ Id flags: ${testflags} # ... # /path/to/cc ...CompilerId${lang}/... # to extract the compiler front-end for the language. - if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerId${lang}(/CompilerId${lang}.xctest)?/(\\./)?CompilerId${lang}[ \t\n\\\"]") + if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerId${lang}/(\\./)?(CompilerId${lang}.xctest/)?CompilerId${lang}[ \t\n\\\"]") set(_comp "${CMAKE_MATCH_2}") if(EXISTS "${_comp}") set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE) @@ -445,7 +440,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) string(REGEX REPLACE "^0+([0-9])" "\\1" SIMULATE_VERSION "${CMAKE_MATCH_1}") string(REGEX REPLACE "\\.0+([0-9])" ".\\1" SIMULATE_VERSION "${SIMULATE_VERSION}") endif() - if("${info}" MATCHES "INFO:qnxnto") + if("${info}" MATCHES "INFO:qnxnto\\[\\]") set(COMPILER_QNXNTO 1) endif() endforeach() diff --git a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake index 92b0d1d..064e650 100644 --- a/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake +++ b/Modules/CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake @@ -26,11 +26,18 @@ macro(_DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _resultIncludeDirs _resultDefines if (${_lang} STREQUAL "c++") set(_compilerExecutable "${CMAKE_CXX_COMPILER}") set(_arg1 "${CMAKE_CXX_COMPILER_ARG1}") + + if (CMAKE_CXX_FLAGS MATCHES "(-stdlib=[^ ]+)") + set(_stdlib "${CMAKE_MATCH_1}") + endif () + if (CMAKE_CXX_FLAGS MATCHES "(-std=[^ ]+)") + set(_stdver "${CMAKE_MATCH_1}") + endif () else () set(_compilerExecutable "${CMAKE_C_COMPILER}") set(_arg1 "${CMAKE_C_COMPILER_ARG1}") endif () - execute_process(COMMAND ${_compilerExecutable} ${_arg1} -v -E -x ${_lang} -dD dummy + execute_process(COMMAND ${_compilerExecutable} ${_arg1} ${_stdver} ${_stdlib} -v -E -x ${_lang} -dD dummy WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles ERROR_VARIABLE _gccOutput OUTPUT_VARIABLE _gccStdout ) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index 50cb972..376a6dc 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -30,11 +30,11 @@ # License text for the above reference.) # if it's the MS C/CXX compiler, search for link -if(CMAKE_C_SIMULATE_ID STREQUAL "MSVC" - OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" - OR CMAKE_Fortran_SIMULATE_ID STREQUAL "MSVC" - OR CMAKE_C_COMPILER_ID STREQUAL "MSVC" - OR CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" +if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_Fortran_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR (CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) diff --git a/Modules/CMakeFindPackageMode.cmake b/Modules/CMakeFindPackageMode.cmake index fc3058d..26731dc 100644 --- a/Modules/CMakeFindPackageMode.cmake +++ b/Modules/CMakeFindPackageMode.cmake @@ -102,15 +102,18 @@ if(UNIX) # guess Debian multiarch if it has not been set: if(EXISTS /etc/debian_version) - if(NOT CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ) + if(NOT CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE ) file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* ) foreach(file ${filesInLib}) if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}") - set(CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ${file}) + set(CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE ${file}) break() endif() endforeach() endif() + if(NOT CMAKE_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_${LANGUAGE}_LIBRARY_ARCHITECTURE}) + endif() endif() endif() diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake index c3ca767..2f35cf4 100644 --- a/Modules/CMakeNinjaFindMake.cmake +++ b/Modules/CMakeNinjaFindMake.cmake @@ -12,6 +12,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_program(CMAKE_MAKE_PROGRAM ninja +find_program(CMAKE_MAKE_PROGRAM + NAMES ninja-build ninja DOC "Program used to build from build.ninja files.") mark_as_advanced(CMAKE_MAKE_PROGRAM) diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index bfcf455..fcc13da 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -66,7 +66,8 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj set(log "${log} arg [${arg}] ==> dir [${dir}]\n") elseif("${arg}" MATCHES "^-l([^:].*)$") # Unix library. - list(APPEND implicit_libs_tmp ${CMAKE_MATCH_1}) + set(lib "${CMAKE_MATCH_1}") + list(APPEND implicit_libs_tmp ${lib}) set(log "${log} arg [${arg}] ==> lib [${lib}]\n") elseif("${arg}" MATCHES "^(.:)?[/\\].*\\.a$") # Unix library full path. diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake index d8293c0..d26a0b3 100644 --- a/Modules/CPackBundle.cmake +++ b/Modules/CPackBundle.cmake @@ -33,6 +33,31 @@ # Path to a startup script. This is a path to an executable or script that # will be run whenever an end-user double-clicks the generated bundle in the # OSX Finder. Optional. +# +# .. variable:: CPACK_BUNDLE_APPLE_CERT_APP +# +# The name of your Apple supplied code signing certificate for the application. +# The name usually takes the form "Developer ID Application: [Name]" or +# "3rd Party Mac Developer Application: [Name]". If this variable is not set +# the application will not be signed. +# +# .. variable:: CPACK_BUNDLE_APPLE_ENTITLEMENTS +# +# The name of the plist file that contains your apple entitlements for sandboxing +# your application. This file is required for submission to the Mac App Store. +# +# .. variable:: CPACK_BUNDLE_APPLE_CODESIGN_FILES +# +# A list of additional files that you wish to be signed. You do not need to +# list the main application folder, or the main executable. You should +# list any frameworks and plugins that are included in your app bundle. +# +# .. variable:: CPACK_COMMAND_CODESIGN +# +# Path to the codesign(1) command used to sign applications with an +# Apple cert. This variable can be used to override the automatically +# detected command (or specify its location if the auto-detection fails +# to find it.) #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 5524a3f..573e5aa 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -110,7 +110,7 @@ # # DESCRIPTION is an extended description of the component, used in # graphical installers to give the user additional information about the -# component. Descriptions can span multiple lines using "\n" as the +# component. Descriptions can span multiple lines using ``\n`` as the # line separator. Typically, these descriptions should be no more than # a few lines long. # @@ -185,7 +185,7 @@ # DESCRIPTION is an extended description of the component group, used in # graphical installers to give the user additional information about the # components within that group. Descriptions can span multiple lines -# using "\n" as the line separator. Typically, these descriptions +# using ``\n`` as the line separator. Typically, these descriptions # should be no more than a few lines long. # # PARENT_GROUP, if supplied, names the parent group of this group. diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index 4b8dc1e..e5b7601 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -14,19 +14,19 @@ # Overview # ^^^^^^^^ # -# CPack ``IFW`` generator helps you create online and offline +# CPack ``IFW`` generator helps you to create online and offline # binary cross-platform installers with a graphical user interface. # -# CPack IFW generator prepare project installation and generate configuration +# CPack IFW generator prepares project installation and generates configuration # and meta information for QtIFW_ tools. # # The QtIFW_ provides a set of tools and utilities to create # installers for the supported desktop Qt platforms: Linux, Microsoft Windows, # and Mac OS X. # -# To use CPack ``IFW`` generator you must also install QtIFW_. -# If you are not using the default path for the installation, please set -# the path to the variable ``QTIFWDIR``. +# You should also install QtIFW_ to use CPack ``IFW`` generator. +# If you don't use a default path for the installation, please set +# the used path in the variable ``QTIFWDIR``. # # Variables # ^^^^^^^^^ @@ -61,7 +61,7 @@ # # .. variable:: CPACK_IFW_PACKAGE_LOGO # -# Filename for a logo used as QWizard::LogoPixmap. +# Filename for a logo is used as QWizard::LogoPixmap. # # .. variable:: CPACK_IFW_TARGET_DIRECTORY # @@ -96,7 +96,7 @@ # # If this is ``ON`` all components will be downloaded. # By default is ``OFF`` or used value -# from :variable:`CPACK_DOWNLOAD_ALL` if set +# from ``CPACK_DOWNLOAD_ALL`` if set # # Components # """""""""" @@ -149,12 +149,12 @@ # This command should be called after cpack_add_component command. # # ``COMMON`` if set, then the component will be packaged and installed as part -# of a group to which he belongs. +# of a group to which it belongs. # # ``VERSION`` is version of component. # By default used :variable:`CPACK_PACKAGE_VERSION`. # -# ``SCRIPT`` is relative or absolute path to operations script +# ``SCRIPT`` is a relative or absolute path to operations script # for this component. # # ``NAME`` is used to create domain-like identification for this component. @@ -190,7 +190,7 @@ # ``NAME`` is used to create domain-like identification for this component group. # By default used origin component group name. # -# ``SCRIPT`` is relative or absolute path to operations script +# ``SCRIPT`` is a relative or absolute path to operations script # for this component group. # # ``PRIORITY`` is priority of the component group in the tree. @@ -255,7 +255,7 @@ # Online installer # ^^^^^^^^^^^^^^^^ # -# By defaul CPack IFW generator make offline installer. This means that all +# By default CPack IFW generator makes offline installer. This means that all # components will be packaged into a binary file. # # To make a component downloaded, you must set the ``DOWNLOADED`` option in @@ -267,7 +267,7 @@ # You also can use command :command:`cpack_ifw_add_repository` and # variable :variable:`CPACK_IFW_DOWNLOAD_ALL` for more specific configuration. # -# CPack IFW generator create "repository" dir in current binary dir. You +# CPack IFW generator creates "repository" dir in current binary dir. You # would copy content of this dir to specified ``site`` (``url``). # # See Also diff --git a/Modules/CPackNSIS.cmake b/Modules/CPackNSIS.cmake index 9d23ec0..4b2e0eb 100644 --- a/Modules/CPackNSIS.cmake +++ b/Modules/CPackNSIS.cmake @@ -114,8 +114,8 @@ # installation prefix. Like:: # # set(CPACK_NSIS_MENU_LINKS -# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help" -# "http://www.cmake.org" "CMake Web Site") +# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" +# "CMake Help" "http://www.cmake.org" "CMake Web Site") # #============================================================================= diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index 56d9b66..d2cb2ee 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -678,14 +678,14 @@ foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLIC endif() endif() + # Do not forget to unset previously set header (from previous component) + unset(TMP_RPM_${_RPM_SPEC_HEADER}) # Treat the RPM Spec keyword iff it has been properly defined if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) # Transform NAME --> Name e.g. PROVIDES --> Provides # The Upper-case first letter and lowercase tail is the # appropriate value required in the final RPM spec file. - string(LENGTH ${_RPM_SPEC_HEADER} _PACKAGE_HEADER_STRLENGTH) - math(EXPR _PACKAGE_HEADER_STRLENGTH "${_PACKAGE_HEADER_STRLENGTH} - 1") - string(SUBSTRING ${_RPM_SPEC_HEADER} 1 ${_PACKAGE_HEADER_STRLENGTH} _PACKAGE_HEADER_TAIL) + string(SUBSTRING ${_RPM_SPEC_HEADER} 1 -1 _PACKAGE_HEADER_TAIL) string(TOLOWER "${_PACKAGE_HEADER_TAIL}" _PACKAGE_HEADER_TAIL) string(SUBSTRING ${_RPM_SPEC_HEADER} 0 1 _PACKAGE_HEADER_NAME) set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}${_PACKAGE_HEADER_TAIL}") @@ -700,9 +700,7 @@ foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLIC message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") endif() set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") - else() - # Do not forget to unset previously set header (from previous component) - unset(TMP_RPM_${_RPM_SPEC_HEADER}) + unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) endif() endforeach() diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake new file mode 100644 index 0000000..f6616e0 --- /dev/null +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -0,0 +1,138 @@ +#.rst: +# CTestCoverageCollectGCOV +# ------------------------ +# +# This module provides the function ``ctest_coverage_collect_gcov``. +# The function will run gcov on the .gcda files in a binary tree and then +# package all of the .gcov files into a tar file with a data.json that +# contains the source and build directories for CDash to use in parsing +# the coverage data. In addtion the Labels.json files for targets that +# have coverage information are also put in the tar file for CDash to +# asign the correct labels. This file can be sent to a CDash server for +# display with the +# :command:`ctest_submit(CDASH_UPLOAD)` command. +# +# .. command:: cdash_coverage_collect_gcov +# +# :: +# +# ctest_coverage_collect_gcov(TARBALL <tarfile> +# [SOURCE <source_dir>][BUILD <build_dir>] +# [GCOV_COMMAND <gcov_command>] +# ) +# +# Run gcov and package a tar file for CDash. The options are: +# +# ``TARBALL <tarfile>`` +# Specify the location of the ``.tar`` file to be created for later +# upload to CDash. Relative paths will be interpreted with respect +# to the top-level build directory. +# +# ``SOURCE <source_dir>`` +# Specify the top-level source directory for the build. +# Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`. +# +# ``BUILD <build_dir>`` +# Specify the top-level build directory for the build. +# Default is the value of :variable:`CTEST_BINARY_DIRECTORY`. +# +# ``GCOV_COMMAND <gcov_command>`` +# Specify the full path to the ``gcov`` command on the machine. +# Default is the value of :variable:`CTEST_COVERAGE_COMMAND`. + +#============================================================================= +# Copyright 2014-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) +include(CMakeParseArguments) +function(ctest_coverage_collect_gcov) + set(options "") + set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND) + set(multiValueArgs "") + cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}" + "${multiValueArgs}" "" ${ARGN} ) + if(NOT DEFINED GCOV_TARBALL) + message(FATAL_ERROR + "TARBALL must be specified. for ctest_coverage_collect_gcov") + endif() + if(NOT DEFINED GCOV_SOURCE) + set(source_dir "${CTEST_SOURCE_DIRECTORY}") + else() + set(source_dir "${GCOV_SOURCE}") + endif() + if(NOT DEFINED GCOV_BUILD) + set(binary_dir "${CTEST_BINARY_DIRECTORY}") + else() + set(binary_dir "${GCOV_BUILD}") + endif() + if(NOT DEFINED GCOV_GCOV_COMMAND) + set(gcov_command "${CTEST_COVERAGE_COMMAND}") + else() + set(gcov_command "${GCOV_GCOV_COMMAND}") + endif() + # run gcov on each gcda file in the binary tree + set(gcda_files) + set(label_files) + # look for gcda files in the target directories + # could do a glob from the top of the binary tree but + # this will be faster and only look where the files will be + file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs) + foreach(target_dir ${target_dirs}) + file(GLOB_RECURSE gfiles RELATIVE ${binary_dir} "${target_dir}/*.gcda") + list(LENGTH gfiles len) + # if we have gcda files then also grab the labels file for that target + if(${len} GREATER 0) + file(GLOB_RECURSE lfiles RELATIVE ${binary_dir} + "${target_dir}/Labels.json") + list(APPEND gcda_files ${gfiles}) + list(APPEND label_files ${lfiles}) + endif() + endforeach() + # return early if no coverage files were found + list(LENGTH gcda_files len) + if(len EQUAL 0) + message("ctest_coverage_collect_gcov: No .gcda files found, " + "ignoring coverage request.") + return() + endif() + # setup the dir for the coverage files + set(coverage_dir "${binary_dir}/Testing/CoverageInfo") + file(MAKE_DIRECTORY "${coverage_dir}") + # call gcov on each .gcda file + foreach (gcda_file ${gcda_files}) + # get the directory of the gcda file + get_filename_component(gcda_file ${binary_dir}/${gcda_file} ABSOLUTE) + get_filename_component(gcov_dir ${gcda_file} DIRECTORY) + # run gcov, this will produce the .gcov file in the current + # working directory + execute_process(COMMAND + ${gcov_command} -b -o ${gcov_dir} ${gcda_file} + OUTPUT_VARIABLE out + WORKING_DIRECTORY ${coverage_dir}) + endforeach() + # create json file with project information + file(WRITE ${coverage_dir}/data.json + "{ + \"Source\": \"${source_dir}\", + \"Binary\": \"${binary_dir}\" +}") + # collect the gcov files + set(gcov_files) + file(GLOB_RECURSE gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov") + # tar up the coverage info with the same date so that the md5 + # sum will be the same for the tar file independent of file time + # stamps + execute_process(COMMAND + ${CMAKE_COMMAND} -E tar cvfj ${GCOV_TARBALL} + "--mtime=1970-01-01 0:0:0 UTC" ${gcov_files} + ${coverage_dir}/data.json ${label_files} + WORKING_DIRECTORY ${binary_dir}) +endfunction() diff --git a/Modules/CheckStructHasMember.cmake b/Modules/CheckStructHasMember.cmake index c8949cf..de31d2c 100644 --- a/Modules/CheckStructHasMember.cmake +++ b/Modules/CheckStructHasMember.cmake @@ -69,8 +69,7 @@ macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT) ${_INCLUDE_FILES} int main() { - ${_STRUCT}* tmp; - (void) tmp->${_MEMBER}; + (void)((${_STRUCT} *)0)->${_MEMBER}; return 0; } ") diff --git a/Modules/Compiler/AppleClang-C-FeatureTests.cmake b/Modules/Compiler/AppleClang-C-FeatureTests.cmake new file mode 100644 index 0000000..6f3d6a7 --- /dev/null +++ b/Modules/Compiler/AppleClang-C-FeatureTests.cmake @@ -0,0 +1,11 @@ + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400") + +set(AppleClang_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L") +set(_cmake_feature_test_c_static_assert "${AppleClang_C11}") +set(AppleClang_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L") +set(_cmake_feature_test_c_restrict "${AppleClang_C99}") +set(_cmake_feature_test_c_variadic_macros "${AppleClang_C99}") + +set(AppleClang_C90 "${_cmake_oldestSupported} && !defined(__STDC_VERSION__)") +set(_cmake_feature_test_c_function_prototypes "${AppleClang_C90}") diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake index 44070b8..16f420f 100644 --- a/Modules/Compiler/AppleClang-C.cmake +++ b/Modules/Compiler/AppleClang-C.cmake @@ -1 +1,32 @@ -include(Compiler/Clang-C) +include(Compiler/Clang) +__compiler_clang(C) + +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") + + set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") + set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") + + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") +endif() + +set(CMAKE_C_STANDARD_DEFAULT 99) + +macro(cmake_record_c_compile_features) + macro(_get_appleclang_features std_version list) + record_compiler_features(C "${std_version}" ${list}) + endmacro() + + set(_result 0) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.0) + _get_appleclang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) + endif() + endif() +endmacro() diff --git a/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake new file mode 100644 index 0000000..f67082c --- /dev/null +++ b/Modules/Compiler/AppleClang-CXX-FeatureTests.cmake @@ -0,0 +1,52 @@ + +# No known reference for AppleClang versions. +# Generic reference: http://clang.llvm.org/cxx_status.html +# http://clang.llvm.org/docs/LanguageExtensions.html + +# Note: CXX compiler in Xcode 4.3 does not set __apple_build_version__ and so is +# not recognized as AppleClang. +# Xcode_43 - Apple clang version 3.1 (tags/Apple/clang-318.0.61) (based on LLVM 3.1svn) +# Xcode_44 - Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn) +# Xcode_45 - Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) +# Xcode_46 - Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) +# Xcode_50 - Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) +# Xcode_51 - Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn) +# Xcode_60 - Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn) +# Xcode_61 - Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) + +# There is some non-correspondance. __has_feature(cxx_user_literals) is +# false for AppleClang 4.0 and 4.1, although it is reported as +# supported in the reference link for Clang 3.1. The compiler does not pass +# the CompileFeatures/cxx_user_literals.cpp test. +# cxx_attributes is listed as not supported until Clang 3.3. It works without +# warning with AppleClang 5.0, but issues a gcc-compat warning for +# AppleClang 4.0-4.2. +# cxx_alignof and cxx_alignas tests work for early AppleClang versions, though +# they are listed as supported for Clang 3.3 and later. + +set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 400") + +include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake") + +set(AppleClang51_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 501 && __cplusplus > 201103L") +# http://llvm.org/bugs/show_bug.cgi?id=19242 +set(_cmake_feature_test_cxx_attribute_deprecated "${AppleClang51_CXX14}") +# http://llvm.org/bugs/show_bug.cgi?id=19698 +set(_cmake_feature_test_cxx_decltype_auto "${AppleClang51_CXX14}") +set(_cmake_feature_test_cxx_digit_separators "${AppleClang51_CXX14}") +# http://llvm.org/bugs/show_bug.cgi?id=19674 +set(_cmake_feature_test_cxx_generic_lambdas "${AppleClang51_CXX14}") + +set(AppleClang40_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_enum_forward_declarations "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_sizeof_member "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_extended_friend_declarations "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_extern_templates "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_func_identifier "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_inline_namespaces "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_long_long_type "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_right_angle_brackets "${AppleClang40_CXX11}") +set(_cmake_feature_test_cxx_variadic_macros "${AppleClang40_CXX11}") + +set(AppleClang_CXX98 "${_cmake_oldestSupported} && __cplusplus >= 199711L") +set(_cmake_feature_test_cxx_template_template_parameters "${AppleClang_CXX98}") diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake index 0372e18..978c382 100644 --- a/Modules/Compiler/AppleClang-CXX.cmake +++ b/Modules/Compiler/AppleClang-CXX.cmake @@ -1,6 +1,42 @@ include(Compiler/Clang) __compiler_clang(CXX) -if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") +if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) + set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") + set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") + + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11") +endif() + +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) + # AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") +endif() + +set(CMAKE_CXX_STANDARD_DEFAULT 98) + +macro(cmake_record_cxx_compile_features) + macro(_get_appleclang_features std_version list) + record_compiler_features(CXX "${std_version}" ${list}) + endmacro() + + set(_result 0) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) + set(_result 0) + if(CMAKE_CXX14_STANDARD_COMPILE_OPTION) + _get_appleclang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) + endif() + if (_result EQUAL 0) + _get_appleclang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) + endif() + endif() +endmacro() diff --git a/Modules/Compiler/Clang-C-FeatureTests.cmake b/Modules/Compiler/Clang-C-FeatureTests.cmake index 4a72e87..2d8673d 100644 --- a/Modules/Compiler/Clang-C-FeatureTests.cmake +++ b/Modules/Compiler/Clang-C-FeatureTests.cmake @@ -1,9 +1,9 @@ set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304") -set(Clang_C11 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 201112L") +set(Clang_C11 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L") set(_cmake_feature_test_c_static_assert "${Clang_C11}") -set(Clang_C99 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 199901L") +set(Clang_C99 "${_cmake_oldestSupported} && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L") set(_cmake_feature_test_c_restrict "${Clang_C99}") set(_cmake_feature_test_c_variadic_macros "${Clang_C99}") diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake index 05d3c0b..548d0a5 100644 --- a/Modules/Compiler/Clang-C.cmake +++ b/Modules/Compiler/Clang-C.cmake @@ -6,7 +6,7 @@ if(WIN32 OR (APPLE AND NOT appleClangPolicy STREQUAL NEW)) return() endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") @@ -17,22 +17,25 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") endif() -set(CMAKE_C_STANDARD_DEFAULT 90) +if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) + set(CMAKE_C_STANDARD_DEFAULT 11) +elseif(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) + set(CMAKE_C_STANDARD_DEFAULT 99) +endif() macro(cmake_record_c_compile_features) macro(_get_clang_features std_version list) - record_compiler_features(C "-std=${std_version}" ${list}) + record_compiler_features(C "${std_version}" ${list}) endmacro() - if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) - _get_clang_features(c11 CMAKE_C11_COMPILE_FEATURES) + set(_result 0) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) + _get_clang_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) if (_result EQUAL 0) - _get_clang_features(c99 CMAKE_C99_COMPILE_FEATURES) + _get_clang_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_clang_features(c90 CMAKE_C90_COMPILE_FEATURES) + _get_clang_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/Clang-CXX-FeatureTests.cmake b/Modules/Compiler/Clang-CXX-FeatureTests.cmake index 4c532fb..df2e1a8 100644 --- a/Modules/Compiler/Clang-CXX-FeatureTests.cmake +++ b/Modules/Compiler/Clang-CXX-FeatureTests.cmake @@ -2,61 +2,9 @@ # Reference: http://clang.llvm.org/cxx_status.html # http://clang.llvm.org/docs/LanguageExtensions.html -set(testable_features - cxx_alias_templates - cxx_alignas - cxx_attributes - cxx_auto_type - cxx_binary_literals - cxx_constexpr - cxx_contextual_conversions - cxx_decltype - cxx_decltype_incomplete_return_types - cxx_default_function_template_args - cxx_defaulted_functions - cxx_delegating_constructors - cxx_deleted_functions - cxx_explicit_conversions - cxx_generalized_initializers - cxx_inheriting_constructors - cxx_lambdas - cxx_local_type_template_args - cxx_noexcept - cxx_nonstatic_member_init - cxx_nullptr - cxx_range_for - cxx_raw_string_literals - cxx_reference_qualified_functions - cxx_relaxed_constexpr - cxx_return_type_deduction - cxx_rvalue_references - cxx_static_assert - cxx_strong_enums - cxx_thread_local - cxx_unicode_literals - cxx_unrestricted_unions - cxx_user_literals - cxx_variable_templates - cxx_variadic_templates -) - set(_cmake_oldestSupported "((__clang_major__ * 100) + __clang_minor__) >= 304") -foreach(feature ${testable_features}) - set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})") -endforeach() - -unset(testable_features) - -set(_cmake_feature_test_cxx_aggregate_default_initializers "${_cmake_oldestSupported} && __has_feature(cxx_aggregate_nsdmi)") - -set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)") -set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)") -set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") -set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") -set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)") -set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)") -set(_cmake_feature_test_cxx_lambda_init_captures "${_cmake_oldestSupported} && __has_feature(cxx_init_captures)") +include("${CMAKE_CURRENT_LIST_DIR}/Clang-CXX-TestableFeatures.cmake") set(Clang34_CXX14 "((__clang_major__ * 100) + __clang_minor__) >= 304 && __cplusplus > 201103L") # http://llvm.org/bugs/show_bug.cgi?id=19242 diff --git a/Modules/Compiler/Clang-CXX-TestableFeatures.cmake b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake new file mode 100644 index 0000000..b39475c --- /dev/null +++ b/Modules/Compiler/Clang-CXX-TestableFeatures.cmake @@ -0,0 +1,54 @@ + +set(testable_features + cxx_alias_templates + cxx_alignas + cxx_attributes + cxx_auto_type + cxx_binary_literals + cxx_constexpr + cxx_contextual_conversions + cxx_decltype + cxx_decltype_incomplete_return_types + cxx_default_function_template_args + cxx_defaulted_functions + cxx_delegating_constructors + cxx_deleted_functions + cxx_explicit_conversions + cxx_generalized_initializers + cxx_inheriting_constructors + cxx_lambdas + cxx_local_type_template_args + cxx_noexcept + cxx_nonstatic_member_init + cxx_nullptr + cxx_range_for + cxx_raw_string_literals + cxx_reference_qualified_functions + cxx_relaxed_constexpr + cxx_return_type_deduction + cxx_rvalue_references + cxx_static_assert + cxx_strong_enums + cxx_thread_local + cxx_unicode_literals + cxx_unrestricted_unions + cxx_user_literals + cxx_variable_templates + cxx_variadic_templates +) + +foreach(feature ${testable_features}) + set(_cmake_feature_test_${feature} "${_cmake_oldestSupported} && __has_feature(${feature})") +endforeach() + +unset(testable_features) + +set(_cmake_feature_test_cxx_aggregate_default_initializers "${_cmake_oldestSupported} && __has_feature(cxx_aggregate_nsdmi)") + +set(_cmake_feature_test_cxx_trailing_return_types "${_cmake_oldestSupported} && __has_feature(cxx_trailing_return)") +set(_cmake_feature_test_cxx_alignof "${_cmake_oldestSupported} && __has_feature(cxx_alignas)") +set(_cmake_feature_test_cxx_final "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_override "${_cmake_oldestSupported} && __has_feature(cxx_override_control)") +set(_cmake_feature_test_cxx_uniform_initialization "${_cmake_oldestSupported} && __has_feature(cxx_generalized_initializers)") +set(_cmake_feature_test_cxx_defaulted_move_initializers "${_cmake_oldestSupported} && __has_feature(cxx_defaulted_functions)") +set(_cmake_feature_test_cxx_lambda_init_captures "${_cmake_oldestSupported} && __has_feature(cxx_init_captures)") diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 5dd7b4a..e07eace 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -1,7 +1,7 @@ include(Compiler/Clang) __compiler_clang(CXX) -if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") +if(NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() @@ -35,18 +35,17 @@ set(CMAKE_CXX_STANDARD_DEFAULT 98) macro(cmake_record_cxx_compile_features) macro(_get_clang_features std_version list) - record_compiler_features(CXX "-std=${std_version}" ${list}) + record_compiler_features(CXX "${std_version}" ${list}) endmacro() + set(_result 0) if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) - _get_clang_features(c++1y CMAKE_CXX14_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) if (_result EQUAL 0) - _get_clang_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_clang_features(c++98 CMAKE_CXX98_COMPILE_FEATURES) + _get_clang_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index eeba119..701089c 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -18,8 +18,8 @@ if(__COMPILER_CLANG) endif() set(__COMPILER_CLANG 1) -if(CMAKE_C_SIMULATE_ID STREQUAL "MSVC" - OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") +if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") macro(__compiler_clang lang) endmacro() else() diff --git a/Modules/Compiler/GNU-C-FeatureTests.cmake b/Modules/Compiler/GNU-C-FeatureTests.cmake index dc1695c..d8e456c 100644 --- a/Modules/Compiler/GNU-C-FeatureTests.cmake +++ b/Modules/Compiler/GNU-C-FeatureTests.cmake @@ -1,10 +1,15 @@ -set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407") +set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404") -set(GNU46_C11 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 201112L") +# GNU 4.7 correctly sets __STDC_VERSION__ to 201112L, but GNU 4.6 sets it +# to 201000L. As the former is strictly greater than the latter, test only +# for the latter. If in the future CMake learns about a C feature which was +# introduced with GNU 4.7, that should test for the correct version, similar +# to the distinction between __cplusplus and __GXX_EXPERIMENTAL_CXX0X__ tests. +set(GNU46_C11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201000L") set(_cmake_feature_test_c_static_assert "${GNU46_C11}") # Since 4.4 at least: -set(GNU44_C99 "${_cmake_oldestSupported} && __STDC_VERSION__ >= 199901L") +set(GNU44_C99 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L") set(_cmake_feature_test_c_restrict "${GNU44_C99}") set(_cmake_feature_test_c_variadic_macros "${GNU44_C99}") diff --git a/Modules/Compiler/GNU-C.cmake b/Modules/Compiler/GNU-C.cmake index 35954be..fa97a94 100644 --- a/Modules/Compiler/GNU-C.cmake +++ b/Modules/Compiler/GNU-C.cmake @@ -1,34 +1,48 @@ include(Compiler/GNU) __compiler_gnu(C) -if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5) set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90") set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90") +elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) + set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89") + set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu89") +endif() +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) set(CMAKE_C99_STANDARD_COMPILE_OPTION "-std=c99") set(CMAKE_C99_EXTENSION_COMPILE_OPTION "-std=gnu99") +endif() +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c11") set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11") +elseif (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) + set(CMAKE_C11_STANDARD_COMPILE_OPTION "-std=c1x") + set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu1x") endif() -# This may change in a future GNU version. -set(CMAKE_C_STANDARD_DEFAULT 90) +if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) + set(CMAKE_C_STANDARD_DEFAULT 11) +else() + set(CMAKE_C_STANDARD_DEFAULT 90) +endif() macro(cmake_record_c_compile_features) macro(_get_gcc_features std_version list) - record_compiler_features(C "-std=${std_version}" ${list}) + record_compiler_features(C "${std_version}" ${list}) endmacro() - if (UNIX AND NOT APPLE AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.7) - _get_gcc_features(c90 CMAKE_C90_COMPILE_FEATURES) + set(_result 0) + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.6) + _get_gcc_features(${CMAKE_C11_STANDARD_COMPILE_OPTION} CMAKE_C11_COMPILE_FEATURES) + endif() + if (UNIX AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) if (_result EQUAL 0) - _get_gcc_features(c99 CMAKE_C99_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_C99_STANDARD_COMPILE_OPTION} CMAKE_C99_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_gcc_features(c11 CMAKE_C11_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_C90_STANDARD_COMPILE_OPTION} CMAKE_C90_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/GNU-CXX-FeatureTests.cmake b/Modules/Compiler/GNU-CXX-FeatureTests.cmake index 9c98e44..5fc3deb 100644 --- a/Modules/Compiler/GNU-CXX-FeatureTests.cmake +++ b/Modules/Compiler/GNU-CXX-FeatureTests.cmake @@ -1,8 +1,15 @@ # Reference: http://gcc.gnu.org/projects/cxx0x.html +# http://gcc.gnu.org/projects/cxx1y.html -set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 407") +set(_cmake_oldestSupported "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404") +set(GNU50_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 500 && __cplusplus >= 201402L") +set(_cmake_feature_test_cxx_variable_templates "${GNU50_CXX14}") + +# GNU 4.9 in c++14 mode sets __cplusplus to 201300L, so don't test for the +# correct value of it below. +# https://patchwork.ozlabs.org/patch/382470/ set(GNU49_CXX14 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L") set(_cmake_feature_test_cxx_contextual_conversions "${GNU49_CXX14}") set(_cmake_feature_test_cxx_attribute_deprecated "${GNU49_CXX14}") @@ -39,7 +46,6 @@ set(_cmake_feature_test_cxx_alias_templates "${GNU47_CXX11}") set(_cmake_feature_test_cxx_delegating_constructors "${GNU47_CXX11}") set(_cmake_feature_test_cxx_extended_friend_declarations "${GNU47_CXX11}") set(_cmake_feature_test_cxx_final "${GNU47_CXX11}") -set(_cmake_feature_test_cxx_noexcept "${GNU47_CXX11}") set(_cmake_feature_test_cxx_nonstatic_member_init "${GNU47_CXX11}") set(_cmake_feature_test_cxx_override "${GNU47_CXX11}") set(_cmake_feature_test_cxx_user_literals "${GNU47_CXX11}") @@ -48,22 +54,25 @@ set(_cmake_feature_test_cxx_user_literals "${GNU47_CXX11}") # support -std=c++11. Prior to that, support for C++11 features is technically # experiemental and possibly incomplete (see for example the note below about # cxx_variadic_template_template_parameters) -# TODO: Should be supported by GNU 4.6 -set(GNU46_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +# GNU does not define __cplusplus correctly before version 4.7. +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773 +# __GXX_EXPERIMENTAL_CXX0X__ is defined in prior versions, but may not be +# defined in the future. +set(GNU_CXX0X_DEFINED "(__cplusplus >= 201103L || (defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__))") +set(GNU46_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 406 && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_constexpr "${GNU46_CXX11}") set(_cmake_feature_test_cxx_defaulted_move_initializers "${GNU46_CXX11}") set(_cmake_feature_test_cxx_enum_forward_declarations "${GNU46_CXX11}") +set(_cmake_feature_test_cxx_noexcept "${GNU46_CXX11}") set(_cmake_feature_test_cxx_nullptr "${GNU46_CXX11}") set(_cmake_feature_test_cxx_range_for "${GNU46_CXX11}") set(_cmake_feature_test_cxx_unrestricted_unions "${GNU46_CXX11}") -# TODO: Should be supported by GNU 4.5 -set(GNU45_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU45_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 405 && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_explicit_conversions "${GNU45_CXX11}") set(_cmake_feature_test_cxx_lambdas "${GNU45_CXX11}") set(_cmake_feature_test_cxx_local_type_template_args "${GNU45_CXX11}") set(_cmake_feature_test_cxx_raw_string_literals "${GNU45_CXX11}") -# TODO: Should be supported by GNU 4.4 -set(GNU44_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU44_CXX11 "(__GNUC__ * 100 + __GNUC_MINOR__) >= 404 && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_auto_type "${GNU44_CXX11}") set(_cmake_feature_test_cxx_defaulted_functions "${GNU44_CXX11}") set(_cmake_feature_test_cxx_deleted_functions "${GNU44_CXX11}") @@ -83,7 +92,7 @@ set(_cmake_feature_test_cxx_variadic_templates "${GNU44_CXX11}") # templates capability in CMake. See # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf # TODO: Should be supported by GNU 4.3 -set(GNU43_CXX11 "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(GNU43_CXX11 "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") set(_cmake_feature_test_cxx_decltype "${GNU43_CXX11}") set(_cmake_feature_test_cxx_default_function_template_args "${GNU43_CXX11}") set(_cmake_feature_test_cxx_long_long_type "${GNU43_CXX11}") @@ -91,8 +100,8 @@ set(_cmake_feature_test_cxx_right_angle_brackets "${GNU43_CXX11}") set(_cmake_feature_test_cxx_rvalue_references "${GNU43_CXX11}") set(_cmake_feature_test_cxx_static_assert "${GNU43_CXX11}") # TODO: Should be supported since GNU 3.4? -set(_cmake_feature_test_cxx_extern_templates "${_cmake_oldestSupported} && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_extern_templates "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") # TODO: Should be supported forever? -set(_cmake_feature_test_cxx_func_identifier "${_cmake_oldestSupported} && __cplusplus >= 201103L") -set(_cmake_feature_test_cxx_variadic_macros "${_cmake_oldestSupported} && __cplusplus >= 201103L") -set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus >= 199711L") +set(_cmake_feature_test_cxx_func_identifier "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") +set(_cmake_feature_test_cxx_variadic_macros "${_cmake_oldestSupported} && ${GNU_CXX0X_DEFINED}") +set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus") diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 14dc76a..c471daf 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -11,7 +11,8 @@ else() endif() endif() -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3) +if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + # Supported since 4.3 set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98") set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") endif() @@ -19,12 +20,16 @@ endif() if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) 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 4.3) +elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + # 4.3 supports 0x variants 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 4.8) +if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14") +elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y") set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y") endif() @@ -33,21 +38,19 @@ set(CMAKE_CXX_STANDARD_DEFAULT 98) macro(cmake_record_cxx_compile_features) macro(_get_gcc_features std_version list) - record_compiler_features(CXX "-std=${std_version}" ${list}) + record_compiler_features(CXX "${std_version}" ${list}) endmacro() set(_result 0) - if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - _get_gcc_features(c++1y CMAKE_CXX14_COMPILE_FEATURES) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + _get_gcc_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) endif() - if (UNIX AND NOT APPLE AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) if (_result EQUAL 0) - _get_gcc_features(c++11 CMAKE_CXX11_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() if (_result EQUAL 0) - _get_gcc_features(c++98 CMAKE_CXX98_COMPILE_FEATURES) + _get_gcc_features(${CMAKE_CXX98_STANDARD_COMPILE_OPTION} CMAKE_CXX98_COMPILE_FEATURES) endif() - else() - set(_result 0) endif() endmacro() diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake index 313ccbd..dfd7927 100644 --- a/Modules/Compiler/GNU-Fortran.cmake +++ b/Modules/Compiler/GNU-Fortran.cmake @@ -8,10 +8,5 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os") set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") -# We require updates to CMake C++ code to support preprocessing rules -# for Fortran. -set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) -set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) - # Fortran-specific feature flags. set(CMAKE_Fortran_MODDIR_FLAG -J) diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake index cc56b46..ad821ab 100644 --- a/Modules/Compiler/HP-Fortran.cmake +++ b/Modules/Compiler/HP-Fortran.cmake @@ -1,3 +1,6 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "+source=fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free") + +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") diff --git a/Modules/Compiler/Intel-Fortran.cmake b/Modules/Compiler/Intel-Fortran.cmake index 84f6182..9ebac5a 100644 --- a/Modules/Compiler/Intel-Fortran.cmake +++ b/Modules/Compiler/Intel-Fortran.cmake @@ -7,3 +7,6 @@ set(CMAKE_Fortran_MODDIR_FLAG "-module ") set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Compiler/PGI-Fortran.cmake b/Modules/Compiler/PGI-Fortran.cmake index 264c23e..2866254 100644 --- a/Modules/Compiler/PGI-Fortran.cmake +++ b/Modules/Compiler/PGI-Fortran.cmake @@ -7,9 +7,4 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-Mfreeform") set(CMAKE_Fortran_FLAGS_INIT "${CMAKE_Fortran_FLAGS_INIT} -Mpreprocess -Kieee") set(CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT} -Mbounds") -# We require updates to CMake C++ code to support preprocessing rules -# for Fortran. -set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) -set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) - set(CMAKE_Fortran_MODDIR_FLAG "-module ") diff --git a/Modules/Compiler/SunPro-CXX-FeatureTests.cmake b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake new file mode 100644 index 0000000..8e97e1d --- /dev/null +++ b/Modules/Compiler/SunPro-CXX-FeatureTests.cmake @@ -0,0 +1,52 @@ + +# Based on GNU 4.8.2 +# http://docs.oracle.com/cd/E37069_01/html/E37071/gncix.html +# Reference: http://gcc.gnu.org/projects/cxx0x.html + +set(_cmake_oldestSupported "__SUNPRO_CC >= 0x5130") + +set(SolarisStudio124_CXX11 "(__SUNPRO_CC >= 0x5130) && __cplusplus >= 201103L") +set(_cmake_feature_test_cxx_alignas "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_alignof "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_attributes "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_inheriting_constructors "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_thread_local "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_alias_templates "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_delegating_constructors "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_extended_friend_declarations "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_final "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_noexcept "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_nonstatic_member_init "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_override "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_constexpr "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_defaulted_move_initializers "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_enum_forward_declarations "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_nullptr "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_range_for "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_unrestricted_unions "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_explicit_conversions "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_lambdas "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_local_type_template_args "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_raw_string_literals "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_auto_type "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_defaulted_functions "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_deleted_functions "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_generalized_initializers "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_inline_namespaces "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_sizeof_member "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_strong_enums "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_trailing_return_types "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_unicode_literals "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_uniform_initialization "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_variadic_templates "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_decltype "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_default_function_template_args "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_long_long_type "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_right_angle_brackets "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_rvalue_references "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_static_assert "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_extern_templates "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_func_identifier "${SolarisStudio124_CXX11}") +set(_cmake_feature_test_cxx_variadic_macros "${SolarisStudio124_CXX11}") + +set(_cmake_feature_test_cxx_template_template_parameters "${_cmake_oldestSupported} && __cplusplus") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index 5968712..cb37713 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -31,3 +31,24 @@ set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <FLAGS> -S <SOURCE> - set(CMAKE_CXX_CREATE_STATIC_LIBRARY "<CMAKE_CXX_COMPILER> -xar -o <TARGET> <OBJECTS> " "<CMAKE_RANLIB> <TARGET> ") + +if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) + set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++11") +endif() + +set(CMAKE_CXX_STANDARD_DEFAULT 98) + +macro(cmake_record_cxx_compile_features) + macro(_get_solaris_studio_features std_version list) + record_compiler_features(CXX "${std_version}" ${list}) + endmacro() + + set(_result 0) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) + _get_solaris_studio_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) + if (_result EQUAL 0) + _get_solaris_studio_features("" CMAKE_CXX98_COMPILE_FEATURES) + endif() + endif() +endmacro() diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index 18e75b9..e4db1e8 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -16,3 +16,6 @@ set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-xO3 -DNDEBUG") set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT "-g -xO2 -DNDEBUG") set(CMAKE_Fortran_MODDIR_FLAG "-moddir=") set(CMAKE_Fortran_MODPATH_FLAG "-M") + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -F <SOURCE> -o <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake index f1c9158..ae9df4e 100644 --- a/Modules/Compiler/XL-Fortran.cmake +++ b/Modules/Compiler/XL-Fortran.cmake @@ -12,6 +12,6 @@ set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D") # -qhalt=e = Halt on error messages (rather than just severe errors) set(CMAKE_Fortran_FLAGS_INIT "-qthreaded -qhalt=e") -# We require updates to CMake C++ code to support preprocessing rules for Fortran. +# xlf: 1501-214 (W) command option E reserved for future use - ignored set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE) diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in index aebae27..7f686a2 100644 --- a/Modules/CompilerId/Xcode-3.pbxproj.in +++ b/Modules/CompilerId/Xcode-3.pbxproj.in @@ -81,7 +81,7 @@ buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_BIT)"; ONLY_ACTIVE_ARCH = YES; - @id_code_sign_identity@ + CODE_SIGNING_REQUIRED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)"; SYMROOT = .; @id_toolset@ diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 79bb064..741db81 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -1,189 +1,301 @@ -#.rst: -# ExternalData -# ------------ -# -# Manage data files stored outside source tree -# -# Use this module to unambiguously reference data files stored outside -# the source tree and fetch them at build time from arbitrary local and -# remote content-addressed locations. Functions provided by this module -# recognize arguments with the syntax ``DATA{<name>}`` as references to -# external data, replace them with full paths to local copies of those -# data, and create build rules to fetch and update the local copies. -# -# The ``DATA{}`` syntax is literal and the ``<name>`` is a full or relative path -# within the source tree. The source tree must contain either a real -# data file at ``<name>`` or a "content link" at ``<name><ext>`` containing a -# hash of the real file using a hash algorithm corresponding to ``<ext>``. -# For example, the argument ``DATA{img.png}`` may be satisfied by either a -# real ``img.png`` file in the current source directory or a ``img.png.md5`` -# file containing its MD5 sum. -# -# The ``ExternalData_Expand_Arguments`` function evaluates ``DATA{}`` -# references in its arguments and constructs a new list of arguments: -# -# .. code-block:: cmake -# -# ExternalData_Expand_Arguments( -# <target> # Name of data management target -# <outVar> # Output variable -# [args...] # Input arguments, DATA{} allowed -# ) -# -# It replaces each ``DATA{}`` reference in an argument with the full path of -# a real data file on disk that will exist after the ``<target>`` builds. -# -# The ``ExternalData_Add_Test`` function wraps around the CMake -# :command:`add_test` command but supports ``DATA{}`` references in -# its arguments: -# -# .. code-block:: cmake -# -# ExternalData_Add_Test( -# <target> # Name of data management target -# ... # Arguments of add_test(), DATA{} allowed -# ) -# -# It passes its arguments through ``ExternalData_Expand_Arguments`` and then -# invokes the :command:`add_test` command using the results. -# -# The ``ExternalData_Add_Target`` function creates a custom target to -# manage local instances of data files stored externally: -# -# .. code-block:: cmake -# -# ExternalData_Add_Target( -# <target> # Name of data management target -# ) -# -# It creates custom commands in the target as necessary to make data -# files available for each ``DATA{}`` reference previously evaluated by -# other functions provided by this module. A list of URL templates may -# be provided in the variable ``ExternalData_URL_TEMPLATES`` using the -# placeholders ``%(algo)`` and ``%(hash)`` in each template. Data fetch -# rules try each URL template in order by substituting the hash -# algorithm name for ``%(algo)`` and the hash value for ``%(hash)``. -# -# The following hash algorithms are supported:: -# -# %(algo) <ext> Description -# ------- ----- ----------- -# MD5 .md5 Message-Digest Algorithm 5, RFC 1321 -# SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174 -# SHA224 .sha224 US Secure Hash Algorithms, RFC 4634 -# SHA256 .sha256 US Secure Hash Algorithms, RFC 4634 -# SHA384 .sha384 US Secure Hash Algorithms, RFC 4634 -# SHA512 .sha512 US Secure Hash Algorithms, RFC 4634 -# -# Note that the hashes are used only for unique data identification and -# download verification. -# -# Example usage: -# -# .. code-block:: cmake -# -# include(ExternalData) -# set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)" -# "file:////host/share/%(algo)/%(hash)" -# "http://data.org/%(algo)/%(hash)") -# ExternalData_Add_Test(MyData -# NAME MyTest -# COMMAND MyExe DATA{MyInput.png} -# ) -# ExternalData_Add_Target(MyData) -# -# When test ``MyTest`` runs the ``DATA{MyInput.png}`` argument will be -# replaced by the full path to a real instance of the data file -# ``MyInput.png`` on disk. If the source tree contains a content link -# such as ``MyInput.png.md5`` then the ``MyData`` target creates a real -# ``MyInput.png`` in the build tree. -# -# The ``DATA{}`` syntax can be told to fetch a file series using the form -# ``DATA{<name>,:}``, where the ``:`` is literal. If the source tree -# contains a group of files or content links named like a series then a -# reference to one member adds rules to fetch all of them. Although all -# members of a series are fetched, only the file originally named by the -# ``DATA{}`` argument is substituted for it. The default configuration -# recognizes file series names ending with ``#.ext``, ``_#.ext``, ``.#.ext``, -# or ``-#.ext`` where ``#`` is a sequence of decimal digits and ``.ext`` is -# any single extension. Configure it with a regex that parses ``<number>`` -# and ``<suffix>`` parts from the end of ``<name>``:: -# -# ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$ -# -# For more complicated cases set:: -# -# ExternalData_SERIES_PARSE = regex with at least two () groups -# ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any -# ExternalData_SERIES_PARSE_NUMBER = <number> regex group number -# ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number -# -# Configure series number matching with a regex that matches the -# ``<number>`` part of series members named ``<prefix><number><suffix>``:: -# -# ExternalData_SERIES_MATCH = regex matching <number> in all series members -# -# Note that the ``<suffix>`` of a series does not include a hash-algorithm -# extension. -# -# The ``DATA{}`` syntax can alternatively match files associated with the -# named file and contained in the same directory. Associated files may -# be specified by options using the syntax -# ``DATA{<name>,<opt1>,<opt2>,...}``. Each option may specify one file by -# name or specify a regular expression to match file names using the -# syntax ``REGEX:<regex>``. For example, the arguments:: -# -# DATA{MyData/MyInput.mhd,MyInput.img} # File pair -# DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series -# -# will pass ``MyInput.mha`` and ``MyFrames00.png`` on the command line but -# ensure that the associated files are present next to them. -# -# The ``DATA{}`` syntax may reference a directory using a trailing slash and -# a list of associated files. The form ``DATA{<name>/,<opt1>,<opt2>,...}`` -# adds rules to fetch any files in the directory that match one of the -# associated file options. For example, the argument -# ``DATA{MyDataDir/,REGEX:.*}`` will pass the full path to a ``MyDataDir`` -# directory on the command line and ensure that the directory contains -# files corresponding to every file or content link in the ``MyDataDir`` -# source directory. -# -# The variable ``ExternalData_LINK_CONTENT`` may be set to the name of a -# supported hash algorithm to enable automatic conversion of real data -# files referenced by the ``DATA{}`` syntax into content links. For each -# such ``<file>`` a content link named ``<file><ext>`` is created. The -# original file is renamed to the form ``.ExternalData_<algo>_<hash>`` to -# stage it for future transmission to one of the locations in the list -# of URL templates (by means outside the scope of this module). The -# data fetch rule created for the content link will use the staged -# object if it cannot be found using any URL template. -# -# The variable ``ExternalData_OBJECT_STORES`` may be set to a list of local -# directories that store objects using the layout ``<dir>/%(algo)/%(hash)``. -# These directories will be searched first for a needed object. If the -# object is not available in any store then it will be fetched remotely -# using the URL templates and added to the first local store listed. If -# no stores are specified the default is a location inside the build -# tree. -# -# The variable ``ExternalData_SOURCE_ROOT`` may be set to the highest source -# directory containing any path named by a ``DATA{}`` reference. The -# default is ``CMAKE_SOURCE_DIR``. ``ExternalData_SOURCE_ROOT`` and -# ``CMAKE_SOURCE_DIR`` must refer to directories within a single source -# distribution (e.g. they come together in one tarball). -# -# The variable ``ExternalData_BINARY_ROOT`` may be set to the directory to -# hold the real data files named by expanded ``DATA{}`` references. The -# default is ``CMAKE_BINARY_DIR``. The directory layout will mirror that of -# content links under ``ExternalData_SOURCE_ROOT``. -# -# Variables ``ExternalData_TIMEOUT_INACTIVITY`` and -# ``ExternalData_TIMEOUT_ABSOLUTE`` set the download inactivity and absolute -# timeouts, in seconds. The defaults are 60 seconds and 300 seconds, -# respectively. Set either timeout to 0 seconds to disable enforcement. +#[=======================================================================[.rst: +ExternalData +------------ + +.. only:: html + + .. contents:: + +Manage data files stored outside source tree + +Introduction +^^^^^^^^^^^^ + +Use this module to unambiguously reference data files stored outside +the source tree and fetch them at build time from arbitrary local and +remote content-addressed locations. Functions provided by this module +recognize arguments with the syntax ``DATA{<name>}`` as references to +external data, replace them with full paths to local copies of those +data, and create build rules to fetch and update the local copies. + +For example: + +.. code-block:: cmake + + include(ExternalData) + set(ExternalData_URL_TEMPLATES "file:///local/%(algo)/%(hash)" + "file:////host/share/%(algo)/%(hash)" + "http://data.org/%(algo)/%(hash)") + ExternalData_Add_Test(MyData + NAME MyTest + COMMAND MyExe DATA{MyInput.png} + ) + ExternalData_Add_Target(MyData) + +When test ``MyTest`` runs the ``DATA{MyInput.png}`` argument will be +replaced by the full path to a real instance of the data file +``MyInput.png`` on disk. If the source tree contains a content link +such as ``MyInput.png.md5`` then the ``MyData`` target creates a real +``MyInput.png`` in the build tree. + +Module Functions +^^^^^^^^^^^^^^^^ + +.. command:: ExternalData_Expand_Arguments + + The ``ExternalData_Expand_Arguments`` function evaluates ``DATA{}`` + references in its arguments and constructs a new list of arguments:: + + ExternalData_Expand_Arguments( + <target> # Name of data management target + <outVar> # Output variable + [args...] # Input arguments, DATA{} allowed + ) + + It replaces each ``DATA{}`` reference in an argument with the full path of + a real data file on disk that will exist after the ``<target>`` builds. + +.. command:: ExternalData_Add_Test + + The ``ExternalData_Add_Test`` function wraps around the CMake + :command:`add_test` command but supports ``DATA{}`` references in + its arguments:: + + ExternalData_Add_Test( + <target> # Name of data management target + ... # Arguments of add_test(), DATA{} allowed + ) + + It passes its arguments through ``ExternalData_Expand_Arguments`` and then + invokes the :command:`add_test` command using the results. + +.. command:: ExternalData_Add_Target + + The ``ExternalData_Add_Target`` function creates a custom target to + manage local instances of data files stored externally:: + + ExternalData_Add_Target( + <target> # Name of data management target + ) + + It creates custom commands in the target as necessary to make data + files available for each ``DATA{}`` reference previously evaluated by + other functions provided by this module. + Data files may be fetched from one of the URL templates specified in + the ``ExternalData_URL_TEMPLATES`` variable, or may be found locally + in one of the paths specified in the ``ExternalData_OBJECT_STORES`` + variable. + +Module Variables +^^^^^^^^^^^^^^^^ + +The following variables configure behavior. They should be set before +calling any of the functions provided by this module. + +.. variable:: ExternalData_BINARY_ROOT + + The ``ExternalData_BINARY_ROOT`` variable may be set to the directory to + hold the real data files named by expanded ``DATA{}`` references. The + default is ``CMAKE_BINARY_DIR``. The directory layout will mirror that of + content links under ``ExternalData_SOURCE_ROOT``. + +.. variable:: ExternalData_CUSTOM_SCRIPT_<key> + + Specify a full path to a ``.cmake`` custom fetch script identified by + ``<key>`` in entries of the ``ExternalData_URL_TEMPLATES`` list. + See `Custom Fetch Scripts`_. + +.. variable:: ExternalData_LINK_CONTENT + + The ``ExternalData_LINK_CONTENT`` variable may be set to the name of a + supported hash algorithm to enable automatic conversion of real data + files referenced by the ``DATA{}`` syntax into content links. For each + such ``<file>`` a content link named ``<file><ext>`` is created. The + original file is renamed to the form ``.ExternalData_<algo>_<hash>`` to + stage it for future transmission to one of the locations in the list + of URL templates (by means outside the scope of this module). The + data fetch rule created for the content link will use the staged + object if it cannot be found using any URL template. + +.. variable:: ExternalData_OBJECT_STORES + + The ``ExternalData_OBJECT_STORES`` variable may be set to a list of local + directories that store objects using the layout ``<dir>/%(algo)/%(hash)``. + These directories will be searched first for a needed object. If the + object is not available in any store then it will be fetched remotely + using the URL templates and added to the first local store listed. If + no stores are specified the default is a location inside the build + tree. + +.. variable:: ExternalData_SERIES_PARSE + ExternalData_SERIES_PARSE_PREFIX + ExternalData_SERIES_PARSE_NUMBER + ExternalData_SERIES_PARSE_SUFFIX + ExternalData_SERIES_MATCH + + See `Referencing File Series`_. + +.. variable:: ExternalData_SOURCE_ROOT + + The ``ExternalData_SOURCE_ROOT`` variable may be set to the highest source + directory containing any path named by a ``DATA{}`` reference. The + default is ``CMAKE_SOURCE_DIR``. ``ExternalData_SOURCE_ROOT`` and + ``CMAKE_SOURCE_DIR`` must refer to directories within a single source + distribution (e.g. they come together in one tarball). + +.. variable:: ExternalData_TIMEOUT_ABSOLUTE + + The ``ExternalData_TIMEOUT_ABSOLUTE`` variable sets the download + absolute timeout, in seconds, with a default of ``300`` seconds. + Set to ``0`` to disable enforcement. + +.. variable:: ExternalData_TIMEOUT_INACTIVITY + + The ``ExternalData_TIMEOUT_INACTIVITY`` variable sets the download + inactivity timeout, in seconds, with a default of ``60`` seconds. + Set to ``0`` to disable enforcement. + +.. variable:: ExternalData_URL_TEMPLATES + + The ``ExternalData_URL_TEMPLATES`` may be set to provide a list of + of URL templates using the placeholders ``%(algo)`` and ``%(hash)`` + in each template. Data fetch rules try each URL template in order + by substituting the hash algorithm name for ``%(algo)`` and the hash + value for ``%(hash)``. + +Referencing Files +^^^^^^^^^^^^^^^^^ + +Referencing Single Files +"""""""""""""""""""""""" + +The ``DATA{}`` syntax is literal and the ``<name>`` is a full or relative path +within the source tree. The source tree must contain either a real +data file at ``<name>`` or a "content link" at ``<name><ext>`` containing a +hash of the real file using a hash algorithm corresponding to ``<ext>``. +For example, the argument ``DATA{img.png}`` may be satisfied by either a +real ``img.png`` file in the current source directory or a ``img.png.md5`` +file containing its MD5 sum. + +Referencing File Series +""""""""""""""""""""""" + +The ``DATA{}`` syntax can be told to fetch a file series using the form +``DATA{<name>,:}``, where the ``:`` is literal. If the source tree +contains a group of files or content links named like a series then a +reference to one member adds rules to fetch all of them. Although all +members of a series are fetched, only the file originally named by the +``DATA{}`` argument is substituted for it. The default configuration +recognizes file series names ending with ``#.ext``, ``_#.ext``, ``.#.ext``, +or ``-#.ext`` where ``#`` is a sequence of decimal digits and ``.ext`` is +any single extension. Configure it with a regex that parses ``<number>`` +and ``<suffix>`` parts from the end of ``<name>``:: + + ExternalData_SERIES_PARSE = regex of the form (<number>)(<suffix>)$ + +For more complicated cases set:: + + ExternalData_SERIES_PARSE = regex with at least two () groups + ExternalData_SERIES_PARSE_PREFIX = <prefix> regex group number, if any + ExternalData_SERIES_PARSE_NUMBER = <number> regex group number + ExternalData_SERIES_PARSE_SUFFIX = <suffix> regex group number + +Configure series number matching with a regex that matches the +``<number>`` part of series members named ``<prefix><number><suffix>``:: + + ExternalData_SERIES_MATCH = regex matching <number> in all series members + +Note that the ``<suffix>`` of a series does not include a hash-algorithm +extension. + +Referencing Associated Files +"""""""""""""""""""""""""""" + +The ``DATA{}`` syntax can alternatively match files associated with the +named file and contained in the same directory. Associated files may +be specified by options using the syntax +``DATA{<name>,<opt1>,<opt2>,...}``. Each option may specify one file by +name or specify a regular expression to match file names using the +syntax ``REGEX:<regex>``. For example, the arguments:: + + DATA{MyData/MyInput.mhd,MyInput.img} # File pair + DATA{MyData/MyFrames00.png,REGEX:MyFrames[0-9]+\\.png} # Series + +will pass ``MyInput.mha`` and ``MyFrames00.png`` on the command line but +ensure that the associated files are present next to them. + +Referencing Directories +""""""""""""""""""""""" + +The ``DATA{}`` syntax may reference a directory using a trailing slash and +a list of associated files. The form ``DATA{<name>/,<opt1>,<opt2>,...}`` +adds rules to fetch any files in the directory that match one of the +associated file options. For example, the argument +``DATA{MyDataDir/,REGEX:.*}`` will pass the full path to a ``MyDataDir`` +directory on the command line and ensure that the directory contains +files corresponding to every file or content link in the ``MyDataDir`` +source directory. + +Hash Algorithms +^^^^^^^^^^^^^^^ + +The following hash algorithms are supported:: + + %(algo) <ext> Description + ------- ----- ----------- + MD5 .md5 Message-Digest Algorithm 5, RFC 1321 + SHA1 .sha1 US Secure Hash Algorithm 1, RFC 3174 + SHA224 .sha224 US Secure Hash Algorithms, RFC 4634 + SHA256 .sha256 US Secure Hash Algorithms, RFC 4634 + SHA384 .sha384 US Secure Hash Algorithms, RFC 4634 + SHA512 .sha512 US Secure Hash Algorithms, RFC 4634 + +Note that the hashes are used only for unique data identification and +download verification. + +.. _`ExternalData Custom Fetch Scripts`: + +Custom Fetch Scripts +^^^^^^^^^^^^^^^^^^^^ + +When a data file must be fetched from one of the URL templates +specified in the ``ExternalData_URL_TEMPLATES`` variable, it is +normally downloaded using the :command:`file(DOWNLOAD)` command. +One may specify usage of a custom fetch script by using a URL +template of the form ``ExternalDataCustomScript://<key>/<loc>``. +The ``<key>`` must be a C identifier, and the ``<loc>`` must +contain the ``%(algo)`` and ``%(hash)`` placeholders. +A variable corresponding to the key, ``ExternalData_CUSTOM_SCRIPT_<key>``, +must be set to the full path to a ``.cmake`` script file. The script +will be included to perform the actual fetch, and provided with +the following variables: + +.. variable:: ExternalData_CUSTOM_LOCATION + + When a custom fetch script is loaded, this variable is set to the + location part of the URL, which will contain the substituted hash + algorithm name and content hash value. + +.. variable:: ExternalData_CUSTOM_FILE + + When a custom fetch script is loaded, this variable is set to the + full path to a file in which the script must store the fetched + content. The name of the file is unspecified and should not be + interpreted in any way. + +The custom fetch script is expected to store fetched content in the +file or set a variable: + +.. variable:: ExternalData_CUSTOM_ERROR + + When a custom fetch script fails to fetch the requested content, + it must set this variable to a short one-line message describing + the reason for failure. + +#]=======================================================================] #============================================================================= -# Copyright 2010-2013 Kitware, Inc. +# Copyright 2010-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -209,6 +321,37 @@ function(ExternalData_add_target target) if(NOT ExternalData_OBJECT_STORES) set(ExternalData_OBJECT_STORES ${CMAKE_BINARY_DIR}/ExternalData/Objects) endif() + set(_ExternalData_CONFIG_CODE "") + + # Store custom script configuration. + foreach(url_template IN LISTS ExternalData_URL_TEMPLATES) + if("${url_template}" MATCHES "^ExternalDataCustomScript://([^/]*)/(.*)$") + set(key "${CMAKE_MATCH_1}") + if(key MATCHES "^[A-Za-z_][A-Za-z0-9_]*$") + if(ExternalData_CUSTOM_SCRIPT_${key}) + if(IS_ABSOLUTE "${ExternalData_CUSTOM_SCRIPT_${key}}") + string(CONCAT _ExternalData_CONFIG_CODE "${_ExternalData_CONFIG_CODE}\n" + "set(ExternalData_CUSTOM_SCRIPT_${key} \"${ExternalData_CUSTOM_SCRIPT_${key}}\")") + else() + message(FATAL_ERROR + "No ExternalData_CUSTOM_SCRIPT_${key} is not set to a full path:\n" + " ${ExternalData_CUSTOM_SCRIPT_${key}}") + endif() + else() + message(FATAL_ERROR + "No ExternalData_CUSTOM_SCRIPT_${key} is set for URL template:\n" + " ${url_template}") + endif() + else() + message(FATAL_ERROR + "Bad ExternalDataCustomScript key '${key}' in URL template:\n" + " ${url_template}\n" + "The key must be a valid C identifier.") + endif() + endif() + endforeach() + + # Store configuration for use by build-time script. set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake) configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY) @@ -715,6 +858,30 @@ function(_ExternalData_download_file url file err_var msg_var) set("${msg_var}" "${msg}" PARENT_SCOPE) endfunction() +function(_ExternalData_custom_fetch key loc file err_var msg_var) + if(NOT ExternalData_CUSTOM_SCRIPT_${key}) + set(err 1) + set(msg "No ExternalData_CUSTOM_SCRIPT_${key} set!") + elseif(NOT EXISTS "${ExternalData_CUSTOM_SCRIPT_${key}}") + set(err 1) + set(msg "No '${ExternalData_CUSTOM_SCRIPT_${key}}' exists!") + else() + set(ExternalData_CUSTOM_LOCATION "${loc}") + set(ExternalData_CUSTOM_FILE "${file}") + unset(ExternalData_CUSTOM_ERROR) + include("${ExternalData_CUSTOM_SCRIPT_${key}}") + if(DEFINED ExternalData_CUSTOM_ERROR) + set(err 1) + set(msg "${ExternalData_CUSTOM_ERROR}") + else() + set(err 0) + set(msg "no error") + endif() + endif() + set("${err_var}" "${err}" PARENT_SCOPE) + set("${msg_var}" "${msg}" PARENT_SCOPE) +endfunction() + function(_ExternalData_download_object name hash algo var_obj) # Search all object stores for an existing object. foreach(dir ${ExternalData_OBJECT_STORES}) @@ -738,7 +905,11 @@ function(_ExternalData_download_object name hash algo var_obj) string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}") string(REPLACE "%(algo)" "${algo}" url "${url_tmp}") message(STATUS "Fetching \"${url}\"") - _ExternalData_download_file("${url}" "${tmp}" err errMsg) + if(url MATCHES "^ExternalDataCustomScript://([A-Za-z_][A-Za-z0-9_]*)/(.*)$") + _ExternalData_custom_fetch("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "${tmp}" err errMsg) + else() + _ExternalData_download_file("${url}" "${tmp}" err errMsg) + endif() set(tried "${tried}\n ${url}") if(err) set(tried "${tried} (${errMsg})") diff --git a/Modules/ExternalData_config.cmake.in b/Modules/ExternalData_config.cmake.in index 0858f53..4434e4b 100644 --- a/Modules/ExternalData_config.cmake.in +++ b/Modules/ExternalData_config.cmake.in @@ -2,3 +2,4 @@ set(ExternalData_OBJECT_STORES "@ExternalData_OBJECT_STORES@") set(ExternalData_URL_TEMPLATES "@ExternalData_URL_TEMPLATES@") set(ExternalData_TIMEOUT_INACTIVITY "@ExternalData_TIMEOUT_INACTIVITY@") set(ExternalData_TIMEOUT_ABSOLUTE "@ExternalData_TIMEOUT_ABSOLUTE@") +@_ExternalData_CONFIG_CODE@ diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index a92f20c..52d41eb 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -80,6 +80,8 @@ Create custom targets to build projects in external trees ``UPDATE_COMMAND <cmd>...`` Source work-tree update command + ``UPDATE_DISCONNECTED 1`` + Never update automatically from the remote repository ``PATCH_COMMAND <cmd>...`` Command to patch downloaded source @@ -98,9 +100,27 @@ Create custom targets to build projects in external trees ``CMAKE_GENERATOR_TOOLSET <toolset>`` Generator-specific toolset name ``CMAKE_ARGS <arg>...`` - Arguments to CMake command line + Arguments to CMake command line. + These arguments are passed to CMake command line, and can contain + arguments other than cache values, see also + :manual:`CMake Options <cmake(1)>`. Arguments in the form + ``-Dvar:string=on`` are always passed to the command line, and + therefore cannot be changed by the user. ``CMAKE_CACHE_ARGS <arg>...`` - Initial cache arguments, of the form ``-Dvar:string=on`` + Initial cache arguments, of the form ``-Dvar:string=on``. + These arguments are written in a pre-load a script that populates + CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to + overcome command line length limits. + These arguments are :command:`set` using the ``FORCE`` argument, + and therefore cannot be changed by the user. + ``CMAKE_CACHE_DEFAULT_ARGS <arg>...`` + Initial default cache arguments, of the form ``-Dvar:string=on``. + These arguments are written in a pre-load a script that populates + CMake cache, see also :manual:`cmake -C <cmake(1)>`. This allows to + overcome command line length limits. + These arguments can be used as default value that will be set if no + previous value is found in the cache, and that the user can change + later. Build step options are: @@ -112,6 +132,9 @@ Create custom targets to build projects in external trees Use source dir for build dir ``BUILD_ALWAYS 1`` No stamp file, build step always runs + ``BUILD_BYPRODUCTS <file>...`` + Files that will be generated by the build command but may or may + not have their modification time updated by subsequent builds. Install step options are: @@ -126,6 +149,8 @@ Create custom targets to build projects in external trees Add test step executed before install step ``TEST_AFTER_INSTALL 1`` Add test step executed after install step + ``TEST_EXCLUDE_FROM_MAIN 1`` + Main target does not depend on the test step ``TEST_COMMAND <cmd>...`` Command to drive test @@ -148,6 +173,9 @@ Create custom targets to build projects in external trees ``STEP_TARGETS <step-target>...`` Generate custom targets for these steps + ``INDEPENDENT_STEP_TARGETS <step-target>...`` + Generate custom targets for these steps that do not depend on other + external projects even if a dependency is set The ``*_DIR`` options specify directories for the project, with default directories computed as follows. If the ``PREFIX`` option is given to @@ -182,6 +210,16 @@ Create custom targets to build projects in external trees options. The ``URL`` option may refer locally to a directory or source tarball, or refer to a remote tarball (e.g. ``http://.../src.tgz``). + If ``UPDATE_DISCONNECTED`` is set, the update step is not executed + automatically when building the main target. The update step can still + be added as a step target and called manually. This is useful if you + want to allow to build the project when you are disconnected from the + network (you might still need the network for the download step). + This is disabled by default. + The directory property ``EP_UPDATE_DISCONNECTED`` can be used to change + the default value for all the external projects in the current + directory and its subdirectories. + .. command:: ExternalProject_Add_Step The ``ExternalProject_Add_Step`` function adds a custom step to an @@ -201,6 +239,9 @@ Create custom targets to build projects in external trees Steps that depend on this step ``DEPENDS <file>...`` Files on which this step depends + ``BYPRODUCTS <file>...`` + Files that will be generated by this step but may or may not + have their modification time updated by subsequent builds. ``ALWAYS 1`` No stamp file, step always runs ``EXCLUDE_FROM_MAIN 1`` @@ -242,18 +283,30 @@ not defined. Behavior of shell operators like ``&&`` is not defined. The ``ExternalProject_Add_StepTargets`` function generates custom targets for the steps listed:: - ExternalProject_Add_StepTargets(<name> [step1 [step2 [...]]]) - -If ``STEP_TARGETS`` is set then ``ExternalProject_Add_StepTargets`` is -automatically called at the end of matching calls to -``ExternalProject_Add_Step``. Pass ``STEP_TARGETS`` explicitly to + ExternalProject_Add_StepTargets(<name> [NO_DEPENDS] [step1 [step2 [...]]]) + +If ``NO_DEPENDS`` is set, the target will not depend on the +dependencies of the complete project. This is usually safe to use for +the download, update, and patch steps that do not require that all the +dependencies are updated and built. Using ``NO_DEPENDS`` for other +of the default steps might break parallel builds, so you should avoid, +it. For custom steps, you should consider whether or not the custom +commands requires that the dependencies are configured, built and +installed. + +If ``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` is set then +``ExternalProject_Add_StepTargets`` is automatically called at the end +of matching calls to ``ExternalProject_Add_Step``. Pass +``STEP_TARGETS`` or ``INDEPENDENT_STEP_TARGETS`` explicitly to individual ``ExternalProject_Add`` calls, or implicitly to all -``ExternalProject_Add`` calls by setting the directory property -``EP_STEP_TARGETS``. +``ExternalProject_Add`` calls by setting the directory properties +``EP_STEP_TARGETS`` and ``EP_INDEPENDENT_STEP_TARGETS``. The +``INDEPENDENT`` version of the argument and of the property will call +``ExternalProject_Add_StepTargets`` with the ``NO_DEPENDS`` argument. -If ``STEP_TARGETS`` is not set, clients may still manually call -``ExternalProject_Add_StepTargets`` after calling -``ExternalProject_Add`` or ``ExternalProject_Add_Step``. +If ``STEP_TARGETS`` and ``INDEPENDENT_STEP_TARGETS`` are not set, +clients may still manually call ``ExternalProject_Add_StepTargets`` +after calling ``ExternalProject_Add`` or ``ExternalProject_Add_Step``. This functionality is provided to make it easy to drive the steps independently of each other by specifying targets on build command @@ -270,6 +323,19 @@ line prior to any ``ExternalProject_Add`` calls in your ``CMakeLists.txt`` file:: set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) + +.. command:: ExternalProject_Add_StepDependencies + + The ``ExternalProject_Add_StepDependencies`` function add some + dependencies for some external project step:: + + ExternalProject_Add_StepDependencies(<name> <step> [target1 [target2 [...]]]) + + This function takes care to set both target and file level + dependencies, and will ensure that parallel builds will not break. + It should be used instead of :command:`add_dependencies()` when adding + a dependency for some of the step targets generated by + ``ExternalProject``. #]=======================================================================] #============================================================================= @@ -379,10 +445,26 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED BRIEF_DOCS "List of ExternalProject steps that automatically get corresponding targets" FULL_DOCS + "These targets will be dependent on the main target dependencies" "See documentation of the ExternalProject_Add_StepTargets() function in the " "ExternalProject module." ) +define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED + BRIEF_DOCS + "List of ExternalProject steps that automatically get corresponding targets" + FULL_DOCS + "These targets will not be dependent on the main target dependencies" + "See documentation of the ExternalProject_Add_StepTargets() function in the " + "ExternalProject module." + ) + +define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED + BRIEF_DOCS "Never update automatically from the remote repo." + FULL_DOCS + "See documentation of the ExternalProject_Add() function in the " + "ExternalProject module." + ) function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_submodules src_name work_dir gitclone_infofile gitclone_stampfile) file(WRITE ${script_filename} @@ -717,6 +799,19 @@ function(_ep_write_downloadfile_script script_filename remote local timeout no_p set(show_progress "SHOW_PROGRESS") endif() + if("${hash}" MATCHES "${_ep_hash_regex}") + string(CONCAT hash_check + "if(EXISTS \"${local}\")\n" + " file(\"${CMAKE_MATCH_1}\" \"${local}\" hash_value)\n" + " if(\"x\${hash_value}\" STREQUAL \"x${CMAKE_MATCH_2}\")\n" + " return()\n" + " endif()\n" + "endif()\n" + ) + else() + set(hash_check "") + endif() + # check for curl globals in the project if(DEFINED CMAKE_TLS_VERIFY) set(tls_verify "set(CMAKE_TLS_VERIFY ${CMAKE_TLS_VERIFY})") @@ -740,7 +835,7 @@ function(_ep_write_downloadfile_script script_filename remote local timeout no_p endif() file(WRITE ${script_filename} -"message(STATUS \"downloading... +"${hash_check}message(STATUS \"downloading... src='${remote}' dst='${local}' timeout='${timeout_msg}'\") @@ -986,17 +1081,20 @@ macro(_ep_replace_location_tags target_name) endmacro() -function(_ep_write_initial_cache target_name script_filename args) - # Write out values into an initial cache, that will be passed to CMake with -C +function(_ep_command_line_to_initial_cache var args force) set(script_initial_cache "") set(regex "^([^:]+):([^=]+)=(.*)$") set(setArg "") + set(forceArg "") + if(force) + set(forceArg "FORCE") + endif() foreach(line ${args}) if("${line}" MATCHES "^-D(.*)") set(line "${CMAKE_MATCH_1}") if(setArg) # This is required to build up lists in variables, or complete an entry - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") + set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") set(script_initial_cache "${script_initial_cache}\n${setArg}") set(accumulator "") set(setArg "") @@ -1016,9 +1114,15 @@ function(_ep_write_initial_cache target_name script_filename args) endforeach() # Catch the final line of the args if(setArg) - set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" FORCE)") + set(setArg "${setArg}${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})") set(script_initial_cache "${script_initial_cache}\n${setArg}") endif() + set(${var} ${script_initial_cache} PARENT_SCOPE) +endfunction() + + +function(_ep_write_initial_cache target_name script_filename script_initial_cache) + # Write out values into an initial cache, that will be passed to CMake with -C # Replace location tags. _ep_replace_location_tags(${target_name} script_initial_cache) # Write out the initial cache file to the location specified. @@ -1137,7 +1241,7 @@ function(_ep_write_log_script name step cmd_var) set(make "") set(code_cygpath_make "") - if("${command}" MATCHES "^\\$\\(MAKE\\)") + if(command MATCHES "^\\$\\(MAKE\\)") # GNU make recognizes the string "$(MAKE)" as recursive make, so # ensure that it appears directly in the makefile. string(REGEX REPLACE "^\\$\\(MAKE\\)" "\${make}" command "${command}") @@ -1169,7 +1273,7 @@ endif() # Wrap multiple 'COMMAND' lines up into a second-level wrapper # script so all output can be sent to one log file. - if("${command}" MATCHES ";COMMAND;") + if(command MATCHES ";COMMAND;") set(code_execute_process " ${code_cygpath_make} execute_process(COMMAND \${command} RESULT_VARIABLE result) @@ -1216,10 +1320,10 @@ if(result) foreach(arg IN LISTS command) set(msg \"\${msg} '\${arg}'\") endforeach() - set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\\n\") + set(msg \"\${msg}\\nSee also\\n ${logbase}-*.log\") message(FATAL_ERROR \"\${msg}\") else() - set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\\n\") + set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\") message(STATUS \"\${msg}\") endif() ") @@ -1256,19 +1360,28 @@ endfunction() function(ExternalProject_Add_StepTargets name) set(steps ${ARGN}) - + if("${ARGV1}" STREQUAL "NO_DEPENDS") + set(no_deps 1) + list(REMOVE_AT steps 0) + endif() foreach(step ${steps}) + if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$") + message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step might break parallel builds") + endif() _ep_get_step_stampfile(${name} ${step} stamp_file) add_custom_target(${name}-${step} DEPENDS ${stamp_file}) + set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1) set_property(TARGET ${name}-${step} PROPERTY LABELS ${name}) set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}") # Depend on other external projects (target-level). - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) - foreach(arg IN LISTS deps) - add_dependencies(${name}-${step} ${arg}) - endforeach() + if(NOT no_deps) + get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + foreach(arg IN LISTS deps) + add_dependencies(${name}-${step} ${arg}) + endforeach() + endif() endforeach() endfunction() @@ -1304,6 +1417,9 @@ function(ExternalProject_Add_Step name step) # Dependencies on files. get_property(depends TARGET ${name} PROPERTY _EP_${step}_DEPENDS) + # Byproducts of the step. + get_property(byproducts TARGET ${name} PROPERTY _EP_${step}_BYPRODUCTS) + # Dependencies on steps. get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES) foreach(dependee IN LISTS dependees) @@ -1350,8 +1466,18 @@ function(ExternalProject_Add_Step name step) _ep_write_log_script(${name} ${step} command) endif() + if("${command}" STREQUAL "") + # Some generators (i.e. Xcode) will not generate a file level target + # if no command is set, and therefore the dependencies on this + # target will be broken. + # The empty command is replaced by an echo command here in order to + # avoid this issue. + set(command ${CMAKE_COMMAND} -E echo_append) + endif() + add_custom_command( OUTPUT ${stamp_file} + BYPRODUCTS ${byproducts} COMMENT ${comment} COMMAND ${command} COMMAND ${touch} @@ -1359,6 +1485,7 @@ function(ExternalProject_Add_Step name step) WORKING_DIRECTORY ${work_dir} VERBATIM ) + set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step}) # Add custom "step target"? get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS) @@ -1371,6 +1498,60 @@ function(ExternalProject_Add_Step name step) break() endif() endforeach() + + get_property(independent_step_targets TARGET ${name} PROPERTY _EP_INDEPENDENT_STEP_TARGETS) + if(NOT independent_step_targets) + get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS) + endif() + foreach(st ${independent_step_targets}) + if("${st}" STREQUAL "${step}") + ExternalProject_Add_StepTargets(${name} NO_DEPENDS ${step}) + break() + endif() + endforeach() +endfunction() + + +function(ExternalProject_Add_StepDependencies name step) + set(dependencies ${ARGN}) + + # Sanity checks on "name" and "step". + if(NOT TARGET ${name}) + message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.") + endif() + + get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT) + if(NOT is_ep) + message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.") + endif() + + get_property(steps TARGET ${name} PROPERTY _EP_STEPS) + list(FIND steps ${step} is_step) + if(NOT is_step) + message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".") + endif() + + if(TARGET ${name}-${step}) + get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP) + if(NOT is_ep_step) + message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add_StepTargets.") + endif() + endif() + + # Always add file-level dependency, but add target-level dependency + # only if the target exists for that step. + _ep_get_step_stampfile(${name} ${step} stamp_file) + foreach(dep ${dependencies}) + add_custom_command(APPEND + OUTPUT ${stamp_file} + DEPENDS ${dep}) + if(TARGET ${name}-${step}) + foreach(dep ${dependencies}) + add_dependencies(${name}-${step} ${dep}) + endforeach() + endif() + endforeach() + endfunction() @@ -1688,6 +1869,12 @@ function(_ep_add_update_command name) get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY) get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY) get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY ) + get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET) + if(update_disconnected_set) + get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED) + else() + get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED) + endif() set(work_dir) set(comment) @@ -1777,10 +1964,26 @@ Update to Mercurial >= 2.1.1. COMMENT ${comment} COMMAND ${cmd} ALWAYS ${always} + EXCLUDE_FROM_MAIN ${update_disconnected} WORKING_DIRECTORY ${work_dir} DEPENDEES download ${log} ) + + if(always AND update_disconnected) + _ep_get_step_stampfile(${name} skip-update skip-update_stamp_file) + string(REPLACE "Performing" "Skipping" comment "${comment}") + ExternalProject_Add_Step(${name} skip-update + COMMENT ${comment} + ALWAYS 1 + EXCLUDE_FROM_MAIN 1 + WORKING_DIRECTORY ${work_dir} + DEPENDEES download + ${log} + ) + set_property(SOURCE ${skip-update_stamp_file} PROPERTY SYMBOLIC 1) + endif() + endfunction() @@ -1833,11 +2036,20 @@ function(_ep_add_configure_command name) get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS) list(APPEND cmd ${cmake_args}) - # If there are any CMAKE_CACHE_ARGS, write an initial cache and use it + # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS, + # write an initial cache and use it get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS) - if(cmake_cache_args) + get_property(cmake_cache_default_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS) + + if(cmake_cache_args OR cmake_cache_default_args) set(_ep_cache_args_script "${tmp_dir}/${name}-cache.cmake") - _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${cmake_cache_args}") + if(cmake_cache_args) + _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1) + endif() + if(cmake_cache_default_args) + _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0) + endif() + _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}") list(APPEND cmd "-C${_ep_cache_args_script}") endif() @@ -1893,10 +2105,22 @@ function(_ep_add_configure_command name) set(log "") endif() + get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET) + if(update_disconnected_set) + get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED) + else() + get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED) + endif() + if(update_disconnected) + set(update_dep skip-update) + else() + set(update_dep update) + endif() + ExternalProject_Add_Step(${name} configure COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} - DEPENDEES update patch + DEPENDEES ${update_dep} patch DEPENDS ${file_deps} ${log} ) @@ -1927,8 +2151,11 @@ function(_ep_add_build_command name) set(always 0) endif() + get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS) + ExternalProject_Add_Step(${name} build COMMAND ${cmd} + BYPRODUCTS ${build_byproducts} WORKING_DIRECTORY ${binary_dir} DEPENDEES configure ALWAYS ${always} @@ -1968,12 +2195,13 @@ function(_ep_add_test_command name) get_property(before TARGET ${name} PROPERTY _EP_TEST_BEFORE_INSTALL) get_property(after TARGET ${name} PROPERTY _EP_TEST_AFTER_INSTALL) + get_property(exclude TARGET ${name} PROPERTY _EP_TEST_EXCLUDE_FROM_MAIN) get_property(cmd_set TARGET ${name} PROPERTY _EP_TEST_COMMAND SET) # Only actually add the test step if one of the test related properties is # explicitly set. (i.e. the test step is omitted unless requested...) # - if(cmd_set OR before OR after) + if(cmd_set OR before OR after OR exclude) if(cmd_set) get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND) else() @@ -1981,9 +2209,21 @@ function(_ep_add_test_command name) endif() if(before) - set(dep_args DEPENDEES build DEPENDERS install) + set(dependees_args DEPENDEES build) else() - set(dep_args DEPENDEES install) + set(dependees_args DEPENDEES install) + endif() + + if(exclude) + set(dependers_args "") + set(exclude_args EXCLUDE_FROM_MAIN 1) + else() + if(before) + set(dependers_args DEPENDERS install) + else() + set(dependers_args "") + endif() + set(exclude_args "") endif() get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST) @@ -1996,7 +2236,9 @@ function(_ep_add_test_command name) ExternalProject_Add_Step(${name} test COMMAND ${cmd} WORKING_DIRECTORY ${binary_dir} - ${dep_args} + ${dependees_args} + ${dependers_args} + ${exclude_args} ${log} ) endif() diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index 37bc6b5..3eea9db 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -17,7 +17,7 @@ # :: # # -- The following OPTIONAL packages have been found: -# LibXml2 (required version >= 2.4) , XML processing library. , <http://xmlsoft.org> +# LibXml2 (required version >= 2.4), XML processing lib, <http://xmlsoft.org> # * Enables HTML-import in MyWordProcessor # * Enables odt-export in MyWordProcessor # PNG , A PNG image library. , <http://www.libpng.org/pub/png/> @@ -40,7 +40,7 @@ # [FATAL_ON_MISSING_REQUIRED_PACKAGES] # [DESCRIPTION "Found packages:"] # WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND -# | ENABLED_FEATURES | DISABLED_FEATURES] +# | ENABLED_FEATURES | DISABLED_FEATURES) # ) # # @@ -265,7 +265,7 @@ # Does the same as SET_PACKAGE_INFO(<name> <description> <url> ) #============================================================================= -# Copyright 2007-2009 Kitware, Inc. +# Copyright 2007-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index aad6575..99293c1 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -478,7 +478,7 @@ else() # The user has not requested an exact version. Among known # versions, find those that are acceptable to the user request. set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} - "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54" + "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51" "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1" "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42" diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 3dd975c..cae9214 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -276,15 +276,17 @@ # Only available for CUDA version 4.0+. # CUDA_curand_LIBRARY -- CUDA Random Number Generation library. # Only available for CUDA version 3.2+. +# CUDA_cusolver_LIBRARY -- CUDA Direct Solver library. +# Only available for CUDA version 7.0+. # CUDA_cusparse_LIBRARY -- CUDA Sparse Matrix library. # Only available for CUDA version 3.2+. -# CUDA_npp_LIBRARY -- NVIDIA Performance Primitives library. +# CUDA_npp_LIBRARY -- NVIDIA Performance Primitives lib. # Only available for CUDA version 4.0+. -# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives library (core). +# CUDA_nppc_LIBRARY -- NVIDIA Performance Primitives lib (core). # Only available for CUDA version 5.5+. -# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives library (image processing). +# CUDA_nppi_LIBRARY -- NVIDIA Performance Primitives lib (image processing). # Only available for CUDA version 5.5+. -# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives library (signal processing). +# CUDA_npps_LIBRARY -- NVIDIA Performance Primitives lib (signal processing). # Only available for CUDA version 5.5+. # CUDA_nvcuvenc_LIBRARY -- CUDA Video Encoder library. # Only available for CUDA version 3.2+. @@ -518,6 +520,7 @@ macro(cuda_unset_include_and_libraries) unset(CUDA_cufft_LIBRARY CACHE) unset(CUDA_cufftemu_LIBRARY CACHE) unset(CUDA_curand_LIBRARY CACHE) + unset(CUDA_cusolver_LIBRARY CACHE) unset(CUDA_cusparse_LIBRARY CACHE) unset(CUDA_npp_LIBRARY CACHE) unset(CUDA_nppc_LIBRARY CACHE) @@ -613,7 +616,7 @@ endif() set(CUDA_VERSION_STRING "${CUDA_VERSION}") # Support for arm cross compilation with CUDA 5.5 -if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" AND EXISTS "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf") +if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm" AND EXISTS "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf") set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT_DIR}/targets/armv7-linux-gnueabihf" CACHE PATH "Toolkit target location.") else() set(CUDA_TOOLKIT_TARGET_DIR "${CUDA_TOOLKIT_ROOT_DIR}" CACHE PATH "Toolkit target location.") @@ -621,7 +624,7 @@ endif() mark_as_advanced(CUDA_TOOLKIT_TARGET_DIR) # Target CPU architecture -if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND ${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") +if(CUDA_VERSION VERSION_GREATER "5.0" AND CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm") set(_cuda_target_cpu_arch_initial "ARM") else() set(_cuda_target_cpu_arch_initial "") @@ -754,6 +757,10 @@ if(CUDA_VERSION VERSION_GREATER "5.0") elseif(NOT CUDA_VERSION VERSION_LESS "4.0") find_cuda_helper_libs(npp) endif() +if(NOT CUDA_VERSION VERSION_LESS "7.0") + # cusolver showed up in version 7.0 + find_cuda_helper_libs(cusolver) +endif() if (CUDA_BUILD_EMULATION) set(CUDA_CUFFT_LIBRARIES ${CUDA_cufftemu_LIBRARY}) @@ -1423,7 +1430,8 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER ) list(APPEND nvcc_flags -ccbin "\"${CUDA_HOST_COMPILER}\"") endif() - # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} + + # Create a list of flags specified by CUDA_NVCC_FLAGS_${CONFIG} and CMAKE_${CUDA_C_OR_CXX}_FLAGS* set(config_specific_flags) set(flags) foreach(config ${CUDA_configuration_types}) @@ -1438,6 +1446,13 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>) endforeach() endforeach() + # Add CMAKE_${CUDA_C_OR_CXX}_FLAGS + set(important_host_flags) + _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS}) + foreach(f ${important_host_flags}) + list(APPEND flags -Xcompiler ${f}) + endforeach() + # Add our general CUDA_NVCC_FLAGS with the configuration specifig flags set(nvcc_flags ${CUDA_NVCC_FLAGS} ${config_specific_flags} ${nvcc_flags}) diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake index a21ca89..f94bd09 100644 --- a/Modules/FindCurses.cmake +++ b/Modules/FindCurses.cmake @@ -179,11 +179,6 @@ if(NOT DEFINED CURSES_HAVE_CURSES_H) endif() endif() -if (NOT CURSES_TINFO_HAS_CBREAK) - find_library(CURSES_EXTRA_LIBRARY cur_colr HINTS "${_cursesLibDir}") - find_library(CURSES_EXTRA_LIBRARY cur_colr ) -endif() - find_library(CURSES_FORM_LIBRARY form HINTS "${_cursesLibDir}") find_library(CURSES_FORM_LIBRARY form ) diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake new file mode 100644 index 0000000..ef125c0 --- /dev/null +++ b/Modules/FindGSL.cmake @@ -0,0 +1,238 @@ +#.rst: +# FindGSL +# -------- +# +# Find the native GSL includes and libraries. +# +# The GNU Scientific Library (GSL) is a numerical library for C and C++ +# programmers. It is free software under the GNU General Public +# License. +# +# Imported Targets +# ^^^^^^^^^^^^^^^^ +# +# If GSL is found, this module defines the following :prop_tgt:`IMPORTED` +# targets:: +# +# GSL::gsl - The main GSL library. +# GSL::gslcblas - The CBLAS support library used by GSL. +# +# Result Variables +# ^^^^^^^^^^^^^^^^ +# +# This module will set the following variables in your project:: +# +# GSL_FOUND - True if GSL found on the local system +# GSL_INCLUDE_DIRS - Location of GSL header files. +# GSL_LIBRARIES - The GSL libraries. +# GSL_VERSION - The version of the discovered GSL install. +# +# Hints +# ^^^^^ +# +# Set ``GSL_ROOT_DIR`` to a directory that contains a GSL installation. +# +# This script expects to find libraries at ``$GSL_ROOT_DIR/lib`` and the GSL +# headers at ``$GSL_ROOT_DIR/include/gsl``. The library directory may +# optionally provide Release and Debug folders. For Unix-like systems, this +# script will use ``$GSL_ROOT_DIR/bin/gsl-config`` (if found) to aid in the +# discovery GSL. +# +# Cache Variables +# ^^^^^^^^^^^^^^^ +# +# This module may set the following variables depending on platform and type +# of GSL installation discovered. These variables may optionally be set to +# help this module find the correct files:: +# +# GSL_CLBAS_LIBRARY - Location of the GSL CBLAS library. +# GSL_CBLAS_LIBRARY_DEBUG - Location of the debug GSL CBLAS library (if any). +# GSL_CONFIG_EXECUTABLE - Location of the ``gsl-config`` script (if any). +# GSL_LIBRARY - Location of the GSL library. +# GSL_LIBRARY_DEBUG - Location of the debug GSL library (if any). +# + +#============================================================================= +# Copyright 2014 Kelly Thompson <kgt@lanl.gov> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Include these modules to handle the QUIETLY and REQUIRED arguments. +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) + +#============================================================================= +# If the user has provided ``GSL_ROOT_DIR``, use it! Choose items found +# at this location over system locations. +if( EXISTS "$ENV{GSL_ROOT_DIR}" ) + file( TO_CMAKE_PATH "$ENV{GSL_ROOT_DIR}" GSL_ROOT_DIR ) + set( GSL_ROOT_DIR "${GSL_ROOT_DIR}" CACHE PATH "Prefix for GSL installation." ) +endif() +if( NOT EXISTS "${GSL_ROOT_DIR}" ) + set( GSL_USE_PKGCONFIG ON ) +endif() + +#============================================================================= +# As a first try, use the PkgConfig module. This will work on many +# *NIX systems. See :module:`findpkgconfig` +# This will return ``GSL_INCLUDEDIR`` and ``GSL_LIBDIR`` used below. +if( GSL_USE_PKGCONFIG ) + find_package(PkgConfig) + pkg_check_modules( GSL QUIET gsl ) + + if( EXISTS "${GSL_INCLUDEDIR}" ) + get_filename_component( GSL_ROOT_DIR "${GSL_INCLUDEDIR}" DIRECTORY CACHE) + endif() +endif() + +#============================================================================= +# Set GSL_INCLUDE_DIRS and GSL_LIBRARIES. If we skipped the PkgConfig step, try +# to find the libraries at $GSL_ROOT_DIR (if provided) or in standard system +# locations. These find_library and find_path calls will prefer custom +# locations over standard locations (HINTS). If the requested file is not found +# at the HINTS location, standard system locations will be still be searched +# (/usr/lib64 (Redhat), lib/i386-linux-gnu (Debian)). + +find_path( GSL_INCLUDE_DIR + NAMES gsl/gsl_sf.h + HINTS ${GSL_ROOT_DIR}/include ${GSL_INCLUDEDIR} +) +find_library( GSL_LIBRARY + NAMES gsl + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Release Debug +) +find_library( GSL_CBLAS_LIBRARY + NAMES gslcblas cblas + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Release Debug +) +# Do we also have debug versions? +find_library( GSL_LIBRARY_DEBUG + NAMES gsl + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Debug +) +find_library( GSL_CBLAS_LIBRARY_DEBUG + NAMES gslcblas cblas + HINTS ${GSL_ROOT_DIR}/lib ${GSL_LIBDIR} + PATH_SUFFIXES Debug +) +set( GSL_INCLUDE_DIRS ${GSL_INCLUDE_DIR} ) +set( GSL_LIBRARIES ${GSL_LIBRARY} ${GSL_CBLAS_LIBRARY} ) + +# If we didn't use PkgConfig, try to find the version via gsl-config or by +# reading gsl_version.h. +if( NOT GSL_VERSION ) + # 1. If gsl-config exists, query for the version. + find_program( GSL_CONFIG_EXECUTABLE + NAMES gsl-config + HINTS "${GSL_ROOT_DIR}/bin" + ) + if( EXISTS "${GSL_CONFIG_EXECUTABLE}" ) + execute_process( + COMMAND "${GSL_CONFIG_EXECUTABLE}" --version + OUTPUT_VARIABLE GSL_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE ) + endif() + + # 2. If gsl-config is not available, try looking in gsl/gsl_version.h + if( NOT GSL_VERSION AND EXISTS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" ) + file( STRINGS "${GSL_INCLUDE_DIRS}/gsl/gsl_version.h" gsl_version_h_contents REGEX "define GSL_VERSION" ) + string( REGEX REPLACE ".*([0-9].[0-9][0-9]).*" "\\1" GSL_VERSION ${gsl_version_h_contents} ) + endif() + + # might also try scraping the directory name for a regex match "gsl-X.X" +endif() + +#============================================================================= +# handle the QUIETLY and REQUIRED arguments and set GSL_FOUND to TRUE if all +# listed variables are TRUE +find_package_handle_standard_args( GSL + FOUND_VAR + GSL_FOUND + REQUIRED_VARS + GSL_INCLUDE_DIR + GSL_LIBRARY + GSL_CBLAS_LIBRARY + VERSION_VAR + GSL_VERSION + ) + +mark_as_advanced( GSL_ROOT_DIR GSL_VERSION GSL_LIBRARY GSL_INCLUDE_DIR + GSL_CBLAS_LIBRARY GSL_LIBRARY_DEBUG GSL_CBLAS_LIBRARY_DEBUG + GSL_USE_PKGCONFIG GSL_CONFIG ) + +#============================================================================= +# Register imported libraries: +# 1. If we can find a Windows .dll file (or if we can find both Debug and +# Release libraries), we will set appropriate target properties for these. +# 2. However, for most systems, we will only register the import location and +# include directory. + +# Look for dlls, or Release and Debug libraries. +if(WIN32) + string( REPLACE ".lib" ".dll" GSL_LIBRARY_DLL "${GSL_LIBRARY}" ) + string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DLL "${GSL_CBLAS_LIBRARY}" ) + string( REPLACE ".lib" ".dll" GSL_LIBRARY_DEBUG_DLL "${GSL_LIBRARY_DEBUG}" ) + string( REPLACE ".lib" ".dll" GSL_CBLAS_LIBRARY_DEBUG_DLL "${GSL_CBLAS_LIBRARY_DEBUG}" ) +endif() + +if( GSL_FOUND AND NOT TARGET GSL::gsl ) + if( EXISTS "${GSL_LIBRARY_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DLL}") + + # Windows systems with dll libraries. + add_library( GSL::gsl SHARED IMPORTED ) + add_library( GSL::gslcblas SHARED IMPORTED ) + + # Windows with dlls, but only Release libraries. + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION_RELEASE "${GSL_CBLAS_LIBRARY_DLL}" + IMPORTED_IMPLIB "${GSL_CBLAS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_CONFIGURATIONS Release + IMPORTED_LINK_INTERFACE_LANGUAGES "C" ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION_RELEASE "${GSL_LIBRARY_DLL}" + IMPORTED_IMPLIB "${GSL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_CONFIGURATIONS Release + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_LINK_LIBRARIES GSL::gslcblas ) + + # If we have both Debug and Release libraries + if( EXISTS "${GSL_LIBRARY_DEBUG_DLL}" AND EXISTS "${GSL_CBLAS_LIBRARY_DEBUG_DLL}") + set_property( TARGET GSL::gslcblas APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug ) + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG_DLL}" + IMPORTED_IMPLIB_DEBUG "${GSL_CBLAS_LIBRARY_DEBUG}" ) + set_property( TARGET GSL::gsl APPEND PROPERTY IMPORTED_CONFIGURATIONS Debug ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION_DEBUG "${GSL_LIBRARY_DEBUG_DLL}" + IMPORTED_IMPLIB_DEBUG "${GSL_LIBRARY_DEBUG}" ) + endif() + + else() + + # For all other environments (ones without dll libraries), create + # the imported library targets. + add_library( GSL::gsl UNKNOWN IMPORTED ) + add_library( GSL::gslcblas UNKNOWN IMPORTED ) + set_target_properties( GSL::gslcblas PROPERTIES + IMPORTED_LOCATION "${GSL_CBLAS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" ) + set_target_properties( GSL::gsl PROPERTIES + IMPORTED_LOCATION "${GSL_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${GSL_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + INTERFACE_LINK_LIBRARIES GSL::gslcblas ) + endif() +endif() diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index 16478cb..ac53c3f 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -17,6 +17,7 @@ # # # Additionally it provides the following macros: +# # GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] file1 ... fileN ) # # :: @@ -32,8 +33,9 @@ # :: # # Process the given pot file to mo files. -# If INSTALL_DESTINATION is given then automatically install rules will be created, -# the language subdirectory will be taken into account (by default use share/locale/). +# If INSTALL_DESTINATION is given then automatically install rules will +# be created, the language subdirectory will be taken into account +# (by default use share/locale/). # If ALL is specified, the pot file is processed when building the all traget. # It creates a custom target "potfile". # @@ -43,10 +45,14 @@ # :: # # Process the given po files to mo files for the given language. -# If INSTALL_DESTINATION is given then automatically install rules will be created, -# the language subdirectory will be taken into account (by default use share/locale/). +# If INSTALL_DESTINATION is given then automatically install rules will +# be created, the language subdirectory will be taken into account +# (by default use share/locale/). # If ALL is specified, the po files are processed when building the all traget. # It creates a custom target "pofiles". +# +# .. note:: +# If you wish to use the Gettext library (libintl), use :module:`FindIntl`. #============================================================================= # Copyright 2007-2009 Kitware, Inc. diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index 570538d..b4f7b4b 100644 --- a/Modules/FindGit.cmake +++ b/Modules/FindGit.cmake @@ -45,11 +45,15 @@ set(git_names git eg) if(WIN32) if(NOT CMAKE_GENERATOR MATCHES "MSYS") set(git_names git.cmd git eg.cmd eg) + # GitHub search path for Windows + set(github_path "$ENV{LOCALAPPDATA}/Github/PortableGit*/bin") + file(GLOB github_path "${github_path}") endif() endif() find_program(GIT_EXECUTABLE NAMES ${git_names} + PATHS ${github_path} PATH_SUFFIXES Git/cmd Git/bin DOC "git command line client" ) diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake index 55528b8..8493d80 100644 --- a/Modules/FindIce.cmake +++ b/Modules/FindIce.cmake @@ -43,7 +43,7 @@ # # Ice_HOME - the root of the Ice installation # -# The environment variable :envvar:`ICE_HOME` may also be used; the +# The environment variable ``ICE_HOME`` may also be used; the # Ice_HOME variable takes precedence. # # The following cache variables may also be set:: @@ -282,21 +282,21 @@ function(_Ice_FIND) PATH_SUFFIXES ${ice_library_suffixes} DOC "Ice ${component} library") mark_as_advanced("${component_cache}") - if("${component_cache}") + if(${component_cache}) set("${component_found}" ON) list(APPEND Ice_LIBRARY "${${component_cache}}") endif() mark_as_advanced("${component_found}") set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) set("${component_found}" "${${component_found}}" PARENT_SCOPE) - if("${component_found}") - if ("Ice_FIND_REQUIRED_${component}") + if(${component_found}) + if (Ice_FIND_REQUIRED_${component}) list(APPEND Ice_LIBS_FOUND "${component} (required)") else() list(APPEND Ice_LIBS_FOUND "${component} (optional)") endif() else() - if ("Ice_FIND_REQUIRED_${component}") + if (Ice_FIND_REQUIRED_${component}) set(Ice_REQUIRED_LIBS_FOUND OFF) list(APPEND Ice_LIBS_NOTFOUND "${component} (required)") else() @@ -356,7 +356,7 @@ if(Ice_FOUND) set(_Ice_component_cache "Ice_${_Ice_component_upcase}_LIBRARY") set(_Ice_component_lib "Ice_${_Ice_component_upcase}_LIBRARIES") set(_Ice_component_found "${_Ice_component_upcase}_FOUND") - if("${_Ice_component_found}") + if(${_Ice_component_found}) set("${_Ice_component_lib}" "${${_Ice_component_cache}}") endif() unset(_Ice_component_upcase) diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake new file mode 100644 index 0000000..cd2ec63 --- /dev/null +++ b/Modules/FindIntl.cmake @@ -0,0 +1,69 @@ +#.rst: +# FindIntl +# -------- +# +# Find the Gettext libintl headers and libraries. +# +# This module reports information about the Gettext libintl +# installation in several variables. General variables:: +# +# Intl_FOUND - true if the libintl headers and libraries were found +# Intl_INCLUDE_DIRS - the directory containing the libintl headers +# Intl_LIBRARIES - libintl libraries to be linked +# +# The following cache variables may also be set:: +# +# Intl_INCLUDE_DIR - the directory containing the libintl headers +# Intl_LIBRARY - the libintl library (if any) +# +# .. note:: +# On some platforms, such as Linux with GNU libc, the gettext +# functions are present in the C standard library and libintl +# is not required. ``Intl_LIBRARIES`` will be empty in this +# case. +# +# .. note:: +# If you wish to use the Gettext tools (``msgmerge``, +# ``msgfmt``, etc.), use :module:`FindGettext`. + + +# Written by Roger Leigh <rleigh@codelibre.net> + +#============================================================================= +# Copyright 2014 Roger Leigh <rleigh@codelibre.net> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Find include directory +find_path(Intl_INCLUDE_DIR + NAMES "libintl.h" + DOC "libintl include directory") +mark_as_advanced(Intl_INCLUDE_DIR) + +# Find all Intl libraries +find_library(Intl_LIBRARY "intl" + DOC "libintl libraries (if not in the C library)") +mark_as_advanced(Intl_LIBRARY) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Intl + FOUND_VAR Intl_FOUND + REQUIRED_VARS Intl_INCLUDE_DIR + FAIL_MESSAGE "Failed to find Gettext libintl") + +if(Intl_FOUND) + set(Intl_INCLUDE_DIRS "${Intl_INCLUDE_DIR}") + if(Intl_LIBRARY) + set(Intl_LIBRARIES "${Intl_LIBRARY}") + else() + unset(Intl_LIBRARIES) + endif() +endif() diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index 0bd7eb0..bb73853 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -17,7 +17,7 @@ # Java_JAVAH_EXECUTABLE = the full path to the Java header generator # Java_JAVADOC_EXECUTABLE = the full path to the Java documention generator # Java_JAR_EXECUTABLE = the full path to the Java archiver -# Java_VERSION_STRING = Version of the package found (java version), eg. 1.6.0_12 +# Java_VERSION_STRING = Version of java found, eg. 1.6.0_12 # Java_VERSION_MAJOR = The major version of the package found. # Java_VERSION_MINOR = The minor version of the package found. # Java_VERSION_PATCH = The patch version of the package found. @@ -115,7 +115,10 @@ if(Java_JAVA_EXECUTABLE) OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) if( res ) - if(${Java_FIND_REQUIRED}) + if(var MATCHES "No Java runtime present, requesting install") + set_property(CACHE Java_JAVA_EXECUTABLE + PROPERTY VALUE "Java_JAVA_EXECUTABLE-NOTFOUND") + elseif(${Java_FIND_REQUIRED}) message( FATAL_ERROR "Error executing java -version" ) else() message( STATUS "Warning, could not run java -version") diff --git a/Modules/FindJsonCpp.cmake b/Modules/FindJsonCpp.cmake new file mode 100644 index 0000000..cbb4fb3 --- /dev/null +++ b/Modules/FindJsonCpp.cmake @@ -0,0 +1,117 @@ +#[=======================================================================[.rst: +FindJsonCpp +----------- + +Find JsonCpp includes and library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +An :ref:`imported target <Imported targets>` named +``JsonCpp::JsonCpp`` is provided if JsonCpp has been found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``JsonCpp_FOUND`` + True if JsonCpp was found, false otherwise. +``JsonCpp_INCLUDE_DIRS`` + Include directories needed to include JsonCpp headers. +``JsonCpp_LIBRARIES`` + Libraries needed to link to JsonCpp. +``JsonCpp_VERSION_STRING`` + The version of JsonCpp found. + May not be set for JsonCpp versions prior to 1.0. +``JsonCpp_VERSION_MAJOR`` + The major version of JsonCpp. +``JsonCpp_VERSION_MINOR`` + The minor version of JsonCpp. +``JsonCpp_VERSION_PATCH`` + The patch version of JsonCpp. + +Cache Variables +^^^^^^^^^^^^^^^ + +This module uses the following cache variables: + +``JsonCpp_LIBRARY`` + The location of the JsonCpp library file. +``JsonCpp_INCLUDE_DIR`` + The location of the JsonCpp include directory containing ``json/json.h``. + +The cache variables should not be used by project code. +They may be set by end users to point at JsonCpp components. +#]=======================================================================] + +#============================================================================= +# Copyright 2014-2015 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +#----------------------------------------------------------------------------- +find_library(JsonCpp_LIBRARY + NAMES jsoncpp + ) +mark_as_advanced(JsonCpp_LIBRARY) + +find_path(JsonCpp_INCLUDE_DIR + NAMES json/json.h + PATH_SUFFIXES jsoncpp + ) +mark_as_advanced(JsonCpp_INCLUDE_DIR) + +#----------------------------------------------------------------------------- +# Extract version number if possible. +set(_JsonCpp_H_REGEX "^#[ \t]*define[ \t]+JSONCPP_VERSION_STRING[ \t]+\"(([0-9]+)\\.([0-9]+)\\.([0-9]+)[^\"]*)\".*$") +if(JsonCpp_INCLUDE_DIR AND EXISTS "${JsonCpp_INCLUDE_DIR}/json/version.h") + file(STRINGS "${JsonCpp_INCLUDE_DIR}/json/version.h" _JsonCpp_H REGEX "${_JsonCpp_H_REGEX}") +else() + set(_JsonCpp_H "") +endif() +if(_JsonCpp_H MATCHES "${_JsonCpp_H_REGEX}") + set(JsonCpp_VERSION_STRING "${CMAKE_MATCH_1}") + set(JsonCpp_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(JsonCpp_VERSION_MINOR "${CMAKE_MATCH_3}") + set(JsonCpp_VERSION_PATCH "${CMAKE_MATCH_4}") +else() + set(JsonCpp_VERSION_STRING "") + set(JsonCpp_VERSION_MAJOR "") + set(JsonCpp_VERSION_MINOR "") + set(JsonCpp_VERSION_PATCH "") +endif() +unset(_JsonCpp_H_REGEX) +unset(_JsonCpp_H) + +#----------------------------------------------------------------------------- +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(JsonCpp + FOUND_VAR JsonCpp_FOUND + REQUIRED_VARS JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR + VERSION_VAR JsonCpp_VERSION_STRING + ) +set(JSONCPP_FOUND ${JsonCpp_FOUND}) + +#----------------------------------------------------------------------------- +# Provide documented result variables and targets. +if(JsonCpp_FOUND) + set(JsonCpp_INCLUDE_DIRS ${JsonCpp_INCLUDE_DIR}) + set(JsonCpp_LIBRARIES ${JsonCpp_LIBRARY}) + if(NOT TARGET JsonCpp::JsonCpp) + add_library(JsonCpp::JsonCpp UNKNOWN IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES + IMPORTED_LOCATION "${JsonCpp_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${JsonCpp_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + ) + endif() +endif() diff --git a/Modules/FindLATEX.cmake b/Modules/FindLATEX.cmake index e353d38..ae83733 100644 --- a/Modules/FindLATEX.cmake +++ b/Modules/FindLATEX.cmake @@ -4,21 +4,54 @@ # # Find Latex # -# This module finds if Latex is installed and determines where the -# executables are. This code sets the following variables: +# This module finds an installed Latex and determines the location +# of the compiler. Additionally the module looks for Latex-related +# software like BibTeX. # -# :: +# This module sets the following result variables:: # +# LATEX_FOUND: whether found Latex and requested components +# LATEX_<component>_FOUND: whether found <component> # LATEX_COMPILER: path to the LaTeX compiler # PDFLATEX_COMPILER: path to the PdfLaTeX compiler +# XELATEX_COMPILER: path to the XeLaTeX compiler +# LUALATEX_COMPILER: path to the LuaLaTeX compiler # BIBTEX_COMPILER: path to the BibTeX compiler +# BIBER_COMPILER: path to the Biber compiler # MAKEINDEX_COMPILER: path to the MakeIndex compiler +# XINDY_COMPILER: path to the xindy compiler # DVIPS_CONVERTER: path to the DVIPS converter +# DVIPDF_CONVERTER: path to the DVIPDF converter # PS2PDF_CONVERTER: path to the PS2PDF converter +# PDFTOPS_CONVERTER: path to the pdftops converter # LATEX2HTML_CONVERTER: path to the LaTeX2Html converter +# HTLATEX_COMPILER: path to the htlatex compiler +# +# Possible components are:: +# +# PDFLATEX +# XELATEX +# LUALATEX +# BIBTEX +# BIBER +# MAKEINDEX +# XINDY +# DVIPS +# DVIPDF +# PS2PDF +# PDFTOPS +# LATEX2HTML +# HTLATEX +# +# Example Usages:: +# +# find_package(LATEX) +# find_package(LATEX COMPONENTS PDFLATEX) +# find_package(LATEX COMPONENTS BIBTEX PS2PDF) #============================================================================= -# Copyright 2002-2009 Kitware, Inc. +# Copyright 2002-2015 Kitware, Inc. +# Copyright 2014-2015 Christoph Grüninger <foss@grueninger.de> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -31,9 +64,7 @@ # License text for the above reference.) if (WIN32) - # Try to find the MikTex binary path (look for its package manager). - find_path(MIKTEX_BINARY_PATH mpm.exe "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MiK\\MiKTeX\\CurrentVersion\\MiKTeX;Install Root]/miktex/bin" DOC @@ -42,7 +73,6 @@ if (WIN32) mark_as_advanced(MIKTEX_BINARY_PATH) # Try to find the GhostScript binary path (look for gswin32). - get_filename_component(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\8.00;GS_DLL]" PATH ) @@ -63,45 +93,124 @@ if (WIN32) DOC "Path to the GhostScript library directory." ) mark_as_advanced(GHOSTSCRIPT_LIBRARY_PATH) - endif () +# try to find Latex and the related programs find_program(LATEX_COMPILER NAMES latex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +# find pdflatex find_program(PDFLATEX_COMPILER NAMES pdflatex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (PDFLATEX_COMPILER) + set(LATEX_PDFLATEX_FOUND TRUE) +else() + set(LATEX_PDFLATEX_FOUND FALSE) +endif() +# find xelatex +find_program(XELATEX_COMPILER + NAMES xelatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (XELATEX_COMPILER) + set(LATEX_XELATEX_FOUND TRUE) +else() + set(LATEX_XELATEX_FOUND FALSE) +endif() + +# find lualatex +find_program(LUALATEX_COMPILER + NAMES lualatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (LUALATEX_COMPILER) + set(LATEX_LUALATEX_FOUND TRUE) +else() + set(LATEX_LUALATEX_FOUND FALSE) +endif() + +# find bibtex find_program(BIBTEX_COMPILER NAMES bibtex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (BIBTEX_COMPILER) + set(LATEX_BIBTEX_FOUND TRUE) +else() + set(LATEX_BIBTEX_FOUND FALSE) +endif() + +# find biber +find_program(BIBER_COMPILER + NAMES biber + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (BIBER_COMPILER) + set(LATEX_BIBER_FOUND TRUE) +else() + set(LATEX_BIBER_FOUND FALSE) +endif() +# find makeindex find_program(MAKEINDEX_COMPILER NAMES makeindex PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (MAKEINDEX_COMPILER) + set(LATEX_MAKEINDEX_FOUND TRUE) +else() + set(LATEX_MAKEINDEX_FOUND FALSE) +endif() +# find xindy +find_program(XINDY_COMPILER + NAMES xindy + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (XINDY_COMPILER) + set(LATEX_XINDY_FOUND TRUE) +else() + set(LATEX_XINDY_FOUND FALSE) +endif() + +# find dvips find_program(DVIPS_CONVERTER NAMES dvips PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (DVIPS_CONVERTER) + set(LATEX_DVIPS_FOUND TRUE) +else() + set(LATEX_DVIPS_FOUND FALSE) +endif() +# find dvipdf find_program(DVIPDF_CONVERTER NAMES dvipdfm dvipdft dvipdf PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (DVIPDF_CONVERTER) + set(LATEX_DVIPDF_FOUND TRUE) +else() + set(LATEX_DVIPDF_FOUND FALSE) +endif() +# find ps2pdf if (WIN32) find_program(PS2PDF_CONVERTER NAMES ps2pdf14.bat ps2pdf14 ps2pdf @@ -113,21 +222,69 @@ else () NAMES ps2pdf14 ps2pdf ) endif () +if (PS2PDF_CONVERTER) + set(LATEX_PS2PDF_FOUND TRUE) +else() + set(LATEX_PS2PDF_FOUND FALSE) +endif() +# find pdftops +find_program(PDFTOPS_CONVERTER + NAMES pdftops + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (PDFTOPS_CONVERTER) + set(LATEX_PDFTOPS_FOUND TRUE) +else() + set(LATEX_PDFTOPS_FOUND FALSE) +endif() + +# find latex2html find_program(LATEX2HTML_CONVERTER NAMES latex2html PATHS ${MIKTEX_BINARY_PATH} /usr/bin ) +if (LATEX2HTML_CONVERTER) + set(LATEX_LATEX2HTML_FOUND TRUE) +else() + set(LATEX_LATEX2HTML_FOUND FALSE) +endif() + +# find htlatex +find_program(HTLATEX_COMPILER + NAMES htlatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin +) +if (HTLATEX_COMPILER) + set(LATEX_HTLATEX_FOUND TRUE) +else() + set(LATEX_HTLATEX_FOUND FALSE) +endif() mark_as_advanced( LATEX_COMPILER PDFLATEX_COMPILER + XELATEX_COMPILER + LUALATEX_COMPILER BIBTEX_COMPILER + BIBER_COMPILER MAKEINDEX_COMPILER + XINDY_COMPILER DVIPS_CONVERTER DVIPDF_CONVERTER PS2PDF_CONVERTER + PDFTOPS_CONVERTER LATEX2HTML_CONVERTER + HTLATEX_COMPILER +) + +# handle variables for found Latex and its components +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(LATEX + REQUIRED_VARS LATEX_COMPILER + HANDLE_COMPONENTS ) diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake index bf2f821..2416341 100644 --- a/Modules/FindLibXslt.cmake +++ b/Modules/FindLibXslt.cmake @@ -17,10 +17,10 @@ # Additionally, the following two variables are set (but not required # for using xslt): # -# :: -# -# LIBXSLT_EXSLT_LIBRARIES - Link to these if you need to link against the exslt library -# LIBXSLT_XSLTPROC_EXECUTABLE - Contains the full path to the xsltproc executable if found +# ``LIBXSLT_EXSLT_LIBRARIES`` +# Link to these if you need to link against the exslt library. +# ``LIBXSLT_XSLTPROC_EXECUTABLE`` +# Contains the full path to the xsltproc executable if found. #============================================================================= # Copyright 2006-2009 Kitware, Inc. diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index ba4ea5b..545b077 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -174,6 +174,13 @@ set(_MPI_EXEC_NAMES mpiexec mpirun lamexec srun) # Grab the path to MPI from the registry if we're on windows. set(_MPI_PREFIX_PATH) if(WIN32) + # MSMPI + file(TO_CMAKE_PATH "$ENV{MSMPI_BIN}" msmpi_bin_path) # The default path ends with a '\' and doesn't mix with ';' when appending. + list(APPEND _MPI_PREFIX_PATH "${msmpi_bin_path}") + unset(msmpi_bin_path) + list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin") + list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_INC}/..") # The SDK is installed separately from the runtime + # MPICH list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..") list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]") list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/") @@ -188,6 +195,21 @@ foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH}) endforeach() endforeach() +function (_mpi_check_compiler compiler options cmdvar resvar) + execute_process( + COMMAND "${compiler}" ${options} + OUTPUT_VARIABLE cmdline OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE cmdline ERROR_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE success) + # Intel MPI 5.0.1 will return a zero return code even when the + # argument to the MPI compiler wrapper is unknown. Attempt to + # catch this case. + if("${cmdline}" MATCHES "undefined reference") + set(success 255 ) + endif() + set(${cmdvar} "${cmdline}" PARENT_SCOPE) + set(${resvar} "${success}" PARENT_SCOPE) +endfunction() # # interrogate_mpi_compiler(lang try_libs) @@ -220,12 +242,7 @@ function (interrogate_mpi_compiler lang try_libs) if (MPI_${lang}_COMPILER) # Check whether the -showme:compile option works. This indicates that we have either OpenMPI # or a newer version of LAM-MPI, and implies that -showme:link will also work. - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -showme:compile - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) - + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) if (MPI_COMPILER_RETURN EQUAL 0) # If we appear to have -showme:compile, then we should # also have -showme:link. Try it. @@ -257,20 +274,12 @@ function (interrogate_mpi_compiler lang try_libs) # Older versions of LAM-MPI have "-showme". Try to find that. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -showme - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() # MVAPICH uses -compile-info and -link-info. Try them. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -compile-info - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) # If we have compile-info, also have link-info. if (MPI_COMPILER_RETURN EQUAL 0) @@ -290,11 +299,7 @@ function (interrogate_mpi_compiler lang try_libs) # MPICH just uses "-show". Try it. if (NOT MPI_COMPILER_RETURN EQUAL 0) - execute_process( - COMMAND ${MPI_${lang}_COMPILER} -show - OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE MPI_COMPILER_RETURN) + _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN) endif() if (MPI_COMPILER_RETURN EQUAL 0) @@ -365,7 +370,7 @@ function (interrogate_mpi_compiler lang try_libs) endif() # Extract linker flags from the link command line - string(REGEX MATCHALL "(^| )-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}") + string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}") set(MPI_LINK_FLAGS_WORK) foreach(FLAG ${MPI_ALL_LINK_FLAGS}) if (MPI_LINK_FLAGS_WORK) @@ -423,16 +428,18 @@ function (interrogate_mpi_compiler lang try_libs) # Decide between 32-bit and 64-bit libraries for Microsoft's MPI if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8) - set(MS_MPI_ARCH_DIR amd64) + set(MS_MPI_ARCH_DIR x64) + set(MS_MPI_ARCH_DIR2 amd64) else() - set(MS_MPI_ARCH_DIR i386) + set(MS_MPI_ARCH_DIR x86) + set(MS_MPI_ARCH_DIR2 i386) endif() set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE) find_library(MPI_LIB NAMES mpi mpich mpich2 msmpi HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH} - PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR}) + PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} Lib/${MS_MPI_ARCH_DIR2}) set(MPI_LIBRARIES_WORK ${MPI_LIB}) # Right now, we only know about the extra libs for C++. diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 2b3bd14..a7eefa7 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -4,16 +4,6 @@ # # FindModule for OpenGL and GLU. # -# IMPORTED Targets -# ^^^^^^^^^^^^^^^^ -# -# This module defines the :prop_tgt:`IMPORTED` targets: -# -# ``OpenGL::GL`` -# Defined if the system has OpenGL. -# ``OpenGL::GLU`` -# Defined if the system has GLU. -# # Result Variables # ^^^^^^^^^^^^^^^^ # @@ -138,19 +128,6 @@ else() unset(_OPENGL_INCLUDE_PATH) unset(_OPENGL_LIB_PATH) - # On Unix OpenGL most certainly always requires X11. - # Feel free to tighten up these conditions if you don't - # think this is always true. - - if (OPENGL_gl_LIBRARY) - if(NOT X11_FOUND) - include(${CMAKE_CURRENT_LIST_DIR}/FindX11.cmake) - endif() - if (X11_FOUND) - set (OPENGL_LIBRARIES ${X11_LIBRARIES}) - endif () - endif () - find_library(OPENGL_glu_LIBRARY NAMES GLU MesaGLU PATHS ${OPENGL_gl_LIBRARY} @@ -191,36 +168,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenGL REQUIRED_VARS ${_OpenGL_REQUIRED_VARS}) unset(_OpenGL_REQUIRED_VARS) -# OpenGL:: targets -if(OPENGL_FOUND) - if(NOT TARGET OpenGL::GL) - add_library(OpenGL::GL UNKNOWN IMPORTED) - set_target_properties(OpenGL::GL PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${OPENGL_INCLUDE_DIR}") - if(OPENGL_gl_LIBRARY MATCHES "/([^/]+)\\.framework$") - set_target_properties(OpenGL::GL PROPERTIES - IMPORTED_LOCATION "${OPENGL_gl_LIBRARY}/${CMAKE_MATCH_1}") - else() - set_target_properties(OpenGL::GL PROPERTIES - IMPORTED_LOCATION "${OPENGL_gl_LIBRARY}") - endif() - endif() - - if(OPENGL_GLU_FOUND AND NOT TARGET OpenGL::GLU) - add_library(OpenGL::GLU UNKNOWN IMPORTED) - set_target_properties(OpenGL::GLU PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${OPENGL_INCLUDE_DIR}" - INTERFACE_LINK_LIBRARIES OpenGL::GL) - if(OPENGL_glu_LIBRARY MATCHES "/([^/]+)\\.framework$") - set_target_properties(OpenGL::GLU PROPERTIES - IMPORTED_LOCATION "${OPENGL_glu_LIBRARY}/${CMAKE_MATCH_1}") - else() - set_target_properties(OpenGL::GLU PROPERTIES - IMPORTED_LOCATION "${OPENGL_glu_LIBRARY}") - endif() - endif() -endif() - mark_as_advanced( OPENGL_INCLUDE_DIR OPENGL_xmesa_INCLUDE_DIR diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index 801b4f8..a102c66 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -111,11 +111,11 @@ int main() { # same in Fortran set(OpenMP_Fortran_TEST_SOURCE " -program test -use omp_lib -integer :: n -n = omp_get_num_threads() -end program test + program test + use omp_lib + integer :: n + n = omp_get_num_threads() + end program test " ) diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 340b417..bfbe01f 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -16,10 +16,12 @@ # # :: # -# OPENSSL_FOUND - system has the OpenSSL library -# OPENSSL_INCLUDE_DIR - the OpenSSL include directory -# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL -# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s) +# OPENSSL_FOUND - System has the OpenSSL library +# OPENSSL_INCLUDE_DIR - The OpenSSL include directory +# OPENSSL_CRYPTO_LIBRARY - The OpenSSL crypto library +# OPENSSL_SSL_LIBRARY - The OpenSSL SSL library +# OPENSSL_LIBRARIES - All OpenSSL libraries +# OPENSSL_VERSION - This is set to $major.$minor.$revision$patch (eg. 0.9.8s) #============================================================================= # Copyright 2006-2009 Kitware, Inc. @@ -153,6 +155,8 @@ if(WIN32 AND NOT CYGWIN) mark_as_advanced(LIB_EAY_LIBRARY_DEBUG LIB_EAY_LIBRARY_RELEASE SSL_EAY_LIBRARY_DEBUG SSL_EAY_LIBRARY_RELEASE) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY_LIBRARY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY_LIBRARY} ) set( OPENSSL_LIBRARIES ${SSL_EAY_LIBRARY} ${LIB_EAY_LIBRARY} ) elseif(MINGW) # same player, for MinGW @@ -181,6 +185,8 @@ if(WIN32 AND NOT CYGWIN) ) mark_as_advanced(SSL_EAY LIB_EAY) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) unset(LIB_EAY_NAMES) unset(SSL_EAY_NAMES) @@ -207,6 +213,8 @@ if(WIN32 AND NOT CYGWIN) ) mark_as_advanced(SSL_EAY LIB_EAY) + set( OPENSSL_SSL_LIBRARY ${SSL_EAY} ) + set( OPENSSL_CRYPTO_LIBRARY ${LIB_EAY} ) set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) endif() else() @@ -275,9 +283,7 @@ function(from_hex HEX DEC) endfunction() if (OPENSSL_INCLUDE_DIR) - if (_OPENSSL_VERSION) - set(OPENSSL_VERSION "${_OPENSSL_VERSION}") - elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index d728324..bf58ede 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -490,9 +490,10 @@ endmacro() pkg_check_modules (XRENDER REQUIRED xrender) - Defines e.g.: - ``XRENDER_LIBRARIES=Xrender;X11`` and - ``XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp`` + Defines for example:: + + XRENDER_LIBRARIES=Xrender;X11`` + XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp #]========================================] macro(pkg_check_modules _prefix _module0) # check cached value diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index 72ca6ed..f01bd41 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -2,127 +2,80 @@ # FindProtobuf # ------------ # -# -# # Locate and configure the Google Protocol Buffers library. # # The following variables can be set and are optional: # -# :: -# -# PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set -# the protobuf-default VS project build locations -# (vsprojects/Debug & vsprojects/Release) will be searched -# for libraries and binaries. -# -# -# -# :: -# -# PROTOBUF_IMPORT_DIRS - List of additional directories to be searched for -# imported .proto files. (New in CMake 2.8.8) -# -# +# ``PROTOBUF_SRC_ROOT_FOLDER`` +# When compiling with MSVC, if this cache variable is set +# the protobuf-default VS project build locations +# (vsprojects/Debug & vsprojects/Release) will be searched +# for libraries and binaries. +# ``PROTOBUF_IMPORT_DIRS`` +# List of additional directories to be searched for +# imported .proto files. # # Defines the following variables: # -# :: -# -# PROTOBUF_FOUND - Found the Google Protocol Buffers library (libprotobuf & header files) -# PROTOBUF_INCLUDE_DIRS - Include directories for Google Protocol Buffers -# PROTOBUF_LIBRARIES - The protobuf libraries -# -# [New in CMake 2.8.5] -# -# :: -# -# PROTOBUF_PROTOC_LIBRARIES - The protoc libraries -# PROTOBUF_LITE_LIBRARIES - The protobuf-lite libraries -# -# +# ``PROTOBUF_FOUND`` +# Found the Google Protocol Buffers library +# (libprotobuf & header files) +# ``PROTOBUF_INCLUDE_DIRS`` +# Include directories for Google Protocol Buffers +# ``PROTOBUF_LIBRARIES`` +# The protobuf libraries +# ``PROTOBUF_PROTOC_LIBRARIES`` +# The protoc libraries +# ``PROTOBUF_LITE_LIBRARIES`` +# The protobuf-lite libraries # # The following cache variables are also available to set or use: # -# :: -# -# PROTOBUF_LIBRARY - The protobuf library -# PROTOBUF_PROTOC_LIBRARY - The protoc library -# PROTOBUF_INCLUDE_DIR - The include directory for protocol buffers -# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler -# -# [New in CMake 2.8.5] -# -# :: -# -# PROTOBUF_LIBRARY_DEBUG - The protobuf library (debug) -# PROTOBUF_PROTOC_LIBRARY_DEBUG - The protoc library (debug) -# PROTOBUF_LITE_LIBRARY - The protobuf lite library -# PROTOBUF_LITE_LIBRARY_DEBUG - The protobuf lite library (debug) -# -# -# -# :: -# -# ==================================================================== -# Example: -# -# -# -# :: -# -# find_package(Protobuf REQUIRED) -# include_directories(${PROTOBUF_INCLUDE_DIRS}) -# -# -# -# :: -# -# include_directories(${CMAKE_CURRENT_BINARY_DIR}) -# PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto) -# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) -# target_link_libraries(bar ${PROTOBUF_LIBRARIES}) -# -# -# -# NOTE: You may need to link against pthreads, depending -# -# :: -# -# on the platform. -# -# -# -# NOTE: The PROTOBUF_GENERATE_CPP macro & add_executable() or -# add_library() -# -# :: -# -# calls only work properly within the same directory. -# -# -# -# :: -# -# ==================================================================== -# -# -# -# PROTOBUF_GENERATE_CPP (public function) -# -# :: -# -# SRCS = Variable to define with autogenerated -# source files -# HDRS = Variable to define with autogenerated -# header files -# ARGN = proto files -# -# -# -# :: -# -# ==================================================================== - +# ``PROTOBUF_LIBRARY`` +# The protobuf library +# ``PROTOBUF_PROTOC_LIBRARY`` +# The protoc library +# ``PROTOBUF_INCLUDE_DIR`` +# The include directory for protocol buffers +# ``PROTOBUF_PROTOC_EXECUTABLE`` +# The protoc compiler +# ``PROTOBUF_LIBRARY_DEBUG`` +# The protobuf library (debug) +# ``PROTOBUF_PROTOC_LIBRARY_DEBUG`` +# The protoc library (debug) +# ``PROTOBUF_LITE_LIBRARY`` +# The protobuf lite library +# ``PROTOBUF_LITE_LIBRARY_DEBUG`` +# The protobuf lite library (debug) +# +# Example: +# +# .. code-block:: cmake +# +# find_package(Protobuf REQUIRED) +# include_directories(${PROTOBUF_INCLUDE_DIRS}) +# include_directories(${CMAKE_CURRENT_BINARY_DIR}) +# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto) +# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) +# target_link_libraries(bar ${PROTOBUF_LIBRARIES}) +# +# .. note:: +# The PROTOBUF_GENERATE_CPP macro and add_executable() or +# add_library() calls only work properly within the same +# directory. +# +# .. command:: protobuf_generate_cpp +# +# Add custom commands to process ``.proto`` files:: +# +# protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...]) +# +# ``SRCS`` +# Variable to define with autogenerated source files +# ``HDRS`` +# Variable to define with autogenerated header files +# ``ARGN`` +# ``.proto`` files #============================================================================= # Copyright 2009 Kitware, Inc. diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake index 5e5c7b9..8784e18 100644 --- a/Modules/FindPythonInterp.cmake +++ b/Modules/FindPythonInterp.cmake @@ -148,8 +148,8 @@ if(PYTHON_EXECUTABLE) # this is older. set(PYTHON_VERSION_STRING "1.4") set(PYTHON_VERSION_MAJOR "1") - set(PYTHON_VERSION_MAJOR "4") - set(PYTHON_VERSION_MAJOR "0") + set(PYTHON_VERSION_MINOR "4") + set(PYTHON_VERSION_PATCH "0") endif() endif() unset(_PYTHON_VERSION_RESULT) diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake index 1bc0940..41b7271 100644 --- a/Modules/FindQt.cmake +++ b/Modules/FindQt.cmake @@ -13,6 +13,9 @@ # or FindQt4 module is included. Once the user sets DESIRED_QT_VERSION, # then the FindQt3 or FindQt4 module is included. # +# This module can only detect and switch between Qt versions 3 and 4. It +# cannot handle Qt5 or any later versions. +# # :: # # QT_REQUIRED if this is set to TRUE then if CMake can @@ -79,7 +82,11 @@ endif() set(GLOB_TEMP_VAR) if (Qt_FIND_VERSION) - set(DESIRED_QT_VERSION "${Qt_FIND_VERSION}") + if (Qt_FIND_VERSION MATCHES "^([34])(\\.[0-9]+.*)?$") + set(DESIRED_QT_VERSION ${CMAKE_MATCH_1}) + else () + message(FATAL_ERROR "FindQt was called with invalid version '${Qt_FIND_VERSION}'. Only Qt major versions 3 or 4 are supported. If you do not need to support both Qt3 and Qt4 in your source consider calling find_package(Qt3) or find_package(Qt4) instead of find_package(Qt) instead.") + endif () endif () # now find qmake @@ -179,9 +186,9 @@ else() endif() if(NOT QT_FOUND AND DESIRED_QT_VERSION) if(QT_REQUIRED) - message(FATAL_ERROR "CMake was unable to find Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_FILE, if those are set then QT_QT_LIBRARY or QT_LIBRARY_DIR.") + message(FATAL_ERROR "CMake was unable to find Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_H_FILE, if those are set then QT_QT_LIBRARY or QT_LIBRARY_DIR.") else() - message( "CMake was unable to find desired Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_FILE.") + message( "CMake was unable to find desired Qt version: ${DESIRED_QT_VERSION}. Set advanced values QT_QMAKE_EXECUTABLE and QT${DESIRED_QT_VERSION}_QGLOBAL_H_FILE.") endif() endif() endif() diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 2c39de5..11091b5 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -23,7 +23,7 @@ # .. note:: # # When using :prop_tgt:`IMPORTED` targets, the qtmain.lib static library is -# automatically linked on Windows for :variable:`WIN32 <WIN32_EXECUTABLE>` +# automatically linked on Windows for :prop_tgt:`WIN32 <WIN32_EXECUTABLE>` # executables. To disable that globally, set the # ``QT4_NO_LINK_QTMAIN`` variable before finding Qt4. To disable that # for a particular executable, set the ``QT4_NO_LINK_QTMAIN`` target @@ -104,9 +104,11 @@ # macro QT4_ADD_DBUS_INTERFACES(outfiles inputfile ... ) # Create the interface header and implementation files # for all listed interface xml files. -# The basename will be automatically determined from the name of the xml file. +# The basename will be automatically determined from the name +# of the xml file. # -# The source file properties described for QT4_ADD_DBUS_INTERFACE also apply here. +# The source file properties described for +# QT4_ADD_DBUS_INTERFACE also apply here. # # # :: @@ -172,7 +174,7 @@ # a class uses the Q_OBJECT macro, moc has to run on it. If you don't # want to use QT4_WRAP_CPP() (which is reliable and mature), you can insert # #include "foo.moc" -# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will the +# in foo.cpp and then give foo.cpp as argument to QT4_AUTOMOC(). This will # scan all listed files at cmake-time for such included moc files and if it # finds them cause a rule to be generated to run moc at build time on the # accompanying header file foo.h. @@ -188,8 +190,8 @@ # This function is obsolete. Use target_link_libraries with IMPORTED targets # instead. # Make <target> use the <modules> from Qt. Using a Qt module means -# to link to the library, add the relevant include directories for the module, -# and add the relevant compiler defines for using the module. +# to link to the library, add the relevant include directories for the +# module, and add the relevant compiler defines for using the module. # Modules are roughly equivalent to components of Qt4, so usage would be # something like: # qt4_use_modules(myexe Core Gui Declarative) @@ -1319,7 +1321,7 @@ endif() if (NOT QT_VERSION_MAJOR EQUAL 4) set(VERSION_MSG "Found unsuitable Qt version \"${QTVERSION}\" from ${QT_QMAKE_EXECUTABLE}") - set(QT4_FOUND FALSE) + set(Qt4_FOUND FALSE) if(Qt4_FIND_REQUIRED) message( FATAL_ERROR "${VERSION_MSG}, this code requires Qt 4.x") else() diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index b5ac703..4be16c9 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -58,7 +58,7 @@ set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby) # if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8 -if(Ruby_FIND_VERSION_MAJOR AND Ruby_FIND_VERSION_MINOR) +if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR) set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}") # we can't construct that if only major version is given set(_RUBY_POSSIBLE_EXECUTABLE_NAMES @@ -90,7 +90,7 @@ if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR) RESULT_VARIABLE _RUBY_SUCCESS OUTPUT_VARIABLE _RUBY_OUTPUT ERROR_QUIET) - if(_RUBY_SUCCESS OR NOT _RUBY_OUTPUT) + if(_RUBY_SUCCESS OR _RUBY_OUTPUT STREQUAL "") execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']" RESULT_VARIABLE _RUBY_SUCCESS OUTPUT_VARIABLE _RUBY_OUTPUT diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake index 3905e54..45ca1d4 100644 --- a/Modules/FindSDL.cmake +++ b/Modules/FindSDL.cmake @@ -106,7 +106,7 @@ find_library(SDL_LIBRARY_TEMP ) if(NOT SDL_BUILDING_LIBRARY) - if(NOT ${SDL_INCLUDE_DIR} MATCHES ".framework") + if(NOT SDL_INCLUDE_DIR MATCHES ".framework") # Non-OS X framework versions expect you to also dynamically link to # SDLmain. This is mainly for Windows and OS X. Other (Unix) platforms # seem to provide SDLmain for compatibility even though they don't diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake index fc2c043..49b5e40 100644 --- a/Modules/FindSDL_image.cmake +++ b/Modules/FindSDL_image.cmake @@ -11,7 +11,8 @@ # SDL_IMAGE_LIBRARIES, the name of the library to link against # SDL_IMAGE_INCLUDE_DIRS, where to find the headers # SDL_IMAGE_FOUND, if false, do not try to link against -# SDL_IMAGE_VERSION_STRING - human-readable string containing the version of SDL_image +# SDL_IMAGE_VERSION_STRING - human-readable string containing the +# version of SDL_image # # # diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake index 176fee6..9e11796 100644 --- a/Modules/FindSDL_mixer.cmake +++ b/Modules/FindSDL_mixer.cmake @@ -11,7 +11,8 @@ # SDL_MIXER_LIBRARIES, the name of the library to link against # SDL_MIXER_INCLUDE_DIRS, where to find the headers # SDL_MIXER_FOUND, if false, do not try to link against -# SDL_MIXER_VERSION_STRING - human-readable string containing the version of SDL_mixer +# SDL_MIXER_VERSION_STRING - human-readable string containing the +# version of SDL_mixer # # # diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake index 5fa40a5..494d358 100644 --- a/Modules/FindSDL_sound.cmake +++ b/Modules/FindSDL_sound.cmake @@ -21,7 +21,8 @@ # flags to SDL_SOUND_LIBRARIES. This is prepended to SDL_SOUND_LIBRARIES. # This is available mostly for cases this module failed to anticipate for # and you must add additional flags. This is marked as ADVANCED. -# SDL_SOUND_VERSION_STRING, human-readable string containing the version of SDL_sound +# SDL_SOUND_VERSION_STRING, human-readable string containing the +# version of SDL_sound # # # diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake index 4fdecb4..51e279d 100644 --- a/Modules/FindSquish.cmake +++ b/Modules/FindSquish.cmake @@ -41,8 +41,9 @@ # # :: # -# squish_v4_add_test(cmakeTestName AUT targetName SUITE suiteName TEST squishTestName -# [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] ) +# squish_v4_add_test(cmakeTestName +# AUT targetName SUITE suiteName TEST squishTestName +# [SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] ) # # # diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake index d4e5dcd..869ba38 100644 --- a/Modules/FindUnixCommands.cmake +++ b/Modules/FindUnixCommands.cmake @@ -2,12 +2,13 @@ # FindUnixCommands # ---------------- # -# Find unix commands from cygwin +# Find Unix commands, including the ones from Cygwin # -# This module looks for some usual Unix commands. +# This module looks for the Unix commands bash, cp, gzip, mv, rm, and tar +# and stores the result in the variables BASH, CP, GZIP, MV, RM, and TAR. #============================================================================= -# Copyright 2001-2009 Kitware, Inc. +# Copyright 2001-2014 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -95,3 +96,8 @@ find_program(TAR mark_as_advanced( TAR ) + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(UnixCommands + REQUIRED_VARS BASH CP GZIP MV RM TAR +) diff --git a/Modules/FindXerces.cmake b/Modules/FindXercesC.cmake index 6c6007a..5a8ea9d 100644 --- a/Modules/FindXerces.cmake +++ b/Modules/FindXercesC.cmake @@ -1,21 +1,21 @@ #.rst: -# FindXerces -# ---------- +# FindXercesC +# ----------- # # Find the Apache Xerces-C++ validating XML parser headers and libraries. # # This module reports information about the Xerces installation in # several variables. General variables:: # -# Xerces_FOUND - true if the Xerces headers and libraries were found -# Xerces_VERSION - Xerces release version -# Xerces_INCLUDE_DIRS - the directory containing the Xerces headers -# Xerces_LIBRARIES - Xerces libraries to be linked +# XercesC_FOUND - true if the Xerces headers and libraries were found +# XercesC_VERSION - Xerces release version +# XercesC_INCLUDE_DIRS - the directory containing the Xerces headers +# XercesC_LIBRARIES - Xerces libraries to be linked # # The following cache variables may also be set:: # -# Xerces_INCLUDE_DIR - the directory containing the Xerces headers -# Xerces_LIBRARY - the Xerces library +# XercesC_INCLUDE_DIR - the directory containing the Xerces headers +# XercesC_LIBRARY - the Xerces library # Written by Roger Leigh <rleigh@codelibre.net> @@ -32,54 +32,54 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -function(_Xerces_GET_VERSION version_hdr) +function(_XercesC_GET_VERSION version_hdr) file(STRINGS ${version_hdr} _contents REGEX "^[ \t]*#define XERCES_VERSION_.*") if(_contents) - string(REGEX REPLACE ".*#define XERCES_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" Xerces_MAJOR "${_contents}") - string(REGEX REPLACE ".*#define XERCES_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" Xerces_MINOR "${_contents}") - string(REGEX REPLACE ".*#define XERCES_VERSION_REVISION[ \t]+([0-9]+).*" "\\1" Xerces_PATCH "${_contents}") + string(REGEX REPLACE ".*#define XERCES_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" XercesC_MAJOR "${_contents}") + string(REGEX REPLACE ".*#define XERCES_VERSION_MINOR[ \t]+([0-9]+).*" "\\1" XercesC_MINOR "${_contents}") + string(REGEX REPLACE ".*#define XERCES_VERSION_REVISION[ \t]+([0-9]+).*" "\\1" XercesC_PATCH "${_contents}") - if(NOT Xerces_MAJOR MATCHES "^[0-9]+$") + if(NOT XercesC_MAJOR MATCHES "^[0-9]+$") message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_MAJOR!") endif() - if(NOT Xerces_MINOR MATCHES "^[0-9]+$") + if(NOT XercesC_MINOR MATCHES "^[0-9]+$") message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_MINOR!") endif() - if(NOT Xerces_PATCH MATCHES "^[0-9]+$") + if(NOT XercesC_PATCH MATCHES "^[0-9]+$") message(FATAL_ERROR "Version parsing failed for XERCES_VERSION_REVISION!") endif() - set(Xerces_VERSION "${Xerces_MAJOR}.${Xerces_MINOR}.${Xerces_PATCH}" PARENT_SCOPE) + set(XercesC_VERSION "${XercesC_MAJOR}.${XercesC_MINOR}.${XercesC_PATCH}" PARENT_SCOPE) else() message(FATAL_ERROR "Include file ${version_hdr} does not exist or does not contain expected version information") endif() endfunction() # Find include directory -find_path(Xerces_INCLUDE_DIR +find_path(XercesC_INCLUDE_DIR NAMES "xercesc/util/PlatformUtils.hpp" DOC "Xerces-C++ include directory") -mark_as_advanced(Xerces_INCLUDE_DIR) +mark_as_advanced(XercesC_INCLUDE_DIR) -# Find all Xerces libraries -find_library(Xerces_LIBRARY "xerces-c" +# Find all XercesC libraries +find_library(XercesC_LIBRARY "xerces-c" DOC "Xerces-C++ libraries") -mark_as_advanced(Xerces_LIBRARY) +mark_as_advanced(XercesC_LIBRARY) -if(Xerces_INCLUDE_DIR) - _Xerces_GET_VERSION("${Xerces_INCLUDE_DIR}/xercesc/util/XercesVersion.hpp") +if(XercesC_INCLUDE_DIR) + _XercesC_GET_VERSION("${XercesC_INCLUDE_DIR}/xercesc/util/XercesVersion.hpp") endif() include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xerces - FOUND_VAR Xerces_FOUND - REQUIRED_VARS Xerces_LIBRARY - Xerces_INCLUDE_DIR - Xerces_VERSION - VERSION_VAR Xerces_VERSION - FAIL_MESSAGE "Failed to find Xerces") +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XercesC + FOUND_VAR XercesC_FOUND + REQUIRED_VARS XercesC_LIBRARY + XercesC_INCLUDE_DIR + XercesC_VERSION + VERSION_VAR XercesC_VERSION + FAIL_MESSAGE "Failed to find XercesC") -if(Xerces_FOUND) - set(Xerces_INCLUDE_DIRS "${Xerces_INCLUDE_DIR}") - set(Xerces_LIBRARIES "${Xerces_LIBRARY}") +if(XercesC_FOUND) + set(XercesC_INCLUDE_DIRS "${XercesC_INCLUDE_DIR}") + set(XercesC_LIBRARIES "${XercesC_LIBRARY}") endif() diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index 7ef06a8..dec0ddf 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake @@ -460,6 +460,8 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32") D:/ ENV ProgramFiles PATH_SUFFIXES + wxWidgets-3.0.2 + wxWidgets-3.0.1 wxWidgets-3.0.0 wxWidgets-2.9.5 wxWidgets-2.9.4 diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 9963517..712a41c 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -179,7 +179,7 @@ function(gp_append_unique list_var value) set(contains 0) foreach(item ${${list_var}}) - if("${item}" STREQUAL "${value}") + if(item STREQUAL "${value}") set(contains 1) break() endif() @@ -546,14 +546,14 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) if(NOT is_system) get_filename_component(original_path "${original_lower}" PATH) get_filename_component(path "${lower}" PATH) - if("${original_path}" STREQUAL "${path}") + if(original_path STREQUAL path) set(is_local 1) else() string(LENGTH "${original_path}/" original_length) string(LENGTH "${lower}" path_length) if(${path_length} GREATER ${original_length}) string(SUBSTRING "${lower}" 0 ${original_length} path) - if("${original_path}/" STREQUAL "${path}") + if("${original_path}/" STREQUAL path) set(is_embedded 1) endif() endif() @@ -642,7 +642,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # Try to choose the right tool by default. Caller can set gp_tool prior to # calling this function to force using a different tool. # - if("${gp_tool}" STREQUAL "") + if(NOT gp_tool) set(gp_tool "ldd") if(APPLE) @@ -666,45 +666,31 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa return() endif() - set(gp_tool_known 0) - - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(gp_cmd_args "") set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$") set(gp_regex_error "not found${eol_char}$") set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "otool") + elseif(gp_tool STREQUAL "otool") set(gp_cmd_args "-L") set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 3) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "dumpbin") + elseif(gp_tool STREQUAL "dumpbin") set(gp_cmd_args "/dependents") set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if("${gp_tool}" STREQUAL "objdump") + elseif(gp_tool STREQUAL "objdump") set(gp_cmd_args "-p") set(gp_regex "^\t*DLL Name: (.*\\.[Dd][Ll][Ll])${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 1) - set(gp_tool_known 1) - endif() - - if(NOT gp_tool_known) + else() message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...") message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'") message(STATUS "Valid gp_tool values are dumpbin, ldd, objdump and otool.") @@ -712,7 +698,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa endif() - if("${gp_tool}" STREQUAL "dumpbin") + if(gp_tool STREQUAL "dumpbin") # When running dumpbin, it also needs the "Common7/IDE" directory in the # PATH. It will already be in the PATH if being run from a Visual Studio # command prompt. Add it to the PATH here in case we are running from a @@ -727,7 +713,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(gp_found_cmd_dlls_dir 0) file(TO_CMAKE_PATH "$ENV{PATH}" env_path) foreach(gp_env_path_element ${env_path}) - if("${gp_env_path_element}" STREQUAL "${gp_cmd_dlls_dir}") + if(gp_env_path_element STREQUAL gp_cmd_dlls_dir) set(gp_found_cmd_dlls_dir 1) endif() endforeach() @@ -741,7 +727,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # # </setup-gp_tool-vars> - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(old_ld_env "$ENV{LD_LIBRARY_PATH}") set(new_ld_env "${exepath}") foreach(dir ${dirs}) @@ -763,7 +749,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa OUTPUT_VARIABLE gp_cmd_ov ) - if("${gp_tool}" STREQUAL "ldd") + if(gp_tool STREQUAL "ldd") set(ENV{LD_LIBRARY_PATH} "${old_ld_env}") endif() @@ -783,7 +769,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # check for install id and remove it from list, since otool -L can include a # reference to itself set(gp_install_id) - if("${gp_tool}" STREQUAL "otool") + if(gp_tool STREQUAL "otool") execute_process( COMMAND otool -D ${target} OUTPUT_VARIABLE gp_install_id_ov @@ -833,7 +819,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa # set(add_item 1) - if("${item}" STREQUAL "${gp_install_id}") + if(item STREQUAL gp_install_id) set(add_item 0) endif() @@ -841,7 +827,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(type "") gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}") - if("${type}" STREQUAL "system") + if(type STREQUAL "system") set(add_item 0) endif() endif() diff --git a/Modules/Platform/HP-UX-HP-Fortran.cmake b/Modules/Platform/HP-UX-HP-Fortran.cmake index 30acab8..e5c5d10 100644 --- a/Modules/Platform/HP-UX-HP-Fortran.cmake +++ b/Modules/Platform/HP-UX-HP-Fortran.cmake @@ -1,2 +1,5 @@ include(Platform/HP-UX-HP) __hpux_compiler_hp(Fortran) + +set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") +set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>") diff --git a/Modules/Platform/IRIX.cmake b/Modules/Platform/IRIX.cmake index 03e98cc..12b0f37 100644 --- a/Modules/Platform/IRIX.cmake +++ b/Modules/Platform/IRIX.cmake @@ -31,6 +31,14 @@ if(NOT CMAKE_COMPILER_IS_GNUCXX) ) endif() +if(NOT CMAKE_COMPILER_IS_GNUG77) + set (CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>") + set (CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE + "<CMAKE_Fortran_COMPILER> <FLAGS> -S <SOURCE>" + "mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>" + ) +endif() + # Initialize C link type selection flags. These flags are used when # building a shared library, shared module, or executable that links # to other libraries to select whether to use the static or shared diff --git a/Modules/Platform/Linux-XL-C.cmake b/Modules/Platform/Linux-XL-C.cmake index f1c584c..d595e44 100644 --- a/Modules/Platform/Linux-XL-C.cmake +++ b/Modules/Platform/Linux-XL-C.cmake @@ -1 +1,2 @@ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj") +set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-export-dynamic") diff --git a/Modules/Platform/Linux-XL-CXX.cmake b/Modules/Platform/Linux-XL-CXX.cmake index abd3fa4..5ceb255 100644 --- a/Modules/Platform/Linux-XL-CXX.cmake +++ b/Modules/Platform/Linux-XL-CXX.cmake @@ -1 +1,2 @@ set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj") +set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,-export-dynamic") diff --git a/Modules/Platform/Linux-XL-Fortran.cmake b/Modules/Platform/Linux-XL-Fortran.cmake index cdd1f70..a878991 100644 --- a/Modules/Platform/Linux-XL-Fortran.cmake +++ b/Modules/Platform/Linux-XL-Fortran.cmake @@ -1 +1,2 @@ set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-qmkshrobj") +set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,-export-dynamic") diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 4c936fe..da19a3d 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -18,8 +18,8 @@ if(__WINDOWS_CLANG) endif() set(__WINDOWS_CLANG 1) -if(CMAKE_C_SIMULATE_ID STREQUAL "MSVC" - OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") +if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") include(Platform/Windows-MSVC) macro(__windows_compiler_clang lang) __windows_compiler_msvc(${lang}) diff --git a/Modules/Platform/Windows-wcl386.cmake b/Modules/Platform/Windows-wcl386.cmake index ac410de..88f9bf7 100644 --- a/Modules/Platform/Windows-wcl386.cmake +++ b/Modules/Platform/Windows-wcl386.cmake @@ -18,8 +18,8 @@ set(CMAKE_CREATE_CONSOLE_EXE "system nt" ) set(CMAKE_SHARED_LINKER_FLAGS_INIT "system nt_dll") set(CMAKE_MODULE_LINKER_FLAGS_INIT "system nt_dll") foreach(type SHARED MODULE EXE) - set(CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT "debug all opt map, symfile") - set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT "debug all opt map, symfile") + set(CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT "debug all opt map") + set(CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT "debug all opt map") endforeach() set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 8c4daac..6516b0a 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -232,7 +232,7 @@ macro (QT4_ADD_RESOURCES outfiles ) # let's make a configured file and add it as a dependency so cmake is run # again when dependencies need to be recomputed. QT4_MAKE_OUTPUT_FILE("${infile}" "" "qrc.depends" out_depends) - configure_file("${infile}" "${out_depends}" COPY_ONLY) + configure_file("${infile}" "${out_depends}" COPYONLY) else() # The .qrc file does not exist (yet). Let's add a dependency and hope # that it will be generated later diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index 86137e2..e81bc08 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -11,6 +11,7 @@ # write_compiler_detection_header( # FILE <file> # PREFIX <prefix> +# [OUTPUT_FILES_VAR <output_files_var> OUTPUT_DIR <output_dir>] # COMPILERS <compiler> [...] # FEATURES <feature> [...] # [VERSION <version>] @@ -21,6 +22,33 @@ # The ``write_compiler_detection_header`` function generates the # file ``<file>`` with macros which all have the prefix ``<prefix>``. # +# By default, all content is written directly to the ``<file>``. The +# ``OUTPUT_FILES_VAR`` may be specified to cause the compiler-specific +# content to be written to separate files. The separate files are then +# available in the ``<output_files_var>`` and may be consumed by the caller +# for installation for example. The ``OUTPUT_DIR`` specifies a relative +# path from the main ``<file>`` to the compiler-specific files. For example: +# +# .. code-block:: cmake +# +# write_compiler_detection_header( +# FILE climbingstats_compiler_detection.h +# PREFIX ClimbingStats +# OUTPUT_FILES_VAR support_files +# OUTPUT_DIR compilers +# COMPILERS GNU Clang +# FEATURES cxx_variadic_templates +# ) +# install(FILES +# ${CMAKE_CURRENT_BINARY_DIR}/climbingstats_compiler_detection.h +# DESTINATION include +# ) +# install(FILES +# ${support_files} +# DESTINATION include/compilers +# ) +# +# # ``VERSION`` may be used to specify the API version to be generated. # Future versions of CMake may introduce alternative APIs. A given # API is selected by any ``<version>`` value greater than or equal @@ -72,7 +100,7 @@ # write_compiler_detection_header( # FILE climbingstats_compiler_detection.h # PREFIX ClimbingStats -# COMPILERS GNU Clang MSVC +# COMPILERS GNU Clang AppleClang # FEATURES cxx_variadic_templates # ) # @@ -166,6 +194,7 @@ # ``cxx_static_assert`` ``<PREFIX>_STATIC_ASSERT_MSG`` ``static_assert`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED`` ``[[deprecated]]`` # ``cxx_attribute_deprecated`` ``<PREFIX>_DEPRECATED_MSG`` ``[[deprecated]]`` +# ``cxx_thread_local`` ``<PREFIX>_THREAD_LOCAL`` ``thread_local`` # ============================= ================================ ===================== # # A use-case which arises with such deprecation macros is the deprecation @@ -205,7 +234,11 @@ function(_load_compiler_variables CompilerId lang) foreach(feature ${ARGN}) set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE) endforeach() - include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL) + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-${lang}-DetermineCompiler.cmake" OPTIONAL + RESULT_VARIABLE determinedCompiler) + if (NOT determinedCompiler) + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL) + endif() set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE) endfunction() @@ -220,7 +253,7 @@ function(write_compiler_detection_header message(FATAL_ERROR "write_compiler_detection_header: PREFIX parameter missing.") endif() set(options) - set(oneValueArgs VERSION EPILOG PROLOG) + set(oneValueArgs VERSION EPILOG PROLOG OUTPUT_FILES_VAR OUTPUT_DIR) set(multiValueArgs COMPILERS FEATURES) cmake_parse_arguments(_WCD "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -255,9 +288,40 @@ function(write_compiler_detection_header message(FATAL_ERROR "${err}") endif() + if(_WCD_OUTPUT_FILES_VAR) + if(NOT _WCD_OUTPUT_DIR) + message(FATAL_ERROR "If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified.") + endif() + endif() + if(_WCD_OUTPUT_DIR) + if(NOT _WCD_OUTPUT_FILES_VAR) + message(FATAL_ERROR "If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified.") + endif() + get_filename_component(main_file_dir ${file_arg} DIRECTORY) + if (NOT IS_ABSOLUTE ${main_file_dir}) + set(main_file_dir "${CMAKE_CURRENT_BINARY_DIR}/${main_file_dir}") + endif() + if (NOT IS_ABSOLUTE ${_WCD_OUTPUT_DIR}) + set(_WCD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_WCD_OUTPUT_DIR}") + endif() + get_filename_component(out_file_dir ${_WCD_OUTPUT_DIR} ABSOLUTE) + string(FIND ${out_file_dir} ${main_file_dir} idx) + if (NOT idx EQUAL 0) + message(FATAL_ERROR "The compiler-specific output directory must be within the same directory as the main file.") + endif() + + if (main_file_dir STREQUAL out_file_dir) + unset(_WCD_OUTPUT_DIR) + else() + string(REPLACE "${main_file_dir}/" "" _WCD_OUTPUT_DIR "${out_file_dir}/") + endif() + endif() + set(compilers GNU Clang + AppleClang + SunPro ) set(_hex_compilers ADSP Borland Embarcadero SunPro) @@ -314,7 +378,22 @@ function(write_compiler_detection_header endforeach() list(REMOVE_DUPLICATES _langs) + if(_WCD_OUTPUT_FILES_VAR) + get_filename_component(main_file_name ${file_arg} NAME) + set(compiler_file_content_ +"#ifndef ${prefix_arg}_COMPILER_DETECTION_H +# error This file may only be included from ${main_file_name} +#endif\n") + endif() + foreach(_lang ${_langs}) + set(target_compilers) + foreach(compiler ${_WCD_COMPILERS}) + _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features}) + if(_cmake_oldestSupported_${compiler}) + list(APPEND target_compilers ${compiler}) + endif() + endforeach() get_property(known_features GLOBAL PROPERTY CMAKE_${_lang}_KNOWN_FEATURES) foreach(feature ${${_lang}_features}) @@ -337,10 +416,21 @@ function(write_compiler_detection_header set(file_content "${file_content}${ID_CONTENT}\n") set(pp_if "if") - foreach(compiler ${_WCD_COMPILERS}) - _load_compiler_variables(${compiler} ${_lang} ${${_lang}_features}) + foreach(compiler ${target_compilers}) set(file_content "${file_content}\n# ${pp_if} ${prefix_arg}_COMPILER_IS_${compiler}\n") - set(file_content "${file_content} + + if(_WCD_OUTPUT_FILES_VAR) + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h") + set(file_content "${file_content}\n# include \"${compile_file_name}\"\n") + endif() + + if(_WCD_OUTPUT_FILES_VAR) + set(compiler_file_content compiler_file_content_${compiler}_${_lang}) + else() + set(compiler_file_content file_content) + endif() + + set(${compiler_file_content} "${${compiler_file_content}} # if !(${_cmake_oldestSupported_${compiler}}) # error Unsupported compiler version # endif\n") @@ -354,7 +444,7 @@ function(write_compiler_detection_header set(MACRO_HEX) endif() string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY) - set(file_content "${file_content}${VERSION_BLOCK}\n") + set(${compiler_file_content} "${${compiler_file_content}}${VERSION_BLOCK}\n") set(PREFIX) set(MACRO_DEC) set(MACRO_HEX) @@ -370,7 +460,7 @@ function(write_compiler_detection_header set(_define_item "\n# define ${prefix_arg}_${feature_PP} 0\n") set(_define_item "\n# if ${_cmake_feature_test_${compiler}_${feature}}\n# define ${prefix_arg}_${feature_PP} 1\n# else${_define_item}# endif\n") endif() - set(file_content "${file_content}${_define_item}") + set(${compiler_file_content} "${${compiler_file_content}}${_define_item}") endforeach() endforeach() if(pp_if STREQUAL "elif") @@ -436,7 +526,7 @@ function(write_compiler_detection_header set(file_content "${file_content} # if ${def_name} # define ${def_value} alignas(X) -# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang # define ${def_value} __attribute__ ((__aligned__(X))) # else # define ${def_value} @@ -448,7 +538,7 @@ function(write_compiler_detection_header set(file_content "${file_content} # if ${def_name} # define ${def_value} alignof(X) -# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang # define ${def_value} __alignof__(X) # endif \n") @@ -495,6 +585,20 @@ function(write_compiler_detection_header # endif \n") endif() + if (feature STREQUAL cxx_thread_local) + set(def_value "${prefix_arg}_THREAD_LOCAL") + set(file_content "${file_content} +# if ${def_name} +# define ${def_value} thread_local +# elif ${prefix_arg}_COMPILER_IS_GNU || ${prefix_arg}_COMPILER_IS_Clang || ${prefix_arg}_COMPILER_IS_AppleClang +# define ${def_value} __thread +# elif ${prefix_arg}_COMPILER_IS_MSVC +# define ${def_value} __declspec(thread) +# else +// ${def_value} not defined for this configuration. +# endif +\n") + endif() if (feature STREQUAL cxx_attribute_deprecated) set(def_name ${prefix_arg}_${feature_PP}) set(def_value "${prefix_arg}_DEPRECATED") @@ -522,6 +626,26 @@ function(write_compiler_detection_header endforeach() + if(_WCD_OUTPUT_FILES_VAR) + foreach(compiler ${_WCD_COMPILERS}) + foreach(_lang ${_langs}) + if(compiler_file_content_${compiler}_${_lang}) + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}") + set(CMAKE_CONFIGURABLE_FILE_CONTENT "${CMAKE_CONFIGURABLE_FILE_CONTENT}${compiler_file_content_${compiler}_${_lang}}") + + set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h") + set(full_path "${main_file_dir}/${compile_file_name}") + list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path}) + configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in" + "${full_path}" + @ONLY + ) + endif() + endforeach() + endforeach() + set(${_WCD_OUTPUT_FILES_VAR} ${${_WCD_OUTPUT_FILES_VAR}} PARENT_SCOPE) + endif() + if (_WCD_EPILOG) set(file_content "${file_content}\n${_WCD_EPILOG}\n") endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 7705683..c04cf9a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -39,6 +39,10 @@ else() set(CMAKE_USE_ELF_PARSER) endif() +if(APPLE) + set(CMAKE_USE_MACH_PARSER 1) +endif() + set(EXECUTABLE_OUTPUT_PATH ${CMake_BIN_DIR}) # ensure Unicode friendly APIs are used on Windows @@ -140,11 +144,15 @@ if(CMAKE_USE_ELF_PARSER) set(ELF_SRCS cmELF.h cmELF.cxx) endif() +# Check if we can build the Mach-O parser. +if(CMAKE_USE_MACH_PARSER) + set(MACH_SRCS cmMachO.h cmMachO.cxx) +endif() + # # Sources for CMakeLib # set(SRCS - cmStandardIncludes.cxx cmArchiveWrite.cxx cmBootstrapCommands1.cxx cmBootstrapCommands2.cxx @@ -219,6 +227,12 @@ set(SRCS cmExtraKateGenerator.h cmExtraSublimeTextGenerator.cxx cmExtraSublimeTextGenerator.h + cmFileLock.cxx + cmFileLock.h + cmFileLockPool.cxx + cmFileLockPool.h + cmFileLockResult.cxx + cmFileLockResult.h cmFileTimeComparison.cxx cmFileTimeComparison.h cmGeneratedFileStream.cxx @@ -261,6 +275,7 @@ set(SRCS cmLocalGenerator.cxx cmLocalGenerator.h cmLocalUnixMakefileGenerator3.cxx + ${MACH_SRCS} cmMakeDepend.cxx cmMakeDepend.h cmMakefile.cxx @@ -320,6 +335,8 @@ set(SRCS cmake.cxx cmake.h + cm_get_date.h + cm_get_date.c cm_sha2.h cm_sha2.c cm_utf8.h @@ -485,7 +502,9 @@ add_library(CMakeLib ${SRCS}) target_link_libraries(CMakeLib cmsys ${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES} ${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES} - ${CMAKE_CURL_LIBRARIES} ) + ${CMAKE_CURL_LIBRARIES} + ${CMAKE_JSONCPP_LIBRARIES} + ) # On Apple we need CoreFoundation if(APPLE) @@ -518,6 +537,7 @@ set(CTEST_SRCS cmCTest.cxx CTest/cmCTestConfigureHandler.cxx CTest/cmCTestCoverageCommand.cxx CTest/cmCTestCoverageHandler.cxx + CTest/cmCTestCurl.cxx CTest/cmParseMumpsCoverage.cxx CTest/cmParseCacheCoverage.cxx CTest/cmParseGTMCoverage.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e82fd0d..25cde98 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 1) -set(CMake_VERSION_PATCH 20141029) +set(CMake_VERSION_PATCH 20150123) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 0644ecb..4a99e50 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -24,7 +24,7 @@ #endif #define cmCPackLogger(logType, msg) \ do { \ - cmOStringStream cmCPackLog_msg; \ + std::ostringstream cmCPackLog_msg; \ cmCPackLog_msg << msg; \ if(Generator) { \ Generator->Logger->Log(logType, __FILE__, __LINE__, \ diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 3c45639..38cef87 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -25,7 +25,7 @@ #endif #define cmCPackLogger(logType, msg) \ do { \ - cmOStringStream cmCPackLog_msg; \ + std::ostringstream cmCPackLog_msg; \ cmCPackLog_msg << msg; \ if(Generator) { \ Generator->Logger->Log(logType, __FILE__, __LINE__, \ diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 7e00027..59c38e9 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -1150,12 +1150,7 @@ void cmCPackWIXGenerator::CollectExtensions( std::vector<std::string> list; cmSystemTools::ExpandListArgument(variableContent, list); - - for(std::vector<std::string>::const_iterator i = list.begin(); - i != list.end(); ++i) - { - extensions.insert(*i); - } + extensions.insert(list.begin(), list.end()); } void cmCPackWIXGenerator::AddCustomFlags( diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index 6c994f1..e751568 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -39,6 +39,21 @@ int cmCPackBundleGenerator::InitializeInternal() return 0; } + if(this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP")) + { + const std::string codesign_path = cmSystemTools::FindProgram("codesign", + std::vector<std::string>(), false); + + if(codesign_path.empty()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot locate codesign command" + << std::endl); + return 0; + } + this->SetOptionIfNotSet("CPACK_COMMAND_CODESIGN", codesign_path.c_str()); + } + return this->Superclass::InitializeInternal(); } @@ -53,7 +68,7 @@ const char* cmCPackBundleGenerator::GetPackagingInstallPrefix() } //---------------------------------------------------------------------- -int cmCPackBundleGenerator::PackageFiles() +int cmCPackBundleGenerator::ConstructBundle() { // Get required arguments ... @@ -97,24 +112,24 @@ int cmCPackBundleGenerator::PackageFiles() // The staging directory contains everything that will end-up inside the // final disk image ... - cmOStringStream staging; + std::ostringstream staging; staging << toplevel; - cmOStringStream contents; + std::ostringstream contents; contents << staging.str() << "/" << cpack_bundle_name << ".app/" << "Contents"; - cmOStringStream application; + std::ostringstream application; application << contents.str() << "/" << "MacOS"; - cmOStringStream resources; + std::ostringstream resources; resources << contents.str() << "/" << "Resources"; // Install a required, user-provided bundle metadata file ... - cmOStringStream plist_source; + std::ostringstream plist_source; plist_source << cpack_bundle_plist; - cmOStringStream plist_target; + std::ostringstream plist_target; plist_target << contents.str() << "/" << "Info.plist"; if(!this->CopyFile(plist_source, plist_target)) @@ -127,10 +142,10 @@ int cmCPackBundleGenerator::PackageFiles() } // Install a user-provided bundle icon ... - cmOStringStream icon_source; + std::ostringstream icon_source; icon_source << cpack_bundle_icon; - cmOStringStream icon_target; + std::ostringstream icon_target; icon_target << resources.str() << "/" << cpack_bundle_name << ".icns"; if(!this->CopyFile(icon_source, icon_target)) @@ -146,10 +161,10 @@ int cmCPackBundleGenerator::PackageFiles() // executable or a script) ... if(!cpack_bundle_startup_command.empty()) { - cmOStringStream command_source; + std::ostringstream command_source; command_source << cpack_bundle_startup_command; - cmOStringStream command_target; + std::ostringstream command_target; command_target << application.str() << "/" << cpack_bundle_name; if(!this->CopyFile(command_source, command_target)) @@ -165,6 +180,22 @@ int cmCPackBundleGenerator::PackageFiles() cmSystemTools::SetPermissions(command_target.str().c_str(), 0777); } + return 1; +} + +//---------------------------------------------------------------------- +int cmCPackBundleGenerator::PackageFiles() +{ + if(!this->ConstructBundle()) + { + return 0; + } + + if(!this->SignBundle(toplevel)) + { + return 0; + } + return this->CreateDMG(toplevel, packageFileNames[0]); } @@ -172,3 +203,96 @@ bool cmCPackBundleGenerator::SupportsComponentInstallation() const { return false; } + + +int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) +{ + const std::string cpack_apple_cert_app = + this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP") + ? this->GetOption("CPACK_BUNDLE_APPLE_CERT_APP") : ""; + + // codesign the application. + if(!cpack_apple_cert_app.empty()) + { + std::string bundle_path; + bundle_path = src_dir + "/"; + bundle_path += this->GetOption("CPACK_BUNDLE_NAME"); + bundle_path += ".app"; + + // A list of additional files to sign, ie. frameworks and plugins. + const std::string sign_files = + this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") + ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") : ""; + + std::vector<std::string> relFiles; + cmSystemTools::ExpandListArgument(sign_files, relFiles); + + // sign the files supplied by the user, ie. frameworks. + for(std::vector<std::string>::iterator it = relFiles.begin(); + it != relFiles.end(); ++it) + { + std::ostringstream temp_sign_file_cmd; + temp_sign_file_cmd << this->GetOption("CPACK_COMMAND_CODESIGN"); + temp_sign_file_cmd << " --deep -f -s \"" << cpack_apple_cert_app; + temp_sign_file_cmd << "\" -i "; + temp_sign_file_cmd << this->GetOption("CPACK_APPLE_BUNDLE_ID"); + temp_sign_file_cmd << " \""; + temp_sign_file_cmd << bundle_path; + temp_sign_file_cmd << it->c_str() << "\""; + + if(!this->RunCommand(temp_sign_file_cmd)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error signing file:" + << bundle_path << it->c_str() << std::endl); + + return 0; + } + } + + // sign main binary + std::ostringstream temp_sign_binary_cmd; + temp_sign_binary_cmd << this->GetOption("CPACK_COMMAND_CODESIGN"); + temp_sign_binary_cmd << " --deep -f -s \"" << cpack_apple_cert_app; + temp_sign_binary_cmd << "\" \"" << bundle_path << "\""; + + if(!this->RunCommand(temp_sign_binary_cmd)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error signing the application binary." + << std::endl); + + return 0; + } + + // sign app bundle + std::ostringstream temp_codesign_cmd; + temp_codesign_cmd << this->GetOption("CPACK_COMMAND_CODESIGN"); + temp_codesign_cmd << " --deep -f -s \"" << cpack_apple_cert_app << "\""; + if(this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS")) + { + temp_codesign_cmd << " --entitlements "; + temp_codesign_cmd << this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS"); + } + temp_codesign_cmd << " \"" << bundle_path << "\""; + + if(!this->RunCommand(temp_codesign_cmd)) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error signing the application package." + << std::endl); + + return 0; + } + + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Application has been codesigned" + << std::endl); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + (this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS") + ? "with entitlement sandboxing" : "without entitlement sandboxing") + << std::endl); + } + + return 1; +} diff --git a/Source/CPack/cmCPackBundleGenerator.h b/Source/CPack/cmCPackBundleGenerator.h index ed0187d..9cb2f0a 100644 --- a/Source/CPack/cmCPackBundleGenerator.h +++ b/Source/CPack/cmCPackBundleGenerator.h @@ -31,6 +31,8 @@ public: protected: virtual int InitializeInternal(); virtual const char* GetPackagingInstallPrefix(); + int ConstructBundle(); + int SignBundle(const std::string& src_dir); int PackageFiles(); bool SupportsComponentInstallation() const; diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx index 77f11cb..fd20e9b 100644 --- a/Source/CPack/cmCPackComponentGroup.cxx +++ b/Source/CPack/cmCPackComponentGroup.cxx @@ -30,7 +30,7 @@ unsigned long cmCPackComponent::GetInstalledSize( std::string path = installDir; path += '/'; path += *fileIt; - this->TotalSize += cmSystemTools::FileLength(path.c_str()); + this->TotalSize += cmSystemTools::FileLength(path); } return this->TotalSize; diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index c939cd2..0a64bd5 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -390,7 +390,7 @@ int cmCPackDebGenerator::createDeb() packageFiles.begin(); fileIt != packageFiles.end(); ++ fileIt ) { - totalSize += cmSystemTools::FileLength(fileIt->c_str()); + totalSize += cmSystemTools::FileLength(*fileIt); } } out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n"; diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 9f0a77e..5da9234 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx @@ -169,8 +169,8 @@ int cmCPackDragNDropGenerator::PackageFiles() } //---------------------------------------------------------------------- -bool cmCPackDragNDropGenerator::CopyFile(cmOStringStream& source, - cmOStringStream& target) +bool cmCPackDragNDropGenerator::CopyFile(std::ostringstream& source, + std::ostringstream& target) { if(!cmSystemTools::CopyFileIfDifferent( source.str().c_str(), @@ -190,7 +190,7 @@ bool cmCPackDragNDropGenerator::CopyFile(cmOStringStream& source, } //---------------------------------------------------------------------- -bool cmCPackDragNDropGenerator::RunCommand(cmOStringStream& command, +bool cmCPackDragNDropGenerator::RunCommand(std::ostringstream& command, std::string* output) { int exit_code = 1; @@ -255,12 +255,12 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // The staging directory contains everything that will end-up inside the // final disk image ... - cmOStringStream staging; + std::ostringstream staging; staging << src_dir; // Add a symlink to /Applications so users can drag-and-drop the bundle // into it - cmOStringStream application_link; + std::ostringstream application_link; application_link << staging.str() << "/Applications"; cmSystemTools::CreateSymlink("/Applications", application_link.str().c_str()); @@ -268,10 +268,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally add a custom volume icon ... if(!cpack_package_icon.empty()) { - cmOStringStream package_icon_source; + std::ostringstream package_icon_source; package_icon_source << cpack_package_icon; - cmOStringStream package_icon_destination; + std::ostringstream package_icon_destination; package_icon_destination << staging.str() << "/.VolumeIcon.icns"; if(!this->CopyFile(package_icon_source, package_icon_destination)) @@ -289,10 +289,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // (e.g. for setting background/layout) ... if(!cpack_dmg_ds_store.empty()) { - cmOStringStream package_settings_source; + std::ostringstream package_settings_source; package_settings_source << cpack_dmg_ds_store; - cmOStringStream package_settings_destination; + std::ostringstream package_settings_destination; package_settings_destination << staging.str() << "/.DS_Store"; if(!this->CopyFile(package_settings_source, package_settings_destination)) @@ -309,10 +309,10 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally add a custom background image ... if(!cpack_dmg_background_image.empty()) { - cmOStringStream package_background_source; + std::ostringstream package_background_source; package_background_source << cpack_dmg_background_image; - cmOStringStream package_background_destination; + std::ostringstream package_background_destination; package_background_destination << staging.str() << "/background.png"; if(!this->CopyFile(package_background_source, @@ -326,7 +326,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } - cmOStringStream temp_background_hiding_command; + std::ostringstream temp_background_hiding_command; temp_background_hiding_command << this->GetOption("CPACK_COMMAND_SETFILE"); temp_background_hiding_command << " -a V \""; temp_background_hiding_command << package_background_destination.str(); @@ -346,7 +346,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, std::string temp_image = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); temp_image += "/temp.dmg"; - cmOStringStream temp_image_command; + std::ostringstream temp_image_command; temp_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); temp_image_command << " create"; temp_image_command << " -ov"; @@ -368,9 +368,9 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Optionally set the custom icon flag for the image ... if(!cpack_package_icon.empty()) { - cmOStringStream temp_mount; + std::ostringstream temp_mount; - cmOStringStream attach_command; + std::ostringstream attach_command; attach_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); attach_command << " attach"; attach_command << " \"" << temp_image << "\""; @@ -389,7 +389,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, mountpoint_regex.find(attach_output.c_str()); temp_mount << mountpoint_regex.match(1); - cmOStringStream setfile_command; + std::ostringstream setfile_command; setfile_command << this->GetOption("CPACK_COMMAND_SETFILE"); setfile_command << " -a C"; setfile_command << " \"" << temp_mount.str() << "\""; @@ -403,7 +403,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, return 0; } - cmOStringStream detach_command; + std::ostringstream detach_command; detach_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); detach_command << " detach"; detach_command << " \"" << temp_mount.str() << "\""; @@ -471,7 +471,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, std::string temp_udco = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); temp_udco += "/temp-udco.dmg"; - cmOStringStream udco_image_command; + std::ostringstream udco_image_command; udco_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); udco_image_command << " convert \"" << temp_image << "\""; udco_image_command << " -format UDCO"; @@ -488,7 +488,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // unflatten dmg - cmOStringStream unflatten_command; + std::ostringstream unflatten_command; unflatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); unflatten_command << " unflatten "; unflatten_command << "\"" << temp_udco << "\""; @@ -503,7 +503,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // Rez the SLA - cmOStringStream embed_sla_command; + std::ostringstream embed_sla_command; embed_sla_command << this->GetOption("CPACK_COMMAND_REZ"); const char* sysroot = this->GetOption("CPACK_OSX_SYSROOT"); if(sysroot && sysroot[0] != '\0') @@ -524,7 +524,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, } // flatten dmg - cmOStringStream flatten_command; + std::ostringstream flatten_command; flatten_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); flatten_command << " flatten "; flatten_command << "\"" << temp_udco << "\""; @@ -543,7 +543,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir, // Create the final compressed read-only disk image ... - cmOStringStream final_image_command; + std::ostringstream final_image_command; final_image_command << this->GetOption("CPACK_COMMAND_HDIUTIL"); final_image_command << " convert \"" << temp_image << "\""; final_image_command << " -format "; diff --git a/Source/CPack/cmCPackDragNDropGenerator.h b/Source/CPack/cmCPackDragNDropGenerator.h index 808c618..1c84d49 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.h +++ b/Source/CPack/cmCPackDragNDropGenerator.h @@ -33,8 +33,8 @@ protected: bool SupportsComponentInstallation() const; - bool CopyFile(cmOStringStream& source, cmOStringStream& target); - bool RunCommand(cmOStringStream& command, std::string* output = 0); + bool CopyFile(std::ostringstream& source, std::ostringstream& target); + bool RunCommand(std::ostringstream& command, std::string* output = 0); std::string GetComponentInstallDirNameSuffix(const std::string& componentName); diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 31f0b59..f21fcf6 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -160,7 +160,7 @@ int cmCPackGenerator::PrepareNames() "Cannot open description file name: " << descFileName << std::endl); return 0; } - cmOStringStream ostr; + std::ostringstream ostr; std::string line; cmCPackLogger(cmCPackLog::LOG_VERBOSE, @@ -217,7 +217,7 @@ int cmCPackGenerator::InstallProject() { std::string destDir = "DESTDIR="; destDir += tempInstallDirectory; - cmSystemTools::PutEnv(destDir.c_str()); + cmSystemTools::PutEnv(destDir); } else { @@ -277,7 +277,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands( { std::string tempInstallDirectoryEnv = "CMAKE_INSTALL_PREFIX="; tempInstallDirectoryEnv += tempInstallDirectory; - cmSystemTools::PutEnv(tempInstallDirectoryEnv.c_str()); + cmSystemTools::PutEnv(tempInstallDirectoryEnv); std::vector<std::string> installCommandsVector; cmSystemTools::ExpandListArgument(installCommands,installCommandsVector); std::vector<std::string>::iterator it; @@ -404,7 +404,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( std::string targetFile; std::string inFileRelative = cmSystemTools::RelativePath(top.c_str(),inFile.c_str()); - cmSystemTools::ReadSymlink(inFile.c_str(),targetFile); + cmSystemTools::ReadSymlink(inFile,targetFile); symlinkedFiles.push_back(std::pair<std::string, std::string>(targetFile,inFileRelative)); } @@ -421,7 +421,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( } } /* rebuild symlinks in the installed tree */ - if (symlinkedFiles.size()>0) + if (!symlinkedFiles.empty()) { std::list< std::pair<std::string,std::string> >::iterator symlinkedIt; std::string curDir = cmSystemTools::GetCurrentWorkingDirectory(); @@ -437,8 +437,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( cmCPackLogger(cmCPackLog::LOG_DEBUG, "Will create a symlink: " << symlinkedIt->second << "--> " << symlinkedIt->first << std::endl); - if (!cmSystemTools::CreateSymlink((symlinkedIt->first).c_str(), - (symlinkedIt->second).c_str())) + if (!cmSystemTools::CreateSymlink(symlinkedIt->first, + symlinkedIt->second)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot create symlink: " << symlinkedIt->second << "--> " @@ -628,6 +628,14 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cmGlobalGenerator* globalGenerator = this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator( cmakeGenerator); + if ( !globalGenerator ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Specified package generator not found. " + "CPACK_CMAKE_GENERATOR value is invalid." + << std::endl); + return 0; + } // set the global flag for unix style paths on cmSystemTools as // soon as the generator is set. This allows gmake to be used // on windows. @@ -787,7 +795,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( * in order to put things in subdirs... */ cmSystemTools::PutEnv( - (std::string("DESTDIR=")+tempInstallDirectory).c_str() + std::string("DESTDIR=")+tempInstallDirectory ); cmCPackLogger(cmCPackLog::LOG_DEBUG, "- Creating directory: '" << dir << "'" << std::endl); @@ -918,7 +926,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( } if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { - if (absoluteDestFiles.length()>0) { + if (!absoluteDestFiles.empty()) { absoluteDestFiles +=";"; } absoluteDestFiles += @@ -1348,7 +1356,7 @@ int cmCPackGenerator::PrepareGroupingKind() groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); } - if (groupingType.length()>0) + if (!groupingType.empty()) { cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" << this->Name << "]" diff --git a/Source/CPack/cmCPackGenerator.h b/Source/CPack/cmCPackGenerator.h index ed89b53..907bb1e 100644 --- a/Source/CPack/cmCPackGenerator.h +++ b/Source/CPack/cmCPackGenerator.h @@ -29,7 +29,7 @@ #define cmCPackLogger(logType, msg) \ do { \ - cmOStringStream cmCPackLog_msg; \ + std::ostringstream cmCPackLog_msg; \ cmCPackLog_msg << msg; \ this->Logger->Log(logType, __FILE__, __LINE__,\ cmCPackLog_msg.str().c_str());\ diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 94ca536..a07c29a 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -158,11 +158,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() //---------------------------------------------------------------------- cmCPackGeneratorFactory::~cmCPackGeneratorFactory() { - std::vector<cmCPackGenerator*>::iterator it; - for ( it = this->Generators.begin(); it != this->Generators.end(); ++ it ) - { - delete *it; - } + cmDeleteAll(this->Generators); } //---------------------------------------------------------------------- diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx index 7befca0..7633ac2 100644 --- a/Source/CPack/cmCPackLog.cxx +++ b/Source/CPack/cmCPackLog.cxx @@ -102,7 +102,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, display = true; if ( needTagString ) { - if ( tagString.size() > 0 ) { tagString += ","; } + if (!tagString.empty()) { tagString += ","; } tagString = "VERBOSE"; } } @@ -112,7 +112,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, display = true; if ( needTagString ) { - if ( tagString.size() > 0 ) { tagString += ","; } + if (!tagString.empty()) { tagString += ","; } tagString = "WARNING"; } } @@ -122,7 +122,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, display = true; if ( needTagString ) { - if ( tagString.size() > 0 ) { tagString += ","; } + if (!tagString.empty()) { tagString += ","; } tagString = "ERROR"; } } @@ -132,7 +132,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, display = true; if ( needTagString ) { - if ( tagString.size() > 0 ) { tagString += ","; } + if (!tagString.empty()) { tagString += ","; } tagString = "DEBUG"; } useFileAndLine = true; @@ -143,7 +143,7 @@ void cmCPackLog::Log(int tag, const char* file, int line, display = true; if ( needTagString ) { - if ( tagString.size() > 0 ) { tagString += ","; } + if (!tagString.empty()) { tagString += ","; } tagString = "VERBOSE"; } } diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h index 812f1de..7a7ff58 100644 --- a/Source/CPack/cmCPackLog.h +++ b/Source/CPack/cmCPackLog.h @@ -17,7 +17,7 @@ #define cmCPack_Log(ctSelf, logType, msg) \ do { \ - cmOStringStream cmCPackLog_msg; \ + std::ostringstream cmCPackLog_msg; \ cmCPackLog_msg << msg; \ (ctSelf)->Log(logType, __FILE__, __LINE__, cmCPackLog_msg.str().c_str());\ } while ( 0 ) diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index c1fff7d..8f63ca2 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -71,7 +71,7 @@ int cmCPackNSISGenerator::PackageFiles() tmpFile += "/NSISOutput.log"; std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini"; nsisFileName += "/project.nsi"; - cmOStringStream str; + std::ostringstream str; std::vector<std::string>::const_iterator it; for ( it = files.begin(); it != files.end(); ++ it ) { @@ -91,7 +91,7 @@ int cmCPackNSISGenerator::PackageFiles() std::vector<std::string> dirs; this->GetListOfSubdirectories(toplevel.c_str(), dirs); std::vector<std::string>::const_iterator sit; - cmOStringStream dstr; + std::ostringstream dstr; for ( sit = dirs.begin(); sit != dirs.end(); ++ sit ) { std::string componentName; @@ -190,7 +190,7 @@ int cmCPackNSISGenerator::PackageFiles() std::string groupDescriptions; std::string installTypesCode; std::string defines; - cmOStringStream macrosOut; + std::ostringstream macrosOut; bool anyDownloadedComponents = false; // Create installation types. The order is significant, so we first fill @@ -503,8 +503,8 @@ int cmCPackNSISGenerator::InitializeInternal() << "not set" << std::endl); } - cmOStringStream str; - cmOStringStream deleteStr; + std::ostringstream str; + std::ostringstream deleteStr; if ( cpackPackageExecutables ) { @@ -565,8 +565,8 @@ int cmCPackNSISGenerator::InitializeInternal() } //---------------------------------------------------------------------- -void cmCPackNSISGenerator::CreateMenuLinks( cmOStringStream& str, - cmOStringStream& deleteStr) +void cmCPackNSISGenerator::CreateMenuLinks( std::ostringstream& str, + std::ostringstream& deleteStr) { const char* cpackMenuLinks = this->GetOption("CPACK_NSIS_MENU_LINKS"); @@ -694,7 +694,7 @@ bool cmCPackNSISGenerator::SupportsComponentInstallation() const std::string cmCPackNSISGenerator:: CreateComponentDescription(cmCPackComponent *component, - cmOStringStream& macrosOut) + std::ostringstream& macrosOut) { // Basic description of the component std::string componentCode = "Section "; @@ -714,7 +714,7 @@ CreateComponentDescription(cmCPackComponent *component, } else if (!component->InstallationTypes.empty()) { - cmOStringStream out; + std::ostringstream out; std::vector<cmCPackInstallationType *>::iterator installTypeIter; for (installTypeIter = component->InstallationTypes.begin(); installTypeIter != component->InstallationTypes.end(); @@ -734,7 +734,7 @@ CreateComponentDescription(cmCPackComponent *component, // Compute the name of the archive. std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); packagesDir += ".dummy"; - cmOStringStream out; + std::ostringstream out; out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-" << component->Name << ".zip"; component->ArchiveFile = out.str(); @@ -825,7 +825,7 @@ CreateComponentDescription(cmCPackComponent *component, } out << std::endl; - totalSize += cmSystemTools::FileLength((dirName + *fileIt).c_str()); + totalSize += cmSystemTools::FileLength(dirName + *fileIt); } } @@ -859,7 +859,7 @@ CreateComponentDescription(cmCPackComponent *component, { totalSizeInKbytes = 1; } - cmOStringStream out; + std::ostringstream out; out << " AddSize " << totalSizeInKbytes << "\n" << " Push \"" << component->ArchiveFile << "\"\n" << " Call DownloadFile\n" @@ -935,7 +935,7 @@ std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription } visited.insert(component); - cmOStringStream out; + std::ostringstream out; std::vector<cmCPackComponent *>::iterator dependIt; for (dependIt = component->Dependencies.begin(); dependIt != component->Dependencies.end(); @@ -967,7 +967,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription } visited.insert(component); - cmOStringStream out; + std::ostringstream out; std::vector<cmCPackComponent *>::iterator dependIt; for (dependIt = component->ReverseDependencies.begin(); dependIt != component->ReverseDependencies.end(); @@ -992,7 +992,7 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription std::string cmCPackNSISGenerator:: CreateComponentGroupDescription(cmCPackComponentGroup *group, - cmOStringStream& macrosOut) + std::ostringstream& macrosOut) { if (group->Components.empty() && group->Subgroups.empty()) { diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h index e46fbda..c7b2ce1 100644 --- a/Source/CPack/cmCPackNSISGenerator.h +++ b/Source/CPack/cmCPackNSISGenerator.h @@ -38,8 +38,8 @@ public: protected: virtual int InitializeInternal(); - void CreateMenuLinks( cmOStringStream& str, - cmOStringStream& deleteStr); + void CreateMenuLinks( std::ostringstream& str, + std::ostringstream& deleteStr); int PackageFiles(); virtual const char* GetOutputExtension() { return ".exe"; } virtual const char* GetOutputPostfix() { return "win32"; } @@ -56,7 +56,7 @@ protected: /// macrosOut. std::string CreateComponentDescription(cmCPackComponent *component, - cmOStringStream& macrosOut); + std::ostringstream& macrosOut); /// Produce NSIS code that selects all of the components that this component /// depends on, recursively. @@ -75,7 +75,7 @@ protected: /// added macros will be emitted via macrosOut. std::string CreateComponentGroupDescription(cmCPackComponentGroup *group, - cmOStringStream& macrosOut); + std::ostringstream& macrosOut); /// Translations any newlines found in the string into \\r\\n, so that the /// resulting string can be used within NSIS. diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx index 28c7f1d..313e08b 100644 --- a/Source/CPack/cmCPackOSXX11Generator.cxx +++ b/Source/CPack/cmCPackOSXX11Generator.cxx @@ -45,8 +45,8 @@ int cmCPackOSXX11Generator::PackageFiles() { cmCPackLogger(cmCPackLog::LOG_DEBUG, "The cpackPackageExecutables: " << cpackPackageExecutables << "." << std::endl); - cmOStringStream str; - cmOStringStream deleteStr; + std::ostringstream str; + std::ostringstream deleteStr; std::vector<std::string> cpackPackageExecutablesVector; cmSystemTools::ExpandListArgument(cpackPackageExecutables, cpackPackageExecutablesVector); @@ -165,7 +165,7 @@ int cmCPackOSXX11Generator::PackageFiles() std::string output; std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/hdiutilOutput.log"; - cmOStringStream dmgCmd; + std::ostringstream dmgCmd; dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE") << "\" create -ov -format UDZO -srcfolder \"" << diskImageDirectory.c_str() diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx index d736948..dfe35c9 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.cxx +++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx @@ -24,11 +24,20 @@ #include <cmsys/Glob.hxx> #include <cmsys/FStream.hxx> +#include <assert.h> + +static inline +unsigned int getVersion(unsigned int major, unsigned int minor) +{ + assert(major < 256 && minor < 256); + return ((major & 0xFF) << 16 | minor); +} + //---------------------------------------------------------------------- cmCPackPackageMakerGenerator::cmCPackPackageMakerGenerator() { this->PackageMakerVersion = 0.0; - this->PackageCompatibilityVersion = 10.4; + this->PackageCompatibilityVersion = getVersion(10, 4); } //---------------------------------------------------------------------- @@ -39,7 +48,7 @@ cmCPackPackageMakerGenerator::~cmCPackPackageMakerGenerator() //---------------------------------------------------------------------- bool cmCPackPackageMakerGenerator::SupportsComponentInstallation() const { - return this->PackageCompatibilityVersion >= 10.4; + return this->PackageCompatibilityVersion >= getVersion(10, 4); } //---------------------------------------------------------------------- @@ -241,7 +250,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() std::string packageFile; if (compIt->second.IsDownloaded) { - if (this->PackageCompatibilityVersion >= 10.5 && + if (this->PackageCompatibilityVersion >= getVersion(10, 5) && this->PackageMakerVersion >= 3.0) { // Build this package within the upload directory. @@ -260,7 +269,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() } else if (!warnedAboutDownloadCompatibility) { - if (this->PackageCompatibilityVersion < 10.5) + if (this->PackageCompatibilityVersion < getVersion(10, 5)) { cmCPackLogger( cmCPackLog::LOG_WARNING, @@ -325,7 +334,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() if (this->Components.empty()) { // Use PackageMaker to build the package. - cmOStringStream pkgCmd; + std::ostringstream pkgCmd; pkgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM") << "\" -build -p \"" << packageDirFileName << "\""; if (this->Components.empty()) @@ -359,7 +368,7 @@ int cmCPackPackageMakerGenerator::PackageFiles() std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/hdiutilOutput.log"; - cmOStringStream dmgCmd; + std::ostringstream dmgCmd; dmgCmd << "\"" << this->GetOption("CPACK_INSTALLER_PROGRAM_DISK_IMAGE") << "\" create -ov -format UDZO -srcfolder \"" << packageDirFileName << "\" \"" << packageFileNames[0] << "\""; @@ -520,22 +529,29 @@ int cmCPackPackageMakerGenerator::InitializeInternal() const char *packageCompat = this->GetOption("CPACK_OSX_PACKAGE_VERSION"); if (packageCompat && *packageCompat) { - this->PackageCompatibilityVersion = atof(packageCompat); + unsigned int majorVersion = 10; + unsigned int minorVersion = 5; + int res = sscanf(packageCompat, "%u.%u", &majorVersion, &minorVersion); + if (res == 2) + { + this->PackageCompatibilityVersion = + getVersion(majorVersion, minorVersion); + } } else if (this->GetOption("CPACK_DOWNLOAD_SITE")) { this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.5"); - this->PackageCompatibilityVersion = 10.5; + this->PackageCompatibilityVersion = getVersion(10, 5); } else if (this->GetOption("CPACK_COMPONENTS_ALL")) { this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.4"); - this->PackageCompatibilityVersion = 10.4; + this->PackageCompatibilityVersion = getVersion(10, 4); } else { this->SetOption("CPACK_OSX_PACKAGE_VERSION", "10.3"); - this->PackageCompatibilityVersion = 10.3; + this->PackageCompatibilityVersion = getVersion(10, 3); } std::vector<std::string> no_paths; @@ -687,7 +703,7 @@ cmCPackPackageMakerGenerator::GetPackageName(const cmCPackComponent& component) { std::string packagesDir = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); packagesDir += ".dummy"; - cmOStringStream out; + std::ostringstream out; out << cmSystemTools::GetFilenameWithoutLastExtension(packagesDir) << "-" << component.Name << ".pkg"; return out.str(); @@ -710,9 +726,9 @@ GenerateComponentPackage(const char *packageFile, packageFile << std::endl); // The command that will be used to run PackageMaker - cmOStringStream pkgCmd; + std::ostringstream pkgCmd; - if (this->PackageCompatibilityVersion < 10.5 || + if (this->PackageCompatibilityVersion < getVersion(10, 5) || this->PackageMakerVersion < 3.0) { // Create Description.plist and Info.plist files for normal Mac OS @@ -800,7 +816,7 @@ WriteDistributionFile(const char* metapackageFile) // Create the choice outline, which provides a tree-based view of // the components in their groups. - cmOStringStream choiceOut; + std::ostringstream choiceOut; choiceOut << "<choices-outline>" << std::endl; // Emit the outline for the groups @@ -862,7 +878,8 @@ WriteDistributionFile(const char* metapackageFile) //---------------------------------------------------------------------- void cmCPackPackageMakerGenerator:: -CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out) +CreateChoiceOutline(const cmCPackComponentGroup& group, + std::ostringstream& out) { out << "<line choice=\"" << group.Name << "Choice\">" << std::endl; std::vector<cmCPackComponentGroup*>::const_iterator groupIt; @@ -885,7 +902,7 @@ CreateChoiceOutline(const cmCPackComponentGroup& group, cmOStringStream& out) //---------------------------------------------------------------------- void cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group, - cmOStringStream& out) + std::ostringstream& out) { out << "<choice id=\"" << group.Name << "Choice\" " << "title=\"" << group.DisplayName << "\" " @@ -903,7 +920,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponentGroup& group, //---------------------------------------------------------------------- void cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, - cmOStringStream& out) + std::ostringstream& out) { std::string packageId = "com."; packageId += this->GetOption("CPACK_PACKAGE_VENDOR"); @@ -964,6 +981,7 @@ cmCPackPackageMakerGenerator::CreateChoice(const cmCPackComponent& component, std::string dirName = this->GetOption("CPACK_TEMPORARY_DIRECTORY"); dirName += '/'; dirName += component.Name; + dirName += this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); unsigned long installedSize = component.GetInstalledSizeInKbytes(dirName.c_str()); @@ -988,7 +1006,7 @@ void cmCPackPackageMakerGenerator:: AddDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, - cmOStringStream& out) + std::ostringstream& out) { if (visited.find(&component) != visited.end()) { @@ -1012,7 +1030,7 @@ void cmCPackPackageMakerGenerator:: AddReverseDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, - cmOStringStream& out) + std::ostringstream& out) { if (visited.find(&component) != visited.end()) { diff --git a/Source/CPack/cmCPackPackageMakerGenerator.h b/Source/CPack/cmCPackPackageMakerGenerator.h index e350a60..7d349c6 100644 --- a/Source/CPack/cmCPackPackageMakerGenerator.h +++ b/Source/CPack/cmCPackPackageMakerGenerator.h @@ -84,30 +84,30 @@ protected: // dependency attributes for inter-component dependencies. void AddDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, - cmOStringStream& out); + std::ostringstream& out); // Subroutine of WriteDistributionFile that writes out the // reverse dependency attributes for inter-component dependencies. void AddReverseDependencyAttributes(const cmCPackComponent& component, std::set<const cmCPackComponent *>& visited, - cmOStringStream& out); + std::ostringstream& out); // Generates XML that encodes the hierarchy of component groups and // their components in a form that can be used by distribution // metapackages. void CreateChoiceOutline(const cmCPackComponentGroup& group, - cmOStringStream& out); + std::ostringstream& out); /// Create the "choice" XML element to describe a component group /// for the installer GUI. void CreateChoice(const cmCPackComponentGroup& group, - cmOStringStream& out); + std::ostringstream& out); /// Create the "choice" XML element to describe a component for the /// installer GUI. void CreateChoice(const cmCPackComponent& component, - cmOStringStream& out); + std::ostringstream& out); // Escape the given string to make it usable as an XML attribute // value. @@ -117,7 +117,7 @@ protected: cmCPackComponent PostFlightComponent; double PackageMakerVersion; - double PackageCompatibilityVersion; + unsigned int PackageCompatibilityVersion; }; #endif diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 26bf607..00bfe5b 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -117,7 +117,7 @@ int main (int argc, char const* const* argv) cmSystemTools::EnableMSVCDebugHook(); - if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) + if (cmSystemTools::GetCurrentWorkingDirectory().empty()) { cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Current working directory cannot be established." << std::endl); @@ -426,7 +426,7 @@ int main (int argc, char const* const* argv) = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR"); const char* projVersionPatch = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH"); - cmOStringStream ostr; + std::ostringstream ostr; ostr << projVersionMajor << "." << projVersionMinor << "." << projVersionPatch; mf->AddDefinition("CPACK_PACKAGE_VERSION", diff --git a/Source/CTest/cmCTestBatchTestHandler.cxx b/Source/CTest/cmCTestBatchTestHandler.cxx index 7f966aa..d62c260 100644 --- a/Source/CTest/cmCTestBatchTestHandler.cxx +++ b/Source/CTest/cmCTestBatchTestHandler.cxx @@ -58,7 +58,7 @@ void cmCTestBatchTestHandler::WriteSrunArgs(int test, cmsys::ofstream& fout) fout << "-J=" << properties->Name << " "; //Write dependency information - /*if(this->Tests[test].size() > 0) + /*if(!this->Tests[test].empty()) { fout << "-P=afterany"; for(TestSet::iterator i = this->Tests[test].begin(); diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index a101e39..d90aeb7 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -55,14 +55,14 @@ int cmCTestBuildAndTestHandler::ProcessHandler() //---------------------------------------------------------------------- int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, - cmOStringStream &out, std::string &cmakeOutString, std::string &cwd, + std::ostringstream &out, std::string &cmakeOutString, std::string &cwd, cmake *cm) { unsigned int k; std::vector<std::string> args; args.push_back(cmSystemTools::GetCMakeCommand()); args.push_back(this->SourceDir); - if(this->BuildGenerator.size()) + if(!this->BuildGenerator.empty()) { std::string generator = "-G"; generator += this->BuildGenerator; @@ -74,7 +74,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, platform += this->BuildGeneratorPlatform; args.push_back(platform); } - if(this->BuildGeneratorToolset.size()) + if(!this->BuildGeneratorToolset.empty()) { std::string toolset = "-T"; toolset += this->BuildGeneratorToolset; @@ -82,7 +82,7 @@ int cmCTestBuildAndTestHandler::RunCMake(std::string* outstring, } const char* config = 0; - if ( this->CTest->GetConfigType().size() > 0 ) + if (!this->CTest->GetConfigType().empty()) { config = this->CTest->GetConfigType().c_str(); } @@ -193,7 +193,7 @@ public: int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) { // if the generator and make program are not specified then it is an error - if (!this->BuildGenerator.size()) + if (this->BuildGenerator.empty()) { if(outstring) { @@ -209,10 +209,10 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::string cmakeOutString; cmCTestBuildAndTestCaptureRAII captureRAII(cm, cmakeOutString); static_cast<void>(captureRAII); - cmOStringStream out; + std::ostringstream out; - if ( this->CTest->GetConfigType().size() == 0 && - this->ConfigSample.size()) + if ( this->CTest->GetConfigType().empty() && + !this->ConfigSample.empty()) { // use the config sample to set the ConfigType std::string fullPath; @@ -225,7 +225,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) resultingConfig, extraPaths, failed); - if (fullPath.size() && resultingConfig.size()) + if (!fullPath.empty() && !resultingConfig.empty()) { this->CTest->SetConfigType(resultingConfig.c_str()); } @@ -269,7 +269,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) // do the build std::vector<std::string>::iterator tarIt; - if ( this->BuildTargets.size() == 0 ) + if (this->BuildTargets.empty()) { this->BuildTargets.push_back(""); } @@ -291,7 +291,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) } std::string output; const char* config = 0; - if ( this->CTest->GetConfigType().size() > 0 ) + if (!this->CTest->GetConfigType().empty()) { config = this->CTest->GetConfigType().c_str(); } @@ -329,7 +329,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) } // if no test was specified then we are done - if (!this->TestCommand.size()) + if (this->TestCommand.empty()) { return 0; } @@ -340,7 +340,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::string resultingConfig; std::vector<std::string> extraPaths; // if this->ExecutableDirectory is set try that as well - if (this->ExecutableDirectory.size()) + if (!this->ExecutableDirectory.empty()) { std::string tempPath = this->ExecutableDirectory; tempPath += "/"; @@ -388,7 +388,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) std::string outs; int retval = 0; // run the test from the this->BuildRunDir if set - if(this->BuildRunDir.size()) + if(!this->BuildRunDir.empty()) { out << "Run test in directory: " << this->BuildRunDir << "\n"; cmSystemTools::ChangeDirectory(this->BuildRunDir); diff --git a/Source/CTest/cmCTestBuildAndTestHandler.h b/Source/CTest/cmCTestBuildAndTestHandler.h index 5a7b916..a75c631 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.h +++ b/Source/CTest/cmCTestBuildAndTestHandler.h @@ -50,7 +50,7 @@ public: protected: ///! Run CMake and build a test and then run it as a single test. int RunCMakeAndTest(std::string* output); - int RunCMake(std::string* outstring, cmOStringStream &out, + int RunCMake(std::string* outstring, std::ostringstream &out, std::string &cmakeOutString, std::string &cwd, cmake *cm); diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index a5a593a..c4df741 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -148,7 +148,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() } else { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "has no project to build. If this is a " "\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR " "and CTEST_PROJECT_NAME are set." @@ -181,7 +181,7 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, bool ret = cmCTestHandlerCommand::InitialPass(args, status); if ( this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) { - cmOStringStream str; + std::ostringstream str; str << this->Handler->GetTotalErrors(); this->Makefile->AddDefinition( this->Values[ctb_NUMBER_ERRORS], str.str().c_str()); @@ -189,7 +189,7 @@ bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, if ( this->Values[ctb_NUMBER_WARNINGS] && *this->Values[ctb_NUMBER_WARNINGS]) { - cmOStringStream str; + std::ostringstream str; str << this->Handler->GetTotalWarnings(); this->Makefile->AddDefinition( this->Values[ctb_NUMBER_WARNINGS], str.str().c_str()); diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 5e8f8f0..8f087ab 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -344,7 +344,7 @@ int cmCTestBuildHandler::ProcessHandler() // Determine build command and build directory std::string makeCommand = this->GetMakeCommand(); - if ( makeCommand.size() == 0 ) + if (makeCommand.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find MakeCommand key in the DartConfiguration.tcl" @@ -354,7 +354,7 @@ int cmCTestBuildHandler::ProcessHandler() const std::string &buildDirectory = this->CTest->GetCTestConfiguration("BuildDirectory"); - if ( buildDirectory.size() == 0 ) + if (buildDirectory.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find BuildDirectory key in the DartConfiguration.tcl" @@ -702,12 +702,12 @@ void cmCTestBuildHandler::GenerateXMLLogScraped(std::ostream& os) } if ( !cm->SourceFile.empty() && cm->LineNumber >= 0 ) { - if ( cm->SourceFile.size() > 0 ) + if (!cm->SourceFile.empty()) { os << "\t\t<SourceFile>" << cm->SourceFile << "</SourceFile>" << std::endl; } - if ( cm->SourceFileTail.size() > 0 ) + if (!cm->SourceFileTail.empty()) { os << "\t\t<SourceFileTail>" << cm->SourceFileTail << "</SourceFileTail>" << std::endl; @@ -828,7 +828,7 @@ cmCTestBuildHandler::LaunchHelper::LaunchHelper(cmCTestBuildHandler* handler): this->WriteLauncherConfig(); std::string launchEnv = "CTEST_LAUNCH_LOGS="; launchEnv += launchDir; - cmSystemTools::PutEnv(launchEnv.c_str()); + cmSystemTools::PutEnv(launchEnv); } } @@ -1094,11 +1094,8 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, { // Create a contiguous array for the line this->CurrentProcessingLine.clear(); - t_BuildProcessingQueueType::iterator cit; - for ( cit = queue->begin(); cit != it; ++cit ) - { - this->CurrentProcessingLine.push_back(*cit); - } + this->CurrentProcessingLine.insert(this->CurrentProcessingLine.end(), + queue->begin(), it); this->CurrentProcessingLine.push_back(0); const char* line = &*this->CurrentProcessingLine.begin(); @@ -1153,7 +1150,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, { // This is not an error or warning. // So, figure out if this is a post-context line - if ( this->ErrorsAndWarnings.size() && + if ( !this->ErrorsAndWarnings.empty() && this->LastErrorOrWarning != this->ErrorsAndWarnings.end() && this->PostContextCount < this->MaxPostContext ) { diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index ef62fd3..0f13263 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -66,7 +66,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() const std::string cmakelists_file = source_dir + "/CMakeLists.txt"; if ( !cmSystemTools::FileExists(cmakelists_file.c_str()) ) { - cmOStringStream e; + std::ostringstream e; e << "CMakeLists.txt file does not exist [" << cmakelists_file << "]"; this->SetError(e.str()); diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx index c492bf0..506433f 100644 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ b/Source/CTest/cmCTestConfigureHandler.cxx @@ -38,7 +38,7 @@ int cmCTestConfigureHandler::ProcessHandler() cmCTestLog(this->CTest, HANDLER_OUTPUT, "Configure project" << std::endl); std::string cCommand = this->CTest->GetCTestConfiguration("ConfigureCommand"); - if ( cCommand.size() == 0 ) + if (cCommand.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find ConfigureCommand key in the DartConfiguration.tcl" @@ -48,7 +48,7 @@ int cmCTestConfigureHandler::ProcessHandler() std::string buildDirectory = this->CTest->GetCTestConfiguration("BuildDirectory"); - if ( buildDirectory.size() == 0 ) + if (buildDirectory.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find BuildDirectory key in the DartConfiguration.tcl" diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 8dc22a8..08b7c66 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -87,7 +87,7 @@ public: } args.push_back(0); // null terminate cmsysProcess_SetCommand(this->Process, &*args.begin()); - if(this->WorkingDirectory.size()) + if(!this->WorkingDirectory.empty()) { cmsysProcess_SetWorkingDirectory(this->Process, this->WorkingDirectory.c_str()); @@ -270,7 +270,7 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, std::string ndc = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage", fFile.c_str(), checkDir.c_str()); - if ( ndc.size() ) + if (!ndc.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc << " so skip coverage of " << file << std::endl); @@ -281,7 +281,7 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, // Get the relative path to the file an apply it to the opposite directory. // If it is the same as fileDir, then ignore, otherwise check. std::string relPath; - if(checkDir.size() ) + if(!checkDir.empty()) { relPath = cmSystemTools::RelativePath(checkDir.c_str(), fFile.c_str()); @@ -309,7 +309,7 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, ndc = cmSystemTools::FileExistsInParentDirectories(".NoDartCoverage", fFile.c_str(), checkDir.c_str()); - if ( ndc.size() ) + if (!ndc.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc << " so skip coverage of: " << file << std::endl); @@ -544,7 +544,7 @@ int cmCTestCoverageHandler::ProcessHandler() cmsys::ifstream ifs(fullFileName.c_str()); if ( !ifs) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "Cannot open source file: " << fullFileName; errorsWhileAccumulating.push_back(ostr.str()); error ++; @@ -563,7 +563,7 @@ int cmCTestCoverageHandler::ProcessHandler() if ( !cmSystemTools::GetLineFromStream(ifs, line) && cc != fcov.size() -1 ) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "Problem reading source file: " << fullFileName << " line:" << cc << " out total: " << fcov.size()-1; errorsWhileAccumulating.push_back(ostr.str()); @@ -584,8 +584,8 @@ int cmCTestCoverageHandler::ProcessHandler() } if ( cmSystemTools::GetLineFromStream(ifs, line) ) { - cmOStringStream ostr; - ostr << "Looks like there are more lines in the file: " << line; + std::ostringstream ostr; + ostr << "Looks like there are more lines in the file: " << fullFileName; errorsWhileAccumulating.push_back(ostr.str()); } float cper = 0; @@ -633,7 +633,7 @@ int cmCTestCoverageHandler::ProcessHandler() cmsys::ifstream ifs(fullPath.c_str()); if (!ifs) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "Cannot open source file: " << fullPath; errorsWhileAccumulating.push_back(ostr.str()); error ++; @@ -665,7 +665,7 @@ int cmCTestCoverageHandler::ProcessHandler() this->EndCoverageLogFile(covLogFile, logFileCount); - if ( errorsWhileAccumulating.size() > 0 ) + if (!errorsWhileAccumulating.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, std::endl); cmCTestLog(this->CTest, ERROR_MESSAGE, @@ -884,7 +884,7 @@ struct cmCTestCoverageHandlerLocale { if(!lc_all.empty()) { - cmSystemTools::PutEnv(("LC_ALL=" + lc_all).c_str()); + cmSystemTools::PutEnv("LC_ALL=" + lc_all); } else { @@ -910,7 +910,7 @@ int cmCTestCoverageHandler::HandleJacocoCoverage( g.FindFiles(coverageFile); files=g.GetFiles(); - if (files.size() > 0) + if (!files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found Jacoco Files, Performing Coverage" << std::endl); @@ -943,7 +943,7 @@ int cmCTestCoverageHandler::HandleDelphiCoverage( g.FindFiles(coverageFile); files=g.GetFiles(); - if (files.size() > 0) + if (!files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found Delphi HTML Files, Performing Coverage" << std::endl); @@ -973,7 +973,7 @@ int cmCTestCoverageHandler::HandleBlanketJSCoverage( std::vector<std::string> files; g.FindFiles(coverageFile); files=g.GetFiles(); - if (files.size() > 0) + if (!files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found BlanketJS output JSON, Performing Coverage" << std::endl); @@ -1037,7 +1037,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( this->FindGCovFiles(files); std::vector<std::string>::iterator it; - if ( files.size() == 0 ) + if (files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any GCov coverage files." @@ -1131,7 +1131,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestLog(this->CTest, DEBUG, "Line: [" << *line << "]" << std::endl); - if ( line->size() == 0 ) + if (line->empty()) { // Ignore empty line; probably style 2 } @@ -1311,7 +1311,7 @@ int cmCTestCoverageHandler::HandleGCovCoverage( //TODO: Handle gcov 3.0 non-coverage lines // Skip empty lines - if ( !nl.size() ) + if (nl.empty()) { continue; } @@ -1456,7 +1456,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( this->FindLCovFiles(files); std::vector<std::string>::iterator it; - if ( files.size() == 0 ) + if (files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any LCov coverage files." @@ -1491,24 +1491,24 @@ int cmCTestCoverageHandler::HandleLCovCoverage( lcovExtraFlags + " "; cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Current coverage dir: " - << fileDir.c_str() << std::endl); + << fileDir << std::endl); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() << std::endl); std::string output = ""; std::string errors = ""; int retVal = 0; - *cont->OFS << "* Run coverage for: " << fileDir.c_str() << std::endl; - *cont->OFS << " Command: " << command.c_str() << std::endl; + *cont->OFS << "* Run coverage for: " << fileDir << std::endl; + *cont->OFS << " Command: " << command << std::endl; int res = this->CTest->RunCommand(command.c_str(), &output, &errors, &retVal, fileDir.c_str(), 0 /*this->TimeOut*/); - *cont->OFS << " Output: " << output.c_str() << std::endl; - *cont->OFS << " Errors: " << errors.c_str() << std::endl; + *cont->OFS << " Output: " << output << std::endl; + *cont->OFS << " Errors: " << errors << std::endl; if ( ! res ) { cmCTestLog(this->CTest, ERROR_MESSAGE, - "Problem running coverage on file: " << it->c_str() << std::endl); + "Problem running coverage on file: " << *it << std::endl); cmCTestLog(this->CTest, ERROR_MESSAGE, "Command produced error: " << errors << std::endl); cont->Error ++; @@ -1517,7 +1517,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( if ( retVal != 0 ) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Coverage command returned: " - << retVal << " while processing: " << it->c_str() << std::endl); + << retVal << " while processing: " << *it << std::endl); cmCTestLog(this->CTest, ERROR_MESSAGE, "Command produced error: " << cont->Error << std::endl); } @@ -1538,7 +1538,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( std::string sourceFile; std::string lcovFile; - if ( line->size() == 0 ) + if (line->empty()) { // Ignore empty line } @@ -1627,7 +1627,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage( cnt ++; // Skip empty lines - if ( !nl.size() ) + if (nl.empty()) { continue; } @@ -1759,7 +1759,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( gl.FindFiles(daGlob); std::vector<std::string> files = gl.GetFiles(); - if ( files.size() == 0 ) + if (files.empty()) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any Python Trace.py coverage files." @@ -1813,7 +1813,7 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( cnt ++; // Skip empty lines - if ( !nl.size() ) + if (nl.empty()) { continue; } @@ -2076,7 +2076,7 @@ int cmCTestCoverageHandler::RunBullseyeCommand( std::string& outputFile) { std::string program = cmSystemTools::FindProgram(cmd); - if(program.size() == 0) + if(program.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find :" << cmd << "\n"); return 0; @@ -2183,7 +2183,7 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( while(cmSystemTools::GetLineFromStream(fin, stdline)) { // if we have a line of output from stdout - if(stdline.size()) + if(!stdline.empty()) { // parse the comma separated output this->ParseBullsEyeCovsrcLine(stdline, @@ -2498,11 +2498,7 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir) // Label the source with the target labels. LabelSet& labelSet = this->SourceLabels[source]; - for(std::vector<int>::const_iterator li = targetLabels.begin(); - li != targetLabels.end(); ++li) - { - labelSet.insert(*li); - } + labelSet.insert(targetLabels.begin(), targetLabels.end()); } } } @@ -2600,7 +2596,7 @@ std::set<std::string> cmCTestCoverageHandler::FindUncoveredFiles( } } - if(extraMatches.size()) + if(!extraMatches.empty()) { for(cmCTestCoverageHandlerContainer::TotalCoverageMap::iterator i = cont->TotalCoverage.begin(); i != cont->TotalCoverage.end(); ++i) diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx new file mode 100644 index 0000000..b0d26cc --- /dev/null +++ b/Source/CTest/cmCTestCurl.cxx @@ -0,0 +1,271 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmCTestCurl.h" + +#include "cmSystemTools.h" +#include "cmCTest.h" + +cmCTestCurl::cmCTestCurl(cmCTest* ctest) +{ + this->CTest = ctest; + this->SetProxyType(); + this->UseHttp10 = false; + // In windows, this will init the winsock stuff + ::curl_global_init(CURL_GLOBAL_ALL); + // default is to verify https + this->VerifyPeerOff = false; + this->VerifyHostOff = false; + this->TimeOutSeconds = 0; +} + +namespace +{ +static size_t +curlWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, + void *data) +{ + int realsize = (int)(size * nmemb); + + std::vector<char> *vec + = static_cast<std::vector<char>* >(data); + const char* chPtr = static_cast<char*>(ptr); + vec->insert(vec->end(), chPtr, chPtr + realsize); + return realsize; +} + +static size_t +curlDebugCallback(CURL *, curl_infotype, char *chPtr, + size_t size, void *data) +{ + std::vector<char> *vec + = static_cast<std::vector<char>* >(data); + vec->insert(vec->end(), chPtr, chPtr + size); + + return size; +} + +} + +void cmCTestCurl::SetCurlOptions(std::vector<std::string> const& args) +{ + for( std::vector<std::string>::const_iterator i = args.begin(); + i != args.end(); ++i) + { + if(*i == "CURLOPT_SSL_VERIFYPEER_OFF") + { + this->VerifyPeerOff = true; + } + if(*i == "CURLOPT_SSL_VERIFYHOST_OFF") + { + this->VerifyHostOff = true; + } + } +} + +bool cmCTestCurl::InitCurl() +{ + this->Curl = curl_easy_init(); + if(!this->Curl) + { + return false; + } + if(this->VerifyPeerOff) + { + curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYPEER, 0); + } + if(this->VerifyHostOff) + { + curl_easy_setopt(this->Curl, CURLOPT_SSL_VERIFYHOST, 0); + } + if(this->HTTPProxy.size()) + { + curl_easy_setopt(this->Curl, CURLOPT_PROXY, this->HTTPProxy.c_str()); + curl_easy_setopt(this->Curl, CURLOPT_PROXYTYPE, this->HTTPProxyType); + if (this->HTTPProxyAuth.size() > 0) + { + curl_easy_setopt(this->Curl, CURLOPT_PROXYUSERPWD, + this->HTTPProxyAuth.c_str()); + } + } + if(this->UseHttp10) + { + curl_easy_setopt(this->Curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); + } + // enable HTTP ERROR parsing + curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + return true; +} + + +bool cmCTestCurl::UploadFile(std::string const& local_file, + std::string const& url, + std::string const& fields, + std::string& response) +{ + response = ""; + if(!this->InitCurl()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed"); + return false; + } + /* enable uploading */ + curl_easy_setopt(this->Curl, CURLOPT_UPLOAD, 1); + // if there is little to no activity for too long stop submitting + if(this->TimeOutSeconds) + { + ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_LIMIT, 1); + ::curl_easy_setopt(this->Curl, CURLOPT_LOW_SPEED_TIME, + this->TimeOutSeconds); + } + /* HTTP PUT please */ + ::curl_easy_setopt(this->Curl, CURLOPT_PUT, 1); + ::curl_easy_setopt(this->Curl, CURLOPT_VERBOSE, 1); + + FILE* ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); + if(!ftpfile) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Could not open file for upload: " << local_file << "\n"); + return false; + } + // set the url + std::string upload_url = url; + upload_url += "?"; + upload_url += fields; + ::curl_easy_setopt(this->Curl, CURLOPT_URL, upload_url.c_str()); + // now specify which file to upload + ::curl_easy_setopt(this->Curl, CURLOPT_INFILE, ftpfile); + unsigned long filelen = cmSystemTools::FileLength(local_file); + // and give the size of the upload (optional) + ::curl_easy_setopt(this->Curl, CURLOPT_INFILESIZE, + static_cast<long>(filelen)); + ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION, + curlWriteMemoryCallback); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, + curlDebugCallback); + std::vector<char> responseData; + std::vector<char> debugData; + ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData); + ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + // Now run off and do what you've been told! + ::curl_easy_perform(this->Curl); + ::fclose(ftpfile); + ::curl_global_cleanup(); + + if ( responseData.size() > 0 ) + { + response = std::string(responseData.begin(), responseData.end()); + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Curl response: [" << response << "]\n"); + } + std::string curlDebug; + if ( debugData.size() > 0 ) + { + curlDebug = std::string(debugData.begin(), debugData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + } + if(response.size() == 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "No response from server.\n" << + curlDebug); + return false; + } + return true; +} + +bool cmCTestCurl::HttpRequest(std::string const& url, + std::string const& fields, + std::string& response) +{ + response = ""; + cmCTestLog(this->CTest, DEBUG, "HttpRequest\n" + << "url: " << url << "\n" + << "fields " << fields << "\n"); + if(!this->InitCurl()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, "Initialization of curl failed"); + return false; + } + curl_easy_setopt(this->Curl, CURLOPT_POST, 1); + curl_easy_setopt(this->Curl, CURLOPT_POSTFIELDS, fields.c_str()); + ::curl_easy_setopt(this->Curl, CURLOPT_URL, url.c_str()); + ::curl_easy_setopt(this->Curl, CURLOPT_FOLLOWLOCATION, 1); + //set response options + ::curl_easy_setopt(this->Curl, CURLOPT_WRITEFUNCTION, + curlWriteMemoryCallback); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGFUNCTION, + curlDebugCallback); + std::vector<char> responseData; + std::vector<char> debugData; + ::curl_easy_setopt(this->Curl, CURLOPT_FILE, (void *)&responseData); + ::curl_easy_setopt(this->Curl, CURLOPT_DEBUGDATA, (void *)&debugData); + ::curl_easy_setopt(this->Curl, CURLOPT_FAILONERROR, 1); + + CURLcode res = ::curl_easy_perform(this->Curl); + + ::curl_easy_cleanup(this->Curl); + ::curl_global_cleanup(); + if ( responseData.size() > 0 ) + { + response = std::string(responseData.begin(), responseData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl response: [" << response << "]\n"); + } + if ( debugData.size() > 0 ) + { + std::string curlDebug = std::string(debugData.begin(), debugData.end()); + cmCTestLog(this->CTest, DEBUG, "Curl debug: [" << curlDebug << "]\n"); + } + cmCTestLog(this->CTest, DEBUG, "Curl res: " << res << "\n"); + return (res == 0); +} + +void cmCTestCurl::SetProxyType() +{ + if ( cmSystemTools::GetEnv("HTTP_PROXY") ) + { + this->HTTPProxy = cmSystemTools::GetEnv("HTTP_PROXY"); + if ( cmSystemTools::GetEnv("HTTP_PROXY_PORT") ) + { + this->HTTPProxy += ":"; + this->HTTPProxy += cmSystemTools::GetEnv("HTTP_PROXY_PORT"); + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_TYPE") ) + { + // this is the default + this->HTTPProxyType = CURLPROXY_HTTP; + std::string type = cmSystemTools::GetEnv("HTTP_PROXY_TYPE"); + // HTTP/SOCKS4/SOCKS5 + if ( type == "HTTP" ) + { + this->HTTPProxyType = CURLPROXY_HTTP; + } + else if ( type == "SOCKS4" ) + { + this->HTTPProxyType = CURLPROXY_SOCKS4; + } + else if ( type == "SOCKS5" ) + { + this->HTTPProxyType = CURLPROXY_SOCKS5; + } + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_USER") ) + { + this->HTTPProxyAuth = cmSystemTools::GetEnv("HTTP_PROXY_USER"); + } + if ( cmSystemTools::GetEnv("HTTP_PROXY_PASSWD") ) + { + this->HTTPProxyAuth += ":"; + this->HTTPProxyAuth += cmSystemTools::GetEnv("HTTP_PROXY_PASSWD"); + } + } +} diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h new file mode 100644 index 0000000..5bb8b41 --- /dev/null +++ b/Source/CTest/cmCTestCurl.h @@ -0,0 +1,52 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmCTestCurl_h +#define cmCTestCurl_h + +#include "cmStandardIncludes.h" + +#include "cm_curl.h" + +class cmCTest; + +class cmCTestCurl +{ +public: + cmCTestCurl(cmCTest*); + bool UploadFile(std::string const& url, + std::string const& file, + std::string const& fields, + std::string& response); + bool HttpRequest(std::string const& url, + std::string const& fields, + std::string& response); + // currently only supports CURLOPT_SSL_VERIFYPEER_OFF + // and CURLOPT_SSL_VERIFYHOST_OFF + void SetCurlOptions(std::vector<std::string> const& args); + void SetUseHttp10On() { this->UseHttp10 = true;} + void SetTimeOutSeconds(int s) { this->TimeOutSeconds = s;} +protected: + void SetProxyType(); + bool InitCurl(); +private: + cmCTest* CTest; + CURL* Curl; + std::string HTTPProxyAuth; + std::string HTTPProxy; + curl_proxytype HTTPProxyType; + bool VerifyHostOff; + bool VerifyPeerOff; + bool UseHttp10; + int TimeOutSeconds; +}; + +#endif diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx index 5ddef01..e175592 100644 --- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx +++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.cxx @@ -24,7 +24,7 @@ bool cmCTestEmptyBinaryDirectoryCommand if ( !cmCTestScriptHandler::EmptyBinaryDirectory(args[0].c_str()) ) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "problem removing the binary directory: " << args[0]; this->SetError(ostr.str()); return false; diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 2df2229..13c8ca5 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -103,7 +103,7 @@ bool cmCTestGenericHandler::StartResultingXML(cmCTest::Part part, << std::endl;); return false; } - cmOStringStream ostr; + std::ostringstream ostr; ostr << name; if ( this->SubmitIndex > 0 ) { @@ -142,7 +142,7 @@ bool cmCTestGenericHandler::StartLogFile(const char* name, "Cannot create log file without providing the name" << std::endl;); return false; } - cmOStringStream ostr; + std::ostringstream ostr; ostr << "Last" << name; if ( this->SubmitIndex > 0 ) { diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index 5b525dd..b886777 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -46,7 +46,7 @@ bool cmCTestHandlerCommand if(!this->CheckArgumentKeyword(args[i]) && !this->CheckArgumentValue(args[i])) { - cmOStringStream e; + std::ostringstream e; e << "called with unknown argument \"" << args[i] << "\"."; this->SetError(e.str()); return false; @@ -141,7 +141,7 @@ bool cmCTestHandlerCommand int res = handler->ProcessHandler(); if ( this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) { - cmOStringStream str; + std::ostringstream str; str << res; this->Makefile->AddDefinition( this->Values[ct_RETURN_VALUE], str.str().c_str()); @@ -183,7 +183,7 @@ bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg) unsigned int k = this->ArgumentIndex; if(this->Values[k]) { - cmOStringStream e; + std::ostringstream e; e << "Called with more than one value for " << this->Arguments[k]; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->ArgumentDoing = ArgumentDoingError; diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index b65d23b..62fa2be 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -21,6 +21,12 @@ #include <cmsys/RegularExpression.hxx> #include <cmsys/FStream.hxx> +#ifdef _WIN32 +#include <io.h> // for _setmode +#include <fcntl.h> // for _O_BINARY +#include <stdio.h> // for std{out,err} and fileno +#endif + //---------------------------------------------------------------------------- cmCTestLaunch::cmCTestLaunch(int argc, const char* const* argv) { @@ -259,6 +265,13 @@ void cmCTestLaunch::RunChild() std::ios::out | std::ios::binary); } +#ifdef _WIN32 + // Do this so that newline transformation is not done when writing to cout + // and cerr below. + _setmode(fileno(stdout), _O_BINARY); + _setmode(fileno(stderr), _O_BINARY); +#endif + // Run the real command. cmsysProcess_Execute(cp); @@ -707,7 +720,7 @@ bool cmCTestLaunch::Match(std::string const& line, //---------------------------------------------------------------------------- bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const { - if(this->OptionFilterPrefix.size() && cmSystemTools::StringStartsWith( + if(!this->OptionFilterPrefix.empty() && cmSystemTools::StringStartsWith( line.c_str(), this->OptionFilterPrefix.c_str())) { return true; diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 089e84b..d4ff24f 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -75,7 +75,7 @@ public: this->ParseError(atts); } // Create the log - cmOStringStream ostr; + std::ostringstream ostr; ostr << name << ":\n"; int i = 0; for(; atts[i] != 0; i+=2) @@ -198,7 +198,7 @@ void cmCTestMemCheckHandler::GenerateTestCommand( { std::vector<std::string>::size_type pp; std::string index; - cmOStringStream stream; + std::ostringstream stream; std::string memcheckcommand = cmSystemTools::ConvertToOutputPath(this->MemoryTester.c_str()); stream << test; @@ -223,7 +223,7 @@ void cmCTestMemCheckHandler::GenerateTestCommand( this->MemoryTesterEnvironmentVariable; for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ ) { - if(memTesterEnvironmentVariable.size()) + if(!memTesterEnvironmentVariable.empty()) { // If we are using env to pass options, append all the options to // this string with space separation. @@ -241,7 +241,7 @@ void cmCTestMemCheckHandler::GenerateTestCommand( } // if this is an env option type, then add the env string as a single // argument. - if(memTesterEnvironmentVariable.size()) + if(!memTesterEnvironmentVariable.empty()) { std::string::size_type pos = memTesterEnvironmentVariable.find("??"); if (pos != std::string::npos) @@ -592,7 +592,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND; } } - if(this->MemoryTester.size() == 0 ) + if(this->MemoryTester.empty()) { cmCTestLog(this->CTest, WARNING, "Memory checker (MemoryCheckCommand) " @@ -834,7 +834,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput( int defects = 0; std::vector<std::string> lines; cmSystemTools::Split(str.c_str(), lines); - cmOStringStream ostr; + std::ostringstream ostr; log = ""; for( std::vector<std::string>::iterator i = lines.begin(); i != lines.end(); ++i) @@ -848,10 +848,10 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput( { resultFound = sanitizerWarning.match(1); } - if(resultFound.size()) + if(!resultFound.empty()) { std::vector<int>::size_type idx = this->FindOrAddWarning(resultFound); - if(result.size() == 0 || idx > result.size()-1) + if(result.empty() || idx > result.size()-1) { result.push_back(1); } @@ -878,7 +878,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput( { std::vector<std::string> lines; cmSystemTools::Split(str.c_str(), lines); - cmOStringStream ostr; + std::ostringstream ostr; log = ""; cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): "); @@ -941,7 +941,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( std::string::size_type cc; - cmOStringStream ostr; + std::ostringstream ostr; log = ""; int defects = 0; @@ -1197,11 +1197,15 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res, << res.Name << std::endl); std::vector<std::string> files; this->TestOutputFileNames(test, files); - if ( files.size() == 0 ) + if (files.empty()) { return; } std::string ofile = files[0]; + if ( ofile.empty() ) + { + return; + } // put a scope around this to close ifs so the file can be removed { cmsys::ifstream ifs(ofile.c_str()); @@ -1265,7 +1269,7 @@ void cmCTestMemCheckHandler::TestOutputFileNames(int test, files) { std::string index; - cmOStringStream stream; + std::ostringstream stream; stream << test; index = stream.str(); std::string ofile = this->MemoryTesterOutputFile; @@ -1276,7 +1280,7 @@ void cmCTestMemCheckHandler::TestOutputFileNames(int test, ofile += ".*"; cmsys::Glob g; g.FindFiles(ofile); - if(g.GetFiles().size() == 0) + if(g.GetFiles().empty()) { std::string log = "Cannot find memory tester output file: " + ofile; diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 4c89caa..f9e8a3c 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -92,7 +92,7 @@ void cmCTestMultiProcessHandler::RunTests() } this->TestHandler->SetMaxIndex(this->FindMaxIndex()); this->StartNextTests(); - while(this->Tests.size() != 0) + while(!this->Tests.empty()) { if(this->StopTimePassed) { @@ -162,12 +162,9 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test) //--------------------------------------------------------- void cmCTestMultiProcessHandler::LockResources(int index) { - for(std::set<std::string>::iterator i = - this->Properties[index]->LockedResources.begin(); - i != this->Properties[index]->LockedResources.end(); ++i) - { - this->LockedResources.insert(*i); - } + this->LockedResources.insert( + this->Properties[index]->LockedResources.begin(), + this->Properties[index]->LockedResources.end()); } //--------------------------------------------------------- @@ -268,7 +265,7 @@ void cmCTestMultiProcessHandler::StartNextTests() bool cmCTestMultiProcessHandler::CheckOutput() { // no more output we are done - if(this->RunningTests.size() == 0) + if(this->RunningTests.empty()) { return false; } @@ -499,11 +496,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() i != previousSet.end(); ++i) { TestSet const& dependencies = this->Tests[*i]; - for(TestSet::const_iterator j = dependencies.begin(); - j != dependencies.end(); ++j) - { - currentSet.insert(*j); - } + currentSet.insert(dependencies.begin(), dependencies.end()); } for(TestSet::const_iterator i = currentSet.begin(); @@ -526,11 +519,8 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList() TestList sortedCopy; - for(TestSet::const_iterator j = currentSet.begin(); - j != currentSet.end(); ++j) - { - sortedCopy.push_back(*j); - } + sortedCopy.insert(sortedCopy.end(), + currentSet.begin(), currentSet.end()); std::stable_sort(sortedCopy.begin(), sortedCopy.end(), comp); @@ -646,7 +636,7 @@ void cmCTestMultiProcessHandler::PrintTestList() testRun.SetTestProperties(&p); testRun.ComputeArguments(); //logs the command in verbose mode - if(p.Labels.size()) //print the labels + if(!p.Labels.empty()) //print the labels { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:"); } @@ -655,7 +645,7 @@ void cmCTestMultiProcessHandler::PrintTestList() { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label); } - if(p.Labels.size()) //print the labels + if(!p.Labels.empty()) //print the labels { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl); } @@ -668,7 +658,7 @@ void cmCTestMultiProcessHandler::PrintTestList() { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Test"); } - cmOStringStream indexStr; + std::ostringstream indexStr; indexStr << " #" << p.Index << ":"; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) @@ -693,7 +683,7 @@ void cmCTestMultiProcessHandler::PrintLabels() allLabels.insert(p.Labels.begin(), p.Labels.end()); } - if(allLabels.size()) + if(!allLabels.empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, "All Labels:" << std::endl); } diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 0bb1a99..31002a6 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -324,7 +324,7 @@ private: //---------------------------------------------------------------------------- void cmCTestP4::SetP4Options(std::vector<char const*> &CommandOptions) { - if(P4Options.size() == 0) + if(P4Options.empty()) { const char* p4 = this->CommandLineTool.c_str(); P4Options.push_back(p4); @@ -349,11 +349,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*> &CommandOptions) std::vector<std::string> args = cmSystemTools::ParseArguments(opts.c_str()); - for(std::vector<std::string>::const_iterator ai = args.begin(); - ai != args.end(); ++ai) - { - P4Options.push_back(*ai); - } + P4Options.insert(P4Options.end(), args.begin(), args.end()); } CommandOptions.clear(); @@ -451,7 +447,7 @@ void cmCTestP4::LoadRevisions() ChangeLists.clear(); this->RunChild(&p4_changes[0], &out, &err); - if(ChangeLists.size() == 0) + if(ChangeLists.empty()) return; //p4 describe -s ...@1111111,2222222 diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx index bdf9b9c..7afbe04 100644 --- a/Source/CTest/cmCTestRunScriptCommand.cxx +++ b/Source/CTest/cmCTestRunScriptCommand.cxx @@ -54,7 +54,7 @@ bool cmCTestRunScriptCommand int ret; cmCTestScriptHandler::RunScript(this->CTest, args[i].c_str(), !np, &ret); - cmOStringStream str; + std::ostringstream str; str << ret; this->Makefile->AddDefinition(returnVariable, str.str().c_str()); } diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 9e3c9fc..314c8ad 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -116,10 +116,10 @@ void cmCTestRunTest::CompressOutput() unsigned char *encoded_buffer = new unsigned char[static_cast<int>(outSize * 1.5)]; - unsigned long rlen + size_t rlen = cmsysBase64_Encode(out, strm.total_out, encoded_buffer, 1); - for(unsigned long i = 0; i < rlen; i++) + for(size_t i = 0; i < rlen; i++) { this->CompressedOutput += encoded_buffer[i]; } @@ -155,7 +155,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) std::string> >::iterator passIt; bool forceFail = false; bool outputTestErrorsToConsole = false; - if ( this->TestProperties->RequiredRegularExpressions.size() > 0 ) + if (!this->TestProperties->RequiredRegularExpressions.empty()) { bool found = false; for ( passIt = this->TestProperties->RequiredRegularExpressions.begin(); @@ -184,7 +184,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } reason += "]"; } - if ( this->TestProperties->ErrorRegularExpressions.size() > 0 ) + if (!this->TestProperties->ErrorRegularExpressions.empty()) { for ( passIt = this->TestProperties->ErrorRegularExpressions.begin(); passIt != this->TestProperties->ErrorRegularExpressions.end(); @@ -318,7 +318,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) *this->TestHandler->LogFile << "----------------------------------------------------------" << std::endl; - if(this->TestResult.Reason.size()) + if(!this->TestResult.Reason.empty()) { *this->TestHandler->LogFile << reasonType << ":\n" << this->TestResult.Reason << "\n"; @@ -670,7 +670,7 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout, cmSystemTools::SaveRestoreEnvironment sre; #endif - if (environment && environment->size()>0) + if (environment && !environment->empty()) { cmSystemTools::AppendEnv(*environment); } @@ -694,7 +694,7 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) cmCTestLog(this->CTest, HANDLER_OUTPUT, "Test"); } - cmOStringStream indexStr; + std::ostringstream indexStr; indexStr << " #" << this->Index << ":"; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 749eb58..8184bb4 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -183,7 +183,7 @@ int cmCTestScriptHandler::ProcessHandler() for (size_t i=0; i < this->ConfigurationScripts.size(); ++i) { // for each script run it - res += this->RunConfigurationScript + res |= this->RunConfigurationScript (cmSystemTools::CollapseFullPath(this->ConfigurationScripts[i]), this->ScriptProcessScope[i]); } @@ -299,7 +299,7 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg) cmsysProcess_Delete(cp); if(failed) { - cmOStringStream message; + std::ostringstream message; message << "Error running command: ["; message << result << "] "; for(std::vector<const char*>::iterator i = argv.begin(); @@ -415,7 +415,7 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) this->UpdateElapsedTime(); // add the script arg if defined - if (script_arg.size()) + if (!script_arg.empty()) { this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str()); } diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 1a39a8a..8ea6cef 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -126,7 +126,7 @@ bool cmCTestStartCommand } if(!cmSystemTools::FileIsDirectory(sourceDir)) { - cmOStringStream e; + std::ostringstream e; e << "given source path\n" << " " << sourceDir << "\n" << "which is not an existing directory. " diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 07a994d..cc3514f 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -27,7 +27,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() = this->Makefile->GetDefinition("CTEST_TRIGGER_SITE"); bool ctestDropSiteCDash = this->Makefile->IsOn("CTEST_DROP_SITE_CDASH"); - + const char* ctestProjectName + = this->Makefile->GetDefinition("CTEST_PROJECT_NAME"); if ( !ctestDropMethod ) { ctestDropMethod = "http"; @@ -43,7 +44,7 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() // error: CDash requires CTEST_DROP_LOCATION definition // in CTestConfig.cmake } - + this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName); this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod); this->CTest->SetCTestConfiguration("DropSite", ctestDropSite); this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation); @@ -74,13 +75,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() std::vector<std::string> notesFiles; cmCTest::VectorOfStrings newNotesFiles; cmSystemTools::ExpandListArgument(notesFilesVariable,notesFiles); - std::vector<std::string>::iterator it; - for ( it = notesFiles.begin(); - it != notesFiles.end(); - ++ it ) - { - newNotesFiles.push_back(*it); - } + newNotesFiles.insert(newNotesFiles.end(), + notesFiles.begin(), notesFiles.end()); this->CTest->GenerateNotesFile(newNotesFiles); } @@ -91,13 +87,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() std::vector<std::string> extraFiles; cmCTest::VectorOfStrings newExtraFiles; cmSystemTools::ExpandListArgument(extraFilesVariable,extraFiles); - std::vector<std::string>::iterator it; - for ( it = extraFiles.begin(); - it != extraFiles.end(); - ++ it ) - { - newExtraFiles.push_back(*it); - } + newExtraFiles.insert(newExtraFiles.end(), + extraFiles.begin(), extraFiles.end()); if ( !this->CTest->SubmitExtraFiles(newExtraFiles)) { this->SetError("problem submitting extra files."); @@ -154,44 +145,75 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() static_cast<cmCTestSubmitHandler*>(handler)->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF"); + if (this->CDashUpload) + { + static_cast<cmCTestSubmitHandler*>(handler)-> + SetOption("CDashUploadFile", this->CDashUploadFile.c_str()); + static_cast<cmCTestSubmitHandler*>(handler)-> + SetOption("CDashUploadType", this->CDashUploadType.c_str()); + } return handler; } +//---------------------------------------------------------------------------- +bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args, + cmExecutionStatus& status) +{ + this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD"; + return this->cmCTestHandlerCommand::InitialPass(args, status); +} //---------------------------------------------------------------------------- bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg) { - // Look for arguments specific to this command. - if(arg == "PARTS") + if (this->CDashUpload) { - this->ArgumentDoing = ArgumentDoingParts; - this->PartsMentioned = true; - return true; - } + if(arg == "CDASH_UPLOAD") + { + this->ArgumentDoing = ArgumentDoingCDashUpload; + return true; + } - if(arg == "FILES") - { - this->ArgumentDoing = ArgumentDoingFiles; - this->FilesMentioned = true; - return true; + if(arg == "CDASH_UPLOAD_TYPE") + { + this->ArgumentDoing = ArgumentDoingCDashUploadType; + return true; + } } - - if(arg == "RETRY_COUNT") + else { - this->ArgumentDoing = ArgumentDoingRetryCount; - return true; - } + // Look for arguments specific to this command. + if(arg == "PARTS") + { + this->ArgumentDoing = ArgumentDoingParts; + this->PartsMentioned = true; + return true; + } - if(arg == "RETRY_DELAY") - { - this->ArgumentDoing = ArgumentDoingRetryDelay; - return true; - } + if(arg == "FILES") + { + this->ArgumentDoing = ArgumentDoingFiles; + this->FilesMentioned = true; + return true; + } - if(arg == "INTERNAL_TEST_CHECKSUM") - { - this->InternalTest = true; - return true; + if(arg == "RETRY_COUNT") + { + this->ArgumentDoing = ArgumentDoingRetryCount; + return true; + } + + if(arg == "RETRY_DELAY") + { + this->ArgumentDoing = ArgumentDoingRetryDelay; + return true; + } + + if(arg == "INTERNAL_TEST_CHECKSUM") + { + this->InternalTest = true; + return true; + } } // Look for other arguments. @@ -212,7 +234,7 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) } else { - cmOStringStream e; + std::ostringstream e; e << "Part name \"" << arg << "\" is invalid."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); this->ArgumentDoing = ArgumentDoingError; @@ -229,7 +251,7 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) } else { - cmOStringStream e; + std::ostringstream e; e << "File \"" << filename << "\" does not exist. Cannot submit " << "a non-existent file."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -250,6 +272,20 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg) return true; } + if(this->ArgumentDoing == ArgumentDoingCDashUpload) + { + this->ArgumentDoing = ArgumentDoingNone; + this->CDashUploadFile = arg; + return true; + } + + if(this->ArgumentDoing == ArgumentDoingCDashUploadType) + { + this->ArgumentDoing = ArgumentDoingNone; + this->CDashUploadType = arg; + return true; + } + // Look for other arguments. return this->Superclass::CheckArgumentValue(arg); } diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 3673fbd..19e8eaf 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -32,6 +32,7 @@ public: this->InternalTest = false; this->RetryCount = ""; this->RetryDelay = ""; + this->CDashUpload = false; } /** @@ -45,6 +46,9 @@ public: return ni; } + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + /** * The name of the command as specified in CMakeList.txt. */ @@ -64,6 +68,8 @@ protected: ArgumentDoingFiles, ArgumentDoingRetryDelay, ArgumentDoingRetryCount, + ArgumentDoingCDashUpload, + ArgumentDoingCDashUploadType, ArgumentDoingLast2 }; @@ -74,6 +80,9 @@ protected: cmCTest::SetOfStrings Files; std::string RetryCount; std::string RetryDelay; + bool CDashUpload; + std::string CDashUploadFile; + std::string CDashUploadType; }; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 5f065c2..11e3343 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -10,7 +10,8 @@ See the License for more information. ============================================================================*/ #include "cmCTestSubmitHandler.h" - +#include "cmCTestScriptHandler.h" +#include "cmake.h" #include "cmSystemTools.h" #include "cmVersion.h" #include "cmGeneratedFileStream.h" @@ -23,8 +24,10 @@ // For XML-RPC submission #include "cm_xmlrpc.h" +#include <cm_jsoncpp_reader.h> // For curl submission #include "cm_curl.h" +#include "cmCTestCurl.h" #include <sys/stat.h> @@ -61,7 +64,7 @@ private: std::string GetCurrentValue() { std::string val; - if(this->CurrentValue.size()) + if(!this->CurrentValue.empty()) { val.assign(&this->CurrentValue[0], this->CurrentValue.size()); } @@ -234,7 +237,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, ::curl_global_cleanup(); return false; } - unsigned long filelen = cmSystemTools::FileLength(local_file.c_str()); + unsigned long filelen = cmSystemTools::FileLength(local_file); ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); *this->LogFile << "\tUpload file: " << local_file << " to " @@ -273,13 +276,13 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, // Now run off and do what you've been told! res = ::curl_easy_perform(curl); - if ( chunk.size() > 0 ) + if (!chunk.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" << std::endl); } - if ( chunkDebug.size() > 0 ) + if (!chunkDebug.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]" @@ -301,7 +304,7 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, << error_buffer << std::endl << " Curl output was: "; // avoid dereference of empty vector - if(chunk.size()) + if(!chunk.empty()) { *this->LogFile << cmCTestLogWrite(&*chunk.begin(), chunk.size()); cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: [" @@ -390,7 +393,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, break; default: curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); - if (this->HTTPProxyAuth.size() > 0) + if (!this->HTTPProxyAuth.empty()) { curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, this->HTTPProxyAuth.c_str()); @@ -475,7 +478,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, ::curl_global_cleanup(); return false; } - unsigned long filelen = cmSystemTools::FileLength(local_file.c_str()); + unsigned long filelen = cmSystemTools::FileLength(local_file); ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: " @@ -523,14 +526,14 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, chunk.assign(mock_output.begin(), mock_output.end()); } - if ( chunk.size() > 0 ) + if (!chunk.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" << std::endl); this->ParseResponse(chunk); } - if ( chunkDebug.size() > 0 ) + if (!chunkDebug.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]" @@ -576,7 +579,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, res = ::curl_easy_perform(curl); - if ( chunk.size() > 0 ) + if (!chunk.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" @@ -605,7 +608,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, << " Error message was: " << error_buffer << std::endl; // avoid deref of begin for zero size array - if(chunk.size()) + if(!chunk.empty()) { *this->LogFile << " Curl output was: " << cmCTestLogWrite(&*chunk.begin(), chunk.size()) @@ -697,7 +700,7 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( break; default: curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); - if (this->HTTPProxyAuth.size() > 0) + if (!this->HTTPProxyAuth.empty()) { curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, this->HTTPProxyAuth.c_str()); @@ -766,7 +769,7 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( << std::endl << " Error message was: " << error_buffer << std::endl; - if(chunk.size()) + if(!chunk.empty()) { *this->LogFile << " Curl output was: " @@ -780,13 +783,13 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( return false; } - if ( chunk.size() > 0 ) + if (!chunk.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" << std::endl); } - if ( chunkDebug.size() > 0 ) + if (!chunkDebug.empty()) { cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) @@ -812,8 +815,8 @@ bool cmCTestSubmitHandler::SubmitUsingSCP( const std::string& remoteprefix, const std::string& url) { - if ( !scp_command.size() || !localprefix.size() || - !files.size() || !remoteprefix.size() || !url.size() ) + if ( scp_command.empty() || localprefix.empty() || + files.empty() || remoteprefix.empty() || url.empty() ) { return 0; } @@ -912,8 +915,8 @@ bool cmCTestSubmitHandler::SubmitUsingCP( const std::string& remoteprefix, const std::string& destination) { - if ( !localprefix.size() || - !files.size() || !remoteprefix.size() || !destination.size() ) + if ( localprefix.empty() || + files.empty() || remoteprefix.empty() || destination.empty() ) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Missing arguments for submit via cp:\n" @@ -1055,19 +1058,181 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(std::string const&, } #endif +void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod, + std::string& url) +{ + dropMethod = this->CTest->GetCTestConfiguration("DropMethod"); + url = dropMethod; + url += "://"; + if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) + { + url += this->CTest->GetCTestConfiguration("DropSiteUser"); + cmCTestLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetCTestConfiguration("DropSiteUser").c_str()); + if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 ) + { + url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); + cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); + } + url += "@"; + } + url += this->CTest->GetCTestConfiguration("DropSite") + + this->CTest->GetCTestConfiguration("DropLocation"); +} + + +int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, + std::string const& typeString) +{ + if (file.empty()) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Upload file not specified\n"); + return -1; + } + if (!cmSystemTools::FileExists(file)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Upload file not found: '" << file << "'\n"); + return -1; + } + cmCTestCurl curl(this->CTest); + std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions")); + std::vector<std::string> args; + cmSystemTools::ExpandListArgument(curlopt, args); + curl.SetCurlOptions(args); + curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT); + std::string dropMethod; + std::string url; + this->ConstructCDashURL(dropMethod, url); + std::string::size_type pos = url.find("submit.php?"); + url = url.substr(0, pos+10); + if ( ! (dropMethod == "http" || dropMethod == "https" ) ) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Only http and https are supported for CDASH_UPLOAD\n"); + return -1; + } + char md5sum[33]; + md5sum[32] = 0; + cmSystemTools::ComputeFileMD5(file, md5sum); + // 1. request the buildid and check to see if the file + // has already been uploaded + // TODO I added support for subproject. You would need to add + // a "&subproject=subprojectname" to the first POST. + cmCTestScriptHandler* ch = + static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); + cmake* cm = ch->GetCMake(); + const char* subproject = cm->GetProperty("SubProject", cmProperty::GLOBAL); + // TODO: Encode values for a URL instead of trusting caller. + std::ostringstream str; + str << "project=" + << this->CTest->GetCTestConfiguration("ProjectName") << "&"; + if(subproject) + { + str << "subproject=" << subproject << "&"; + } + str << "stamp=" << this->CTest->GetCurrentTag() << "-" + << this->CTest->GetTestModelString() << "&" + << "model=" << this->CTest->GetTestModelString() << "&" + << "build=" << this->CTest->GetCTestConfiguration("BuildName") << "&" + << "site=" << this->CTest->GetCTestConfiguration("Site") << "&" + << "track=" << this->CTest->GetTestModelString() << "&" + << "starttime=" << (int)cmSystemTools::GetTime() << "&" + << "endtime=" << (int)cmSystemTools::GetTime() << "&" + << "datafilesmd5[0]=" << md5sum << "&" + << "type=" << typeString; + std::string fields = str.str(); + cmCTestLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:" + << url << "\nfile: " << file << "\n"); + std::string response; + if(!curl.HttpRequest(url, fields, response)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Error in HttpRequest\n" << response); + return -1; + } + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Request upload response: [" << response << "]\n"); + Json::Value json; + Json::Reader reader; + if(!reader.parse(response, json)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error parsing json string [" << response << "]\n" + << reader.getFormattedErrorMessages() << "\n"); + return -1; + } + if(json["status"].asInt() != 0) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Bad status returned from CDash: " + << json["status"].asInt()); + return -1; + } + if(json["datafilesmd5"].isArray()) + { + int datares = json["datafilesmd5"][0].asInt(); + if(datares == 1) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "File already exists on CDash, skip upload " + << file << "\n"); + return 0; + } + } + else + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "bad datafilesmd5 value in response " + << response << "\n"); + return -1; + } + + std::string upload_as = cmSystemTools::GetFilenameName(file); + std::ostringstream fstr; + fstr << "type=" << typeString << "&" + << "md5=" << md5sum << "&" + << "filename=" << upload_as << "&" + << "buildid=" << json["buildid"].asString(); + if(!curl.UploadFile(file, url, fstr.str(), response)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error uploading to CDash. " + << file << " " << url << " " << fstr.str()); + return -1; + } + if(!reader.parse(response, json)) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "error parsing json string [" << response << "]\n" + << reader.getFormattedErrorMessages() << "\n"); + return -1; + } + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Upload file response: [" << response << "]\n"); + return 0; +} + //---------------------------------------------------------------------------- int cmCTestSubmitHandler::ProcessHandler() { + const char* cdashUploadFile = this->GetOption("CDashUploadFile"); + const char* cdashUploadType = this->GetOption("CDashUploadType"); + if(cdashUploadFile && cdashUploadType) + { + return this->HandleCDashUploadFile(cdashUploadFile, cdashUploadType); + } std::string iscdash = this->CTest->GetCTestConfiguration("IsCDash"); // cdash does not need to trigger so just return true - if(iscdash.size()) + if(!iscdash.empty()) { this->CDash = true; } const std::string &buildDirectory = this->CTest->GetCTestConfiguration("BuildDirectory"); - if ( buildDirectory.size() == 0 ) + if (buildDirectory.empty()) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot find BuildDirectory key in the DartConfiguration.tcl" @@ -1140,12 +1305,12 @@ int cmCTestSubmitHandler::ProcessHandler() } } - if ( this->HTTPProxy.size() > 0 ) + if (!this->HTTPProxy.empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: " << this->HTTPProxy << std::endl); } - if ( this->FTPProxy.size() > 0 ) + if (!this->FTPProxy.empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: " << this->FTPProxy << std::endl); @@ -1160,11 +1325,7 @@ int cmCTestSubmitHandler::ProcessHandler() { // Submit the explicitly selected files: // - cmCTest::SetOfStrings::const_iterator it; - for (it = this->Files.begin(); it != this->Files.end(); ++it) - { - files.insert(*it); - } + files.insert(this->Files.begin(), this->Files.end()); } // Add to the list of files to submit from any selected, existing parts: @@ -1219,11 +1380,7 @@ int cmCTestSubmitHandler::ProcessHandler() // Submit files from this part. std::vector<std::string> const& pfiles = this->CTest->GetSubmitFiles(p); - for(std::vector<std::string>::const_iterator pi = pfiles.begin(); - pi != pfiles.end(); ++pi) - { - files.insert(*pi); - } + files.insert(pfiles.begin(), pfiles.end()); } if ( ofs ) @@ -1264,12 +1421,12 @@ int cmCTestSubmitHandler::ProcessHandler() this->CTest->GetCTestConfiguration("DropSite") + cmCTest::MakeURLSafe( this->CTest->GetCTestConfiguration("DropLocation")); - if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) + if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, this->CTest->GetCTestConfiguration( "DropSiteUser").c_str()); - if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 ) + if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); } @@ -1318,12 +1475,12 @@ int cmCTestSubmitHandler::ProcessHandler() cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP submit method" << std::endl << " Drop site:" << url); - if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) + if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { url += this->CTest->GetCTestConfiguration("DropSiteUser"); cmCTestLog(this->CTest, HANDLER_OUTPUT, this->CTest->GetCTestConfiguration("DropSiteUser").c_str()); - if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 ) + if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); @@ -1408,7 +1565,7 @@ int cmCTestSubmitHandler::ProcessHandler() { std::string url; std::string oldWorkingDirectory; - if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) + if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { url += this->CTest->GetCTestConfiguration("DropSiteUser") + "@"; } @@ -1503,9 +1660,5 @@ void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts) //---------------------------------------------------------------------------- void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files) { - cmCTest::SetOfStrings::const_iterator it; - for (it = files.begin(); it != files.end(); ++it) - { - this->Files.insert(*it); - } + this->Files.insert(files.begin(), files.end()); } diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index accabd1..f9cd894 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -41,6 +41,11 @@ public: /** Specify a set of files to submit. */ void SelectFiles(cmCTest::SetOfStrings const& files); + // handle the cdash file upload protocol + int HandleCDashUploadFile(std::string const& file, std::string const& type); + + void ConstructCDashURL(std::string& dropMethod, std::string& url); + private: void SetLogFile(std::ostream* ost) { this->LogFile = ost; } diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 231f035..d209094 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -53,7 +53,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() if ( this->Values[ctt_START] || this->Values[ctt_END] || this->Values[ctt_STRIDE] ) { - cmOStringStream testsToRunString; + std::ostringstream testsToRunString; if ( this->Values[ctt_START] ) { testsToRunString << this->Values[ctt_START]; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 435fb32..925e3c9 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -564,7 +564,7 @@ int cmCTestTestHandler::ProcessHandler() } else { - if (this->HandlerVerbose && passed.size() && + if (this->HandlerVerbose && !passed.empty() && (this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag)) { cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl @@ -578,7 +578,7 @@ int cmCTestTestHandler::ProcessHandler() } float percent = float(passed.size()) * 100.0f / float(total); - if ( failed.size() > 0 && percent > 99) + if (!failed.empty() && percent > 99) { percent = 99; } @@ -596,7 +596,7 @@ int cmCTestTestHandler::ProcessHandler() cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nTotal Test time (real) = " << realBuf << "\n" ); - if (failed.size()) + if (!failed.empty()) { cmGeneratedFileStream ofs; cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl @@ -668,7 +668,7 @@ void cmCTestTestHandler::PrintLabelSummary() for(; it != this->TestList.end(); ++it) { cmCTestTestProperties& p = *it; - if(p.Labels.size() != 0) + if(!p.Labels.empty()) { for(std::vector<std::string>::iterator l = p.Labels.begin(); l != p.Labels.end(); ++l) @@ -688,7 +688,7 @@ void cmCTestTestHandler::PrintLabelSummary() { cmCTestTestResult &result = *ri; cmCTestTestProperties& p = *result.Properties; - if(p.Labels.size() != 0) + if(!p.Labels.empty()) { for(std::vector<std::string>::iterator l = p.Labels.begin(); l != p.Labels.end(); ++l) @@ -698,7 +698,7 @@ void cmCTestTestHandler::PrintLabelSummary() } } // now print times - if(labels.size()) + if(!labels.empty()) { cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:"); } @@ -717,7 +717,7 @@ void cmCTestTestHandler::PrintLabelSummary() << buf << "\n"; } } - if(labels.size()) + if(!labels.empty()) { if(this->LogFile) { @@ -738,7 +738,7 @@ void cmCTestTestHandler::CheckLabelFilterInclude(cmCTestTestProperties& it) } // if there are no labels and we are filtering by labels // then exclude the test as it does not have the label - if(it.Labels.size() == 0 ) + if(it.Labels.empty()) { it.IsInBasedOnREOptions = false; return; @@ -772,7 +772,7 @@ void cmCTestTestHandler::CheckLabelFilterExclude(cmCTestTestProperties& it) } // if there are no labels and we are excluding by labels // then do nothing as a no label can not be a match - if(it.Labels.size() == 0 ) + if(it.Labels.empty()) { return; } @@ -850,7 +850,7 @@ void cmCTestTestHandler::ComputeTestList() if (this->UseUnion) { // if it is not in the list and not in the regexp then skip - if ((this->TestsToRun.size() && + if ((!this->TestsToRun.empty() && std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == this->TestsToRun.end()) && !it->IsInBasedOnREOptions) { @@ -860,7 +860,7 @@ void cmCTestTestHandler::ComputeTestList() else { // is this test in the list of tests to run? If not then skip it - if ((this->TestsToRun.size() && + if ((!this->TestsToRun.empty() && std::find(this->TestsToRun.begin(), this->TestsToRun.end(), inREcnt) == this->TestsToRun.end()) || !it->IsInBasedOnREOptions) @@ -891,7 +891,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed() cnt ++; // if this test is not in our list of tests to run, then skip it. - if ((this->TestsToRun.size() && + if ((!this->TestsToRun.empty() && std::find(this->TestsToRun.begin(), this->TestsToRun.end(), cnt) == this->TestsToRun.end())) { @@ -1094,7 +1094,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed, p.Timeout = this->CTest->GetGlobalTimeout(); } - if(p.Depends.size()) + if(!p.Depends.empty()) { for(std::vector<std::string>::iterator i = p.Depends.begin(); i != p.Depends.end(); ++i) @@ -1192,7 +1192,7 @@ void cmCTestTestHandler::GenerateDartOutput(std::ostream& os) << "name=\"Execution Time\"><Value>" << result->ExecutionTime << "</Value></NamedMeasurement>\n"; - if(result->Reason.size()) + if(!result->Reason.empty()) { const char* reasonType = "Pass Reason"; if(result->Status != cmCTestTestHandler::COMPLETED && @@ -1317,7 +1317,7 @@ void cmCTestTestHandler::AttachFiles(std::ostream& os, result->Properties->AttachedFiles.begin(); file != result->Properties->AttachedFiles.end(); ++file) { - std::string base64 = this->CTest->Base64GzipEncodeFile(*file); + const std::string &base64 = this->CTest->Base64GzipEncodeFile(*file); std::string fname = cmSystemTools::GetFilenameName(*file); os << "\t\t<NamedMeasurement name=\"Attached File\" encoding=\"base64\" " "compression=\"tar/gzip\" filename=\"" << fname << "\" type=\"file\">" @@ -1376,7 +1376,7 @@ void cmCTestTestHandler { std::string tempPath; - if (filepath.size() && + if (!filepath.empty() && filepath[filepath.size()-1] != '/') { filepath += "/"; @@ -1385,7 +1385,7 @@ void cmCTestTestHandler attempted.push_back(tempPath); attemptedConfigs.push_back(""); - if(ctest->GetConfigType().size()) + if(!ctest->GetConfigType().empty()) { tempPath = filepath; tempPath += ctest->GetConfigType(); @@ -1463,7 +1463,7 @@ std::string cmCTestTestHandler // even if a fullpath was specified also try it relative to the current // directory - if (filepath.size() && filepath[0] == '/') + if (!filepath.empty() && filepath[0] == '/') { std::string localfilepath = filepath.substr(1,filepath.size()-1); cmCTestTestHandler::AddConfigurations(ctest, attempted, @@ -1474,7 +1474,7 @@ std::string cmCTestTestHandler // if extraPaths are provided and we were not passed a full path, try them, // try any extra paths - if (filepath.size() == 0) + if (filepath.empty()) { for (unsigned int i = 0; i < extraPaths.size(); ++i) { @@ -1494,7 +1494,7 @@ std::string cmCTestTestHandler // now look in the paths we specified above for(unsigned int ai=0; - ai < attempted.size() && fullPath.size() == 0; ++ai) + ai < attempted.size() && fullPath.empty(); ++ai) { // first check without exe extension if(cmSystemTools::FileExists(attempted[ai].c_str()) @@ -1524,7 +1524,7 @@ std::string cmCTestTestHandler // if everything else failed, check the users path, but only if a full path // wasn't specified - if (fullPath.size() == 0 && filepath.size() == 0) + if (fullPath.empty() && filepath.empty()) { std::string path = cmSystemTools::FindProgram(filename.c_str()); if (path != "") @@ -1533,7 +1533,7 @@ std::string cmCTestTestHandler return path; } } - if(fullPath.size() == 0) + if(fullPath.empty()) { cmCTestLog(ctest, HANDLER_OUTPUT, "Could not find executable " << testCommand << "\n" @@ -1865,7 +1865,7 @@ std::string cmCTestTestHandler::GenerateRegressionImages( SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX "*>([^<]*)</DartMeasurementFile>"); - cmOStringStream ostr; + std::ostringstream ostr; bool done = false; std::string cxml = xml; while ( ! done ) @@ -1939,7 +1939,7 @@ std::string cmCTestTestHandler::GenerateRegressionImages( cmCTest::CleanString(measurementfile.match(5)); if ( cmSystemTools::FileExists(filename.c_str()) ) { - long len = cmSystemTools::FileLength(filename.c_str()); + long len = cmSystemTools::FileLength(filename); if ( len == 0 ) { std::string k1 = measurementfile.match(1); @@ -1976,9 +1976,8 @@ std::string cmCTestTestHandler::GenerateRegressionImages( = new unsigned char [ static_cast<int>( static_cast<double>(len) * 1.5 + 5.0) ]; - unsigned long rlen + size_t rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); - unsigned long cc; ostr << "\t\t\t<NamedMeasurement" @@ -1988,7 +1987,7 @@ std::string cmCTestTestHandler::GenerateRegressionImages( << measurementfile.match(4) << "\"" << " encoding=\"base64\"" << ">" << std::endl << "\t\t\t\t<Value>"; - for ( cc = 0; cc < rlen; cc ++ ) + for (size_t cc = 0; cc < rlen; cc ++ ) { ostr << encoded_buffer[cc]; if ( cc % 60 == 0 && cc ) @@ -2099,7 +2098,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length) output = output.substr(0, current - begin); // Append truncation message. - cmOStringStream msg; + std::ostringstream msg; msg << "...\n" "The rest of the test output was removed since it exceeds the threshold " "of " << length << " bytes.\n"; @@ -2153,36 +2152,18 @@ bool cmCTestTestHandler::SetTestsProperties( } if ( key == "ATTACHED_FILES" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - - for(std::vector<std::string>::iterator f = lval.begin(); - f != lval.end(); ++f) - { - rtit->AttachedFiles.push_back(*f); - } + cmSystemTools::ExpandListArgument(val, rtit->AttachedFiles); } if ( key == "ATTACHED_FILES_ON_FAIL" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - - for(std::vector<std::string>::iterator f = lval.begin(); - f != lval.end(); ++f) - { - rtit->AttachOnFail.push_back(*f); - } + cmSystemTools::ExpandListArgument(val, rtit->AttachOnFail); } if ( key == "RESOURCE_LOCK" ) { std::vector<std::string> lval; cmSystemTools::ExpandListArgument(val, lval); - for(std::vector<std::string>::iterator f = lval.begin(); - f != lval.end(); ++f) - { - rtit->LockedResources.insert(*f); - } + rtit->LockedResources.insert(lval.begin(), lval.end()); } if ( key == "TIMEOUT" ) { @@ -2195,14 +2176,7 @@ bool cmCTestTestHandler::SetTestsProperties( } if ( key == "REQUIRED_FILES" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - - for(std::vector<std::string>::iterator f = lval.begin(); - f != lval.end(); ++f) - { - rtit->RequiredFiles.push_back(*f); - } + cmSystemTools::ExpandListArgument(val, rtit->RequiredFiles); } if ( key == "RUN_SERIAL" ) { @@ -2239,33 +2213,15 @@ bool cmCTestTestHandler::SetTestsProperties( } if ( key == "DEPENDS" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - std::vector<std::string>::iterator crit; - for ( crit = lval.begin(); crit != lval.end(); ++ crit ) - { - rtit->Depends.push_back(*crit); - } + cmSystemTools::ExpandListArgument(val, rtit->Depends); } if ( key == "ENVIRONMENT" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - std::vector<std::string>::iterator crit; - for ( crit = lval.begin(); crit != lval.end(); ++ crit ) - { - rtit->Environment.push_back(*crit); - } + cmSystemTools::ExpandListArgument(val, rtit->Environment); } if ( key == "LABELS" ) { - std::vector<std::string> lval; - cmSystemTools::ExpandListArgument(val, lval); - std::vector<std::string>::iterator crit; - for ( crit = lval.begin(); crit != lval.end(); ++ crit ) - { - rtit->Labels.push_back(*crit); - } + cmSystemTools::ExpandListArgument(val, rtit->Labels); } if ( key == "MEASUREMENT" ) { diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 68f5fe1..4c37c8b 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -94,11 +94,11 @@ cmCTestUpdateHandlerLocale::~cmCTestUpdateHandlerLocale() { // restore the value of LC_MESSAGES after running the version control // commands - if(saveLCMessages.size()) + if(!saveLCMessages.empty()) { std::string put = "LC_MESSAGES="; put += saveLCMessages; - cmSystemTools::PutEnv(put.c_str()); + cmSystemTools::PutEnv(put); } else { @@ -413,7 +413,7 @@ bool cmCTestUpdateHandler::SelectVCS() } if (this->UpdateCommand.empty()) { - cmOStringStream e; + std::ostringstream e; e << "Cannot find UpdateCommand "; if (key) { diff --git a/Source/CTest/cmCTestUpdateHandler.h b/Source/CTest/cmCTestUpdateHandler.h index 954c024..d2423c0 100644 --- a/Source/CTest/cmCTestUpdateHandler.h +++ b/Source/CTest/cmCTestUpdateHandler.h @@ -17,10 +17,6 @@ #include "cmCTestGenericHandler.h" #include "cmListFileCache.h" -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - /** \class cmCTestUpdateHandler * \brief A class that handles ctest -S invocations * @@ -70,8 +66,4 @@ private: bool SelectVCS(); }; -#if defined(__sgi) && !defined(__GNUC__) -# pragma reset woff 1375 /* base class destructor not virtual */ -#endif - #endif diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx index f7de294..5613751 100644 --- a/Source/CTest/cmCTestUploadCommand.cxx +++ b/Source/CTest/cmCTestUploadCommand.cxx @@ -55,7 +55,7 @@ bool cmCTestUploadCommand::CheckArgumentValue(std::string const& arg) } else { - cmOStringStream e; + std::ostringstream e; e << "File \"" << filename << "\" does not exist. Cannot submit " << "a non-existent file."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx index 15f796f..6e93e95 100644 --- a/Source/CTest/cmCTestVC.cxx +++ b/Source/CTest/cmCTestVC.cxx @@ -105,7 +105,7 @@ bool cmCTestVC::RunChild(char const* const* cmd, OutputParser* out, //---------------------------------------------------------------------------- std::string cmCTestVC::ComputeCommandLine(char const* const* cmd) { - cmOStringStream line; + std::ostringstream line; const char* sep = ""; for(const char* const* arg = cmd; *arg; ++arg) { diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 5f4a708..85d066b 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -78,10 +78,9 @@ public: * information in the local vector */ FileLinesType& CoverageVector = - this->Coverage.TotalCoverage[filename.c_str()]; + this->Coverage.TotalCoverage[filename]; CoverageVector = localCoverageVector; localCoverageVector.clear(); - foundFile=false; } foundFile= true; inSource = false; @@ -98,7 +97,7 @@ public: * FoundFile and foundSource ensure that * only the value of the line coverage is captured */ - std::string result = getValue(line,1).c_str(); + std::string result = getValue(line,1); result = result.substr(2,result.npos); if(result == "\"\"") { @@ -120,9 +119,8 @@ public: // On exit, capture end of last file covered. FileLinesType& CoverageVector = - this->Coverage.TotalCoverage[filename.c_str()]; + this->Coverage.TotalCoverage[filename]; CoverageVector = localCoverageVector; - foundFile=false; localCoverageVector.clear(); return true; } diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index 97454a8..3642308 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -163,7 +163,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file) } // if we do not have a routine yet, then it should be // the first argument in the vector - if(routine.size() == 0) + if(routine.empty()) { routine = separateLine[0]; // Find the full path to the file @@ -191,7 +191,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file) // move to next line. We should have already warned // after the call to FindMumpsFile that we did not find // it, so don't report again to cut down on output - if(filepath.size() == 0) + if(filepath.empty()) { continue; } diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index 0742be1..e19b199 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -12,9 +12,11 @@ public: XMLParser(cmCTest* ctest, cmCTestCoverageHandlerContainer& cont) : CTest(ctest), Coverage(cont) { - this->InSources = false; - this->InSource = false; + this->InSources = false; + this->InSource = false; + this->SkipThisClass = false; this->FilePaths.push_back(this->Coverage.SourceDir); + this->FilePaths.push_back(this->Coverage.BinaryDir); this->CurFileName = ""; } @@ -35,6 +37,10 @@ protected: { this->InSources=false; } + else if(name == "class") + { + this->SkipThisClass = false; + } } virtual void CharacterDataHandler(const char* data, int length) @@ -72,15 +78,33 @@ protected: << atts[tagCount+1]<< std::endl); std::string filename = atts[tagCount+1]; this->CurFileName = ""; + + // Check if this is an absolute path that falls within our + // source or binary directories. for(size_t i=0;i < FilePaths.size();i++) { - finalpath = FilePaths[i] + "/" + filename; - if(cmSystemTools::FileExists(finalpath.c_str())) + if (filename.find(FilePaths[i]) == 0) { - this->CurFileName = finalpath; + this->CurFileName = filename; break; } } + + if (this->CurFileName == "") + { + // Check if this is a path that is relative to our source or + // binary directories. + for(size_t i=0;i < FilePaths.size();i++) + { + finalpath = FilePaths[i] + "/" + filename; + if(cmSystemTools::FileExists(finalpath.c_str())) + { + this->CurFileName = finalpath; + break; + } + } + } + cmsys::ifstream fin(this->CurFileName.c_str()); if(this->CurFileName == "" || !fin ) { @@ -89,10 +113,11 @@ protected: fin.open(this->CurFileName.c_str()); if (!fin) { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Python Coverage: Error opening " << this->CurFileName - << std::endl); - this->Coverage.Error++; + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Skipping system file " << filename << + std::endl); + + this->SkipThisClass = true; break; } } @@ -117,6 +142,10 @@ protected: int curHits = -1; while(true) { + if(this->SkipThisClass) + { + break; + } if(strcmp(atts[tagCount], "hits") == 0) { curHits = atoi(atts[tagCount+1]); @@ -144,6 +173,7 @@ private: bool InSources; bool InSource; + bool SkipThisClass; std::vector<std::string> FilePaths; typedef cmCTestCoverageHandlerContainer::SingleFileCoverageVector FileLinesType; diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index ad71c85..4dfdfac 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -61,7 +61,7 @@ public: continue; } else if((line.find("end;") != line.npos) - && (beginSet.size() > 0)) + && !beginSet.empty()) { beginSet.pop_back(); coverageVector.push_back(-1); @@ -80,7 +80,7 @@ public: } } //Based up what was found, add a line to the coverageVector - if((beginSet.size() > 0) && line != "" && !blockComFlag + if(!beginSet.empty() && line != "" && !blockComFlag && !lineComFlag) { coverageVector.push_back(0); @@ -136,8 +136,6 @@ public: break; } pos = lastoffset+1; - endnamepos = 0; - lastoffset =0; } /* * Glob through the source directory for the @@ -149,7 +147,7 @@ public: std::string glob = Coverage.SourceDir + "*/" + filename; gl.FindFiles(glob); std::vector<std::string> const& files = gl.GetFiles(); - if(files.size() == 0) + if(files.empty()) { /* * If that doesn't find any matching files @@ -242,7 +240,7 @@ bool cmParseDelphiCoverage::LoadCoverageData( } } return true; - }; + } bool cmParseDelphiCoverage::ReadDelphiHTML(const char* file) { @@ -250,4 +248,4 @@ bool cmParseDelphiCoverage::ReadDelphiHTML(const char* file) parser(this->CTest, this->Coverage); parser.ParseFile(file); return true; - }; + } diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx index d77244a..f3f8008 100644 --- a/Source/CTest/cmParseGTMCoverage.cxx +++ b/Source/CTest/cmParseGTMCoverage.cxx @@ -80,7 +80,7 @@ bool cmParseGTMCoverage::ReadMCovFile(const char* file) // no need to search the file if we just did it if(function == lastfunction && lastroutine == routine) { - if(lastpath.size()) + if(!lastpath.empty()) { this->Coverage.TotalCoverage[lastpath][lastoffset + linenumber] += count; diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index f270adb..780debc 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -106,7 +106,7 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser { FileLinesType& curFileLines= this->Coverage.TotalCoverage[this->CurFileName]; - if(curFileLines.size() > 0) + if(!curFileLines.empty()) { curFileLines[nr-1] = ci; } diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 167b992..e1bd02b 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -39,7 +39,7 @@ void cmProcess::SetCommandArguments(std::vector<std::string> const& args) bool cmProcess::StartProcess() { - if(this->Command.size() == 0) + if(this->Command.empty()) { return false; } @@ -56,7 +56,7 @@ bool cmProcess::StartProcess() this->ProcessArgs.push_back(0); // null terminate the list this->Process = cmsysProcess_New(); cmsysProcess_SetCommand(this->Process, &*this->ProcessArgs.begin()); - if(this->WorkingDirectory.size()) + if(!this->WorkingDirectory.empty()) { cmsysProcess_SetWorkingDirectory(this->Process, this->WorkingDirectory.c_str()); diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt index 548f5a5..7d4e88c 100644 --- a/Source/CursesDialog/CMakeLists.txt +++ b/Source/CursesDialog/CMakeLists.txt @@ -26,13 +26,25 @@ set( CURSES_SRCS CursesDialog/ccmake ) -include_directories(${CMake_SOURCE_DIR}/Source/CursesDialog/form - ${CMake_BINARY_DIR}/Source/CursesDialog/form) +if( NOT CMAKE_USE_SYSTEM_FORM ) + include_directories(${CMake_SOURCE_DIR}/Source/CursesDialog/form + ${CMake_BINARY_DIR}/Source/CursesDialog/form) +endif() include_directories(${CURSES_INCLUDE_PATH}) add_executable(ccmake ${CURSES_SRCS} ) target_link_libraries(ccmake CMakeLib) -target_link_libraries(ccmake cmForm) +if(CMAKE_USE_SYSTEM_FORM) + target_link_libraries(ccmake + ${CURSES_FORM_LIBRARY} + ${CURSES_LIBRARY} + ) + if(CURSES_EXTRA_LIBRARY) + target_link_libraries(ccmake ${CURSES_EXTRA_LIBRARY}) + endif() +else() + target_link_libraries(ccmake cmForm) +endif() install(TARGETS ccmake DESTINATION bin) diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h index d2a25ca..8a57c73 100644 --- a/Source/CursesDialog/cmCursesBoolWidget.h +++ b/Source/CursesDialog/cmCursesBoolWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesBoolWidget_h -#define __cmCursesBoolWidget_h +#ifndef cmCursesBoolWidget_h +#define cmCursesBoolWidget_h #include "cmCursesWidget.h" class cmCursesMainForm; @@ -37,4 +37,4 @@ protected: }; -#endif // __cmCursesBoolWidget_h +#endif // cmCursesBoolWidget_h diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h index 98107cc..7cdf13b 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.h +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesCacheEntryComposite_h -#define __cmCursesCacheEntryComposite_h +#ifndef cmCursesCacheEntryComposite_h +#define cmCursesCacheEntryComposite_h #include "../cmCacheManager.h" #include "cmCursesLabelWidget.h" @@ -40,4 +40,4 @@ protected: int EntryWidth; }; -#endif // __cmCursesCacheEntryComposite_h +#endif // cmCursesCacheEntryComposite_h diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h index 9ac1365..2b3b9b5 100644 --- a/Source/CursesDialog/cmCursesDummyWidget.h +++ b/Source/CursesDialog/cmCursesDummyWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesDummyWidget_h -#define __cmCursesDummyWidget_h +#ifndef cmCursesDummyWidget_h +#define cmCursesDummyWidget_h #include "cmCursesWidget.h" @@ -33,4 +33,4 @@ protected: }; -#endif // __cmCursesDummyWidget_h +#endif // cmCursesDummyWidget_h diff --git a/Source/CursesDialog/cmCursesFilePathWidget.h b/Source/CursesDialog/cmCursesFilePathWidget.h index 9d2972e..6c50dd4 100644 --- a/Source/CursesDialog/cmCursesFilePathWidget.h +++ b/Source/CursesDialog/cmCursesFilePathWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesFilePathWidget_h -#define __cmCursesFilePathWidget_h +#ifndef cmCursesFilePathWidget_h +#define cmCursesFilePathWidget_h #include "cmCursesPathWidget.h" @@ -25,4 +25,4 @@ protected: }; -#endif // __cmCursesFilePathWidget_h +#endif // cmCursesFilePathWidget_h diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h index f9317b9..9837f5a 100644 --- a/Source/CursesDialog/cmCursesForm.h +++ b/Source/CursesDialog/cmCursesForm.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesForm_h -#define __cmCursesForm_h +#ifndef cmCursesForm_h +#define cmCursesForm_h #include "../cmStandardIncludes.h" #include "cmCursesStandardIncludes.h" @@ -73,4 +73,4 @@ protected: FORM* Form; }; -#endif // __cmCursesForm_h +#endif // cmCursesForm_h diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h index cc32d11..98170f5 100644 --- a/Source/CursesDialog/cmCursesLabelWidget.h +++ b/Source/CursesDialog/cmCursesLabelWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesLabelWidget_h -#define __cmCursesLabelWidget_h +#ifndef cmCursesLabelWidget_h +#define cmCursesLabelWidget_h #include "cmCursesWidget.h" #include "cmCursesStandardIncludes.h" @@ -35,4 +35,4 @@ protected: void operator=(const cmCursesLabelWidget&); }; -#endif // __cmCursesLabelWidget_h +#endif // cmCursesLabelWidget_h diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h index 1e86974..6e37eea 100644 --- a/Source/CursesDialog/cmCursesLongMessageForm.h +++ b/Source/CursesDialog/cmCursesLongMessageForm.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesLongMessageForm_h -#define __cmCursesLongMessageForm_h +#ifndef cmCursesLongMessageForm_h +#define cmCursesLongMessageForm_h #include "../cmStandardIncludes.h" #include "cmCursesForm.h" @@ -55,4 +55,4 @@ protected: }; -#endif // __cmCursesLongMessageForm_h +#endif // cmCursesLongMessageForm_h diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index 0734927..dcd0b6c 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -47,7 +47,7 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args, cmSystemTools::GetCMakeCursesCommand()); // create the arguments for the cmake object - std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0].c_str()); + std::string whereCMake = cmSystemTools::GetProgramPath(this->Args[0]); whereCMake += "/cmake"; this->Args[0] = whereCMake; this->CMakeInstance->SetArgs(this->Args); @@ -69,11 +69,7 @@ cmCursesMainForm::~cmCursesMainForm() // Clean-up composites if (this->Entries) { - std::vector<cmCursesCacheEntryComposite*>::iterator it; - for (it = this->Entries->begin(); it != this->Entries->end(); ++it) - { - delete *it; - } + cmDeleteAll(*this->Entries); } delete this->Entries; if (this->CMakeInstance) @@ -188,12 +184,7 @@ void cmCursesMainForm::InitializeUI() // Clean old entries if (this->Entries) { - // Have to call delete on each pointer - std::vector<cmCursesCacheEntryComposite*>::iterator it; - for (it = this->Entries->begin(); it != this->Entries->end(); ++it) - { - delete *it; - } + cmDeleteAll(*this->Entries); } delete this->Entries; this->Entries = newEntries; @@ -902,7 +893,7 @@ void cmCursesMainForm::HandleInput() if ( key == 10 || key == KEY_ENTER ) { this->SearchMode = false; - if ( this->SearchString.size() > 0 ) + if (!this->SearchString.empty()) { this->JumpToCacheEntry(this->SearchString.c_str()); this->OldSearchString = this->SearchString; @@ -927,7 +918,7 @@ void cmCursesMainForm::HandleInput() } else if ( key == ctrl('h') || key == KEY_BACKSPACE || key == KEY_DC ) { - if ( this->SearchString.size() > 0 ) + if (!this->SearchString.empty()) { this->SearchString.resize(this->SearchString.size()-1); } @@ -1076,7 +1067,7 @@ void cmCursesMainForm::HandleInput() } else if ( key == 'n' ) { - if ( this->OldSearchString.size() > 0 ) + if (!this->OldSearchString.empty()) { this->JumpToCacheEntry(this->OldSearchString.c_str()); } @@ -1210,7 +1201,7 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr) int findex = start_index; for(;;) { - if ( str.size() > 0 ) + if (!str.empty()) { cmCursesWidget* lbl = 0; if ( findex >= 0 ) diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h index fba9bc5..6455252 100644 --- a/Source/CursesDialog/cmCursesMainForm.h +++ b/Source/CursesDialog/cmCursesMainForm.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesMainForm_h -#define __cmCursesMainForm_h +#ifndef cmCursesMainForm_h +#define cmCursesMainForm_h #include "../cmStandardIncludes.h" #include "cmCursesForm.h" @@ -161,4 +161,4 @@ protected: bool SearchMode; }; -#endif // __cmCursesMainForm_h +#endif // cmCursesMainForm_h diff --git a/Source/CursesDialog/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h index 5cee489..324014e 100644 --- a/Source/CursesDialog/cmCursesOptionsWidget.h +++ b/Source/CursesDialog/cmCursesOptionsWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesOptionsWidget_h -#define __cmCursesOptionsWidget_h +#ifndef cmCursesOptionsWidget_h +#define cmCursesOptionsWidget_h #include "cmCursesWidget.h" class cmCursesMainForm; @@ -36,4 +36,4 @@ protected: std::vector<std::string>::size_type CurrentOption; }; -#endif // __cmCursesOptionsWidget_h +#endif // cmCursesOptionsWidget_h diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h index 45c22a3..18d298a 100644 --- a/Source/CursesDialog/cmCursesPathWidget.h +++ b/Source/CursesDialog/cmCursesPathWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesPathWidget_h -#define __cmCursesPathWidget_h +#ifndef cmCursesPathWidget_h +#define cmCursesPathWidget_h #include "cmCursesStringWidget.h" @@ -37,4 +37,4 @@ protected: std::string::size_type CurrentIndex; }; -#endif // __cmCursesPathWidget_h +#endif // cmCursesPathWidget_h diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h index b157a28..6047ec5 100644 --- a/Source/CursesDialog/cmCursesStandardIncludes.h +++ b/Source/CursesDialog/cmCursesStandardIncludes.h @@ -15,52 +15,12 @@ #define _MSE_INT_H #endif -#include <cmFormConfigure.h> - #if defined(__hpux) # define _BOOL_DEFINED # include <sys/time.h> -# define _XOPEN_SOURCE_EXTENDED -# include <curses.h> -# include <form.h> -# undef _XOPEN_SOURCE_EXTENDED -#else -/* figure out which curses.h to include */ -# if defined(CURSES_HAVE_NCURSES_H) -# include <ncurses.h> -# elif defined(CURSES_HAVE_NCURSES_NCURSES_H) -# include <ncurses/ncurses.h> -# elif defined(CURSES_HAVE_NCURSES_CURSES_H) -# include <ncurses/curses.h> -# else -# include <curses.h> -# endif - -# include <form.h> -#endif - -// This is a hack to prevent warnings about these functions being -// declared but not referenced. -#if defined(__sgi) && !defined(__GNUC__) -class cmCursesStandardIncludesHack -{ -public: - enum - { - Ref1 = sizeof(cfgetospeed(0)), - Ref2 = sizeof(cfgetispeed(0)), - Ref3 = sizeof(tcgetattr(0, 0)), - Ref4 = sizeof(tcsetattr(0, 0, 0)), - Ref5 = sizeof(cfsetospeed(0,0)), - Ref6 = sizeof(cfsetispeed(0,0)) - }; -}; -#endif - -#ifndef getmaxyx - #define getmaxyx(w,y,x) ((y) = getmaxy(w), (x) = getmaxx(w)) #endif +#include <form.h> // on some machines move erase and clear conflict with stl // so remove them from the namespace diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h index dd8c02a..fc1b2ba 100644 --- a/Source/CursesDialog/cmCursesStringWidget.h +++ b/Source/CursesDialog/cmCursesStringWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesStringWidget_h -#define __cmCursesStringWidget_h +#ifndef cmCursesStringWidget_h +#define cmCursesStringWidget_h #include "cmCursesWidget.h" @@ -73,4 +73,4 @@ protected: bool Done; }; -#endif // __cmCursesStringWidget_h +#endif // cmCursesStringWidget_h diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h index d91a0cb..7d82864 100644 --- a/Source/CursesDialog/cmCursesWidget.h +++ b/Source/CursesDialog/cmCursesWidget.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmCursesWidget_h -#define __cmCursesWidget_h +#ifndef cmCursesWidget_h +#define cmCursesWidget_h #include "../cmCacheManager.h" #include "cmCursesStandardIncludes.h" @@ -84,4 +84,4 @@ protected: int Page; }; -#endif // __cmCursesWidget_h +#endif // cmCursesWidget_h diff --git a/Source/CursesDialog/form/fld_attr.c b/Source/CursesDialog/form/fld_attr.c index 8619588..35ea903 100644 --- a/Source/CursesDialog/form/fld_attr.c +++ b/Source/CursesDialog/form/fld_attr.c @@ -29,13 +29,7 @@ /**************************************************************************** * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 * ****************************************************************************/ -#if defined(__hpux) - #define _XOPEN_SOURCE_EXTENDED -#endif - #include "form.priv.h" -#if defined(__hpux) - #undef _XOPEN_SOURCE_EXTENDED -#endif +#include "form.priv.h" MODULE_ID("$Id$") /*---------------------------------------------------------------------------- diff --git a/Source/CursesDialog/form/form.h b/Source/CursesDialog/form/form.h index 94f05af..1219cb5 100644 --- a/Source/CursesDialog/form/form.h +++ b/Source/CursesDialog/form/form.h @@ -47,7 +47,17 @@ # elif defined(CURSES_HAVE_NCURSES_CURSES_H) # include <ncurses/curses.h> # else +# if defined(__hpux) +# if defined(_XOPEN_SOURCE_EXTENDED) +# define HAVE__XOPEN_SOURCE_EXTENDED +# else +# define _XOPEN_SOURCE_EXTENDED +# endif +# endif # include <curses.h> +# if defined(__hpux) && !defined(HAVE__XOPEN_SOURCE_EXTENDED) +# undef _XOPEN_SOURCE_EXTENDED +# endif # endif #include <eti.h> diff --git a/Source/CursesDialog/form/form.priv.h b/Source/CursesDialog/form/form.priv.h index 3691f2f..8516a6f 100644 --- a/Source/CursesDialog/form/form.priv.h +++ b/Source/CursesDialog/form/form.priv.h @@ -33,12 +33,6 @@ #include "mf_common.h" #include "form.h" -/* get around odd bug on aCC and itanium */ -#if defined(__hpux) && defined(__ia64) -#define getmaxx __getmaxx -#define getmaxy __getmaxy -#endif - /* form status values */ #define _OVLMODE (0x04) /* Form is in overlay mode */ #define _WINDOW_MODIFIED (0x10) /* Current field window has been modified */ diff --git a/Source/CursesDialog/form/frm_driver.c b/Source/CursesDialog/form/frm_driver.c index b9611bf..26f580e 100644 --- a/Source/CursesDialog/form/frm_driver.c +++ b/Source/CursesDialog/form/frm_driver.c @@ -29,13 +29,7 @@ /**************************************************************************** * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 * ****************************************************************************/ -#if defined(__hpux) - #define _XOPEN_SOURCE_EXTENDED -#endif #include "form.priv.h" -#if defined(__hpux) - #undef _XOPEN_SOURCE_EXTENDED -#endif /* AIX seems to define this */ #undef lines @@ -357,12 +351,7 @@ static void Buffer_To_Window(const FIELD * field, WINDOW * win) assert(win && field); -#if defined(__LSB_VERSION__) getmaxyx(win, height, width); -#else - width = getmaxx(win); - height = getmaxy(win); -#endif for(row=0, pBuffer=field->buf; row < height; @@ -394,17 +383,13 @@ static void Window_To_Buffer(WINDOW * win, FIELD * field) int pad; int len = 0; char *p; - int row, height; + int row, height, width; assert(win && field && field->buf ); pad = field->pad; p = field->buf; -#if defined(__LSB_VERSION__) - { int width; getmaxyx(win, height, width); } -#else - height = getmaxy(win); -#endif + getmaxyx(win, height, width); for(row=0; (row < height) && (row < field->drows); row++ ) { diff --git a/Source/CursesDialog/form/frm_post.c b/Source/CursesDialog/form/frm_post.c index 3c63de7..924fe6a 100644 --- a/Source/CursesDialog/form/frm_post.c +++ b/Source/CursesDialog/form/frm_post.c @@ -63,12 +63,7 @@ int post_form(FORM * form) RETURN(E_NOT_CONNECTED); formwin = Get_Form_Window(form); -#if defined(__LSB_VERSION__) getmaxyx(formwin, height, width); -#else - width = getmaxx(formwin); - height = getmaxy(formwin); -#endif if ((form->cols > width) || (form->rows > height)) RETURN(E_NO_ROOM); diff --git a/Source/CursesDialog/form/frm_req_name.c b/Source/CursesDialog/form/frm_req_name.c index b108dab..6fb9183 100644 --- a/Source/CursesDialog/form/frm_req_name.c +++ b/Source/CursesDialog/form/frm_req_name.c @@ -35,13 +35,7 @@ * Routines to handle external names of menu requests * ***************************************************************************/ -#if defined(__hpux) - #define _XOPEN_SOURCE_EXTENDED -#endif #include "form.priv.h" -#if defined(__hpux) - #undef _XOPEN_SOURCE_EXTENDED -#endif MODULE_ID("$Id$") diff --git a/Source/QtDialog/CMake.desktop b/Source/QtDialog/CMake.desktop index 7be495f..842091f 100644 --- a/Source/QtDialog/CMake.desktop +++ b/Source/QtDialog/CMake.desktop @@ -3,7 +3,7 @@ Version=1.0 Name=CMake Comment=Cross-platform buildsystem Exec=cmake-gui %f -Icon=CMakeSetup32 +Icon=CMakeSetup Terminal=false X-MultipleArgs=false Type=Application diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 03c2fb4..b59af94 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -171,11 +171,17 @@ set(CMAKE_INSTALL_DESTINATION_ARGS install(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS}) -if(UNIX) +if(UNIX AND NOT APPLE) + foreach (size IN ITEMS 32 128) + install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/CMakeSetup${size}.png" + DESTINATION "share/icons/hicolor/${size}x${size}/apps" + RENAME "CMakeSetup.png") + endforeach () + # install a desktop file so CMake appears in the application start menu # with an icon install(FILES CMake.desktop DESTINATION share/applications ) - install(FILES CMakeSetup32.png DESTINATION share/pixmaps ) install(FILES cmakecache.xml DESTINATION share/mime/packages ) endif() diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index bd82f0d..d910eb7 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -10,8 +10,8 @@ See the License for more information. ============================================================================*/ -#ifndef __QCMake_h -#define __QCMake_h +#ifndef QCMake_h +#define QCMake_h #ifdef _MSC_VER #pragma warning ( disable : 4127 ) #pragma warning ( disable : 4512 ) @@ -152,5 +152,5 @@ protected: QAtomicInt InterruptFlag; }; -#endif // __QCMake_h +#endif // QCMake_h diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 2d19610..8fb49ca 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -32,9 +32,10 @@ bool cmAddCustomCommandCommand std::string source, target, main_dependency, working; std::string comment_buffer; const char* comment = 0; - std::vector<std::string> depends, outputs, output; + std::vector<std::string> depends, outputs, output, byproducts; bool verbatim = false; bool append = false; + bool uses_terminal = false; std::string implicit_depends_lang; cmCustomCommand::ImplicitDependsList implicit_depends; @@ -56,6 +57,7 @@ bool cmAddCustomCommandCommand doing_main_dependency, doing_output, doing_outputs, + doing_byproducts, doing_comment, doing_working_directory, doing_nothing @@ -102,6 +104,10 @@ bool cmAddCustomCommandCommand { append = true; } + else if(copy == "USES_TERMINAL") + { + uses_terminal = true; + } else if(copy == "TARGET") { doing = doing_target; @@ -122,6 +128,10 @@ bool cmAddCustomCommandCommand { doing = doing_output; } + else if (copy == "BYPRODUCTS") + { + doing = doing_byproducts; + } else if (copy == "WORKING_DIRECTORY") { doing = doing_working_directory; @@ -145,6 +155,7 @@ bool cmAddCustomCommandCommand { case doing_output: case doing_outputs: + case doing_byproducts: if (!cmSystemTools::FileIsFullPath(copy.c_str())) { // This is an output to be generated, so it should be @@ -228,6 +239,9 @@ bool cmAddCustomCommandCommand case doing_outputs: outputs.push_back(filename); break; + case doing_byproducts: + byproducts.push_back(filename); + break; case doing_comment: comment_buffer = copy; comment = comment_buffer.c_str(); @@ -267,7 +281,9 @@ bool cmAddCustomCommandCommand } // Make sure the output names and locations are safe. - if(!this->CheckOutputs(output) || !this->CheckOutputs(outputs)) + if(!this->CheckOutputs(output) || + !this->CheckOutputs(outputs) || + !this->CheckOutputs(byproducts)) { return false; } @@ -289,7 +305,7 @@ bool cmAddCustomCommandCommand } // No command for this output exists. - cmOStringStream e; + std::ostringstream e; e << "given APPEND option with output \"" << output[0] << "\" which is not already a custom command output."; this->SetError(e.str()); @@ -309,19 +325,19 @@ bool cmAddCustomCommandCommand { // Source is empty, use the target. std::vector<std::string> no_depends; - this->Makefile->AddCustomCommandToTarget(target, no_depends, + this->Makefile->AddCustomCommandToTarget(target, byproducts, no_depends, commandLines, cctype, comment, working.c_str(), - escapeOldStyle); + escapeOldStyle, uses_terminal); } else if(target.empty()) { // Target is empty, use the output. - this->Makefile->AddCustomCommandToOutput(output, depends, - main_dependency, + this->Makefile->AddCustomCommandToOutput(output, byproducts, + depends, main_dependency, commandLines, comment, working.c_str(), false, - escapeOldStyle); + escapeOldStyle, uses_terminal); // Add implicit dependency scanning requests if any were given. if(!implicit_depends.empty()) @@ -338,7 +354,7 @@ bool cmAddCustomCommandCommand } if(!okay) { - cmOStringStream e; + std::ostringstream e; e << "could not locate source file with a custom command producing \"" << output[0] << "\" even though this command tried to create it!"; this->SetError(e.str()); @@ -346,10 +362,20 @@ bool cmAddCustomCommandCommand } } } + else if (!byproducts.empty()) + { + this->SetError("BYPRODUCTS may not be specified with SOURCE signatures"); + return false; + } + else if (uses_terminal) + { + this->SetError("USES_TERMINAL may not be used with SOURCE signatures"); + return false; + } else { bool issueMessage = true; - cmOStringStream e; + std::ostringstream e; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0050)) { @@ -410,7 +436,7 @@ cmAddCustomCommandCommand std::string::size_type pos = o->find_first_of("#<>"); if(pos != o->npos) { - cmOStringStream msg; + std::ostringstream msg; msg << "called with OUTPUT containing a \"" << (*o)[pos] << "\". This character is not allowed."; this->SetError(msg.str()); diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 3235502..a0e20c8 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -30,7 +30,7 @@ bool cmAddCustomTargetCommand // Check the target name. if(targetName.find_first_of("/\\") != targetName.npos) { - cmOStringStream e; + std::ostringstream e; e << "called with invalid target name \"" << targetName << "\". Target names may not contain a slash. " << "Use ADD_CUSTOM_COMMAND to generate files."; @@ -45,9 +45,10 @@ bool cmAddCustomTargetCommand cmCustomCommandLines commandLines; // Accumulate dependencies. - std::vector<std::string> depends; + std::vector<std::string> depends, byproducts; std::string working_directory; bool verbatim = false; + bool uses_terminal = false; std::string comment_buffer; const char* comment = 0; std::vector<std::string> sources; @@ -56,10 +57,11 @@ bool cmAddCustomTargetCommand enum tdoing { doing_command, doing_depends, + doing_byproducts, doing_working_directory, doing_comment, doing_source, - doing_verbatim + doing_nothing }; tdoing doing = doing_command; @@ -84,15 +86,24 @@ bool cmAddCustomTargetCommand { doing = doing_depends; } + else if(copy == "BYPRODUCTS") + { + doing = doing_byproducts; + } else if(copy == "WORKING_DIRECTORY") { doing = doing_working_directory; } else if(copy == "VERBATIM") { - doing = doing_verbatim; + doing = doing_nothing; verbatim = true; } + else if(copy == "USES_TERMINAL") + { + doing = doing_nothing; + uses_terminal = true; + } else if (copy == "COMMENT") { doing = doing_comment; @@ -122,6 +133,19 @@ bool cmAddCustomTargetCommand case doing_command: currentLine.push_back(copy); break; + case doing_byproducts: + { + std::string filename; + if (!cmSystemTools::FileIsFullPath(copy.c_str())) + { + filename = this->Makefile->GetCurrentOutputDirectory(); + filename += "/"; + } + filename += copy; + cmSystemTools::ConvertToUnixSlashes(filename); + byproducts.push_back(filename); + } + break; case doing_depends: { std::string dep = copy; @@ -146,7 +170,7 @@ bool cmAddCustomTargetCommand std::string::size_type pos = targetName.find_first_of("#<>"); if(pos != targetName.npos) { - cmOStringStream msg; + std::ostringstream msg; msg << "called with target name containing a \"" << targetName[pos] << "\". This character is not allowed."; this->SetError(msg.str()); @@ -165,7 +189,7 @@ bool cmAddCustomTargetCommand if (!nameOk) { cmake::MessageType messageType = cmake::AUTHOR_WARNING; - cmOStringStream e; + std::ostringstream e; bool issueMessage = false; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) { @@ -221,12 +245,27 @@ bool cmAddCustomTargetCommand cmSystemTools::CollapseFullPath(working_directory, build_dir); } + if (commandLines.empty() && !byproducts.empty()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "BYPRODUCTS may not be specified without any COMMAND"); + return true; + } + if (commandLines.empty() && uses_terminal) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "USES_TERMINAL may not be specified without any COMMAND"); + return true; + } + // Add the utility target to the makefile. bool escapeOldStyle = !verbatim; cmTarget* target = this->Makefile->AddUtilityCommand(targetName, excludeFromAll, - working_directory.c_str(), depends, - commandLines, escapeOldStyle, comment); + working_directory.c_str(), + byproducts, depends, + commandLines, escapeOldStyle, comment, + uses_terminal); // Add additional user-specified source files to the target. target->AddSources(sources); diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index e897d81..b560452 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -26,7 +26,7 @@ bool cmAddDependenciesCommand std::string target_name = args[0]; if(this->Makefile->IsAlias(target_name)) { - cmOStringStream e; + std::ostringstream e; e << "Cannot add target-level dependencies to alias target \"" << target_name << "\".\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -35,7 +35,7 @@ bool cmAddDependenciesCommand { if (target->GetType() == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Cannot add target-level dependencies to INTERFACE library " "target \"" << target_name << "\".\n"; this->SetError(e.str()); @@ -51,7 +51,7 @@ bool cmAddDependenciesCommand } else { - cmOStringStream e; + std::ostringstream e; e << "Cannot add target-level dependencies to non-existent target \"" << target_name << "\".\n" << "The add_dependencies works for top-level logical targets created " diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index c30e764..74dc8eb 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -79,7 +79,7 @@ bool cmAddExecutableCommand if (!nameOk) { cmake::MessageType messageType = cmake::AUTHOR_WARNING; - cmOStringStream e; + std::ostringstream e; bool issueMessage = false; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) { @@ -149,7 +149,7 @@ bool cmAddExecutableCommand } if(args.size() != 3) { - cmOStringStream e; + std::ostringstream e; e << "ALIAS requires exactly one target argument."; this->SetError(e.str()); return false; @@ -158,7 +158,7 @@ bool cmAddExecutableCommand const char *aliasedName = s->c_str(); if(this->Makefile->IsAlias(aliasedName)) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is itself an ALIAS."; this->SetError(e.str()); @@ -168,7 +168,7 @@ bool cmAddExecutableCommand this->Makefile->FindTargetToUse(aliasedName, true); if(!aliasedTarget) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" does not already " "exist."; @@ -178,7 +178,7 @@ bool cmAddExecutableCommand cmTarget::TargetType type = aliasedTarget->GetType(); if(type != cmTarget::EXECUTABLE) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is not an " "executable."; @@ -187,7 +187,7 @@ bool cmAddExecutableCommand } if(aliasedTarget->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << exename << "\" because target \"" << aliasedName << "\" is IMPORTED."; this->SetError(e.str()); @@ -203,7 +203,7 @@ bool cmAddExecutableCommand // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(exename)) { - cmOStringStream e; + std::ostringstream e; e << "cannot create imported target \"" << exename << "\" because another target with the same name already exists."; this->SetError(e.str()); diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index cdc9f2a..db2f6fb 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -51,7 +51,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting STATIC type."; this->SetError(e.str()); return false; @@ -64,7 +64,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting SHARED type."; this->SetError(e.str()); return false; @@ -77,7 +77,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting MODULE type."; this->SetError(e.str()); return false; @@ -90,7 +90,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting OBJECT type."; this->SetError(e.str()); return false; @@ -103,7 +103,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting UNKNOWN type."; this->SetError(e.str()); return false; @@ -116,7 +116,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting ALIAS type."; this->SetError(e.str()); return false; @@ -128,21 +128,21 @@ bool cmAddLibraryCommand { if (haveSpecifiedType) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting/multiple types."; this->SetError(e.str()); return false; } if (isAlias) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified with conflicting ALIAS type."; this->SetError(e.str()); return false; } if (excludeFromAll) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; this->SetError(e.str()); return false; @@ -155,7 +155,7 @@ bool cmAddLibraryCommand { if (type == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; this->SetError(e.str()); return false; @@ -175,7 +175,7 @@ bool cmAddLibraryCommand } else if(type == cmTarget::INTERFACE_LIBRARY && *s == "GLOBAL") { - cmOStringStream e; + std::ostringstream e; e << "GLOBAL option may only be used with IMPORTED libraries."; this->SetError(e.str()); return false; @@ -190,14 +190,14 @@ bool cmAddLibraryCommand { if (s != args.end()) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library requires no source arguments."; this->SetError(e.str()); return false; } if (importGlobal && !importTarget) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE library specified as GLOBAL, but not as IMPORTED."; this->SetError(e.str()); return false; @@ -214,7 +214,7 @@ bool cmAddLibraryCommand if (!nameOk) { cmake::MessageType messageType = cmake::AUTHOR_WARNING; - cmOStringStream e; + std::ostringstream e; bool issueMessage = false; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037)) { @@ -267,7 +267,7 @@ bool cmAddLibraryCommand } if(args.size() != 3) { - cmOStringStream e; + std::ostringstream e; e << "ALIAS requires exactly one target argument."; this->SetError(e.str()); return false; @@ -276,7 +276,7 @@ bool cmAddLibraryCommand const char *aliasedName = s->c_str(); if(this->Makefile->IsAlias(aliasedName)) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is itself an ALIAS."; this->SetError(e.str()); @@ -286,7 +286,7 @@ bool cmAddLibraryCommand this->Makefile->FindTargetToUse(aliasedName, true); if(!aliasedTarget) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" does not already " "exist."; @@ -300,7 +300,7 @@ bool cmAddLibraryCommand && aliasedType != cmTarget::OBJECT_LIBRARY && aliasedType != cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is not a library."; this->SetError(e.str()); @@ -308,7 +308,7 @@ bool cmAddLibraryCommand } if(aliasedTarget->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "cannot create ALIAS target \"" << libName << "\" because target \"" << aliasedName << "\" is IMPORTED."; this->SetError(e.str()); @@ -328,13 +328,12 @@ bool cmAddLibraryCommand CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to STATIC. But at this point we know only the name of the target, but not yet its linker language. */ - if ((type != cmTarget::STATIC_LIBRARY) && - (type != cmTarget::OBJECT_LIBRARY) && - (type != cmTarget::INTERFACE_LIBRARY) && + if ((type == cmTarget::SHARED_LIBRARY || + type == cmTarget::MODULE_LIBRARY) && (this->Makefile->GetCMakeInstance()->GetPropertyAsBool( "TARGET_SUPPORTS_SHARED_LIBS") == false)) { - cmOStringStream w; + std::ostringstream w; w << "ADD_LIBRARY called with " << (type==cmTarget::SHARED_LIBRARY ? "SHARED" : "MODULE") << @@ -365,7 +364,7 @@ bool cmAddLibraryCommand { if (!cmGeneratorExpression::IsValidTargetName(libName)) { - cmOStringStream e; + std::ostringstream e; e << "Invalid name for IMPORTED INTERFACE library target: " << libName; this->SetError(e.str()); return false; @@ -375,7 +374,7 @@ bool cmAddLibraryCommand // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(libName)) { - cmOStringStream e; + std::ostringstream e; e << "cannot create imported target \"" << libName << "\" because another target with the same name already exists."; this->SetError(e.str()); @@ -414,7 +413,7 @@ bool cmAddLibraryCommand if (!cmGeneratorExpression::IsValidTargetName(libName) || libName.find("::") != std::string::npos) { - cmOStringStream e; + std::ostringstream e; e << "Invalid name for INTERFACE library target: " << libName; this->SetError(e.str()); return false; diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 477a3d9..01598bc 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -37,7 +37,7 @@ bool cmAddSubDirectoryCommand::InitialPass excludeFromAll = true; continue; } - else if (!binArg.size()) + else if (binArg.empty()) { binArg = *i; } @@ -81,7 +81,7 @@ bool cmAddSubDirectoryCommand::InitialPass if(!cmSystemTools::IsSubDirectory(srcPath, this->Makefile->GetCurrentDirectory())) { - cmOStringStream e; + std::ostringstream e; e << "not given a binary directory but the given source directory " << "\"" << srcPath << "\" is not a subdirectory of \"" << this->Makefile->GetCurrentDirectory() << "\". " diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx index 2531a1a..3472b98 100644 --- a/Source/cmAddTestCommand.cxx +++ b/Source/cmAddTestCommand.cxx @@ -36,11 +36,7 @@ bool cmAddTestCommand // Collect the command with arguments. std::vector<std::string> command; - for(std::vector<std::string>::const_iterator it = args.begin() + 1; - it != args.end(); ++it) - { - command.push_back(*it); - } + command.insert(command.end(), args.begin() + 1, args.end()); // Create the test but add a generator only the first time it is // seen. This preserves behavior from before test generators. @@ -51,7 +47,7 @@ bool cmAddTestCommand // allow it to be duplicated. if(!test->GetOldStyle()) { - cmOStringStream e; + std::ostringstream e; e << " given test name \"" << args[0] << "\" which already exists in this directory."; this->SetError(e.str()); @@ -135,7 +131,7 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << " given unknown argument:\n " << args[i] << "\n"; this->SetError(e.str()); return false; @@ -159,7 +155,7 @@ bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args) // Require a unique test name within the directory. if(this->Makefile->GetTest(name)) { - cmOStringStream e; + std::ostringstream e; e << " given test NAME \"" << name << "\" which already exists in this directory."; this->SetError(e.str()); diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index a2aecac..c24c68e 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -16,6 +16,7 @@ #include <cmsys/Directory.hxx> #include <cmsys/FStream.hxx> #include <cm_libarchive.h> +#include "cm_get_date.h" //---------------------------------------------------------------------------- static std::string cm_archive_error_string(struct archive* a) @@ -271,10 +272,26 @@ bool cmArchiveWrite::AddFile(const char* file, cm_archive_entry_copy_pathname(e, dest); if(archive_read_disk_entry_from_file(this->Disk, e, -1, 0) != ARCHIVE_OK) { - this->Error = "archive_read_disk_entry_from_file: "; + this->Error = "archive_read_disk_entry_from_file '"; + this->Error += file; + this->Error += "': "; this->Error += cm_archive_error_string(this->Disk); return false; } + if (!this->MTime.empty()) + { + time_t now; + time(&now); + time_t t = cm_get_date(now, this->MTime.c_str()); + if (t == -1) + { + this->Error = "unable to parse mtime '"; + this->Error += this->MTime; + this->Error += "'"; + return false; + } + archive_entry_set_mtime(e, t, 0); + } // Clear acl and xattr fields not useful for distribution. archive_entry_acl_clear(e); archive_entry_xattr_clear(e); diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index a6dcc0e..17357b4 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -74,6 +74,7 @@ public: // std::cout. void SetVerbose(bool v) { this->Verbose = v; } + void SetMTime(std::string const& t) { this->MTime = t; } private: bool Okay() const { return this->Error.empty(); } bool AddPath(const char* path, size_t skip, const char* prefix); @@ -90,6 +91,7 @@ private: struct archive* Disk; bool Verbose; std::string Error; + std::string MTime; }; #endif diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index d8c3c43..a30d992 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -61,7 +61,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass std::string ext = file.substr(dotpos+1); std::string base = file.substr(0, dotpos); // Process only source files - if( base.size() != 0 + if(!base.empty() && std::find( this->Makefile->GetSourceExtensions().begin(), this->Makefile->GetSourceExtensions().end(), ext ) != this->Makefile->GetSourceExtensions().end() ) diff --git a/Source/cmBootstrapCommands1.cxx b/Source/cmBootstrapCommands1.cxx index 9093579..4274d85 100644 --- a/Source/cmBootstrapCommands1.cxx +++ b/Source/cmBootstrapCommands1.cxx @@ -28,6 +28,7 @@ #include "cmCMakePolicyCommand.cxx" #include "cmCommandArgumentsHelper.cxx" #include "cmConfigureFileCommand.cxx" +#include "cmContinueCommand.cxx" #include "cmCoreTryCompile.cxx" #include "cmCreateTestSourceList.cxx" #include "cmDefinePropertyCommand.cxx" @@ -52,6 +53,8 @@ #include "cmFindProgramCommand.cxx" #include "cmForEachCommand.cxx" #include "cmFunctionCommand.cxx" +#include "cmPathLabel.cxx" +#include "cmSearchPath.cxx" void GetBootstrapCommands1(std::list<cmCommand*>& commands) { @@ -68,6 +71,7 @@ void GetBootstrapCommands1(std::list<cmCommand*>& commands) commands.push_back(new cmCMakeMinimumRequired); commands.push_back(new cmCMakePolicyCommand); commands.push_back(new cmConfigureFileCommand); + commands.push_back(new cmContinueCommand); commands.push_back(new cmCreateTestSourceList); commands.push_back(new cmDefinePropertyCommand); commands.push_back(new cmElseCommand); diff --git a/Source/cmBreakCommand.cxx b/Source/cmBreakCommand.cxx index b70e400..34245b3 100644 --- a/Source/cmBreakCommand.cxx +++ b/Source/cmBreakCommand.cxx @@ -12,10 +12,76 @@ #include "cmBreakCommand.h" // cmBreakCommand -bool cmBreakCommand::InitialPass(std::vector<std::string> const&, +bool cmBreakCommand::InitialPass(std::vector<std::string> const &args, cmExecutionStatus &status) { + if(!this->Makefile->IsLoopBlock()) + { + bool issueMessage = true; + std::ostringstream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0055)) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + messageType = cmake::FATAL_ERROR; + break; + } + + if(issueMessage) + { + e << "A BREAK command was found outside of a proper " + "FOREACH or WHILE loop scope."; + this->Makefile->IssueMessage(messageType, e.str()); + if(messageType == cmake::FATAL_ERROR) + { + return false; + } + } + } + status.SetBreakInvoked(true); + + if(!args.empty()) + { + bool issueMessage = true; + std::ostringstream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0055)) + { + case cmPolicies::WARN: + e << (this->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0055)) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + messageType = cmake::FATAL_ERROR; + break; + } + + if(issueMessage) + { + e << "The BREAK command does not accept any arguments."; + this->Makefile->IssueMessage(messageType, e.str()); + if(messageType == cmake::FATAL_ERROR) + { + return false; + } + } + } + return true; } diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 93f7801..5d32437 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -78,7 +78,7 @@ bool cmBuildCommand } else { - cmOStringStream e; + std::ostringstream e; e << "unknown argument \"" << args[i] << "\""; this->SetError(e.str()); return false; diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx index c64209f..171ed0f 100644 --- a/Source/cmBuildNameCommand.cxx +++ b/Source/cmBuildNameCommand.cxx @@ -50,7 +50,7 @@ bool cmBuildNameCommand { buildname = ""; cmSystemTools::RunSingleCommand("uname -a", &buildname); - if(buildname.length()) + if(!buildname.empty()) { std::string RegExp = "([^ ]*) [^ ]* ([^ ]*) "; cmsys::RegularExpression reg( RegExp.c_str() ); diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index 58b61de..8591ed6 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -63,22 +63,22 @@ bool cmCMakeMinimumRequired // Get the current version number. - int current_major = cmVersion::GetMajorVersion(); - int current_minor = cmVersion::GetMinorVersion(); - int current_patch = cmVersion::GetPatchVersion(); - int current_tweak = cmVersion::GetTweakVersion(); + unsigned int current_major = cmVersion::GetMajorVersion(); + unsigned int current_minor = cmVersion::GetMinorVersion(); + unsigned int current_patch = cmVersion::GetPatchVersion(); + unsigned int current_tweak = cmVersion::GetTweakVersion(); // Parse at least two components of the version number. // Use zero for those not specified. - int required_major = 0; - int required_minor = 0; - int required_patch = 0; - int required_tweak = 0; + unsigned int required_major = 0; + unsigned int required_minor = 0; + unsigned int required_patch = 0; + unsigned int required_tweak = 0; if(sscanf(version_string.c_str(), "%u.%u.%u.%u", &required_major, &required_minor, &required_patch, &required_tweak) < 2) { - cmOStringStream e; + std::ostringstream e; e << "could not parse VERSION \"" << version_string << "\"."; this->SetError(e.str()); return false; @@ -97,7 +97,7 @@ bool cmCMakeMinimumRequired current_tweak < required_tweak)) { // The current version is too low. - cmOStringStream e; + std::ostringstream e; e << "CMake " << version_string << " or higher is required. You are running version " << cmVersion::GetCMakeVersion(); @@ -132,7 +132,7 @@ bool cmCMakeMinimumRequired::EnforceUnknownArguments() { if(!this->UnknownArguments.empty()) { - cmOStringStream e; + std::ostringstream e; e << "called with unknown argument \"" << this->UnknownArguments[0] << "\"."; this->SetError(e.str()); diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx index ddd5d6a..9662fbf 100644 --- a/Source/cmCMakePolicyCommand.cxx +++ b/Source/cmCMakePolicyCommand.cxx @@ -56,7 +56,7 @@ bool cmCMakePolicyCommand return this->HandleVersionMode(args); } - cmOStringStream e; + std::ostringstream e; e << "given unknown first argument \"" << args[0] << "\""; this->SetError(e.str()); return false; @@ -82,7 +82,7 @@ bool cmCMakePolicyCommand::HandleSetMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "SET given unrecognized policy status \"" << args[2] << "\""; this->SetError(e.str()); return false; @@ -113,7 +113,7 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args) cmPolicies::PolicyID pid; if(!this->Makefile->GetPolicies()->GetPolicyID(id.c_str(), pid)) { - cmOStringStream e; + std::ostringstream e; e << "GET given policy \"" << id << "\" which is not known to this " << "version of CMake."; this->SetError(e.str()); @@ -140,7 +140,7 @@ bool cmCMakePolicyCommand::HandleGetMode(std::vector<std::string> const& args) case cmPolicies::REQUIRED_ALWAYS: // The policy is required to be set before anything needs it. { - cmOStringStream e; + std::ostringstream e; e << this->Makefile->GetPolicies()->GetRequiredPolicyError(pid) << "\n" << "The call to cmake_policy(GET " << id << " ...) at which this " diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index dd2a1b8..d0dc30a 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -353,10 +353,11 @@ void CCONV cmAddCustomCommandToTarget(void *arg, const char* target, } // Pass the call to the makefile instance. + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; const char* no_comment = 0; const char* no_working_dir = 0; - mf->AddCustomCommandToTarget(target, no_depends, commandLines, + mf->AddCustomCommandToTarget(target, no_byproducts, no_depends, commandLines, cctype, no_comment, no_working_dir); } @@ -768,7 +769,7 @@ void CCONV cmSourceFileSetName(void *arg, const char* name, const char* dir, } } - cmOStringStream e; + std::ostringstream e; e << "Cannot find source file \"" << pathname << "\""; e << "\n\nTried extensions"; for( std::vector<std::string>::const_iterator ext = sourceExts.begin(); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index f88f72c..1ef4c92 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -212,7 +212,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method, ::curl_easy_setopt(curl, CURLOPT_INFILE, file); //fall through to append GET fields case cmCTest::HTTP_GET: - if(fields.size()) + if(!fields.empty()) { url += "?" + fields; } @@ -240,7 +240,7 @@ int cmCTest::HTTPRequest(std::string url, HTTPMethod method, //---------------------------------------------------------------------- std::string cmCTest::MakeURLSafe(const std::string& str) { - cmOStringStream ost; + std::ostringstream ost; char buffer[10]; for ( std::string::size_type pos = 0; pos < str.size(); pos ++ ) { @@ -378,13 +378,7 @@ cmCTest::cmCTest() //---------------------------------------------------------------------- cmCTest::~cmCTest() { - cmCTest::t_TestingHandlers::iterator it; - for ( it = this->TestingHandlers.begin(); - it != this->TestingHandlers.end(); ++ it ) - { - delete it->second; - it->second = 0; - } + cmDeleteAll(this->TestingHandlers); this->SetOutputLogFileName(0); } @@ -586,7 +580,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } tfin.close(); } - if (tag.size() == 0 || (0 != command) || this->Parts[PartStart]) + if (tag.empty() || (0 != command) || this->Parts[PartStart]) { cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString() << std::endl); @@ -778,7 +772,7 @@ bool cmCTest::UpdateCTestConfiguration() fin.getline(buffer, 1023); buffer[1023] = 0; std::string line = cmCTest::CleanString(buffer); - if(line.size() == 0) + if(line.empty()) { continue; } @@ -878,7 +872,7 @@ bool cmCTest::OpenOutputFile(const std::string& path, bool compress) { std::string testingDir = this->BinaryDir + "/Testing"; - if ( path.size() > 0 ) + if (!path.empty()) { testingDir += "/" + path; } @@ -1073,7 +1067,7 @@ int cmCTest::ProcessTests() if ( cmSystemTools::FileExists(fullname.c_str()) && !cmSystemTools::FileIsDirectory(fullname) ) { - if ( this->NotesFiles.size() > 0 ) + if (!this->NotesFiles.empty()) { this->NotesFiles += ";"; } @@ -1086,7 +1080,7 @@ int cmCTest::ProcessTests() if (this->Parts[PartNotes]) { this->UpdateCTestConfiguration(); - if ( this->NotesFiles.size() ) + if (!this->NotesFiles.empty()) { this->GenerateNotesFile(this->NotesFiles.c_str()); } @@ -1272,7 +1266,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::ostream* log, double testTimeOut, std::vector<std::string>* environment) { - bool modifyEnv = (environment && environment->size()>0); + bool modifyEnv = (environment && !environment->empty()); // determine how much time we have double timeout = this->GetRemainingTimeAllowed() - 120; @@ -1302,7 +1296,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, inst.TimeOut = timeout; // Capture output of the child ctest. - cmOStringStream oss; + std::ostringstream oss; inst.SetStreams(&oss, &oss); std::vector<std::string> args; @@ -1316,7 +1310,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, if (strcmp(argv[i],"--build-generator") == 0 && timeout > 0) { args.push_back("--test-timeout"); - cmOStringStream msg; + std::ostringstream msg; msg << timeout; args.push_back(msg.str()); } @@ -1659,7 +1653,7 @@ int cmCTest::GenerateNotesFile(const char* cfiles) cmCTestLog(this, OUTPUT, "Create notes file" << std::endl); files = cmSystemTools::SplitString(cfiles, ';'); - if ( files.size() == 0 ) + if (files.empty()) { return 1; } @@ -1674,7 +1668,8 @@ std::string cmCTest::Base64GzipEncodeFile(std::string file) std::vector<std::string> files; files.push_back(file); - if(!cmSystemTools::CreateTar(tarFile.c_str(), files, true, false, false)) + if(!cmSystemTools::CreateTar(tarFile.c_str(), files, + cmSystemTools::TarCompressGZip, false)) { cmCTestLog(this, ERROR_MESSAGE, "Error creating tar while " "encoding file: " << file << std::endl); @@ -1688,7 +1683,7 @@ std::string cmCTest::Base64GzipEncodeFile(std::string file) //---------------------------------------------------------------------- std::string cmCTest::Base64EncodeFile(std::string file) { - long len = cmSystemTools::FileLength(file.c_str()); + size_t const len = cmSystemTools::FileLength(file); cmsys::ifstream ifs(file.c_str(), std::ios::in #ifdef _WIN32 | std::ios::binary @@ -1699,14 +1694,13 @@ std::string cmCTest::Base64EncodeFile(std::string file) ifs.close(); unsigned char *encoded_buffer - = new unsigned char [ static_cast<int>( - static_cast<double>(len) * 1.5 + 5.0) ]; + = new unsigned char [ (len * 3) / 2 + 5 ]; - unsigned long rlen + size_t const rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1); std::string base64 = ""; - for(unsigned long i = 0; i < rlen; i++) + for(size_t i = 0; i < rlen; i++) { base64 += encoded_buffer[i]; } @@ -1750,7 +1744,7 @@ bool cmCTest::SubmitExtraFiles(const char* cfiles) cmCTestLog(this, OUTPUT, "Submit extra files" << std::endl); files = cmSystemTools::SplitString(cfiles, ';'); - if ( files.size() == 0 ) + if (files.empty()) { return 1; } @@ -2598,16 +2592,14 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def, return; } cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl); - std::vector<std::string> slist; - cmSystemTools::ExpandListArgument(dval, slist); - std::vector<std::string>::iterator it; vec.clear(); + cmSystemTools::ExpandListArgument(dval, vec); - for ( it = slist.begin(); it != slist.end(); ++it ) + for (std::vector<std::string>::const_iterator it = vec.begin(); + it != vec.end(); ++it ) { cmCTestLog(this, DEBUG, " -- " << *it << std::endl); - vec.push_back(*it); } } @@ -2860,7 +2852,7 @@ void cmCTest::SetConfigType(const char* ct) cmSystemTools::ReplaceString(this->ConfigType, ".\\", ""); std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->ConfigType; - cmSystemTools::PutEnv(confTypeEnv.c_str()); + cmSystemTools::PutEnv(confTypeEnv); } //---------------------------------------------------------------------- @@ -2944,11 +2936,11 @@ bool cmCTest::RunCommand( } cmsysProcess_WaitForExit(cp, 0); - if ( tempOutput.size() > 0 ) + if (!tempOutput.empty()) { stdOut->append(&*tempOutput.begin(), tempOutput.size()); } - if ( tempError.size() > 0 ) + if (!tempError.empty()) { stdErr->append(&*tempError.begin(), tempError.size()); } @@ -3144,7 +3136,7 @@ double cmCTest::GetRemainingTimeAllowed() void cmCTest::OutputTestErrors(std::vector<char> const &process_output) { std::string test_outputs("\n*** Test Failed:\n"); - if(process_output.size()) + if(!process_output.empty()) { test_outputs.append(&*process_output.begin(), process_output.size()); } @@ -3192,9 +3184,9 @@ bool cmCTest::CompressString(std::string& str) // Now base64 encode the resulting binary string unsigned char* base64EncodedBuffer - = new unsigned char[static_cast<int>(outSize * 1.5)]; + = new unsigned char[(outSize * 3) / 2]; - unsigned long rlen + size_t rlen = cmsysBase64_Encode(out, strm.total_out, base64EncodedBuffer, 1); str = ""; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index e19d32c..deb8896 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -27,7 +27,7 @@ class cmCTestStartCommand; #define cmCTestLog(ctSelf, logType, msg) \ do { \ - cmOStringStream cmCTestLog_msg; \ + std::ostringstream cmCTestLog_msg; \ cmCTestLog_msg << msg; \ (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\ cmCTestLog_msg.str().c_str());\ diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 9fc1a5a..45e92ce 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -139,7 +139,7 @@ bool cmCacheManager::ParseEntry(const std::string& entry, { // input line is: key:type=value static cmsys::RegularExpression reg( - "^([^:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); + "^([^=:]*):([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); // input line is: "key":type=value static cmsys::RegularExpression regQuoted( "^\"([^\"]*)\":([^=]*)=(.*[^\r\t ]|[\r\t ]*)[\r\t ]*$"); @@ -609,7 +609,7 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key) void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value) { // if value has trailing space or tab, enclose it in single quotes - if (value.size() && + if (!value.empty() && (value[value.size() - 1] == ' ' || value[value.size() - 1] == '\t')) { diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx index 0c15477..c211111 100644 --- a/Source/cmCallVisualStudioMacro.cxx +++ b/Source/cmCallVisualStudioMacro.cxx @@ -34,8 +34,6 @@ static bool LogErrorsAsMessages; // Copied from a correct comdef.h to avoid problems with deficient versions // of comdef.h that exist in the wild... Fixes issue #7533. // -#if ( _MSC_VER >= 1300 ) -// VS7 and later: #ifdef _NATIVE_WCHAR_T_DEFINED # ifdef _DEBUG # pragma comment(lib, "comsuppwd.lib") @@ -49,10 +47,6 @@ static bool LogErrorsAsMessages; # pragma comment(lib, "comsupp.lib") # endif #endif -#else -// VS6 only had comsupp.lib: -# pragma comment(lib, "comsupp.lib") -#endif //---------------------------------------------------------------------------- @@ -63,12 +57,13 @@ static bool LogErrorsAsMessages; { \ if (LogErrorsAsMessages) \ { \ - std::ostringstream oss; \ - oss.flags(std::ios::hex); \ - oss << context << " failed HRESULT, hr = 0x" << hr << std::endl; \ - oss.flags(std::ios::dec); \ - oss << __FILE__ << "(" << __LINE__ << ")"; \ - cmSystemTools::Message(oss.str().c_str()); \ + std::ostringstream _hresult_oss; \ + _hresult_oss.flags(std::ios::hex); \ + _hresult_oss << context << " failed HRESULT, hr = 0x" \ + << hr << std::endl; \ + _hresult_oss.flags(std::ios::dec); \ + _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \ + cmSystemTools::Message(_hresult_oss.str().c_str()); \ } \ } diff --git a/Source/cmCommand.h b/Source/cmCommand.h index a34ea71..6689243 100644 --- a/Source/cmCommand.h +++ b/Source/cmCommand.h @@ -155,7 +155,7 @@ public: */ const char* GetError() { - if(this->Error.length() == 0) + if(this->Error.empty()) { this->Error = this->GetName(); this->Error += " unknown error."; diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 64b67c9..747b7e4 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -103,7 +103,7 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, } return this->EmptyVariable; } - cmOStringStream e; + std::ostringstream e; e << "Syntax $" << key << "{} is not supported. " << "Only ${}, $ENV{}, and $CACHE{} are allowed."; this->SetError(e.str()); @@ -118,7 +118,7 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) } if(this->FileLine >= 0 && strcmp(var, "CMAKE_CURRENT_LIST_LINE") == 0) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << this->FileLine; return this->AddString(ostr.str()); } @@ -136,7 +136,7 @@ char* cmCommandArgumentParserHelper::ExpandVariable(const char* var) cmSystemTools::IsSubDirectory(this->FileName, this->Makefile->GetHomeOutputDirectory())) { - cmOStringStream msg; + std::ostringstream msg; cmListFileBacktrace bt(this->Makefile->GetLocalGenerator()); cmListFileContext lfc; lfc.FilePath = this->FileName; @@ -253,7 +253,7 @@ bool cmCommandArgumentParserHelper::HandleEscapeSymbol break; default: { - cmOStringStream e; + std::ostringstream e; e << "Invalid escape sequence \\" << symbol; this->SetError(e.str()); } @@ -335,7 +335,7 @@ int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen) void cmCommandArgumentParserHelper::Error(const char* str) { unsigned long pos = static_cast<unsigned long>(this->InputBufferPos); - cmOStringStream ostr; + std::ostringstream ostr; ostr << str << " (" << pos << ")"; this->SetError(ostr.str()); } diff --git a/Source/cmCommandArgumentsHelper.cxx b/Source/cmCommandArgumentsHelper.cxx index 1d5fc07..1a2efc6 100644 --- a/Source/cmCommandArgumentsHelper.cxx +++ b/Source/cmCommandArgumentsHelper.cxx @@ -50,13 +50,8 @@ void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group) if (group!=0) { this->ArgumentsBeforeEmpty = false; - for(std::vector<cmCommandArgument*>::const_iterator - argIt= group->ContainedArguments.begin(); - argIt != group->ContainedArguments.end(); - ++argIt) - { - this->ArgumentsBefore.insert(*argIt); - } + this->ArgumentsBefore.insert(group->ContainedArguments.begin(), + group->ContainedArguments.end()); } } diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index b13a125..32d5cd3 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -200,12 +200,7 @@ cmComputeLinkDepends //---------------------------------------------------------------------------- cmComputeLinkDepends::~cmComputeLinkDepends() { - for(std::vector<DependSetList*>::iterator - i = this->InferredDependSets.begin(); - i != this->InferredDependSets.end(); ++i) - { - delete *i; - } + cmDeleteAll(this->InferredDependSets); delete this->CCG; } @@ -263,21 +258,26 @@ cmComputeLinkDepends::Compute() this->OrderLinkEntires(); // Compute the final set of link entries. + // Iterate in reverse order so we can keep only the last occurrence + // of a shared library. std::set<int> emmitted; - for(std::vector<int>::const_iterator li = this->FinalLinkOrder.begin(); - li != this->FinalLinkOrder.end(); ++li) + for(std::vector<int>::const_reverse_iterator + li = this->FinalLinkOrder.rbegin(), + le = this->FinalLinkOrder.rend(); + li != le; ++li) { int i = *li; LinkEntry const& e = this->EntryList[i]; cmTarget const* t = e.Target; - // Entries that we know the linker will re-use for symbols - // needed by later entries do not need to be repeated. + // Entries that we know the linker will re-use do not need to be repeated. bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY; if(!uniquify || emmitted.insert(i).second) { this->FinalLinkEntries.push_back(e); } } + // Reverse the resulting order since we iterated in reverse. + std::reverse(this->FinalLinkEntries.begin(), this->FinalLinkEntries.end()); // Display the final set. if(this->DebugMode) @@ -676,11 +676,8 @@ void cmComputeLinkDepends::InferDependencies() } // Add the inferred dependencies to the graph. - for(DependSet::const_iterator j = common.begin(); j != common.end(); ++j) - { - int dependee_index = *j; - this->EntryConstraintGraph[depender_index].push_back(dependee_index); - } + cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index]; + edges.insert(edges.end(), common.begin(), common.end()); } } @@ -704,7 +701,7 @@ void cmComputeLinkDepends::CleanConstraintGraph() void cmComputeLinkDepends::DisplayConstraintGraph() { // Display the graph nodes and their edges. - cmOStringStream e; + std::ostringstream e; for(unsigned int i=0; i < this->EntryConstraintGraph.size(); ++i) { EdgeList const& nl = this->EntryConstraintGraph[i]; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index f4fa5c6..479da75 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -408,11 +408,7 @@ cmComputeLinkInformation // Construct a mask to not bother with this behavior for link // directories already specified by the user. std::vector<std::string> const& dirs = this->Target->GetLinkDirectories(); - for(std::vector<std::string>::const_iterator di = dirs.begin(); - di != dirs.end(); ++di) - { - this->OldLinkDirMask.insert(*di); - } + this->OldLinkDirMask.insert(dirs.begin(), dirs.end()); } } @@ -448,18 +444,7 @@ std::string cmComputeLinkInformation::GetRPathLinkString() } // Construct the linker runtime search path. - std::string rpath_link; - const char* sep = ""; - std::vector<std::string> const& dirs = - this->OrderDependentRPath->GetOrderedDirectories(); - for(std::vector<std::string>::const_iterator di = dirs.begin(); - di != dirs.end(); ++di) - { - rpath_link += sep; - sep = ":"; - rpath_link += *di; - } - return rpath_link; + return cmJoin(this->OrderDependentRPath->GetOrderedDirectories(), ":"); } //---------------------------------------------------------------------------- @@ -1342,7 +1327,7 @@ void cmComputeLinkInformation::AddFrameworkItem(std::string const& item) // Try to separate the framework name and path. if(!this->SplitFramework.find(item.c_str())) { - cmOStringStream e; + std::ostringstream e; e << "Could not parse framework path \"" << item << "\" " << "linked by target " << this->Target->GetName() << "."; cmSystemTools::Error(e.str().c_str()); @@ -1389,7 +1374,7 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item) { // A full path to a directory was found as a link item. Warn the // user. - cmOStringStream e; + std::ostringstream e; e << "WARNING: Target \"" << this->Target->GetName() << "\" requests linking to directory \"" << item << "\". " << "Targets may link only to libraries. " @@ -1420,11 +1405,8 @@ void cmComputeLinkInformation::ComputeFrameworkInfo() cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec); } - for(std::vector<std::string>::const_iterator i = implicitDirVec.begin(); - i != implicitDirVec.end(); ++i) - { - this->FrameworkPathsEmmitted.insert(*i); - } + this->FrameworkPathsEmmitted.insert(implicitDirVec.begin(), + implicitDirVec.end()); // Regular expression to extract a framework path and name. this->SplitFramework.compile("(.*)/(.*)\\.framework$"); @@ -1505,7 +1487,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, if(!this->CMakeInstance->GetPropertyAsBool(wid)) { this->CMakeInstance->SetProperty(wid, "1"); - cmOStringStream w; + std::ostringstream w; w << (this->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0008)) << "\n" << "Target \"" << this->Target->GetName() << "\" links to item\n" @@ -1524,7 +1506,7 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item, case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: { - cmOStringStream e; + std::ostringstream e; e << (this->Makefile->GetPolicies()-> GetRequiredPolicyError(cmPolicies::CMP0008)) << "\n" << "Target \"" << this->Target->GetName() << "\" links to item\n" @@ -1554,7 +1536,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories() if(!this->CMakeInstance->GetPropertyAsBool("CMP0003-WARNING-GIVEN")) { this->CMakeInstance->SetProperty("CMP0003-WARNING-GIVEN", "1"); - cmOStringStream w; + std::ostringstream w; this->PrintLinkPolicyDiagnosis(w); this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(), this->Target->GetBacktrace()); @@ -1569,7 +1551,7 @@ bool cmComputeLinkInformation::FinishLinkerSearchDirectories() case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: { - cmOStringStream e; + std::ostringstream e; e << (this->Makefile->GetPolicies()-> GetRequiredPolicyError(cmPolicies::CMP0003)) << "\n"; this->PrintLinkPolicyDiagnosis(e); @@ -1694,11 +1676,7 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo() } // Store implicit link directories. - for(std::vector<std::string>::const_iterator i = implicitDirVec.begin(); - i != implicitDirVec.end(); ++i) - { - this->ImplicitLinkDirs.insert(*i); - } + this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end()); // Get language-specific implicit libraries. std::vector<std::string> implicitLibVec; @@ -1999,18 +1977,7 @@ std::string cmComputeLinkInformation::GetRPathString(bool for_install) this->GetRPath(runtimeDirs, for_install); // Concatenate the paths. - std::string rpath; - const char* sep = ""; - for(std::vector<std::string>::const_iterator ri = runtimeDirs.begin(); - ri != runtimeDirs.end(); ++ri) - { - // Separate from previous path. - rpath += sep; - sep = this->GetRuntimeSep().c_str(); - - // Add this path. - rpath += *ri; - } + std::string rpath = cmJoin(runtimeDirs, this->GetRuntimeSep()); // If the rpath will be replaced at install time, prepare space. if(!for_install && this->RuntimeUseChrpath) diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 75d3967..cf2b88e 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -361,7 +361,7 @@ void cmComputeTargetDepends::AddTargetDepend( cmMakefile *makefile = depender->GetMakefile(); cmake::MessageType messageType = cmake::AUTHOR_WARNING; bool issueMessage = false; - cmOStringStream e; + std::ostringstream e; switch(depender->GetPolicyStatusCMP0046()) { case cmPolicies::WARN: @@ -539,7 +539,7 @@ cmComputeTargetDepends bool strong) { // Construct the error message. - cmOStringStream e; + std::ostringstream e; e << "The inter-target dependency graph contains the following " << "strongly connected component (cycle):\n"; std::vector<NodeList> const& components = ccg.GetComponents(); diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index aba26de..eb4f3a1 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -53,10 +53,7 @@ bool cmConditionEvaluator::IsTrue( cmArgumentList newArgs; // copy to the list structure - for(unsigned int i = 0; i < args.size(); ++i) - { - newArgs.push_back(args[i]); - } + newArgs.insert(newArgs.end(), args.begin(), args.end()); // now loop through the arguments and see if we can reduce any of them // we do this multiple times. Once for each level of precedence @@ -119,7 +116,7 @@ const char* cmConditionEvaluator::GetDefinitionIfUnquoted( if(!hasBeenReported) { - cmOStringStream e; + std::ostringstream e; e << (this->Makefile.GetPolicies()->GetPolicyWarning( cmPolicies::CMP0054)) << "\n"; e << "Quoted variables like \"" << argument.GetValue() << @@ -169,7 +166,7 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword, if(!hasBeenReported) { - cmOStringStream e; + std::ostringstream e; e << (this->Makefile.GetPolicies()->GetPolicyWarning( cmPolicies::CMP0054)) << "\n"; e << "Quoted keywords like \"" << argument.GetValue() << @@ -411,10 +408,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList &newArgs, // copy to the list structure cmArgumentList::iterator argP1 = arg; argP1++; - for(; argP1 != argClose; argP1++) - { - newArgs2.push_back(*argP1); - } + newArgs2.insert(newArgs2.end(), argP1, argClose); newArgs2.pop_back(); // now recursively invoke IsTrue to handle the values inside the // parenthetical expression @@ -559,7 +553,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList &newArgs, cmsys::RegularExpression regEntry; if ( !regEntry.compile(rex) ) { - cmOStringStream error; + std::ostringstream error; error << "Regular expression \"" << rex << "\" cannot compile"; errorString = error.str(); status = cmake::FATAL_ERROR; diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in index 2b0280d..c0a1aa9 100644 --- a/Source/cmConfigure.cmake.h.in +++ b/Source/cmConfigure.cmake.h.in @@ -9,12 +9,9 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#cmakedefine CMAKE_NO_STD_NAMESPACE -#cmakedefine CMAKE_NO_ANSI_STREAM_HEADERS -#cmakedefine CMAKE_NO_ANSI_STRING_STREAM -#cmakedefine CMAKE_NO_ANSI_FOR_SCOPE #cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE #cmakedefine HAVE_UNSETENV #cmakedefine CMAKE_USE_ELF_PARSER +#cmakedefine CMAKE_USE_MACH_PARSER #cmakedefine CMAKE_ENCODING_UTF8 #define CMAKE_DATA_DIR "/@CMAKE_DATA_DIR@" diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index af4805e..fa7f486 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -34,7 +34,7 @@ bool cmConfigureFileCommand // If the input location is a directory, error out. if(cmSystemTools::FileIsDirectory(this->InputFile)) { - cmOStringStream e; + std::ostringstream e; e << "input location\n" << " " << this->InputFile << "\n" << "is a directory but a file was expected."; @@ -74,6 +74,7 @@ bool cmConfigureFileCommand this->CopyOnly = false; this->EscapeQuotes = false; + std::string unknown_args; this->AtOnly = false; for(unsigned int i=2;i < args.size();++i) { @@ -99,6 +100,18 @@ bool cmConfigureFileCommand { /* Ignore legacy option. */ } + else + { + unknown_args += " "; + unknown_args += args[i]; + unknown_args += "\n"; + } + } + if (!unknown_args.empty()) + { + std::string msg = "configure_file called with unknown argument(s):\n"; + msg += unknown_args; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, msg); } if ( !this->ConfigureFile() ) diff --git a/Source/cmContinueCommand.cxx b/Source/cmContinueCommand.cxx new file mode 100644 index 0000000..4a03caa --- /dev/null +++ b/Source/cmContinueCommand.cxx @@ -0,0 +1,39 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2014 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmContinueCommand.h" + +// cmContinueCommand +bool cmContinueCommand::InitialPass(std::vector<std::string> const &args, + cmExecutionStatus &status) +{ + if(!this->Makefile->IsLoopBlock()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "A CONTINUE command was found outside of a " + "proper FOREACH or WHILE loop scope."); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + + status.SetContinueInvoked(true); + + if(!args.empty()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "The CONTINUE command does not accept any " + "arguments."); + cmSystemTools::SetFatalErrorOccured(); + return true; + } + + return true; +} diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h new file mode 100644 index 0000000..093b14f --- /dev/null +++ b/Source/cmContinueCommand.h @@ -0,0 +1,55 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2014 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmContinueCommand_h +#define cmContinueCommand_h + +#include "cmCommand.h" + +/** \class cmContinueCommand + * \brief Continue from an enclosing foreach or while loop + * + * cmContinueCommand returns from an enclosing foreach or while loop + */ +class cmContinueCommand : public cmCommand +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmContinueCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector<std::string> const& args, + cmExecutionStatus &status); + + /** + * This determines if the command is invoked when in script mode. + */ + virtual bool IsScriptable() const { return true; } + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual std::string GetName() const { return "continue"; } + + cmTypeMacro(cmContinueCommand, cmCommand); +}; + + + +#endif diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 512f5cf..60d8dd9 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -150,7 +150,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } else { - cmOStringStream m; + std::ostringstream m; m << "try_compile given unknown argument \"" << argv[i] << "\"."; this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str()); } @@ -201,13 +201,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) else { // only valid for srcfile signatures - if (compileDefs.size()) + if (!compileDefs.empty()) { this->Makefile->IssueMessage(cmake::FATAL_ERROR, "COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE"); return -1; } - if (copyFile.size()) + if (!copyFile.empty()) { this->Makefile->IssueMessage(cmake::FATAL_ERROR, "COPY_FILE specified on a srcdir type TRY_COMPILE"); @@ -220,7 +220,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) // do not allow recursive try Compiles if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory()) { - cmOStringStream e; + std::ostringstream e; e << "Attempt at a recursive or nested TRY_COMPILE in directory\n" << " " << this->BinaryDirectory << "\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -256,7 +256,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) } else { - cmOStringStream err; + std::ostringstream err; err << "Unknown extension \"" << ext << "\" for file\n" << " " << *si << "\n" << "try_compile() works only for enabled languages. " @@ -282,7 +282,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) FILE *fout = cmsys::SystemTools::Fopen(outFileName,"w"); if (!fout) { - cmOStringStream e; + std::ostringstream e; e << "Failed to open\n" << " " << outFileName << "\n" << cmSystemTools::GetLastSystemError(); @@ -331,11 +331,47 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) fprintf(fout, "set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}" " ${COMPILE_DEFINITIONS}\")\n", li->c_str(), li->c_str()); } + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0056)) + { + case cmPolicies::WARN: + if(this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0056")) + { + std::ostringstream w; + w << (this->Makefile->GetCMakeInstance()->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0056)) << "\n" + "For compatibility with older versions of CMake, try_compile " + "is not honoring caller link flags (e.g. CMAKE_EXE_LINKER_FLAGS) " + "in the test project." + ; + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } + case cmPolicies::OLD: + // OLD behavior is to do nothing. + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + this->Makefile->GetCMakeInstance()->GetPolicies() + ->GetRequiredPolicyError(cmPolicies::CMP0056) + ); + case cmPolicies::NEW: + // NEW behavior is to pass linker flags. + { + const char* exeLinkFlags = + this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS"); + fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n", + lg->EscapeForCMake(exeLinkFlags?exeLinkFlags:"").c_str()); + } break; + } + fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}" + " ${EXE_LINKER_FLAGS}\")\n"); fprintf(fout, "include_directories(${INCLUDE_DIRECTORIES})\n"); fprintf(fout, "set(CMAKE_SUPPRESS_REGENERATION 1)\n"); fprintf(fout, "link_directories(${LINK_DIRECTORIES})\n"); // handle any compile flags we need to pass on - if (compileDefs.size()) + if (!compileDefs.empty()) { fprintf(fout, "add_definitions( "); for (size_t i = 0; i < compileDefs.size(); ++i) @@ -501,7 +537,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) "Result of TRY_COMPILE", cmCacheManager::INTERNAL); - if ( outputVariable.size() > 0 ) + if (!outputVariable.empty()) { this->Makefile->AddDefinition(outputVariable, output.c_str()); } @@ -511,13 +547,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) std::string copyFileErrorMessage; this->FindOutputFile(targetName); - if ((res==0) && (copyFile.size())) + if ((res==0) && !copyFile.empty()) { if(this->OutputFile.empty() || !cmSystemTools::CopyFileAlways(this->OutputFile, copyFile)) { - cmOStringStream emsg; + std::ostringstream emsg; emsg << "Cannot copy output executable\n" << " '" << this->OutputFile << "'\n" << "to destination specified by COPY_FILE:\n" @@ -655,7 +691,7 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName) } } - cmOStringStream emsg; + std::ostringstream emsg; emsg << "Unable to find the executable at any of:\n"; for (unsigned int i = 0; i < searchDirs.size(); ++i) { diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx index 02fb8cb..f93d3df 100644 --- a/Source/cmCreateTestSourceList.cxx +++ b/Source/cmCreateTestSourceList.cxx @@ -101,7 +101,7 @@ bool cmCreateTestSourceList break; } std::string func_name; - if (cmSystemTools::GetFilenamePath(*i).size() > 0) + if (!cmSystemTools::GetFilenamePath(*i).empty()) { func_name = cmSystemTools::GetFilenamePath(*i) + "/" + cmSystemTools::GetFilenameWithoutLastExtension(*i); @@ -126,7 +126,7 @@ bool cmCreateTestSourceList for(i = testsBegin, j = tests_func_name.begin(); i != tests.end(); ++i, ++j) { std::string func_name; - if (cmSystemTools::GetFilenamePath(*i).size() > 0) + if (!cmSystemTools::GetFilenamePath(*i).empty()) { func_name = cmSystemTools::GetFilenamePath(*i) + "/" + cmSystemTools::GetFilenameWithoutLastExtension(*i); @@ -145,12 +145,12 @@ bool cmCreateTestSourceList " },\n"; numTests++; } - if(extraInclude.size()) + if(!extraInclude.empty()) { this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES", extraInclude.c_str()); } - if(function.size()) + if(!function.empty()) { this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function.c_str()); diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index c161eb6..015825d 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -22,11 +22,13 @@ cmCustomCommand::cmCustomCommand() this->HaveComment = false; this->EscapeOldStyle = true; this->EscapeAllowMakeVars = false; + this->UsesTerminal = false; } //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): Outputs(r.Outputs), + Byproducts(r.Byproducts), Depends(r.Depends), CommandLines(r.CommandLines), HaveComment(r.HaveComment), @@ -34,7 +36,8 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r): WorkingDirectory(r.WorkingDirectory), EscapeAllowMakeVars(r.EscapeAllowMakeVars), EscapeOldStyle(r.EscapeOldStyle), - Backtrace(r.Backtrace) + Backtrace(r.Backtrace), + UsesTerminal(r.UsesTerminal) { } @@ -47,6 +50,7 @@ cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r) } this->Outputs = r.Outputs; + this->Byproducts= r.Byproducts; this->Depends = r.Depends; this->CommandLines = r.CommandLines; this->HaveComment = r.HaveComment; @@ -56,6 +60,7 @@ cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r) this->EscapeOldStyle = r.EscapeOldStyle; this->ImplicitDepends = r.ImplicitDepends; this->Backtrace = r.Backtrace; + this->UsesTerminal = r.UsesTerminal; return *this; } @@ -63,11 +68,13 @@ cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r) //---------------------------------------------------------------------------- cmCustomCommand::cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDirectory): Outputs(outputs), + Byproducts(byproducts), Depends(depends), CommandLines(commandLines), HaveComment(comment?true:false), @@ -97,6 +104,12 @@ const std::vector<std::string>& cmCustomCommand::GetOutputs() const } //---------------------------------------------------------------------------- +const std::vector<std::string>& cmCustomCommand::GetByproducts() const +{ + return this->Byproducts; +} + +//---------------------------------------------------------------------------- const std::vector<std::string>& cmCustomCommand::GetDepends() const { return this->Depends; @@ -118,21 +131,14 @@ const char* cmCustomCommand::GetComment() const //---------------------------------------------------------------------------- void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines) { - for(cmCustomCommandLines::const_iterator i=commandLines.begin(); - i != commandLines.end(); ++i) - { - this->CommandLines.push_back(*i); - } + this->CommandLines.insert(this->CommandLines.end(), + commandLines.begin(), commandLines.end()); } //---------------------------------------------------------------------------- void cmCustomCommand::AppendDepends(const std::vector<std::string>& depends) { - for(std::vector<std::string>::const_iterator i=depends.begin(); - i != depends.end(); ++i) - { - this->Depends.push_back(*i); - } + this->Depends.insert(this->Depends.end(), depends.begin(), depends.end()); } //---------------------------------------------------------------------------- @@ -184,3 +190,15 @@ void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l) this->ImplicitDepends.insert(this->ImplicitDepends.end(), l.begin(), l.end()); } + +//---------------------------------------------------------------------------- +bool cmCustomCommand::GetUsesTerminal() const +{ + return this->UsesTerminal; +} + +//---------------------------------------------------------------------------- +void cmCustomCommand::SetUsesTerminal(bool b) +{ + this->UsesTerminal = b; +} diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index 21dbefb..0bfaef2 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -32,6 +32,7 @@ public: /** Main constructor specifies all information for the command. */ cmCustomCommand(cmMakefile const* mf, const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, const char* comment, @@ -42,6 +43,9 @@ public: /** Get the output file produced by the command. */ const std::vector<std::string>& GetOutputs() const; + /** Get the extra files produced by the command. */ + const std::vector<std::string>& GetByproducts() const; + /** Get the vector that holds the list of dependencies. */ const std::vector<std::string>& GetDepends() const; @@ -79,8 +83,14 @@ public: void AppendImplicitDepends(ImplicitDependsList const&); ImplicitDependsList const& GetImplicitDepends() const; + /** Set/Get whether this custom command should be given access to the + real console (if possible). */ + bool GetUsesTerminal() const; + void SetUsesTerminal(bool b); + private: std::vector<std::string> Outputs; + std::vector<std::string> Byproducts; std::vector<std::string> Depends; cmCustomCommandLines CommandLines; bool HaveComment; @@ -90,6 +100,7 @@ private: bool EscapeOldStyle; cmListFileBacktrace Backtrace; ImplicitDependsList ImplicitDepends; + bool UsesTerminal; }; #endif diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 1bca6e6..162d7a1 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -91,6 +91,12 @@ std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const } //---------------------------------------------------------------------------- +std::vector<std::string> const& cmCustomCommandGenerator::GetByproducts() const +{ + return this->CC.GetByproducts(); +} + +//---------------------------------------------------------------------------- std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const { if (!this->DependsDone) diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h index 0d8a0a4..b4ae014 100644 --- a/Source/cmCustomCommandGenerator.h +++ b/Source/cmCustomCommandGenerator.h @@ -42,6 +42,7 @@ public: const char* GetComment() const; std::string GetWorkingDirectory() const; std::vector<std::string> const& GetOutputs() const; + std::vector<std::string> const& GetByproducts() const; std::vector<std::string> const& GetDepends() const; }; diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx index 6b729de..5ff0186 100644 --- a/Source/cmDefinePropertyCommand.cxx +++ b/Source/cmDefinePropertyCommand.cxx @@ -53,7 +53,7 @@ bool cmDefinePropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid scope " << args[0] << ". " << "Valid scopes are " << "GLOBAL, DIRECTORY, TARGET, SOURCE, " @@ -100,7 +100,7 @@ bool cmDefinePropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid argument \"" << args[i] << "\"."; this->SetError(e.str()); return false; diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx index 947db82..d419011 100644 --- a/Source/cmDepends.cxx +++ b/Source/cmDepends.cxx @@ -123,7 +123,7 @@ void cmDepends::Clear(const char *file) // Print verbose output. if(this->Verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Clearing dependencies in \"" << file << "\"." << std::endl; cmSystemTools::Stdout(msg.str().c_str()); } @@ -213,7 +213,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, // Print verbose output. if(this->Verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Dependee \"" << dependee << "\" does not exist for depender \"" << depender << "\"." << std::endl; @@ -235,7 +235,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, // Print verbose output. if(this->Verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Dependee \"" << dependee << "\" is newer than depender \"" << depender << "\"." << std::endl; @@ -257,7 +257,7 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends, // Print verbose output. if(this->Verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Dependee \"" << dependee << "\" is newer than depends file \"" << internalDependsFileName << "\"." << std::endl; diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index a1fc268..6dde349 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -90,12 +90,7 @@ cmDependsC::cmDependsC(cmLocalGenerator* lg, cmDependsC::~cmDependsC() { this->WriteCacheFile(); - - for (std::map<std::string, cmIncludeLines*>::iterator it= - this->FileCache.begin(); it!=this->FileCache.end(); ++it) - { - delete it->second; - } + cmDeleteAll(this->FileCache); } //---------------------------------------------------------------------------- @@ -125,11 +120,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, this->ValidDeps->find(obj); if (tmpIt!= this->ValidDeps->end()) { - for(DependencyVector::const_iterator i=tmpIt->second.begin(); - i != tmpIt->second.end(); ++i) - { - dependencies.insert(*i); - } + dependencies.insert(tmpIt->second.begin(), tmpIt->second.end()); haveDeps = true; } } @@ -294,7 +285,7 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, //---------------------------------------------------------------------------- void cmDependsC::ReadCacheFile() { - if(this->CacheFileName.size() == 0) + if(this->CacheFileName.empty()) { return; } @@ -383,7 +374,7 @@ void cmDependsC::ReadCacheFile() //---------------------------------------------------------------------------- void cmDependsC::WriteCacheFile() const { - if(this->CacheFileName.size() == 0) + if(this->CacheFileName.empty()) { return; } diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index 4082d24..d9818ce 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -319,17 +319,13 @@ void cmDependsFortran::LocateModules() infoI != objInfo.end(); ++infoI) { cmDependsFortranSourceInfo const& info = infoI->second; - for(std::set<std::string>::const_iterator i = info.Provides.begin(); - i != info.Provides.end(); ++i) - { - // Include this module in the set provided by this target. - this->Internal->TargetProvides.insert(*i); - } + // Include this module in the set provided by this target. + this->Internal->TargetProvides.insert(info.Provides.begin(), + info.Provides.end()); for(std::set<std::string>::const_iterator i = info.Requires.begin(); i != info.Requires.end(); ++i) { - // Include this module in the set required by this target. this->Internal->TargetRequires[*i] = ""; } } diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx index 02f2d21..3c02325 100644 --- a/Source/cmDependsJavaParserHelper.cxx +++ b/Source/cmDependsJavaParserHelper.cxx @@ -226,7 +226,7 @@ void cmDependsJavaParserHelper::EndClass() { CurrentClass* parent = 0; CurrentClass* current = 0; - if ( this->ClassStack.size() > 0 ) + if (!this->ClassStack.empty()) { current = &(*(this->ClassStack.end() - 1)); if ( this->ClassStack.size() > 1 ) @@ -251,7 +251,7 @@ void cmDependsJavaParserHelper::EndClass() void cmDependsJavaParserHelper::PrintClasses() { - if ( this->ClassStack.size() == 0 ) + if (this->ClassStack.empty()) { std::cerr << "Error when parsing. No classes on class stack" << std::endl; abort(); @@ -305,13 +305,13 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) if ( verb ) { - if ( this->CurrentPackage.size() > 0 ) + if (!this->CurrentPackage.empty()) { std::cout << "Current package is: " << this->CurrentPackage << std::endl; } std::cout << "Imports packages:"; - if ( this->PackagesImport.size() > 0 ) + if (!this->PackagesImport.empty()) { std::vector<std::string>::iterator it; for ( it = this->PackagesImport.begin(); @@ -323,7 +323,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb) } std::cout << std::endl; std::cout << "Depends on:"; - if ( this->ClassesFound.size() > 0 ) + if (!this->ClassesFound.empty()) { std::vector<std::string>::iterator it; for ( it = this->ClassesFound.begin(); diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 3ff1017..f4e3a75 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -87,12 +87,7 @@ cmDocumentation::cmDocumentation() //---------------------------------------------------------------------------- cmDocumentation::~cmDocumentation() { - for(std::map<std::string,cmDocumentationSection *>::iterator i = - this->AllSections.begin(); - i != this->AllSections.end(); ++i) - { - delete i->second; - } + cmDeleteAll(this->AllSections); } //---------------------------------------------------------------------------- @@ -167,7 +162,7 @@ bool cmDocumentation::PrintRequestedDocumentation(std::ostream& os) // given stream. cmsys::ofstream* fout = 0; std::ostream* s = &os; - if(i->Filename.length() > 0) + if(!i->Filename.empty()) { fout = new cmsys::ofstream(i->Filename.c_str(), std::ios::out); if(fout) @@ -882,7 +877,7 @@ bool cmDocumentation::PrintHelp(std::ostream& os) //---------------------------------------------------------------------------- const char* cmDocumentation::GetNameString() const { - if(this->NameString.length() > 0) + if(!this->NameString.empty()) { return this->NameString.c_str(); } diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index 29c806d..4de59c0 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -46,7 +46,7 @@ void cmDocumentationFormatter::PrintFormatted(std::ostream& os, preformatted.append(1, '\n'); } } - if(preformatted.length()) + if(!preformatted.empty()) { this->PrintPreformatted(os, preformatted.c_str()); } @@ -62,7 +62,7 @@ void cmDocumentationFormatter::PrintFormatted(std::ostream& os, ++ptr; paragraph.append(1, '\n'); } - if(paragraph.length()) + if(!paragraph.empty()) { this->PrintParagraph(os, paragraph.c_str()); } @@ -201,7 +201,7 @@ void cmDocumentationFormatter for(std::vector<cmDocumentationEntry>::const_iterator op = entries.begin(); op != entries.end(); ++op) { - if(op->Name.size()) + if(!op->Name.empty()) { os << " " << op->Name; this->TextIndent = " "; diff --git a/Source/cmDynamicLoader.h b/Source/cmDynamicLoader.h index d038b5c..84bc9bc 100644 --- a/Source/cmDynamicLoader.h +++ b/Source/cmDynamicLoader.h @@ -15,8 +15,8 @@ // libraries into a process. -#ifndef __cmDynamicLoader_h -#define __cmDynamicLoader_h +#ifndef cmDynamicLoader_h +#define cmDynamicLoader_h #include "cmStandardIncludes.h" diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index cab23b7..d062987 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -532,7 +532,7 @@ cmELFInternalImpl<Types> break; } #endif - cmOStringStream e; + std::ostringstream e; e << "Unknown ELF file type " << eti; this->SetErrorMessage(e.str().c_str()); return; diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx index 9b59088..e021d0b 100644 --- a/Source/cmExecProgramCommand.cxx +++ b/Source/cmExecProgramCommand.cxx @@ -41,7 +41,7 @@ bool cmExecProgramCommand } else if ( haveoutput_variable ) { - if ( output_variable.size() > 0 ) + if (!output_variable.empty()) { this->SetError("called with incorrect number of arguments"); return false; @@ -59,7 +59,7 @@ bool cmExecProgramCommand } else if ( havereturn_variable ) { - if ( return_variable.size() > 0 ) + if (!return_variable.empty()) { this->SetError("called with incorrect number of arguments"); return false; @@ -84,7 +84,7 @@ bool cmExecProgramCommand } std::string command; - if(arguments.size()) + if(!arguments.empty()) { command = cmSystemTools::ConvertToRunCommandPath(args[0].c_str()); command += " "; @@ -95,7 +95,7 @@ bool cmExecProgramCommand command = args[0]; } bool verbose = true; - if(output_variable.size() > 0) + if(!output_variable.empty()) { verbose = false; } @@ -118,7 +118,7 @@ bool cmExecProgramCommand retVal = -1; } - if ( output_variable.size() > 0 ) + if (!output_variable.empty()) { std::string::size_type first = output.find_first_not_of(" \n\t\r"); std::string::size_type last = output.find_last_not_of(" \n\t\r"); @@ -135,7 +135,7 @@ bool cmExecProgramCommand this->Makefile->AddDefinition(output_variable, coutput.c_str()); } - if ( return_variable.size() > 0 ) + if (!return_variable.empty()) { char buffer[100]; sprintf(buffer, "%d", retVal); diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 11f8ae5..1225992 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -189,7 +189,7 @@ bool cmExecuteProcessCommand } else { - cmOStringStream e; + std::ostringstream e; e << " given unknown argument \"" << args[i] << "\"."; this->SetError(e.str()); return false; @@ -324,12 +324,12 @@ bool cmExecuteProcessCommand error_strip_trailing_whitespace); // Store the output obtained. - if(!output_variable.empty() && tempOutput.size()) + if(!output_variable.empty() && !tempOutput.empty()) { this->Makefile->AddDefinition(output_variable, &*tempOutput.begin()); } - if(!merge_output && !error_variable.empty() && tempError.size()) + if(!merge_output && !error_variable.empty() && !tempError.empty()) { this->Makefile->AddDefinition(error_variable, &*tempError.begin()); diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h index 5c94a97..d4da5a4 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -36,10 +36,16 @@ public: virtual bool GetBreakInvoked() { return this->BreakInvoked; } + virtual void SetContinueInvoked(bool val) + { this->ContinueInvoked = val; } + virtual bool GetContinueInvoked() + { return this->ContinueInvoked; } + virtual void Clear() { this->ReturnInvoked = false; this->BreakInvoked = false; + this->ContinueInvoked = false; this->NestedError = false; } virtual void SetNestedError(bool val) { this->NestedError = val; } @@ -49,6 +55,7 @@ public: protected: bool ReturnInvoked; bool BreakInvoked; + bool ContinueInvoked; bool NestedError; }; diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 30a52d4..a28ec48 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -45,7 +45,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) } else { - cmOStringStream e; + std::ostringstream e; e << "given target \"" << te->GetName() << "\" more than once."; this->Makefile->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, e.str(), this->Backtrace); @@ -68,6 +68,16 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) tei != this->Exports.end(); ++tei) { cmTarget* te = *tei; + if (te->GetProperty("INTERFACE_SOURCES")) + { + std::ostringstream e; + e << "Target \"" + << te->GetName() + << "\" has a populated INTERFACE_SOURCES property. This is not " + "currently supported."; + cmSystemTools::Error(e.str().c_str()); + return false; + } this->GenerateImportTargetCode(os, te); te->AppendBuildInterfaceIncludes(); @@ -303,7 +313,7 @@ cmExportBuildFileGenerator return; } - cmOStringStream e; + std::ostringstream e; e << "export called with target \"" << depender->GetName() << "\" which requires target \"" << dependee->GetName() << "\" "; if (occurrences == 0) diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index db21c49..76283d4 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -89,7 +89,7 @@ bool cmExportCommand if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString()) != ".cmake") { - cmOStringStream e; + std::ostringstream e; e << "FILE option given filename \"" << this->Filename.GetString() << "\" which does not have an extension of \".cmake\".\n"; this->SetError(e.str()); @@ -103,7 +103,7 @@ bool cmExportCommand { if(!this->Makefile->CanIWriteThisFile(fname.c_str())) { - cmOStringStream e; + std::ostringstream e; e << "FILE option given filename \"" << fname << "\" which is in the source tree.\n"; this->SetError(e.str()); @@ -126,7 +126,7 @@ bool cmExportCommand { if (this->Append.IsEnabled()) { - cmOStringStream e; + std::ostringstream e; e << "EXPORT signature does not recognise the APPEND option."; this->SetError(e.str()); return false; @@ -134,7 +134,7 @@ bool cmExportCommand if (this->ExportOld.IsEnabled()) { - cmOStringStream e; + std::ostringstream e; e << "EXPORT signature does not recognise the " "EXPORT_LINK_INTERFACE_LIBRARIES option."; this->SetError(e.str()); @@ -145,7 +145,7 @@ bool cmExportCommand std::string setName = this->ExportSetName.GetString(); if (setMap.find(setName) == setMap.end()) { - cmOStringStream e; + std::ostringstream e; e << "Export set \"" << setName << "\" not found."; this->SetError(e.str()); return false; @@ -161,7 +161,7 @@ bool cmExportCommand { if (this->Makefile->IsAlias(*currentTarget)) { - cmOStringStream e; + std::ostringstream e; e << "given ALIAS target \"" << *currentTarget << "\" which may not be exported."; this->SetError(e.str()); @@ -172,7 +172,7 @@ bool cmExportCommand { if(target->GetType() == cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "given OBJECT library \"" << *currentTarget << "\" which may not be exported."; this->SetError(e.str()); @@ -181,7 +181,7 @@ bool cmExportCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given target \"" << *currentTarget << "\" which is not built by this project."; this->SetError(e.str()); @@ -261,7 +261,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "PACKAGE given unknown argument: " << args[i]; this->SetError(e.str()); return false; @@ -278,7 +278,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args) cmsys::RegularExpression packageRegex(packageExpr); if(!packageRegex.find(package.c_str())) { - cmOStringStream e; + std::ostringstream e; e << "PACKAGE given invalid package name \"" << package << "\". " << "Package names must match \"" << packageExpr << "\"."; this->SetError(e.str()); @@ -314,7 +314,7 @@ void cmExportCommand::ReportRegistryError(std::string const& msg, std::string const& key, long err) { - cmOStringStream e; + std::ostringstream e; e << msg << "\n" << " HKEY_CURRENT_USER\\" << key << "\n"; wchar_t winmsg[1024]; @@ -355,7 +355,7 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package, RegCloseKey(hKey); if(err != ERROR_SUCCESS) { - cmOStringStream msg; + std::ostringstream msg; msg << "Cannot set registry value \"" << hash << "\" under key"; this->ReportRegistryError(msg.str(), key, err); return; @@ -400,7 +400,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package, } else { - cmOStringStream e; + std::ostringstream e; e << "Cannot create package registry file:\n" << " " << fname << "\n" << cmSystemTools::GetLastSystemError() << "\n"; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 1f39d7a..af4ce8b 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -81,7 +81,7 @@ bool cmExportFileGenerator::GenerateImportFile() if(!foutPtr.get() || !*foutPtr) { std::string se = cmSystemTools::GetLastSystemError(); - cmOStringStream e; + std::ostringstream e; e << "cannot write to file \"" << this->MainImportFile << "\": " << se; cmSystemTools::Error(e.str().c_str()); @@ -247,7 +247,7 @@ static bool checkInterfaceDirs(const std::string &prepro, continue; } cmake::MessageType messageType = cmake::FATAL_ERROR; - cmOStringStream e; + std::ostringstream e; if (genexPos != std::string::npos) { switch (target->GetPolicyStatusCMP0041()) @@ -295,7 +295,7 @@ static bool checkInterfaceDirs(const std::string &prepro, { case cmPolicies::WARN: { - cmOStringStream s; + std::ostringstream s; s << target->GetMakefile()->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0052) << "\n"; s << "Directory:\n \"" << *li << "\"\nin " @@ -391,7 +391,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( if (cge->GetHadContextSensitiveCondition()) { cmMakefile* mf = target->GetMakefile(); - cmOStringStream e; + std::ostringstream e; e << "Target \"" << target->GetName() << "\" is installed with " "INCLUDES DESTINATION set to a context sensitive path. Paths which " "depend on the configuration, policy values or the link interface are " @@ -456,11 +456,7 @@ void getPropertyContents(cmTarget const* tgt, const std::string& prop, } std::vector<std::string> content; cmSystemTools::ExpandListArgument(p, content); - for (std::vector<std::string>::const_iterator ci = content.begin(); - ci != content.end(); ++ci) - { - ifaceProperties.insert(*ci); - } + ifaceProperties.insert(content.begin(), content.end()); } //---------------------------------------------------------------------------- @@ -473,7 +469,7 @@ void getCompatibleInterfaceProperties(cmTarget *target, if (!info) { cmMakefile* mf = target->GetMakefile(); - cmOStringStream e; + std::ostringstream e; e << "Exporting the target \"" << target->GetName() << "\" is not " "allowed since its linker language cannot be determined"; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -773,7 +769,7 @@ cmExportFileGenerator if(newCMP0022Behavior && !this->ExportOld) { cmMakefile *mf = target->GetMakefile(); - cmOStringStream e; + std::ostringstream e; e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, " "but also has old-style LINK_INTERFACE_LIBRARIES properties " "populated, but it was exported without the " @@ -857,7 +853,7 @@ cmExportFileGenerator { std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; prop += suffix; - cmOStringStream m; + std::ostringstream m; m << iface->Multiplicity; properties[prop] = m.str(); } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 89071c0..98ed818 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -56,7 +56,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) } else { - cmOStringStream e; + std::ostringstream e; e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName() << "\" ...) " << "includes target \"" << te->Target->GetName() @@ -69,13 +69,24 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateExpectedTargetsCode(os, expectedTargets); } - // Add code to compute the installation prefix relative to the - // import file location. + // Set an _IMPORT_PREFIX variable for import location properties + // to reference if they are relative to the install prefix. + std::string installPrefix = + this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); const char* installDest = this->IEGen->GetDestination(); - if(!cmSystemTools::FileIsFullPath(installDest)) + if(cmSystemTools::FileIsFullPath(installDest)) { - std::string installPrefix = - this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + // The export file is being installed to an absolute path so the + // package is not relocatable. Use the configured install prefix. + os << + "# The installation prefix configured by this project.\n" + "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n" + "\n"; + } + else + { + // Add code to compute the installation prefix relative to the + // import file location. std::string absDest = installPrefix + "/" + installDest; std::string absDestS = absDest + "/"; os << "# Compute the installation prefix relative to this file.\n" @@ -106,9 +117,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) dest = cmSystemTools::GetFilenamePath(dest); } os << "\n"; - - // Import location properties may reference this variable. - this->ImportPrefix = "${_IMPORT_PREFIX}/"; } std::vector<std::string> missingTargets; @@ -123,6 +131,17 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { cmTarget* te = (*tei)->Target; + if (te->GetProperty("INTERFACE_SOURCES")) + { + std::ostringstream e; + e << "Target \"" + << te->GetName() + << "\" has a populated INTERFACE_SOURCES property. This is not " + "currently supported."; + cmSystemTools::Error(e.str().c_str()); + return false; + } + requiresConfigFiles = requiresConfigFiles || te->GetType() != cmTarget::INTERFACE_LIBRARY; @@ -198,12 +217,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) << "\n"; // Cleanup the import prefix variable. - if(!this->ImportPrefix.empty()) - { - os << "# Cleanup temporary variables.\n" - << "set(_IMPORT_PREFIX)\n" - << "\n"; - } + os << "# Cleanup temporary variables.\n" + << "set(_IMPORT_PREFIX)\n" + << "\n"; this->GenerateImportedFileCheckLoop(os); bool result = true; @@ -274,7 +290,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig( if(!exportFileStream) { std::string se = cmSystemTools::GetLastSystemError(); - cmOStringStream e; + std::ostringstream e; e << "cannot write to file \"" << fileName << "\": " << se; cmSystemTools::Error(e.str().c_str()); @@ -383,11 +399,7 @@ cmExportInstallFileGenerator if(!cmSystemTools::FileIsFullPath(dest.c_str())) { // The target is installed relative to the installation prefix. - if(this->ImportPrefix.empty()) - { - this->ComplainAboutImportPrefix(itgen); - } - value = this->ImportPrefix; + value = "${_IMPORT_PREFIX}/"; } value += dest; value += "/"; @@ -497,24 +509,6 @@ cmExportInstallFileGenerator return namespaces; } - -//---------------------------------------------------------------------------- -void -cmExportInstallFileGenerator -::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen) -{ - const char* installDest = this->IEGen->GetDestination(); - cmOStringStream e; - e << "install(EXPORT \"" - << this->IEGen->GetExportSet()->GetName() - << "\") given absolute " - << "DESTINATION \"" << installDest << "\" but the export " - << "references an installation of target \"" - << itgen->GetTarget()->GetName() << "\" which has relative " - << "DESTINATION \"" << itgen->GetDestination() << "\"."; - cmSystemTools::Error(e.str().c_str()); -} - //---------------------------------------------------------------------------- void cmExportInstallFileGenerator @@ -522,7 +516,7 @@ cmExportInstallFileGenerator cmTarget* dependee, int occurrences) { - cmOStringStream e; + std::ostringstream e; e << "install(EXPORT \"" << this->IEGen->GetExportSet()->GetName() << "\" ...) " diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index b851ad5..6f86ac9 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -83,14 +83,10 @@ protected: std::set<std::string>& importedLocations ); - void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); - std::string InstallNameDir(cmTarget* target, const std::string& config); cmInstallExportGenerator* IEGen; - std::string ImportPrefix; - // The import file generated for each configuration. std::map<std::string, std::string> ConfigImportFiles; }; diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index 33b0630..14812e4 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -15,10 +15,7 @@ cmExportSet::~cmExportSet() { - for(unsigned int i = 0; i < this->TargetExports.size(); ++ i) - { - delete this->TargetExports[i]; - } + cmDeleteAll(this->TargetExports); } void cmExportSet::AddTargetExport(cmTargetExport* te) diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx index 5174118..14c4458 100644 --- a/Source/cmExportSetMap.cxx +++ b/Source/cmExportSetMap.cxx @@ -25,12 +25,7 @@ cmExportSet* cmExportSetMap::operator[](const std::string &name) void cmExportSetMap::clear() { - for(std::map<std::string, cmExportSet*>::iterator it = this->begin(); - it != this->end(); - ++ it) - { - delete it->second; - } + cmDeleteAll(*this); this->derived::clear(); } diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index cc35f84..6016c4c 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -99,7 +99,7 @@ int cmExprParserHelper::LexInput(char* buf, int maxlen) void cmExprParserHelper::Error(const char* str) { unsigned long pos = static_cast<unsigned long>(this->InputBufferPos); - cmOStringStream ostr; + std::ostringstream ostr; ostr << str << " (" << pos << ")"; this->ErrorString = ostr.str(); } diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 79d7bcaff..69857ef 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -615,12 +615,8 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, std::vector<std::string> includes; target->GetMakefile()->GetLocalGenerator()-> GetIncludeDirectories(includes, gtgt, "C", buildType); - for(std::vector<std::string>::const_iterator dirIt=includes.begin(); - dirIt != includes.end(); - ++dirIt) - { - uniqIncludeDirs.insert(*dirIt); - } + + uniqIncludeDirs.insert(includes.begin(), includes.end()); std::string systemIncludeDirs = makefile->GetSafeDefinition( "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); @@ -628,12 +624,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, { std::vector<std::string> dirs; cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); - for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); - dirIt != dirs.end(); - ++dirIt) - { - uniqIncludeDirs.insert(*dirIt); - } + uniqIncludeDirs.insert(dirs.begin(), dirs.end()); } systemIncludeDirs = makefile->GetSafeDefinition( @@ -642,12 +633,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, { std::vector<std::string> dirs; cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); - for(std::vector<std::string>::const_iterator dirIt=dirs.begin(); - dirIt != dirs.end(); - ++dirIt) - { - uniqIncludeDirs.insert(*dirIt); - } + uniqIncludeDirs.insert(dirs.begin(), dirs.end()); } for(std::set<std::string>::const_iterator dirIt=uniqIncludeDirs.begin(); diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index cc42bca..eb50a7d 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -454,7 +454,7 @@ cmExtraCodeLiteGenerator::GetBuildCommand(const cmMakefile* mf) const else if ( generator == "MinGW Makefiles" || generator == "Unix Makefiles" ) { - cmOStringStream ss; + std::ostringstream ss; ss << make << " -j " << this->CpuCount; buildCommand = ss.str(); } @@ -482,7 +482,7 @@ cmExtraCodeLiteGenerator::GetSingleFileBuildCommand std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR"); if ( generator == "Unix Makefiles" || generator == "MinGW Makefiles" ) { - cmOStringStream ss; + std::ostringstream ss; ss << make << " -f$(ProjectPath)/Makefile $(CurrentFileName).cpp.o"; buildCommand = ss.str(); } diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 2f69882..d64b0d7 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -62,6 +62,7 @@ void cmExtraEclipseCDT4Generator if (*lit == "CXX") { this->Natures.insert("org.eclipse.cdt.core.ccnature"); + this->Natures.insert("org.eclipse.cdt.core.cnature"); } else if (*lit == "C") { @@ -1179,7 +1180,7 @@ std::string cmExtraEclipseCDT4Generator::GetPathBasename(const std::string& path) { std::string outputBasename = path; - while (outputBasename.size() > 0 && + while (!outputBasename.empty() && (outputBasename[outputBasename.size() - 1] == '/' || outputBasename[outputBasename.size() - 1] == '\\')) { diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx index 567542e..9645d0e 100644 --- a/Source/cmExtraKateGenerator.cxx +++ b/Source/cmExtraKateGenerator.cxx @@ -334,7 +334,7 @@ std::string cmExtraKateGenerator::GenerateProjectName(const std::string& name, std::string cmExtraKateGenerator::GetPathBasename(const std::string& path)const { std::string outputBasename = path; - while (outputBasename.size() > 0 && + while (!outputBasename.empty() && (outputBasename[outputBasename.size() - 1] == '/' || outputBasename[outputBasename.size() - 1] == '\\')) { diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 7ebd750..2c92db2 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -21,6 +21,7 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cm_curl.h" +#include "cmFileLockResult.h" #endif #undef GetCurrentDirectory @@ -33,6 +34,7 @@ #include <cmsys/Glob.hxx> #include <cmsys/RegularExpression.hxx> #include <cmsys/FStream.hxx> +#include <cmsys/Encoding.hxx> // Table of permissions flags. #if defined(_WIN32) && !defined(__CYGWIN__) @@ -61,6 +63,35 @@ static mode_t mode_setuid = S_ISUID; static mode_t mode_setgid = S_ISGID; #endif +#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) +// libcurl doesn't support file:// urls for unicode filenames on Windows. +// Convert string from UTF-8 to ACP if this is a file:// URL. +static std::string fix_file_url_windows(const std::string& url) +{ + std::string ret = url; + if(strncmp(url.c_str(), "file://", 7) == 0) + { + cmsys_stl::wstring wurl = cmsys::Encoding::ToWide(url); + if(!wurl.empty()) + { + int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, + NULL, 0, NULL, NULL); + if(mblen > 0) + { + std::vector<char> chars(mblen); + mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, + &chars[0], mblen, NULL, NULL); + if(mblen > 0) + { + ret = &chars[0]; + } + } + } + } + return ret; +} +#endif + // cmLibraryCommand bool cmFileCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) @@ -172,6 +203,10 @@ bool cmFileCommand { return this->HandleGenerateCommand(args); } + else if ( subCommand == "LOCK" ) + { + return this->HandleLockCommand(args); + } std::string e = "does not recognize sub-command "+subCommand; this->SetError(e); @@ -301,14 +336,14 @@ bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args) // is there a limit? long sizeLimit = -1; - if (limitArg.GetString().size() > 0) + if (!limitArg.GetString().empty()) { sizeLimit = atoi(limitArg.GetCString()); } // is there an offset? long offset = 0; - if (offsetArg.GetString().size() > 0) + if (!offsetArg.GetString().empty()) { offset = atoi(offsetArg.GetCString()); } @@ -369,7 +404,7 @@ bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args) #if defined(CMAKE_BUILD_WITH_CMAKE) if(args.size() != 3) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " requires a file name and output variable"; this->SetError(e.str()); return false; @@ -384,14 +419,14 @@ bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args) this->Makefile->AddDefinition(args[2], out.c_str()); return true; } - cmOStringStream e; + std::ostringstream e; e << args[0] << " failed to read file \"" << args[1] << "\": " << cmSystemTools::GetLastSystemError(); this->SetError(e.str()); } return false; #else - cmOStringStream e; + std::ostringstream e; e << args[0] << " not available during bootstrap"; this->SetError(e.str().c_str()); return false; @@ -484,7 +519,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) if(sscanf(args[i].c_str(), "%d", &limit_input) != 1 || limit_input < 0) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option LIMIT_INPUT value \"" << args[i] << "\" is not an unsigned integer."; this->SetError(e.str()); @@ -497,7 +532,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) if(sscanf(args[i].c_str(), "%d", &limit_output) != 1 || limit_output < 0) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option LIMIT_OUTPUT value \"" << args[i] << "\" is not an unsigned integer."; this->SetError(e.str()); @@ -510,7 +545,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) int count; if(sscanf(args[i].c_str(), "%d", &count) != 1 || count < 0) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option LIMIT_COUNT value \"" << args[i] << "\" is not an unsigned integer."; this->SetError(e.str()); @@ -524,7 +559,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) int len; if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option LENGTH_MINIMUM value \"" << args[i] << "\" is not an unsigned integer."; this->SetError(e.str()); @@ -538,7 +573,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) int len; if(sscanf(args[i].c_str(), "%d", &len) != 1 || len < 0) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option LENGTH_MAXIMUM value \"" << args[i] << "\" is not an unsigned integer."; this->SetError(e.str()); @@ -551,7 +586,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) { if(!regex.compile(args[i].c_str())) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option REGEX value \"" << args[i] << "\" could not be compiled."; this->SetError(e.str()); @@ -568,7 +603,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "STRINGS option ENCODING \"" << args[i] << "\" not recognized."; this->SetError(e.str()); @@ -578,7 +613,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "STRINGS given unknown argument \"" << args[i] << "\""; this->SetError(e.str()); @@ -606,7 +641,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) #endif if(!fin) { - cmOStringStream e; + std::ostringstream e; e << "STRINGS file \"" << fileName << "\" cannot be read."; this->SetError(e.str()); return false; @@ -710,7 +745,7 @@ bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args) // A non-string character has been found. Check if the current // string matches the requirements. We require that the length // be at least one no matter what the user specified. - if(s.length() >= minlen && s.length() >= 1 && + if(s.length() >= minlen && !s.empty() && (!have_regex || regex.find(s.c_str()))) { output_size += static_cast<int>(s.size()) + 1; @@ -864,7 +899,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, { std::string expr = this->Makefile->GetCurrentDirectory(); // Handle script mode - if ( expr.size() > 0 ) + if (!expr.empty()) { expr += "/" + *i; g.FindFiles(expr); @@ -1002,7 +1037,7 @@ cmFileCommand::HandleDifferentCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "DIFFERENT given unknown argument " << args[i]; this->SetError(e.str()); return false; @@ -1117,7 +1152,7 @@ protected: { if(permissions && !cmSystemTools::SetPermissions(toFile, permissions)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot set permissions on \"" << toFile << "\""; this->FileCommand->SetError(e.str()); return false; @@ -1141,7 +1176,7 @@ protected: else if(arg == "SETGID") { permissions |= mode_setgid; } else { - cmOStringStream e; + std::ostringstream e; e << this->Name << " given invalid permission \"" << arg << "\"."; this->FileCommand->SetError(e.str()); return false; @@ -1168,7 +1203,7 @@ protected: virtual bool ReportMissing(const char* fromFile) { // The input file does not exist and installation is not optional. - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot find \"" << fromFile << "\"."; this->FileCommand->SetError(e.str()); return false; @@ -1201,14 +1236,14 @@ protected: void NotBeforeMatch(std::string const& arg) { - cmOStringStream e; + std::ostringstream e; e << "option " << arg << " may not appear before PATTERN or REGEX."; this->FileCommand->SetError(e.str()); this->Doing = DoingError; } void NotAfterMatch(std::string const& arg) { - cmOStringStream e; + std::ostringstream e; e << "option " << arg << " may not appear after PATTERN or REGEX."; this->FileCommand->SetError(e.str()); this->Doing = DoingError; @@ -1246,7 +1281,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args) if(!this->CheckKeyword(args[i]) && !this->CheckValue(args[i])) { - cmOStringStream e; + std::ostringstream e; e << "called with unknown argument \"" << args[i] << "\"."; this->FileCommand->SetError(e.str()); return false; @@ -1262,7 +1297,7 @@ bool cmFileCopier::Parse(std::vector<std::string> const& args) // Require a destination. if(this->Destination.empty()) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " given no DESTINATION"; this->FileCommand->SetError(e.str()); return false; @@ -1442,7 +1477,7 @@ bool cmFileCopier::CheckValue(std::string const& arg) } else { - cmOStringStream e; + std::ostringstream e; e << "could not compile PATTERN \"" << arg << "\"."; this->FileCommand->SetError(e.str()); this->Doing = DoingError; @@ -1458,7 +1493,7 @@ bool cmFileCopier::CheckValue(std::string const& arg) } else { - cmOStringStream e; + std::ostringstream e; e << "could not compile REGEX \"" << arg << "\"."; this->FileCommand->SetError(e.str()); this->Doing = DoingError; @@ -1538,7 +1573,7 @@ bool cmFileCopier::Install(const char* fromFile, const char* toFile) { if(!*fromFile) { - cmOStringStream e; + std::ostringstream e; e << "INSTALL encountered an empty string input file name."; this->FileCommand->SetError(e.str()); return false; @@ -1579,7 +1614,7 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile) std::string symlinkTarget; if(!cmSystemTools::ReadSymlink(fromFile, symlinkTarget)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot read symlink \"" << fromFile << "\" to duplicate at \"" << toFile << "\"."; this->FileCommand->SetError(e.str()); @@ -1610,9 +1645,9 @@ bool cmFileCopier::InstallSymlink(const char* fromFile, const char* toFile) cmSystemTools::RemoveFile(toFile); // Create the symlink. - if(!cmSystemTools::CreateSymlink(symlinkTarget.c_str(), toFile)) + if(!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot duplicate symlink \"" << fromFile << "\" at \"" << toFile << "\"."; this->FileCommand->SetError(e.str()); @@ -1644,7 +1679,7 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile, // Copy the file. if(copy && !cmSystemTools::CopyAFile(fromFile, toFile, true)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot copy file \"" << fromFile << "\" to \"" << toFile << "\"."; this->FileCommand->SetError(e.str()); @@ -1663,7 +1698,7 @@ bool cmFileCopier::InstallFile(const char* fromFile, const char* toFile, } if (!cmSystemTools::CopyFileTime(fromFile, toFile)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot set modification time on \"" << toFile << "\""; this->FileCommand->SetError(e.str()); @@ -1695,7 +1730,7 @@ bool cmFileCopier::InstallDirectory(const char* source, // Make sure the destination directory exists. if(!cmSystemTools::MakeDirectory(destination)) { - cmOStringStream e; + std::ostringstream e; e << this->Name << " cannot make directory \"" << destination << "\": " << cmSystemTools::GetLastSystemError(); this->FileCommand->SetError(e.str()); @@ -2040,7 +2075,7 @@ bool cmFileInstaller::CheckKeyword(std::string const& arg) else if(arg == "COMPONENTS" || arg == "CONFIGURATIONS" || arg == "PROPERTIES") { - cmOStringStream e; + std::ostringstream e; e << "INSTALL called with old-style " << arg << " argument. " << "This script was generated with an older version of CMake. " << "Re-run this cmake version on your build tree."; @@ -2108,7 +2143,7 @@ bool cmFileInstaller } else { - cmOStringStream e; + std::ostringstream e; e << "Option TYPE given unknown value \"" << stype << "\"."; this->FileCommand->SetError(e.str()); return false; @@ -2253,7 +2288,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "RPATH_CHANGE given unknown argument " << args[i]; this->SetError(e.str()); return false; @@ -2276,7 +2311,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args) } if(!cmSystemTools::FileExists(file, true)) { - cmOStringStream e; + std::ostringstream e; e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist."; this->SetError(e.str()); return false; @@ -2288,7 +2323,7 @@ cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args) bool changed; if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed)) { - cmOStringStream e; + std::ostringstream e; e << "RPATH_CHANGE could not write new RPATH:\n" << " " << newRPath << "\n" << "to the file:\n" @@ -2338,7 +2373,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "RPATH_REMOVE given unknown argument " << args[i]; this->SetError(e.str()); return false; @@ -2351,7 +2386,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args) } if(!cmSystemTools::FileExists(file, true)) { - cmOStringStream e; + std::ostringstream e; e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist."; this->SetError(e.str()); return false; @@ -2363,7 +2398,7 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args) bool removed; if(!cmSystemTools::RemoveRPath(file, &emsg, &removed)) { - cmOStringStream e; + std::ostringstream e; e << "RPATH_REMOVE could not remove RPATH from file:\n" << " " << file << "\n" << emsg; @@ -2419,7 +2454,7 @@ cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "RPATH_CHECK given unknown argument " << args[i]; this->SetError(e.str()); return false; @@ -2520,7 +2555,7 @@ bool cmFileCommand::HandleRename(std::vector<std::string> const& args) if(!cmSystemTools::RenameFile(oldname.c_str(), newname.c_str())) { std::string err = cmSystemTools::GetLastSystemError(); - cmOStringStream e; + std::ostringstream e; e << "RENAME failed to rename\n" << " " << oldname << "\n" << "to\n" @@ -2687,7 +2722,7 @@ namespace { if (updated) { - cmOStringStream oss; + std::ostringstream oss; oss << "[" << this->Text << " " << this->CurrentPercentage << "% complete]"; status = oss.str(); @@ -2957,9 +2992,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) msg = "returning early; file already exists with expected "; msg += hashMatchMSG; msg += "\""; - if(statusVar.size()) + if(!statusVar.empty()) { - cmOStringStream result; + std::ostringstream result; result << (int)0 << ";\"" << msg; this->Makefile->AddDefinition(statusVar, result.str().c_str()); @@ -2988,6 +3023,10 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) return false; } +#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) + url = fix_file_url_windows(url); +#endif + ::CURL *curl; ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); @@ -3046,7 +3085,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); check_curl_result(res, "DOWNLOAD cannot set follow-redirect option: "); - if(verboseLog.size()) + if(!verboseLog.empty()) { res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); check_curl_result(res, "DOWNLOAD cannot set verbose: "); @@ -3092,9 +3131,9 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) g_curl.release(); ::curl_easy_cleanup(curl); - if(statusVar.size()) + if(!statusVar.empty()) { - cmOStringStream result; + std::ostringstream result; result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\""; this->Makefile->AddDefinition(statusVar, result.str().c_str()); @@ -3112,7 +3151,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (hash.get()) { std::string actualHash = hash->HashFile(file); - if (actualHash.size() == 0) + if (actualHash.empty()) { this->SetError("DOWNLOAD cannot compute hash on downloaded file"); return false; @@ -3120,7 +3159,7 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) if (expectedHash != actualHash) { - cmOStringStream oss; + std::ostringstream oss; oss << "DOWNLOAD HASH mismatch" << std::endl << " for file: [" << file << "]" << std::endl << " expected hash: [" << expectedHash << "]" << std::endl @@ -3133,14 +3172,14 @@ cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args) } } - if(chunkDebug.size()) + if(!chunkDebug.empty()) { chunkDebug.push_back(0); if(CURLE_OPERATION_TIMEOUTED == res) { std::string output = &*chunkDebug.begin(); - if(verboseLog.size()) + if(!verboseLog.empty()) { this->Makefile->AddDefinition(verboseLog, &*chunkDebug.begin()); @@ -3248,7 +3287,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) return false; } - unsigned long file_size = cmsys::SystemTools::FileLength(filename.c_str()); + unsigned long file_size = cmsys::SystemTools::FileLength(filename); + +#if defined(WIN32) && defined(CMAKE_ENCODING_UTF8) + url = fix_file_url_windows(url); +#endif ::CURL *curl; ::curl_global_init(CURL_GLOBAL_DEFAULT); @@ -3292,7 +3335,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) res = ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); check_curl_result(res, "UPLOAD cannot set follow-redirect option: "); - if(logVar.size()) + if(!logVar.empty()) { res = ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); check_curl_result(res, "UPLOAD cannot set verbose: "); @@ -3347,9 +3390,9 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) g_curl.release(); ::curl_easy_cleanup(curl); - if(statusVar.size()) + if(!statusVar.empty()) { - cmOStringStream result; + std::ostringstream result; result << (int)res << ";\"" << ::curl_easy_strerror(res) << "\""; this->Makefile->AddDefinition(statusVar, result.str().c_str()); @@ -3360,11 +3403,11 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) fclose(fin); fin = NULL; - if(logVar.size()) + if(!logVar.empty()) { std::string log; - if(chunkResponse.size()) + if(!chunkResponse.empty()) { chunkResponse.push_back(0); log += "Response:\n"; @@ -3372,7 +3415,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) log += "\n"; } - if(chunkDebug.size()) + if(!chunkDebug.empty()) { chunkDebug.push_back(0); log += "Debug:\n"; @@ -3464,6 +3507,205 @@ bool cmFileCommand::HandleGenerateCommand( } //---------------------------------------------------------------------------- +bool cmFileCommand::HandleLockCommand( + std::vector<std::string> const& args) +{ +#if defined(CMAKE_BUILD_WITH_CMAKE) + // Default values + bool directory = false; + bool release = false; + enum Guard { + GUARD_FUNCTION, + GUARD_FILE, + GUARD_PROCESS + }; + Guard guard = GUARD_PROCESS; + std::string resultVariable; + unsigned long timeout = static_cast<unsigned long>(-1); + + // Parse arguments + if(args.size() < 2) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "sub-command LOCK requires at least two arguments."); + return false; + } + + std::string path = args[1]; + for (unsigned i = 2; i < args.size(); ++i) + { + if (args[i] == "DIRECTORY") + { + directory = true; + } + else if (args[i] == "RELEASE") + { + release = true; + } + else if (args[i] == "GUARD") + { + ++i; + const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD"; + if (i >= args.size()) + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, merr); + return false; + } + else + { + if (args[i] == "FUNCTION") + { + guard = GUARD_FUNCTION; + } + else if (args[i] == "FILE") + { + guard = GUARD_FILE; + } + else if (args[i] == "PROCESS") + { + guard = GUARD_PROCESS; + } + else + { + std::ostringstream e; + e << merr << ", but got:\n \"" << args[i] << "\"."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + } + } + else if (args[i] == "RESULT_VARIABLE") + { + ++i; + if (i >= args.size()) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "expected variable name after RESULT_VARIABLE"); + return false; + } + resultVariable = args[i]; + } + else if (args[i] == "TIMEOUT") + { + ++i; + if (i >= args.size()) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "expected timeout value after TIMEOUT"); + return false; + } + long scanned; + if(!cmSystemTools::StringToLong(args[i].c_str(), &scanned) + || scanned < 0) + { + std::ostringstream e; + e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + timeout = static_cast<unsigned long>(scanned); + } + else + { + std::ostringstream e; + e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n"; + e << "but got: \"" << args[i] << "\"."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + } + + if (directory) + { + path += "/cmake.lock"; + } + + if (!cmsys::SystemTools::FileIsFullPath(path)) + { + path = this->Makefile->GetCurrentDirectory() + ("/" + path); + } + + // Unify path (remove '//', '/../', ...) + path = cmSystemTools::CollapseFullPath(path); + + // Create file and directories if needed + std::string parentDir = cmSystemTools::GetParentDirectory(path); + if (!cmSystemTools::MakeDirectory(parentDir)) + { + std::ostringstream e; + e << "directory\n \"" << parentDir << "\"\ncreation failed "; + e << "(check permissions)."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + FILE *file = cmsys::SystemTools::Fopen(path, "w"); + if (!file) + { + std::ostringstream e; + e << "file\n \"" << path << "\"\ncreation failed (check permissions)."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + fclose(file); + + // Actual lock/unlock + cmFileLockPool& lockPool = this->Makefile->GetLocalGenerator()-> + GetGlobalGenerator()->GetFileLockPool(); + + cmFileLockResult fileLockResult(cmFileLockResult::MakeOk()); + if (release) + { + fileLockResult = lockPool.Release(path); + } + else + { + switch (guard) + { + case GUARD_FUNCTION: + fileLockResult = lockPool.LockFunctionScope(path, timeout); + break; + case GUARD_FILE: + fileLockResult = lockPool.LockFileScope(path, timeout); + break; + case GUARD_PROCESS: + fileLockResult = lockPool.LockProcessScope(path, timeout); + break; + default: + cmSystemTools::SetFatalErrorOccured(); + return false; + } + } + + const std::string result = fileLockResult.GetOutputMessage(); + + if (resultVariable.empty() && !fileLockResult.IsOk()) + { + std::ostringstream e; + e << "error locking file\n \"" << path << "\"\n" << result << "."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + return false; + } + + if (!resultVariable.empty()) + { + this->Makefile->AddDefinition(resultVariable, result.c_str()); + } + + return true; +#else + static_cast<void>(args); + this->SetError("sub-command LOCK not implemented in bootstrap cmake"); + return false; +#endif +} + +//---------------------------------------------------------------------------- bool cmFileCommand::HandleTimestampCommand( std::vector<std::string> const& args) { diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 8d66fdf..a4d341f 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -75,6 +75,7 @@ protected: bool HandleTimestampCommand(std::vector<std::string> const& args); bool HandleGenerateCommand(std::vector<std::string> const& args); + bool HandleLockCommand(std::vector<std::string> const& args); private: void AddEvaluationFile(const std::string &inputName, diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx new file mode 100644 index 0000000..e6aa5f4 --- /dev/null +++ b/Source/cmFileLock.cxx @@ -0,0 +1,78 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLock.h" + +#include <assert.h> +#include "cmFileLockResult.h" + +// Common implementation + +cmFileLock::~cmFileLock() +{ + if (!this->Filename.empty()) + { + const cmFileLockResult result = this->Release(); + static_cast<void>(result); + assert(result.IsOk()); + } +} + +cmFileLockResult cmFileLock::Lock( + const std::string& filename, unsigned long timeout) +{ + if (filename.empty()) + { + // Error is internal since all the directories and file must be created + // before actual lock called. + return cmFileLockResult::MakeInternal(); + } + + if (!this->Filename.empty()) + { + // Error is internal since double-lock must be checked in class + // cmFileLockPool by the cmFileLock::IsLocked method. + return cmFileLockResult::MakeInternal(); + } + + this->Filename = filename; + cmFileLockResult result = this->OpenFile(); + if (result.IsOk()) + { + if (timeout == static_cast<unsigned long>(-1)) + { + result = this->LockWithoutTimeout(); + } + else + { + result = this->LockWithTimeout(timeout); + } + } + + if (!result.IsOk()) + { + this->Filename = ""; + } + + return result; +} + +bool cmFileLock::IsLocked(const std::string& filename) const +{ + return filename == this->Filename; +} + +#if defined(_WIN32) +# include "cmFileLockWin32.cxx" +#else +# include "cmFileLockUnix.cxx" +#endif diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h new file mode 100644 index 0000000..dd959a7 --- /dev/null +++ b/Source/cmFileLock.h @@ -0,0 +1,74 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmFileLock_h +#define cmFileLock_h + +#include "cmStandardIncludes.h" + +#if defined(_WIN32) +# include <windows.h> // HANDLE +#endif + +class cmFileLockResult; + +/** + * @brief Cross-platform file locking. + * @details Under the hood this class use 'fcntl' for Unix-like platforms and + * 'LockFileEx'/'UnlockFileEx' for Win32 platform. Locks are exclusive and + * advisory. + */ +class cmFileLock +{ + public: + cmFileLock(); + ~cmFileLock(); + + /** + * @brief Lock the file. + * @param timeoutSec Lock timeout. If -1 try until success or fatal error. + */ + cmFileLockResult Lock(const std::string& filename, unsigned long timeoutSec); + + /** + * @brief Unlock the file. + */ + cmFileLockResult Release(); + + /** + * @brief Check file is locked by this class. + * @details This function helps to find double locks (deadlocks) and to do + * explicit unlocks. + */ + bool IsLocked(const std::string& filename) const; + + private: + cmFileLock(const cmFileLock&); + cmFileLock& operator=(const cmFileLock&); + + cmFileLockResult OpenFile(); + cmFileLockResult LockWithoutTimeout(); + cmFileLockResult LockWithTimeout(unsigned long timeoutSec); + +#if defined(_WIN32) + typedef HANDLE FileId; + BOOL LockFile(DWORD flags); +#else + typedef int FileId; + int LockFile(int cmd, int type); +#endif + + FileId File; + std::string Filename; +}; + +#endif // cmFileLock_h diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx new file mode 100644 index 0000000..cf8e9a9 --- /dev/null +++ b/Source/cmFileLockPool.cxx @@ -0,0 +1,187 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLockPool.h" + +#include <assert.h> + +#include "cmFileLock.h" +#include "cmFileLockResult.h" + +cmFileLockPool::cmFileLockPool() +{ +} + +cmFileLockPool::~cmFileLockPool() +{ + cmDeleteAll(this->FunctionScopes); + cmDeleteAll(this->FileScopes); +} + +void cmFileLockPool::PushFunctionScope() +{ + this->FunctionScopes.push_back(new ScopePool()); +} + +void cmFileLockPool::PopFunctionScope() +{ + assert(!this->FunctionScopes.empty()); + delete this->FunctionScopes.back(); + this->FunctionScopes.pop_back(); +} + +void cmFileLockPool::PushFileScope() +{ + this->FileScopes.push_back(new ScopePool()); +} + +void cmFileLockPool::PopFileScope() +{ + assert(!this->FileScopes.empty()); + delete this->FileScopes.back(); + this->FileScopes.pop_back(); +} + +cmFileLockResult cmFileLockPool::LockFunctionScope( + const std::string& filename, unsigned long timeoutSec) +{ + if (this->IsAlreadyLocked(filename)) + { + return cmFileLockResult::MakeAlreadyLocked(); + } + if (this->FunctionScopes.empty()) + { + return cmFileLockResult::MakeNoFunction(); + } + return this->FunctionScopes.back()->Lock(filename, timeoutSec); +} + +cmFileLockResult cmFileLockPool::LockFileScope( + const std::string& filename, unsigned long timeoutSec) +{ + if (this->IsAlreadyLocked(filename)) + { + return cmFileLockResult::MakeAlreadyLocked(); + } + assert(!this->FileScopes.empty()); + return this->FileScopes.back()->Lock(filename, timeoutSec); +} + +cmFileLockResult cmFileLockPool::LockProcessScope( + const std::string& filename, unsigned long timeoutSec) +{ + if (this->IsAlreadyLocked(filename)) + { + return cmFileLockResult::MakeAlreadyLocked(); + } + return this->ProcessScope.Lock(filename, timeoutSec); +} + +cmFileLockResult cmFileLockPool::Release(const std::string& filename) +{ + for (It i = this->FunctionScopes.begin(); + i != this->FunctionScopes.end(); ++i) + { + const cmFileLockResult result = (*i)->Release(filename); + if (!result.IsOk()) + { + return result; + } + } + + for (It i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i) + { + const cmFileLockResult result = (*i)->Release(filename); + if (!result.IsOk()) + { + return result; + } + } + + return this->ProcessScope.Release(filename); +} + +bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const +{ + for (CIt i = this->FunctionScopes.begin(); + i != this->FunctionScopes.end(); ++i) + { + const bool result = (*i)->IsAlreadyLocked(filename); + if (result) + { + return true; + } + } + + for (CIt i = this->FileScopes.begin(); i != this->FileScopes.end(); ++i) + { + const bool result = (*i)->IsAlreadyLocked(filename); + if (result) + { + return true; + } + } + + return this->ProcessScope.IsAlreadyLocked(filename); +} + +cmFileLockPool::ScopePool::ScopePool() +{ +} + +cmFileLockPool::ScopePool::~ScopePool() +{ + cmDeleteAll(this->Locks); +} + +cmFileLockResult cmFileLockPool::ScopePool::Lock( + const std::string& filename, unsigned long timeoutSec) +{ + cmFileLock *lock = new cmFileLock(); + const cmFileLockResult result = lock->Lock(filename, timeoutSec); + if (result.IsOk()) + { + this->Locks.push_back(lock); + return cmFileLockResult::MakeOk(); + } + else + { + delete lock; + return result; + } +} + +cmFileLockResult cmFileLockPool::ScopePool::Release( + const std::string& filename) +{ + for (It i = this->Locks.begin(); i != this->Locks.end(); ++i) + { + if ((*i)->IsLocked(filename)) + { + return (*i)->Release(); + } + } + return cmFileLockResult::MakeOk(); +} + +bool cmFileLockPool::ScopePool::IsAlreadyLocked( + const std::string& filename) const +{ + for (CIt i = this->Locks.begin(); i != this->Locks.end(); ++i) + { + if ((*i)->IsLocked(filename)) + { + return true; + } + } + return false; +} diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h new file mode 100644 index 0000000..baef310 --- /dev/null +++ b/Source/cmFileLockPool.h @@ -0,0 +1,102 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmFileLockPool_h +#define cmFileLockPool_h + +#include "cmStandardIncludes.h" + +class cmFileLockResult; +class cmFileLock; + +class cmFileLockPool +{ + public: + cmFileLockPool(); + ~cmFileLockPool(); + + //@{ + /** + * @brief Function scope control. + */ + void PushFunctionScope(); + void PopFunctionScope(); + //@} + + //@{ + /** + * @brief File scope control. + */ + void PushFileScope(); + void PopFileScope(); + //@} + + //@{ + /** + * @brief Lock the file in given scope. + * @param timeoutSec Lock timeout. If -1 try until success or fatal error. + */ + cmFileLockResult LockFunctionScope( + const std::string& filename, unsigned long timeoutSec + ); + cmFileLockResult LockFileScope( + const std::string& filename, unsigned long timeoutSec + ); + cmFileLockResult LockProcessScope( + const std::string& filename, unsigned long timeoutSec + ); + //@} + + /** + * @brief Unlock the file explicitly. + */ + cmFileLockResult Release(const std::string& filename); + + private: + cmFileLockPool(const cmFileLockPool&); + cmFileLockPool& operator=(const cmFileLockPool&); + + bool IsAlreadyLocked(const std::string& filename) const; + + class ScopePool + { + public: + ScopePool(); + ~ScopePool(); + + cmFileLockResult Lock( + const std::string& filename, unsigned long timeoutSec + ); + cmFileLockResult Release(const std::string& filename); + bool IsAlreadyLocked(const std::string& filename) const; + + private: + ScopePool(const ScopePool&); + ScopePool& operator=(const ScopePool&); + + typedef std::list<cmFileLock*> List; + typedef List::iterator It; + typedef List::const_iterator CIt; + + List Locks; + }; + + typedef std::list<ScopePool*> List; + + typedef List::iterator It; + typedef List::const_iterator CIt; + + List FunctionScopes; + List FileScopes; + ScopePool ProcessScope; +}; + +#endif // cmFileLockPool_h diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx new file mode 100644 index 0000000..045e7ee --- /dev/null +++ b/Source/cmFileLockResult.cxx @@ -0,0 +1,111 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLockResult.h" + +#include <errno.h> + +cmFileLockResult cmFileLockResult::MakeOk() +{ + return cmFileLockResult(OK, 0); +} + +cmFileLockResult cmFileLockResult::MakeSystem() +{ +#if defined(_WIN32) + const Error lastError = GetLastError(); +#else + const Error lastError = errno; +#endif + return cmFileLockResult(SYSTEM, lastError); +} + +cmFileLockResult cmFileLockResult::MakeTimeout() +{ + return cmFileLockResult(TIMEOUT, 0); +} + +cmFileLockResult cmFileLockResult::MakeAlreadyLocked() +{ + return cmFileLockResult(ALREADY_LOCKED, 0); +} + +cmFileLockResult cmFileLockResult::MakeInternal() +{ + return cmFileLockResult(INTERNAL, 0); +} + +cmFileLockResult cmFileLockResult::MakeNoFunction() +{ + return cmFileLockResult(NO_FUNCTION, 0); +} + +bool cmFileLockResult::IsOk() const +{ + return this->Type == OK; +} + +std::string cmFileLockResult::GetOutputMessage() const +{ + switch (this->Type) + { + case OK: + return "0"; + case SYSTEM: +#if defined(_WIN32) + { + char* errorText = NULL; + + // http://stackoverflow.com/a/455533/2288008 + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_IGNORE_INSERTS; + ::FormatMessageA( + flags, + NULL, + this->ErrorValue, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&errorText, + 0, + NULL + ); + + if (errorText != NULL) + { + const std::string message = errorText; + ::LocalFree(errorText); + return message; + } + else + { + return "Internal error (FormatMessageA failed)"; + } + } +#else + return strerror(this->ErrorValue); +#endif + case TIMEOUT: + return "Timeout reached"; + case ALREADY_LOCKED: + return "File already locked"; + case NO_FUNCTION: + return "'GUARD FUNCTION' not used in function definition"; + case INTERNAL: + default: + return "Internal error"; + } +} + +cmFileLockResult::cmFileLockResult(ErrorType typeValue, Error errorValue): + Type(typeValue), ErrorValue(errorValue) +{ +} diff --git a/Source/cmFileLockResult.h b/Source/cmFileLockResult.h new file mode 100644 index 0000000..531fb49 --- /dev/null +++ b/Source/cmFileLockResult.h @@ -0,0 +1,85 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmFileLockResult_h +#define cmFileLockResult_h + +#include "cmStandardIncludes.h" + +#if defined(_WIN32) +# include <windows.h> // DWORD +#endif + +/** + * @brief Result of the locking/unlocking file. + * @note See @c cmFileLock + */ +class cmFileLockResult +{ + public: +#if defined(_WIN32) + typedef DWORD Error; +#else + typedef int Error; +#endif + + /** + * @brief Successful lock/unlock. + */ + static cmFileLockResult MakeOk(); + + /** + * @brief Lock/Unlock failed. Read error/GetLastError. + */ + static cmFileLockResult MakeSystem(); + + /** + * @brief Lock/Unlock failed. Timeout reached. + */ + static cmFileLockResult MakeTimeout(); + + /** + * @brief File already locked. + */ + static cmFileLockResult MakeAlreadyLocked(); + + /** + * @brief Internal error. + */ + static cmFileLockResult MakeInternal(); + + /** + * @brief Try to lock with function guard outside of the function + */ + static cmFileLockResult MakeNoFunction(); + + bool IsOk() const; + std::string GetOutputMessage() const; + + private: + enum ErrorType + { + OK, + SYSTEM, + TIMEOUT, + ALREADY_LOCKED, + INTERNAL, + NO_FUNCTION + }; + + cmFileLockResult(ErrorType type, Error errorValue); + + ErrorType Type; + Error ErrorValue; +}; + +#endif // cmFileLockResult_h diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx new file mode 100644 index 0000000..fc18a64 --- /dev/null +++ b/Source/cmFileLockUnix.cxx @@ -0,0 +1,102 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLock.h" + +#include <errno.h> // errno +#include <stdio.h> // SEEK_SET +#include <fcntl.h> +#include "cmSystemTools.h" + +cmFileLock::cmFileLock(): File(-1) +{ +} + +cmFileLockResult cmFileLock::Release() +{ + if (this->Filename.empty()) + { + return cmFileLockResult::MakeOk(); + } + const int lockResult = this->LockFile(F_SETLK, F_UNLCK); + + this->Filename = ""; + + if (lockResult == 0) + { + return cmFileLockResult::MakeOk(); + } + else + { + return cmFileLockResult::MakeSystem(); + } +} + +cmFileLockResult cmFileLock::OpenFile() +{ + this->File = ::open(this->Filename.c_str(), O_RDWR); + if (this->File == -1) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithoutTimeout() +{ + if (this->LockFile(F_SETLKW, F_WRLCK) == -1) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds) +{ + while (true) + { + if (this->LockFile(F_SETLK, F_WRLCK) == -1) + { + if (errno != EACCES && errno != EAGAIN) + { + return cmFileLockResult::MakeSystem(); + } + } + else + { + return cmFileLockResult::MakeOk(); + } + if (seconds == 0) + { + return cmFileLockResult::MakeTimeout(); + } + --seconds; + cmSystemTools::Delay(1000); + } +} + +int cmFileLock::LockFile(int cmd, int type) +{ + struct ::flock lock; + lock.l_start = 0; + lock.l_len = 0; // lock all bytes + lock.l_pid = 0; // unused (for F_GETLK only) + lock.l_type = static_cast<short>(type); // exclusive lock + lock.l_whence = SEEK_SET; + return ::fcntl(this->File, cmd, &lock); +} diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx new file mode 100644 index 0000000..4691689 --- /dev/null +++ b/Source/cmFileLockWin32.cxx @@ -0,0 +1,126 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLock.h" + +#include <windows.h> // CreateFileW +#include "cmSystemTools.h" + +cmFileLock::cmFileLock(): File(INVALID_HANDLE_VALUE) +{ +} + +cmFileLockResult cmFileLock::Release() +{ + if (this->Filename.empty()) + { + return cmFileLockResult::MakeOk(); + } + const unsigned long len = static_cast<unsigned long>(-1); + static OVERLAPPED overlapped; + const DWORD reserved = 0; + const BOOL unlockResult = UnlockFileEx( + File, + reserved, + len, + len, + &overlapped + ); + + this->Filename = ""; + + if (unlockResult) + { + return cmFileLockResult::MakeOk(); + } + else + { + return cmFileLockResult::MakeSystem(); + } +} + +cmFileLockResult cmFileLock::OpenFile() +{ + const DWORD access = GENERIC_READ | GENERIC_WRITE; + const DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + const PSECURITY_ATTRIBUTES security = NULL; + const DWORD attr = 0; + const HANDLE templ = NULL; + this->File = CreateFileW( + cmSystemTools::ConvertToWindowsExtendedPath(this->Filename).c_str(), + access, + shareMode, + security, + OPEN_EXISTING, + attr, + templ + ); + if (this->File == INVALID_HANDLE_VALUE) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithoutTimeout() +{ + if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK)) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds) +{ + const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; + while (true) + { + const BOOL result = this->LockFile(flags); + if (result) + { + return cmFileLockResult::MakeOk(); + } + const DWORD error = GetLastError(); + if (error != ERROR_LOCK_VIOLATION) + { + return cmFileLockResult::MakeSystem(); + } + if (seconds == 0) + { + return cmFileLockResult::MakeTimeout(); + } + --seconds; + cmSystemTools::Delay(1000); + } +} + +BOOL cmFileLock::LockFile(DWORD flags) +{ + const DWORD reserved = 0; + const unsigned long len = static_cast<unsigned long>(-1); + static OVERLAPPED overlapped; + return LockFileEx( + this->File, + flags, + reserved, + len, + len, + &overlapped + ); +} diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index e4e819a..69991d5 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -140,11 +140,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } else if(doing == DoingPaths) { - this->AddUserPath(args[j], this->UserPaths); + this->UserGuessArgs.push_back(args[j]); } else if(doing == DoingHints) { - this->AddUserPath(args[j], this->UserHints); + this->UserHintsArgs.push_back(args[j]); } else if(doing == DoingPathSuffixes) { @@ -152,10 +152,10 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } } - if(this->VariableDocumentation.size() == 0) + if(this->VariableDocumentation.empty()) { this->VariableDocumentation = "Where can "; - if(this->Names.size() == 0) + if(this->Names.empty()) { this->VariableDocumentation += "the (unknown) library be found"; } @@ -184,18 +184,11 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) std::vector<std::string> shortArgs = this->Names; this->Names.clear(); // clear out any values in Names this->Names.push_back(shortArgs[0]); - for(unsigned int j = 1; j < shortArgs.size(); ++j) - { - this->AddUserPath(shortArgs[j], this->UserPaths); - } + this->UserGuessArgs.insert(this->UserGuessArgs.end(), + shortArgs.begin() + 1, shortArgs.end()); } this->ExpandPaths(); - // Filter out ignored paths from the prefix list - std::set<std::string> ignored; - this->GetIgnoredPaths(ignored); - this->FilterPaths(this->SearchPaths, ignored); - this->ComputeFinalPaths(); return true; @@ -203,226 +196,142 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) void cmFindBase::ExpandPaths() { - this->AddCMakeVariablePath(); - this->AddCMakeEnvironmentPath(); - this->AddUserHintsPath(); - this->AddSystemEnvironmentPath(); - this->AddCMakeSystemVariablePath(); - this->AddUserGuessPath(); - - // Add suffixes and clean up paths. - this->AddPathSuffixes(); -} - -//---------------------------------------------------------------------------- -void cmFindBase::AddPrefixPaths(std::vector<std::string> const& in_paths, - PathType pathType) -{ - // default for programs - std::string subdir = "bin"; - - if (this->CMakePathName == "INCLUDE") + if(!this->NoDefaultPath) { - subdir = "include"; - } - else if (this->CMakePathName == "LIBRARY") - { - subdir = "lib"; - } - else if (this->CMakePathName == "FRAMEWORK") - { - subdir = ""; // ? what to do for frameworks ? - } - - for(std::vector<std::string>::const_iterator it = in_paths.begin(); - it != in_paths.end(); ++it) - { - std::string dir = *it; - if(!subdir.empty() && !dir.empty() && dir[dir.size()-1] != '/') + if(!this->NoCMakePath) { - dir += "/"; + this->FillCMakeVariablePath(); } - if(subdir == "include" || subdir == "lib") + if(!this->NoCMakeEnvironmentPath) { - const char* arch = - this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); - if(arch && *arch) - { - this->AddPathInternal(dir+subdir+"/"+arch, pathType); - } + this->FillCMakeEnvironmentPath(); } - std::string add = dir + subdir; - if(add != "/") + if(!this->NoSystemEnvironmentPath) { - this->AddPathInternal(add, pathType); + this->FillSystemEnvironmentPath(); } - if (subdir == "bin") + if(!this->NoCMakeSystemPath) { - this->AddPathInternal(dir+"sbin", pathType); - } - if(!subdir.empty() && *it != "/") - { - this->AddPathInternal(*it, pathType); + this->FillCMakeSystemVariablePath(); } } -} -//---------------------------------------------------------------------------- -void cmFindBase::AddCMakePrefixPath(const std::string& variable) -{ - // Get a path from a CMake variable. - if(const char* varPath = this->Makefile->GetDefinition(variable)) - { - std::vector<std::string> tmp; - cmSystemTools::ExpandListArgument(varPath, tmp); - this->AddPrefixPaths(tmp, CMakePath); - } + this->FillUserHintsPath(); + this->FillUserGuessPath(); } //---------------------------------------------------------------------------- -void cmFindBase::AddEnvPrefixPath(const std::string& variable) +void cmFindBase::FillCMakeEnvironmentPath() { - // Get a path from the environment. - std::vector<std::string> tmp; - cmSystemTools::GetPath(tmp, variable.c_str()); - this->AddPrefixPaths(tmp, EnvPath); -} + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeEnvironment]; -//---------------------------------------------------------------------------- -void cmFindBase::AddCMakeEnvironmentPath() -{ - if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath) - { - // Add CMAKE_*_PATH environment variables - std::string var = "CMAKE_"; - var += this->CMakePathName; - var += "_PATH"; - this->AddEnvPrefixPath("CMAKE_PREFIX_PATH"); - this->AddEnvPath(var.c_str()); + // Add CMAKE_*_PATH environment variables + std::string var = "CMAKE_"; + var += this->CMakePathName; + var += "_PATH"; + paths.AddEnvPrefixPath("CMAKE_PREFIX_PATH"); + paths.AddEnvPath(var); - if(this->CMakePathName == "PROGRAM") - { - this->AddEnvPath("CMAKE_APPBUNDLE_PATH"); - } - else - { - this->AddEnvPath("CMAKE_FRAMEWORK_PATH"); - } + if(this->CMakePathName == "PROGRAM") + { + paths.AddEnvPath("CMAKE_APPBUNDLE_PATH"); } + else + { + paths.AddEnvPath("CMAKE_FRAMEWORK_PATH"); + } + paths.AddSuffixes(this->SearchPathSuffixes); } //---------------------------------------------------------------------------- -void cmFindBase::AddCMakeVariablePath() +void cmFindBase::FillCMakeVariablePath() { - if(!this->NoCMakePath && !this->NoDefaultPath) + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMake]; + + // Add CMake varibles of the same name as the previous environment + // varibles CMAKE_*_PATH to be used most of the time with -D + // command line options + std::string var = "CMAKE_"; + var += this->CMakePathName; + var += "_PATH"; + paths.AddCMakePrefixPath("CMAKE_PREFIX_PATH"); + paths.AddCMakePath(var); + + if(this->CMakePathName == "PROGRAM") { - // Add CMake varibles of the same name as the previous environment - // varibles CMAKE_*_PATH to be used most of the time with -D - // command line options - std::string var = "CMAKE_"; - var += this->CMakePathName; - var += "_PATH"; - this->AddCMakePrefixPath("CMAKE_PREFIX_PATH"); - this->AddCMakePath(var); - - if(this->CMakePathName == "PROGRAM") - { - this->AddCMakePath("CMAKE_APPBUNDLE_PATH"); - } - else - { - this->AddCMakePath("CMAKE_FRAMEWORK_PATH"); - } + paths.AddCMakePath("CMAKE_APPBUNDLE_PATH"); } + else + { + paths.AddCMakePath("CMAKE_FRAMEWORK_PATH"); + } + paths.AddSuffixes(this->SearchPathSuffixes); } //---------------------------------------------------------------------------- -void cmFindBase::AddSystemEnvironmentPath() +void cmFindBase::FillSystemEnvironmentPath() { - if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath) + cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemEnvironment]; + + // Add LIB or INCLUDE + if(!this->EnvironmentPath.empty()) { - // Add LIB or INCLUDE - if(!this->EnvironmentPath.empty()) - { - this->AddEnvPath(this->EnvironmentPath.c_str()); - } - // Add PATH - this->AddEnvPath(0); + paths.AddEnvPath(this->EnvironmentPath); } + // Add PATH + paths.AddEnvPath("PATH"); + paths.AddSuffixes(this->SearchPathSuffixes); } //---------------------------------------------------------------------------- -void cmFindBase::AddCMakeSystemVariablePath() +void cmFindBase::FillCMakeSystemVariablePath() { - if(!this->NoCMakeSystemPath && !this->NoDefaultPath) - { - std::string var = "CMAKE_SYSTEM_"; - var += this->CMakePathName; - var += "_PATH"; - this->AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); - this->AddCMakePath(var); + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeSystem]; - if(this->CMakePathName == "PROGRAM") - { - this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH"); - } - else - { - this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH"); - } + std::string var = "CMAKE_SYSTEM_"; + var += this->CMakePathName; + var += "_PATH"; + paths.AddCMakePrefixPath("CMAKE_SYSTEM_PREFIX_PATH"); + paths.AddCMakePath(var); + + if(this->CMakePathName == "PROGRAM") + { + paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH"); } + else + { + paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH"); + } + paths.AddSuffixes(this->SearchPathSuffixes); } //---------------------------------------------------------------------------- -void cmFindBase::AddUserHintsPath() +void cmFindBase::FillUserHintsPath() { - this->AddPathsInternal(this->UserHints, CMakePath); -} + cmSearchPath &paths = this->LabeledPaths[PathLabel::Hints]; -//---------------------------------------------------------------------------- -void cmFindBase::AddUserGuessPath() -{ - this->AddPathsInternal(this->UserPaths, CMakePath); + for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin(); + p != this->UserHintsArgs.end(); ++p) + { + paths.AddUserPath(*p); + } + paths.AddSuffixes(this->SearchPathSuffixes); } //---------------------------------------------------------------------------- -void cmFindBase::AddPathSuffixes() +void cmFindBase::FillUserGuessPath() { - std::vector<std::string>& paths = this->SearchPaths; - std::vector<std::string> finalPath = paths; - std::vector<std::string>::iterator i; - // clear the path - paths.clear(); - // convert all paths to unix slashes and add search path suffixes - // if there are any - for(i = finalPath.begin(); - i != finalPath.end(); ++i) + cmSearchPath &paths = this->LabeledPaths[PathLabel::Guess]; + + for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin(); + p != this->UserGuessArgs.end(); ++p) { - cmSystemTools::ConvertToUnixSlashes(*i); - // copy each finalPath combined with SearchPathSuffixes - // to the SearchPaths ivar - for(std::vector<std::string>::iterator j = - this->SearchPathSuffixes.begin(); - j != this->SearchPathSuffixes.end(); ++j) - { - // if *i is only / then do not add a // - // this will get incorrectly considered a network - // path on windows and cause huge delays. - std::string p = *i; - if(p.size() && p[p.size()-1] != '/') - { - p += std::string("/"); - } - p += *j; - // add to all paths because the search path may be modified - // later with lib being replaced for lib64 which may exist - paths.push_back(p); - } - // now put the path without the path suffixes in the SearchPaths - paths.push_back(*i); + paths.AddUserPath(*p); } + paths.AddSuffixes(this->SearchPathSuffixes); } +//---------------------------------------------------------------------------- void cmFindBase::PrintFindStuff() { std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n"; @@ -457,9 +366,10 @@ void cmFindBase::PrintFindStuff() } std::cerr << "\n"; std::cerr << "SearchPaths\n"; - for(unsigned int i =0; i < this->SearchPaths.size(); ++i) + for(std::vector<std::string>::const_iterator i = this->SearchPaths.begin(); + i != this->SearchPaths.end(); ++i) { - std::cerr << "[" << this->SearchPaths[i] << "]\n"; + std::cerr << "[" << *i << "]\n"; } } diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h index 42d9bc1..8ca311d 100644 --- a/Source/cmFindBase.h +++ b/Source/cmFindBase.h @@ -34,7 +34,6 @@ public: protected: void PrintFindStuff(); void ExpandPaths(); - void AddPathSuffixes(); // see if the VariableName is already set in the cache, // also copy the documentation from the cache to VariableDocumentation @@ -55,18 +54,12 @@ protected: bool AlreadyInCacheWithoutMetaInfo; private: // Add pieces of the search. - void AddCMakeEnvironmentPath(); - void AddCMakeVariablePath(); - void AddSystemEnvironmentPath(); - void AddCMakeSystemVariablePath(); - void AddUserHintsPath(); - void AddUserGuessPath(); - - // Helpers. - void AddCMakePrefixPath(const std::string& variable); - void AddEnvPrefixPath(const std::string& variable); - void AddPrefixPaths(std::vector<std::string> const& in_paths, - PathType pathType); + void FillCMakeVariablePath(); + void FillCMakeEnvironmentPath(); + void FillUserHintsPath(); + void FillSystemEnvironmentPath(); + void FillCMakeSystemVariablePath(); + void FillUserGuessPath(); }; diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 6376d42..913985f 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -10,6 +10,19 @@ See the License for more information. ============================================================================*/ #include "cmFindCommon.h" +#include <functional> +#include <algorithm> + +//---------------------------------------------------------------------------- +cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL"); +cmFindCommon::PathLabel cmFindCommon::PathLabel::CMake("CMAKE"); +cmFindCommon::PathLabel + cmFindCommon::PathLabel::CMakeEnvironment("CMAKE_ENVIRONMENT"); +cmFindCommon::PathLabel cmFindCommon::PathLabel::Hints("HINTS"); +cmFindCommon::PathLabel + cmFindCommon::PathLabel::SystemEnvironment("SYSTM_ENVIRONMENT"); +cmFindCommon::PathLabel cmFindCommon::PathLabel::CMakeSystem("CMAKE_SYSTEM"); +cmFindCommon::PathLabel cmFindCommon::PathLabel::Guess("GUESS"); //---------------------------------------------------------------------------- cmFindCommon::cmFindCommon() @@ -34,6 +47,8 @@ cmFindCommon::cmFindCommon() this->SearchFrameworkLast = false; this->SearchAppBundleOnly = false; this->SearchAppBundleLast = false; + + this->InitializeSearchPathGroups(); } //---------------------------------------------------------------------------- @@ -42,11 +57,42 @@ cmFindCommon::~cmFindCommon() } //---------------------------------------------------------------------------- -void cmFindCommon::SelectDefaultRootPathMode() +void cmFindCommon::InitializeSearchPathGroups() { - // Use both by default. - this->FindRootPathMode = RootPathModeBoth; + std::vector<PathLabel>* labels; + + // Define the varoius different groups of path types + + // All search paths + labels = &this->PathGroupLabelMap[PathGroup::All]; + labels->push_back(PathLabel::CMake); + labels->push_back(PathLabel::CMakeEnvironment); + labels->push_back(PathLabel::Hints); + labels->push_back(PathLabel::SystemEnvironment); + labels->push_back(PathLabel::CMakeSystem); + labels->push_back(PathLabel::Guess); + + // Define the search group order + this->PathGroupOrder.push_back(PathGroup::All); + + // Create the idividual labeld search paths + this->LabeledPaths.insert(std::make_pair(PathLabel::CMake, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::CMakeEnvironment, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::Hints, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::SystemEnvironment, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::CMakeSystem, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::Guess, + cmSearchPath(this))); +} +//---------------------------------------------------------------------------- +void cmFindCommon::SelectDefaultRootPathMode() +{ // Check the policy variable for this find command type. std::string findRootPathVar = "CMAKE_FIND_ROOT_PATH_MODE_"; findRootPathVar += this->CMakePathName; @@ -54,11 +100,11 @@ void cmFindCommon::SelectDefaultRootPathMode() this->Makefile->GetSafeDefinition(findRootPathVar); if (rootPathMode=="NEVER") { - this->FindRootPathMode = RootPathModeNoRootPath; + this->FindRootPathMode = RootPathModeNever; } else if (rootPathMode=="ONLY") { - this->FindRootPathMode = RootPathModeOnlyRootPath; + this->FindRootPathMode = RootPathModeOnly; } else if (rootPathMode=="BOTH") { @@ -132,12 +178,12 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) fprintf(stderr, "[%s]\n", i->c_str()); } #endif - // Short-circuit if there is nothing to do. - if(this->FindRootPathMode == RootPathModeNoRootPath) + if(this->FindRootPathMode == RootPathModeNever) { return; } + const char* sysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT"); const char* rootPath = @@ -212,24 +258,20 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths) } //---------------------------------------------------------------------------- -void cmFindCommon::FilterPaths(std::vector<std::string>& paths, - const std::set<std::string>& ignore) +void cmFindCommon::FilterPaths(const std::vector<std::string>& inPaths, + const std::set<std::string>& ignore, + std::vector<std::string>& outPaths) { - // Now filter out anything that's in the ignore set. - std::vector<std::string> unfiltered; - unfiltered.swap(paths); - - for(std::vector<std::string>::iterator pi = unfiltered.begin(); - pi != unfiltered.end(); ++pi) + for(std::vector<std::string>::const_iterator i = inPaths.begin(); + i != inPaths.end(); ++i) { - if (ignore.count(*pi) == 0) + if(ignore.count(*i) == 0) { - paths.push_back(*pi); + outPaths.push_back(*i); } } } - //---------------------------------------------------------------------------- void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore) { @@ -266,8 +308,6 @@ void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore) ignore.insert(ignoreVec.begin(), ignoreVec.end()); } - - //---------------------------------------------------------------------------- bool cmFindCommon::CheckCommonArgument(std::string const& arg) { @@ -291,13 +331,13 @@ bool cmFindCommon::CheckCommonArgument(std::string const& arg) { this->NoCMakeSystemPath = true; } - else if(arg == "NO_CMAKE_FIND_ROOT_PATH") + else if(arg == "NO_CMAKE_FIND_ROOT_PATH") { - this->FindRootPathMode = RootPathModeNoRootPath; + this->FindRootPathMode = RootPathModeNever; } else if(arg == "ONLY_CMAKE_FIND_ROOT_PATH") { - this->FindRootPathMode = RootPathModeOnlyRootPath; + this->FindRootPathMode = RootPathModeOnly; } else if(arg == "CMAKE_FIND_ROOT_PATH_BOTH") { @@ -345,116 +385,34 @@ void cmFindCommon::AddPathSuffix(std::string const& arg) } //---------------------------------------------------------------------------- -void cmFindCommon::AddUserPath(std::string const& p, - std::vector<std::string>& paths) -{ - // We should view the registry as the target application would view - // it. - cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32; - cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64; - if(this->Makefile->PlatformIs64Bit()) - { - view = cmSystemTools::KeyWOW64_64; - other_view = cmSystemTools::KeyWOW64_32; - } - - // Expand using the view of the target application. - std::string expanded = p; - cmSystemTools::ExpandRegistryValues(expanded, view); - cmSystemTools::GlobDirs(expanded, paths); - - // Executables can be either 32-bit or 64-bit, so expand using the - // alternative view. - if(expanded != p && this->CMakePathName == "PROGRAM") - { - expanded = p; - cmSystemTools::ExpandRegistryValues(expanded, other_view); - cmSystemTools::GlobDirs(expanded, paths); - } -} - -//---------------------------------------------------------------------------- -void cmFindCommon::AddCMakePath(const std::string& variable) -{ - // Get a path from a CMake variable. - if(const char* varPath = this->Makefile->GetDefinition(variable)) - { - std::vector<std::string> tmp; - cmSystemTools::ExpandListArgument(varPath, tmp); - - // Relative paths are interpreted with respect to the current - // source directory. - this->AddPathsInternal(tmp, CMakePath); - } -} - -//---------------------------------------------------------------------------- -void cmFindCommon::AddEnvPath(const char* variable) -{ - // Get a path from the environment. - std::vector<std::string> tmp; - cmSystemTools::GetPath(tmp, variable); - // Relative paths are interpreted with respect to the current - // working directory. - this->AddPathsInternal(tmp, EnvPath); -} - -//---------------------------------------------------------------------------- -void cmFindCommon::AddPathsInternal(std::vector<std::string> const& in_paths, - PathType pathType) +void AddTrailingSlash(std::string& s) { - for(std::vector<std::string>::const_iterator i = in_paths.begin(); - i != in_paths.end(); ++i) + if(!s.empty() && *s.rbegin() != '/') { - this->AddPathInternal(*i, pathType); + s += '/'; } } - -//---------------------------------------------------------------------------- -void cmFindCommon::AddPathInternal(std::string const& in_path, - PathType pathType) +void cmFindCommon::ComputeFinalPaths() { - if(in_path.empty()) - { - return; - } + // Filter out ignored paths from the prefix list + std::set<std::string> ignored; + this->GetIgnoredPaths(ignored); - // Select the base path with which to interpret relative paths. - const char* relbase = 0; - if(pathType == CMakePath) + // Combine the seperate path types, filtering out ignores + this->SearchPaths.clear(); + std::vector<PathLabel>& allLabels = this->PathGroupLabelMap[PathGroup::All]; + for(std::vector<PathLabel>::const_iterator l = allLabels.begin(); + l != allLabels.end(); ++l) { - relbase = this->Makefile->GetCurrentDirectory(); + this->LabeledPaths[*l].ExtractWithout(ignored, this->SearchPaths); } - // Convert to clean full path. - std::string fullPath = - cmSystemTools::CollapseFullPath(in_path, relbase); - - // Insert the path if has not already been emitted. - if(this->SearchPathsEmitted.insert(fullPath).second) - { - this->SearchPaths.push_back(fullPath); - } -} - -//---------------------------------------------------------------------------- -void cmFindCommon::ComputeFinalPaths() -{ - std::vector<std::string>& paths = this->SearchPaths; - // Expand list of paths inside all search roots. - this->RerootPaths(paths); + this->RerootPaths(this->SearchPaths); // Add a trailing slash to all paths to aid the search process. - for(std::vector<std::string>::iterator i = paths.begin(); - i != paths.end(); ++i) - { - std::string& p = *i; - if(!p.empty() && p[p.size()-1] != '/') - { - p += "/"; - } - } + std::for_each(this->SearchPaths.begin(), this->SearchPaths.end(), + &AddTrailingSlash); } //---------------------------------------------------------------------------- diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h index 5a905cd..3fefc8d 100644 --- a/Source/cmFindCommon.h +++ b/Source/cmFindCommon.h @@ -13,6 +13,8 @@ #define cmFindCommon_h #include "cmCommand.h" +#include "cmSearchPath.h" +#include "cmPathLabel.h" /** \class cmFindCommon * \brief Base class for FIND_XXX implementations. @@ -29,12 +31,39 @@ public: cmTypeMacro(cmFindCommon, cmCommand); protected: - - enum RootPathMode { RootPathModeBoth, - RootPathModeOnlyRootPath, - RootPathModeNoRootPath }; - - enum PathType { FullPath, CMakePath, EnvPath }; + friend class cmSearchPath; + + /** Used to define groups of path labels */ + class PathGroup : public cmPathLabel + { + protected: + PathGroup(); + public: + PathGroup(const std::string& label) : cmPathLabel(label) { } + static PathGroup All; + }; + + /* Individual path types */ + class PathLabel : public cmPathLabel + { + protected: + PathLabel(); + public: + PathLabel(const std::string& label) : cmPathLabel(label) { } + static PathLabel CMake; + static PathLabel CMakeEnvironment; + static PathLabel Hints; + static PathLabel SystemEnvironment; + static PathLabel CMakeSystem; + static PathLabel Guess; + }; + + enum RootPathMode { RootPathModeNever, + RootPathModeOnly, + RootPathModeBoth }; + + /** Construct the various path groups and labels */ + void InitializeSearchPathGroups(); /** Place a set of search paths under the search roots. */ void RerootPaths(std::vector<std::string>& paths); @@ -44,8 +73,9 @@ protected: void GetIgnoredPaths(std::set<std::string>& ignore); /** Remove paths in the ignore set from the supplied vector. */ - void FilterPaths(std::vector<std::string>& paths, - const std::set<std::string>& ignore); + void FilterPaths(const std::vector<std::string>& inPaths, + const std::set<std::string>& ignore, + std::vector<std::string>& outPaths); /** Compute final search path list (reroot + trailing slash). */ void ComputeFinalPaths(); @@ -56,19 +86,15 @@ protected: /** Compute the current default bundle/framework search policy. */ void SelectDefaultMacMode(); + // Path arguments prior to path manipulation routines + std::vector<std::string> UserHintsArgs; + std::vector<std::string> UserGuessArgs; + std::string CMakePathName; RootPathMode FindRootPathMode; bool CheckCommonArgument(std::string const& arg); void AddPathSuffix(std::string const& arg); - void AddUserPath(std::string const& p, - std::vector<std::string>& paths); - void AddCMakePath(const std::string& variable); - void AddEnvPath(const char* variable); - void AddPathsInternal(std::vector<std::string> const& in_paths, - PathType pathType); - void AddPathInternal(std::string const& in_path, PathType pathType); - void SetMakefile(cmMakefile* makefile); bool NoDefaultPath; @@ -78,8 +104,12 @@ protected: bool NoCMakeSystemPath; std::vector<std::string> SearchPathSuffixes; - std::vector<std::string> UserPaths; - std::vector<std::string> UserHints; + + std::map<PathGroup, std::vector<PathLabel> > PathGroupLabelMap; + std::vector<PathGroup> PathGroupOrder; + std::map<std::string, PathLabel> PathLabelStringMap; + std::map<PathLabel, cmSearchPath> LabeledPaths; + std::vector<std::string> SearchPaths; std::set<std::string> SearchPathsEmitted; diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 16deaab..78f0e9e 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -88,7 +88,7 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix) { std::vector<std::string> original; original.swap(this->SearchPaths); - for(std::vector<std::string>::iterator i = original.begin(); + for(std::vector<std::string>::const_iterator i = original.begin(); i != original.end(); ++i) { this->AddArchitecturePath(*i, 0, suffix); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 4633e71..7746980 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -26,6 +26,14 @@ #endif //---------------------------------------------------------------------------- +cmFindPackageCommand::PathLabel + cmFindPackageCommand::PathLabel::UserRegistry("PACKAGE_REGISTRY"); +cmFindPackageCommand::PathLabel + cmFindPackageCommand::PathLabel::Builds("BUILDS"); +cmFindPackageCommand::PathLabel + cmFindPackageCommand::PathLabel::SystemRegistry("SYSTEM_PACKAGE_REGISTRY"); + +//---------------------------------------------------------------------------- cmFindPackageCommand::cmFindPackageCommand() { this->CMakePathName = "PACKAGE"; @@ -51,6 +59,33 @@ cmFindPackageCommand::cmFindPackageCommand() this->VersionFoundTweak = 0; this->VersionFoundCount = 0; this->RequiredCMakeVersion = 0; + + this->AppendSearchPathGroups(); +} + +//---------------------------------------------------------------------------- +void cmFindPackageCommand::AppendSearchPathGroups() +{ + std::vector<cmFindCommon::PathLabel>* labels; + + // Update the All group with new paths + labels = &this->PathGroupLabelMap[PathGroup::All]; + labels->insert(std::find(labels->begin(), labels->end(), + PathLabel::CMakeSystem), + PathLabel::UserRegistry); + labels->insert(std::find(labels->begin(), labels->end(), + PathLabel::CMakeSystem), + PathLabel::Builds); + labels->insert(std::find(labels->begin(), labels->end(), PathLabel::Guess), + PathLabel::SystemRegistry); + + // Create the new path objects + this->LabeledPaths.insert(std::make_pair(PathLabel::UserRegistry, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::Builds, + cmSearchPath(this))); + this->LabeledPaths.insert(std::make_pair(PathLabel::SystemRegistry, + cmSearchPath(this))); } //---------------------------------------------------------------------------- @@ -248,11 +283,11 @@ bool cmFindPackageCommand } else if(doing == DoingPaths) { - this->AddUserPath(args[i], this->UserPaths); + this->UserGuessArgs.push_back(args[i]); } else if(doing == DoingHints) { - this->AddUserPath(args[i], this->UserHints); + this->UserHintsArgs.push_back(args[i]); } else if(doing == DoingPathSuffixes) { @@ -263,7 +298,7 @@ bool cmFindPackageCommand if(args[i].find_first_of(":/\\") != args[i].npos || cmSystemTools::GetFilenameLastExtension(args[i]) != ".cmake") { - cmOStringStream e; + std::ostringstream e; e << "given CONFIGS option followed by invalid file name \"" << args[i] << "\". The names given must be file names without " << "a path and with a \".cmake\" extension."; @@ -279,7 +314,7 @@ bool cmFindPackageCommand } else { - cmOStringStream e; + std::ostringstream e; e << "called with invalid argument \"" << args[i] << "\""; this->SetError(e.str()); return false; @@ -292,7 +327,7 @@ bool cmFindPackageCommand std::back_inserter(doubledComponents)); if(!doubledComponents.empty()) { - cmOStringStream e; + std::ostringstream e; e << "called with components that are both required and optional:\n"; for(unsigned int i=0; i<doubledComponents.size(); ++i) { @@ -307,7 +342,7 @@ bool cmFindPackageCommand this->UseConfigFiles = moduleArgs.empty(); if(!this->UseFindModules && !this->UseConfigFiles) { - cmOStringStream e; + std::ostringstream e; e << "given options exclusive to Module mode:\n"; for(std::set<unsigned int>::const_iterator si = moduleArgs.begin(); si != moduleArgs.end(); ++si) @@ -389,7 +424,7 @@ bool cmFindPackageCommand { if (this->Required) { - cmOStringStream e; + std::ostringstream e; e << "for module " << this->Name << " called with REQUIRED, but " << disableFindPackageVar << " is enabled. A REQUIRED package cannot be disabled."; @@ -422,7 +457,7 @@ bool cmFindPackageCommand if(this->UseFindModules && this->UseConfigFiles && this->Makefile->IsOn("CMAKE_FIND_PACKAGE_WARN_NO_MODULE")) { - cmOStringStream aw; + std::ostringstream aw; if(this->RequiredCMakeVersion >= CMake_VERSION_ENCODE(2,8,8)) { aw << "find_package called without either MODULE or CONFIG option and " @@ -587,7 +622,7 @@ bool cmFindPackageCommand::FindModule(bool& found) module += this->Name; module += ".cmake"; std::string mfile = this->Makefile->GetModulesFile(module.c_str()); - if ( mfile.size() ) + if (!mfile.empty()) { // Load the module we found, and set "<name>_FIND_MODULE" to true // while inside it. @@ -713,8 +748,8 @@ bool cmFindPackageCommand::HandlePackageMode() if (result && !found && (!this->Quiet || this->Required)) { // The variable is not set. - cmOStringStream e; - cmOStringStream aw; + std::ostringstream e; + std::ostringstream aw; if (configFileSetFOUNDFalse) { e << "Found package configuration file:\n" @@ -728,7 +763,7 @@ bool cmFindPackageCommand::HandlePackageMode() } // 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.size() > 0) + else if (!this->ConsideredConfigs.empty()) { e << "Could not find a configuration file for package \"" << this->Name << "\" that " @@ -1111,86 +1146,97 @@ void cmFindPackageCommand::AppendSuccessInformation() //---------------------------------------------------------------------------- void cmFindPackageCommand::ComputePrefixes() { - this->AddPrefixesCMakeVariable(); - this->AddPrefixesCMakeEnvironment(); - this->AddPrefixesUserHints(); - this->AddPrefixesSystemEnvironment(); - this->AddPrefixesUserRegistry(); - this->AddPrefixesBuilds(); - this->AddPrefixesCMakeSystemVariable(); - this->AddPrefixesSystemRegistry(); - this->AddPrefixesUserGuess(); + if(!this->NoDefaultPath) + { + if(!this->NoCMakePath) + { + this->FillPrefixesCMakeVariable(); + } + if(!this->NoCMakeEnvironmentPath) + { + this->FillPrefixesCMakeEnvironment(); + } + if(!this->NoSystemEnvironmentPath) + { + this->FillPrefixesSystemEnvironment(); + } + if(!this->NoUserRegistry) + { + this->FillPrefixesUserRegistry(); + } + if(!this->NoBuilds) + { + this->FillPrefixesBuilds(); + } + if(!this->NoCMakeSystemPath) + { + this->FillPrefixesCMakeSystemVariable(); + } + if(!this->NoSystemRegistry) + { + this->FillPrefixesSystemRegistry(); + } + } + this->FillPrefixesUserHints(); + this->FillPrefixesUserGuess(); + this->ComputeFinalPaths(); } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesCMakeEnvironment() +void cmFindPackageCommand::FillPrefixesCMakeEnvironment() { - if(!this->NoCMakeEnvironmentPath && !this->NoDefaultPath) - { - // Check the environment variable with the same name as the cache - // entry. - std::string env; - if(cmSystemTools::GetEnv(this->Variable.c_str(), env) && env.length() > 0) - { - cmSystemTools::ConvertToUnixSlashes(env); - this->AddPathInternal(env, EnvPath); - } + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeEnvironment]; - this->AddEnvPath("CMAKE_PREFIX_PATH"); - this->AddEnvPath("CMAKE_FRAMEWORK_PATH"); - this->AddEnvPath("CMAKE_APPBUNDLE_PATH"); - } + // Check the environment variable with the same name as the cache + // entry. + paths.AddEnvPath(this->Variable); + + // And now the general CMake environment variables + paths.AddEnvPath("CMAKE_PREFIX_PATH"); + paths.AddEnvPath("CMAKE_FRAMEWORK_PATH"); + paths.AddEnvPath("CMAKE_APPBUNDLE_PATH"); } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesCMakeVariable() +void cmFindPackageCommand::FillPrefixesCMakeVariable() { - if(!this->NoCMakePath && !this->NoDefaultPath) - { - this->AddCMakePath("CMAKE_PREFIX_PATH"); - this->AddCMakePath("CMAKE_FRAMEWORK_PATH"); - this->AddCMakePath("CMAKE_APPBUNDLE_PATH"); - } + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMake]; + + paths.AddCMakePath("CMAKE_PREFIX_PATH"); + paths.AddCMakePath("CMAKE_FRAMEWORK_PATH"); + paths.AddCMakePath("CMAKE_APPBUNDLE_PATH"); } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesSystemEnvironment() +void cmFindPackageCommand::FillPrefixesSystemEnvironment() { - if(!this->NoSystemEnvironmentPath && !this->NoDefaultPath) + cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemEnvironment]; + + // Use the system search path to generate prefixes. + // Relative paths are interpreted with respect to the current + // working directory. + std::vector<std::string> tmp; + cmSystemTools::GetPath(tmp); + for(std::vector<std::string>::iterator i = tmp.begin(); + i != tmp.end(); ++i) { - // Use the system search path to generate prefixes. - // Relative paths are interpreted with respect to the current - // working directory. - std::vector<std::string> tmp; - cmSystemTools::GetPath(tmp); - for(std::vector<std::string>::iterator i = tmp.begin(); - i != tmp.end(); ++i) + // If the path is a PREFIX/bin case then add its parent instead. + if((cmHasLiteralSuffix(*i, "/bin")) || + (cmHasLiteralSuffix(*i, "/sbin"))) { - std::string const& d = *i; - - // If the path is a PREFIX/bin case then add its parent instead. - if((cmHasLiteralSuffix(d, "/bin")) || - (cmHasLiteralSuffix(d, "/sbin"))) - { - this->AddPathInternal(cmSystemTools::GetFilenamePath(d), EnvPath); - } - else - { - this->AddPathInternal(d, EnvPath); - } + paths.AddPath(cmSystemTools::GetFilenamePath(*i)); + } + else + { + paths.AddPath(*i); } } } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesUserRegistry() +void cmFindPackageCommand::FillPrefixesUserRegistry() { - if(this->NoUserRegistry || this->NoDefaultPath) - { - return; - } - #if defined(_WIN32) && !defined(__CYGWIN__) this->LoadPackageRegistryWinUser(); #elif defined(__HAIKU__) @@ -1201,7 +1247,8 @@ void cmFindPackageCommand::AddPrefixesUserRegistry() std::string fname = dir; fname += "/cmake/packages/"; fname += Name; - this->LoadPackageRegistryDir(fname); + this->LoadPackageRegistryDir(fname, + this->LabeledPaths[PathLabel::UserRegistry]); } #else if(const char* home = cmSystemTools::GetEnv("HOME")) @@ -1209,13 +1256,14 @@ void cmFindPackageCommand::AddPrefixesUserRegistry() std::string dir = home; dir += "/.cmake/packages/"; dir += this->Name; - this->LoadPackageRegistryDir(dir); + this->LoadPackageRegistryDir(dir, + this->LabeledPaths[PathLabel::UserRegistry]); } #endif } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesSystemRegistry() +void cmFindPackageCommand::FillPrefixesSystemRegistry() { if(this->NoSystemRegistry || this->NoDefaultPath) { @@ -1241,29 +1289,32 @@ void cmFindPackageCommand::AddPrefixesSystemRegistry() void cmFindPackageCommand::LoadPackageRegistryWinUser() { // HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views. - this->LoadPackageRegistryWin(true, 0); + this->LoadPackageRegistryWin(true, 0, + this->LabeledPaths[PathLabel::UserRegistry]); } //---------------------------------------------------------------------------- void cmFindPackageCommand::LoadPackageRegistryWinSystem() { + cmSearchPath &paths = this->LabeledPaths[PathLabel::SystemRegistry]; + // HKEY_LOCAL_MACHINE\\SOFTWARE has separate 32-bit and 64-bit views. // Prefer the target platform view first. if(this->Makefile->PlatformIs64Bit()) { - this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY); - this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY); + this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY, paths); + this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY, paths); } else { - this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY); - this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY); + this->LoadPackageRegistryWin(false, KEY_WOW64_32KEY, paths); + this->LoadPackageRegistryWin(false, KEY_WOW64_64KEY, paths); } } //---------------------------------------------------------------------------- -void cmFindPackageCommand::LoadPackageRegistryWin(bool user, - unsigned int view) +void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view, + cmSearchPath& outPaths) { std::wstring key = L"Software\\Kitware\\CMake\\Packages\\"; key += cmsys::Encoding::ToWide(this->Name); @@ -1289,8 +1340,8 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user, if(valueType == REG_SZ) { data[dataSize] = 0; - cmsys_ios::stringstream ss(cmsys::Encoding::ToNarrow(&data[0])); - if(!this->CheckPackageRegistryEntry(ss)) + if(!this->CheckPackageRegistryEntry( + cmsys::Encoding::ToNarrow(&data[0]), outPaths)) { // The entry is invalid. bad.insert(name); @@ -1332,7 +1383,8 @@ public: }; //---------------------------------------------------------------------------- -void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir) +void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir, + cmSearchPath& outPaths) { cmsys::Directory files; if(!files.Load(dir)) @@ -1354,7 +1406,9 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir) // Load the file. cmsys::ifstream fin(fname.c_str(), std::ios::in | cmsys_ios_binary); - if(fin && this->CheckPackageRegistryEntry(fin)) + std::string fentry; + if(fin && cmSystemTools::GetLineFromStream(fin, fentry) && + this->CheckPackageRegistryEntry(fentry, outPaths)) { // The file references an existing package, so release it. holdFile.Release(); @@ -1367,12 +1421,11 @@ void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir) #endif //---------------------------------------------------------------------------- -bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is) +bool cmFindPackageCommand::CheckPackageRegistryEntry(const std::string& fname, + cmSearchPath& outPaths) { // Parse the content of one package registry entry. - std::string fname; - if(cmSystemTools::GetLineFromStream(is, fname) && - cmSystemTools::FileIsFullPath(fname.c_str())) + if(cmSystemTools::FileIsFullPath(fname.c_str())) { // The first line in the stream is the full path to a file or // directory containing the package. @@ -1381,9 +1434,12 @@ bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is) // The path exists. Look for the package here. if(!cmSystemTools::FileIsDirectory(fname)) { - fname = cmSystemTools::GetFilenamePath(fname); + outPaths.AddPath(cmSystemTools::GetFilenamePath(fname)); + } + else + { + outPaths.AddPath(fname); } - this->AddPathInternal(fname, FullPath); return true; } else @@ -1404,52 +1460,60 @@ bool cmFindPackageCommand::CheckPackageRegistryEntry(std::istream& is) } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesBuilds() +void cmFindPackageCommand::FillPrefixesBuilds() { - if(!this->NoBuilds && !this->NoDefaultPath) - { - // It is likely that CMake will have recently built the project. - for(int i=0; i <= 10; ++i) - { - cmOStringStream r; - r << - "[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\" - "Settings\\StartPath;WhereBuild" << i << "]"; - std::string f = r.str(); - cmSystemTools::ExpandRegistryValues(f); - cmSystemTools::ConvertToUnixSlashes(f); - if(cmSystemTools::FileIsFullPath(f.c_str()) && - cmSystemTools::FileIsDirectory(f)) - { - this->AddPathInternal(f, FullPath); - } + cmSearchPath &paths = this->LabeledPaths[PathLabel::Builds]; + + // It is likely that CMake will have recently built the project. + for(int i=0; i <= 10; ++i) + { + std::ostringstream r; + r << + "[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\" + "Settings\\StartPath;WhereBuild" << i << "]"; + std::string f = r.str(); + cmSystemTools::ExpandRegistryValues(f); + cmSystemTools::ConvertToUnixSlashes(f); + if(cmSystemTools::FileIsFullPath(f.c_str()) && + cmSystemTools::FileIsDirectory(f)) + { + paths.AddPath(f); } } } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesCMakeSystemVariable() +void cmFindPackageCommand::FillPrefixesCMakeSystemVariable() { - if(!this->NoCMakeSystemPath && !this->NoDefaultPath) - { - this->AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH"); - this->AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH"); - this->AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH"); - } + cmSearchPath &paths = this->LabeledPaths[PathLabel::CMakeSystem]; + + paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH"); + paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH"); + paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH"); } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesUserGuess() +void cmFindPackageCommand::FillPrefixesUserGuess() { - // Add guesses specified by the caller. - this->AddPathsInternal(this->UserPaths, CMakePath); + cmSearchPath &paths = this->LabeledPaths[PathLabel::Guess]; + + for(std::vector<std::string>::const_iterator p = this->UserGuessArgs.begin(); + p != this->UserGuessArgs.end(); ++p) + { + paths.AddUserPath(*p); + } } //---------------------------------------------------------------------------- -void cmFindPackageCommand::AddPrefixesUserHints() +void cmFindPackageCommand::FillPrefixesUserHints() { - // Add hints specified by the caller. - this->AddPathsInternal(this->UserHints, CMakePath); + cmSearchPath &paths = this->LabeledPaths[PathLabel::Hints]; + + for(std::vector<std::string>::const_iterator p = this->UserHintsArgs.begin(); + p != this->UserHintsArgs.end(); ++p) + { + paths.AddUserPath(*p); + } } //---------------------------------------------------------------------------- diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 2249459..949dcb1 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -53,6 +53,21 @@ public: cmTypeMacro(cmFindPackageCommand, cmFindCommon); private: + class PathLabel : public cmFindCommon::PathLabel + { + protected: + PathLabel(); + public: + PathLabel(const std::string& label) : cmFindCommon::PathLabel(label) { } + static PathLabel UserRegistry; + static PathLabel Builds; + static PathLabel SystemRegistry; + }; + + // Add additional search path labels and groups not present in the + // parent class + void AppendSearchPathGroups(); + void AppendSuccessInformation(); void AppendToFoundProperty(bool found); void SetModuleVariables(const std::string& components); @@ -69,20 +84,22 @@ private: void StoreVersionFound(); void ComputePrefixes(); - void AddPrefixesCMakeEnvironment(); - void AddPrefixesCMakeVariable(); - void AddPrefixesSystemEnvironment(); - void AddPrefixesUserRegistry(); - void AddPrefixesSystemRegistry(); - void AddPrefixesBuilds(); - void AddPrefixesCMakeSystemVariable(); - void AddPrefixesUserGuess(); - void AddPrefixesUserHints(); - void LoadPackageRegistryDir(std::string const& dir); + void FillPrefixesCMakeEnvironment(); + void FillPrefixesCMakeVariable(); + void FillPrefixesSystemEnvironment(); + void FillPrefixesUserRegistry(); + void FillPrefixesSystemRegistry(); + void FillPrefixesBuilds(); + void FillPrefixesCMakeSystemVariable(); + void FillPrefixesUserGuess(); + void FillPrefixesUserHints(); + void LoadPackageRegistryDir(std::string const& dir, cmSearchPath& outPaths); void LoadPackageRegistryWinUser(); void LoadPackageRegistryWinSystem(); - void LoadPackageRegistryWin(bool user, unsigned int view); - bool CheckPackageRegistryEntry(std::istream& is); + void LoadPackageRegistryWin(bool user, unsigned int view, + cmSearchPath& outPaths); + bool CheckPackageRegistryEntry(const std::string& fname, + cmSearchPath& outPaths); bool SearchDirectory(std::string const& dir); bool CheckDirectory(std::string const& dir); bool FindConfigFile(std::string const& dir, std::string& file); diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index f4cc4c2..49fbf45 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -48,7 +48,7 @@ bool cmFindPathCommand } std::string result = this->FindHeader(); - if(result.size() != 0) + if(!result.empty()) { this->Makefile->AddCacheDefinition (this->VariableName, result.c_str(), @@ -108,7 +108,7 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file, fileName = file; frameWorkName = ""; } - if(frameWorkName.size()) + if(!frameWorkName.empty()) { std::string fpath = dir; fpath += frameWorkName; @@ -134,7 +134,7 @@ cmFindPathCommand::FindHeaderInFramework(std::string const& file, cmsys::Glob globIt; globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); - if(files.size()) + if(!files.empty()) { std::string fheader = cmSystemTools::CollapseFullPath(files[0]); if(this->IncludeFileInPath) diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index b6577e1..4ee419c 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -88,7 +88,7 @@ std::string cmFindProgramCommand { std::string appName = *name + std::string(".app"); - std::string appPath = cmSystemTools::FindDirectory(appName.c_str(), + std::string appPath = cmSystemTools::FindDirectory(appName, this->SearchPaths, true); diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index e3f66c1..8e3510d 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -27,6 +27,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endofreach for this statement if (!this->Depth) { + cmMakefile::LoopBlockPop loopBlockPop(&mf); + // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> fb(mf.RemoveFunctionBlocker(this, lff)); @@ -67,12 +69,17 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, mf.AddDefinition(this->Args[0],oldDef.c_str()); return true; } + if (status.GetContinueInvoked()) + { + break; + } if(cmSystemTools::GetFatalErrorOccured() ) { return true; } } } + // restore the variable to its prior value mf.AddDefinition(this->Args[0],oldDef.c_str()); return true; @@ -163,7 +170,7 @@ bool cmForEachCommand step == 0 ) { - cmOStringStream str; + std::ostringstream str; str << "called with incorrect range specification: start "; str << start << ", stop " << stop << ", step " << step; this->SetError(str.str()); @@ -199,6 +206,8 @@ bool cmForEachCommand } this->Makefile->AddFunctionBlocker(f); + this->Makefile->PushLoopBlock(); + return true; } @@ -234,7 +243,7 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "Unknown argument:\n" << " " << args[i] << "\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return true; @@ -242,5 +251,8 @@ bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args) } this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass auto_ptr + + this->Makefile->PushLoopBlock(); + return true; } diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index 3580374..c33048c 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -103,7 +103,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); // set the value of argc - cmOStringStream strStream; + std::ostringstream strStream; strStream << expandedArgs.size(); this->Makefile->AddDefinition("ARGC",strStream.str().c_str()); this->Makefile->MarkVariableAsUsed("ARGC"); @@ -111,7 +111,7 @@ bool cmFunctionHelperCommand::InvokeInitialPass // set the values for ARGV0 ARGV1 ... for (unsigned int t = 0; t < expandedArgs.size(); ++t) { - cmOStringStream tmpStream; + std::ostringstream tmpStream; tmpStream << "ARGV" << t; this->Makefile->AddDefinition(tmpStream.str(), expandedArgs[t].c_str()); @@ -132,14 +132,14 @@ bool cmFunctionHelperCommand::InvokeInitialPass unsigned int cnt = 0; for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit ) { - if ( argvDef.size() > 0 ) + if (!argvDef.empty()) { argvDef += ";"; } argvDef += *eit; if ( cnt >= this->Args.size()-1 ) { - if ( argnDef.size() > 0 ) + if (!argnDef.empty()) { argnDef += ";"; } @@ -271,11 +271,7 @@ bool cmFunctionCommand // create a function blocker cmFunctionFunctionBlocker *f = new cmFunctionFunctionBlocker(); - for(std::vector<std::string>::const_iterator j = args.begin(); - j != args.end(); ++j) - { - f->Args.push_back(*j); - } + f->Args.insert(f->Args.end(), args.begin(), args.end()); this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmGeneratedFileStream.h b/Source/cmGeneratedFileStream.h index 7adee7b..2aa6beb 100644 --- a/Source/cmGeneratedFileStream.h +++ b/Source/cmGeneratedFileStream.h @@ -15,10 +15,6 @@ #include "cmStandardIncludes.h" #include <cmsys/FStream.hxx> -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - // This is the first base class of cmGeneratedFileStream. It will be // created before and destroyed after the ofstream portion and can // therefore be used to manage the temporary file. @@ -146,8 +142,4 @@ private: cmGeneratedFileStream(cmGeneratedFileStream const&); // not implemented }; -#if defined(__sgi) && !defined(__GNUC__) -# pragma reset woff 1375 /* base class destructor not virtual */ -#endif - #endif diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 09d02ea..bf96951 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -15,8 +15,6 @@ #include "cmTarget.h" #include "assert.h" -#include <cmsys/String.h> - #include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionLexer.h" #include "cmGeneratorExpressionParser.h" @@ -90,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( context.HadError = false; context.HadContextSensitiveCondition = false; context.HadHeadSensitiveCondition = false; + context.SourceSensitiveTargets.clear(); context.HeadTarget = headTarget; context.EvaluateForBuildsystem = this->EvaluateForBuildsystem; context.CurrentTarget = currentTarget ? currentTarget : headTarget; @@ -99,12 +98,8 @@ const char *cmCompiledGeneratorExpression::Evaluate( { this->Output += (*it)->Evaluate(&context, dagChecker); - for(std::set<std::string>::const_iterator - p = context.SeenTargetProperties.begin(); - p != context.SeenTargetProperties.end(); ++p) - { - this->SeenTargetProperties.insert(*p); - } + this->SeenTargetProperties.insert(context.SeenTargetProperties.begin(), + context.SeenTargetProperties.end()); if (context.HadError) { this->Output = ""; @@ -118,6 +113,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( { this->HadContextSensitiveCondition = context.HadContextSensitiveCondition; this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition; + this->SourceSensitiveTargets = context.SourceSensitiveTargets; } this->DependTargets = context.DependTargets; @@ -150,15 +146,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( //---------------------------------------------------------------------------- cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() { - std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it - = this->Evaluators.begin(); - const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end - = this->Evaluators.end(); - - for ( ; it != end; ++it) - { - delete *it; - } + cmDeleteAll(this->Evaluators); } //---------------------------------------------------------------------------- @@ -445,7 +433,7 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input, return stripExportInterface(input, context, resolveRelative); } - assert(!"cmGeneratorExpression::Preprocess called with invalid args"); + assert(0 && "cmGeneratorExpression::Preprocess called with invalid args"); return std::string(); } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index b952520..57f78c5 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -115,6 +115,10 @@ public: { return this->HadHeadSensitiveCondition; } + std::set<cmTarget const*> GetSourceSensitiveTargets() const + { + return this->SourceSensitiveTargets; + } void SetEvaluateForBuildsystem(bool eval) { @@ -146,6 +150,7 @@ private: mutable std::string Output; mutable bool HadContextSensitiveCondition; mutable bool HadHeadSensitiveCondition; + mutable std::set<cmTarget const*> SourceSensitiveTargets; bool EvaluateForBuildsystem; }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 75a84cb..c8b9949 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -66,9 +66,7 @@ cmGeneratorExpressionDAGChecker::Initialize() if (it != top->Seen.end()) { const std::set<std::string> &propSet = it->second; - const std::set<std::string>::const_iterator i - = propSet.find(this->Property); - if (i != propSet.end()) + if (propSet.find(this->Property) != propSet.end()) { this->CheckResult = ALREADY_SEEN; return; @@ -106,7 +104,7 @@ void cmGeneratorExpressionDAGChecker::ReportError( if (parent && !parent->Parent) { - cmOStringStream e; + std::ostringstream e; e << "Error evaluating generator expression:\n" << " " << expr << "\n" << "Self reference on target \"" @@ -118,7 +116,7 @@ void cmGeneratorExpressionDAGChecker::ReportError( } { - cmOStringStream e; + std::ostringstream e; e << "Error evaluating generator expression:\n" << " " << expr << "\n" << "Dependency loop found."; @@ -130,7 +128,7 @@ void cmGeneratorExpressionDAGChecker::ReportError( int loopStep = 1; while (parent) { - cmOStringStream e; + std::ostringstream e; e << "Loop step " << loopStep << "\n" << " " << (parent->Content ? parent->Content->GetOriginalExpression() : expr) diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index f9067cf..4e2a868 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -13,6 +13,9 @@ #include "cmGeneratorExpressionEvaluationFile.h" #include "cmMakefile.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" +#include "cmSourceFile.h" #include "cmGeneratedFileStream.h" #include <cmsys/FStream.hxx> @@ -36,7 +39,7 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( //---------------------------------------------------------------------------- void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, cmCompiledGeneratorExpression* inputExpression, - std::map<std::string, std::string> &outputFiles) + std::map<std::string, std::string> &outputFiles, mode_t perm) { std::string rawCondition = this->Condition->GetInput(); if (!rawCondition.empty()) @@ -48,7 +51,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, } if (condResult != "1") { - cmOStringStream e; + std::ostringstream e; e << "Evaluation file condition \"" << rawCondition << "\" did " "not evaluate to valid content. Got \"" << condResult << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -70,24 +73,44 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, { return; } - cmOStringStream e; + std::ostringstream e; e << "Evaluation file to be written multiple times for different " "configurations with different content:\n " << outputFileName; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } + this->Makefile->AddCMakeOutputFile(outputFileName.c_str()); this->Files.push_back(outputFileName); outputFiles[outputFileName] = outputContent; cmGeneratedFileStream fout(outputFileName.c_str()); fout.SetCopyIfDifferent(true); fout << outputContent; + if (fout.Close() && perm) + { + cmSystemTools::SetPermissions(outputFileName.c_str(), perm); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorExpressionEvaluationFile::CreateOutputFile( + std::string const& config) +{ + std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config); + cmSourceFile* sf = this->Makefile->GetOrCreateSource(name); + sf->SetProperty("GENERATED", "1"); + + cmGlobalGenerator *gg + = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + gg->SetFilenameTargetDepends(sf, + this->OutputFileExpr->GetSourceSensitiveTargets()); } //---------------------------------------------------------------------------- void cmGeneratorExpressionEvaluationFile::Generate() { + mode_t perm = 0; std::string inputContent; if (this->InputIsContent) { @@ -95,10 +118,12 @@ void cmGeneratorExpressionEvaluationFile::Generate() } else { + this->Makefile->AddCMakeDependFile(this->Input.c_str()); + cmSystemTools::GetPermissions(this->Input.c_str(), perm); cmsys::ifstream fin(this->Input.c_str()); if(!fin) { - cmOStringStream e; + std::ostringstream e; e << "Evaluation file \"" << this->Input << "\" cannot be read."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; @@ -131,7 +156,7 @@ void cmGeneratorExpressionEvaluationFile::Generate() for(std::vector<std::string>::const_iterator li = allConfigs.begin(); li != allConfigs.end(); ++li) { - this->Generate(*li, inputExpression.get(), outputFiles); + this->Generate(*li, inputExpression.get(), outputFiles, perm); if(cmSystemTools::GetFatalErrorOccured()) { return; diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index f939916..3394ade 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -31,10 +31,12 @@ public: std::vector<std::string> GetFiles() const { return this->Files; } + void CreateOutputFile(std::string const& config); + private: void Generate(const std::string& config, cmCompiledGeneratorExpression* inputExpression, - std::map<std::string, std::string> &outputFiles); + std::map<std::string, std::string> &outputFiles, mode_t perm); private: const std::string Input; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 0010dba..5f246f9 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -36,7 +36,7 @@ void reportError(cmGeneratorExpressionContext *context, return; } - cmOStringStream e; + std::ostringstream e; e << "Error evaluating generator expression:\n" << " " << expr << "\n" << result; @@ -69,9 +69,42 @@ struct cmGeneratorExpressionNode const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *dagChecker ) const = 0; + + static std::string EvaluateDependentExpression( + std::string const& prop, cmMakefile *makefile, + cmGeneratorExpressionContext *context, + cmTarget const* headTarget, cmTarget const* currentTarget, + cmGeneratorExpressionDAGChecker *dagChecker); }; //---------------------------------------------------------------------------- +std::string cmGeneratorExpressionNode::EvaluateDependentExpression( + std::string const& prop, cmMakefile *makefile, + cmGeneratorExpressionContext *context, + cmTarget const* headTarget, cmTarget const* currentTarget, + cmGeneratorExpressionDAGChecker *dagChecker) +{ + cmGeneratorExpression ge(&context->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); + cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem); + std::string result = cge->Evaluate(makefile, + context->Config, + context->Quiet, + headTarget, + currentTarget, + dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + if (cge->GetHadHeadSensitiveCondition()) + { + context->HadHeadSensitiveCondition = true; + } + return result; +} + +//---------------------------------------------------------------------------- static const struct ZeroNode : public cmGeneratorExpressionNode { ZeroNode() {} @@ -329,7 +362,7 @@ static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode const GeneratorExpressionContent *, cmGeneratorExpressionDAGChecker *) const { - return cmSystemTools::MakeCidentifier(parameters.front().c_str()); + return cmSystemTools::MakeCidentifier(parameters.front()); } } makeCIdentifierNode; @@ -396,7 +429,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode { const char *compilerId = context->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID"); - if (parameters.size() == 0) + if (parameters.empty()) { return compilerId ? compilerId : ""; } @@ -423,7 +456,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode { case cmPolicies::WARN: { - cmOStringStream e; + std::ostringstream e; e << context->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0044); context->Makefile->GetCMakeInstance() @@ -501,7 +534,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode { const char *compilerVersion = context->Makefile->GetSafeDefinition( "CMAKE_" + lang + "_COMPILER_VERSION"); - if (parameters.size() == 0) + if (parameters.empty()) { return compilerVersion ? compilerVersion : ""; } @@ -583,7 +616,7 @@ struct PlatformIdNode : public cmGeneratorExpressionNode { const char *platformId = context->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - if (parameters.size() == 0) + if (parameters.empty()) { return platformId ? platformId : ""; } @@ -770,18 +803,9 @@ static const struct JoinNode : public cmGeneratorExpressionNode const GeneratorExpressionContent *, cmGeneratorExpressionDAGChecker *) const { - std::string result; - std::vector<std::string> list; cmSystemTools::ExpandListArgument(parameters.front(), list); - std::string sep; - for(std::vector<std::string>::const_iterator li = list.begin(); - li != list.end(); ++li) - { - result += sep + *li; - sep = parameters[1]; - } - return result; + return cmJoin(list, parameters[1]); } } joinNode; @@ -825,22 +849,10 @@ getLinkedTargetsContent( } if(!depString.empty()) { - cmGeneratorExpression ge(&context->Backtrace); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString); - linkedTargetsContent = cge->Evaluate(target->GetMakefile(), - context->Config, - context->Quiet, - headTarget, - target, - dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } - if (cge->GetHadHeadSensitiveCondition()) - { - context->HadHeadSensitiveCondition = true; - } + linkedTargetsContent = + cmGeneratorExpressionNode::EvaluateDependentExpression(depString, + target->GetMakefile(), context, + headTarget, target, dagChecker); } linkedTargetsContent = cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); @@ -932,14 +944,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if (!target) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << targetName << "\" not found."; reportError(context, content->GetOriginalExpression(), e.str()); return std::string(); } - context->AllTargets.insert(target); + context->AllTargets.insert(target); } if (target == context->HeadTarget) @@ -950,6 +962,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode // value for all evaluations. context->SeenTargetProperties.insert(propertyName); } + if (propertyName == "SOURCES") + { + context->SourceSensitiveTargets.insert(target); + } if (propertyName.empty()) { @@ -1181,24 +1197,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } if(!interfacePropertyName.empty()) { - cmGeneratorExpression ge(&context->Backtrace); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop); - cge->SetEvaluateForBuildsystem(context->EvaluateForBuildsystem); - std::string result = cge->Evaluate(context->Makefile, - context->Config, - context->Quiet, - headTarget, - target, - &dagChecker); - - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } - if (cge->GetHadHeadSensitiveCondition()) - { - context->HadHeadSensitiveCondition = true; - } + std::string result = this->EvaluateDependentExpression(prop, + context->Makefile, context, + headTarget, target, &dagChecker); if (!linkedTargetsContent.empty()) { result += (result.empty() ? "" : ";") + linkedTargetsContent; @@ -1243,7 +1244,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode { if (!context->EvaluateForBuildsystem) { - cmOStringStream e; + std::ostringstream e; e << "The evaluation of the TARGET_OBJECTS generator expression " "is only suitable for consumption by CMake. It is not suitable " "for writing out elsewhere."; @@ -1256,7 +1257,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode context->Makefile->FindGeneratorTargetToUse(tgtName); if (!gt) { - cmOStringStream e; + std::ostringstream e; e << "Objects of target \"" << tgtName << "\" referenced but no such target exists."; reportError(context, content->GetOriginalExpression(), e.str()); @@ -1264,7 +1265,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode } if (gt->GetType() != cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Objects of target \"" << tgtName << "\" referenced but is not an OBJECT library."; reportError(context, content->GetOriginalExpression(), e.str()); @@ -1286,12 +1287,16 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode std::string obj_dir = gt->ObjectDirectory; std::string result; const char* sep = ""; - for(std::map<cmSourceFile const*, std::string>::const_iterator it - = mapping.begin(); it != mapping.end(); ++it) + for(std::vector<cmSourceFile const*>::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) { - assert(!it->second.empty()); + // Find the object file name corresponding to this source file. + std::map<cmSourceFile const*, std::string>::const_iterator + map_it = mapping.find(*it); + // It must exist because we populated the mapping just above. + assert(!map_it->second.empty()); result += sep; - std::string objFile = obj_dir + it->second; + std::string objFile = obj_dir + map_it->second; cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true); sf->SetObjectLibrary(tgtName); sf->SetProperty("EXTERNAL_OBJECT", "1"); @@ -1363,10 +1368,17 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode for (LangMap::const_iterator lit = testedFeatures.begin(); lit != testedFeatures.end(); ++lit) { + std::vector<std::string> const& langAvailable + = availableFeatures[lit->first]; for (std::vector<std::string>::const_iterator it = lit->second.begin(); it != lit->second.end(); ++it) { - if (!context->Makefile->HaveFeatureAvailable(target, + if (std::find(langAvailable.begin(), langAvailable.end(), *it) + == langAvailable.end()) + { + return "0"; + } + if (!context->Makefile->HaveStandardAvailable(target, lit->first, *it)) { if (evalLL) @@ -1415,7 +1427,7 @@ cmPolicies::PolicyStatus statusForTarget(cmTarget const* tgt, #undef RETURN_POLICY - assert("!Unreachable code. Not a valid policy"); + assert(0 && "Unreachable code. Not a valid policy"); return cmPolicies::WARN; } @@ -1431,7 +1443,7 @@ cmPolicies::PolicyID policyForString(const char *policy_id) #undef RETURN_POLICY_ID - assert("!Unreachable code. Not a valid policy"); + assert(0 && "Unreachable code. Not a valid policy"); return cmPolicies::CMP0002; } @@ -2014,7 +2026,7 @@ std::string GeneratorExpressionContent::EvaluateParameters( } else { - cmOStringStream e; + std::ostringstream e; e << "$<" + identifier + "> expression requires " << numExpected << " comma separated parameters, but got " @@ -2040,30 +2052,9 @@ std::string GeneratorExpressionContent::EvaluateParameters( } //---------------------------------------------------------------------------- -static void deleteAll(const std::vector<cmGeneratorExpressionEvaluator*> &c) -{ - std::vector<cmGeneratorExpressionEvaluator*>::const_iterator it - = c.begin(); - const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end - = c.end(); - for ( ; it != end; ++it) - { - delete *it; - } -} - -//---------------------------------------------------------------------------- GeneratorExpressionContent::~GeneratorExpressionContent() { - deleteAll(this->IdentifierChildren); - - typedef std::vector<cmGeneratorExpressionEvaluator*> EvaluatorVector; - std::vector<EvaluatorVector>::const_iterator pit = - this->ParamChildren.begin(); - const std::vector<EvaluatorVector>::const_iterator pend = - this->ParamChildren.end(); - for ( ; pit != pend; ++pit) - { - deleteAll(*pit); - } + cmDeleteAll(this->IdentifierChildren); + std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(), + cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*> >); } diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 8a529e8..0bf1797 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -31,6 +31,7 @@ struct cmGeneratorExpressionContext std::set<cmTarget*> DependTargets; std::set<cmTarget const*> AllTargets; std::set<std::string> SeenTargetProperties; + std::set<cmTarget const*> SourceSensitiveTargets; std::map<cmTarget const*, std::map<std::string, std::string> > MaxLanguageStandard; cmMakefile *Makefile; diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index a41a6e5..a17da8c 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -39,7 +39,7 @@ void cmGeneratorExpressionParser::Parse( static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result, std::vector<cmGeneratorExpressionToken>::const_iterator it) { - if (result.size() > 0 + if (!result.empty() && (*(result.end() - 1))->GetType() == cmGeneratorExpressionEvaluator::Text) { @@ -57,7 +57,7 @@ static void extendText(std::vector<cmGeneratorExpressionEvaluator*> &result, static void extendResult(std::vector<cmGeneratorExpressionEvaluator*> &result, const std::vector<cmGeneratorExpressionEvaluator*> &contents) { - if (result.size() > 0 + if (!result.empty() && (*(result.end() - 1))->GetType() == cmGeneratorExpressionEvaluator::Text && (*contents.begin())->GetType() @@ -256,7 +256,7 @@ void cmGeneratorExpressionParser::ParseContent( { if (this->NestingLevel == 0) { - if (result.size() > 0 + if (!result.empty() && (*(result.end() - 1))->GetType() == cmGeneratorExpressionEvaluator::Text) { @@ -292,11 +292,11 @@ void cmGeneratorExpressionParser::ParseContent( } else { - assert(!"Got unexpected syntax token."); + assert(0 && "Got unexpected syntax token."); } assert(this->it != this->Tokens.end()); ++this->it; return; } - assert(!"Unhandled token in generator expression."); + assert(0 && "Unhandled token in generator expression."); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 1d1225f..8d18c3a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -31,7 +31,7 @@ void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib, { if(!badObjLib.empty()) { - cmOStringStream e; + std::ostringstream e; e << "OBJECT library \"" << target->GetName() << "\" contains:\n"; for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin(); i != badObjLib.end(); ++i) @@ -56,7 +56,6 @@ struct ModuleDefinitionFileTag {}; struct AppManifestTag{}; struct CertificatesTag{}; -#if !defined(_MSC_VER) || _MSC_VER >= 1310 template<typename Tag, typename OtherTag> struct IsSameTag { @@ -72,25 +71,6 @@ struct IsSameTag<Tag, Tag> Result = true }; }; -#else -struct IsSameTagBase -{ - typedef char (&no_type)[1]; - typedef char (&yes_type)[2]; - template<typename T> struct Check; - template<typename T> static yes_type check(Check<T>*, Check<T>*); - static no_type check(...); -}; -template<typename Tag1, typename Tag2> -struct IsSameTag: public IsSameTagBase -{ - enum { - Result = (sizeof(check(static_cast< Check<Tag1>* >(0), - static_cast< Check<Tag2>* >(0))) == - sizeof(yes_type)) - }; -}; -#endif template<bool> struct DoAccept @@ -509,11 +489,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, unique.insert(*li); } result.clear(); - for(std::set<std::string>::iterator li = unique.begin(); - li != unique.end(); ++li) - { - result.push_back(*li); - } + result.insert(result.end(), unique.begin(), unique.end()); IncludeCacheType::value_type entry(config_upper, result); iter = this->SystemIncludesCache.insert(entry).first; @@ -646,6 +622,17 @@ cmTargetTraceDependencies si != sources.end(); ++si) { cmSourceFile* sf = *si; + const std::set<cmTarget const*> tgts = + this->GlobalGenerator->GetFilenameTargetDepends(sf); + if (tgts.find(this->Target) != tgts.end()) + { + std::ostringstream e; + e << "Evaluation output file\n \"" << sf->GetFullPath() + << "\"\ndepends on the sources of a target it is used in. This " + "is a dependency loop and is not allowed."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } if(emitted.insert(sf).second && this->SourcesQueued.insert(sf).second) { this->SourceQueue.push(sf); @@ -831,11 +818,7 @@ cmTargetTraceDependencies = ge.Parse(*cli); cge->Evaluate(this->Makefile, "", true); std::set<cmTarget*> geTargets = cge->GetTargets(); - for(std::set<cmTarget*>::const_iterator it = geTargets.begin(); - it != geTargets.end(); ++it) - { - targets.insert(*it); - } + targets.insert(geTargets.begin(), geTargets.end()); } } diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index e88f498..e193cf5 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -33,7 +33,7 @@ bool cmGetCMakePropertyCommand { int cacheonly = 0; std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly); - if (vars.size()>0) + if (!vars.empty()) { output = vars[0]; } diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx index 77850af..9aceb39 100644 --- a/Source/cmGetFilenameComponentCommand.cxx +++ b/Source/cmGetFilenameComponentCommand.cxx @@ -79,7 +79,7 @@ bool cmGetFilenameComponentCommand } } } - cmSystemTools::SplitProgramFromArgs(filename.c_str(), + cmSystemTools::SplitProgramFromArgs(filename, result, programArgs); } else if (args[2] == "EXT") @@ -113,7 +113,7 @@ bool cmGetFilenameComponentCommand if(args.size() == 4 && args[3] == "CACHE") { - if(programArgs.size() && storeArgs.size()) + if(!programArgs.empty() && !storeArgs.empty()) { this->Makefile->AddCacheDefinition (storeArgs, programArgs.c_str(), @@ -127,7 +127,7 @@ bool cmGetFilenameComponentCommand } else { - if(programArgs.size() && storeArgs.size()) + if(!programArgs.empty() && !storeArgs.empty()) { this->Makefile->AddDefinition(storeArgs, programArgs.c_str()); } diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index 3c59c25..f0b2686 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -73,7 +73,7 @@ bool cmGetPropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid scope " << args[1] << ". " << "Valid scopes are " << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."; @@ -122,7 +122,7 @@ bool cmGetPropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid argument \"" << args[i] << "\"."; this->SetError(e.str()); return false; @@ -312,7 +312,7 @@ bool cmGetPropertyCommand::HandleTargetMode() } else { - cmOStringStream e; + std::ostringstream e; e << "could not find TARGET " << this->Name << ". Perhaps it has not yet been created."; this->SetError(e.str()); @@ -338,7 +338,7 @@ bool cmGetPropertyCommand::HandleSourceMode() } else { - cmOStringStream e; + std::ostringstream e; e << "given SOURCE name that could not be found or created: " << this->Name; this->SetError(e.str()); @@ -362,7 +362,7 @@ bool cmGetPropertyCommand::HandleTestMode() } // If not found it is an error. - cmOStringStream e; + std::ostringstream e; e << "given TEST name that does not exist: " << this->Name; this->SetError(e.str()); return false; @@ -423,7 +423,7 @@ bool cmGetPropertyCommand::HandleInstallMode() } else { - cmOStringStream e; + std::ostringstream e; e << "given INSTALL name that could not be found or created: " << this->Name; this->SetError(e.str()); diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index aa6f0c1..eed19f4 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -23,6 +23,7 @@ bool cmGetTargetPropertyCommand std::string var = args[0]; const std::string& targetName = args[1]; std::string prop; + bool prop_exists = false; if(args[2] == "ALIASED_TARGET") { @@ -32,6 +33,7 @@ bool cmGetTargetPropertyCommand this->Makefile->FindTargetToUse(targetName)) { prop = target->GetName(); + prop_exists = true; } } } @@ -42,12 +44,13 @@ bool cmGetTargetPropertyCommand if(prop_cstr) { prop = prop_cstr; + prop_exists = true; } } else { bool issueMessage = false; - cmOStringStream e; + std::ostringstream e; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0045)) { @@ -74,7 +77,7 @@ bool cmGetTargetPropertyCommand } } } - if (!prop.empty()) + if (prop_exists) { this->Makefile->AddDefinition(var, prop.c_str()); return true; diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 6c20952..950d440 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -49,6 +49,7 @@ cmLocalGenerator *cmGlobalBorlandMakefileGenerator::CreateLocalGenerator() lg->SetUnixCD(false); lg->SetMakeCommandEscapeTargetTwice(true); lg->SetBorlandMakeCurlyHack(true); + lg->SetNoMultiOutputMultiDepRules(true); return lg; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index a729c3d..dd3b1ec 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -11,6 +11,9 @@ ============================================================================*/ #if defined(_WIN32) && !defined(__CYGWIN__) #include "windows.h" // this must be first to define GetCurrentDirectory +#if defined(_MSC_VER) && _MSC_VER >= 1800 +# define KWSYS_WINDOWS_DEPRECATED_GetVersionEx +#endif #endif #include "cmGlobalGenerator.h" @@ -35,6 +38,8 @@ #if defined(CMAKE_BUILD_WITH_CMAKE) # include <cmsys/MD5.h> +# include "cm_jsoncpp_value.h" +# include "cm_jsoncpp_writer.h" #endif #include <stdlib.h> // required for atof @@ -85,7 +90,7 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p, } else { - cmOStringStream e; + std::ostringstream e; e << "Generator\n" " " << this->GetName() << "\n" @@ -106,7 +111,7 @@ bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, } else { - cmOStringStream e; + std::ostringstream e; e << "Generator\n" " " << this->GetName() << "\n" @@ -171,7 +176,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, { path = name; } - if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) + if((path.empty() || !cmSystemTools::FileExists(path.c_str())) && (optional==false)) { return; @@ -262,7 +267,7 @@ cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const // Find the make program for the generator, required for try compiles void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) { - if(this->FindMakeProgramFile.size() == 0) + if(this->FindMakeProgramFile.empty()) { cmSystemTools::Error( "Generator implementation error, " @@ -273,7 +278,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) { std::string setMakeProgram = mf->GetModulesFile(this->FindMakeProgramFile.c_str()); - if(setMakeProgram.size()) + if(!setMakeProgram.empty()) { mf->ReadListFile(0, setMakeProgram.c_str()); } @@ -281,7 +286,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) if(!mf->GetDefinition("CMAKE_MAKE_PROGRAM") || cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) { - cmOStringStream err; + std::ostringstream err; err << "CMake was unable to find a build program corresponding to \"" << this->GetName() << "\". CMAKE_MAKE_PROGRAM is not set. You " << "probably need to select a different build tool."; @@ -297,11 +302,11 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) { std::string dir; std::string file; - cmSystemTools::SplitProgramPath(makeProgram.c_str(), + cmSystemTools::SplitProgramPath(makeProgram, dir, file); std::string saveFile = file; cmSystemTools::GetShortPath(makeProgram, makeProgram); - cmSystemTools::SplitProgramPath(makeProgram.c_str(), + cmSystemTools::SplitProgramPath(makeProgram, dir, file); makeProgram = dir; makeProgram += "/"; @@ -380,7 +385,7 @@ void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, cmMakefile *mf, bool optional) { - if(languages.size() == 0) + if(languages.empty()) { cmSystemTools::Error("EnableLanguage must have a lang specified!"); cmSystemTools::SetFatalErrorOccured(); @@ -402,7 +407,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, const char* lang = li->c_str(); if(this->LanguagesReady.find(lang) == this->LanguagesReady.end()) { - cmOStringStream e; + std::ostringstream e; e << "The test project needs language " << lang << " which is not enabled."; this->TryCompileOuterMakefile @@ -423,7 +428,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, // If the configuration files path has been set, // then we are in a try compile and need to copy the enable language // files from the parent cmake bin dir, into the try compile bin dir - if(this->ConfiguredFilesPath.size()) + if(!this->ConfiguredFilesPath.empty()) { rootBin = this->ConfiguredFilesPath; } @@ -456,8 +461,15 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(osvi)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); +#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx +# pragma warning (push) +# pragma warning (disable:4996) +#endif GetVersionEx (&osvi); - cmOStringStream windowsVersionString; +#ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx +# pragma warning (pop) +#endif + std::ostringstream windowsVersionString; windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion; windowsVersionString.str(); mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", @@ -597,7 +609,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, std::string env = envVar; env += "="; env += envVarValue; - cmSystemTools::PutEnv(env.c_str()); + cmSystemTools::PutEnv(env); } // if determineLanguage was called then load the file it @@ -650,7 +662,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, std::string compilerEnv = "CMAKE_"; compilerEnv += lang; compilerEnv += "_COMPILER_ENV_VAR"; - cmOStringStream noCompiler; + std::ostringstream noCompiler; const char* compilerFile = mf->GetDefinition(compilerName); if(!compilerFile || !*compilerFile || cmSystemTools::IsNOTFOUND(compilerFile)) @@ -842,7 +854,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf, if(!this->CMakeInstance->GetIsInTryCompile() && mf->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0025")) { - cmOStringStream w; + std::ostringstream w; w << policies->GetPolicyWarning(cmPolicies::CMP0025) << "\n" "Converting " << lang << " compiler id \"AppleClang\" to \"Clang\" for compatibility." @@ -874,7 +886,7 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf, if(!this->CMakeInstance->GetIsInTryCompile() && mf->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0047")) { - cmOStringStream w; + std::ostringstream w; w << policies->GetPolicyWarning(cmPolicies::CMP0047) << "\n" "Converting " << lang << " compiler id \"QCC\" to \"GNU\" for compatibility." @@ -1137,7 +1149,7 @@ void cmGlobalGenerator::Configure() if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE) { - cmOStringStream msg; + std::ostringstream msg; if(cmSystemTools::GetErrorOccuredFlag()) { msg << "Configuring incomplete, errors occurred!"; @@ -1186,7 +1198,7 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const } // This generator does not support duplicate custom targets. - cmOStringStream e; + std::ostringstream e; e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS " << "global property. " << "The \"" << this->GetName() << "\" generator does not support " @@ -1253,8 +1265,6 @@ void cmGlobalGenerator::Generate() // Create per-target generator information. this->CreateGeneratorTargets(); - this->ForceLinkerLanguages(); - #ifdef CMAKE_BUILD_WITH_CMAKE for (AutogensType::iterator it = autogens.begin(); it != autogens.end(); ++it) @@ -1270,6 +1280,8 @@ void cmGlobalGenerator::Generate() this->LocalGenerators[i]->TraceDependencies(); } + this->ForceLinkerLanguages(); + // Compute the manifest of main targets generated. for (i = 0; i < this->LocalGenerators.size(); ++i) { @@ -1336,7 +1348,7 @@ void cmGlobalGenerator::Generate() if(!this->CMP0042WarnTargets.empty()) { - cmOStringStream w; + std::ostringstream w; w << (this->GetCMakeInstance()->GetPolicies()-> GetPolicyWarning(cmPolicies::CMP0042)) << "\n"; @@ -1500,34 +1512,16 @@ void cmGlobalGenerator::CreateGeneratorTargets() //---------------------------------------------------------------------------- void cmGlobalGenerator::ClearGeneratorMembers() { - for(cmGeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); - i != this->GeneratorTargets.end(); ++i) - { - delete i->second; - } + cmDeleteAll(this->GeneratorTargets); this->GeneratorTargets.clear(); - for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator - li = this->EvaluationFiles.begin(); - li != this->EvaluationFiles.end(); - ++li) - { - delete *li; - } + cmDeleteAll(this->EvaluationFiles); this->EvaluationFiles.clear(); - for(std::map<std::string, cmExportBuildFileGenerator*>::iterator - i = this->BuildExportSets.begin(); - i != this->BuildExportSets.end(); ++i) - { - delete i->second; - } + cmDeleteAll(this->BuildExportSets); this->BuildExportSets.clear(); - for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) - { - delete this->LocalGenerators[i]; - } + cmDeleteAll(this->LocalGenerators); this->LocalGenerators.clear(); this->ExportSets.clear(); @@ -1640,7 +1634,7 @@ void cmGlobalGenerator::CheckLocalGenerators() static_cast<float>(this->LocalGenerators.size())); } - if(notFoundMap.size()) + if(!notFoundMap.empty()) { std::string notFoundVars; for(std::map<std::string, std::string>::const_iterator @@ -2197,7 +2191,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) = this->CreateGlobalTarget(this->GetPackageTargetName(), "Run CPack packaging tool...", &cpackCommandLines, depends, - workingDir.c_str()); + workingDir.c_str(), /*uses_terminal*/false); } // CPack source const char* packageSourceTargetName = this->GetPackageSourceTargetName(); @@ -2221,8 +2215,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) = this->CreateGlobalTarget(packageSourceTargetName, "Run CPack packaging tool for source...", &cpackCommandLines, depends, - workingDir.c_str() - ); + workingDir.c_str(), /*uses_terminal*/false); } } @@ -2247,7 +2240,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) cpackCommandLines.push_back(singleLine); (*targets)[this->GetTestTargetName()] = this->CreateGlobalTarget(this->GetTestTargetName(), - "Running tests...", &cpackCommandLines, depends, 0); + "Running tests...", &cpackCommandLines, depends, 0, + /*uses_terminal*/false); } //Edit Cache @@ -2270,7 +2264,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)[editCacheTargetName] = this->CreateGlobalTarget( editCacheTargetName, "Running CMake cache editor...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/true); } else { @@ -2283,7 +2277,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) this->CreateGlobalTarget( editCacheTargetName, "No interactive CMake dialog available...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); } } @@ -2302,7 +2296,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)[rebuildCacheTargetName] = this->CreateGlobalTarget( rebuildCacheTargetName, "Running CMake to regenerate build system...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); } //Install @@ -2321,8 +2315,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end()); depends.erase(depends.begin(), depends.end()); - cmOStringStream ostr; - if ( componentsSet->size() > 0 ) + std::ostringstream ostr; + if (!componentsSet->empty()) { ostr << "Available install components are:"; std::set<std::string>::iterator it; @@ -2342,7 +2336,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)["list_install_components"] = this->CreateGlobalTarget("list_install_components", ostr.str().c_str(), - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); } std::string cmd = cmakeCommand; cpackCommandLines.erase(cpackCommandLines.begin(), @@ -2362,7 +2356,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) depends.push_back(this->GetAllTargetName()); } } - if(mf->GetDefinition("CMake_BINARY_DIR")) + if(mf->GetDefinition("CMake_BINARY_DIR") && + !mf->IsOn("CMAKE_CROSSCOMPILING")) { // We are building CMake itself. We cannot use the original // executable to install over itself. The generator will @@ -2382,7 +2377,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)[this->GetInstallTargetName()] = this->CreateGlobalTarget( this->GetInstallTargetName(), "Install the project...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); // install_local if(const char* install_local = this->GetInstallLocalTargetName()) @@ -2398,7 +2393,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)[install_local] = this->CreateGlobalTarget( install_local, "Installing only the local directory...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); } // install_strip @@ -2415,7 +2410,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) (*targets)[install_strip] = this->CreateGlobalTarget( install_strip, "Installing the project stripped...", - &cpackCommandLines, depends, 0); + &cpackCommandLines, depends, 0, /*uses_terminal*/false); } } } @@ -2458,24 +2453,24 @@ void cmGlobalGenerator::EnableMinGWLanguage(cmMakefile *mf) this->FindMakeProgram(mf); std::string makeProgram = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); std::vector<std::string> locations; - locations.push_back(cmSystemTools::GetProgramPath(makeProgram.c_str())); + locations.push_back(cmSystemTools::GetProgramPath(makeProgram)); locations.push_back("/mingw/bin"); locations.push_back("c:/mingw/bin"); std::string tgcc = cmSystemTools::FindProgram("gcc", locations); std::string gcc = "gcc.exe"; - if(tgcc.size()) + if(!tgcc.empty()) { gcc = tgcc; } std::string tgxx = cmSystemTools::FindProgram("g++", locations); std::string gxx = "g++.exe"; - if(tgxx.size()) + if(!tgxx.empty()) { gxx = tgxx; } std::string trc = cmSystemTools::FindProgram("windres", locations); std::string rc = "windres.exe"; - if(trc.size()) + if(!trc.empty()) { rc = trc; } @@ -2489,7 +2484,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( const std::string& name, const char* message, const cmCustomCommandLines* commandLines, std::vector<std::string> depends, - const char* workingDirectory) + const char* workingDirectory, + bool uses_terminal) { // Package cmTarget target; @@ -2498,10 +2494,12 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget( target.SetProperty("EXCLUDE_FROM_ALL","TRUE"); std::vector<std::string> no_outputs; + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; // Store the custom command in the target. - cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0, - workingDirectory); + cmCustomCommand cc(0, no_outputs, no_byproducts, no_depends, + *commandLines, 0, workingDirectory); + cc.SetUsesTerminal(uses_terminal); target.AddPostBuildCommand(cc); target.SetProperty("EchoString", message); std::vector<std::string>::iterator dit; @@ -2711,7 +2709,9 @@ void cmGlobalGenerator::AddToManifest(const std::string& config, // Add to the content listing for the file's directory. std::string dir = cmSystemTools::GetFilenamePath(f); std::string file = cmSystemTools::GetFilenameName(f); - this->DirectoryContentMap[dir].insert(file); + DirectoryContent& dc = this->DirectoryContentMap[dir]; + dc.Generated.insert(file); + dc.All.insert(file); } //---------------------------------------------------------------------------- @@ -2719,25 +2719,32 @@ std::set<std::string> const& cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk) { DirectoryContent& dc = this->DirectoryContentMap[dir]; - if(needDisk && !dc.LoadedFromDisk) + if(needDisk) { - // Load the directory content from disk. - cmsys::Directory d; - if(d.Load(dir)) + long mt = cmSystemTools::ModifiedTime(dir); + if (mt != dc.LastDiskTime) { - unsigned long n = d.GetNumberOfFiles(); - for(unsigned long i = 0; i < n; ++i) + // Reset to non-loaded directory content. + dc.All = dc.Generated; + + // Load the directory content from disk. + cmsys::Directory d; + if(d.Load(dir)) { - const char* f = d.GetFile(i); - if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0) + unsigned long n = d.GetNumberOfFiles(); + for(unsigned long i = 0; i < n; ++i) { - dc.insert(f); + const char* f = d.GetFile(i); + if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0) + { + dc.All.insert(f); + } } } + dc.LastDiskTime = mt; } - dc.LoadedFromDisk = true; } - return dc; + return dc.All; } //---------------------------------------------------------------------------- @@ -2906,10 +2913,21 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target) std::string dir = target->GetSupportDirectory(); std::string file = dir; file += "/Labels.txt"; + std::string json_file = dir + "/Labels.json"; +#ifdef CMAKE_BUILD_WITH_CMAKE // Check whether labels are enabled for this target. if(const char* value = target->GetProperty("LABELS")) { + Json::Value lj_root(Json::objectValue); + Json::Value& lj_target = + lj_root["target"] = Json::objectValue; + lj_target["name"] = target->GetName(); + Json::Value& lj_target_labels = + lj_target["labels"] = Json::arrayValue; + Json::Value& lj_sources = + lj_root["sources"] = Json::arrayValue; + cmSystemTools::MakeDirectory(dir.c_str()); cmGeneratedFileStream fout(file.c_str()); @@ -2924,6 +2942,7 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target) li != labels.end(); ++li) { fout << " " << *li << "\n"; + lj_target_labels.append(*li); } } @@ -2949,23 +2968,33 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target) { continue; } + Json::Value& lj_source = lj_sources.append(Json::objectValue); cmSourceFile* sf = *si; - fout << sf->GetFullPath() << "\n"; + std::string const& sfp = sf->GetFullPath(); + fout << sfp << "\n"; + lj_source["file"] = sfp; if(const char* svalue = sf->GetProperty("LABELS")) { labels.clear(); + Json::Value& lj_source_labels = + lj_source["labels"] = Json::arrayValue; cmSystemTools::ExpandListArgument(svalue, labels); for(std::vector<std::string>::const_iterator li = labels.begin(); li != labels.end(); ++li) { fout << " " << *li << "\n"; + lj_source_labels.append(*li); } } } + cmGeneratedFileStream json_fout(json_file.c_str()); + json_fout << lj_root; } else +#endif { cmSystemTools::RemoveFile(file); + cmSystemTools::RemoveFile(json_file); } } @@ -2983,6 +3012,32 @@ std::string cmGlobalGenerator::EscapeJSON(const std::string& s) { } //---------------------------------------------------------------------------- +void cmGlobalGenerator::SetFilenameTargetDepends(cmSourceFile* sf, + std::set<cmTarget const*> tgts) +{ + this->FilenameTargetDepends[sf] = tgts; +} + +//---------------------------------------------------------------------------- +std::set<cmTarget const*> const& +cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const { + return this->FilenameTargetDepends[sf]; +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::CreateEvaluationSourceFiles( + std::string const& config) const +{ + for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator + li = this->EvaluationFiles.begin(); + li != this->EvaluationFiles.end(); + ++li) + { + (*li)->CreateOutputFile(config); + } +} + +//---------------------------------------------------------------------------- void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile, cmsys::auto_ptr<cmCompiledGeneratorExpression> outputExpr, cmMakefile *makefile, diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index ddd7e91..08f061a 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -23,6 +23,7 @@ #include "cmGeneratorExpression.h" #if defined(CMAKE_BUILD_WITH_CMAKE) +# include "cmFileLockPool.h" # include <cmsys/hash_map.hxx> #endif @@ -254,9 +255,9 @@ public: cmTargetManifest const& GetTargetManifest() const { return this->TargetManifest; } - /** Get the content of a directory. Directory listings are loaded - from disk at most once and cached. During the generation step - the content will include the target files to be built even if + /** Get the content of a directory. Directory listings are cached + and re-loaded from disk only when modified. During the generation + step the content will include the target files to be built even if they do not yet exist. */ std::set<std::string> const& GetDirectoryContent(std::string const& dir, bool needDisk = true); @@ -341,6 +342,17 @@ public: bool GenerateCPackPropertiesFile(); + void CreateEvaluationSourceFiles(std::string const& config) const; + + void SetFilenameTargetDepends(cmSourceFile* sf, + std::set<cmTarget const*> tgts); + std::set<cmTarget const*> const& + GetFilenameTargetDepends(cmSourceFile* sf) const; + +#if defined(CMAKE_BUILD_WITH_CMAKE) + cmFileLockPool& GetFileLockPool() { return FileLockPool; } +#endif + protected: virtual void Generate(); @@ -378,7 +390,8 @@ protected: void CreateDefaultGlobalTargets(cmTargets* targets); cmTarget CreateGlobalTarget(const std::string& name, const char* message, const cmCustomCommandLines* commandLines, - std::vector<std::string> depends, const char* workingDir); + std::vector<std::string> depends, const char* workingDir, + bool uses_terminal); bool NeedSymbolicMark; bool UseLinkScript; @@ -473,13 +486,14 @@ private: virtual const char* GetBuildIgnoreErrorsFlag() const { return 0; } // Cache directory content and target files to be built. - struct DirectoryContent: public std::set<std::string> + struct DirectoryContent { - typedef std::set<std::string> derived; - bool LoadedFromDisk; - DirectoryContent(): LoadedFromDisk(false) {} + long LastDiskTime; + std::set<std::string> All; + std::set<std::string> Generated; + DirectoryContent(): LastDiskTime(-1) {} DirectoryContent(DirectoryContent const& dc): - derived(dc), LoadedFromDisk(dc.LoadedFromDisk) {} + LastDiskTime(dc.LastDiskTime), All(dc.All), Generated(dc.Generated) {} }; std::map<std::string, DirectoryContent> DirectoryContentMap; @@ -488,6 +502,14 @@ private: // track targets to issue CMP0042 warning for. std::set<std::string> CMP0042WarnTargets; + + mutable std::map<cmSourceFile*, std::set<cmTarget const*> > + FilenameTargetDepends; + +#if defined(CMAKE_BUILD_WITH_CMAKE) + // Pool of file locks + cmFileLockPool FileLockPool; +#endif }; #endif diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index ee0c583..b9c01fa 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -236,7 +236,7 @@ bool cmGlobalKdevelopGenerator // make it relative to the project dir cmSystemTools::ReplaceString(tmp, projectDir.c_str(), ""); // only put relative paths - if (tmp.size() && tmp[0] != '/') + if (!tmp.empty() && tmp[0] != '/') { fout << tmp.c_str() <<"\n"; } diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 498ae9a..3c07be1 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -71,7 +71,7 @@ std::string cmGlobalNinjaGenerator::EncodeIdent(const std::string &ident, if (std::find_if(ident.begin(), ident.end(), std::not1(std::ptr_fun(IsIdentChar))) != ident.end()) { static unsigned VarNum = 0; - cmOStringStream names; + std::ostringstream names; names << "ident" << VarNum++; vars << names.str() << " = " << ident << "\n"; return "$" + names.str(); @@ -191,7 +191,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, build += " " + rule; // Write the variables bound to this build statement. - cmOStringStream variable_assignments; + std::ostringstream variable_assignments; for(cmNinjaVars::const_iterator i = variables.begin(); i != variables.end(); ++i) cmGlobalNinjaGenerator::WriteVariable(variable_assignments, @@ -242,7 +242,7 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ true, + /*restat*/ "1", /*generator*/ false); } @@ -250,6 +250,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, const std::string& description, const std::string& comment, + bool uses_terminal, const cmNinjaDeps& outputs, const cmNinjaDeps& deps, const cmNinjaDeps& orderOnly) @@ -266,6 +267,10 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, cmNinjaVars vars; vars["COMMAND"] = cmd; vars["DESC"] = EncodeLiteral(description); + if (uses_terminal && SupportsConsolePool()) + { + vars["pool"] = "console"; + } this->WriteBuild(*this->BuildFileStream, comment, @@ -290,7 +295,7 @@ cmGlobalNinjaGenerator::AddMacOSXContentRule() cmLocalGenerator *lg = this->LocalGenerators[0]; cmMakefile* mfRoot = lg->GetMakefile(); - cmOStringStream cmd; + std::ostringstream cmd; cmd << lg->ConvertToOutputFormat( mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), cmLocalGenerator::SHELL) @@ -304,7 +309,7 @@ cmGlobalNinjaGenerator::AddMacOSXContentRule() /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ false, + /*restat*/ "", /*generator*/ false); } @@ -339,7 +344,7 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, - bool restat, + const std::string& restat, bool generator) { // Make sure the rule has a name. @@ -403,10 +408,10 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, os << "rspfile_content = " << rspcontent << "\n"; } - if(restat) + if(!restat.empty()) { cmGlobalNinjaGenerator::Indent(os, 1); - os << "restat = 1\n"; + os << "restat = " << restat << "\n"; } if(generator) @@ -602,7 +607,7 @@ void cmGlobalNinjaGenerator::AddRule(const std::string& name, const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, - bool restat, + const std::string& restat, bool generator) { // Do not add the same rule twice. @@ -826,6 +831,7 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps)); WriteCustomCommandBuild(/*command=*/"", /*description=*/"", "Assume dependencies for generated source file.", + /*uses_terminal*/false, cmNinjaDeps(1, i->first), deps); } } @@ -1015,12 +1021,9 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) } //insert outputs from all WirteBuild commands - for(std::set<std::string>::iterator i = this->CombinedBuildOutputs.begin(); - i != this->CombinedBuildOutputs.end(); ++i) - { - //these paths have already be encoded when added to CombinedBuildOutputs - knownDependencies.insert(*i); - } + //these paths have already be encoded when added to CombinedBuildOutputs + knownDependencies.insert(this->CombinedBuildOutputs.begin(), + this->CombinedBuildOutputs.end()); //after we have combined the data into knownDependencies we have no need //to keep this data around @@ -1097,7 +1100,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmLocalGenerator *lg = this->LocalGenerators[0]; cmMakefile* mfRoot = lg->GetMakefile(); - cmOStringStream cmd; + std::ostringstream cmd; cmd << lg->ConvertToOutputFormat( mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), cmLocalGenerator::SHELL) @@ -1116,7 +1119,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", - /*restat=*/ false, + /*restat=*/ "", /*generator=*/ true); cmLocalNinjaGenerator *ng = static_cast<cmLocalNinjaGenerator *>(lg); @@ -1141,9 +1144,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) cmNinjaVars variables; // Use 'console' pool to get non buffered output of the CMake re-run call // Available since Ninja 1.5 - if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, - ninjaVersion().c_str(), - "1.5") == false) + if(SupportsConsolePool()) { variables["pool"] = "console"; } @@ -1185,6 +1186,12 @@ std::string cmGlobalNinjaGenerator::ninjaVersion() const return version; } +bool cmGlobalNinjaGenerator::SupportsConsolePool() const +{ + return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, + ninjaVersion().c_str(), "1.5") == false; +} + void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { WriteRule(*this->RulesFileStream, @@ -1196,7 +1203,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", - /*restat=*/ false, + /*restat=*/ "", /*generator=*/ false); WriteBuild(os, "Clean all the built files.", @@ -1219,7 +1226,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) /*deptype=*/ "", /*rspfile=*/ "", /*rspcontent*/ "", - /*restat=*/ false, + /*restat=*/ "", /*generator=*/ false); WriteBuild(os, "Print all primary targets available.", diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index f666ee3..3d443d8 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -103,6 +103,7 @@ public: void WriteCustomCommandBuild(const std::string& command, const std::string& description, const std::string& comment, + bool uses_terminal, const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnly = cmNinjaDeps()); @@ -124,7 +125,7 @@ public: const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, - bool restat, + const std::string& restat, bool generator); /** @@ -244,7 +245,7 @@ public: const std::string& deptype, const std::string& rspfile, const std::string& rspcontent, - bool restat, + const std::string& restat, bool generator); bool HasRule(const std::string& name); @@ -299,6 +300,9 @@ public: virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; std::string ninjaVersion() const; + + bool SupportsConsolePool() const; + protected: /// Overloaded methods. @see cmGlobalGenerator::Generate() diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 3478534..5f1bb83 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -572,7 +572,7 @@ void cmGlobalUnixMakefileGenerator3 if (!targetName.empty()) { cmLocalUnixMakefileGenerator3 *lg; - if (this->LocalGenerators.size()) + if (!this->LocalGenerators.empty()) { lg = static_cast<cmLocalUnixMakefileGenerator3 *> (this->LocalGenerators[0]); @@ -597,7 +597,7 @@ void cmGlobalUnixMakefileGenerator3 tname = lg->Convert(tname,cmLocalGenerator::HOME_OUTPUT); cmSystemTools::ConvertToOutputSlashes(tname); makeCommand.push_back(tname); - if (!this->LocalGenerators.size()) + if (this->LocalGenerators.empty()) { delete lg; } @@ -783,7 +783,7 @@ cmGlobalUnixMakefileGenerator3 lg->GetMakefile()->GetHomeOutputDirectory(); progressDir += cmake::GetCMakeFilesDirectory(); { - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; // all target counts progCmd << lg->Convert(progressDir, @@ -824,7 +824,7 @@ cmGlobalUnixMakefileGenerator3 { // TODO: Convert the total progress count to a make variable. - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # in target progCmd << lg->Convert(progressDir, @@ -841,7 +841,7 @@ cmGlobalUnixMakefileGenerator3 commands.push_back(lg->GetRecursiveMakeCall (tmp.c_str(),localName)); { - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 progCmd << lg->Convert(progressDir, cmLocalGenerator::FULL, diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index d70d2af..531a714 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -156,7 +156,7 @@ cmGlobalVisualStudio10Generator::SetGeneratorToolset(std::string const& ts, if (this->SystemIsWindowsCE && ts.empty() && this->DefaultPlatformToolset.empty()) { - cmOStringStream e; + std::ostringstream e; e << this->GetName() << " Windows CE version '" << this->SystemVersion << "' requires CMAKE_GENERATOR_TOOLSET to be set."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -202,7 +202,7 @@ bool cmGlobalVisualStudio10Generator::InitializeSystem(cmMakefile* mf) { if(this->DefaultPlatformName != "Win32") { - cmOStringStream e; + std::ostringstream e; e << "CMAKE_SYSTEM_NAME is 'Android' but CMAKE_GENERATOR " << "specifies a platform too: '" << this->GetName() << "'"; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -231,7 +231,7 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf) { if (this->DefaultPlatformName != "Win32") { - cmOStringStream e; + std::ostringstream e; e << "CMAKE_SYSTEM_NAME is 'WindowsCE' but CMAKE_GENERATOR " << "specifies a platform too: '" << this->GetName() << "'"; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -246,7 +246,7 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf) //---------------------------------------------------------------------------- bool cmGlobalVisualStudio10Generator::InitializeWindowsPhone(cmMakefile* mf) { - cmOStringStream e; + std::ostringstream e; e << this->GetName() << " does not support Windows Phone."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; @@ -255,13 +255,31 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsPhone(cmMakefile* mf) //---------------------------------------------------------------------------- bool cmGlobalVisualStudio10Generator::InitializeWindowsStore(cmMakefile* mf) { - cmOStringStream e; + std::ostringstream e; e << this->GetName() << " does not support Windows Store."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } //---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset( + std::string& toolset) const +{ + toolset = ""; + return false; +} + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset( + std::string& toolset) const +{ + toolset = ""; + return false; +} + +//---------------------------------------------------------------------------- std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const { if (this->SystemVersion == "8.0") @@ -302,7 +320,7 @@ void cmGlobalVisualStudio10Generator::Generate() if(this->LongestSource.Length > 0) { cmMakefile* mf = this->LongestSource.Target->GetMakefile(); - cmOStringStream e; + std::ostringstream e; e << "The binary and/or source directory paths may be too long to generate " "Visual Studio 10 files for this project. " @@ -556,7 +574,7 @@ bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf) "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\" "Windows\\v7.1;InstallationFolder", winSDK_7_1)) { - cmOStringStream m; + std::ostringstream m; m << "Found Windows SDK v7.1: " << winSDK_7_1; mf->DisplayStatus(m.str().c_str(), -1); this->DefaultPlatformToolset = "Windows7.1SDK"; @@ -564,7 +582,7 @@ bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf) } else { - cmOStringStream e; + std::ostringstream e; e << "Cannot enable 64-bit tools with Visual Studio 2010 Express.\n" << "Install the Microsoft Windows SDK v7.1 to get 64-bit tools:\n" << " http://msdn.microsoft.com/en-us/windows/bb980924.aspx"; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 686dcdf..3b0a5cf 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -118,9 +118,10 @@ protected: virtual bool InitializeWindowsCE(cmMakefile* mf); virtual bool InitializeWindowsPhone(cmMakefile* mf); virtual bool InitializeWindowsStore(cmMakefile* mf); + virtual std::string SelectWindowsCEToolset() const; - virtual std::string SelectWindowsPhoneToolset() const { return ""; } - virtual std::string SelectWindowsStoreToolset() const { return ""; } + virtual bool SelectWindowsPhoneToolset(std::string& toolset) const; + virtual bool SelectWindowsStoreToolset(std::string& toolset) const; virtual const char* GetIDEVersion() { return "10.0"; } diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 39bbdc0..3013200 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -131,12 +131,20 @@ cmGlobalVisualStudio11Generator::MatchesGeneratorName( //---------------------------------------------------------------------------- bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf) { - this->DefaultPlatformToolset = this->SelectWindowsPhoneToolset(); - if(this->DefaultPlatformToolset.empty()) + if(!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) { - cmOStringStream e; - e << this->GetName() << " supports Windows Phone '8.0', but not '" - << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + std::ostringstream e; + if(this->DefaultPlatformToolset.empty()) + { + e << this->GetName() << " supports Windows Phone '8.0', but not '" + << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + } + else + { + e << "A Windows Phone component with CMake requires both the Windows " + << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion + << "' SDK. Please make sure that you have both installed"; + } mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -146,12 +154,20 @@ bool cmGlobalVisualStudio11Generator::InitializeWindowsPhone(cmMakefile* mf) //---------------------------------------------------------------------------- bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf) { - this->DefaultPlatformToolset = this->SelectWindowsStoreToolset(); - if(this->DefaultPlatformToolset.empty()) + if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) { - cmOStringStream e; - e << this->GetName() << " supports Windows Store '8.0', but not '" - << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + std::ostringstream e; + if(this->DefaultPlatformToolset.empty()) + { + e << this->GetName() << " supports Windows Store '8.0', but not '" + << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + } + else + { + e << "A Windows Store component with CMake requires both the Windows " + << "Desktop SDK as well as the Windows Store '" << this->SystemVersion + << "' SDK. Please make sure that you have both installed"; + } mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -159,23 +175,47 @@ bool cmGlobalVisualStudio11Generator::InitializeWindowsStore(cmMakefile* mf) } //---------------------------------------------------------------------------- -std::string cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset() const +bool +cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset( + std::string& toolset) const { if(this->SystemVersion == "8.0") { - return "v110_wp80"; + if (this->IsWindowsPhoneToolsetInstalled() && + this->IsWindowsDesktopToolsetInstalled()) + { + toolset = "v110_wp80"; + return true; + } + else + { + return false; + } } - return this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(); + return + this->cmGlobalVisualStudio10Generator::SelectWindowsPhoneToolset(toolset); } //---------------------------------------------------------------------------- -std::string cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset() const +bool +cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset( + std::string& toolset) const { if(this->SystemVersion == "8.0") { - return "v110"; + if(this->IsWindowsStoreToolsetInstalled() && + this->IsWindowsDesktopToolsetInstalled()) + { + toolset = "v110"; + return true; + } + else + { + return false; + } } - return this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(); + return + this->cmGlobalVisualStudio10Generator::SelectWindowsStoreToolset(toolset); } //---------------------------------------------------------------------------- @@ -256,3 +296,54 @@ cmGlobalVisualStudio11Generator::NeedsDeploy(cmTarget::TargetType type) const } return cmGlobalVisualStudio10Generator::NeedsDeploy(type); } + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio11Generator::IsWindowsDesktopToolsetInstalled() const +{ + const char desktop80Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "VisualStudio\\11.0\\VC\\Libraries\\Extended"; + const char VS2012DesktopExpressKey[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "WDExpress\\11.0;InstallDir"; + + std::vector<std::string> subkeys; + std::string path; + return cmSystemTools::ReadRegistryValue(VS2012DesktopExpressKey, + path, + cmSystemTools::KeyWOW64_32) || + cmSystemTools::GetRegistrySubKeys(desktop80Key, + subkeys, + cmSystemTools::KeyWOW64_32); +} + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio11Generator::IsWindowsPhoneToolsetInstalled() const +{ + const char wp80Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "Microsoft SDKs\\WindowsPhone\\v8.0\\" + "Install Path;Install Path"; + + std::string path; + cmSystemTools::ReadRegistryValue(wp80Key, + path, + cmSystemTools::KeyWOW64_32); + return !path.empty(); +} + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio11Generator::IsWindowsStoreToolsetInstalled() const +{ + const char win80Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "VisualStudio\\11.0\\VC\\Libraries\\Core\\Arm"; + + std::vector<std::string> subkeys; + return cmSystemTools::GetRegistrySubKeys(win80Key, + subkeys, + cmSystemTools::KeyWOW64_32); +} diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index bbd935c..c79dc97 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -36,8 +36,15 @@ public: protected: virtual bool InitializeWindowsPhone(cmMakefile* mf); virtual bool InitializeWindowsStore(cmMakefile* mf); - virtual std::string SelectWindowsPhoneToolset() const; - virtual std::string SelectWindowsStoreToolset() const; + virtual bool SelectWindowsPhoneToolset(std::string& toolset) const; + virtual bool SelectWindowsStoreToolset(std::string& toolset) const; + + // These aren't virtual because we need to check if the selected version + // of the toolset is installed + bool IsWindowsDesktopToolsetInstalled() const; + bool IsWindowsPhoneToolsetInstalled() const; + bool IsWindowsStoreToolsetInstalled() const; + virtual const char* GetIDEVersion() { return "11.0"; } bool UseFolderProperty(); static std::set<std::string> GetInstalledWindowsCESDKs(); diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index 29ecfe0..2bc9379 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -111,12 +111,20 @@ cmGlobalVisualStudio12Generator::MatchesGeneratorName( //---------------------------------------------------------------------------- bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf) { - this->DefaultPlatformToolset = this->SelectWindowsPhoneToolset(); - if(this->DefaultPlatformToolset.empty()) + if(!this->SelectWindowsPhoneToolset(this->DefaultPlatformToolset)) { - cmOStringStream e; - e << this->GetName() << " supports Windows Phone '8.0' and '8.1', " - "but not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + std::ostringstream e; + if(this->DefaultPlatformToolset.empty()) + { + e << this->GetName() << " supports Windows Phone '8.0' and '8.1', but " + "not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + } + else + { + e << "A Windows Phone component with CMake requires both the Windows " + << "Desktop SDK as well as the Windows Phone '" << this->SystemVersion + << "' SDK. Please make sure that you have both installed"; + } mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -126,12 +134,20 @@ bool cmGlobalVisualStudio12Generator::InitializeWindowsPhone(cmMakefile* mf) //---------------------------------------------------------------------------- bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf) { - this->DefaultPlatformToolset = this->SelectWindowsStoreToolset(); - if(this->DefaultPlatformToolset.empty()) + if(!this->SelectWindowsStoreToolset(this->DefaultPlatformToolset)) { - cmOStringStream e; - e << this->GetName() << " supports Windows Store '8.0' and '8.1', " - "but not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + std::ostringstream e; + if(this->DefaultPlatformToolset.empty()) + { + e << this->GetName() << " supports Windows Store '8.0' and '8.1', but " + "not '" << this->SystemVersion << "'. Check CMAKE_SYSTEM_VERSION."; + } + else + { + e << "A Windows Store component with CMake requires both the Windows " + << "Desktop SDK as well as the Windows Store '" << this->SystemVersion + << "' SDK. Please make sure that you have both installed"; + } mf->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; } @@ -139,23 +155,47 @@ bool cmGlobalVisualStudio12Generator::InitializeWindowsStore(cmMakefile* mf) } //---------------------------------------------------------------------------- -std::string cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset() const +bool +cmGlobalVisualStudio12Generator::SelectWindowsPhoneToolset( + std::string& toolset) const { if(this->SystemVersion == "8.1") { - return "v120_wp81"; + if (this->IsWindowsPhoneToolsetInstalled() && + this->IsWindowsDesktopToolsetInstalled()) + { + toolset = "v120_wp81"; + return true; + } + else + { + return false; + } } - return this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(); + return + this->cmGlobalVisualStudio11Generator::SelectWindowsPhoneToolset(toolset); } //---------------------------------------------------------------------------- -std::string cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset() const +bool +cmGlobalVisualStudio12Generator::SelectWindowsStoreToolset( + std::string& toolset) const { if(this->SystemVersion == "8.1") { - return "v120"; + if(this->IsWindowsStoreToolsetInstalled() && + this->IsWindowsDesktopToolsetInstalled()) + { + toolset = "v120"; + return true; + } + else + { + return false; + } } - return this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(); + return + this->cmGlobalVisualStudio11Generator::SelectWindowsStoreToolset(toolset); } //---------------------------------------------------------------------------- @@ -180,3 +220,46 @@ cmLocalGenerator *cmGlobalVisualStudio12Generator::CreateLocalGenerator() lg->SetGlobalGenerator(this); return lg; } + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio12Generator::IsWindowsDesktopToolsetInstalled() const +{ + const char desktop81Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "VisualStudio\\12.0\\VC\\LibraryDesktop"; + + std::vector<std::string> subkeys; + return cmSystemTools::GetRegistrySubKeys(desktop81Key, + subkeys, + cmSystemTools::KeyWOW64_32); +} + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio12Generator::IsWindowsPhoneToolsetInstalled() const +{ + const char wp81Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "Microsoft SDKs\\WindowsPhone\\v8.1\\Install Path;Install Path"; + + std::string path; + cmSystemTools::ReadRegistryValue(wp81Key, + path, + cmSystemTools::KeyWOW64_32); + return !path.empty(); +} + +//---------------------------------------------------------------------------- +bool +cmGlobalVisualStudio12Generator::IsWindowsStoreToolsetInstalled() const +{ + const char win81Key[] = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" + "VisualStudio\\12.0\\VC\\Libraries\\Core\\Arm"; + + std::vector<std::string> subkeys; + return cmSystemTools::GetRegistrySubKeys(win81Key, + subkeys, + cmSystemTools::KeyWOW64_32); +} diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h index ec85f10..a81516f 100644 --- a/Source/cmGlobalVisualStudio12Generator.h +++ b/Source/cmGlobalVisualStudio12Generator.h @@ -41,8 +41,14 @@ public: protected: virtual bool InitializeWindowsPhone(cmMakefile* mf); virtual bool InitializeWindowsStore(cmMakefile* mf); - virtual std::string SelectWindowsPhoneToolset() const; - virtual std::string SelectWindowsStoreToolset() const; + virtual bool SelectWindowsPhoneToolset(std::string& toolset) const; + virtual bool SelectWindowsStoreToolset(std::string& toolset) const; + + // These aren't virtual because we need to check if the selected version + // of the toolset is installed + bool IsWindowsDesktopToolsetInstalled() const; + bool IsWindowsPhoneToolsetInstalled() const; + bool IsWindowsStoreToolsetInstalled() const; virtual const char* GetIDEVersion() { return "12.0"; } private: class Factory; diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index d001f93..fe702c0 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -13,21 +13,36 @@ #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" -static const char vs14generatorName[] = "Visual Studio 14"; +static const char vs14generatorName[] = "Visual Studio 14 2015"; + +// Map generator name without year to name with year. +static const char* cmVS14GenName(const std::string& name, std::string& genName) +{ + if(strncmp(name.c_str(), vs14generatorName, + sizeof(vs14generatorName)-6) != 0) + { + return 0; + } + const char* p = name.c_str() + sizeof(vs14generatorName) - 6; + if(cmHasLiteralPrefix(p, " 2015")) + { + p += 5; + } + genName = std::string(vs14generatorName) + p; + return p; +} class cmGlobalVisualStudio14Generator::Factory : public cmGlobalGeneratorFactory { public: virtual cmGlobalGenerator* CreateGlobalGenerator( - const std::string& genName) const + const std::string& name) const { - if(strncmp(genName.c_str(), vs14generatorName, - sizeof(vs14generatorName) - 1) != 0) - { - return 0; - } - const char* p = genName.c_str() + sizeof(vs14generatorName) - 1; + std::string genName; + const char* p = cmVS14GenName(name, genName); + if(!p) + { return 0; } if(!*p) { return new cmGlobalVisualStudio14Generator( @@ -51,7 +66,7 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry) const { entry.Name = vs14generatorName; - entry.Brief = "Generates Visual Studio 14 project files."; + entry.Brief = "Generates Visual Studio 14 (VS 2015) project files."; } virtual void GetGenerators(std::vector<std::string>& names) const @@ -85,7 +100,12 @@ bool cmGlobalVisualStudio14Generator::MatchesGeneratorName( const std::string& name) const { - return name == this->GetName(); + std::string genName; + if(cmVS14GenName(name, genName)) + { + return genName == this->GetName(); + } + return false; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index a67a649..64f9cee 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -93,6 +93,11 @@ void cmGlobalVisualStudio71Generator cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { +#ifdef CMAKE_ENCODING_UTF8 + // Add UTF-8 BOM for .sln file to indicate encoding + const unsigned char utf8_bom[3] = {0xEF,0xBB,0xBF}; + fout.write(reinterpret_cast<const char*>(utf8_bom), 3); +#endif // Write out the header for a SLN file this->WriteSLNHeader(fout); diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 401e475..0eb7d2c 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -558,6 +558,11 @@ void cmGlobalVisualStudio7Generator cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { +#ifdef CMAKE_ENCODING_UTF8 + // Add UTF-8 BOM for .sln file to indicate encoding + const unsigned char utf8_bom[3] = {0xEF,0xBB,0xBF}; + fout.write(reinterpret_cast<const char*>(utf8_bom), 3); +#endif // Write out the header for a SLN file this->WriteSLNHeader(fout); diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 745515b..e6ce45d 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -341,9 +341,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() // overwritten by the CreateVCProjBuildRule. // (this could be avoided with per-target source files) std::string no_main_dependency = ""; + std::vector<std::string> no_byproducts; if(cmSourceFile* file = mf->AddCustomCommandToOutput( - stamps, listFiles, + stamps, no_byproducts, listFiles, no_main_dependency, commandLines, "Checking Build System", no_working_directory, true)) { diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 2dab23c..320a1f4 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -845,22 +845,14 @@ cmGlobalVisualStudioGenerator::TargetCompare cmGlobalVisualStudioGenerator::OrderedTargetDependSet ::OrderedTargetDependSet(TargetDependSet const& targets) { - for(TargetDependSet::const_iterator ti = - targets.begin(); ti != targets.end(); ++ti) - { - this->insert(*ti); - } + this->insert(targets.begin(), targets.end()); } //---------------------------------------------------------------------------- cmGlobalVisualStudioGenerator::OrderedTargetDependSet ::OrderedTargetDependSet(TargetSet const& targets) { - for(TargetSet::const_iterator ti = targets.begin(); - ti != targets.end(); ++ti) - { - this->insert(*ti); - } + this->insert(targets.begin(), targets.end()); } std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir( diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 13e6988..b6c428b 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -477,7 +477,9 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)"); cmCustomCommandLines commandLines; commandLines.push_back(makeHelper); + std::vector<std::string> no_byproducts; lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(), + no_byproducts, no_depends, commandLines, cmTarget::POST_BUILD, @@ -555,6 +557,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects() } this->XCodeObjects.clear(); this->XCodeObjectIDs.clear(); + this->XCodeObjectMap.clear(); this->GroupMap.clear(); this->GroupNameMap.clear(); this->TargetGroup.clear(); @@ -966,16 +969,40 @@ struct cmSourceFilePathCompare }; //---------------------------------------------------------------------------- -void +struct cmCompareTargets +{ + bool operator () (std::string const& a, std::string const& b) const + { + if (a == "ALL_BUILD") + { + return true; + } + if (b == "ALL_BUILD") + { + return false; + } + return strcmp(a.c_str(), b.c_str()) < 0; + } +}; + +//---------------------------------------------------------------------------- +bool cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets) { this->SetCurrentLocalGenerator(gen); cmTargets &tgts = this->CurrentMakefile->GetTargets(); + typedef std::map<std::string, cmTarget*, cmCompareTargets> cmSortedTargets; + cmSortedTargets sortedTargets; for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { - cmTarget& cmtarget = l->second; + sortedTargets[l->first] = &l->second; + } + for(cmSortedTargets::iterator l = sortedTargets.begin(); + l != sortedTargets.end(); l++) + { + cmTarget& cmtarget = *l->second; cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget); // make sure ALL_BUILD, INSTALL, etc are only done once @@ -992,7 +1019,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, if(cmtarget.GetType() == cmTarget::UTILITY || cmtarget.GetType() == cmTarget::GLOBAL_TARGET) { - targets.push_back(this->CreateUtilityTarget(cmtarget)); + cmXCodeObject* t = this->CreateUtilityTarget(cmtarget); + if (!t) + { + return false; + } + targets.push_back(t); continue; } @@ -1000,7 +1032,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmSourceFile*> classes; if (!cmtarget.GetConfigCommonSourceFiles(classes)) { - return; + return false; } std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); @@ -1167,7 +1199,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, this->CreateString("2147483647")); copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", this->CreateString("6")); - cmOStringStream ostr; + std::ostringstream ostr; if (cmtarget.IsFrameworkOnApple()) { // dstPath in frameworks is relative to Versions/<version> @@ -1227,6 +1259,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases)); } + return true; } //---------------------------------------------------------------------------- @@ -1368,6 +1401,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, cmCustomCommand command(this->CurrentMakefile, std::vector<std::string>(), std::vector<std::string>(), + std::vector<std::string>(), cmd, "Creating symlinks", ""); @@ -1494,7 +1528,6 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, const & commands, const char* name) { - bool haveMultipleOutputPairs = false; std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory(); dir += "/CMakeScripts"; cmSystemTools::MakeDirectory(dir.c_str()); @@ -1513,8 +1546,7 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, this->CreateCustomRulesMakefile(makefile.c_str(), target, commands, - currentConfig->c_str(), - haveMultipleOutputPairs); + currentConfig->c_str()); } std::string cdir = this->CurrentMakefile->GetCurrentOutputDirectory(); @@ -1524,10 +1556,6 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase, makecmd += " -f "; makecmd += this->ConvertToRelativeForMake( (makefile+"$CONFIGURATION").c_str()); - if(haveMultipleOutputPairs) - { - makecmd += " cmake_check_multiple_outputs"; - } makecmd += " all"; cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ "); buildphase->AddAttribute("shellScript", @@ -1542,8 +1570,7 @@ void cmGlobalXCodeGenerator cmTarget& target, std::vector<cmCustomCommand> const & commands, - const std::string& configName, - bool& haveMultipleOutputPairs) + const std::string& configName) { std::string makefileName=makefileBasename; if(this->XcodeVersion > 20) @@ -1566,7 +1593,6 @@ void cmGlobalXCodeGenerator makefileStream << "all: "; std::map<const cmCustomCommand*, std::string> tname; int count = 0; - std::map<std::string, std::string> multipleOutputPairs; for(std::vector<cmCustomCommand>::const_iterator i = commands.begin(); i != commands.end(); ++i) { @@ -1582,20 +1608,10 @@ void cmGlobalXCodeGenerator makefileStream << "\\\n\t" << this->ConvertToRelativeForMake(o->c_str()); } - - // If there is more than one output treat the first as the - // primary output and make the rest depend on it. - std::vector<std::string>::const_iterator o = outputs.begin(); - std::string primaryOutput = this->ConvertToRelativeForMake(o->c_str()); - for(++o; o != outputs.end(); ++o) - { - std::string currentOutput=this->ConvertToRelativeForMake(o->c_str()); - multipleOutputPairs[currentOutput] = primaryOutput; - } } else { - cmOStringStream str; + std::ostringstream str; str << "_buildpart_" << count++ ; tname[&ccg.GetCC()] = std::string(target.GetName()) + str.str(); makefileStream << "\\\n\t" << tname[&ccg.GetCC()]; @@ -1614,9 +1630,15 @@ void cmGlobalXCodeGenerator if(!outputs.empty()) { // There is at least one output, start the rule for it - std::string primary_output = - this->ConvertToRelativeForMake(outputs.begin()->c_str()); - makefileStream << primary_output << ": "; + const char* sep = ""; + for(std::vector<std::string>::const_iterator oi = outputs.begin(); + oi != outputs.end(); ++oi) + { + makefileStream << sep << + this->ConvertToRelativeForMake(oi->c_str()); + sep = " "; + } + makefileStream << ": "; } else { @@ -1666,33 +1688,6 @@ void cmGlobalXCodeGenerator } } } - - // Add rules to deal with multiple outputs of custom commands. - if(!multipleOutputPairs.empty()) - { - makefileStream << - "\n# Dependencies of multiple outputs to their primary outputs \n"; - - for(std::map<std::string, std::string>::const_iterator o = - multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o) - { - makefileStream << o->first << ": " << o->second << "\n"; - } - - makefileStream << - "\n" - "cmake_check_multiple_outputs:\n"; - for(std::map<std::string, std::string>::const_iterator o = - multipleOutputPairs.begin(); o != multipleOutputPairs.end(); ++o) - { - makefileStream << "\t@if [ ! -f " - << o->first << " ]; then rm -f " - << o->second << "; fi\n"; - } - } - - haveMultipleOutputPairs = - haveMultipleOutputPairs || !multipleOutputPairs.empty(); } //---------------------------------------------------------------------------- @@ -1960,7 +1955,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { buildSettings->AddAttribute("LIBRARY_STYLE", this->CreateString("BUNDLE")); - if (target.GetPropertyAsBool("BUNDLE")) + if (target.IsCFBundleOnApple()) { // It turns out that a BUNDLE is basically the same // in many ways as an application bundle, as far as @@ -2314,6 +2309,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, group->AddObject(this->CreateString("-Wmost")); group->AddObject(this->CreateString("-Wno-four-char-constants")); group->AddObject(this->CreateString("-Wno-unknown-pragmas")); + group->AddObject(this->CreateString("$(inherited)")); buildSettings->AddAttribute("WARNING_CFLAGS", group); } else @@ -2333,7 +2329,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // VERSION -> current_version target.GetTargetVersion(false, major, minor, patch); - cmOStringStream v; + std::ostringstream v; // Xcode always wants at least 1.0.0 or nothing if(!(major == 0 && minor == 0 && patch == 0)) @@ -2345,7 +2341,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // SOVERSION -> compatibility_version target.GetTargetVersion(true, major, minor, patch); - cmOStringStream vso; + std::ostringstream vso; // Xcode always wants at least 1.0.0 or nothing if(!(major == 0 && minor == 0 && patch == 0)) @@ -2454,6 +2450,7 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget) target->AddAttribute("name", this->CreateString(cmtarget.GetName())); target->AddAttribute("productName",this->CreateString(cmtarget.GetName())); target->SetTarget(&cmtarget); + this->XCodeObjectMap[&cmtarget] = target; // Add source files without build rules for editing convenience. if(cmtarget.GetType() == cmTarget::UTILITY) @@ -2657,6 +2654,7 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget, target->AddAttribute("productType", this->CreateString(productType)); } target->SetTarget(&cmtarget); + this->XCodeObjectMap[&cmtarget] = target; target->SetId(this->GetOrCreateId( cmtarget.GetName(), target->GetId()).c_str()); return target; @@ -2669,16 +2667,14 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget const* t) { return 0; } - for(std::vector<cmXCodeObject*>::iterator i = this->XCodeObjects.begin(); - i != this->XCodeObjects.end(); ++i) + + std::map<cmTarget const*, cmXCodeObject*>::const_iterator const i = + this->XCodeObjectMap.find(t); + if (i == this->XCodeObjectMap.end()) { - cmXCodeObject* o = *i; - if(o->GetTarget() == t) - { - return o; - } + return 0; } - return 0; + return i->second; } //---------------------------------------------------------------------------- @@ -2940,7 +2936,7 @@ void cmGlobalXCodeGenerator } //---------------------------------------------------------------------------- -void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, +bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { @@ -2983,7 +2979,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, std::vector<cmSourceFile*> classes; if (!cmtarget.GetConfigCommonSourceFiles(classes)) { - return; + return false; } // Put cmSourceFile instances in proper groups: for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); @@ -3016,6 +3012,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, } } } + return true; } cmXCodeObject *cmGlobalXCodeGenerator @@ -3136,7 +3133,7 @@ cmXCodeObject* cmGlobalXCodeGenerator } //---------------------------------------------------------------------------- -void cmGlobalXCodeGenerator +bool cmGlobalXCodeGenerator ::CreateXCodeObjects(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) @@ -3217,7 +3214,10 @@ void cmGlobalXCodeGenerator this->MainGroupChildren->AddObject(resourcesGroup); // now create the cmake groups - this->CreateGroups(root, generators); + if (!this->CreateGroups(root, generators)) + { + return false; + } cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup); productGroup->AddAttribute("name", this->CreateString("Products")); @@ -3417,7 +3417,10 @@ void cmGlobalXCodeGenerator { if(!this->IsExcluded(root, *i)) { - this->CreateXCodeTargets(*i, targets); + if (!this->CreateXCodeTargets(*i, targets)) + { + return false; + } } } // loop over all targets and add link and depend info @@ -3446,6 +3449,7 @@ void cmGlobalXCodeGenerator } } this->RootObject->AddAttribute("targets", allTargets); + return true; } //---------------------------------------------------------------------------- @@ -3632,8 +3636,10 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root, } } - this->CreateXCodeObjects(root, - generators); + if (!this->CreateXCodeObjects(root, generators)) + { + return; + } std::string xcodeDir = root->GetMakefile()->GetStartOutputDirectory(); xcodeDir += "/"; xcodeDir += root->GetMakefile()->GetProjectName(); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 9d7b784..a39c8c7 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -91,7 +91,7 @@ private: cmSourceGroup* sg); cmXCodeObject* CreatePBXGroup(cmXCodeObject *parent, std::string name); - void CreateGroups(cmLocalGenerator* root, + bool CreateGroups(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); std::string XCodeEscapePath(const char* p); @@ -118,8 +118,7 @@ private: void CreateCustomRulesMakefile(const char* makefileBasename, cmTarget& target, std::vector<cmCustomCommand> const & commands, - const std::string& configName, - bool& haveMultipleOutputPairs); + const std::string& configName); cmXCodeObject* FindXCodeTarget(cmTarget const*); std::string GetOrCreateId(const std::string& name, const std::string& id); @@ -151,7 +150,7 @@ private: std::string ExtractFlag(const char* flag, std::string& flags); // delete all objects in the this->XCodeObjects vector. void ClearXCodeObjects(); - void CreateXCodeObjects(cmLocalGenerator* root, + bool CreateXCodeObjects(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); void OutputXCodeProject(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); @@ -170,7 +169,7 @@ private: cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf, cmTarget& cmtarget); - void CreateXCodeTargets(cmLocalGenerator* gen, + bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&); bool IsHeaderFile(cmSourceFile*); void AddDependTarget(cmXCodeObject* target, @@ -241,6 +240,7 @@ private: std::map<std::string, cmXCodeObject* > GroupNameMap; std::map<std::string, cmXCodeObject* > TargetGroup; std::map<std::string, cmXCodeObject* > FileRefs; + std::map<cmTarget const*, cmXCodeObject* > XCodeObjectMap; std::vector<std::string> Architectures; std::string GeneratorToolset; }; diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 601993f..af88d1c 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -125,7 +125,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, __set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS"); this->TargetsToIgnoreRegex.clear(); - if (ignoreTargetsRegexes.size() > 0) + if (!ignoreTargetsRegexes.empty()) { std::vector<std::string> ignoreTargetsRegExVector; cmSystemTools::ExpandListArgument(ignoreTargetsRegexes, @@ -497,7 +497,7 @@ int cmGraphVizWriter::CollectAllTargets() continue; } //std::cout << "Found target: " << tit->first.c_str() << std::endl; - cmOStringStream ostr; + std::ostringstream ostr; ostr << this->GraphNodePrefix << cnt++; this->TargetNamesNodes[realTargetName] = ostr.str(); this->TargetPtrs[realTargetName] = &tit->second; @@ -544,7 +544,7 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt) this->TargetPtrs.find(libName); if ( tarIt == this->TargetPtrs.end() ) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << this->GraphNodePrefix << cnt++; this->TargetNamesNodes[libName] = ostr.str(); this->TargetPtrs[libName] = NULL; diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index f728c15..3362abb 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -116,7 +116,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, bool isTrue = conditionEvaluator.IsTrue( expandedArguments, errorString, messType); - if (errorString.size()) + if (!errorString.empty()) { std::string err = cmIfCommandError(&mf, expandedArguments); err += errorString; @@ -151,6 +151,11 @@ IsFunctionBlocked(const cmListFileFunction& lff, inStatus.SetBreakInvoked(true); return true; } + if (status.GetContinueInvoked()) + { + inStatus.SetContinueInvoked(true); + return true; + } } } return true; @@ -172,7 +177,7 @@ bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff, { // if the endif has arguments, then make sure // they match the arguments of the matching if - if (lff.Arguments.size() == 0 || + if (lff.Arguments.empty() || lff.Arguments == this->Args) { return true; @@ -199,7 +204,7 @@ bool cmIfCommand bool isTrue = conditionEvaluator.IsTrue( expandedArguments, errorString, status); - if (errorString.size()) + if (!errorString.empty()) { std::string err = cmIfCommandError(this->Makefile, expandedArguments); err += errorString; diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx index 0a1d280..c15d46e 100644 --- a/Source/cmIncludeCommand.cxx +++ b/Source/cmIncludeCommand.cxx @@ -40,7 +40,7 @@ bool cmIncludeCommand } else if(args[i] == "RESULT_VARIABLE") { - if (resultVarName.size() > 0) + if (!resultVarName.empty()) { this->SetError("called with invalid arguments: " "only one result variable allowed"); @@ -83,7 +83,7 @@ bool cmIncludeCommand std::string module = fname; module += ".cmake"; std::string mfile = this->Makefile->GetModulesFile(module.c_str()); - if ( mfile.size() ) + if (!mfile.empty()) { fname = mfile.c_str(); } @@ -98,7 +98,7 @@ bool cmIncludeCommand if (gg->IsExportedTargetsFile(fname_abs)) { const char *modal = 0; - cmOStringStream e; + std::ostringstream e; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0024)) @@ -137,7 +137,7 @@ bool cmIncludeCommand noPolicyScope); // add the location of the included file if a result variable was given - if (resultVarName.size()) + if (!resultVarName.empty()) { this->Makefile->AddDefinition(resultVarName, readit?fullFilePath.c_str():"NOTFOUND"); diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index df5508e..464b4c2 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -47,7 +47,7 @@ bool cmIncludeDirectoryCommand system = true; continue; } - if(i->size() == 0) + if(i->empty()) { this->SetError("given empty-string as include directory."); return false; @@ -71,11 +71,7 @@ bool cmIncludeDirectoryCommand } if (system) { - for (std::vector<std::string>::const_iterator li = includes.begin(); - li != includes.end(); ++li) - { - systemIncludes.insert(*li); - } + systemIncludes.insert(includes.begin(), includes.end()); } } std::reverse(beforeIncludes.begin(), beforeIncludes.end()); diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index c3c9c55..2d7d7cc 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -273,7 +273,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if(!unknownArgs.empty()) { // Unknown argument. - cmOStringStream e; + std::ostringstream e; e << "TARGETS given unknown argument \"" << unknownArgs[0] << "\"."; this->SetError(e.str()); return false; @@ -373,7 +373,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) if (this->Makefile->IsAlias(*targetIt)) { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given target \"" << (*targetIt) << "\" which is an alias."; this->SetError(e.str()); @@ -390,7 +390,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) target->GetType() != cmTarget::OBJECT_LIBRARY && target->GetType() != cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given target \"" << (*targetIt) << "\" which is not an executable, library, or module."; this->SetError(e.str()); @@ -398,7 +398,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else if(target->GetType() == cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given OBJECT library \"" << (*targetIt) << "\" which may not be installed."; this->SetError(e.str()); @@ -410,7 +410,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) else { // Did not find the target. - cmOStringStream e; + std::ostringstream e; e << "TARGETS given target \"" << (*targetIt) << "\" which does not exist in this directory."; this->SetError(e.str()); @@ -502,7 +502,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no FRAMEWORK DESTINATION for shared library " "FRAMEWORK target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -522,7 +522,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no LIBRARY DESTINATION for shared library " "target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -542,7 +542,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no ARCHIVE DESTINATION for static library " "target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -563,7 +563,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no LIBRARY DESTINATION for module target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -598,7 +598,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } if(!bundleGenerator) { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE " "executable target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -615,7 +615,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "TARGETS given no RUNTIME DESTINATION for executable " "target \"" << target.GetName() << "\"."; this->SetError(e.str()); @@ -681,7 +681,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "INSTALL TARGETS - target " << target.GetName() << " has " << "PRIVATE_HEADER files but no PRIVATE_HEADER DESTINATION."; cmSystemTools::Message(e.str().c_str(), "Warning"); @@ -708,7 +708,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "INSTALL TARGETS - target " << target.GetName() << " has " << "PUBLIC_HEADER files but no PUBLIC_HEADER DESTINATION."; cmSystemTools::Message(e.str().c_str(), "Warning"); @@ -734,7 +734,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) } else { - cmOStringStream e; + std::ostringstream e; e << "INSTALL TARGETS - target " << target.GetName() << " has " << "RESOURCE files but no RESOURCE DESTINATION."; cmSystemTools::Message(e.str().c_str(), "Warning"); @@ -777,19 +777,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args) this->Makefile->GetLocalGenerator()->GetGlobalGenerator() ->GetExportSets()[exports.GetString()]->AddTargetExport(te); - std::vector<std::string> dirs = includesArgs.GetIncludeDirs(); - if(!dirs.empty()) - { - std::string dirString; - const char *sep = ""; - for (std::vector<std::string>::const_iterator it = dirs.begin(); - it != dirs.end(); ++it) - { - te->InterfaceIncludeDirectories += sep; - te->InterfaceIncludeDirectories += *it; - sep = ";"; - } - } + te->InterfaceIncludeDirectories = + cmJoin(includesArgs.GetIncludeDirs(), ";"); } } @@ -855,7 +844,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if(!unknownArgs.empty()) { // Unknown argument. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\"."; this->SetError(e.str()); return false; @@ -870,7 +859,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if(!ica.GetRename().empty() && files.GetVector().size() > 1) { // The rename option works only with one file. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given RENAME option with more than one file."; this->SetError(e.str()); return false; @@ -890,7 +879,7 @@ bool cmInstallCommand::HandleFilesMode(std::vector<std::string> const& args) if(ica.GetDestination().empty()) { // A destination is required. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given no DESTINATION!"; this->SetError(e.str()); return false; @@ -931,7 +920,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -945,7 +934,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -960,7 +949,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -988,7 +977,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) // Add this property to the current match rule. if(!in_match_mode || doing == DoingPattern || doing == DoingRegex) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" before a PATTERN or REGEX is given."; this->SetError(e.str()); @@ -1001,7 +990,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(!in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" before a PATTERN or REGEX is given."; this->SetError(e.str()); @@ -1016,7 +1005,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1030,7 +1019,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1044,7 +1033,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1059,7 +1048,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1074,7 +1063,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1088,7 +1077,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) { if(in_match_mode) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " does not allow \"" << args[i] << "\" after PATTERN or REGEX."; this->SetError(e.str()); @@ -1113,7 +1102,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) if(cmSystemTools::FileExists(dir.c_str()) && !cmSystemTools::FileIsDirectory(dir)) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given non-directory \"" << args[i] << "\" to install."; this->SetError(e.str()); @@ -1169,7 +1158,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) // Check the requested permission. if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_file)) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given invalid file permission \"" << args[i] << "\"."; this->SetError(e.str()); @@ -1181,7 +1170,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) // Check the requested permission. if(!cmInstallCommandArguments::CheckPermissions(args[i],permissions_dir)) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given invalid directory permission \"" << args[i] << "\"."; this->SetError(e.str()); @@ -1193,7 +1182,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) // Check the requested permission. if(!cmInstallCommandArguments::CheckPermissions(args[i], literal_args)) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given invalid permission \"" << args[i] << "\"."; this->SetError(e.str()); @@ -1203,7 +1192,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) else { // Unknown argument. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given unknown argument \"" << args[i] << "\"."; this->SetError(e.str()); return false; @@ -1224,7 +1213,7 @@ cmInstallCommand::HandleDirectoryMode(std::vector<std::string> const& args) if(!destination) { // A destination is required. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given no DESTINATION!"; this->SetError(e.str()); return false; @@ -1271,7 +1260,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if (!unknownArgs.empty()) { // Unknown argument. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given unknown argument \"" << unknownArgs[0] << "\"."; this->SetError(e.str()); return false; @@ -1286,7 +1275,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if(ica.GetDestination().empty()) { // A destination is required. - cmOStringStream e; + std::ostringstream e; e << args[0] << " given no DESTINATION!"; this->SetError(e.str()); return false; @@ -1296,7 +1285,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) std::string fname = filename.GetString(); if(fname.find_first_of(":/\\") != fname.npos) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given invalid export file name \"" << fname << "\". " << "The FILE argument may not contain a path. " << "Specify the path in the DESTINATION argument."; @@ -1308,7 +1297,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if(!fname.empty() && cmSystemTools::GetFilenameLastExtension(fname) != ".cmake") { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given invalid export file name \"" << fname << "\". " << "The FILE argument must specify a name ending in \".cmake\"."; this->SetError(e.str()); @@ -1323,7 +1312,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if(fname.find_first_of(":/\\") != fname.npos) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " given export name \"" << exp.GetString() << "\". " << "This name cannot be safely converted to a file name. " << "Specify a different export name or use the FILE option to set " @@ -1348,7 +1337,7 @@ bool cmInstallCommand::HandleExportMode(std::vector<std::string> const& args) if(!newCMP0022Behavior) { - cmOStringStream e; + std::ostringstream e; e << "INSTALL(EXPORT) given keyword \"" << "EXPORT_LINK_INTERFACE_LIBRARIES" << "\", but target \"" << te->Target->GetName() @@ -1395,7 +1384,7 @@ bool cmInstallCommand::MakeFilesFullPath(const char* modeName, // Make sure the file is not a directory. if(gpos == file.npos && cmSystemTools::FileIsDirectory(file)) { - cmOStringStream e; + std::ostringstream e; e << modeName << " given directory \"" << (*fileIt) << "\" to install."; this->SetError(e.str()); return false; diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index ddfd6c5..4480cc6 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -121,7 +121,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) // Skip empty sets. if(ExportSet->GetTargetExports()->empty()) { - cmOStringStream e; + std::ostringstream e; e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() << "\""; cmSystemTools::Error(e.str().c_str()); diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index f106e1a..06a78e5 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -47,11 +47,8 @@ bool cmInstallFilesCommand else { this->IsFilesForm = false; - std::vector<std::string>::const_iterator s = args.begin(); - for (++s;s != args.end(); ++s) - { - this->FinalArgs.push_back(*s); - } + this->FinalArgs.insert(this->FinalArgs.end(), + args.begin() + 1, args.end()); } this->Makefile->GetLocalGenerator()->GetGlobalGenerator() @@ -83,7 +80,7 @@ void cmInstallFilesCommand::FinalPass() { // replace any variables std::string temps = *s; - if (cmSystemTools::GetFilenamePath(temps).size() > 0) + if (!cmSystemTools::GetFilenamePath(temps).empty()) { testf = cmSystemTools::GetFilenamePath(temps) + "/" + cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext; diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx index 0405769..cc223ab 100644 --- a/Source/cmInstallProgramsCommand.cxx +++ b/Source/cmInstallProgramsCommand.cxx @@ -27,11 +27,7 @@ bool cmInstallProgramsCommand this->Destination = args[0]; - std::vector<std::string>::const_iterator s = args.begin(); - for (++s;s != args.end(); ++s) - { - this->FinalArgs.push_back(*s); - } + this->FinalArgs.insert(this->FinalArgs.end(), args.begin() + 1, args.end()); this->Makefile->GetLocalGenerator()->GetGlobalGenerator() ->AddInstallComponent(this->Makefile->GetSafeDefinition( diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index d689c89..6d69f54 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -47,7 +47,7 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os) // Warn if installing an exclude-from-all target. if(this->Target->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - cmOStringStream msg; + std::ostringstream msg; msg << "WARNING: Target \"" << this->Target->GetName() << "\" has EXCLUDE_FROM_ALL set and will not be built by default " << "but an install rule has been provided for it. CMake does " @@ -95,7 +95,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, case cmTarget::INTERFACE_LIBRARY: // Not reachable. We never create a cmInstallTargetGenerator for // an INTERFACE_LIBRARY. - assert(!"INTERFACE_LIBRARY targets have no installable outputs."); + assert(0 && "INTERFACE_LIBRARY targets have no installable outputs."); break; case cmTarget::OBJECT_LIBRARY: case cmTarget::UTILITY: @@ -424,7 +424,7 @@ cmInstallTargetGenerator ::AddTweak(std::ostream& os, Indent const& indent, const std::string& config, std::string const& file, TweakMethod tweak) { - cmOStringStream tw; + std::ostringstream tw; (this->*tweak)(tw, indent.Next(), config, file); std::string tws = tw.str(); if(!tws.empty()) @@ -450,7 +450,7 @@ cmInstallTargetGenerator else { // Generate a foreach loop to tweak multiple files. - cmOStringStream tw; + std::ostringstream tw; this->AddTweak(tw, indent.Next(), config, "${file}", tweak); std::string tws = tw.str(); if(!tws.empty()) @@ -523,7 +523,7 @@ cmInstallTargetGenerator std::string installNameTool = this->Target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL"); - if(!installNameTool.size()) + if(installNameTool.empty()) { return; } @@ -699,7 +699,7 @@ cmInstallTargetGenerator (!oldRuntimeDirs.empty() || !newRuntimeDirs.empty()) ) { - cmOStringStream msg; + std::ostringstream msg; msg << "WARNING: Target \"" << this->Target->GetName() << "\" has runtime paths which cannot be changed during install. " << "To change runtime paths, OS X version 10.6 or newer is required. " diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h index 7134a4e..503f92c 100644 --- a/Source/cmInstalledFile.h +++ b/Source/cmInstalledFile.h @@ -38,11 +38,7 @@ public: ~Property() { - for(ExpressionVectorType::iterator i = ValueExpressions.begin(); - i != ValueExpressions.end(); ++i) - { - delete *i; - } + cmDeleteAll(this->ValueExpressions); } ExpressionVectorType ValueExpressions; diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx index 3644d93..ade1feb 100644 --- a/Source/cmLinkDirectoriesCommand.cxx +++ b/Source/cmLinkDirectoriesCommand.cxx @@ -36,7 +36,7 @@ void cmLinkDirectoriesCommand::AddLinkDir(std::string const& dir) if(!cmSystemTools::FileIsFullPath(unixPath.c_str())) { bool convertToAbsolute = false; - cmOStringStream e; + std::ostringstream e; e << "This command specifies the relative path\n" << " " << unixPath << "\n" << "as a link directory.\n"; diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index f1ea088..107dca9 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -98,7 +98,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, return false; } // if the size of the list - if(listString.size() == 0) + if(listString.empty()) { return true; } @@ -109,7 +109,7 @@ bool cmListCommand::GetList(std::vector<std::string>& list, for(std::vector<std::string>::iterator i = list.begin(); i != list.end(); ++i) { - if(i->size() == 0) + if(i->empty()) { hasEmpty = true; break; @@ -225,7 +225,7 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) } if ( item < 0 || nitem <= (size_t)item ) { - cmOStringStream str; + std::ostringstream str; str << "index: " << item << " out of range (-" << varArgsExpanded.size() << ", " << varArgsExpanded.size()-1 << ")"; @@ -257,7 +257,7 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) size_t cc; for ( cc = 2; cc < args.size(); ++ cc ) { - if(listString.size()) + if(!listString.empty()) { listString += ";"; } @@ -322,13 +322,13 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) if((!this->GetList(varArgsExpanded, listName) || varArgsExpanded.empty()) && item != 0) { - cmOStringStream str; + std::ostringstream str; str << "index: " << item << " out of range (0, 0)"; this->SetError(str.str()); return false; } - if ( varArgsExpanded.size() != 0 ) + if (!varArgsExpanded.empty()) { size_t nitem = varArgsExpanded.size(); if ( item < 0 ) @@ -337,31 +337,19 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args) } if ( item < 0 || nitem <= (size_t)item ) { - cmOStringStream str; + std::ostringstream str; str << "index: " << item << " out of range (-" << varArgsExpanded.size() << ", " - << (varArgsExpanded.size() == 0?0:(varArgsExpanded.size()-1)) << ")"; + << (varArgsExpanded.empty() ? 0 : (varArgsExpanded.size() - 1)) << ")"; this->SetError(str.str()); return false; } } - size_t cc; - size_t cnt = 0; - for ( cc = 3; cc < args.size(); ++ cc ) - { - varArgsExpanded.insert(varArgsExpanded.begin()+item+cnt, args[cc]); - cnt ++; - } - std::string value; - const char* sep = ""; - for ( cc = 0; cc < varArgsExpanded.size(); cc ++ ) - { - value += sep; - value += varArgsExpanded[cc]; - sep = ";"; - } + varArgsExpanded.insert(varArgsExpanded.begin()+item, + args.begin() + 3, args.end()); + std::string value = cmJoin(varArgsExpanded, ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; } @@ -402,15 +390,8 @@ bool cmListCommand } } - std::string value; - const char* sep = ""; - for ( cc = 0; cc < varArgsExpanded.size(); cc ++ ) - { - value += sep; - value += varArgsExpanded[cc]; - sep = ";"; - } + std::string value = cmJoin(varArgsExpanded, ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; } @@ -518,16 +499,7 @@ bool cmListCommand std::sort(varArgsExpanded.begin(), varArgsExpanded.end()); - std::string value; - std::vector<std::string>::iterator it; - const char* sep = ""; - for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it ) - { - value += sep; - value += it->c_str(); - sep = ";"; - } - + std::string value = cmJoin(varArgsExpanded, ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; } @@ -570,7 +542,7 @@ bool cmListCommand::HandleRemoveAtCommand( } if ( item < 0 || nitem <= (size_t)item ) { - cmOStringStream str; + std::ostringstream str; str << "index: " << item << " out of range (-" << varArgsExpanded.size() << ", " << varArgsExpanded.size()-1 << ")"; diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 1c39563..3e26349 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -68,7 +68,7 @@ bool cmListFileParser::ParseFile() bom != cmListFileLexer_BOM_UTF8) { cmListFileLexer_SetFileName(this->Lexer, 0, 0); - cmOStringStream m; + std::ostringstream m; m << "File\n " << this->FileName << "\n" << "starts with a Byte-Order-Mark that is not UTF-8."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, m.str()); @@ -108,7 +108,7 @@ bool cmListFileParser::ParseFile() } else { - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << token->line << ":\n" << "Parse error. Expected a newline, got " @@ -120,7 +120,7 @@ bool cmListFileParser::ParseFile() } else { - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << token->line << ":\n" << "Parse error. Expected a command name, got " @@ -268,7 +268,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line) token->type == cmListFileLexer_Token_Space) {} if(!token) { - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n" << "Parse error. Function missing opening \"(\"."; @@ -277,7 +277,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line) } if(token->type != cmListFileLexer_Token_ParenLeft) { - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n" << "Parse error. Expected \"(\", got " @@ -355,7 +355,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line) else { // Error. - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << cmListFileLexer_GetCurrentLine(this->Lexer) << ":\n" << "Parse error. Function missing ending \")\". " @@ -367,7 +367,7 @@ bool cmListFileParser::ParseFunction(const char* name, long line) } } - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << this->FileName << ":" << lastLine << ":\n" << "Parse error. Function missing ending \")\". " @@ -389,7 +389,7 @@ bool cmListFileParser::AddArgument(cmListFileLexer_Token* token, } bool isError = (this->Separation == SeparationError || delim == cmListFileArgument::Bracket); - cmOStringStream m; + std::ostringstream m; m << "Syntax " << (isError? "Error":"Warning") << " in cmake code at\n" << " " << this->FileName << ":" << token->line << ":" << token->column << "\n" diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index 427e29d..93aec32 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -110,10 +110,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) // Prepare the table of variables to read. this->Prefix = args[2]; - for(unsigned int i=3; i < args.size(); ++i) - { - this->VariablesToRead.insert(args[i]); - } + this->VariablesToRead.insert(args.begin() + 3, args.end()); // Read the cache file. cmsys::ifstream fin(cacheFile.c_str()); @@ -160,7 +157,7 @@ bool cmLoadCacheCommand::ReadWithPrefix(std::vector<std::string> const& args) } } } - if(line.length()) + if(!line.empty()) { // Partial last line. this->CheckLine(line.c_str()); @@ -184,7 +181,7 @@ void cmLoadCacheCommand::CheckLine(const char* line) // This was requested. Set this variable locally with the given // prefix. var = this->Prefix + var; - if(value.length()) + if(!value.empty()) { this->Makefile->AddDefinition(var, value.c_str()); } diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index a4063a6..cdfd00c 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -226,7 +226,7 @@ bool cmLoadCommandCommand std::string fullPath = cmSystemTools::FindFile(moduleName.c_str(), path); if (fullPath == "") { - cmOStringStream e; + std::ostringstream e; e << "Attempt to load command failed from file \"" << moduleName << "\""; this->SetError(e.str()); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 69b56c6..834f705 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -79,9 +79,15 @@ public: this->GG = lg->GetGlobalGenerator(); this->LG = this->GG->GetCurrentLocalGenerator(); this->GG->SetCurrentLocalGenerator(lg); +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PushFileScope(); +#endif } ~cmLocalGeneratorCurrent() { +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GG->GetFileLockPool().PopFileScope(); +#endif this->GG->SetCurrentLocalGenerator(this->LG); } }; @@ -147,7 +153,7 @@ void cmLocalGenerator::ComputeObjectMaxPath() } else { - cmOStringStream w; + std::ostringstream w; w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax << ", which is less than the minimum of 128. " << "The value will be ignored."; @@ -156,7 +162,7 @@ void cmLocalGenerator::ComputeObjectMaxPath() } else { - cmOStringStream w; + std::ostringstream w; w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen << "\", which fails to parse as a positive integer. " << "The value will be ignored."; @@ -185,7 +191,7 @@ void cmLocalGenerator::ReadInputFile() // The file is missing. Check policy CMP0014. cmMakefile* mf = this->Parent->GetMakefile(); - cmOStringStream e; + std::ostringstream e; e << "The source directory\n" << " " << this->Makefile->GetStartDirectory() << "\n" << "does not contain a CMakeLists.txt file."; @@ -259,6 +265,17 @@ void cmLocalGenerator::ConfigureFinalPass() void cmLocalGenerator::TraceDependencies() { + std::vector<std::string> configs; + this->Makefile->GetConfigurations(configs); + if (configs.empty()) + { + configs.push_back(""); + } + for(std::vector<std::string>::const_iterator ci = configs.begin(); + ci != configs.end(); ++ci) + { + this->GlobalGenerator->CreateEvaluationSourceFiles(*ci); + } // Generate the rule files for each target. cmGeneratorTargetsType targets = this->Makefile->GetGeneratorTargets(); for(cmGeneratorTargetsType::iterator t = targets.begin(); @@ -318,7 +335,7 @@ void cmLocalGenerator::GenerateTestFiles() { (*gi)->Generate(fout, config, configurationTypes); } - if ( this->Children.size()) + if (!this->Children.empty()) { size_t i; for(i = 0; i < this->Children.size(); ++i) @@ -617,11 +634,7 @@ void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname, // Parse the string to get the custom command line. cmCustomCommandLine commandLine; std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str()); - for(std::vector<std::string>::iterator a = cmd.begin(); - a != cmd.end(); ++a) - { - commandLine.push_back(*a); - } + commandLine.insert(commandLine.end(), cmd.begin(), cmd.end()); // Store this command line. commandLines.push_back(commandLine); @@ -728,11 +741,7 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang, // Parse the string to get the custom command line. cmCustomCommandLine commandLine; std::vector<std::string> cmd = cmSystemTools::ParseArguments(i->c_str()); - for(std::vector<std::string>::iterator a = cmd.begin(); - a != cmd.end(); ++a) - { - commandLine.push_back(*a); - } + commandLine.insert(commandLine.end(), cmd.begin(), cmd.end()); // Store this command line. commandLines.push_back(commandLine); @@ -927,7 +936,7 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, if(variable == "TARGET_QUOTED") { std::string targetQuoted = replaceValues.Target; - if(targetQuoted.size() && targetQuoted[0] != '\"') + if(!targetQuoted.empty() && targetQuoted[0] != '\"') { targetQuoted = '\"'; targetQuoted += replaceValues.Target; @@ -1228,7 +1237,7 @@ void cmLocalGenerator::InsertRuleLauncher(std::string& s, cmTarget* target, { if(const char* val = this->GetRuleLauncher(target, prop)) { - cmOStringStream wrapped; + std::ostringstream wrapped; wrapped << val << " " << s; s = wrapped.str(); } @@ -1309,7 +1318,7 @@ std::string cmLocalGenerator::GetIncludeFlags( } OutputFormat shellFormat = forResponseFile? RESPONSE : SHELL; - cmOStringStream includeFlags; + std::ostringstream includeFlags; std::string flagVar = "CMAKE_INCLUDE_FLAG_"; flagVar += lang; @@ -1405,12 +1414,12 @@ std::string cmLocalGenerator::GetIncludeFlags( } std::string includePath = this->ConvertToIncludeReference(*i, shellFormat, forceFullPaths); - if(quotePaths && includePath.size() && includePath[0] != '\"') + if(quotePaths && !includePath.empty() && includePath[0] != '\"') { includeFlags << "\""; } includeFlags << includePath; - if(quotePaths && includePath.size() && includePath[0] != '\"') + if(quotePaths && !includePath.empty() && includePath[0] != '\"') { includeFlags << "\""; } @@ -1418,7 +1427,7 @@ std::string cmLocalGenerator::GetIncludeFlags( } std::string flags = includeFlags.str(); // remove trailing separators - if((sep[0] != ' ') && flags.size()>0 && flags[flags.size()-1] == sep[0]) + if((sep[0] != ' ') && !flags.empty() && flags[flags.size()-1] == sep[0]) { flags[flags.size()-1] = ' '; } @@ -1504,7 +1513,7 @@ void cmLocalGenerator::AddCompileOptions( } if (this->Makefile->IsLaterStandard(it->first, standard, it->second)) { - cmOStringStream e; + std::ostringstream e; e << "The COMPILE_FEATURES property of target \"" << target->GetName() << "\" was evaluated when computing the link " "implementation, and the \"" << it->first << "_STANDARD\" was \"" @@ -1863,7 +1872,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, OutputFormat shellFormat = (forResponseFile) ? RESPONSE : ((useWatcomQuote) ? WATCOMQUOTE : SHELL); bool escapeAllowMakeVars = !forResponseFile; - cmOStringStream fout; + std::ostringstream fout; std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config); if(!pcli) @@ -2225,7 +2234,7 @@ AddCompilerRequirementFlag(std::string &flags, cmTarget* target, const char *opt = target->GetMakefile()->GetDefinition(option_flag); if (!opt) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << target->GetName() << "\" requires the language " "dialect \"" << lang << standardProp << "\" " << (ext ? "(with compiler extensions)" : "") << ", but CMake " @@ -2310,7 +2319,7 @@ static void AddVisibilityCompileOption(std::string &flags, cmTarget* target, && strcmp(prop, "protected") != 0 && strcmp(prop, "internal") != 0 ) { - cmOStringStream e; + std::ostringstream e; e << "Target " << target->GetName() << " uses unsupported value \"" << prop << "\" for " << flagDefine << "."; cmSystemTools::Error(e.str().c_str()); @@ -2425,7 +2434,7 @@ bool cmLocalGenerator::GetShouldUseOldFlags(bool shared, { case cmPolicies::WARN: { - cmOStringStream e; + std::ostringstream e; e << "Variable " << flagsVar << " has been modified. CMake " "will ignore the POSITION_INDEPENDENT_CODE target property for " "shared libraries and will use the " << flagsVar << " variable " @@ -2505,7 +2514,7 @@ void cmLocalGenerator::AppendFlags(std::string& flags, { if(!newFlags.empty()) { - if(flags.size()) + if(!flags.empty()) { flags += " "; } @@ -2897,7 +2906,7 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, assert(in_remote[0] != '\"'); // The local path should never have a trailing slash. - assert(local.size() > 0 && !(local[local.size()-1] == "")); + assert(!local.empty() && !(local[local.size()-1] == "")); // If the path is already relative then just return the path. if(!cmSystemTools::FileIsFullPath(in_remote.c_str())) @@ -2959,7 +2968,7 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, // If the entire path is in common except for a trailing slash then // just return a "./". if(common+1 == remote.size() && - remote[common].size() == 0 && + remote[common].empty() && common == local.size()) { return "./"; @@ -2989,7 +2998,7 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, // the trailing slash in the output. for(unsigned int i=common; i < remote.size(); ++i) { - if(relative.size() > 0) + if(!relative.empty()) { relative += "/"; } @@ -3234,7 +3243,7 @@ cmLocalGenerator // Warn if this is the first time the path has been seen. if(this->ObjectMaxPathViolations.insert(dir_max).second) { - cmOStringStream m; + std::ostringstream m; m << "The object file directory\n" << " " << dir_max << "\n" << "has " << dir_max.size() << " characters. " @@ -3632,7 +3641,7 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const } if(function_style) { - cmOStringStream e; + std::ostringstream e; e << "WARNING: Function-style preprocessor definitions may not be " << "passed on the compiler command line because many compilers " << "do not support it.\n" @@ -3645,7 +3654,7 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const // Many compilers do not support # in the value so we disable it. if(define.find_first_of("#") != define.npos) { - cmOStringStream e; + std::ostringstream e; e << "WARNING: Preprocessor definitions containing '#' may not be " << "passed on the compiler command line because many compilers " << "do not support it.\n" @@ -3687,7 +3696,7 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmTarget* target, } if(!cmSystemTools::FileExists(inFile.c_str(), true)) { - cmOStringStream e; + std::ostringstream e; e << "Target " << target->GetName() << " Info.plist template \"" << inFile << "\" could not be found."; cmSystemTools::Error(e.str().c_str()); @@ -3731,7 +3740,7 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(cmTarget* target, } if(!cmSystemTools::FileExists(inFile.c_str(), true)) { - cmOStringStream e; + std::ostringstream e; e << "Target " << target->GetName() << " Info.plist template \"" << inFile << "\" could not be found."; cmSystemTools::Error(e.str().c_str()); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 9225f64..413dc0f 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -369,7 +369,7 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( return ":"; #endif - cmOStringStream cmd; + std::ostringstream cmd; for (std::vector<std::string>::const_iterator li = cmdLines.begin(); li != cmdLines.end(); ++li) #ifdef _WIN32 @@ -409,7 +409,7 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines( if (wd.empty()) wd = this->GetMakefile()->GetStartOutputDirectory(); - cmOStringStream cdCmd; + std::ostringstream cdCmd; #ifdef _WIN32 std::string cdStr = "cd /D "; #else @@ -440,10 +440,18 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile); const std::vector<std::string> &outputs = ccg.GetOutputs(); - cmNinjaDeps ninjaOutputs(outputs.size()), ninjaDeps; + const std::vector<std::string> &byproducts = ccg.GetByproducts(); + cmNinjaDeps ninjaOutputs(outputs.size()+byproducts.size()), ninjaDeps; +#if 0 +#error TODO: Once CC in an ExternalProject target must provide the \ + file of each imported target that has an add_dependencies pointing \ + at us. How to know which ExternalProject step actually provides it? +#endif std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), MapToNinjaPath()); + std::transform(byproducts.begin(), byproducts.end(), + ninjaOutputs.begin() + outputs.size(), MapToNinjaPath()); this->AppendCustomCommandDeps(ccg, ninjaDeps); for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end(); @@ -468,6 +476,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( this->BuildCommandLine(cmdLines), this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], + cc->GetUsesTerminal(), ninjaOutputs, ninjaDeps, orderOnlyDeps); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index c18e027..f825f5f 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -92,6 +92,7 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3() this->SkipAssemblySourceRules = false; this->MakeCommandEscapeTargetTwice = false; this->BorlandMakeCurlyHack = false; + this->NoMultiOutputMultiDepRules = false; } //---------------------------------------------------------------------------- @@ -315,36 +316,43 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() // Check whether preprocessing and assembly rules make sense. // They make sense only for C and C++ sources. - bool lang_is_c_or_cxx = false; + bool lang_has_preprocessor = false; + bool lang_has_assembly = false; + for(std::vector<LocalObjectEntry>::const_iterator ei = lo->second.begin(); ei != lo->second.end(); ++ei) { - if(ei->Language == "C" || ei->Language == "CXX") + if(ei->Language == "C" || + ei->Language == "CXX" || + ei->Language == "Fortran") { - lang_is_c_or_cxx = true; + // Right now, C, C++ and Fortran have both a preprocessor and the + // ability to generate assembly code + lang_has_preprocessor = true; + lang_has_assembly = true; break; } } // Add convenience rules for preprocessed and assembly files. - if(lang_is_c_or_cxx && (do_preprocess_rules || do_assembly_rules)) + if(lang_has_preprocessor && do_preprocess_rules) { std::string::size_type dot_pos = lo->first.rfind("."); std::string base = lo->first.substr(0, dot_pos); - if(do_preprocess_rules) - { - this->WriteObjectConvenienceRule( - ruleFileStream, "target to preprocess a source file", - (base + ".i").c_str(), lo->second); - lo->second.HasPreprocessRule = true; - } - if(do_assembly_rules) - { - this->WriteObjectConvenienceRule( - ruleFileStream, "target to generate assembly for a file", - (base + ".s").c_str(), lo->second); - lo->second.HasAssembleRule = true; - } + this->WriteObjectConvenienceRule( + ruleFileStream, "target to preprocess a source file", + (base + ".i").c_str(), lo->second); + lo->second.HasPreprocessRule = true; + } + + if(lang_has_assembly && do_assembly_rules) + { + std::string::size_type dot_pos = lo->first.rfind("."); + std::string base = lo->first.substr(0, dot_pos); + this->WriteObjectConvenienceRule( + ruleFileStream, "target to generate assembly for a file", + (base + ".s").c_str(), lo->second); + lo->second.HasAssembleRule = true; } } @@ -611,6 +619,30 @@ cmLocalUnixMakefileGenerator3 comment); return; } + std::vector<std::string> outputs(1, target); + this->WriteMakeRule(os, comment, + outputs, depends, commands, + symbolic, in_help); +} + +//---------------------------------------------------------------------------- +void +cmLocalUnixMakefileGenerator3 +::WriteMakeRule(std::ostream& os, + const char* comment, + const std::vector<std::string>& outputs, + const std::vector<std::string>& depends, + const std::vector<std::string>& commands, + bool symbolic, + bool in_help) +{ + // Make sure there is an output. + if(outputs.empty()) + { + cmSystemTools::Error("No outputs for WriteMakeRule! called with comment: ", + comment); + return; + } std::string replace; @@ -629,8 +661,18 @@ cmLocalUnixMakefileGenerator3 } // Construct the left hand side of the rule. - replace = target; - std::string tgt = this->Convert(replace,HOME_OUTPUT,MAKERULE); + std::string tgt; + { + const char* sep = ""; + for (std::vector<std::string>::const_iterator i = outputs.begin(); + i != outputs.end(); ++i) + { + tgt += sep; + tgt += this->Convert(*i,HOME_OUTPUT,MAKERULE); + sep = " "; + } + } + const char* space = ""; if(tgt.size() == 1) { @@ -655,6 +697,19 @@ cmLocalUnixMakefileGenerator3 // No dependencies. The commands will always run. os << cmMakeSafe(tgt) << space << ":\n"; } + else if(this->NoMultiOutputMultiDepRules && outputs.size() >= 2) + { + // Borland make does not understand multiple dependency rules when + // there are multiple outputs, so write them all on one line. + os << cmMakeSafe(tgt) << space << ":"; + for(std::vector<std::string>::const_iterator dep = depends.begin(); + dep != depends.end(); ++dep) + { + replace = this->Convert(*dep, HOME_OUTPUT, MAKERULE); + os << " " << cmMakeSafe(replace); + } + os << "\n"; + } else { // Split dependencies into multiple rule lines. This allows for @@ -683,7 +738,8 @@ cmLocalUnixMakefileGenerator3 // Add the output to the local help if requested. if(in_help) { - this->LocalHelp.push_back(target); + this->LocalHelp.insert(this->LocalHelp.end(), + outputs.begin(), outputs.end()); } } @@ -1101,7 +1157,7 @@ cmLocalUnixMakefileGenerator3 { // Build the command line in a single string. std::string cmd = ccg.GetCommand(c); - if (cmd.size()) + if (!cmd.empty()) { // Use "call " before any invocations of .bat or .cmd files // invoked as custom commands in the WindowsShell. @@ -1495,7 +1551,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Dependee \"" << tgtInfo << "\" is newer than depender \"" << internalDependFile << "\"." << std::endl; @@ -1518,7 +1574,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \"" << internalDependFile << "\"." << std::endl; @@ -1702,6 +1758,8 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) { + // Nothing populates multiple output pairs anymore, but we need to + // honor it when working in a build tree generated by an older CMake. cmMakefile* mf = this->Makefile; // Get the string listing the multiple output pairs. @@ -1727,7 +1785,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose) { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Deleting primary custom command output \"" << dependee << "\" because another output \"" << depender << "\" does not exist." << std::endl; @@ -1795,13 +1853,8 @@ void cmLocalUnixMakefileGenerator3 { text = "Running external command ..."; } - std::set<std::string>::const_iterator dit; - for ( dit = glIt->second.GetUtilities().begin(); - dit != glIt->second.GetUtilities().end(); - ++ dit ) - { - depends.push_back(*dit); - } + depends.insert(depends.end(), glIt->second.GetUtilities().begin(), + glIt->second.GetUtilities().end()); this->AppendEcho(commands, text, cmLocalUnixMakefileGenerator3::EchoGlobal); @@ -1857,7 +1910,7 @@ void cmLocalUnixMakefileGenerator3 std::string progressDir = this->Makefile->GetHomeOutputDirectory(); progressDir += cmake::GetCMakeFilesDirectory(); { - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; progCmd << this->Convert(progressDir, @@ -1881,7 +1934,7 @@ void cmLocalUnixMakefileGenerator3 this->Makefile->GetHomeOutputDirectory(), cmLocalGenerator::START_OUTPUT); { - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 progCmd << this->Convert(progressDir, cmLocalGenerator::FULL, @@ -2117,7 +2170,7 @@ cmLocalUnixMakefileGenerator3 cmd += " "; // Pass down verbosity level. - if(this->GetMakeSilentFlag().size()) + if(!this->GetMakeSilentFlag().empty()) { cmd += this->GetMakeSilentFlag(); cmd += " "; @@ -2241,7 +2294,7 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p, for(unsigned int i=1; i < components.size(); ++i) { // Only the last component can be empty to avoid double slashes. - if(components[i].length() > 0 || (i == (components.size()-1))) + if(!components[i].empty() || (i == (components.size()-1))) { if(!first) { diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 4f2e4a0..7c8e27f 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -61,6 +61,13 @@ public: const std::vector<std::string>& commands, bool symbolic, bool in_help = false); + void WriteMakeRule(std::ostream& os, + const char* comment, + const std::vector<std::string>& outputs, + const std::vector<std::string>& depends, + const std::vector<std::string>& commands, + bool symbolic, + bool in_help = false); // write the main variables used by the makefiles void WriteMakeVariables(std::ostream& makefileStream); @@ -154,6 +161,9 @@ public: void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; } + void SetNoMultiOutputMultiDepRules(bool b) + { this->NoMultiOutputMultiDepRules = b; } + // used in writing out Cmake files such as WriteDirectoryInformation static void WriteCMakeArgument(std::ostream& os, const char* s); @@ -338,6 +348,7 @@ private: bool PassMakeflags; bool MakeCommandEscapeTargetTwice; bool BorlandMakeCurlyHack; + bool NoMultiOutputMultiDepRules; //========================================================================== std::string HomeRelativeOutputPath; diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index c14fb2b..1d62093 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -821,10 +821,12 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target, command.push_back("make_directory"); command.push_back(outDir); std::vector<std::string> no_output; + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, + no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; @@ -1319,7 +1321,7 @@ void cmLocalVisualStudio6Generator int major; int minor; target.GetTargetVersion(major, minor); - cmOStringStream targetVersionStream; + std::ostringstream targetVersionStream; targetVersionStream << "/version:" << major << "." << minor; targetVersionFlag = targetVersionStream.str(); } @@ -1996,7 +1998,7 @@ cmLocalVisualStudio6Generator if(define.find_first_of(" ") != define.npos && define.find_first_of("\"$;") != define.npos) { - cmOStringStream e; + std::ostringstream e; e << "WARNING: The VS6 IDE does not support preprocessor definition " << "values with spaces and '\"', '$', or ';'.\n" << "CMake is dropping a preprocessor definition: " << define << "\n" diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index eb45423..914df5f 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -592,6 +592,15 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {0,0,0,0,0} }; +cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranLinkFlagTable[] = +{ + {"LinkIncremental", "INCREMENTAL:NO", "link incremental", + "linkIncrementalNo", 0}, + {"LinkIncremental", "INCREMENTAL:YES", "link incremental", + "linkIncrementalYes", 0}, + {0,0,0,0,0} +}; + //---------------------------------------------------------------------------- // Helper class to write build event <Tool .../> elements. class cmLocalVisualStudio7Generator::EventWriter @@ -1056,8 +1065,13 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, extraLinkOptions += " "; extraLinkOptions += targetLinkFlags; } - Options linkOptions(this, Options::Linker, - cmLocalVisualStudio7GeneratorLinkFlagTable); + Options linkOptions(this, Options::Linker); + if(this->FortranProject) + { + linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable); + } + linkOptions.AddTable(cmLocalVisualStudio7GeneratorLinkFlagTable); + linkOptions.Parse(extraLinkOptions.c_str()); if(!this->ModuleDefinitionFile.empty()) { @@ -1101,7 +1115,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, if(this->GetVersion() < VS8 || this->FortranProject) { - cmOStringStream libdeps; + std::ostringstream libdeps; this->Internal->OutputObjects(libdeps, &target); if(!libdeps.str().empty()) { @@ -1699,7 +1713,7 @@ bool cmLocalVisualStudio7Generator // Write the children to temporary output. bool hasChildrenWithSources = false; - cmOStringStream tmpOut; + std::ostringstream tmpOut; for(unsigned int i=0;i<children.size();++i) { if(this->WriteGroup(&children[i], target, tmpOut, libName, configs)) diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 9680d43..f01aa6b 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -95,10 +95,12 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target, command.push_back("make_directory"); command.push_back(impDir); std::vector<std::string> no_output; + std::vector<std::string> no_byproducts; std::vector<std::string> no_depends; cmCustomCommandLines commands; commands.push_back(command); - pcc.reset(new cmCustomCommand(0, no_output, no_depends, commands, 0, 0)); + pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, + no_depends, commands, 0, 0)); pcc->SetEscapeOldStyle(false); pcc->SetEscapeAllowMakeVars(true); return pcc; diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx new file mode 100644 index 0000000..1607845 --- /dev/null +++ b/Source/cmMachO.cxx @@ -0,0 +1,419 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmStandardIncludes.h" // to get CMAKE_USE_MACH_PARSER first +#include "cmMachO.h" + +#include <cmsys/FStream.hxx> + +// Include the Mach-O format information system header. +#include <mach-o/loader.h> +#include <mach-o/fat.h> + +/** + + https://developer.apple.com/library/mac/documentation/ + DeveloperTools/Conceptual/MachORuntime/index.html + + A Mach-O file has 3 major regions: header, load commands and segments. + Data Structures are provided from <mach-o/loader.h> which + correspond to the file structure. + + The header can be either a struct mach_header or struct mach_header_64. + One can peek at the first 4 bytes to identify the type of header. + + Following is the load command region which starts with + struct load_command, and is followed by n number of load commands. + + In the case of a universal binary (an archive of multiple Mach-O files), + the file begins with a struct fat_header and is followed by multiple + struct fat_arch instances. The struct fat_arch indicates the offset + for each Mach-O file. + + */ + +namespace { + + // peek in the file + template <typename T> + bool peek(cmsys::ifstream& fin, T &v) + { + std::streampos p = fin.tellg(); + if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T))) + { + return false; + } + fin.seekg(p); + return fin.good(); + } + + // read from the file and fill a data structure + template <typename T> + bool read(cmsys::ifstream& fin, T& v) + { + if(!fin.read(reinterpret_cast<char*>(&v), sizeof(T))) + { + return false; + } + return true; + } + + // read from the file and fill multiple data structures where + // the vector has been resized + template <typename T> + bool read(cmsys::ifstream& fin, std::vector<T>& v) + { + // nothing to read + if(v.empty()) + { + return true; + } + if(!fin.read(reinterpret_cast<char*>(&v[0]), sizeof(T) * v.size())) + { + return false; + } + return true; + } +} + + +// Contains header and load commands for a single Mach-O file +class cmMachOHeaderAndLoadCommands +{ +public: + // A load_command and its associated data + struct RawLoadCommand + { + uint32_t type(const cmMachOHeaderAndLoadCommands* m) const + { + if(this->LoadCommand.size() < sizeof(load_command)) + { + return 0; + } + const load_command* cmd = + reinterpret_cast<const load_command*>(&this->LoadCommand[0]); + return m->swap(cmd->cmd); + } + std::vector<char> LoadCommand; + }; + + cmMachOHeaderAndLoadCommands(bool _swap) + : Swap(_swap) + { + } + virtual ~cmMachOHeaderAndLoadCommands() + { + } + + virtual bool read_mach_o(cmsys::ifstream& fin) = 0; + + const std::vector<RawLoadCommand>& load_commands() const + { + return this->LoadCommands; + } + + uint32_t swap(uint32_t v) const + { + if(this->Swap) + { + char* c = reinterpret_cast<char*>(&v); + std::swap(c[0], c[3]); + std::swap(c[1], c[2]); + } + return v; + } + +protected: + bool read_load_commands(uint32_t ncmds, uint32_t sizeofcmds, + cmsys::ifstream& fin); + + bool Swap; + std::vector<RawLoadCommand> LoadCommands; +}; + +// Implementation for reading Mach-O header and load commands. +// This is 32 or 64 bit arch specific. +template <class T> +class cmMachOHeaderAndLoadCommandsImpl : public cmMachOHeaderAndLoadCommands +{ +public: + cmMachOHeaderAndLoadCommandsImpl(bool _swap) + : cmMachOHeaderAndLoadCommands(_swap) + { + } + bool read_mach_o(cmsys::ifstream& fin) + { + if(!read(fin, this->Header)) + { + return false; + } + this->Header.cputype = swap(this->Header.cputype); + this->Header.cpusubtype = swap(this->Header.cpusubtype); + this->Header.filetype = swap(this->Header.filetype); + this->Header.ncmds = swap(this->Header.ncmds); + this->Header.sizeofcmds = swap(this->Header.sizeofcmds); + this->Header.flags = swap(this->Header.flags); + + return read_load_commands(this->Header.ncmds, + this->Header.sizeofcmds, + fin); + } +protected: + T Header; +}; + + +bool cmMachOHeaderAndLoadCommands::read_load_commands(uint32_t ncmds, + uint32_t sizeofcmds, + cmsys::ifstream& fin) +{ + uint32_t size_read = 0; + this->LoadCommands.resize(ncmds); + for(uint32_t i = 0; i<ncmds; i++) + { + load_command lc; + if(!peek(fin, lc)) + { + return false; + } + lc.cmd = swap(lc.cmd); + lc.cmdsize = swap(lc.cmdsize); + size_read += lc.cmdsize; + + RawLoadCommand& c = this->LoadCommands[i]; + c.LoadCommand.resize(lc.cmdsize); + if(!read(fin, c.LoadCommand)) + { + return false; + } + } + + if(size_read != sizeofcmds) + { + this->LoadCommands.clear(); + return false; + } + + return true; +} + +//---------------------------------------------------------------------------- +class cmMachOInternal +{ +public: + cmMachOInternal(const char* fname); + ~cmMachOInternal(); + + // read a Mach-O file + bool read_mach_o(uint32_t file_offset); + + // the file we are reading + cmsys::ifstream Fin; + + // The archs in the universal binary + // If the binary is not a universal binary, this will be empty. + std::vector<fat_arch> FatArchs; + + // the error message while parsing + std::string ErrorMessage; + + // the list of Mach-O's + std::vector<cmMachOHeaderAndLoadCommands*> MachOList; +}; + +cmMachOInternal::cmMachOInternal(const char* fname) + : Fin(fname) +{ + // Quit now if the file could not be opened. + if(!this->Fin || !this->Fin.get() ) + { + this->ErrorMessage = "Error opening input file."; + return; + } + + if(!this->Fin.seekg(0)) + { + this->ErrorMessage = "Error seeking to beginning of file."; + return; + } + + // Read the binary identification block. + uint32_t magic = 0; + if(!peek(this->Fin, magic)) + { + this->ErrorMessage = "Error reading Mach-O identification."; + return; + } + + // Verify the binary identification. + if(!(magic == MH_CIGAM || + magic == MH_MAGIC || + magic == MH_CIGAM_64 || + magic == MH_MAGIC_64 || + magic == FAT_CIGAM || + magic == FAT_MAGIC)) + { + this->ErrorMessage = "File does not have a valid Mach-O identification."; + return; + } + + if(magic == FAT_MAGIC || magic == FAT_CIGAM) + { + // this is a universal binary + fat_header header; + if(!read(this->Fin, header)) + { + this->ErrorMessage = "Error reading fat header."; + return; + } + + // read fat_archs + this->FatArchs.resize(OSSwapBigToHostInt32(header.nfat_arch)); + if(!read(this->Fin, this->FatArchs)) + { + this->ErrorMessage = "Error reading fat header archs."; + return; + } + + // parse each Mach-O file + for(size_t i=0; i<this->FatArchs.size(); i++) + { + const fat_arch& arch = this->FatArchs[i]; + if(!this->read_mach_o(OSSwapBigToHostInt32(arch.offset))) + { + return; + } + } + } + else + { + // parse Mach-O file at the beginning of the file + this->read_mach_o(0); + } +} + +cmMachOInternal::~cmMachOInternal() +{ + for(size_t i=0; i<this->MachOList.size(); i++) + { + delete this->MachOList[i]; + } +} + +bool cmMachOInternal::read_mach_o(uint32_t file_offset) +{ + if(!this->Fin.seekg(file_offset)) + { + this->ErrorMessage = "Failed to locate Mach-O content."; + return false; + } + + uint32_t magic; + if(!peek(this->Fin, magic)) + { + this->ErrorMessage = "Error reading Mach-O identification."; + return false; + } + + cmMachOHeaderAndLoadCommands* f = NULL; + if(magic == MH_CIGAM || magic == MH_MAGIC) + { + bool swap = false; + if(magic == MH_CIGAM) + { + swap = true; + } + f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap); + } + else if(magic == MH_CIGAM_64 || magic == MH_MAGIC_64) + { + bool swap = false; + if(magic == MH_CIGAM_64) + { + swap = true; + } + f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap); + } + + if(f && f->read_mach_o(this->Fin)) + { + this->MachOList.push_back(f); + } + else + { + delete f; + this->ErrorMessage = "Failed to read Mach-O header."; + return false; + } + + return true; +} + +//============================================================================ +// External class implementation. + +//---------------------------------------------------------------------------- +cmMachO::cmMachO(const char* fname): Internal(0) +{ + this->Internal = new cmMachOInternal(fname); + +} + +//---------------------------------------------------------------------------- +cmMachO::~cmMachO() +{ + delete this->Internal; +} + +std::string const& cmMachO::GetErrorMessage() const +{ + return this->Internal->ErrorMessage; +} + +//---------------------------------------------------------------------------- +bool cmMachO::Valid() const +{ + return !this->Internal->MachOList.empty(); +} + +bool cmMachO::GetInstallName(std::string& install_name) +{ + if(this->Internal->MachOList.empty()) + { + return false; + } + + // grab the first Mach-O and get the install name from that one + cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0]; + for(size_t i=0; i<macho->load_commands().size(); i++) + { + const cmMachOHeaderAndLoadCommands::RawLoadCommand &cmd = + macho->load_commands()[i]; + uint32_t lc_cmd = cmd.type(macho); + if(lc_cmd == LC_ID_DYLIB || + lc_cmd == LC_LOAD_WEAK_DYLIB || + lc_cmd == LC_LOAD_DYLIB) + { + if(sizeof(dylib_command) < cmd.LoadCommand.size()) + { + uint32_t namelen = cmd.LoadCommand.size() - sizeof(dylib_command); + install_name.assign(&cmd.LoadCommand[sizeof(dylib_command)], namelen); + return true; + } + } + } + + return false; +} + +void cmMachO::PrintInfo(std::ostream& /*os*/) const +{ +} diff --git a/Source/cmMachO.h b/Source/cmMachO.h new file mode 100644 index 0000000..f06f8de --- /dev/null +++ b/Source/cmMachO.h @@ -0,0 +1,51 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmMachO_h +#define cmMachO_h + +#if !defined(CMAKE_USE_MACH_PARSER) +# error "This file may be included only if CMAKE_USE_MACH_PARSER is enabled." +#endif + +class cmMachOInternal; + +/** \class cmMachO + * \brief Executable and Link Format (Mach-O) parser. + */ +class cmMachO +{ +public: + /** Construct with the name of the Mach-O input file to parse. */ + cmMachO(const char* fname); + + /** Destruct. */ + ~cmMachO(); + + /** Get the error message if any. */ + std::string const& GetErrorMessage() const; + + /** Boolean conversion. True if the Mach-O file is valid. */ + operator bool() const { return this->Valid(); } + + /** Get Install name from binary **/ + bool GetInstallName(std::string& install_name); + + /** Print human-readable information about the Mach-O file. */ + void PrintInfo(std::ostream& os) const; + +private: + friend class cmMachOInternal; + bool Valid() const; + cmMachOInternal* Internal; +}; + +#endif diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index ae81c58..69fcca7 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -107,7 +107,7 @@ bool cmMacroHelperCommand::InvokeInitialPass cmMakefile::PolicyPushPop polScope(this->Makefile, true, this->Policies); // set the value of argc - cmOStringStream argcDefStream; + std::ostringstream argcDefStream; argcDefStream << expandedArgs.size(); std::string argcDef = argcDefStream.str(); @@ -116,7 +116,7 @@ bool cmMacroHelperCommand::InvokeInitialPass std::string argnDef; bool argnDefInitialized = false; bool argvDefInitialized = false; - if( this->Functions.size()) + if(!this->Functions.empty()) { this->FilePath = this->Functions[0].FilePath; } @@ -170,7 +170,7 @@ bool cmMacroHelperCommand::InvokeInitialPass { if ( cnt >= this->Args.size()-1 ) { - if ( argnDef.size() > 0 ) + if (!argnDef.empty()) { argnDef += ";"; } @@ -195,7 +195,7 @@ bool cmMacroHelperCommand::InvokeInitialPass std::vector<std::string>::const_iterator eit; for(eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit) { - if ( argvDef.size() > 0 ) + if (!argvDef.empty()) { argvDef += ";"; } @@ -328,11 +328,7 @@ bool cmMacroCommand::InitialPass(std::vector<std::string> const& args, // create a function blocker cmMacroFunctionBlocker *f = new cmMacroFunctionBlocker(); - for(std::vector<std::string>::const_iterator j = args.begin(); - j != args.end(); ++j) - { - f->Args.push_back(*j); - } + f->Args.insert(f->Args.end(), args.begin(), args.end()); this->Makefile->AddFunctionBlocker(f); return true; } diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 1499e57..31bbb73 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -34,12 +34,7 @@ cmMakeDepend::cmMakeDepend() cmMakeDepend::~cmMakeDepend() { - for(DependInformationMapType::iterator i = - this->DependInformationMap.begin(); - i != this->DependInformationMap.end(); ++i) - { - delete i->second; - } + cmDeleteAll(this->DependInformationMap); } @@ -180,7 +175,7 @@ void cmMakeDepend::GenerateDependInformation(cmDependInformation* info) t != this->IncludeDirectories.end(); ++t) { std::string incpath = *t; - if (incpath.size() && incpath[incpath.size() - 1] != '/') + if (!incpath.empty() && incpath[incpath.size() - 1] != '/') { incpath = incpath + "/"; } @@ -323,7 +318,7 @@ std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath) i != this->IncludeDirectories.end(); ++i) { std::string path = *i; - if (path.size() && path[path.size() - 1] != '/') + if (!path.empty() && path[path.size() - 1] != '/') { path = path + "/"; } @@ -340,7 +335,7 @@ std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath) if (extraPath) { std::string path = extraPath; - if (path.size() && path[path.size() - 1] != '/') + if (!path.empty() && path[path.size() - 1] != '/') { path = path + "/"; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 8a8aadc..87e62d7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -102,7 +102,6 @@ cmMakefile::cmMakefile(): Internal(new Internals) this->PreOrder = false; this->GeneratingBuildSystem = false; - this->NumLastMatches = 0; this->SuppressWatches = false; } @@ -153,7 +152,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->ListFileStack = mf.ListFileStack; this->OutputToSource = mf.OutputToSource; - this->NumLastMatches = mf.NumLastMatches; this->SuppressWatches = mf.SuppressWatches; } @@ -171,6 +169,9 @@ void cmMakefile::Initialize() // Protect the directory-level policies. this->PushPolicyBarrier(); + // push empty loop block + this->PushLoopBlockBarrier(); + // By default the check is not done. It is enabled by // cmListFileCache in the top level if necessary. this->CheckCMP0000 = false; @@ -193,45 +194,13 @@ bool cmMakefile::NeedCacheCompatibility(int major, int minor) const cmMakefile::~cmMakefile() { - for(std::vector<cmInstallGenerator*>::iterator - i = this->InstallGenerators.begin(); - i != this->InstallGenerators.end(); ++i) - { - delete *i; - } - for(std::vector<cmTestGenerator*>::iterator - i = this->TestGenerators.begin(); - i != this->TestGenerators.end(); ++i) - { - delete *i; - } - for(std::vector<cmSourceFile*>::iterator i = this->SourceFiles.begin(); - i != this->SourceFiles.end(); ++i) - { - delete *i; - } - for(std::map<std::string, cmTest*>::iterator i = this->Tests.begin(); - i != this->Tests.end(); ++i) - { - delete i->second; - } - for(std::vector<cmTarget*>::iterator - i = this->ImportedTargetsOwned.begin(); - i != this->ImportedTargetsOwned.end(); ++i) - { - delete *i; - } - for(unsigned int i=0; i < this->FinalPassCommands.size(); i++) - { - delete this->FinalPassCommands[i]; - } - std::vector<cmFunctionBlocker*>::iterator pos; - for (pos = this->FunctionBlockers.begin(); - pos != this->FunctionBlockers.end(); ++pos) - { - cmFunctionBlocker* b = *pos; - delete b; - } + cmDeleteAll(this->InstallGenerators); + cmDeleteAll(this->TestGenerators); + cmDeleteAll(this->SourceFiles); + cmDeleteAll(this->Tests); + cmDeleteAll(this->ImportedTargetsOwned); + cmDeleteAll(this->FinalPassCommands); + cmDeleteAll(this->FunctionBlockers); this->FunctionBlockers.clear(); if (this->PolicyStack.size() != 1) { @@ -362,7 +331,7 @@ cmListFileBacktrace cmMakefile::GetBacktrace() const //---------------------------------------------------------------------------- void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const { - cmOStringStream msg; + std::ostringstream msg; msg << lff.FilePath << "(" << lff.Line << "): "; msg << lff.Name << "("; for(std::vector<cmListFileArgument>::const_iterator i = @@ -555,7 +524,7 @@ void cmMakefile::IncludeScope::EnforceCMP0011() case cmPolicies::WARN: // Warn because the user did not set this policy. { - cmOStringStream w; + std::ostringstream w; w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n" << "The included script\n " << this->File << "\n" << "affects policy settings. " @@ -567,7 +536,7 @@ void cmMakefile::IncludeScope::EnforceCMP0011() case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: { - cmOStringStream e; + std::ostringstream e; e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n" << "The included script\n " << this->File << "\n" << "affects policy settings, so it requires this policy to be set."; @@ -740,7 +709,7 @@ void cmMakefile::EnforceDirectoryLevelRules() const // Diagnose a violation of CMP0000 if necessary. if(this->CheckCMP0000) { - cmOStringStream msg; + std::ostringstream msg; msg << "No cmake_minimum_required command is present. " << "A line of code such as\n" << " cmake_minimum_required(VERSION " @@ -880,12 +849,14 @@ void cmMakefile::ConfigureFinalPass() //---------------------------------------------------------------------------- void cmMakefile::AddCustomCommandToTarget(const std::string& target, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, const char* comment, const char* workingDir, - bool escapeOldStyle) const + bool escapeOldStyle, + bool uses_terminal) { // Find the target to which to add the custom command. cmTargets::iterator ti = this->Targets.find(target); @@ -894,7 +865,7 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target, { cmake::MessageType messageType = cmake::AUTHOR_WARNING; bool issueMessage = false; - cmOStringStream e; + std::ostringstream e; switch(this->GetPolicyStatus(cmPolicies::CMP0040)) { case cmPolicies::WARN: @@ -921,7 +892,7 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target, if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << target << "\" is an OBJECT library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -929,18 +900,30 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target, } if(ti->second.GetType() == cmTarget::INTERFACE_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << target << "\" is an INTERFACE library " "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } + + // Always create the byproduct sources and mark them generated. + for(std::vector<std::string>::const_iterator o = byproducts.begin(); + o != byproducts.end(); ++o) + { + if(cmSourceFile* out = this->GetOrCreateSource(*o, true)) + { + out->SetProperty("GENERATED", "1"); + } + } + // Add the command to the appropriate build step for the target. std::vector<std::string> no_output; - cmCustomCommand cc(this, no_output, depends, + cmCustomCommand cc(this, no_output, byproducts, depends, commandLines, comment, workingDir); cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeAllowMakeVars(true); + cc.SetUsesTerminal(uses_terminal); switch(type) { case cmTarget::PRE_BUILD: @@ -958,13 +941,15 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target, //---------------------------------------------------------------------------- cmSourceFile* cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, - bool escapeOldStyle) + bool escapeOldStyle, + bool uses_terminal) { // Make sure there is at least one output. if(outputs.empty()) @@ -980,7 +965,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, cmCustomCommandLine const& cl = *i; if(!cl.empty() && !cl[0].empty() && cl[0][0] == '"') { - cmOStringStream e; + std::ostringstream e; e << "COMMAND may not contain literal quotes:\n " << cl[0] << "\n"; this->IssueMessage(cmake::FATAL_ERROR, e.str()); return 0; @@ -1055,6 +1040,14 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, out->SetProperty("GENERATED", "1"); } } + for(std::vector<std::string>::const_iterator o = byproducts.begin(); + o != byproducts.end(); ++o) + { + if(cmSourceFile* out = this->GetOrCreateSource(*o, true)) + { + out->SetProperty("GENERATED", "1"); + } + } // Attach the custom command to the file. if(file) @@ -1067,10 +1060,11 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, } cmCustomCommand* cc = - new cmCustomCommand(this, outputs, depends2, commandLines, - comment, workingDir); + new cmCustomCommand(this, outputs, byproducts, depends2, + commandLines, comment, workingDir); cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); + cc->SetUsesTerminal(uses_terminal); file->SetCustomCommand(cc); this->UpdateOutputToSourceMap(outputs, file); } @@ -1119,13 +1113,17 @@ cmMakefile::AddCustomCommandToOutput(const std::string& output, const char* comment, const char* workingDir, bool replace, - bool escapeOldStyle) + bool escapeOldStyle, + bool uses_terminal) { std::vector<std::string> outputs; outputs.push_back(output); - return this->AddCustomCommandToOutput(outputs, depends, main_dependency, + std::vector<std::string> no_byproducts; + return this->AddCustomCommandToOutput(outputs, no_byproducts, + depends, main_dependency, commandLines, comment, workingDir, - replace, escapeOldStyle); + replace, escapeOldStyle, + uses_terminal); } //---------------------------------------------------------------------------- @@ -1144,7 +1142,9 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target, // In the old-style signature if the source and target were the // same then it added a post-build rule to the target. Preserve // this behavior. - this->AddCustomCommandToTarget(target, depends, commandLines, + std::vector<std::string> no_byproducts; + this->AddCustomCommandToTarget(target, no_byproducts, + depends, commandLines, cmTarget::POST_BUILD, comment, 0); return; } @@ -1242,7 +1242,25 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName, const char* workingDirectory, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, - bool escapeOldStyle, const char* comment) + bool escapeOldStyle, const char* comment, + bool uses_terminal) +{ + std::vector<std::string> no_byproducts; + return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory, + no_byproducts, depends, commandLines, + escapeOldStyle, comment, uses_terminal); +} + +//---------------------------------------------------------------------------- +cmTarget* +cmMakefile::AddUtilityCommand(const std::string& utilityName, + bool excludeFromAll, + const char* workingDirectory, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, + bool escapeOldStyle, const char* comment, + bool uses_terminal) { // Create a target instance for this utility. cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName); @@ -1263,13 +1281,15 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName, force += cmake::GetCMakeFilesDirectory(); force += "/"; force += utilityName; + std::vector<std::string> forced; + forced.push_back(force); std::string no_main_dependency = ""; bool no_replace = false; - this->AddCustomCommandToOutput(force, depends, - no_main_dependency, + this->AddCustomCommandToOutput(forced, byproducts, + depends, no_main_dependency, commandLines, comment, workingDirectory, no_replace, - escapeOldStyle); + escapeOldStyle, uses_terminal); cmSourceFile* sf = target->AddSourceCMP0049(force); // The output is not actually created so mark it symbolic. @@ -1282,6 +1302,16 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName, cmSystemTools::Error("Could not get source file entry for ", force.c_str()); } + + // Always create the byproduct sources and mark them generated. + for(std::vector<std::string>::const_iterator o = byproducts.begin(); + o != byproducts.end(); ++o) + { + if(cmSourceFile* out = this->GetOrCreateSource(*o, true)) + { + out->SetProperty("GENERATED", "1"); + } + } } return target; } @@ -1493,7 +1523,7 @@ void cmMakefile::AddLinkLibraryForTarget(const std::string& target, (tgt->GetType() == cmTarget::INTERFACE_LIBRARY) || tgt->IsExecutableWithExports())) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << lib << "\" of type " << cmTarget::GetTargetTypeName(tgt->GetType()) << " may not be linked into another target. " @@ -1506,7 +1536,7 @@ void cmMakefile::AddLinkLibraryForTarget(const std::string& target, } else { - cmOStringStream e; + std::ostringstream e; e << "Attempt to add link library \"" << lib << "\" to target \"" << target << "\" which is not built in this directory."; @@ -1522,7 +1552,7 @@ void cmMakefile::AddLinkDirectoryForTarget(const std::string& target, { if(this->IsAlias(target)) { - cmOStringStream e; + std::ostringstream e; e << "ALIAS target \"" << target << "\" " << "may not be linked into another target."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1729,22 +1759,12 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs, return; } - std::string incString; - std::string sep; - - for(std::vector<std::string>::const_iterator li = incs.begin(); - li != incs.end(); ++li) - { - incString += sep + *li; - sep = ";"; - } - std::vector<cmValueWithOrigin>::iterator position = before ? this->IncludeDirectoriesEntries.begin() : this->IncludeDirectoriesEntries.end(); cmListFileBacktrace lfbt = this->GetBacktrace(); - cmValueWithOrigin entry(incString, lfbt); + cmValueWithOrigin entry(cmJoin(incs, ";"), lfbt); this->IncludeDirectoriesEntries.insert(position, entry); // Property on each target: @@ -1760,11 +1780,7 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs, void cmMakefile::AddSystemIncludeDirectories(const std::set<std::string> &incs) { - for(std::set<std::string>::const_iterator li = incs.begin(); - li != incs.end(); ++li) - { - this->SystemIncludeDirectories.insert(*li); - } + this->SystemIncludeDirectories.insert(incs.begin(), incs.end()); for (cmTargets::iterator l = this->Targets.begin(); l != this->Targets.end(); ++l) @@ -1782,7 +1798,7 @@ void cmMakefile::AddDefinition(const std::string& name, const char* value) } this->Internal->VarStack.top().Set(name, value); - if (this->Internal->VarUsageStack.size() && + if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { this->CheckForUnused("changing definition", name); @@ -1857,7 +1873,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, void cmMakefile::AddDefinition(const std::string& name, bool value) { this->Internal->VarStack.top().Set(name, value? "ON" : "OFF"); - if (this->Internal->VarUsageStack.size() && + if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { this->CheckForUnused("changing definition", name); @@ -1921,7 +1937,7 @@ void cmMakefile::CheckForUnused(const char* reason, { std::string path; cmListFileBacktrace bt(this->GetLocalGenerator()); - if (this->CallStack.size()) + if (!this->CallStack.empty()) { const cmListFileContext* file = this->CallStack.back().Context; bt.push_back(*file); @@ -1944,7 +1960,7 @@ void cmMakefile::CheckForUnused(const char* reason, !cmSystemTools::IsSubDirectory(path, cmake::GetCMakeFilesDirectory()))) { - cmOStringStream msg; + std::ostringstream msg; msg << "unused variable (" << reason << ") \'" << name << "\'"; this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, msg.str(), @@ -1956,7 +1972,7 @@ void cmMakefile::CheckForUnused(const char* reason, void cmMakefile::RemoveDefinition(const std::string& name) { this->Internal->VarStack.top().Set(name, 0); - if (this->Internal->VarUsageStack.size() && + if (!this->Internal->VarUsageStack.empty() && this->VariableInitialized(name)) { this->CheckForUnused("unsetting", name); @@ -2249,7 +2265,7 @@ void cmMakefile::ExpandVariablesCMP0019() { return; } - cmOStringStream w; + std::ostringstream w; const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); if(mightExpandVariablesCMP0019(includeDirs)) @@ -2327,7 +2343,7 @@ void cmMakefile::ExpandVariablesCMP0019() if(!w.str().empty()) { - cmOStringStream m; + std::ostringstream m; m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019) << "\n" << "The following variable evaluations were encountered:\n" @@ -2505,12 +2521,7 @@ std::vector<std::string> cmMakefile } std::vector<std::string> res; - - std::set<std::string>::iterator fit; - for ( fit = definitions.begin(); fit != definitions.end(); fit ++ ) - { - res.push_back(*fit); - } + res.insert(res.end(), definitions.begin(), definitions.end()); return res; } @@ -2720,7 +2731,7 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringOld( else { // Construct the main error message. - cmOStringStream error; + std::ostringstream error; error << "Syntax error in cmake code "; if(filename && line > 0) { @@ -2828,7 +2839,7 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( case NORMAL: if(filename && lookup == lineVar) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << line; varresult = ostr.str(); } @@ -2870,7 +2881,7 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( cmSystemTools::IsSubDirectory(filename, this->GetHomeOutputDirectory())) { - cmOStringStream msg; + std::ostringstream msg; cmListFileBacktrace bt(this->GetLocalGenerator()); cmListFileContext lfc; lfc.FilePath = filename; @@ -3064,7 +3075,7 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( if(error) { - cmOStringStream emsg; + std::ostringstream emsg; emsg << "Syntax error in cmake code "; if(filename) { @@ -3279,7 +3290,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) { // Report the context in which the unclosed block was opened. cmListFileContext const& lfc = fb->GetStartingContext(); - cmOStringStream e; + std::ostringstream e; e << "A logical block opening on the line\n" << " " << lfc << "\n" << "is not closed."; @@ -3293,6 +3304,38 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) } //---------------------------------------------------------------------------- +void cmMakefile::PushLoopBlock() +{ + assert(!this->LoopBlockCounter.empty()); + this->LoopBlockCounter.top()++; +} + +void cmMakefile::PopLoopBlock() +{ + assert(!this->LoopBlockCounter.empty()); + assert(this->LoopBlockCounter.top() > 0); + this->LoopBlockCounter.top()--; +} + +void cmMakefile::PushLoopBlockBarrier() +{ + this->LoopBlockCounter.push(0); +} + +void cmMakefile::PopLoopBlockBarrier() +{ + assert(!this->LoopBlockCounter.empty()); + assert(this->LoopBlockCounter.top() == 0); + this->LoopBlockCounter.pop(); +} + +bool cmMakefile::IsLoopBlock() const +{ + assert(!this->LoopBlockCounter.empty()); + return !this->LoopBlockCounter.empty() && this->LoopBlockCounter.top() > 0; +} + +//---------------------------------------------------------------------------- bool cmMakefile::ExpandArguments( std::vector<cmListFileArgument> const& inArgs, std::vector<std::string>& outArgs) const @@ -3405,7 +3448,7 @@ cmMakefile::RemoveFunctionBlocker(cmFunctionBlocker* fb, if(!(*pos)->ShouldRemove(lff, *this)) { cmListFileContext const& lfc = fb->GetStartingContext(); - cmOStringStream e; + std::ostringstream e; e << "A logical block opening on the line\n" << " " << lfc << "\n" << "closes on the line\n" @@ -3465,14 +3508,14 @@ void cmMakefile::SetScriptModeFile(const char* scriptfile) void cmMakefile::SetArgcArgv(const std::vector<std::string>& args) { - cmOStringStream strStream; + std::ostringstream strStream; strStream << args.size(); this->AddDefinition("CMAKE_ARGC", strStream.str().c_str()); //this->MarkVariableAsUsed("CMAKE_ARGC"); for (unsigned int t = 0; t < args.size(); ++t) { - cmOStringStream tmpStream; + std::ostringstream tmpStream; tmpStream << "CMAKE_ARGV" << t; this->AddDefinition(tmpStream.str(), args[t].c_str()); //this->MarkVariableAsUsed(tmpStream.str().c_str()); @@ -3809,12 +3852,12 @@ std::string cmMakefile::GetModulesFile(const char* filename) const // from which we are being called is located itself in CMAKE_ROOT, then // prefer results from CMAKE_ROOT depending on the policy setting. result = moduleInCMakeModulePath; - if (result.size() == 0) + if (result.empty()) { result = moduleInCMakeRoot; } - if ((moduleInCMakeModulePath.size()>0) && (moduleInCMakeRoot.size()>0)) + if (!moduleInCMakeModulePath.empty() && !moduleInCMakeRoot.empty()) { const char* currentFile = this->GetDefinition("CMAKE_CURRENT_LIST_FILE"); std::string mods = cmakeRoot + std::string("/Modules/"); @@ -3824,7 +3867,7 @@ std::string cmMakefile::GetModulesFile(const char* filename) const { case cmPolicies::WARN: { - cmOStringStream e; + std::ostringstream e; e << "File " << currentFile << " includes " << moduleInCMakeModulePath << " (found via CMAKE_MODULE_PATH) which shadows " @@ -4004,7 +4047,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, if(bom != cmsys::FStream::BOM_None && bom != cmsys::FStream::BOM_UTF8) { - cmOStringStream e; + std::ostringstream e; e << "File starts with a Byte-Order-Mark that is not UTF-8:\n " << sinfile; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -4216,7 +4259,7 @@ const char *cmMakefile::GetProperty(const std::string& prop, } else if (prop == "LINK_DIRECTORIES") { - cmOStringStream str; + std::ostringstream str; for (std::vector<std::string>::const_iterator it = this->GetLinkDirectories().begin(); it != this->GetLinkDirectories().end(); @@ -4394,7 +4437,7 @@ void cmMakefile::AddCMakeDependFilesFromUser() std::string cmMakefile::GetListFileStack() const { - cmOStringStream tmp; + std::ostringstream tmp; size_t depth = this->ListFileStack.size(); if (depth > 0) { @@ -4426,10 +4469,24 @@ void cmMakefile::PushScope() this->Internal->VarStack.push(cmDefinitions(parent)); this->Internal->VarInitStack.push(init); this->Internal->VarUsageStack.push(usage); + + this->PushLoopBlockBarrier(); + +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetLocalGenerator()->GetGlobalGenerator()-> + GetFileLockPool().PushFunctionScope(); +#endif } void cmMakefile::PopScope() { +#if defined(CMAKE_BUILD_WITH_CMAKE) + this->GetLocalGenerator()->GetGlobalGenerator()-> + GetFileLockPool().PopFunctionScope(); +#endif + + this->PopLoopBlockBarrier(); + cmDefinitions* current = &this->Internal->VarStack.top(); std::set<std::string> init = this->Internal->VarInitStack.top(); std::set<std::string> usage = this->Internal->VarUsageStack.top(); @@ -4453,16 +4510,8 @@ void cmMakefile::PopScope() this->Internal->VarInitStack.pop(); this->Internal->VarUsageStack.pop(); // Push initialization and usage up to the parent scope. - it = init.begin(); - for (; it != init.end(); ++it) - { - this->Internal->VarInitStack.top().insert(*it); - } - it = usage.begin(); - for (; it != usage.end(); ++it) - { - this->Internal->VarUsageStack.top().insert(*it); - } + this->Internal->VarInitStack.top().insert(init.begin(), init.end()); + this->Internal->VarUsageStack.top().insert(usage.begin(), usage.end()); } void cmMakefile::RaiseScope(const std::string& var, const char *varDef) @@ -4498,7 +4547,7 @@ void cmMakefile::RaiseScope(const std::string& var, const char *varDef) } else { - cmOStringStream m; + std::ostringstream m; m << "Cannot set \"" << var << "\": current scope has no parent."; this->IssueMessage(cmake::AUTHOR_WARNING, m.str()); } @@ -4593,7 +4642,7 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg, { if(this->IsAlias(name)) { - cmOStringStream e; + std::ostringstream e; e << "cannot create target \"" << name << "\" because an alias with the same name already exists."; msg = e.str(); @@ -4607,7 +4656,7 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg, { // Imported targets were not supported in previous versions. // This is new code, so we can make it an error. - cmOStringStream e; + std::ostringstream e; e << "cannot create target \"" << name << "\" because an imported target with the same name already exists."; msg = e.str(); @@ -4646,7 +4695,7 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg, // Produce an error that tells the user how to work around the // problem. - cmOStringStream e; + std::ostringstream e; e << "cannot create target \"" << name << "\" because another target with the same name already exists. " << "The existing target is "; @@ -4692,7 +4741,7 @@ bool cmMakefile::EnforceUniqueDir(const std::string& srcPath, { return true; } - cmOStringStream e; + std::ostringstream e; switch (this->GetPolicyStatus(cmPolicies::CMP0013)) { case cmPolicies::WARN: @@ -4743,7 +4792,7 @@ std::vector<cmSourceFile*> cmMakefile::GetQtUiFilesWithOptions() const return this->QtUiFilesWithOptions; } -static std::string matchVariables[] = { +static std::string const matchVariables[] = { "CMAKE_MATCH_0", "CMAKE_MATCH_1", "CMAKE_MATCH_2", @@ -4756,10 +4805,18 @@ static std::string matchVariables[] = { "CMAKE_MATCH_9" }; +static std::string const nMatchesVariable = "CMAKE_MATCH_COUNT"; + //---------------------------------------------------------------------------- void cmMakefile::ClearMatches() { - for (unsigned int i=0; i<this->NumLastMatches; i++) + const char* nMatchesStr = this->GetDefinition(nMatchesVariable); + if (!nMatchesStr) + { + return; + } + int nMatches = atoi(nMatchesStr); + for (int i=0; i<=nMatches; i++) { std::string const& var = matchVariables[i]; std::string const& s = this->GetSafeDefinition(var); @@ -4769,13 +4826,15 @@ void cmMakefile::ClearMatches() this->MarkVariableAsUsed(var); } } - this->NumLastMatches = 0; + this->AddDefinition(nMatchesVariable, "0"); + this->MarkVariableAsUsed(nMatchesVariable); } //---------------------------------------------------------------------------- void cmMakefile::StoreMatches(cmsys::RegularExpression& re) { - for (unsigned int i=0; i<10; i++) + char highest = 0; + for (int i=0; i<10; i++) { std::string const& m = re.match(i); if(!m.empty()) @@ -4783,9 +4842,12 @@ void cmMakefile::StoreMatches(cmsys::RegularExpression& re) std::string const& var = matchVariables[i]; this->AddDefinition(var, m.c_str()); this->MarkVariableAsUsed(var); - this->NumLastMatches = i + 1; + highest = static_cast<char>('0' + i); } } + char nMatches[] = {highest, '\0'}; + this->AddDefinition(nMatchesVariable, nMatches); + this->MarkVariableAsUsed(nMatchesVariable); } //---------------------------------------------------------------------------- @@ -4864,7 +4926,7 @@ bool cmMakefile::SetPolicy(const char *id, cmPolicies::PolicyID pid; if (!this->GetPolicies()->GetPolicyID(id, /* out */ pid)) { - cmOStringStream e; + std::ostringstream e; e << "Policy \"" << id << "\" is not known to this version of CMake."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); return false; @@ -5079,7 +5141,7 @@ AddRequiredTargetFeature(cmTarget *target, const std::string& feature, availableFeatures.end(), feature) == availableFeatures.end()) { - cmOStringStream e; + std::ostringstream e; e << "The compiler feature \"" << feature << "\" is not known to " << lang << " compiler\n\"" << this->GetDefinition("CMAKE_" + lang + "_COMPILER_ID") @@ -5119,7 +5181,7 @@ CompileFeatureKnown(cmTarget const* target, const std::string& feature, lang = "CXX"; return true; } - cmOStringStream e; + std::ostringstream e; if (error) { e << "specified"; @@ -5150,7 +5212,7 @@ CompileFeaturesAvailable(const std::string& lang, std::string *error) const if (!featuresKnown || !*featuresKnown) { - cmOStringStream e; + std::ostringstream e; if (error) { e << "no"; @@ -5177,18 +5239,19 @@ CompileFeaturesAvailable(const std::string& lang, std::string *error) const } //---------------------------------------------------------------------------- -bool cmMakefile::HaveFeatureAvailable(cmTarget const* target, +bool cmMakefile::HaveStandardAvailable(cmTarget const* target, std::string const& lang, const std::string& feature) const { return lang == "C" - ? this->HaveCFeatureAvailable(target, feature) - : this->HaveCxxFeatureAvailable(target, feature); + ? this->HaveCStandardAvailable(target, feature) + : this->HaveCxxStandardAvailable(target, feature); } //---------------------------------------------------------------------------- bool cmMakefile:: -HaveCFeatureAvailable(cmTarget const* target, const std::string& feature) const +HaveCStandardAvailable(cmTarget const* target, + const std::string& feature) const { bool needC90 = false; bool needC99 = false; @@ -5205,7 +5268,7 @@ HaveCFeatureAvailable(cmTarget const* target, const std::string& feature) const if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) { - cmOStringStream e; + std::ostringstream e; e << "The C_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCStandard << "\"."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -5265,7 +5328,7 @@ bool cmMakefile::IsLaterStandard(std::string const& lang, } //---------------------------------------------------------------------------- -bool cmMakefile::HaveCxxFeatureAvailable(cmTarget const* target, +bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target, const std::string& feature) const { bool needCxx98 = false; @@ -5282,7 +5345,7 @@ bool cmMakefile::HaveCxxFeatureAvailable(cmTarget const* target, if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), cmStrCmp(existingCxxStandard)) == cmArrayEnd(CXX_STANDARDS)) { - cmOStringStream e; + std::ostringstream e; e << "The CXX_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCxxStandard << "\"."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -5357,7 +5420,7 @@ AddRequiredTargetCxxFeature(cmTarget *target, if (std::find_if(cmArrayBegin(CXX_STANDARDS), cmArrayEnd(CXX_STANDARDS), cmStrCmp(existingCxxStandard)) == cmArrayEnd(CXX_STANDARDS)) { - cmOStringStream e; + std::ostringstream e; e << "The CXX_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCxxStandard << "\"."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -5456,7 +5519,7 @@ AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const if (std::find_if(cmArrayBegin(C_STANDARDS), cmArrayEnd(C_STANDARDS), cmStrCmp(existingCStandard)) == cmArrayEnd(C_STANDARDS)) { - cmOStringStream e; + std::ostringstream e; e << "The C_STANDARD property on target \"" << target->GetName() << "\" contained an invalid value: \"" << existingCStandard << "\"."; this->IssueMessage(cmake::FATAL_ERROR, e.str()); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 824513b..bff8c12 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -34,6 +34,8 @@ # include <cmsys/hash_map.hxx> #endif +#include <stack> + class cmFunctionBlocker; class cmCommand; class cmInstallGenerator; @@ -123,6 +125,15 @@ public: }; friend class LexicalPushPop; + class LoopBlockPop + { + public: + LoopBlockPop(cmMakefile* mf) { this->Makefile = mf; } + ~LoopBlockPop() { this->Makefile->PopLoopBlock(); } + private: + cmMakefile* Makefile; + }; + /** * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. @@ -170,19 +181,23 @@ public: /** Add a custom command to the build. */ void AddCustomCommandToTarget(const std::string& target, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, const char* comment, const char* workingDir, - bool escapeOldStyle = true) const; + bool escapeOldStyle = true, + bool uses_terminal = false); cmSourceFile* AddCustomCommandToOutput( const std::vector<std::string>& outputs, + const std::vector<std::string>& byproducts, const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, - bool escapeOldStyle = true); + bool escapeOldStyle = true, + bool uses_terminal = false); cmSourceFile* AddCustomCommandToOutput( const std::string& output, const std::vector<std::string>& depends, @@ -190,7 +205,8 @@ public: const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, - bool escapeOldStyle = true); + bool escapeOldStyle = true, + bool uses_terminal = false); void AddCustomCommandOldStyle(const std::string& target, const std::vector<std::string>& outputs, const std::vector<std::string>& depends, @@ -237,7 +253,17 @@ public: const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, bool escapeOldStyle = true, - const char* comment = 0); + const char* comment = 0, + bool uses_terminal = false); + cmTarget* AddUtilityCommand(const std::string& utilityName, + bool excludeFromAll, + const char* workingDirectory, + const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, + bool escapeOldStyle = true, + const char* comment = 0, + bool uses_terminal = false); /** * Add a link library to the build. @@ -885,6 +911,10 @@ public: void PopScope(); void RaiseScope(const std::string& var, const char *value); + // push and pop loop scopes + void PushLoopBlockBarrier(); + void PopLoopBlockBarrier(); + /** Helper class to push and pop scopes automatically. */ class ScopePushPop { @@ -935,13 +965,17 @@ public: const char* CompileFeaturesAvailable(const std::string& lang, std::string *error) const; - bool HaveFeatureAvailable(cmTarget const* target, std::string const& lang, + bool HaveStandardAvailable(cmTarget const* target, std::string const& lang, const std::string& feature) const; bool IsLaterStandard(std::string const& lang, std::string const& lhs, std::string const& rhs); + void PushLoopBlock(); + void PopLoopBlock(); + bool IsLoopBlock() const; + void ClearMatches(); void StoreMatches(cmsys::RegularExpression& re); @@ -1039,6 +1073,8 @@ private: void PushFunctionBlockerBarrier(); void PopFunctionBlockerBarrier(bool reportError = true); + std::stack<int> LoopBlockCounter; + typedef std::map<std::string, std::string> StringStringMap; StringStringMap MacrosMap; @@ -1150,8 +1186,6 @@ private: std::vector<cmSourceFile*> QtUiFilesWithOptions; - unsigned int NumLastMatches; - bool AddRequiredTargetCFeature(cmTarget *target, const std::string& feature) const; @@ -1163,9 +1197,9 @@ private: void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98, bool& needCxx11, bool& needCxx14) const; - bool HaveCFeatureAvailable(cmTarget const* target, + bool HaveCStandardAvailable(cmTarget const* target, const std::string& feature) const; - bool HaveCxxFeatureAvailable(cmTarget const* target, + bool HaveCxxStandardAvailable(cmTarget const* target, const std::string& feature) const; mutable bool SuppressWatches; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index fc52ccc..d4036d2 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -371,8 +371,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) std::string targetVersionMajor; std::string targetVersionMinor; { - cmOStringStream majorStream; - cmOStringStream minorStream; + std::ostringstream majorStream; + std::ostringstream minorStream; int major; int minor; this->Target->GetTargetVersion(major, minor); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 80473f6..cdda36c 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -566,8 +566,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules std::string targetVersionMajor; std::string targetVersionMinor; { - cmOStringStream majorStream; - cmOStringStream minorStream; + std::ostringstream majorStream; + std::ostringstream minorStream; int major; int minor; this->Target->GetTargetVersion(major, minor); @@ -752,26 +752,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules this->Target); } - // Write the build rule. - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - targetFullPathReal, - depends, commands, false); - - // Some targets have more than one output file. Create rules to - // drive the build if any extra outputs are missing. - std::vector<std::string> extraOutputs; + // Compute the list of outputs. + std::vector<std::string> outputs(1, targetFullPathReal); if(targetNameSO != targetNameReal) { - this->GenerateExtraOutput(targetFullPathSO.c_str(), - targetFullPathReal.c_str()); + outputs.push_back(targetFullPathSO); } if(targetName != targetNameSO && targetName != targetNameReal) { - this->GenerateExtraOutput(targetFullPath.c_str(), - targetFullPathReal.c_str()); + outputs.push_back(targetFullPath); } + // Write the build rule. + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, + outputs, depends, commands, false); + + // Write the main driver rule to build everything in this target. this->WriteTargetDriverRule(targetFullPath, relink); @@ -808,7 +805,7 @@ cmMakefileLibraryTargetGenerator if(major > 0 || minor > 0 || patch > 0) { // Append the flag since a non-zero version is specified. - cmOStringStream vflag; + std::ostringstream vflag; vflag << flag << major << "." << minor << "." << patch; this->LocalGenerator->AppendFlags(flags, vflag.str()); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 1adcb8a..f8471fd 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -451,7 +451,7 @@ void cmMakefileTargetGenerator } else { - cmOStringStream err; + std::ostringstream err; err << "Warning: Source file \"" << source.GetFullPath() << "\" is listed multiple times for target \"" @@ -702,7 +702,14 @@ cmMakefileTargetGenerator vars.Defines = definesString.c_str(); - bool lang_is_c_or_cxx = ((lang == "C") || (lang == "CXX")); + // At the moment, it is assumed that C, C++, and Fortran have both + // assembly and preprocessor capabilities. The same is true for the + // ability to export compile commands + bool lang_has_preprocessor = ((lang == "C") || + (lang == "CXX") || + (lang == "Fortran")); + bool const lang_has_assembly = lang_has_preprocessor; + bool const lang_can_export_cmds = lang_has_preprocessor; // Construct the compile rules. { @@ -715,7 +722,7 @@ cmMakefileTargetGenerator cmSystemTools::ExpandListArgument(compileRule, compileCommands); if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") && - lang_is_c_or_cxx && compileCommands.size() == 1) + lang_can_export_cmds && compileCommands.size() == 1) { std::string compileCommand = compileCommands[0]; this->LocalGenerator->ExpandRuleVariables(compileCommand, vars); @@ -747,33 +754,24 @@ cmMakefileTargetGenerator compileCommands.begin(), compileCommands.end()); } - // Write the rule. - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - relativeObj, - depends, commands, false); - // Check for extra outputs created by the compilation. + std::vector<std::string> outputs(1, relativeObj); if(const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) { - std::vector<std::string> extra_outputs; - cmSystemTools::ExpandListArgument(extra_outputs_str, extra_outputs); - for(std::vector<std::string>::const_iterator eoi = extra_outputs.begin(); - eoi != extra_outputs.end(); ++eoi) - { - // Register this as an extra output for the object file rule. - // This will cause the object file to be rebuilt if the extra - // output is missing. - this->GenerateExtraOutput(eoi->c_str(), relativeObj.c_str(), false); - - // Register this as an extra file to clean. - this->CleanFiles.push_back(*eoi); - } + // Register these as extra files to clean. + cmSystemTools::ExpandListArgument(extra_outputs_str, outputs); + this->CleanFiles.insert(this->CleanFiles.end(), + outputs.begin() + 1, outputs.end()); } - bool do_preprocess_rules = lang_is_c_or_cxx && + // Write the rule. + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, + outputs, depends, commands, false); + + bool do_preprocess_rules = lang_has_preprocessor && this->LocalGenerator->GetCreatePreprocessedSourceRules(); - bool do_assembly_rules = lang_is_c_or_cxx && + bool do_assembly_rules = lang_has_assembly && this->LocalGenerator->GetCreateAssemblySourceRules(); if(do_preprocess_rules || do_assembly_rules) { @@ -1010,25 +1008,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() this->LocalGenerator-> WriteDependLanguageInfo(*this->InfoFileStream,*this->Target); - // Store multiple output pairs in the depend info file. - if(!this->MultipleOutputPairs.empty()) - { - *this->InfoFileStream - << "\n" - << "# Pairs of files generated by the same build rule.\n" - << "set(CMAKE_MULTIPLE_OUTPUT_PAIRS\n"; - for(MultipleOutputPairsType::const_iterator pi = - this->MultipleOutputPairs.begin(); - pi != this->MultipleOutputPairs.end(); ++pi) - { - *this->InfoFileStream - << " " << this->LocalGenerator->EscapeForCMake(pi->first) - << " " << this->LocalGenerator->EscapeForCMake(pi->second) - << "\n"; - } - *this->InfoFileStream << " )\n\n"; - } - // Store list of targets linked directly or transitively. { *this->InfoFileStream @@ -1119,7 +1098,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() // Add a command to call CMake to scan dependencies. CMake will // touch the corresponding depends file after scanning dependencies. - cmOStringStream depCmd; + std::ostringstream depCmd; // TODO: Account for source file properties and directory-level // definitions when scanning for dependencies. #if !defined(_WIN32) || defined(__CYGWIN__) @@ -1192,11 +1171,7 @@ cmMakefileTargetGenerator { cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->Makefile); const std::vector<std::string>& outputs = ccg.GetOutputs(); - for(std::vector<std::string>::const_iterator o = outputs.begin(); - o != outputs.end(); ++o) - { - depends.push_back(*o); - } + depends.insert(depends.end(), outputs.begin(), outputs.end()); } } } @@ -1211,13 +1186,7 @@ void cmMakefileTargetGenerator depends.push_back(source.GetFullPath()); if(const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) { - std::vector<std::string> deps; - cmSystemTools::ExpandListArgument(objectDeps, deps); - for(std::vector<std::string>::iterator i = deps.begin(); - i != deps.end(); ++i) - { - depends.push_back(*i); - } + cmSystemTools::ExpandListArgument(objectDeps, depends); } } @@ -1241,7 +1210,7 @@ void cmMakefileTargetGenerator } // Now append the actual user-specified commands. - cmOStringStream content; + std::ostringstream content; this->LocalGenerator->AppendCustomCommand(commands, ccg, this->Target, false, cmLocalGenerator::HOME_OUTPUT, &content); @@ -1266,7 +1235,7 @@ void cmMakefileTargetGenerator } } this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - *o, depends, commands, + outputs, depends, commands, symbolic); // If the rule has changed make sure the output is rebuilt. @@ -1276,21 +1245,6 @@ void cmMakefileTargetGenerator } } - // Write rules to drive building any outputs beyond the first. - const char* in = o->c_str(); - for(++o; o != outputs.end(); ++o) - { - bool symbolic = false; - if(need_symbolic) - { - if(cmSourceFile* sf = this->Makefile->GetSource(*o)) - { - symbolic = sf->GetPropertyAsBool("SYMBOLIC"); - } - } - this->GenerateExtraOutput(o->c_str(), in, symbolic); - } - // Setup implicit dependency scanning. for(cmCustomCommand::ImplicitDependsList::const_iterator idi = ccg.GetCC().GetImplicitDepends().begin(); @@ -1309,32 +1263,6 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void -cmMakefileTargetGenerator -::GenerateExtraOutput(const char* out, const char* in, bool symbolic) -{ - // Add a rule to build the primary output if the extra output needs - // to be created. - std::vector<std::string> commands; - std::vector<std::string> depends; - std::string emptyCommand = this->GlobalGenerator->GetEmptyRuleHackCommand(); - if(!emptyCommand.empty()) - { - commands.push_back(emptyCommand); - } - depends.push_back(in); - this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0, - out, depends, commands, - symbolic); - - // Register the extra output as paired with the first output so that - // the check-build-system step will remove the primary output if any - // extra outputs are missing. This forces the rule to regenerate - // all outputs. - this->AddMultipleOutputPair(out, in); -} - -//---------------------------------------------------------------------------- -void cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands) { this->NumberOfProgressActions++; @@ -1344,7 +1272,7 @@ cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands) } std::string progressDir = this->Makefile->GetHomeOutputDirectory(); progressDir += cmake::GetCMakeFilesDirectory(); - cmOStringStream progCmd; + std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; progCmd << this->LocalGenerator->Convert(progressDir, cmLocalGenerator::FULL, @@ -1527,11 +1455,8 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( } // Make sure the extra files are built. - for(std::set<std::string>::const_iterator i = this->ExtraFiles.begin(); - i != this->ExtraFiles.end(); ++i) - { - depends.push_back(*i); - } + depends.insert(depends.end(), + this->ExtraFiles.begin(), this->ExtraFiles.end()); } // Write the driver rule. @@ -1618,11 +1543,7 @@ void cmMakefileTargetGenerator if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { std::vector<std::string> const& libDeps = cli->GetDepends(); - for(std::vector<std::string>::const_iterator j = libDeps.begin(); - j != libDeps.end(); ++j) - { - depends.push_back(*j); - } + depends.insert(depends.end(), libDeps.begin(), libDeps.end()); } } @@ -1642,12 +1563,8 @@ void cmMakefileTargetGenerator } // Add dependencies on the external object files. - for(std::vector<std::string>::const_iterator obj - = this->ExternalObjects.begin(); - obj != this->ExternalObjects.end(); ++obj) - { - depends.push_back(*obj); - } + depends.insert(depends.end(), + this->ExternalObjects.begin(), this->ExternalObjects.end()); // Add a dependency on the rule file itself. this->LocalGenerator->AppendRuleDepend(depends, @@ -1763,15 +1680,6 @@ void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar, //---------------------------------------------------------------------------- void cmMakefileTargetGenerator -::AddMultipleOutputPair(const char* depender, const char* dependee) -{ - MultipleOutputPairsType::value_type p(depender, dependee); - this->MultipleOutputPairs.insert(p); -} - -//---------------------------------------------------------------------------- -void -cmMakefileTargetGenerator ::CreateLinkScript(const char* name, std::vector<std::string> const& link_commands, std::vector<std::string>& makefile_commands, @@ -1846,7 +1754,7 @@ cmMakefileTargetGenerator useWatcomQuote); linkLibs = frameworkPath + linkPath + linkLibs; - if(useResponseFile) + if(useResponseFile && linkLibs.find_first_not_of(" ") != linkLibs.npos) { // Lookup the response file reference flag. std::string responseFlagVar = "CMAKE_"; diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 9fac574..e31e086 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -142,15 +142,6 @@ protected: // Lookup the link rule for this target. std::string GetLinkRule(const std::string& linkRuleVar); - /** In order to support parallel builds for custom commands with - multiple outputs the outputs are given a serial order, and only - the first output actually has the build rule. Other outputs - just depend on the first one. The check-build-system step must - remove a dependee if the depender is missing to make sure both - are regenerated properly. This method is used by the local - makefile generators to register such pairs. */ - void AddMultipleOutputPair(const char* depender, const char* dependee); - /** Create a script to hold link rules and a command to invoke the script at build time. */ void CreateLinkScript(const char* name, @@ -231,9 +222,6 @@ protected: // Set of extra output files to be driven by the build. std::set<std::string> ExtraFiles; - typedef std::map<std::string, std::string> MultipleOutputPairsType; - MultipleOutputPairsType MultipleOutputPairs; - // Target name info. std::string TargetNameOut; std::string TargetNameSO; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 0cc3e3b..32a5ccf 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -110,13 +110,26 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules() << "\n\n"; #endif + // Write rules for languages compiled in this target. std::set<std::string> languages; - this->GetTarget()->GetLanguages(languages, - this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE")); + std::vector<cmSourceFile*> sourceFiles; + this->GetTarget()->GetSourceFiles(sourceFiles, + this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE")); + for(std::vector<cmSourceFile*>::const_iterator + i = sourceFiles.begin(); i != sourceFiles.end(); ++i) + { + const std::string& lang = (*i)->GetLanguage(); + if(!lang.empty()) + { + languages.insert(lang); + } + } for(std::set<std::string>::const_iterator l = languages.begin(); l != languages.end(); ++l) + { this->WriteLanguageRules(*l); + } } const char *cmNinjaNormalTargetGenerator::GetVisibleTypeName() const @@ -194,12 +207,7 @@ cmNinjaNormalTargetGenerator vars.ObjectDir = "$OBJECT_DIR"; - // TODO: - // Makefile generator expands <TARGET> to the plain target name - // with suffix. $out expands to a relative path. This difference - // could make trouble when switching to Ninja generator. Maybe - // using TARGET_NAME and RuleVariables::TargetName is a fix. - vars.Target = "$out"; + vars.Target = "$TARGET_FILE"; vars.SONameFlag = "$SONAME_FLAG"; vars.TargetSOName = "$SONAME"; @@ -210,8 +218,8 @@ cmNinjaNormalTargetGenerator std::string targetVersionMajor; std::string targetVersionMinor; { - cmOStringStream majorStream; - cmOStringStream minorStream; + std::ostringstream majorStream; + std::ostringstream minorStream; int major; int minor; this->GetTarget()->GetTargetVersion(major, minor); @@ -247,12 +255,12 @@ cmNinjaNormalTargetGenerator this->GetLocalGenerator()->BuildCommandLine(linkCmds); // Write the linker rule with response file if needed. - cmOStringStream comment; + std::ostringstream comment; comment << "Rule for linking " << this->TargetLinkLanguage << " " << this->GetVisibleTypeName() << "."; - cmOStringStream description; + std::ostringstream description; description << "Linking " << this->TargetLinkLanguage << " " - << this->GetVisibleTypeName() << " $out"; + << this->GetVisibleTypeName() << " $TARGET_FILE"; this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(), @@ -261,7 +269,7 @@ cmNinjaNormalTargetGenerator /*deptype*/ "", rspfile, rspcontent, - /*restat*/ false, + /*restat*/ "$RESTAT", /*generator*/ false); } @@ -283,7 +291,7 @@ cmNinjaNormalTargetGenerator /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ false, + /*restat*/ "", /*generator*/ false); else this->GetGlobalGenerator()->AddRule("CMAKE_SYMLINK_LIBRARY", @@ -297,7 +305,7 @@ cmNinjaNormalTargetGenerator /*deptype*/ "", /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ false, + /*restat*/ "", /*generator*/ false); } } @@ -326,7 +334,7 @@ cmNinjaNormalTargetGenerator this->GetLocalGenerator()->ConvertToOutputFormat( mf->GetRequiredDefinition("CMAKE_COMMAND"), cmLocalGenerator::SHELL); - linkCmds.push_back(cmakeCommand + " -E remove $out"); + linkCmds.push_back(cmakeCommand + " -E remove $TARGET_FILE"); } // TODO: Use ARCHIVE_APPEND for archives over a certain size. { @@ -427,7 +435,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaVars vars; // Compute the comment. - cmOStringStream comment; + std::ostringstream comment; comment << "Link the " << this->GetVisibleTypeName() << " " << targetOutputReal; @@ -450,6 +458,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetConfigName()); bool useWatcomQuote = mf->IsOn(createRule+"_USE_WATCOM_QUOTE"); cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator(); + + vars["TARGET_FILE"] = + localGen.ConvertToOutputFormat(targetOutputReal, cmLocalGenerator::SHELL); + localGen.GetTargetFlags(vars["LINK_LIBRARIES"], vars["FLAGS"], vars["LINK_FLAGS"], @@ -509,6 +521,10 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmLocalGenerator::SHELL); vars["TARGET_IMPLIB"] = impLibPath; EnsureParentDirectoryExists(impLibPath); + if(target.HasImportLibrary()) + { + outputs.push_back(targetOutputImplib); + } } if (!this->SetMsvcTargetPdbVariable(vars)) @@ -553,6 +569,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() &postBuildCmdLines }; + cmNinjaDeps byproducts; for (unsigned i = 0; i != 3; ++i) { for (std::vector<cmCustomCommand>::const_iterator @@ -561,6 +578,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() { cmCustomCommandGenerator ccg(*ci, cfgName, mf); localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]); + std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); + std::transform(ccByproducts.begin(), ccByproducts.end(), + std::back_inserter(byproducts), MapToNinjaPath()); } } @@ -608,6 +628,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetLocalGenerator()->AppendTargetDepends(this->GetTarget(), orderOnlyDeps); + // Ninja should restat after linking if and only if there are byproducts. + vars["RESTAT"] = byproducts.empty()? "" : "1"; + + for (cmNinjaDeps::const_iterator oi = byproducts.begin(), + oe = byproducts.end(); + oi != oe; ++oi) + { + this->GetGlobalGenerator()->SeenCustomCommandOutput(*oi); + outputs.push_back(*oi); + } + // Write the build statement for this target. globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(), @@ -659,16 +690,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } } - if (!this->TargetNameImport.empty()) - { - // Since using multiple outputs would mess up the $out variable, use an - // alias for the import library. - globalGen.WritePhonyBuild(this->GetBuildFileStream(), - "Alias for import library.", - cmNinjaDeps(1, targetOutputImplib), - cmNinjaDeps(1, targetOutputReal)); - } - // Add aliases for the file name and the target name. globalGen.AddTargetAlias(this->TargetNameOut, &target); globalGen.AddTargetAlias(this->GetTargetName(), &target); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 80213d8..c019ceb 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -454,7 +454,10 @@ cmNinjaTargetGenerator std::vector<std::string> compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); - compileCmds.front().insert(0, cldeps); + if (!compileCmds.empty()) + { + compileCmds.front().insert(0, cldeps); + } for (std::vector<std::string>::iterator i = compileCmds.begin(); i != compileCmds.end(); ++i) @@ -465,9 +468,9 @@ cmNinjaTargetGenerator // Write the rule for compiling file of the given language. - cmOStringStream comment; + std::ostringstream comment; comment << "Rule for compiling " << lang << " files."; - cmOStringStream description; + std::ostringstream description; description << "Building " << lang << " object $out"; this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang), cmdLine, @@ -477,7 +480,7 @@ cmNinjaTargetGenerator deptype, /*rspfile*/ "", /*rspcontent*/ "", - /*restat*/ false, + /*restat*/ "", /*generator*/ false); } @@ -538,8 +541,11 @@ cmNinjaTargetGenerator cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->GetMakefile()); const std::vector<std::string>& ccoutputs = ccg.GetOutputs(); + const std::vector<std::string>& ccbyproducts= ccg.GetByproducts(); std::transform(ccoutputs.begin(), ccoutputs.end(), std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::transform(ccbyproducts.begin(), ccbyproducts.end(), + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); } if (!orderOnlyDeps.empty()) diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 40a15a3..17cf517 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -116,7 +116,6 @@ protected: void WriteObjectBuildStatements(); void WriteObjectBuildStatement(cmSourceFile const* source, bool writeOrderDependsTargetForTarget); - void WriteCustomCommandBuildStatement(cmCustomCommand *cc); cmNinjaDeps GetObjects() const { return this->Objects; } diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index f5d18dc..42d6b46 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -27,14 +27,19 @@ cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() {} void cmNinjaUtilityTargetGenerator::Generate() { + std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash(); + utilCommandName += this->GetTargetName() + ".util"; + std::vector<std::string> commands; - cmNinjaDeps deps, outputs; + cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName); const std::vector<cmCustomCommand> *cmdLists[2] = { &this->GetTarget()->GetPreBuildCommands(), &this->GetTarget()->GetPostBuildCommands() }; + bool uses_terminal = false; + for (unsigned i = 0; i != 2; ++i) { for (std::vector<cmCustomCommand>::const_iterator ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) { @@ -42,6 +47,11 @@ void cmNinjaUtilityTargetGenerator::Generate() this->GetMakefile()); this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps); this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands); + std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); + std::transform(ccByproducts.begin(), ccByproducts.end(), + std::back_inserter(util_outputs), MapToNinjaPath()); + if (ci->GetUsesTerminal()) + uses_terminal = true; } } @@ -60,8 +70,11 @@ void cmNinjaUtilityTargetGenerator::Generate() // Depend on all custom command outputs. const std::vector<std::string>& ccOutputs = ccg.GetOutputs(); + const std::vector<std::string>& ccByproducts = ccg.GetByproducts(); std::transform(ccOutputs.begin(), ccOutputs.end(), std::back_inserter(deps), MapToNinjaPath()); + std::transform(ccByproducts.begin(), ccByproducts.end(), + std::back_inserter(deps), MapToNinjaPath()); } } @@ -103,14 +116,19 @@ void cmNinjaUtilityTargetGenerator::Generate() if (command.find('$') != std::string::npos) return; - std::string utilCommandName = cmake::GetCMakeFilesDirectoryPostSlash(); - utilCommandName += this->GetTargetName() + ".util"; + for (cmNinjaDeps::const_iterator + oi = util_outputs.begin(), oe = util_outputs.end(); + oi != oe; ++oi) + { + this->GetGlobalGenerator()->SeenCustomCommandOutput(*oi); + } this->GetGlobalGenerator()->WriteCustomCommandBuild( command, desc, "Utility command for " + this->GetTargetName(), - cmNinjaDeps(1, utilCommandName), + uses_terminal, + util_outputs, deps); this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 9a086ca..55e20ab 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -113,7 +113,7 @@ void cmOSXBundleGenerator::CreateFramework( newName = versions; newName += "/Current"; cmSystemTools::RemoveFile(newName); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); // foo -> Versions/Current/foo @@ -122,7 +122,7 @@ void cmOSXBundleGenerator::CreateFramework( newName = contentdir; newName += name; cmSystemTools::RemoveFile(newName); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); // Resources -> Versions/Current/Resources @@ -133,7 +133,7 @@ void cmOSXBundleGenerator::CreateFramework( newName = contentdir; newName += "Resources"; cmSystemTools::RemoveFile(newName); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); } @@ -145,7 +145,7 @@ void cmOSXBundleGenerator::CreateFramework( newName = contentdir; newName += "Headers"; cmSystemTools::RemoveFile(newName); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); } @@ -157,7 +157,7 @@ void cmOSXBundleGenerator::CreateFramework( newName = contentdir; newName += "PrivateHeaders"; cmSystemTools::RemoveFile(newName); - cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + cmSystemTools::CreateSymlink(oldName, newName); this->Makefile->AddCMakeOutputFile(newName); } } diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 3cdd2f6..23f8526 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -86,7 +86,7 @@ public: } } - void FindImplicitConflicts(cmOStringStream& w) + void FindImplicitConflicts(std::ostringstream& w) { bool first = true; for(unsigned int i=0; i < this->OD->OriginalDirectories.size(); ++i) @@ -291,18 +291,8 @@ cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg, //---------------------------------------------------------------------------- cmOrderDirectories::~cmOrderDirectories() { - for(std::vector<cmOrderDirectoriesConstraint*>::iterator - i = this->ConstraintEntries.begin(); - i != this->ConstraintEntries.end(); ++i) - { - delete *i; - } - for(std::vector<cmOrderDirectoriesConstraint*>::iterator - i = this->ImplicitDirEntries.begin(); - i != this->ImplicitDirEntries.end(); ++i) - { - delete *i; - } + cmDeleteAll(this->ConstraintEntries); + cmDeleteAll(this->ImplicitDirEntries); } //---------------------------------------------------------------------------- @@ -541,7 +531,7 @@ void cmOrderDirectories::FindImplicitConflicts() { // Check for items in implicit link directories that have conflicts // in the explicit directories. - cmOStringStream conflicts; + std::ostringstream conflicts; for(unsigned int i=0; i < this->ImplicitDirEntries.size(); ++i) { this->ImplicitDirEntries[i]->FindImplicitConflicts(conflicts); @@ -555,7 +545,7 @@ void cmOrderDirectories::FindImplicitConflicts() } // Warn about the conflicts. - cmOStringStream w; + std::ostringstream w; w << "Cannot generate a safe " << this->Purpose << " for target " << this->Target->GetName() << " because files in some directories may conflict with " @@ -624,7 +614,7 @@ void cmOrderDirectories::DiagnoseCycle() this->CycleDiagnosed = true; // Construct the message. - cmOStringStream e; + std::ostringstream e; e << "Cannot generate a safe " << this->Purpose << " for target " << this->Target->GetName() << " because there is a cycle in the constraint graph:\n"; diff --git a/Source/cmPathLabel.cxx b/Source/cmPathLabel.cxx new file mode 100644 index 0000000..67d56e1 --- /dev/null +++ b/Source/cmPathLabel.cxx @@ -0,0 +1,41 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmPathLabel.h" + +//---------------------------------------------------------------------------- +cmPathLabel::cmPathLabel(const std::string& label) +: Label(label), Hash(0) +{ + // Use a Jenkins one-at-a-time hash with under/over-flow protection + for(size_t i = 0; i < this->Label.size(); ++i) + { + this->Hash += this->Label[i]; + this->Hash += ((this->Hash & 0x003FFFFF) << 10); + this->Hash ^= ((this->Hash & 0xFFFFFFC0) >> 6); + } + this->Hash += ((this->Hash & 0x1FFFFFFF) << 3); + this->Hash ^= ((this->Hash & 0xFFFFF800) >> 11); + this->Hash += ((this->Hash & 0x0001FFFF) << 15); +} + +//---------------------------------------------------------------------------- +bool cmPathLabel::operator < (const cmPathLabel& l) const +{ + return this->Hash < l.Hash; +} + +//---------------------------------------------------------------------------- +bool cmPathLabel::operator == (const cmPathLabel& l) const +{ + return this->Hash == l.Hash; +} diff --git a/Source/cmPathLabel.h b/Source/cmPathLabel.h new file mode 100644 index 0000000..02d5261 --- /dev/null +++ b/Source/cmPathLabel.h @@ -0,0 +1,44 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmPathLabel_h +#define cmPathLabel_h + +#include "cmStandardIncludes.h" + +/** \class cmPathLabel + * \brief Helper class for text based labels + * + * cmPathLabel is extended in different classes to act as an inheritable + * enum. Comparisons are done on a precomputed Jenkins hash of the string + * label for indexing and searchig. + */ +class cmPathLabel +{ +public: + cmPathLabel(const std::string& label); + + // The comparison operators are only for quick sorting and searching and + // in no way imply any lexicographical order of the label + bool operator < (const cmPathLabel& l) const; + bool operator == (const cmPathLabel& l) const; + + const std::string& GetLabel() const { return this->Label; } + const unsigned int& GetHash() const { return this->Hash; } + +protected: + cmPathLabel(); + + std::string Label; + unsigned int Hash; +}; + +#endif diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index a420f59..3a48101 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -41,7 +41,7 @@ public: std::string GetVersionString() { - cmOStringStream v; + std::ostringstream v; v << this->MajorVersionIntroduced << "." << this->MinorVersionIntroduced; if(this->PatchVersionIntroduced > 0) { @@ -364,17 +364,21 @@ cmPolicies::cmPolicies() CMP0054, "CMP0054", "Only interpret if() arguments as variables or keywords when unquoted.", 3,1,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0055, "CMP0055", + "Strict checking for break() command.", + 3,2,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0056, "CMP0056", + "Honor link flags in try_compile() source-file signature.", + 3,2,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() { - // free the policies - std::map<cmPolicies::PolicyID,cmPolicy *>::iterator i - = this->Policies.begin(); - for (;i != this->Policies.end(); ++i) - { - delete i->second; - } + cmDeleteAll(this->Policies); } void cmPolicies::DefinePolicy(cmPolicies::PolicyID iD, @@ -422,7 +426,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, if(sscanf(ver.c_str(), "%u.%u.%u.%u", &majorVer, &minorVer, &patchVer, &tweakVer) < 2) { - cmOStringStream e; + std::ostringstream e; e << "Invalid policy version value \"" << ver << "\". " << "A numeric major.minor[.patch[.tweak]] must be given."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -452,7 +456,7 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, patchVer == cmVersion::GetPatchVersion() && tweakVer > cmVersion::GetTweakVersion())) { - cmOStringStream e; + std::ostringstream e; e << "An attempt was made to set the policy version of CMake to \"" << version << "\" which is greater than this version of CMake. " << "This is not allowed because the greater version may have new " @@ -524,7 +528,7 @@ bool cmPolicies::GetPolicyDefault(cmMakefile* mf, std::string const& policy, } else { - cmOStringStream e; + std::ostringstream e; e << defaultVar << " has value \"" << defaultValue << "\" but must be \"OLD\", \"NEW\", or \"\" (empty)."; mf->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -574,7 +578,7 @@ std::string cmPolicies::GetPolicyWarning(cmPolicies::PolicyID id) return "Request for warning text for undefined policy!"; } - cmOStringStream msg; + std::ostringstream msg; msg << "Policy " << pos->second->IDString << " is not set: " "" << pos->second->ShortDescription << " " @@ -598,7 +602,7 @@ std::string cmPolicies::GetRequiredPolicyError(cmPolicies::PolicyID id) return "Request for error text for undefined policy!"; } - cmOStringStream error; + std::ostringstream error; error << "Policy " << pos->second->IDString << " is not set to NEW: " "" << pos->second->ShortDescription << " " @@ -635,7 +639,7 @@ std::string cmPolicies::GetRequiredAlwaysPolicyError(cmPolicies::PolicyID id) { std::string pid = this->GetPolicyIDString(id); - cmOStringStream e; + std::ostringstream e; e << "Policy " << pid << " may not be set to OLD behavior because this " << "version of CMake no longer supports it. " << "The policy was introduced in " @@ -657,7 +661,7 @@ cmPolicies::DiagnoseAncientPolicies(std::vector<PolicyID> const& ancient, unsigned int patchVer, cmMakefile* mf) { - cmOStringStream e; + std::ostringstream e; e << "The project requests behavior compatible with CMake version \"" << majorVer << "." << minorVer << "." << patchVer << "\", which requires the OLD behavior for some policies:\n"; diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 7c73da8..c393c2f 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -111,6 +111,8 @@ public: CMP0053, ///< Simplify variable reference and escape sequence evaluation CMP0054, ///< Only interpret if() arguments as variables /// or keywords when unquoted. + CMP0055, ///< Strict checking for break() command. + CMP0056, ///< Honor link flags in try_compile() source-file signature. /** \brief Always the last entry. * diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index 12318c8..61c0133 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -215,7 +215,7 @@ bool cmProjectCommand } if(!vw.empty()) { - cmOStringStream w; + std::ostringstream w; w << (this->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0048)) << "\nThe following variable(s) would be set to empty:" << vw; diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 929cbc0..bf79066 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -178,7 +178,7 @@ std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf, command.push_back("--list"); std::string absFile = cmsys::SystemTools::GetRealPath( - sf->GetFullPath().c_str()); + sf->GetFullPath()); command.push_back(absFile); @@ -224,16 +224,7 @@ std::string cmQtAutoGenerators::ListQt5RccInputs(cmSourceFile* sf, } } depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end()); - std::string entriesList; - const char* sep = ""; - for(std::vector<std::string>::const_iterator it = qrcEntries.begin(); - it != qrcEntries.end(); ++it) - { - entriesList += sep; - entriesList += *it; - sep = "@list_sep@"; - } - return entriesList; + return cmJoin(qrcEntries, "@list_sep@"); } std::string cmQtAutoGenerators::ListQt4RccInputs(cmSourceFile* sf, @@ -394,7 +385,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) { cmSourceFile* sf = *fileIt; std::string absFile = cmsys::SystemTools::GetRealPath( - sf->GetFullPath().c_str()); + sf->GetFullPath()); std::string ext = sf->GetExtension(); @@ -438,7 +429,8 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) // rejection in cmMakefile::AddCustomCommandToTarget because we know // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. std::vector<std::string> no_output; - cmCustomCommand cc(makefile, no_output, depends, + std::vector<std::string> no_byproducts; + cmCustomCommand cc(makefile, no_output, no_byproducts, depends, commandLines, autogenComment.c_str(), workingDirectory.c_str()); cc.SetEscapeOldStyle(false); @@ -451,7 +443,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) cmTarget* autogenTarget = 0; if (!rcc_output.empty()) { - makefile->AddCustomCommandToOutput(rcc_output, depends, "", + std::vector<std::string> no_byproducts; + makefile->AddCustomCommandToOutput(rcc_output, no_byproducts, + depends, "", commandLines, 0, workingDirectory.c_str(), false, false); @@ -509,29 +503,13 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target, // Get the include dirs for this target, without stripping the implicit // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 localGen->GetIncludeDirectories(includeDirs, gtgt, "CXX", config, false); - const char* sep = ""; - incs = ""; - for(std::vector<std::string>::const_iterator incDirIt = includeDirs.begin(); - incDirIt != includeDirs.end(); - ++incDirIt) - { - incs += sep; - sep = ";"; - incs += *incDirIt; - } + + incs = cmJoin(includeDirs, ";"); std::set<std::string> defines; localGen->AddCompileDefinitions(defines, target, config); - sep = ""; - for(std::set<std::string>::const_iterator defIt = defines.begin(); - defIt != defines.end(); - ++defIt) - { - defs += sep; - sep = ";"; - defs += *defIt; - } + defs += cmJoin(defines, ";"); } void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) @@ -876,16 +854,7 @@ static void GetUicOpts(cmTarget const* target, const std::string& config, { std::vector<std::string> opts; target->GetAutoUicOptions(opts, config); - - const char* sep = ""; - for(std::vector<std::string>::const_iterator optIt = opts.begin(); - optIt != opts.end(); - ++optIt) - { - optString += sep; - sep = ";"; - optString += *optIt; - } + optString = cmJoin(opts, ";"); } void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, @@ -896,12 +865,7 @@ void cmQtAutoGenerators::SetupAutoUicTarget(cmTarget const* target, std::set<std::string> skipped; std::vector<std::string> skipVec; cmSystemTools::ExpandListArgument(this->SkipUic, skipVec); - - for (std::vector<std::string>::const_iterator li = skipVec.begin(); - li != skipVec.end(); ++li) - { - skipped.insert(*li); - } + skipped.insert(skipVec.begin(), skipVec.end()); makefile->AddDefinition("_skip_uic", cmLocalGenerator::EscapeForCMake(this->SkipUic).c_str()); @@ -1479,7 +1443,7 @@ void cmQtAutoGenerators::Init() { const std::string &path = *it; this->MocIncludes.push_back("-I" + path); - if (this->EndsWith(path, ".framework/Headers")) + if (cmHasLiteralSuffix(path, ".framework/Headers")) { // Go up twice to get to the framework root std::vector<std::string> pathComponents; @@ -1500,7 +1464,7 @@ void cmQtAutoGenerators::Init() if (this->IncludeProjectDirsBefore) { - const std::string &binDir = "-I" + this->ProjectBinaryDir; + const std::string binDir = "-I" + this->ProjectBinaryDir; const std::string srcDir = "-I" + this->ProjectSourceDir; @@ -1619,12 +1583,7 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) std::vector<std::string> headerFilesVec; cmSystemTools::ExpandListArgument(this->Headers, headerFilesVec); - for (std::vector<std::string>::const_iterator it = headerFilesVec.begin(); - it != headerFilesVec.end(); - ++it) - { - headerFiles.insert(*it); - } + headerFiles.insert(headerFilesVec.begin(), headerFilesVec.end()); // key = moc source filepath, value = moc output filename std::map<std::string, std::string> notIncludedMocs; @@ -1771,7 +1730,7 @@ void cmQtAutoGenerators::ParseCppFile(const std::string& absFilename, std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(currentMoc); - const bool moc_style = this->StartsWith(basename, "moc_"); + const bool moc_style = cmHasLiteralPrefix(basename, "moc_"); // If the moc include is of the moc_foo.cpp style we expect // the Q_OBJECT class declaration in a header file. @@ -1953,7 +1912,7 @@ void cmQtAutoGenerators::StrictParseCppFile(const std::string& absFilename, std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(currentMoc); - const bool mocUnderscoreStyle = this->StartsWith(basename, "moc_"); + const bool mocUnderscoreStyle = cmHasLiteralPrefix(basename, "moc_"); // If the moc include is of the moc_foo.cpp style we expect // the Q_OBJECT class declaration in a header file. @@ -2185,24 +2144,12 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile, std::vector<std::string> command; command.push_back(this->MocExecutable); - for (std::list<std::string>::const_iterator it = this->MocIncludes.begin(); - it != this->MocIncludes.end(); - ++it) - { - command.push_back(*it); - } - for(std::list<std::string>::const_iterator it=this->MocDefinitions.begin(); - it != this->MocDefinitions.end(); - ++it) - { - command.push_back(*it); - } - for(std::vector<std::string>::const_iterator it=this->MocOptions.begin(); - it != this->MocOptions.end(); - ++it) - { - command.push_back(*it); - } + command.insert(command.end(), + this->MocIncludes.begin(), this->MocIncludes.end()); + command.insert(command.end(), + this->MocDefinitions.begin(), this->MocDefinitions.end()); + command.insert(command.end(), + this->MocOptions.begin(), this->MocOptions.end()); #ifdef _WIN32 command.push_back("-DWIN32"); #endif @@ -2274,12 +2221,7 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName, cmSystemTools::ExpandListArgument(optionIt->second, fileOpts); this->MergeUicOptions(opts, fileOpts, this->QtMajorVersion == "5"); } - for(std::vector<std::string>::const_iterator optIt = opts.begin(); - optIt != opts.end(); - ++optIt) - { - command.push_back(*optIt); - } + command.insert(command.end(), opts.begin(), opts.end()); command.push_back("-o"); command.push_back(this->Builddir + ui_output_file); @@ -2319,8 +2261,8 @@ bool cmQtAutoGenerators::InputFilesNewerThanQrc(const std::string& qrcFile, it != files.end(); ++it) { int inputNewerThanQrc = 0; - bool success = cmsys::SystemTools::FileTimeCompare(it->c_str(), - rccOutput.c_str(), + bool success = cmsys::SystemTools::FileTimeCompare(*it, + rccOutput, &inputNewerThanQrc); if (!success || inputNewerThanQrc >= 0) { @@ -2353,7 +2295,7 @@ bool cmQtAutoGenerators::GenerateQrc() int sourceNewerThanQrc = 0; bool generateQrc = !cmsys::SystemTools::FileTimeCompare(*si, - rcc_output_file.c_str(), + rcc_output_file, &sourceNewerThanQrc); generateQrc = generateQrc || (sourceNewerThanQrc >= 0); generateQrc = generateQrc || this->InputFilesNewerThanQrc(*si, @@ -2365,14 +2307,7 @@ bool cmQtAutoGenerators::GenerateQrc() = this->RccOptions.find(*si); if (optionIt != this->RccOptions.end()) { - std::vector<std::string> opts; - cmSystemTools::ExpandListArgument(optionIt->second, opts); - for(std::vector<std::string>::const_iterator optIt = opts.begin(); - optIt != opts.end(); - ++optIt) - { - command.push_back(*optIt); - } + cmSystemTools::ExpandListArgument(optionIt->second, command); } command.push_back("-name"); diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index cca995b..f4607c6 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -417,14 +417,7 @@ void cmRST::ProcessDirectiveReplace() { // Record markup lines as replacement text. std::string& replacement = this->Replace[this->ReplaceName]; - const char* sep = ""; - for(std::vector<std::string>::iterator i = this->MarkupLines.begin(); - i != this->MarkupLines.end(); ++i) - { - replacement += sep; - replacement += *i; - sep = " "; - } + replacement += cmJoin(this->MarkupLines, " "); this->ReplaceName = ""; } diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index bcb8564..bad38be 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -39,10 +39,7 @@ bool cmRemoveCommand // check for REMOVE(VAR v1 v2 ... vn) std::vector<std::string> argsExpanded; std::vector<std::string> temp; - for(unsigned int j = 1; j < args.size(); ++j) - { - temp.push_back(args[j]); - } + temp.insert(temp.end(), args.begin() + 1, args.end()); cmSystemTools::ExpandList(temp, argsExpanded); // now create the new value @@ -60,7 +57,7 @@ bool cmRemoveCommand } if (!found) { - if (value.size()) + if (!value.empty()) { value += ";"; } diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx new file mode 100644 index 0000000..861dbf1 --- /dev/null +++ b/Source/cmSearchPath.cxx @@ -0,0 +1,251 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmSearchPath.h" +#include "cmFindCommon.h" + +//---------------------------------------------------------------------------- +cmSearchPath::cmSearchPath(cmFindCommon* findCmd) +: FC(findCmd) +{ +} + +//---------------------------------------------------------------------------- +cmSearchPath::~cmSearchPath() +{ +} + +//---------------------------------------------------------------------------- + +void cmSearchPath::ExtractWithout(const std::set<std::string>& ignore, + std::vector<std::string>& outPaths, + bool clear) const +{ + if(clear) + { + outPaths.clear(); + } + for(std::vector<std::string>::const_iterator p = this->Paths.begin(); + p != this->Paths.end(); ++p) + { + if(ignore.count(*p) == 0) + { + outPaths.push_back(*p); + } + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddPath(const std::string& path) +{ + this->AddPathInternal(path); +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddUserPath(const std::string& path) +{ + assert(this->FC != NULL); + + std::vector<std::string> outPaths; + + // We should view the registry as the target application would view + // it. + cmSystemTools::KeyWOW64 view = cmSystemTools::KeyWOW64_32; + cmSystemTools::KeyWOW64 other_view = cmSystemTools::KeyWOW64_64; + if(this->FC->Makefile->PlatformIs64Bit()) + { + view = cmSystemTools::KeyWOW64_64; + other_view = cmSystemTools::KeyWOW64_32; + } + + // Expand using the view of the target application. + std::string expanded = path; + cmSystemTools::ExpandRegistryValues(expanded, view); + cmSystemTools::GlobDirs(expanded, outPaths); + + // Executables can be either 32-bit or 64-bit, so expand using the + // alternative view. + if(expanded != path && this->FC->CMakePathName == "PROGRAM") + { + expanded = path; + cmSystemTools::ExpandRegistryValues(expanded, other_view); + cmSystemTools::GlobDirs(expanded, outPaths); + } + + // Process them all from the current directory + for(std::vector<std::string>::const_iterator p = outPaths.begin(); + p != outPaths.end(); ++p) + { + this->AddPathInternal(*p, this->FC->Makefile->GetCurrentDirectory()); + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddCMakePath(const std::string& variable) +{ + assert(this->FC != NULL); + + // Get a path from a CMake variable. + if(const char* value = this->FC->Makefile->GetDefinition(variable)) + { + std::vector<std::string> expanded; + cmSystemTools::ExpandListArgument(value, expanded); + + for(std::vector<std::string>::const_iterator p = expanded.begin(); + p!= expanded.end(); ++p) + { + this->AddPathInternal(*p, this->FC->Makefile->GetCurrentDirectory()); + } + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddEnvPath(const std::string& variable) +{ + std::vector<std::string> expanded; + cmSystemTools::GetPath(expanded, variable.c_str()); + for(std::vector<std::string>::const_iterator p = expanded.begin(); + p!= expanded.end(); ++p) + { + this->AddPathInternal(*p); + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddCMakePrefixPath(const std::string& variable) +{ + assert(this->FC != NULL); + + // Get a path from a CMake variable. + if(const char* value = this->FC->Makefile->GetDefinition(variable)) + { + std::vector<std::string> expanded; + cmSystemTools::ExpandListArgument(value, expanded); + + this->AddPrefixPaths(expanded, this->FC->Makefile->GetCurrentDirectory()); + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddEnvPrefixPath(const std::string& variable) +{ + std::vector<std::string> expanded; + cmSystemTools::GetPath(expanded, variable.c_str()); + this->AddPrefixPaths(expanded); +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddSuffixes(const std::vector<std::string>& suffixes) +{ + std::vector<std::string> inPaths; + inPaths.swap(this->Paths); + this->Paths.reserve(inPaths.size()*(suffixes.size()+1)); + + for(std::vector<std::string>::iterator ip = inPaths.begin(); + ip != inPaths.end(); ++ip) + { + cmSystemTools::ConvertToUnixSlashes(*ip); + + // if *i is only / then do not add a // + // this will get incorrectly considered a network + // path on windows and cause huge delays. + std::string p = *ip; + if(!p.empty() && *p.rbegin() != '/') + { + p += "/"; + } + + // Combine with all the suffixes + for(std::vector<std::string>::const_iterator s = suffixes.begin(); + s != suffixes.end(); ++s) + { + this->Paths.push_back(p+*s); + } + + // And now the original w/o any suffix + this->Paths.push_back(*ip); + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths, + const char *base) +{ + assert(this->FC != NULL); + + // default for programs + std::string subdir = "bin"; + + if (this->FC->CMakePathName == "INCLUDE") + { + subdir = "include"; + } + else if (this->FC->CMakePathName == "LIBRARY") + { + subdir = "lib"; + } + else if (this->FC->CMakePathName == "FRAMEWORK") + { + subdir = ""; // ? what to do for frameworks ? + } + + for(std::vector<std::string>::const_iterator p = paths.begin(); + p != paths.end(); ++p) + { + std::string dir = *p; + if(!subdir.empty() && !dir.empty() && *dir.rbegin() != '/') + { + dir += "/"; + } + if(subdir == "include" || subdir == "lib") + { + const char* arch = + this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); + if(arch && *arch) + { + this->AddPathInternal(dir+subdir+"/"+arch, base); + } + } + std::string add = dir + subdir; + if(add != "/") + { + this->AddPathInternal(add, base); + } + if (subdir == "bin") + { + this->AddPathInternal(dir+"sbin", base); + } + if(!subdir.empty() && *p != "/") + { + this->AddPathInternal(*p, base); + } + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddPathInternal(const std::string& path, const char *base) +{ + assert(this->FC != NULL); + + std::string collapsed = cmSystemTools::CollapseFullPath(path, base); + + if(collapsed.empty()) + { + return; + } + + // Insert the path if has not already been emitted. + if(this->FC->SearchPathsEmitted.insert(collapsed).second) + { + this->Paths.push_back(collapsed); + } +} diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h new file mode 100644 index 0000000..51a6149 --- /dev/null +++ b/Source/cmSearchPath.h @@ -0,0 +1,57 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmSearchPath_h +#define cmSearchPath_h + +#include "cmStandardIncludes.h" + +class cmFindCommon; + +/** \class cmSearchPath + * \brief Container for encapsulating a set of search paths + * + * cmSearchPath is a container that encapsulates search path construction and + * management + */ +class cmSearchPath +{ +public: + // cmSearchPath must be initialized from a valid pointer. The only reason + // for teh default is to allow it to be easily used in stl containers. + // Attempting to initialize with a NULL value will fail an assertion + cmSearchPath(cmFindCommon* findCmd = 0); + ~cmSearchPath(); + + const std::vector<std::string>& GetPaths() const { return this->Paths; } + + void ExtractWithout(const std::set<std::string>& ignore, + std::vector<std::string>& outPaths, + bool clear = false) const; + + void AddPath(const std::string& path); + void AddUserPath(const std::string& path); + void AddCMakePath(const std::string& variable); + void AddEnvPath(const std::string& variable); + void AddCMakePrefixPath(const std::string& variable); + void AddEnvPrefixPath(const std::string& variable); + void AddSuffixes(const std::vector<std::string>& suffixes); + +protected: + void AddPrefixPaths(const std::vector<std::string>& paths, + const char *base = 0); + void AddPathInternal(const std::string& path, const char *base = 0); + + cmFindCommon *FC; + std::vector<std::string> Paths; +}; + +#endif diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx index 1ee3f29..8e6c311 100644 --- a/Source/cmSeparateArgumentsCommand.cxx +++ b/Source/cmSeparateArgumentsCommand.cxx @@ -51,7 +51,7 @@ bool cmSeparateArgumentsCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given unknown argument " << args[i]; this->SetError(e.str()); return false; diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 0ca36eb..90d7b03 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -37,13 +37,13 @@ bool cmSetCommand delete [] varName; // will it be set to something, then set it - if (args.size() > 1 && args[1].size()) + if (args.size() > 1 && !args[1].empty()) { // but only if it is different from current value if (!currValue || strcmp(currValue,args[1].c_str())) { putEnvArg += args[1]; - cmSystemTools::PutEnv(putEnvArg.c_str()); + cmSystemTools::PutEnv(putEnvArg); } return true; } @@ -51,7 +51,7 @@ bool cmSetCommand // if it will be cleared, then clear it if it isn;t already clear if (currValue) { - cmSystemTools::PutEnv(putEnvArg.c_str()); + cmSystemTools::PutEnv(putEnvArg); } return true; } diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 653d764..1150bc7 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -67,7 +67,7 @@ bool cmSetPropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid scope " << *arg << ". " << "Valid scopes are GLOBAL, DIRECTORY, " "TARGET, SOURCE, TEST, CACHE, INSTALL."; @@ -117,7 +117,7 @@ bool cmSetPropertyCommand } else { - cmOStringStream e; + std::ostringstream e; e << "given invalid argument \"" << *arg << "\"."; this->SetError(e.str()); return false; @@ -265,7 +265,7 @@ bool cmSetPropertyCommand::HandleTargetMode() } else { - cmOStringStream e; + std::ostringstream e; e << "could not find TARGET " << *ni << ". Perhaps it has not yet been created."; this->SetError(e.str()); @@ -316,7 +316,7 @@ bool cmSetPropertyCommand::HandleSourceMode() } else { - cmOStringStream e; + std::ostringstream e; e << "given SOURCE name that could not be found or created: " << *ni; this->SetError(e.str()); return false; @@ -373,7 +373,7 @@ bool cmSetPropertyCommand::HandleTestMode() // Names that are still left were not found. if(!this->Names.empty()) { - cmOStringStream e; + std::ostringstream e; e << "given TEST names that do not exist:\n"; for(std::set<std::string>::const_iterator ni = this->Names.begin(); ni != this->Names.end(); ++ni) @@ -417,7 +417,7 @@ bool cmSetPropertyCommand::HandleCacheMode() !cmSystemTools::IsOn(this->PropertyValue.c_str()) && !cmSystemTools::IsOff(this->PropertyValue.c_str())) { - cmOStringStream e; + std::ostringstream e; e << "given non-boolean value \"" << this->PropertyValue << "\" for CACHE property \"ADVANCED\". "; this->SetError(e.str()); @@ -428,7 +428,7 @@ bool cmSetPropertyCommand::HandleCacheMode() { if(!cmCacheManager::IsType(this->PropertyValue.c_str())) { - cmOStringStream e; + std::ostringstream e; e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\""; this->SetError(e.str()); return false; @@ -438,7 +438,7 @@ bool cmSetPropertyCommand::HandleCacheMode() this->PropertyName != "STRINGS" && this->PropertyName != "VALUE") { - cmOStringStream e; + std::ostringstream e; e << "given invalid CACHE property " << this->PropertyName << ". " << "Settable CACHE properties are: " << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE."; @@ -463,7 +463,7 @@ bool cmSetPropertyCommand::HandleCacheMode() } else { - cmOStringStream e; + std::ostringstream e; e << "could not find CACHE variable " << *ni << ". Perhaps it has not yet been created."; this->SetError(e.str()); @@ -513,7 +513,7 @@ bool cmSetPropertyCommand::HandleInstallMode() } else { - cmOStringStream e; + std::ostringstream e; e << "given INSTALL name that could not be found or created: " << *i; this->SetError(e.str()); return false; diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index bf3519c..aeb8077 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -61,7 +61,7 @@ bool cmSetTargetPropertiesCommand return false; } } - if(propertyPairs.size() == 0) + if(propertyPairs.empty()) { this->SetError("called with illegal arguments, maybe missing " "a PROPERTIES specifier?"); diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index b026ff3..e66d13d 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -62,7 +62,7 @@ bool cmSetTestsPropertiesCommand return false; } } - if(propertyPairs.size() == 0) + if(propertyPairs.empty()) { this->SetError("called with illegal arguments, maybe " "missing a PROPERTIES specifier?"); diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx index e61caab..927888b 100644 --- a/Source/cmSiteNameCommand.cxx +++ b/Source/cmSiteNameCommand.cxx @@ -66,7 +66,7 @@ bool cmSiteNameCommand &host, 0, 0, cmSystemTools::OUTPUT_NONE); // got the hostname - if (host.length()) + if (!host.empty()) { // remove any white space from the host name std::string hostRegExp = "[ \t\n\r]*([^\t\n\r ]*)[ \t\n\r]*"; @@ -77,7 +77,7 @@ bool cmSiteNameCommand host = hostReg.match(1); } - if(host.length()) + if(!host.empty()) { siteName = host; } diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx index 6fe5c62..6847475 100644 --- a/Source/cmSourceFile.cxx +++ b/Source/cmSourceFile.cxx @@ -24,7 +24,7 @@ cmSourceFile::cmSourceFile(cmMakefile* mf, const std::string& name): this->CustomCommand = 0; this->Properties.SetCMakeInstance(mf->GetCMakeInstance()); this->FindFullPathFailed = false; - this->IsUiFile = ("ui" == + this->IsUiFile = (".ui" == cmSystemTools::GetFilenameLastExtension(this->Location.GetName())); } @@ -202,7 +202,7 @@ bool cmSourceFile::FindFullPath(std::string* error) } } - cmOStringStream e; + std::ostringstream e; std::string missing = this->Location.GetDirectory(); if(!missing.empty()) { diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index efc4376..b81951d 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -216,7 +216,8 @@ bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc) // Both extensions are similarly ambiguous. Since only the old fixed set // of extensions will be tried, the names must match at this point to be // the same file. - if(this->Name.size() != loc.Name.size() || this->Name != loc.Name) + if(this->Name.size() != loc.Name.size() || + !cmSystemTools::ComparePath(this->Name, loc.Name)) { return false; } diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index edba5ba..1741e05 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -90,7 +90,7 @@ bool cmSourceGroupCommand } else { - cmOStringStream err; + std::ostringstream err; err << "Unknown argument \"" << args[i] << "\". " << "Perhaps the FILES keyword is missing.\n"; this->SetError(err.str()); diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index ffabd7a..646300d 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -16,8 +16,6 @@ #ifndef cmStandardIncludes_h #define cmStandardIncludes_h -// include configure generated header to define CMAKE_NO_ANSI_STREAM_HEADERS, -// CMAKE_NO_STD_NAMESPACE, and other macros. #include <cmConfigure.h> #include <cmsys/Configure.hxx> @@ -25,7 +23,6 @@ #pragma warning ( disable : 4786 ) #pragma warning ( disable : 4503 ) #pragma warning ( disable : 4512 ) /* operator=() could not be generated */ -#define CMAKE_NO_ANSI_FOR_SCOPE #endif @@ -37,35 +34,12 @@ // Provide fixed-size integer types. #include <cmIML/INT.h> -#include <stdarg.h> // Work-around for SGI MIPSpro 7.4.2m header bug - -// This is a hack to prevent warnings about these functions being -// declared but not referenced. -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 3970 /* conversion from pointer to same-sized */ -# include <sys/termios.h> -class cmStandardIncludesHack -{ -public: - enum - { - Ref1 = sizeof(cfgetospeed(0)), - Ref2 = sizeof(cfgetispeed(0)), - Ref3 = sizeof(tcgetattr(0, 0)), - Ref4 = sizeof(tcsetattr(0, 0, 0)), - Ref5 = sizeof(cfsetospeed(0,0)), - Ref6 = sizeof(cfsetispeed(0,0)) - }; -}; -#endif - // Include stream compatibility layer from KWSys. // This is needed to work with large file support // on some platforms whose stream operators do not // support the large integer types. #if defined(CMAKE_BUILD_WITH_CMAKE) # include <cmsys/IOStream.hxx> -# undef GetCurrentDirectory // Borland <iosfwd> includes windows.h #endif // Avoid warnings in system headers. @@ -73,23 +47,10 @@ public: # pragma warning (push,1) #endif -#ifndef CMAKE_NO_ANSI_STREAM_HEADERS -# include <fstream> -# include <iostream> -# include <iomanip> -#else -# include <fstream.h> -# include <iostream.h> -# include <iomanip.h> -#endif - -#if !defined(CMAKE_NO_ANSI_STRING_STREAM) -# include <sstream> -#elif !defined(CMAKE_NO_ANSI_STREAM_HEADERS) -# include <strstream> -#else -# include <strstream.h> -#endif +#include <fstream> +#include <iostream> +#include <iomanip> +#include <sstream> // we must have stl with the standard include style #include <vector> @@ -111,195 +72,18 @@ public: #include <stdio.h> #include <stdlib.h> -// Borland C++ defines several of the stdlib.h and string.h symbols in -// sub-headers search.h and mem.h. These sub-headers have using -// declarations to pull functions from the std namespace to the global -// namespace, but they are defined only if the header was not included -// through the C++-style cstdlib or cstring header. These outer -// headers are included by the streams library in C++-style and -// include blockers are put in place that prevent including the -// C-style versions from ever including the sub-headers. Therefore we -// have to include the sub-headers here to get the using declarations. - - -#if !defined(_WIN32) && defined(__COMO__) -// Hack for como strict mode to avoid defining _SVID_SOURCE or _BSD_SOURCE. -extern "C" -{ -extern FILE *popen (__const char *__command, __const char *__modes) __THROW; -extern int pclose (FILE *__stream) __THROW; -extern char *realpath (__const char *__restrict __name, - char *__restrict __resolved) __THROW; -extern char *strdup (__const char *__s) __THROW; -extern int putenv (char *__string) __THROW; -} -#endif - -// if std:: is not supported, then just #define it away -#ifdef CMAKE_NO_STD_NAMESPACE -#define std -#endif - -// if the compiler does not support ansi for scoping of vars use a -// #define hack -#ifdef CMAKE_NO_ANSI_FOR_SCOPE -#define for if(false) {} else for -#endif - -// Provide std::ios_base on ancient GCC 2.9x -#if defined(__GNUC__) && __GNUC__ < 3 -namespace std { typedef ios ios_base; } -#endif - -// check for the 720 compiler on the SGI -// which has some strange properties that I don't think are worth -// checking for in a general way in configure -#if defined(__sgi) && !defined(__GNUC__) -# if (_COMPILER_VERSION >= 730) -# define CM_SGI_CC_730 -# elif (_COMPILER_VERSION >= 720) -# define CM_HAS_STD_BUT_NOT_FOR_IOSTREAM -# endif -#endif - -#ifdef __DECCXX_VER -# if __DECCXX_VER <= 60390008 -# define CM_HAS_STD_BUT_NOT_FOR_IOSTREAM -# endif -#endif - #if defined( _MSC_VER ) typedef unsigned short mode_t; #endif - -#ifdef CM_HAS_STD_BUT_NOT_FOR_IOSTREAM -// some compilers have std:: but not for the stream library, -// so we have to bring it into the std namespace by hand. -namespace std { -using ::ostream; -using ::istream; -using ::ios; -using ::cout; -using ::cerr; -using ::cin; -using ::ifstream; -using ::ofstream; - -#if !defined(CMAKE_NO_ANSI_STRING_STREAM) - using ::ostringstream; - using ::istringstream; -#else - using ::ostrstream; - using ::istrstream; -#endif - -using ::endl; -using ::ends; -using ::flush; -using ::dec; -using ::hex; -using ::setw; -using ::setiosflags; -using ::setfill; -using ::setprecision; -} -// The string class is missing these operators so add them -#if !defined(cmsys_STL_STRING_NEQ_CHAR_DEFINED) -# define cmsys_STL_STRING_NO_NEQ_CHAR -inline bool operator!=(std::string const& a, const char* b) -{ return !(a==std::string(b)); } -#endif - -inline bool operator==(std::string const& a, const char* b) -{ return (a==std::string(b)); } -# endif // end CM_SGI_CC_720 - -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - // use this class to shrink the size of symbols in .o files // std::string is really basic_string<....lots of stuff....> // when combined with a map or set, the symbols can be > 2000 chars! #include <cmsys/String.hxx> //typedef cmsys::String std::string; -// Define cmOStringStream and cmIStringStream wrappers to hide -// differences between std::stringstream and the old strstream. -#if !defined(CMAKE_NO_ANSI_STRING_STREAM) -class cmOStringStream: public std::ostringstream -{ -public: - cmOStringStream(); - ~cmOStringStream(); -private: - cmOStringStream(const cmOStringStream&); - void operator=(const cmOStringStream&); -}; -class cmIStringStream: public std::istringstream -{ -public: - typedef std::istringstream Superclass; - cmIStringStream() {} - cmIStringStream(const std::string& s): Superclass(s) {} -private: - cmIStringStream(const cmIStringStream&); - void operator=(const cmIStringStream&); -}; -#else -class cmOStrStreamCleanup -{ -public: - cmOStrStreamCleanup(std::ostrstream& ostr): OStrStream(ostr) {} - ~cmOStrStreamCleanup() { this->OStrStream.rdbuf()->freeze(0); } - static void IgnoreUnusedVariable(const cmOStrStreamCleanup&) {} -protected: - std::ostrstream& OStrStream; -}; - -class cmOStringStream: public std::ostrstream -{ -public: - typedef std::ostrstream Superclass; - cmOStringStream() {} - std::string str() - { - cmOStrStreamCleanup cleanup(*this); - cmOStrStreamCleanup::IgnoreUnusedVariable(cleanup); - int pcount = this->pcount(); - const char* ptr = this->Superclass::str(); - return std::string(ptr?ptr:"", pcount); - } -private: - cmOStringStream(const cmOStringStream&); - void operator=(const cmOStringStream&); -}; - -class cmIStringStream: private std::string, public std::istrstream -{ -public: - typedef std::string StdString; - typedef std::istrstream IStrStream; - cmIStringStream(): StdString(), IStrStream(StdString::c_str()) {} - cmIStringStream(const std::string& s): - StdString(s), IStrStream(StdString::c_str()) {} - std::string str() const { return *this; } - void str(const std::string& s) - { - // Very dangerous. If this throws, the object is hosed. When the - // destructor is later called, the program is hosed too. - this->~cmIStringStream(); - new (this) cmIStringStream(s); - } -private: - cmIStringStream(const cmIStringStream&); - void operator=(const cmIStringStream&); -}; -#endif - /* Poison this operator to avoid common mistakes. */ -extern void operator << (std::ostream&, const cmOStringStream&); +extern void operator << (std::ostream&, const std::ostringstream&); /** Standard documentation entry for cmDocumentation's formatting. */ struct cmDocumentationEntry @@ -332,10 +116,6 @@ public: typedef Superclass::const_iterator const_iterator; }; -#if defined(__sgi) && !defined(__GNUC__) -# pragma reset woff 1375 /* base class destructor not virtual */ -#endif - // All subclasses of cmCommand or cmCTestGenericHandler should // invoke this macro. #define cmTypeMacro(thisClass,superclass) \ @@ -363,6 +143,33 @@ static thisClass* SafeDownCast(cmObject *c) \ } \ class cmTypeMacro_UseTrailingSemicolon +template<typename Range> +std::string cmJoin(Range const& r, const char* delimiter) +{ + if (r.empty()) + { + return std::string(); + } + std::ostringstream os; + typedef typename Range::value_type ValueType; + typedef typename Range::const_iterator InputIt; + InputIt first = r.begin(); + InputIt last = r.end(); + --last; + std::copy(first, last, + std::ostream_iterator<ValueType>(os, delimiter)); + + os << *last; + + return os.str(); +} + +template<typename Range> +std::string cmJoin(Range const& r, std::string delimiter) +{ + return cmJoin(r, delimiter.c_str()); +}; + inline bool cmHasLiteralPrefixImpl(const std::string &str1, const char *str2, size_t N) @@ -393,21 +200,6 @@ inline bool cmHasLiteralSuffixImpl(const char* str1, return len >= N && strcmp(str1 + len - N, str2) == 0; } -#if defined(_MSC_VER) && _MSC_VER < 1300 \ - || defined(__GNUC__) && __GNUC__ < 3 - -#define cmArrayBegin(a) a -#define cmArraySize(a) (sizeof(a)/sizeof(*a)) -#define cmArrayEnd(a) a + cmArraySize(a) - -#define cmHasLiteralPrefix(STR1, STR2) \ - cmHasLiteralPrefixImpl(STR1, "" STR2 "", sizeof(STR2) - 1) - -#define cmHasLiteralSuffix(STR1, STR2) \ - cmHasLiteralSuffixImpl(STR1, "" STR2 "", sizeof(STR2) - 1) - -#else - template<typename T, size_t N> const T* cmArrayBegin(const T (&a)[N]) { return a; } template<typename T, size_t N> @@ -427,8 +219,6 @@ bool cmHasLiteralSuffix(T str1, const char (&str2)[N]) return cmHasLiteralSuffixImpl(str1, str2, N - 1); } -#endif - struct cmStrCmp { cmStrCmp(const char *test) : m_test(test) {} cmStrCmp(const std::string &test) : m_test(test) {} @@ -447,4 +237,44 @@ private: const std::string m_test; }; +namespace ContainerAlgorithms { + +template<typename T> +struct cmIsPair +{ + enum { value = false }; +}; + +template<typename K, typename V> +struct cmIsPair<std::pair<K, V> > +{ + enum { value = true }; +}; + +template<typename Container, + bool valueTypeIsPair = cmIsPair<typename Container::value_type>::value> +struct DefaultDeleter +{ + void operator()(typename Container::value_type value) { + delete value; + } +}; + +template<typename Container> +struct DefaultDeleter<Container, /* valueTypeIsPair = */ true> +{ + void operator()(typename Container::value_type value) { + delete value.second; + } +}; + +} + +template<typename Container> +void cmDeleteAll(Container const& c) +{ + std::for_each(c.begin(), c.end(), + ContainerAlgorithms::DefaultDeleter<Container>()); +} + #endif diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h index 981e03e..bd08ac7 100644 --- a/Source/cmStandardLexer.h +++ b/Source/cmStandardLexer.h @@ -25,12 +25,6 @@ # pragma warning ( disable : 4786 ) #endif -/* Make sure SGI termios does not define ECHO differently. */ -#if defined(__sgi) && !defined(__GNUC__) -# include <sys/termios.h> -# undef ECHO -#endif - /* Define isatty on windows. */ #if defined(_WIN32) && !defined(__CYGWIN__) # include <io.h> diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 90a8f85..3e606d7 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -122,7 +122,7 @@ bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args) #if defined(CMAKE_BUILD_WITH_CMAKE) if(args.size() != 3) { - cmOStringStream e; + std::ostringstream e; e << args[0] << " requires an output variable and an input string"; this->SetError(e.str()); return false; @@ -137,7 +137,7 @@ bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args) } return false; #else - cmOStringStream e; + std::ostringstream e; e << args[0] << " not available during bootstrap"; this->SetError(e.str().c_str()); return false; @@ -233,7 +233,7 @@ bool cmStringCommand::HandleConfigureCommand( } else { - cmOStringStream err; + std::ostringstream err; err << "Unrecognized argument \"" << args[i] << "\""; this->SetError(err.str()); return false; @@ -386,7 +386,7 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) this->SetError(e); return false; } - if(output.length() > 0) + if(!output.empty()) { output += ";"; } @@ -591,7 +591,7 @@ bool cmStringCommand::HandleFindCommand(std::vector<std::string> const& } if(std::string::npos != pos) { - cmOStringStream s; + std::ostringstream s; s << pos; this->Makefile->AddDefinition(outvar, s.str().c_str()); return true; @@ -705,18 +705,16 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const& int intStringLength = static_cast<int>(stringLength); if ( begin < 0 || begin > intStringLength ) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "begin index: " << begin << " is out of range 0 - " << stringLength; this->SetError(ostr.str()); return false; } - int leftOverLength = intStringLength - begin; - if ( end < -1 || end > leftOverLength ) + if ( end < -1 ) { - cmOStringStream ostr; - ostr << "end index: " << end << " is out of range -1 - " - << leftOverLength; + std::ostringstream ostr; + ostr << "end index: " << end << " should be -1 or greater"; this->SetError(ostr.str()); return false; } @@ -782,7 +780,7 @@ bool cmStringCommand const std::string& variableName = args[2]; this->Makefile->AddDefinition(variableName, - cmSystemTools::MakeCidentifier(input.c_str()).c_str()); + cmSystemTools::MakeCidentifier(input).c_str()); return true; } @@ -900,7 +898,7 @@ bool cmStringCommand } } } - if ( !alphabet.size() ) + if (alphabet.empty()) { alphabet = cmStringCommandDefaultAlphabet; } @@ -1091,7 +1089,7 @@ bool cmStringCommand this->Makefile->AddDefinition(outputVariable, uuid.c_str()); return true; #else - cmOStringStream e; + std::ostringstream e; e << args[0] << " not available during bootstrap"; this->SetError(e.str().c_str()); return false; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 6b7009a..e9735ed 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -9,9 +9,7 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#if defined(_MSC_VER) && _MSC_VER < 1300 -# define _WIN32_WINNT 0x0400 /* for wincrypt.h */ -#endif + #include "cmSystemTools.h" #include <ctype.h> #include <errno.h> @@ -65,6 +63,10 @@ # include "cmELF.h" #endif +#if defined(CMAKE_USE_MACH_PARSER) +# include "cmMachO.h" +#endif + class cmSystemToolsFileTime { public: @@ -77,10 +79,6 @@ public: #endif }; -#if defined(__sgi) && !defined(__GNUC__) -# pragma set woff 1375 /* base class destructor not virtual */ -#endif - #if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE) // For GetEnvironmentVariables # if defined(_WIN32) @@ -826,18 +824,12 @@ bool cmSystemTools::RunSingleCommand( std::string cmSystemTools::PrintSingleCommand(std::vector<std::string> const& command) { - std::string commandStr; - const char* sep = ""; - for(std::vector<std::string>::const_iterator i = command.begin(); - i != command.end(); ++i) + if (command.empty()) { - commandStr += sep; - commandStr += "\""; - commandStr += *i; - commandStr += "\""; - sep = " "; + return std::string(); } - return commandStr; + + return "\"" + cmJoin(command, "\" \"") + "\""; } bool cmSystemTools::DoesFileExistWithExtensions( @@ -1160,7 +1152,7 @@ bool cmSystemTools::SimpleGlob(const std::string& glob, std::string path = cmSystemTools::GetFilenamePath(glob); std::string ppath = cmSystemTools::GetFilenameName(glob); ppath = ppath.substr(0, ppath.size()-1); - if ( path.size() == 0 ) + if (path.empty()) { path = "/"; } @@ -1271,11 +1263,7 @@ bool cmSystemTools::Split(const char* s, std::vector<std::string>& l) { std::vector<std::string> temp; bool res = Superclass::Split(s, temp); - for(std::vector<std::string>::const_iterator i = temp.begin(); - i != temp.end(); ++i) - { - l.push_back(*i); - } + l.insert(l.end(), temp.begin(), temp.end()); return res; } @@ -1409,7 +1397,7 @@ void cmSystemTools::AppendEnv(std::vector<std::string> const& env) for(std::vector<std::string>::const_iterator eit = env.begin(); eit != env.end(); ++eit) { - cmSystemTools::PutEnv(eit->c_str()); + cmSystemTools::PutEnv(*eit); } } @@ -1480,7 +1468,8 @@ bool cmSystemTools::IsPathToFramework(const char* path) bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<std::string>& files, - bool gzip, bool bzip2, bool verbose) + cmTarCompression compressType, + bool verbose, std::string const& mtime) { #if defined(CMAKE_BUILD_WITH_CMAKE) std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); @@ -1494,10 +1483,25 @@ bool cmSystemTools::CreateTar(const char* outFileName, cmSystemTools::Error(e.c_str()); return false; } - cmArchiveWrite a(fout, (gzip? cmArchiveWrite::CompressGZip : - (bzip2? cmArchiveWrite::CompressBZip2 : - cmArchiveWrite::CompressNone)), - cmArchiveWrite::TypeTAR); + cmArchiveWrite::Compress compress = cmArchiveWrite::CompressNone; + switch (compressType) + { + case TarCompressGZip: + compress = cmArchiveWrite::CompressGZip; + break; + case TarCompressBZip2: + compress = cmArchiveWrite::CompressBZip2; + break; + case TarCompressXZ: + compress = cmArchiveWrite::CompressXZ; + break; + case TarCompressNone: + compress = cmArchiveWrite::CompressNone; + break; + } + cmArchiveWrite a(fout, compress, + cmArchiveWrite::TypeTAR); + a.SetMTime(mtime); a.SetVerbose(verbose); for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) @@ -1522,7 +1526,6 @@ bool cmSystemTools::CreateTar(const char* outFileName, #else (void)outFileName; (void)files; - (void)gzip; (void)verbose; return false; #endif @@ -1783,7 +1786,7 @@ bool extract_tar(const char* outFileName, bool verbose, #endif bool cmSystemTools::ExtractTar(const char* outFileName, - bool , bool verbose) + bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) return extract_tar(outFileName, verbose, true); @@ -1795,7 +1798,6 @@ bool cmSystemTools::ExtractTar(const char* outFileName, } bool cmSystemTools::ListTar(const char* outFileName, - bool , bool verbose) { #if defined(CMAKE_BUILD_WITH_CMAKE) @@ -2333,7 +2335,7 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath, { return false; } - if(!cmSystemTools::ReadSymlink(fullPath.c_str(), soname)) + if(!cmSystemTools::ReadSymlink(fullPath, soname)) { return false; } @@ -2359,31 +2361,17 @@ bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath, bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath, std::string& soname) { - std::vector<std::string> cmds; - cmds.push_back("otool"); - cmds.push_back("-D"); - cmds.push_back(fullPath); - - std::string output; - if(!RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE)) +#if defined(CMAKE_USE_MACH_PARSER) + cmMachO macho(fullPath.c_str()); + if(macho) { - cmds.insert(cmds.begin(), "-r"); - cmds.insert(cmds.begin(), "xcrun"); - if(!RunSingleCommand(cmds, &output, 0, 0, OUTPUT_NONE)) - { - return false; - } + return macho.GetInstallName(soname); } +#else + (void)fullPath; + (void)soname; +#endif - std::vector<std::string> strs = cmSystemTools::tokenize(output, "\n"); - // otool returns extra lines reporting multiple install names - // in case the binary is multi-arch and none of the architectures - // is native (e.g. i386;ppc on x86_64) - if(strs.size() >= 2) - { - soname = strs[1]; - return true; - } return false; } @@ -2517,7 +2505,7 @@ bool cmSystemTools::ChangeRPath(std::string const& file, } if(emsg) { - cmOStringStream e; + std::ostringstream e; e << "The current " << se_name[i] << " is:\n" << " " << se[i]->Value << "\n" << "which does not contain:\n" @@ -2634,29 +2622,37 @@ bool cmSystemTools::ChangeRPath(std::string const& file, bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op, const char* lhss, const char* rhss) { - // Parse out up to 8 components. - unsigned int lhs[8] = {0,0,0,0,0,0,0,0}; - unsigned int rhs[8] = {0,0,0,0,0,0,0,0}; - sscanf(lhss, "%u.%u.%u.%u.%u.%u.%u.%u", - &lhs[0], &lhs[1], &lhs[2], &lhs[3], - &lhs[4], &lhs[5], &lhs[6], &lhs[7]); - sscanf(rhss, "%u.%u.%u.%u.%u.%u.%u.%u", - &rhs[0], &rhs[1], &rhs[2], &rhs[3], - &rhs[4], &rhs[5], &rhs[6], &rhs[7]); + const char *endl = lhss; + const char *endr = rhss; + unsigned long lhs, rhs; - // Do component-wise comparison. - for(unsigned int i=0; i < 8; ++i) + while (((*endl >= '0') && (*endl <= '9')) || + ((*endr >= '0') && (*endr <= '9'))) { - if(lhs[i] < rhs[i]) + // Do component-wise comparison. + lhs = strtoul(endl, const_cast<char**>(&endl), 10); + rhs = strtoul(endr, const_cast<char**>(&endr), 10); + + if(lhs < rhs) { // lhs < rhs, so true if operation is LESS return op == cmSystemTools::OP_LESS; } - else if(lhs[i] > rhs[i]) + else if(lhs > rhs) { // lhs > rhs, so true if operation is GREATER return op == cmSystemTools::OP_GREATER; } + + if (*endr == '.') + { + endr++; + } + + if (*endl == '.') + { + endl++; + } } // lhs == rhs, so true if operation is EQUAL return op == cmSystemTools::OP_EQUAL; @@ -2917,3 +2913,12 @@ std::vector<std::string> cmSystemTools::tokenize(const std::string& str, } return tokens; } + +//---------------------------------------------------------------------------- +bool cmSystemTools::StringToLong(const char* str, long* value) +{ + errno = 0; + char *endp; + *value = strtol(str, &endp, 10); + return (*endp == '\0') && (endp != str) && (errno == 0); +} diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 4455dd1..361f42e 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -383,13 +383,20 @@ public: static void EnableVSConsoleOutput(); /** Create tar */ + enum cmTarCompression + { + TarCompressGZip, + TarCompressBZip2, + TarCompressXZ, + TarCompressNone + }; static bool ListTar(const char* outFileName, - bool gzip, bool verbose); + bool verbose); static bool CreateTar(const char* outFileName, - const std::vector<std::string>& files, bool gzip, - bool bzip2, bool verbose); - static bool ExtractTar(const char* inFileName, bool gzip, - bool verbose); + const std::vector<std::string>& files, + cmTarCompression compressType, bool verbose, + std::string const& mtime = std::string()); + static bool ExtractTar(const char* inFileName, bool verbose); // This should be called first thing in main // it will keep child processes from inheriting the // stdin and stdout of this process. This is important @@ -458,6 +465,9 @@ public: static std::vector<std::string> tokenize(const std::string& str, const std::string& sep); + /** Convert string to long. Expected that the whole string is an integer */ + static bool StringToLong(const char* str, long* value); + #ifdef _WIN32 struct WindowsFileRetry { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ee62f06..98cb75c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -226,13 +226,7 @@ cmLinkImplItem cmTargetInternals::TargetPropertyEntry::NoLinkImplItem; static void deleteAndClear( std::vector<cmTargetInternals::TargetPropertyEntry*> &entries) { - for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator - it = entries.begin(), - end = entries.end(); - it != end; ++it) - { - delete *it; - } + cmDeleteAll(entries); entries.clear(); } @@ -325,6 +319,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY) { this->SetPropertyDefault("ANDROID_API", 0); + this->SetPropertyDefault("ANDROID_API_MIN", 0); this->SetPropertyDefault("INSTALL_NAME_DIR", 0); this->SetPropertyDefault("INSTALL_RPATH", ""); this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF"); @@ -423,12 +418,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) const std::set<std::string> parentSystemIncludes = this->Makefile->GetSystemIncludeDirectories(); - for (std::set<std::string>::const_iterator it - = parentSystemIncludes.begin(); - it != parentSystemIncludes.end(); ++it) - { - this->SystemIncludeDirectories.insert(*it); - } + this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(), + parentSystemIncludes.end()); const std::vector<cmValueWithOrigin> parentOptions = this->Makefile->GetCompileOptionsEntries(); @@ -547,12 +538,8 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->LinkClosureMap.clear(); - for (cmTargetLinkInformationMap::const_iterator it - = this->LinkInformation.begin(); - it != this->LinkInformation.end(); ++it) - { - delete it->second; - } + this->Internal->SourceFilesMap.clear(); + cmDeleteAll(this->LinkInformation); this->LinkInformation.clear(); } @@ -649,6 +636,8 @@ static bool processSources(cmTarget const* tgt, for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator it = entries.begin(), end = entries.end(); it != end; ++it) { + cmLinkImplItem const& item = (*it)->LinkImplItem; + std::string const& targetName = item; std::vector<std::string> entrySources; cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, config, @@ -667,11 +656,10 @@ static bool processSources(cmTarget const* tgt, i != entrySources.end(); ++i) { std::string& src = *i; - cmSourceFile* sf = mf->GetOrCreateSource(src); std::string e; - src = sf->GetFullPath(&e); - if(src.empty()) + std::string fullPath = sf->GetFullPath(&e); + if(fullPath.empty()) { if(!e.empty()) { @@ -681,6 +669,25 @@ static bool processSources(cmTarget const* tgt, } return contextDependent; } + + if (!targetName.empty() && !cmSystemTools::FileIsFullPath(src.c_str())) + { + std::ostringstream err; + if (!targetName.empty()) + { + err << "Target \"" << targetName << "\" contains relative " + "path in its INTERFACE_SOURCES:\n" + " \"" << src << "\""; + } + else + { + err << "Found relative path while evaluating sources of " + "\"" << tgt->GetName() << "\":\n \"" << src << "\"\n"; + } + tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, err.str()); + return contextDependent; + } + src = fullPath; } std::string usedSources; for(std::vector<std::string>::iterator @@ -842,7 +849,7 @@ cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const thisConfigFiles += (*fi)->GetFullPath(); sep = "\n "; } - cmOStringStream e; + std::ostringstream e; e << "Target \"" << this->Name << "\" has source files which vary by " "configuration. This is not supported by the \"" << this->Makefile->GetLocalGenerator() @@ -902,16 +909,7 @@ void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files, //---------------------------------------------------------------------------- void cmTarget::AddTracedSources(std::vector<std::string> const& srcs) { - std::string srcFiles; - const char* sep = ""; - for(std::vector<std::string>::const_iterator i = srcs.begin(); - i != srcs.end(); ++i) - { - std::string filename = *i; - srcFiles += sep; - srcFiles += filename; - sep = ";"; - } + std::string srcFiles = cmJoin(srcs, ";"); if (!srcFiles.empty()) { this->Internal->SourceFilesMap.clear(); @@ -975,7 +973,7 @@ std::string cmTarget::ProcessSourceItemCMP0049(const std::string& s) this->Makefile->ExpandVariablesInString(src); if (src != s) { - cmOStringStream e; + std::ostringstream e; bool noMessage = false; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0049)) @@ -1258,7 +1256,7 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature) } //---------------------------------------------------------------------------- -void cmTarget::GetTllSignatureTraces(cmOStringStream &s, +void cmTarget::GetTllSignatureTraces(std::ostringstream &s, TLLSignature sig) const { std::vector<cmListFileBacktrace> sigs; @@ -1286,7 +1284,7 @@ void cmTarget::GetTllSignatureTraces(cmOStringStream &s, if(i != it->end()) { cmListFileContext const& lfc = *i; - cmOStringStream line; + std::ostringstream line; line << " * " << (lfc.Line? "": " in ") << lfc << std::endl; if (emitted.insert(line.str()).second) { @@ -1376,22 +1374,14 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, void cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs) { - for(std::set<std::string>::const_iterator li = incs.begin(); - li != incs.end(); ++li) - { - this->SystemIncludeDirectories.insert(*li); - } + this->SystemIncludeDirectories.insert(incs.begin(), incs.end()); } //---------------------------------------------------------------------------- void cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs) { - for(std::vector<std::string>::const_iterator li = incs.begin(); - li != incs.end(); ++li) - { - this->SystemIncludeDirectories.insert(*li); - } + this->SystemIncludeDirectories.insert(incs.begin(), incs.end()); } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1518,7 +1508,7 @@ cmTarget::AnalyzeLibDependenciesForVS6( const cmMakefile& mf ) { // skip zero size library entries, this may happen // if a variable expands to nothing. - if (lib->first.size() != 0) + if (!lib->first.empty()) { this->EmitForVS6( *lib, dep_map, done, visited, newLinkLibrariesForVS6 ); } @@ -1658,7 +1648,7 @@ void cmTarget::GatherDependenciesForVS6( const cmMakefile& mf, while( end != std::string::npos ) { std::string l = depline.substr( start, end-start ); - if( l.size() != 0 ) + if(!l.empty()) { if (l == "debug") { @@ -1728,7 +1718,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) if (this->GetType() == INTERFACE_LIBRARY && !whiteListedInterfaceProperty(prop)) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " "The property \"" << prop << "\" is not allowed."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1736,7 +1726,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) } else if (prop == "NAME") { - cmOStringStream e; + std::ostringstream e; e << "NAME property is read-only\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; @@ -1779,7 +1769,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) } else if(prop == "EXPORT_NAME" && this->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "EXPORT_NAME property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1795,7 +1785,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) { if(this->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "SOURCES property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1823,7 +1813,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, if (this->GetType() == INTERFACE_LIBRARY && !whiteListedInterfaceProperty(prop)) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " "The property \"" << prop << "\" is not allowed."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1831,7 +1821,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, } else if (prop == "NAME") { - cmOStringStream e; + std::ostringstream e; e << "NAME property is read-only\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; @@ -1866,7 +1856,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, } else if(prop == "EXPORT_NAME" && this->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "EXPORT_NAME property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1881,7 +1871,7 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value, { if(this->IsImported()) { - cmOStringStream e; + std::ostringstream e; e << "SOURCES property can't be set on imported targets (\"" << this->Name << "\")\n"; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -1910,7 +1900,7 @@ std::string cmTarget::GetExportName() const { if (!cmGeneratorExpression::IsValidTargetName(exportName)) { - cmOStringStream e; + std::ostringstream e; e << "EXPORT_NAME property \"" << exportName << "\" for \"" << this->GetName() << "\": is not valid."; cmSystemTools::Error(e.str().c_str()); @@ -2022,7 +2012,7 @@ static void processIncludeDirectories(cmTarget const* tgt, if (fromImported && !cmSystemTools::FileExists(li->c_str())) { - cmOStringStream e; + std::ostringstream e; cmake::MessageType messageType = cmake::FATAL_ERROR; if (checkCMP0027) { @@ -2055,7 +2045,7 @@ static void processIncludeDirectories(cmTarget const* tgt, if (!cmSystemTools::FileIsFullPath(li->c_str())) { - cmOStringStream e; + std::ostringstream e; bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; if (!targetName.empty()) @@ -2405,7 +2395,7 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, { case cmPolicies::WARN: { - cmOStringStream e; + std::ostringstream e; e << this->Makefile->GetCMakeInstance()->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0043); this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, @@ -2538,7 +2528,7 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES( "LINK_INTERFACE_LIBRARIES"); // Report an error. - cmOStringStream e; + std::ostringstream e; e << "Property " << prop << " may not contain link-type keyword \"" << keys.match(2) << "\". " << "The " << base << " property has a per-configuration " @@ -2575,7 +2565,7 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value, } // Report an error. - cmOStringStream e; + std::ostringstream e; e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type " "keyword \"" << keys.match(2) << "\". The INTERFACE_LINK_LIBRARIES " @@ -2874,7 +2864,7 @@ bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const { return true; } - cmOStringStream e; + std::ostringstream e; const char *modal = 0; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch (context->GetPolicyStatus(cmPolicies::CMP0026)) @@ -2933,7 +2923,7 @@ const char *cmTarget::GetProperty(const std::string& prop, if (this->GetType() == INTERFACE_LIBRARY && !whiteListedInterfaceProperty(prop)) { - cmOStringStream e; + std::ostringstream e; e << "INTERFACE_LIBRARY targets may only have whitelisted properties. " "The property \"" << prop << "\" is not allowed."; context->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -3109,7 +3099,7 @@ const char *cmTarget::GetProperty(const std::string& prop, return 0; } - cmOStringStream ss; + std::ostringstream ss; const char* sep = ""; typedef cmTargetInternals::TargetPropertyEntry TargetPropertyEntry; @@ -3139,7 +3129,7 @@ const char *cmTarget::GetProperty(const std::string& prop, bool addContent = false; bool noMessage = true; - cmOStringStream e; + std::ostringstream e; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(context->GetPolicyStatus(cmPolicies::CMP0051)) { @@ -3237,7 +3227,7 @@ public: { bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; - cmOStringStream e; + std::ostringstream e; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028)) { case cmPolicies::WARN: @@ -3358,7 +3348,7 @@ public: } else if(this->Preferred.size() > 1) { - cmOStringStream e; + std::ostringstream e; e << "Target " << this->Target->GetName() << " contains multiple languages with the highest linker preference" << " (" << this->Preference << "):\n"; @@ -3730,7 +3720,7 @@ bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG")) { - cmOStringStream w; + std::ostringstream w; w << "Attempting to use"; if(macosx_rpath) { @@ -4036,15 +4026,8 @@ void cmTarget::GetFullNameInternal(const std::string& config, if(this->IsCFBundleOnApple()) { - fw_prefix = this->GetOutputName(config, false); - fw_prefix += "."; - const char *ext = this->GetProperty("BUNDLE_EXTENSION"); - if (!ext) - { - ext = "bundle"; - } - fw_prefix += ext; - fw_prefix += "/Contents/MacOS/"; + fw_prefix = this->GetCFBundleDirectory(config, false); + fw_prefix += "/"; targetPrefix = fw_prefix.c_str(); targetSuffix = 0; } @@ -4713,7 +4696,7 @@ const char* cmTarget::GetExportMacro() const { std::string in = this->GetName(); in += "_EXPORTS"; - this->ExportMacro = cmSystemTools::MakeCindentifier(in.c_str()); + this->ExportMacro = cmSystemTools::MakeCindentifier(in); } return this->ExportMacro.c_str(); } @@ -4781,16 +4764,6 @@ std::pair<bool, const char*> consistentStringProperty(const char *lhs, return std::make_pair(b, b ? lhs : 0); } -#if defined(_MSC_VER) && _MSC_VER <= 1200 -template<typename T> const T& -cmMaximum(const T& l, const T& r) {return l > r ? l : r;} -template<typename T> const T& -cmMinimum(const T& l, const T& r) {return l < r ? l : r;} -#else -#define cmMinimum std::min -#define cmMaximum std::max -#endif - //---------------------------------------------------------------------------- std::pair<bool, const char*> consistentNumberProperty(const char *lhs, const char *rhs, @@ -4798,11 +4771,7 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs, { char *pEnd; -#if defined(_MSC_VER) - static const char* const null_ptr = 0; -#else -# define null_ptr 0 -#endif + const char* const null_ptr = 0; long lnum = strtol(lhs, &pEnd, 0); if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) @@ -4816,17 +4785,13 @@ std::pair<bool, const char*> consistentNumberProperty(const char *lhs, return std::pair<bool, const char*>(false, null_ptr); } -#if !defined(_MSC_VER) -#undef null_ptr -#endif - if (t == NumberMaxType) { - return std::make_pair(true, cmMaximum(lnum, rnum) == lnum ? lhs : rhs); + return std::make_pair(true, std::max(lnum, rnum) == lnum ? lhs : rhs); } else { - return std::make_pair(true, cmMinimum(lnum, rnum) == lnum ? lhs : rhs); + return std::make_pair(true, std::min(lnum, rnum) == lnum ? lhs : rhs); } } @@ -4849,16 +4814,12 @@ std::pair<bool, const char*> consistentProperty(const char *lhs, return std::make_pair(true, lhs); } -#if defined(_MSC_VER) - static const char* const null_ptr = 0; -#else -# define null_ptr 0 -#endif + const char* const null_ptr = 0; switch(t) { case BoolType: - assert(!"consistentProperty for strings called with BoolType"); + assert(0 && "consistentProperty for strings called with BoolType"); return std::pair<bool, const char*>(false, null_ptr); case StringType: return consistentStringProperty(lhs, rhs); @@ -4866,13 +4827,8 @@ std::pair<bool, const char*> consistentProperty(const char *lhs, case NumberMaxType: return consistentNumberProperty(lhs, rhs, t); } - assert(!"Unreachable!"); + assert(0 && "Unreachable!"); return std::pair<bool, const char*>(false, null_ptr); - -#if !defined(_MSC_VER) -#undef null_ptr -#endif - } template<typename PropertyType> @@ -4956,7 +4912,7 @@ std::string compatibilityType(CompatibleType t) case NumberMinType: return "Numeric minimum compatibility"; } - assert(!"Unreachable!"); + assert(0 && "Unreachable!"); return ""; } @@ -4972,7 +4928,7 @@ std::string compatibilityAgree(CompatibleType t, bool dominant) case NumberMinType: return dominant ? "(Dominant)\n" : "(Ignored)\n"; } - assert(!"Unreachable!"); + assert(0 && "Unreachable!"); return ""; } @@ -5062,7 +5018,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, report += compatibilityAgree(t, propContent != consistent.second); if (!consistent.first) { - cmOStringStream e; + std::ostringstream e; e << "Property " << p << " on target \"" << tgt->GetName() << "\" does\nnot match the " "INTERFACE_" << p << " property requirement\nof " @@ -5095,7 +5051,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, report += compatibilityAgree(t, propContent != consistent.second); if (!consistent.first) { - cmOStringStream e; + std::ostringstream e; e << "Property " << p << " on target \"" << tgt->GetName() << "\" is\nimplied to be " << defaultValue << " because it was used to determine the link libraries\n" @@ -5129,7 +5085,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, report += compatibilityAgree(t, propContent != consistent.second); if (!consistent.first) { - cmOStringStream e; + std::ostringstream e; e << "The INTERFACE_" << p << " property of \"" << theTarget->GetName() << "\" does\nnot agree with the value " "of " << p << " already determined\nfor \"" @@ -6037,7 +5993,7 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( if (newExplicitLibraries && strcmp(newExplicitLibraries, explicitLibraries) != 0) { - cmOStringStream w; + std::ostringstream w; w << (thisTarget->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" @@ -6083,8 +6039,8 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( // The link implementation is the default link interface. cmTarget::LinkImplementationLibraries const* impl = thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); - std::copy(impl->Libraries.begin(), impl->Libraries.end(), - std::back_inserter(iface.Libraries)); + iface.Libraries.insert(iface.Libraries.end(), + impl->Libraries.begin(), impl->Libraries.end()); if(thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN && !this->PolicyWarnedCMP0022 && !usage_requirements_only) { @@ -6101,30 +6057,14 @@ cmTargetInternals::ComputeLinkInterfaceLibraries( } if (ifaceLibs != iface.Libraries) { - std::string oldLibraries; - std::string newLibraries; - const char *sep = ""; - for(std::vector<cmLinkImplItem>::const_iterator it - = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) - { - oldLibraries += sep; - oldLibraries += *it; - sep = ";"; - } - sep = ""; - for(std::vector<cmLinkItem>::const_iterator it - = ifaceLibs.begin(); it != ifaceLibs.end(); ++it) - { - newLibraries += sep; - newLibraries += *it; - sep = ";"; - } + std::string oldLibraries = cmJoin(impl->Libraries, ";"); + std::string newLibraries = cmJoin(ifaceLibs, ";"); if(oldLibraries.empty()) { oldLibraries = "(empty)"; } if(newLibraries.empty()) { newLibraries = "(empty)"; } - cmOStringStream w; + std::ostringstream w; w << (thisTarget->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n" @@ -6379,7 +6319,7 @@ cmTargetInternals::ComputeLinkImplementationLibraries( { bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; - cmOStringStream e; + std::ostringstream e; switch(thisTarget->GetPolicyStatusCMP0038()) { case cmPolicies::WARN: @@ -6462,11 +6402,8 @@ cmTargetInternals::ComputeLinkImplementationLanguages( // Get languages used in our source files. thisTarget->GetLanguages(languages, config); // Copy the set of langauges to the link implementation. - for(std::set<std::string>::iterator li = languages.begin(); - li != languages.end(); ++li) - { - impl.Languages.push_back(*li); - } + impl.Languages.insert(impl.Languages.begin(), + languages.begin(), languages.end()); } //---------------------------------------------------------------------------- @@ -6485,7 +6422,7 @@ cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << this->GetName() << "\" links to " "OBJECT library \"" << tgt->GetName() << "\" but this is not " "allowed. " @@ -6524,7 +6461,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const { case cmPolicies::WARN: { - cmOStringStream w; + std::ostringstream w; w << (this->Makefile->GetPolicies() ->GetPolicyWarning(cmPolicies::CMP0004)) << "\n" << "Target \"" << this->GetName() << "\" links to item \"" @@ -6536,7 +6473,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const break; case cmPolicies::NEW: { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << this->GetName() << "\" links to item \"" << item << "\" which has leading or trailing whitespace. " << "This is now an error according to policy CMP0004."; @@ -6546,7 +6483,7 @@ std::string cmTarget::CheckCMP0004(std::string const& item) const case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: { - cmOStringStream e; + std::ostringstream e; e << (this->Makefile->GetPolicies() ->GetRequiredPolicyError(cmPolicies::CMP0004)) << "\n" << "Target \"" << this->GetName() << "\" links to item \"" @@ -6585,7 +6522,7 @@ const char * getLinkInterfaceDependentProperty(cmTarget const* tgt, switch(t) { case BoolType: - assert(!"String compatibility check function called for boolean"); + assert(0 && "String compatibility check function called for boolean"); return 0; case StringType: return tgt->GetLinkInterfaceDependentStringProperty(prop, config); @@ -6594,7 +6531,7 @@ const char * getLinkInterfaceDependentProperty(cmTarget const* tgt, case NumberMaxType: return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config); } - assert(!"Unreachable!"); + assert(0 && "Unreachable!"); return 0; } @@ -6627,7 +6564,7 @@ void checkPropertyConsistency(cmTarget const* depender, std::string pfile = pdir + pname + ".rst"; if(cmSystemTools::FileExists(pfile.c_str(), true)) { - cmOStringStream e; + std::ostringstream e; e << "Target \"" << dependee->GetName() << "\" has property \"" << *pi << "\" listed in its " << propName << " property. " "This is not allowed. Only user-defined properties may appear " @@ -6789,7 +6726,7 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, { propsString += " and the " + *props.begin(); } - cmOStringStream e; + std::ostringstream e; e << "Property \"" << prop << "\" appears in both the " << propsString << " property in the dependencies of target \"" << this->GetName() << @@ -6932,10 +6869,7 @@ cmTargetLinkInformationMap //---------------------------------------------------------------------------- cmTargetLinkInformationMap::~cmTargetLinkInformationMap() { - for(derived::iterator i = this->begin(); i != this->end(); ++i) - { - delete i->second; - } + cmDeleteAll(*this); } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a3ecca0..ddd9859 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -202,7 +202,7 @@ public: PlainTLLSignature }; bool PushTLLCommandTrace(TLLSignature signature); - void GetTllSignatureTraces(cmOStringStream &s, TLLSignature sig) const; + void GetTllSignatureTraces(std::ostringstream &s, TLLSignature sig) const; void MergeLinkLibraries( cmMakefile& mf, const std::string& selfname, const LinkLibraryVectorType& libs ); diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index 66d8ad3..dc19720 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -20,7 +20,7 @@ bool cmTargetCompileDefinitionsCommand void cmTargetCompileDefinitionsCommand ::HandleImportedTarget(const std::string &tgt) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile definitions for imported target \"" << tgt << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -29,7 +29,7 @@ void cmTargetCompileDefinitionsCommand void cmTargetCompileDefinitionsCommand ::HandleMissingTarget(const std::string &name) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile definitions for target \"" << name << "\" " "which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index 10daad4..6ebc31e 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -21,7 +21,7 @@ bool cmTargetCompileFeaturesCommand::InitialPass( void cmTargetCompileFeaturesCommand ::HandleImportedTarget(const std::string &tgt) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile features for imported target \"" << tgt << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -30,7 +30,7 @@ void cmTargetCompileFeaturesCommand void cmTargetCompileFeaturesCommand ::HandleMissingTarget(const std::string &name) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile features for target \"" << name << "\" " "which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -40,15 +40,7 @@ void cmTargetCompileFeaturesCommand std::string cmTargetCompileFeaturesCommand ::Join(const std::vector<std::string> &content) { - std::string defs; - std::string sep; - for(std::vector<std::string>::const_iterator it = content.begin(); - it != content.end(); ++it) - { - defs += sep + *it; - sep = ";"; - } - return defs; + return cmJoin(content, ";"); } //---------------------------------------------------------------------------- diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index 3fb76a6..8c6fc06 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -20,7 +20,7 @@ bool cmTargetCompileOptionsCommand void cmTargetCompileOptionsCommand ::HandleImportedTarget(const std::string &tgt) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile options for imported target \"" << tgt << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -29,7 +29,7 @@ void cmTargetCompileOptionsCommand void cmTargetCompileOptionsCommand ::HandleMissingTarget(const std::string &name) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify compile options for target \"" << name << "\" " "which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -39,15 +39,7 @@ void cmTargetCompileOptionsCommand std::string cmTargetCompileOptionsCommand ::Join(const std::vector<std::string> &content) { - std::string defs; - std::string sep; - for(std::vector<std::string>::const_iterator it = content.begin(); - it != content.end(); ++it) - { - defs += sep + *it; - sep = ";"; - } - return defs; + return cmJoin(content, ";"); } //---------------------------------------------------------------------------- diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index e9f0e04..b638e57 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -25,7 +25,7 @@ bool cmTargetIncludeDirectoriesCommand void cmTargetIncludeDirectoriesCommand ::HandleImportedTarget(const std::string &tgt) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify include directories for imported target \"" << tgt << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -35,7 +35,7 @@ void cmTargetIncludeDirectoriesCommand void cmTargetIncludeDirectoriesCommand ::HandleMissingTarget(const std::string &name) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify include directories for target \"" << name << "\" " "which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -91,15 +91,7 @@ void cmTargetIncludeDirectoriesCommand if (system) { - std::string joined; - std::string sep; - for(std::vector<std::string>::const_iterator it = content.begin(); - it != content.end(); ++it) - { - joined += sep; - sep = ";"; - joined += *it; - } + std::string joined = cmJoin(content, ";"); tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined.c_str()); } diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 56e1338..75c94c5 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -43,7 +43,7 @@ bool cmTargetLinkLibrariesCommand if(!this->Target) { cmake::MessageType t = cmake::FATAL_ERROR; // fail by default - cmOStringStream e; + std::ostringstream e; e << "Cannot specify link libraries for target \"" << args[0] << "\" " << "which is not built by this project."; // The bad target is the only argument. Check how policy CMP0016 is set, @@ -92,7 +92,7 @@ bool cmTargetLinkLibrariesCommand if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY) { - cmOStringStream e; + std::ostringstream e; e << "Object library target \"" << args[0] << "\" " << "may not link to anything."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -102,7 +102,7 @@ bool cmTargetLinkLibrariesCommand if (this->Target->GetType() == cmTarget::UTILITY) { - cmOStringStream e; + std::ostringstream e; const char *modal = 0; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0039)) @@ -311,7 +311,7 @@ bool cmTargetLinkLibrariesCommand // Make sure the last argument was not a library type specifier. if(haveLLT) { - cmOStringStream e; + std::ostringstream e; e << "The \"" << this->LinkLibraryTypeNames[llt] << "\" argument must be followed by a library."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -342,7 +342,7 @@ void cmTargetLinkLibrariesCommand ::LinkLibraryTypeSpecifierWarning(int left, int right) { - cmOStringStream w; + std::ostringstream w; w << "Link library type specifier \"" << this->LinkLibraryTypeNames[left] << "\" is followed by specifier \"" << this->LinkLibraryTypeNames[right] << "\" instead of a library name. " @@ -373,7 +373,7 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib, ? cmTarget::KeywordTLLSignature : cmTarget::PlainTLLSignature; if (!this->Target->PushTLLCommandTrace(sig)) { - cmOStringStream e; + std::ostringstream e; const char *modal = 0; cmake::MessageType messageType = cmake::AUTHOR_WARNING; switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0023)) diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index ce3b11e..0a44d6f 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -24,7 +24,7 @@ bool cmTargetSourcesCommand void cmTargetSourcesCommand ::HandleImportedTarget(const std::string &tgt) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify sources for imported target \"" << tgt << "\"."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -34,7 +34,7 @@ void cmTargetSourcesCommand void cmTargetSourcesCommand ::HandleMissingTarget(const std::string &name) { - cmOStringStream e; + std::ostringstream e; e << "Cannot specify sources for target \"" << name << "\" " "which is not built by this project."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); @@ -44,15 +44,7 @@ void cmTargetSourcesCommand std::string cmTargetSourcesCommand ::Join(const std::vector<std::string> &content) { - std::string srcs; - std::string sep; - for(std::vector<std::string>::const_iterator it = content.begin(); - it != content.end(); ++it) - { - srcs += sep + *it; - sep = ";"; - } - return srcs; + return cmJoin(content, ";"); } //---------------------------------------------------------------------------- diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 8f2deeb..3daf61e 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -104,8 +104,8 @@ bool cmTryRunCommand // although they could be used together, don't allow it, because // using OUTPUT_VARIABLE makes crosscompiling harder if (this->OutputVariable.size() - && ((this->RunOutputVariable.size()) - || (this->CompileOutputVariable.size()))) + && (!this->RunOutputVariable.empty() + || !this->CompileOutputVariable.empty())) { cmSystemTools::Error( "You cannot use OUTPUT_VARIABLE together with COMPILE_OUTPUT_VARIABLE " @@ -115,18 +115,18 @@ bool cmTryRunCommand } bool captureRunOutput = false; - if (this->OutputVariable.size()) + if (!this->OutputVariable.empty()) { captureRunOutput = true; tryCompile.push_back("OUTPUT_VARIABLE"); tryCompile.push_back(this->OutputVariable); } - if (this->CompileOutputVariable.size()) + if (!this->CompileOutputVariable.empty()) { tryCompile.push_back("OUTPUT_VARIABLE"); tryCompile.push_back(this->CompileOutputVariable); } - if (this->RunOutputVariable.size()) + if (!this->RunOutputVariable.empty()) { captureRunOutput = true; } @@ -140,7 +140,7 @@ bool cmTryRunCommand // now try running the command if it compiled if (!res) { - if (this->OutputFile.size() == 0) + if (this->OutputFile.empty()) { cmSystemTools::Error(this->FindErrorMessage.c_str()); } @@ -160,13 +160,13 @@ bool cmTryRunCommand } // now put the output into the variables - if(this->RunOutputVariable.size()) + if(!this->RunOutputVariable.empty()) { this->Makefile->AddDefinition(this->RunOutputVariable, runOutputContents.c_str()); } - if(this->OutputVariable.size()) + if(!this->OutputVariable.empty()) { // if the TryCompileCore saved output in this outputVariable then // prepend that output to this output @@ -196,7 +196,7 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs, int retVal = -1; std::string finalCommand = cmSystemTools::ConvertToRunCommandPath( this->OutputFile.c_str()); - if (runArgs.size()) + if (!runArgs.empty()) { finalCommand += runArgs; } diff --git a/Source/cmUseMangledMesaCommand.cxx b/Source/cmUseMangledMesaCommand.cxx index 8d26f86..2ee664f 100644 --- a/Source/cmUseMangledMesaCommand.cxx +++ b/Source/cmUseMangledMesaCommand.cxx @@ -44,7 +44,7 @@ bool cmUseMangledMesaCommand const char* destDir = args[1].c_str(); std::vector<std::string> files; cmSystemTools::Glob(inputDir, "\\.h$", files); - if(files.size() == 0) + if(files.empty()) { cmSystemTools::Error("Could not open Mesa Directory ", inputDir); return false; diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index ba6b4ac..ee1ff29 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -95,7 +95,7 @@ bool cmUtilitySourceCommand { exePath = this->Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"); } - if(exePath.size()) + if(!exePath.empty()) { utilityDirectory = exePath; } diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx index 8b5b7ae..e2d0049 100644 --- a/Source/cmUuid.cxx +++ b/Source/cmUuid.cxx @@ -66,7 +66,7 @@ void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace, { output = uuidNamespace; - if(name.size()) + if(!name.empty()) { output.resize(output.size() + name.size()); diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index cb6cb12..b8a6df2 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -34,21 +34,16 @@ cmVariableWatch::cmVariableWatch() { } -cmVariableWatch::~cmVariableWatch() +template<typename C> +void deleteAllSecond(typename C::value_type it) { - cmVariableWatch::StringToVectorOfPairs::iterator svp_it; - - for ( svp_it = this->WatchMap.begin(); - svp_it != this->WatchMap.end(); ++svp_it ) - { - cmVariableWatch::VectorOfPairs::iterator p_it; + cmDeleteAll(it.second); +} - for ( p_it = svp_it->second.begin(); - p_it != svp_it->second.end(); ++p_it ) - { - delete *p_it; - } - } +cmVariableWatch::~cmVariableWatch() +{ + std::for_each(this->WatchMap.begin(), this->WatchMap.end(), + deleteAllSecond<cmVariableWatch::StringToVectorOfPairs>); } bool cmVariableWatch::AddWatch(const std::string& variable, diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index debe243..9473008 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -70,7 +70,7 @@ static void cmVariableWatchCommandVariableAccessed( { arg.FilePath = "Unknown"; arg.Line = 0; - cmOStringStream error; + std::ostringstream error; error << "Error in cmake code at\n" << arg.FilePath << ":" << arg.Line << ":\n" << "A command failed during the invocation of callback \"" @@ -83,7 +83,7 @@ static void cmVariableWatchCommandVariableAccessed( } if ( !processed ) { - cmOStringStream msg; + std::ostringstream msg; msg << "Variable \"" << variable << "\" was accessed using " << accessString << " with value \"" << (newValue?newValue:"") << "\"."; makefile->IssueMessage(cmake::LOG, msg.str()); @@ -135,7 +135,7 @@ bool cmVariableWatchCommand } if ( variable == "CMAKE_CURRENT_LIST_FILE" ) { - cmOStringStream ostr; + std::ostringstream ostr; ostr << "cannot be set on the variable: " << variable; this->SetError(ostr.str()); return false; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 26fc317..b265c0e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -307,7 +307,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->BuildFileStream->SetCopyIfDifferent(true); // Write the encoding header into the file - char magic[] = {0xEF,0xBB, 0xBF}; + char magic[] = {char(0xEF), char(0xBB), char(0xBF)}; this->BuildFileStream->write(magic, 3); //get the tools version to use @@ -326,9 +326,9 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1); if(this->NsightTegraVersion[0] >= 2) { - // Nsight Tegra 2.0 uses project revision 8. + // Nsight Tegra 2.0 uses project revision 9. this->WriteString("<NsightTegraProjectRevisionNumber>" - "8" + "9" "</NsightTegraProjectRevisionNumber>\n", 2); // Tell newer versions to upgrade silently when loading. this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>" @@ -748,6 +748,12 @@ void cmVisualStudio10TargetGenerator ntv += toolset? toolset : "Default"; ntv += "</NdkToolchainVersion>\n"; this->WriteString(ntv.c_str(), 2); + if(const char* minApi = this->Target->GetProperty("ANDROID_API_MIN")) + { + this->WriteString("<AndroidMinAPI>", 2); + (*this->BuildFileStream ) << + "android-" << cmVS10EscapeXML(minApi) << "</AndroidMinAPI>\n"; + } if(const char* api = this->Target->GetProperty("ANDROID_API")) { this->WriteString("<AndroidTargetAPI>", 2); @@ -937,7 +943,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() path += ".vcxproj.filters"; cmGeneratedFileStream fout(path.c_str()); fout.SetCopyIfDifferent(true); - char magic[] = {0xEF,0xBB, 0xBF}; + char magic[] = {char(0xEF), char(0xBB), char(0xBF)}; fout.write(magic, 3); cmGeneratedFileStream* save = this->BuildFileStream; this->BuildFileStream = & fout; @@ -1203,6 +1209,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) bool toolHasSettings = false; std::string tool = "None"; std::string shaderType; + std::string shaderEntryPoint; + std::string shaderModel; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); if(ext == "hlsl") { @@ -1213,6 +1221,18 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) shaderType = st; toolHasSettings = true; } + // Figure out which entry point to use if any + if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) + { + shaderEntryPoint = se; + toolHasSettings = true; + } + // Figure out which shader model to use if any + if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) + { + shaderModel = sm; + toolHasSettings = true; + } } else if(ext == "jpg" || ext == "png") @@ -1247,6 +1267,7 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) } std::string deployContent; + std::string deployLocation; if(this->GlobalGenerator->TargetsWindowsPhone() || this->GlobalGenerator->TargetsWindowsStore()) { @@ -1255,6 +1276,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) { toolHasSettings = true; deployContent = content; + + const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION"); + if(location && *location) + { + deployLocation = location; + } } } @@ -1269,6 +1296,14 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) cmGeneratorExpression ge; cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(deployContent); + // Deployment location cannot be set on a configuration basis + if(!deployLocation.empty()) + { + this->WriteString("<Link>", 3); + (*this->BuildFileStream) << deployLocation + << "\\%(FileName)%(Extension)"; + this->WriteString("</Link>\n", 0); + } for(size_t i = 0; i != configs->size(); ++i) { if(0 == strcmp(cge->Evaluate(this->Makefile, (*configs)[i]), "1")) @@ -1295,7 +1330,18 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) (*this->BuildFileStream) << cmVS10EscapeXML(shaderType) << "</ShaderType>\n"; } - + if(!shaderEntryPoint.empty()) + { + this->WriteString("<EntryPointName>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(shaderEntryPoint) + << "</EntryPointName>\n"; + } + if(!shaderModel.empty()) + { + this->WriteString("<ShaderModel>", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(shaderModel) + << "</ShaderModel>\n"; + } this->WriteString("</", 2); (*this->BuildFileStream) << tool << ">\n"; } @@ -1597,6 +1643,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( clOptions.AppendFlag("AdditionalIncludeDirectories", "%(AdditionalIncludeDirectories)"); } + if(clOptions.HasFlag("DisableSpecificWarnings")) + { + clOptions.AppendFlag("DisableSpecificWarnings", + "%(DisableSpecificWarnings)"); + } clOptions.AddDefines(configDefines.c_str()); clOptions.SetConfiguration((*config).c_str()); clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); @@ -2036,7 +2087,8 @@ WriteMasmOptions(std::string const& configName, void cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config) { - if(this->Target->GetType() != cmTarget::STATIC_LIBRARY) + if(this->Target->GetType() != cmTarget::STATIC_LIBRARY && + this->Target->GetType() != cmTarget::OBJECT_LIBRARY) { return; } @@ -2267,7 +2319,14 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) linkOptions.AddFlag("SubSystem", "WindowsCE"); if (this->Target->GetType() == cmTarget::EXECUTABLE) { - linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); + if (this->ClOptions[config]->UsingUnicode()) + { + linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup"); + } + else + { + linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); + } } } else @@ -2282,7 +2341,14 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) linkOptions.AddFlag("SubSystem", "WindowsCE"); if (this->Target->GetType() == cmTarget::EXECUTABLE) { - linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); + if (this->ClOptions[config]->UsingUnicode()) + { + linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup"); + } + else + { + linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); + } } } else diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index cdc8879..00386f6 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -28,6 +28,26 @@ std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret) cmVisualStudioGeneratorOptions ::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg, Tool tool, + cmVisualStudio10TargetGenerator* g): + cmIDEOptions(), + LocalGenerator(lg), Version(lg->GetVersion()), CurrentTool(tool), + TargetGenerator(g) +{ + // Preprocessor definitions are not allowed for linker tools. + this->AllowDefine = (tool != Linker); + + // Slash options are allowed for VS. + this->AllowSlash = true; + + this->FortranRuntimeDebug = false; + this->FortranRuntimeDLL = false; + this->FortranRuntimeMT = false; +} + +//---------------------------------------------------------------------------- +cmVisualStudioGeneratorOptions +::cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg, + Tool tool, cmVS7FlagTable const* table, cmVS7FlagTable const* extraTable, cmVisualStudio10TargetGenerator* g): @@ -36,9 +56,8 @@ cmVisualStudioGeneratorOptions TargetGenerator(g) { // Store the given flag tables. - cmIDEFlagTable const** ft = this->FlagTable; - if(table) { *ft++ = table; } - if(extraTable) { *ft++ = extraTable; } + this->AddTable(table); + this->AddTable(extraTable); // Preprocessor definitions are not allowed for linker tools. this->AllowDefine = (tool != Linker); @@ -52,6 +71,22 @@ cmVisualStudioGeneratorOptions } //---------------------------------------------------------------------------- +void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table) +{ + if(table) + { + for(int i=0; i < FlagTableCount; ++i) + { + if (!this->FlagTable[i]) + { + this->FlagTable[i] = table; + break; + } + } + } +} + +//---------------------------------------------------------------------------- void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault() { // Exception handling is on by default because the platform file has diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h index 9951033..5490a43 100644 --- a/Source/cmVisualStudioGeneratorOptions.h +++ b/Source/cmVisualStudioGeneratorOptions.h @@ -38,6 +38,13 @@ public: cmVS7FlagTable const* extraTable = 0, cmVisualStudio10TargetGenerator* g = 0); + cmVisualStudioGeneratorOptions(cmLocalVisualStudioGenerator* lg, + Tool tool, + cmVisualStudio10TargetGenerator* g = 0); + + // Add a table of flags. + void AddTable(cmVS7FlagTable const* table); + // Store options from command line flags. void Parse(const char* flags); void ParseFinish(); diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx index 851c4cb..5170ead 100644 --- a/Source/cmWhileCommand.cxx +++ b/Source/cmWhileCommand.cxx @@ -27,6 +27,8 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endwhile for this while loop then execute if (!this->Depth) { + cmMakefile::LoopBlockPop loopBlockPop(&mf); + // Remove the function blocker for this scope or bail. cmsys::auto_ptr<cmFunctionBlocker> fb(mf.RemoveFunctionBlocker(this, lff)); @@ -45,7 +47,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, while (isTrue) { - if (errorString.size()) + if (!errorString.empty()) { std::string err = "had incorrect arguments: "; unsigned int i; @@ -81,6 +83,10 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, { return true; } + if (status.GetContinueInvoked()) + { + break; + } if(cmSystemTools::GetFatalErrorOccured() ) { return true; @@ -114,7 +120,7 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile& ) { // if the endwhile has arguments, then make sure // they match the arguments of the matching while - if (lff.Arguments.size() == 0 || + if (lff.Arguments.empty() || lff.Arguments == this->Args) { return true; @@ -138,6 +144,8 @@ bool cmWhileCommand f->Args = args; this->Makefile->AddFunctionBlocker(f); + this->Makefile->PushLoopBlock(); + return true; } diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx index 391b874..1d3e0e9 100644 --- a/Source/cmXMLParser.cxx +++ b/Source/cmXMLParser.cxx @@ -54,7 +54,7 @@ int cmXMLParser::ParseFile(const char* file) return 0; } - cmOStringStream str; + std::ostringstream str; str << ifs.rdbuf(); return this->Parse(str.str().c_str()); } diff --git a/Source/cmStandardIncludes.cxx b/Source/cm_get_date.c index a4bdb2e..2e0d4bd 100644 --- a/Source/cmStandardIncludes.cxx +++ b/Source/cm_get_date.c @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2000-2010 Kitware, Inc., Insight Software Consortium + Copyright 2000-2015 Kitware, Inc. Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#include "cmStandardIncludes.h" -#if !defined(CMAKE_NO_ANSI_STRING_STREAM) -cmOStringStream::cmOStringStream() {} -cmOStringStream::~cmOStringStream() {} -#endif +#include "cm_get_date.h" + +#define __archive_get_date cm_get_date + +#include "../Utilities/cmlibarchive/libarchive/archive_getdate.c" diff --git a/Source/cm_get_date.h b/Source/cm_get_date.h new file mode 100644 index 0000000..d5f6d3e --- /dev/null +++ b/Source/cm_get_date.h @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cm_get_date_h +#define cm_get_date_h + +#include <time.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** Parse a date/time string. Treat relative times with respect to 'now'. */ +time_t cm_get_date(time_t now, const char *str); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c index 4738920..b90e060 100644 --- a/Source/cm_sha2.c +++ b/Source/cm_sha2.c @@ -663,7 +663,7 @@ void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) { context->s1.bitcount += freespace << 3; len -= freespace; data += freespace; - SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len); @@ -675,7 +675,7 @@ void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) { } while (len >= 64) { /* Process as many complete blocks as we can */ - SHA1_Internal_Transform(context, (sha_word32*)data); + SHA1_Internal_Transform(context, (const sha_word32*)data); context->s1.bitcount += 512; len -= 64; data += 64; @@ -724,7 +724,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) { MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace); } /* Do second-to-last transform: */ - SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->s1.buffer, 56); @@ -741,7 +741,7 @@ void SHA1_Final(sha_byte digest[], SHA_CTX* context) { sizeof(sha_word64)); /* Final transform: */ - SHA1_Internal_Transform(context, (sha_word32*)context->s1.buffer); + SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN @@ -1004,7 +1004,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { context->s256.bitcount += freespace << 3; len -= freespace; data += freespace; - SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); + SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len); @@ -1016,7 +1016,7 @@ void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) { } while (len >= 64) { /* Process as many complete blocks as we can */ - SHA256_Internal_Transform(context, (sha_word32*)data); + SHA256_Internal_Transform(context, (const sha_word32*)data); context->s256.bitcount += 512; len -= 64; data += 64; @@ -1050,7 +1050,7 @@ void SHA256_Internal_Last(SHA_CTX* context) { MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace); } /* Do second-to-last transform: */ - SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); + SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->s256.buffer, 56); @@ -1069,7 +1069,7 @@ void SHA256_Internal_Last(SHA_CTX* context) { sizeof(sha_word64)); /* Final transform: */ - SHA256_Internal_Transform(context, (sha_word32*)context->s256.buffer); + SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer); } void SHA256_Final(sha_byte digest[], SHA_CTX* context) { @@ -1412,7 +1412,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { ADDINC128(context->s512.bitcount, freespace << 3); len -= freespace; data += freespace; - SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); + SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len); @@ -1424,7 +1424,7 @@ void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) { } while (len >= 128) { /* Process as many complete blocks as we can */ - SHA512_Internal_Transform(context, (sha_word64*)data); + SHA512_Internal_Transform(context, (const sha_word64*)data); ADDINC128(context->s512.bitcount, 1024); len -= 128; data += 128; @@ -1459,7 +1459,7 @@ void SHA512_Internal_Last(SHA_CTX* context) { MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace); } /* Do second-to-last transform: */ - SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); + SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->s512.buffer, 112); @@ -1480,7 +1480,7 @@ void SHA512_Internal_Last(SHA_CTX* context) { sizeof(sha_word64)); /* Final transform: */ - SHA512_Internal_Transform(context, (sha_word64*)context->s512.buffer); + SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer); } void SHA512_Final(sha_byte digest[], SHA_CTX* context) { diff --git a/Source/cmake.cxx b/Source/cmake.cxx index dc1b113..29d8206 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -171,16 +171,8 @@ cmake::~cmake() delete this->GlobalGenerator; this->GlobalGenerator = 0; } - for(RegisteredCommandsMap::iterator j = this->Commands.begin(); - j != this->Commands.end(); ++j) - { - delete (*j).second; - } - for(RegisteredGeneratorsVector::iterator j = this->Generators.begin(); - j != this->Generators.end(); ++j) - { - delete *j; - } + cmDeleteAll(this->Commands); + cmDeleteAll(this->Generators); #ifdef CMAKE_BUILD_WITH_CMAKE delete this->VariableWatch; #endif @@ -324,7 +316,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) if(arg.find("-D",0) == 0) { std::string entry = arg.substr(2); - if(entry.size() == 0) + if(entry.empty()) { ++i; if(i < args.size()) @@ -388,7 +380,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) else if(arg.find("-U",0) == 0) { std::string entryPattern = arg.substr(2); - if(entryPattern.size() == 0) + if(entryPattern.empty()) { ++i; if(i < args.size()) @@ -432,7 +424,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) else if(arg.find("-C",0) == 0) { std::string path = arg.substr(2); - if ( path.size() == 0 ) + if (path.empty()) { ++i; if(i < args.size()) @@ -457,7 +449,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) return false; } std::string path = args[i]; - if ( path.size() == 0 ) + if (path.empty()) { cmSystemTools::Error("No cmake script provided."); return false; @@ -771,7 +763,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, else if(arg.find("-A",0) == 0) { std::string value = arg.substr(2); - if(value.size() == 0) + if(value.empty()) { ++i; if(i >= args.size()) @@ -792,7 +784,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, else if(arg.find("-T",0) == 0) { std::string value = arg.substr(2); - if(value.size() == 0) + if(value.empty()) { ++i; if(i >= args.size()) @@ -813,7 +805,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, else if(arg.find("-G",0) == 0) { std::string value = arg.substr(2); - if(value.size() == 0) + if(value.empty()) { ++i; if(i >= args.size()) @@ -917,7 +909,7 @@ void cmake::SetDirectoriesFromFile(const char* arg) } // If there is a CMakeCache.txt file, use its settings. - if(cachePath.length() > 0) + if(!cachePath.empty()) { cmCacheManager* cachem = this->GetCacheManager(); cmCacheManager::CacheIterator it = cachem->NewIterator(); @@ -933,7 +925,7 @@ void cmake::SetDirectoriesFromFile(const char* arg) } // If there is a CMakeLists.txt file, use it as the source tree. - if(listPath.length() > 0) + if(!listPath.empty()) { this->SetHomeDirectory(listPath); this->SetStartDirectory(listPath); @@ -1131,17 +1123,17 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator *gg) // restore the original environment variables CXX and CC // Restore CC std::string env = "CC="; - if(this->CCEnvironment.size()) + if(!this->CCEnvironment.empty()) { env += this->CCEnvironment; } - cmSystemTools::PutEnv(env.c_str()); + cmSystemTools::PutEnv(env); env = "CXX="; - if(this->CXXEnvironment.size()) + if(!this->CXXEnvironment.empty()) { env += this->CXXEnvironment; } - cmSystemTools::PutEnv(env.c_str()); + cmSystemTools::PutEnv(env); } // set the new @@ -1182,7 +1174,7 @@ int cmake::DoPreConfigureChecks() srcList += "/CMakeLists.txt"; if(!cmSystemTools::FileExists(srcList.c_str())) { - cmOStringStream err; + std::ostringstream err; if(cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) { err << "The source directory \"" << this->GetHomeDirectory() @@ -1250,7 +1242,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) } cmCacheManager::CacheIterator ci = this->CacheManager->NewIterator(); std::vector<SaveCacheEntry> saved; - cmOStringStream warning; + std::ostringstream warning; warning << "You have changed variables that require your cache to be deleted.\n" << "Configure will be re-run and you may have to reset some variables.\n" @@ -1401,7 +1393,7 @@ int cmake::ActualConfigure() {"10.0", "Visual Studio 10 2010"}, {"11.0", "Visual Studio 11 2012"}, {"12.0", "Visual Studio 12 2013"}, - {"14.0", "Visual Studio 14"}, + {"14.0", "Visual Studio 14 2015"}, {0, 0}}; for(int i=0; version[i].MSVersion != 0; i++) { @@ -1616,7 +1608,7 @@ void cmake::PreLoadCMakeFiles() { std::vector<std::string> args; std::string pre_load = this->GetHomeDirectory(); - if ( pre_load.size() > 0 ) + if (!pre_load.empty()) { pre_load += "/PreLoad.cmake"; if ( cmSystemTools::FileExists(pre_load.c_str()) ) @@ -1625,7 +1617,7 @@ void cmake::PreLoadCMakeFiles() } } pre_load = this->GetHomeOutputDirectory(); - if ( pre_load.size() > 0 ) + if (!pre_load.empty()) { pre_load += "/PreLoad.cmake"; if ( cmSystemTools::FileExists(pre_load.c_str()) ) @@ -1967,11 +1959,11 @@ int cmake::CheckBuildSystem() // determine whether CMake should rerun. // If no file is provided for the check, we have to rerun. - if(this->CheckBuildSystemArgument.size() == 0) + if(this->CheckBuildSystemArgument.empty()) { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake no build system arguments\n"; cmSystemTools::Stdout(msg.str().c_str()); } @@ -1983,7 +1975,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument << "\n"; cmSystemTools::Stdout(msg.str().c_str()); @@ -2003,7 +1995,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake error reading : " << this->CheckBuildSystemArgument << "\n"; cmSystemTools::Stdout(msg.str().c_str()); @@ -2045,7 +2037,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake, missing byproduct: " << *pi << "\n"; cmSystemTools::Stdout(msg.str().c_str()); } @@ -2068,7 +2060,7 @@ int cmake::CheckBuildSystem() // Not enough information was provided to do the test. Just rerun. if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake no CMAKE_MAKEFILE_DEPENDS " "or CMAKE_MAKEFILE_OUTPUTS :\n"; cmSystemTools::Stdout(msg.str().c_str()); @@ -2094,7 +2086,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake: build system dependency is missing\n"; cmSystemTools::Stdout(msg.str().c_str()); } @@ -2120,7 +2112,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake: build system output is missing\n"; cmSystemTools::Stdout(msg.str().c_str()); } @@ -2138,7 +2130,7 @@ int cmake::CheckBuildSystem() { if(verbose) { - cmOStringStream msg; + std::ostringstream msg; msg << "Re-run cmake file: " << out_oldest << " older than: " << dep_newest << "\n"; cmSystemTools::Stdout(msg.str().c_str()); @@ -2285,7 +2277,7 @@ const char *cmake::GetProperty(const std::string& prop, this->GetCacheManager()->GetCacheIterator(); for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() ) { - if ( output.size() ) + if (!output.empty()) { output += ";"; } @@ -2320,14 +2312,7 @@ const char *cmake::GetProperty(const std::string& prop, { std::vector<std::string> enLangs; this->GlobalGenerator->GetEnabledLanguages(enLangs); - const char* sep = ""; - for(std::vector<std::string>::iterator i = enLangs.begin(); - i != enLangs.end(); ++i) - { - lang += sep; - sep = ";"; - lang += *i; - } + lang = cmJoin(enLangs, ";"); } this->SetProperty("ENABLED_LANGUAGES", lang.c_str()); } @@ -2410,7 +2395,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) else if(arg.find("-G",0) == 0) { std::string value = arg.substr(2); - if(value.size() == 0) + if(value.empty()) { ++i; if(i >= args.size()) @@ -2465,7 +2450,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) } // do we write to a file or to stdout? - if (resultFile.size() == 0) + if (resultFile.empty()) { resultFile = cwd; resultFile += "/__cmake_systeminformation/results.txt"; @@ -2546,7 +2531,7 @@ static bool cmakeCheckStampFile(const char* stampName) while(cmSystemTools::GetLineFromStream(fin, dep)) { int result; - if(dep.length() >= 1 && dep[0] != '#' && + if(!dep.empty() && dep[0] != '#' && (!ftc.FileTimeCompare(stampDepends.c_str(), dep.c_str(), &result) || result < 0)) { @@ -2563,7 +2548,7 @@ static bool cmakeCheckStampFile(const char* stampName) // The build system is up to date. The stamp file has been removed // by the VS IDE due to a "rebuild" request. Restore it atomically. - cmOStringStream stampTempStream; + std::ostringstream stampTempStream; stampTempStream << stampName << ".tmp" << cmSystemTools::RandomSeed(); std::string stampTempString = stampTempStream.str(); const char* stampTemp = stampTempString.c_str(); @@ -2627,7 +2612,7 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, cmListFileBacktrace backtrace = bt; backtrace.MakeRelative(); - cmOStringStream msg; + std::ostringstream msg; bool isError = false; // Construct the message header. if(t == cmake::FATAL_ERROR) @@ -2835,7 +2820,7 @@ void cmake::RunCheckForUnusedVariables() { #ifdef CMAKE_BUILD_WITH_CMAKE bool haveUnused = false; - cmOStringStream msg; + std::ostringstream msg; msg << "Manually-specified variables were not used by the project:"; for(std::map<std::string, bool>::const_iterator it = this->UsedCliVariables.begin(); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 61b175e..6d25b70 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -96,11 +96,9 @@ static const char * cmDocumentationOptions[][2] = static int do_command(int ac, char const* const* av) { std::vector<std::string> args; + args.reserve(ac - 1); args.push_back(av[0]); - for(int i = 2; i < ac; ++i) - { - args.push_back(av[i]); - } + args.insert(args.end(), av + 2, av + ac); return cmcmd::ExecuteCMakeCommand(args); } @@ -203,7 +201,7 @@ int main(int ac, char const* const* av) int do_cmake(int ac, char const* const* av) { - if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) + if (cmSystemTools::GetCurrentWorkingDirectory().empty()) { std::cerr << "Current working directory cannot be established." << std::endl; @@ -221,11 +219,7 @@ int do_cmake(int ac, char const* const* av) // the command line args are processed here so that you can do // -DCMAKE_MODULE_PATH=/some/path and have this value accessible here - std::vector<std::string> args; - for(int i =0; i < ac; ++i) - { - args.push_back(av[i]); - } + std::vector<std::string> args(av, av + ac); hcm.SetCacheArgs(args); std::vector<cmDocumentationEntry> generators; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index f5436ff..7ca3eb3 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -36,7 +36,7 @@ void CMakeCommandUsage(const char* program) { - cmOStringStream errorStream; + std::ostringstream errorStream; #ifdef CMAKE_BUILD_WITH_CMAKE errorStream @@ -71,7 +71,7 @@ void CMakeCommandUsage(const char* program) << " remove_directory dir - remove a directory and its contents\n" << " rename oldname newname - rename a file or directory " "(on one volume)\n" - << " tar [cxt][vfz][cvfj] file.tar [file/dir1 file/dir2 ...]\n" + << " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n" << " - create or extract a tar or zip archive\n" << " sleep <number>... - sleep for given number of seconds\n" << " time command [args] ... - run command and return elapsed time\n" @@ -215,7 +215,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) else if(a.find("=") != a.npos) { // Set environment variable. - cmSystemTools::PutEnv(a.c_str()); + cmSystemTools::PutEnv(a); } else { @@ -549,7 +549,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) "' because existing path cannot be removed: " << emsg << "\n"; return 1; } - if(!cmSystemTools::CreateSymlink(args[2].c_str(), args[3].c_str())) + if(!cmSystemTools::CreateSymlink(args[2], args[3])) { std::string emsg = cmSystemTools::GetLastSystemError(); std::cerr << @@ -729,20 +729,56 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) std::string flags = args[2]; std::string outFile = args[3]; std::vector<std::string> files; + std::string mtime; + bool doing_options = true; for (std::string::size_type cc = 4; cc < args.size(); cc ++) { - files.push_back(args[cc]); + std::string const& arg = args[cc]; + if (doing_options && cmHasLiteralPrefix(arg, "--")) + { + if (arg == "--") + { + doing_options = false; + } + else if (cmHasLiteralPrefix(arg, "--mtime=")) + { + mtime = arg.substr(8); + } + else + { + cmSystemTools::Error("Unknown option to -E tar: ", arg.c_str()); + return 1; + } + } + else + { + files.push_back(arg); + } } - bool gzip = false; - bool bzip2 = false; + cmSystemTools::cmTarCompression compress = + cmSystemTools::TarCompressNone; bool verbose = false; + int nCompress = 0; if ( flags.find_first_of('j') != flags.npos ) { - bzip2 = true; + compress = cmSystemTools::TarCompressBZip2; + ++nCompress; + } + if ( flags.find_first_of('J') != flags.npos ) + { + compress = cmSystemTools::TarCompressXZ; + ++nCompress; } if ( flags.find_first_of('z') != flags.npos ) { - gzip = true; + compress = cmSystemTools::TarCompressGZip; + ++nCompress; + } + if ( nCompress > 1 ) + { + cmSystemTools::Error("Can only compress a tar file one way; " + "at most one flag of z, j, or J may be used"); + return 1; } if ( flags.find_first_of('v') != flags.npos ) { @@ -751,16 +787,16 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if ( flags.find_first_of('t') != flags.npos ) { - if ( !cmSystemTools::ListTar(outFile.c_str(), gzip, verbose) ) + if ( !cmSystemTools::ListTar(outFile.c_str(), verbose) ) { - cmSystemTools::Error("Problem creating tar: ", outFile.c_str()); + cmSystemTools::Error("Problem listing tar: ", outFile.c_str()); return 1; } } else if ( flags.find_first_of('c') != flags.npos ) { if ( !cmSystemTools::CreateTar( - outFile.c_str(), files, gzip, bzip2, verbose) ) + outFile.c_str(), files, compress, verbose, mtime) ) { cmSystemTools::Error("Problem creating tar: ", outFile.c_str()); return 1; @@ -769,7 +805,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) else if ( flags.find_first_of('x') != flags.npos ) { if ( !cmSystemTools::ExtractTar( - outFile.c_str(), gzip, verbose) ) + outFile.c_str(), verbose) ) { cmSystemTools::Error("Problem extracting tar: ", outFile.c_str()); return 1; @@ -893,7 +929,7 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link) return cmSystemTools::CopyFileAlways(file.c_str(), link.c_str()); #else std::string linktext = cmSystemTools::GetFilenameName(file); - return cmSystemTools::CreateSymlink(linktext.c_str(), link.c_str()); + return cmSystemTools::CreateSymlink(linktext, link); #endif } @@ -1214,7 +1250,7 @@ int cmcmd::ParseVisualStudioLinkCommand(std::vector<std::string>& args, targetName = i->substr(5); } } - if(targetName.size() == 0 || command.size() == 0) + if(targetName.empty() || command.empty()) { return -1; } diff --git a/Source/ctest.cxx b/Source/ctest.cxx index fb97af6..b77c231 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -136,7 +136,7 @@ int main (int argc, char const* const* argv) cmCTest inst; - if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) + if (cmSystemTools::GetCurrentWorkingDirectory().empty()) { cmCTestLog(&inst, ERROR_MESSAGE, "Current working directory cannot be established." << std::endl); diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c index d07bdd0..4b8ede2 100644 --- a/Source/kwsys/Base64.c +++ b/Source/kwsys/Base64.c @@ -115,10 +115,10 @@ void kwsysBase64_Encode1(const unsigned char *src, unsigned char *dest) actually knowing how much data to expect (if the input is not a multiple of 3 bytes then the extra padding needed to complete the encode 4 bytes will stop the decoding anyway). */ -unsigned long kwsysBase64_Encode(const unsigned char *input, - unsigned long length, - unsigned char *output, - int mark_end) +size_t kwsysBase64_Encode(const unsigned char *input, + size_t length, + unsigned char *output, + int mark_end) { const unsigned char *ptr = input; const unsigned char *end = input + length; @@ -157,7 +157,7 @@ unsigned long kwsysBase64_Encode(const unsigned char *input, optr += 4; } - return (unsigned long)(optr - output); + return (size_t)(optr - output); } /*--------------------------------------------------------------------------*/ @@ -207,10 +207,10 @@ int kwsysBase64_Decode3(const unsigned char *src, unsigned char *dest) 'length' parameter is ignored. This enables the caller to decode a stream without actually knowing how much decoded data to expect (of course, the buffer must be large enough). */ -unsigned long kwsysBase64_Decode(const unsigned char *input, - unsigned long length, - unsigned char *output, - unsigned long max_input_length) +size_t kwsysBase64_Decode(const unsigned char *input, + size_t length, + unsigned char *output, + size_t max_input_length) { const unsigned char *ptr = input; unsigned char *optr = output; @@ -226,7 +226,7 @@ unsigned long kwsysBase64_Decode(const unsigned char *input, optr += len; if(len < 3) { - return (unsigned long)(optr - output); + return (size_t)(optr - output); } ptr += 4; } @@ -240,7 +240,7 @@ unsigned long kwsysBase64_Decode(const unsigned char *input, optr += len; if(len < 3) { - return (unsigned long)(optr - output); + return (size_t)(optr - output); } ptr += 4; } @@ -275,5 +275,5 @@ unsigned long kwsysBase64_Decode(const unsigned char *input, } } - return (unsigned long)(optr - output); + return (size_t)(optr - output); } diff --git a/Source/kwsys/Base64.h.in b/Source/kwsys/Base64.h.in index 3468007..36ed3cc 100644 --- a/Source/kwsys/Base64.h.in +++ b/Source/kwsys/Base64.h.in @@ -14,6 +14,8 @@ #include <@KWSYS_NAMESPACE@/Configure.h> +#include <stddef.h> /* size_t */ + /* Redefine all public interface symbol names to be in the proper namespace. These macros are used internally to kwsys only, and are not visible to user code. Use kwsysHeaderDump.pl to reproduce @@ -68,10 +70,10 @@ kwsysEXPORT void kwsysBase64_Encode1(const unsigned char *src, * the extra padding needed to complete the encode 4 bytes will stop * the decoding anyway). */ -kwsysEXPORT unsigned long kwsysBase64_Encode(const unsigned char *input, - unsigned long length, - unsigned char *output, - int mark_end); +kwsysEXPORT size_t kwsysBase64_Encode(const unsigned char *input, + size_t length, + unsigned char *output, + int mark_end); /** * Decode 4 bytes into a 3 byte string. Returns the number of bytes @@ -92,10 +94,10 @@ kwsysEXPORT int kwsysBase64_Decode3(const unsigned char *src, * much decoded data to expect (of course, the buffer must be large * enough). */ -kwsysEXPORT unsigned long kwsysBase64_Decode(const unsigned char *input, - unsigned long length, - unsigned char *output, - unsigned long max_input_length); +kwsysEXPORT size_t kwsysBase64_Decode(const unsigned char *input, + size_t length, + unsigned char *output, + size_t max_input_length); #if defined(__cplusplus) } /* extern "C" */ diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 8ca4360..8069ee2 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -96,7 +96,7 @@ ENDIF() IF(NOT KWSYS_NAMESPACE) SET(KWSYS_NAMESPACE "kwsys") SET(KWSYS_STANDALONE 1) -ENDIF(NOT KWSYS_NAMESPACE) +ENDIF() #----------------------------------------------------------------------------- # The project name is that of the specified namespace. @@ -130,49 +130,49 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_USE_String 1) SET(KWSYS_USE_SystemInformation 1) SET(KWSYS_USE_CPU 1) -ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) +ENDIF() # Enforce component dependencies. IF(KWSYS_USE_SystemTools) SET(KWSYS_USE_Directory 1) SET(KWSYS_USE_FStream 1) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_SystemTools) +ENDIF() IF(KWSYS_USE_Glob) SET(KWSYS_USE_Directory 1) SET(KWSYS_USE_SystemTools 1) SET(KWSYS_USE_RegularExpression 1) SET(KWSYS_USE_FStream 1) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_Glob) +ENDIF() IF(KWSYS_USE_Process) SET(KWSYS_USE_System 1) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_Process) +ENDIF() IF(KWSYS_USE_SystemInformation) SET(KWSYS_USE_Process 1) -ENDIF(KWSYS_USE_SystemInformation) +ENDIF() IF(KWSYS_USE_System) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_System) +ENDIF() IF(KWSYS_USE_Directory) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_Directory) +ENDIF() IF(KWSYS_USE_FStream) SET(KWSYS_USE_Encoding 1) -ENDIF(KWSYS_USE_FStream) +ENDIF() # Setup the large file support default. IF(KWSYS_LFS_DISABLE) SET(KWSYS_LFS_REQUESTED 0) -ELSE(KWSYS_LFS_DISABLE) +ELSE() SET(KWSYS_LFS_REQUESTED 1) -ENDIF(KWSYS_LFS_DISABLE) +ENDIF() # Specify default 8 bit encoding for Windows IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP) -ENDIF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE) +ENDIF() # Enable testing if building standalone. IF(KWSYS_STANDALONE) @@ -180,8 +180,8 @@ IF(KWSYS_STANDALONE) MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH) IF(BUILD_TESTING) ENABLE_TESTING() - ENDIF(BUILD_TESTING) -ENDIF(KWSYS_STANDALONE) + ENDIF() +ENDIF() # Include helper macros. INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake) @@ -197,15 +197,15 @@ INCLUDE_REGULAR_EXPRESSION("^.*$") IF(NOT KWSYS_INSTALL_INCLUDE_DIR) STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR "${KWSYS_HEADER_INSTALL_DIR}") -ENDIF(NOT KWSYS_INSTALL_INCLUDE_DIR) +ENDIF() IF(NOT KWSYS_INSTALL_LIB_DIR) STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR "${KWSYS_LIBRARY_INSTALL_DIR}") -ENDIF(NOT KWSYS_INSTALL_LIB_DIR) +ENDIF() IF(NOT KWSYS_INSTALL_BIN_DIR) STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR "${KWSYS_LIBRARY_INSTALL_DIR}") -ENDIF(NOT KWSYS_INSTALL_BIN_DIR) +ENDIF() # Setup header install rules. SET(KWSYS_INSTALL_INCLUDE_OPTIONS) @@ -213,7 +213,7 @@ IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS} COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} ) -ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) +ENDIF() # Setup library install rules. SET(KWSYS_INSTALL_LIBRARY_RULE) @@ -230,7 +230,7 @@ IF(KWSYS_INSTALL_LIB_DIR) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + ENDIF() # Install the archive to the lib directory. SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} @@ -241,8 +241,8 @@ IF(KWSYS_INSTALL_LIB_DIR) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT} ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT) -ENDIF(KWSYS_INSTALL_LIB_DIR) + ENDIF() +ENDIF() IF(KWSYS_INSTALL_BIN_DIR) # Install the runtime library to the bin directory. SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} @@ -253,8 +253,8 @@ IF(KWSYS_INSTALL_BIN_DIR) SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE} COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) -ENDIF(KWSYS_INSTALL_BIN_DIR) + ENDIF() +ENDIF() # Do not support old KWSYS_*a_INSTALL_DIR variable names. SET(KWSYS_HEADER_INSTALL_DIR) @@ -265,8 +265,8 @@ STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}" KWSYS_IN_SOURCE_BUILD) IF(NOT KWSYS_IN_SOURCE_BUILD) CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h - ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPY_ONLY IMMEDIATE) -ENDIF(NOT KWSYS_IN_SOURCE_BUILD) + ${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE) +ENDIF() # Select plugin module file name convention. IF(NOT KWSYS_DynamicLoader_PREFIX) @@ -280,7 +280,7 @@ ENDIF() # We require ANSI support from the C compiler. Add any needed flags. IF(CMAKE_ANSI_CFLAGS) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}") -ENDIF(CMAKE_ANSI_CFLAGS) +ENDIF() #----------------------------------------------------------------------------- # Adjust compiler flags for some platforms. @@ -292,11 +292,11 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX) KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}") IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local") - ENDIF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL) + ENDIF() IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include") - ENDIF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE) - ENDIF(CMAKE_SYSTEM MATCHES "OSF1-V.*") + ENDIF() + ENDIF() IF(CMAKE_SYSTEM MATCHES "HP-UX") SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p") IF(CMAKE_CXX_COMPILER_ID MATCHES "HP") @@ -306,8 +306,8 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98") ENDIF() ENDIF() - ENDIF(CMAKE_SYSTEM MATCHES "HP-UX") -ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX) + ENDIF() +ENDIF() #----------------------------------------------------------------------------- # Configure Large File Support. @@ -327,11 +327,11 @@ IF(KWSYS_LFS_REQUESTED) IF(KWSYS_LFS_WORKS) SET(KWSYS_LFS_AVAILABLE 1) - ENDIF(KWSYS_LFS_WORKS) -ELSE(KWSYS_LFS_REQUESTED) + ENDIF() +ELSE() # Large File Support is not requested. SET(KWSYS_LFS_REQUESTED 0) -ENDIF(KWSYS_LFS_REQUESTED) +ENDIF() #----------------------------------------------------------------------------- # Configure the standard library header wrappers based on compiler's @@ -343,34 +343,34 @@ KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAVE_STD IF(KWSYS_IOS_FORCE_OLD) SET(KWSYS_IOS_USE_ANSI 0) -ELSE(KWSYS_IOS_FORCE_OLD) +ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_ANSI "Checking whether ANSI stream headers are available" DIRECT) -ENDIF(KWSYS_IOS_FORCE_OLD) +ENDIF() IF(KWSYS_IOS_USE_ANSI) KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAVE_STD "Checking whether ANSI streams are in std namespace" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_SSTREAM "Checking whether ANSI string stream is available" DIRECT) -ELSE(KWSYS_IOS_USE_ANSI) +ELSE() SET(KWSYS_IOS_HAVE_STD 0) SET(KWSYS_IOS_USE_SSTREAM 0) -ENDIF(KWSYS_IOS_USE_ANSI) +ENDIF() IF(KWSYS_IOS_USE_SSTREAM) SET(KWSYS_IOS_USE_STRSTREAM_H 0) SET(KWSYS_IOS_USE_STRSTREA_H 0) -ELSE(KWSYS_IOS_USE_SSTREAM) +ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREAM_H "Checking whether strstream.h is available" DIRECT) IF(KWSYS_IOS_USE_STRSTREAM_H) SET(KWSYS_IOS_USE_STRSTREA_H 0) - ELSE(KWSYS_IOS_USE_STRSTREAM_H) + ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_USE_STRSTREA_H "Checking whether strstrea.h is available" DIRECT) - ENDIF(KWSYS_IOS_USE_STRSTREAM_H) -ENDIF(KWSYS_IOS_USE_SSTREAM) + ENDIF() +ENDIF() KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CSTDDEF "Checking whether header cstddef is available" DIRECT) @@ -384,16 +384,16 @@ KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_TRAITS IF(KWSYS_STL_HAS_ITERATOR_TRAITS) SET(KWSYS_STL_HAS_ITERATOR_CATEGORY 0) SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0) -ELSE(KWSYS_STL_HAS_ITERATOR_TRAITS) +ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ITERATOR_CATEGORY "Checking whether stl has old iterator_category" DIRECT) IF(KWSYS_STL_HAS_ITERATOR_CATEGORY) SET(KWSYS_STL_HAS___ITERATOR_CATEGORY 0) - ELSE(KWSYS_STL_HAS_ITERATOR_CATEGORY) + ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS___ITERATOR_CATEGORY "Checking whether stl has internal __iterator_category" DIRECT) - ENDIF(KWSYS_STL_HAS_ITERATOR_CATEGORY) -ENDIF(KWSYS_STL_HAS_ITERATOR_TRAITS) + ENDIF() +ENDIF() KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE "Checking whether stl has standard template allocator" DIRECT) IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) @@ -402,25 +402,25 @@ IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) "Checking for rebind member of stl allocator" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT "Checking for non-standard argument to stl allocator<>::max_size" DIRECT) -ELSE(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) +ELSE() KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE "Checking whether stl has old non-template allocator" DIRECT) SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0) SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0) -ENDIF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) +ENDIF() KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS "Checking whether stl containers support allocator objects." DIRECT) IF(KWSYS_IOS_USE_ANSI AND NOT WATCOM) # ANSI streams always have string operators. SET(KWSYS_STL_STRING_HAVE_OSTREAM 1) SET(KWSYS_STL_STRING_HAVE_ISTREAM 1) -ELSE(KWSYS_IOS_USE_ANSI AND NOT WATCOM) +ELSE() # There may not be string operators for old streams. KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM "Checking whether stl string has ostream operator<<" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM "Checking whether stl string has istream operator>>" DIRECT) -ENDIF(KWSYS_IOS_USE_ANSI AND NOT WATCOM) +ENDIF() SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_IOS_USE_ANSI=${KWSYS_IOS_USE_ANSI} -DKWSYS_IOS_HAVE_STD=${KWSYS_IOS_HAVE_STD}) @@ -440,7 +440,7 @@ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ARGUMENT_DEPENDENT_LOOKUP IF(UNIX) KWSYS_PLATFORM_CXX_TEST(KWSYS_STAT_HAS_ST_MTIM "Checking whether struct stat has st_mtim member" DIRECT) -ENDIF(UNIX) +ENDIF() # Check existence and uniqueness of long long and __int64. KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG @@ -528,20 +528,20 @@ IF(KWSYS_USE_FundamentalType) IF(KWSYS_USE___INT64) KWSYS_PLATFORM_CXX_TEST(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE "Checking whether unsigned __int64 can convert to double" DIRECT) - ELSE(KWSYS_USE___INT64) + ELSE() SET(KWSYS_CAN_CONVERT_UI64_TO_DOUBLE 1) - ENDIF(KWSYS_USE___INT64) + ENDIF() # Check signedness of "char" type. KWSYS_PLATFORM_CXX_TEST_RUN(KWSYS_CHAR_IS_SIGNED "Checking whether char is signed" DIRECT) -ENDIF(KWSYS_USE_FundamentalType) +ENDIF() IF(KWSYS_USE_Encoding) # Look for type size helper macros. KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING "Checking whether wstring is available" DIRECT) -ENDIF(KWSYS_USE_Encoding) +ENDIF() IF(KWSYS_USE_IOStream) # Determine whether iostreams support long long. @@ -567,26 +567,26 @@ IF(KWSYS_USE_IOStream) SET(KWSYS_IOS_HAS_OSTREAM___INT64 0) ENDIF() SET(KWSYS_PLATFORM_CXX_TEST_DEFINES) -ENDIF(KWSYS_USE_IOStream) +ENDIF() IF(KWSYS_NAMESPACE MATCHES "^kwsys$") SET(KWSYS_NAME_IS_KWSYS 1) -ELSE(KWSYS_NAMESPACE MATCHES "^kwsys$") +ELSE() SET(KWSYS_NAME_IS_KWSYS 0) -ENDIF(KWSYS_NAMESPACE MATCHES "^kwsys$") +ENDIF() # Choose default shared/static build if not specified. IF(KWSYS_BUILD_SHARED MATCHES "^KWSYS_BUILD_SHARED$") SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS}) -ENDIF(KWSYS_BUILD_SHARED MATCHES "^KWSYS_BUILD_SHARED$") +ENDIF() IF(KWSYS_BUILD_SHARED) SET(KWSYS_BUILD_SHARED 1) SET(KWSYS_LIBRARY_TYPE SHARED) -ELSE(KWSYS_BUILD_SHARED) +ELSE() SET(KWSYS_BUILD_SHARED 0) SET(KWSYS_LIBRARY_TYPE STATIC) -ENDIF(KWSYS_BUILD_SHARED) +ENDIF() #----------------------------------------------------------------------------- # Configure some implementation details. @@ -789,7 +789,7 @@ ENDIF() # Choose a directory for the generated headers. IF(NOT KWSYS_HEADER_ROOT) SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}") -ENDIF(NOT KWSYS_HEADER_ROOT) +ENDIF() SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}") INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT}) @@ -801,13 +801,13 @@ IF(KWSYS_INSTALL_DOC_DIR) SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS} COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME} ) - ENDIF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME) + ENDIF() # Install the license under the documentation directory. INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LICENSE_OPTIONS}) -ENDIF(KWSYS_INSTALL_DOC_DIR) +ENDIF() #----------------------------------------------------------------------------- # Create STL header wrappers to block warnings in the STL headers and @@ -844,10 +844,10 @@ FOREACH(header INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) - ELSE(KWSYS_STL_HEADER_EXTRA_${header}) + ENDIF() + ELSE() SET(KWSYS_STL_HEADER_EXTRA "") - ENDIF(KWSYS_STL_HEADER_EXTRA_${header}) + ENDIF() CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.hxx.in ${KWSYS_HEADER_DIR}/stl/${header} @ONLY IMMEDIATE) @@ -857,8 +857,8 @@ FOREACH(header INSTALL(FILES ${KWSYS_HEADER_DIR}/stl/${header} DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/stl ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) -ENDFOREACH(header) + ENDIF() +ENDFOREACH() # Provide cstddef header. CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_cstddef.hxx.in @@ -868,7 +868,7 @@ IF(KWSYS_INSTALL_INCLUDE_DIR) INSTALL(FILES ${KWSYS_HEADER_DIR}/cstddef DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) -ENDIF(KWSYS_INSTALL_INCLUDE_DIR) +ENDIF() #----------------------------------------------------------------------------- # Create streams header wrappers to give standard names by which they @@ -884,8 +884,8 @@ FOREACH(header iostream fstream sstream iosfwd) INSTALL(FILES ${KWSYS_HEADER_DIR}/ios/${header} DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}/ios ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) -ENDFOREACH(header) + ENDIF() +ENDFOREACH() #----------------------------------------------------------------------------- # Build a list of classes and headers we need to implement the @@ -910,9 +910,9 @@ FOREACH(cpp ${cppclasses}) # Load component-specific CMake code. IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake) INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake) - ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake) - ENDIF(KWSYS_USE_${cpp}) -ENDFOREACH(cpp) + ENDIF() + ENDIF() +ENDFOREACH() # Add selected C components. FOREACH(c @@ -925,9 +925,9 @@ FOREACH(c # Load component-specific CMake code. IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake) INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake) - ENDIF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake) - ENDIF(KWSYS_USE_${c}) -ENDFOREACH(c) + ENDIF() + ENDIF() +ENDFOREACH() #----------------------------------------------------------------------------- # Build a list of sources for the library based on components that are @@ -940,11 +940,11 @@ IF(KWSYS_USE_Process) IF(NOT UNIX) # Use the Windows implementation. SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c) - ELSE(NOT UNIX) + ELSE() # Use the UNIX implementation. SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c) - ENDIF(NOT UNIX) -ENDIF(KWSYS_USE_Process) + ENDIF() +ENDIF() # Add selected C sources. FOREACH(c Base64 Encoding MD5 Terminal System String) @@ -954,8 +954,8 @@ FOREACH(c Base64 Encoding MD5 Terminal System String) ELSE() LIST(APPEND KWSYS_C_SRCS ${c}.c) ENDIF() - ENDIF(KWSYS_USE_${c}) -ENDFOREACH(c) + ENDIF() +ENDFOREACH() # Configure headers of C++ classes and construct the list of sources. FOREACH(c ${KWSYS_CLASSES}) @@ -976,8 +976,8 @@ FOREACH(c ${KWSYS_CLASSES}) INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) -ENDFOREACH(c) + ENDIF() +ENDFOREACH() # Configure C headers. FOREACH(h ${KWSYS_H_FILES}) @@ -991,8 +991,8 @@ FOREACH(h ${KWSYS_H_FILES}) INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) -ENDFOREACH(h) + ENDIF() +ENDFOREACH() # Configure other C++ headers. FOREACH(h ${KWSYS_HXX_FILES}) @@ -1006,8 +1006,8 @@ FOREACH(h ${KWSYS_HXX_FILES}) INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE} ${KWSYS_INSTALL_INCLUDE_OPTIONS}) - ENDIF(KWSYS_INSTALL_INCLUDE_DIR) -ENDFOREACH(h) + ENDIF() +ENDFOREACH() #----------------------------------------------------------------------------- # Add the library with the configured name and list of sources. @@ -1018,8 +1018,8 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) IF(KWSYS_USE_DynamicLoader) IF(UNIX) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE} ${CMAKE_DL_LIBS}) - ENDIF(UNIX) - ENDIF(KWSYS_USE_DynamicLoader) + ENDIF() + ENDIF() IF(KWSYS_USE_SystemInformation) IF(WIN32) @@ -1044,13 +1044,13 @@ IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES ${KWSYS_PROPERTIES_CXX} ) - ENDIF(KWSYS_PROPERTIES_CXX) + ENDIF() # Create an install target for the library. IF(KWSYS_INSTALL_LIBRARY_RULE) INSTALL(TARGETS ${KWSYS_NAMESPACE} ${KWSYS_INSTALL_LIBRARY_RULE}) - ENDIF(KWSYS_INSTALL_LIBRARY_RULE) -ENDIF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS) + ENDIF() +ENDIF() # Add a C-only library if requested. IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) @@ -1062,20 +1062,20 @@ IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) SET_TARGET_PROPERTIES(${KWSYS_NAMESPACE} PROPERTIES ${KWSYS_PROPERTIES_C} ) - ENDIF(KWSYS_PROPERTIES_C) + ENDIF() # Create an install target for the library. IF(KWSYS_INSTALL_LIBRARY_RULE) INSTALL(TARGETS ${KWSYS_NAMESPACE}_c ${KWSYS_INSTALL_LIBRARY_RULE}) - ENDIF(KWSYS_INSTALL_LIBRARY_RULE) -ENDIF(KWSYS_ENABLE_C AND KWSYS_C_SRCS) + ENDIF() +ENDIF() # For building kwsys itself, we use a macro defined on the command # line to configure the namespace in the C and C++ source files. ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}") # Disable deprecation warnings for standard C functions. -IF(MSVC OR (WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")) +IF(MSVC OR (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel")) ADD_DEFINITIONS( -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_DEPRECATE @@ -1093,13 +1093,13 @@ IF(KWSYS_USE_String) # Activate code in "String.c". See the comment in the source. SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES COMPILE_FLAGS "-DKWSYS_STRING_C") -ENDIF(KWSYS_USE_String) +ENDIF() IF(KWSYS_USE_Encoding) # Set default 8 bit encoding in "EndcodingC.c". SET_PROPERTY(SOURCE EncodingC.c APPEND PROPERTY COMPILE_DEFINITIONS KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE}) -ENDIF(KWSYS_USE_Encoding) +ENDIF() #----------------------------------------------------------------------------- # Setup testing if not being built as part of another project. @@ -1109,7 +1109,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}") IF(EXECUTABLE_OUTPUT_PATH) SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}") - ENDIF(EXECUTABLE_OUTPUT_PATH) + ENDIF() # C tests SET(KWSYS_C_TESTS @@ -1129,7 +1129,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) FOREACH(test ${KWSYS_C_TESTS}) ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}}) SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - ENDFOREACH(test) + ENDFOREACH() # C++ tests IF(NOT WATCOM) @@ -1137,7 +1137,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) testAutoPtr testHashSTL ) - ENDIF(NOT WATCOM) + ENDIF() SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testIOS testSystemTools @@ -1148,22 +1148,22 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testEncoding ) - ENDIF(KWSYS_STL_HAS_WSTRING) + ENDIF() IF(KWSYS_USE_FStream) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testFStream ) - ENDIF(KWSYS_USE_FStream) + ENDIF() IF(KWSYS_USE_SystemInformation) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation) - ENDIF(KWSYS_USE_SystemInformation) + ENDIF() IF(KWSYS_USE_DynamicLoader) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader) # If kwsys contains the DynamicLoader, need extra library ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c) SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB}) ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_NAMESPACE}) - ENDIF(KWSYS_USE_DynamicLoader) + ENDIF() CREATE_TEST_SOURCELIST( KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx ${KWSYS_CXX_TESTS} @@ -1183,7 +1183,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake") SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake") - ENDIF(CTEST_TEST_KWSYS) + ENDIF() SET(KWSYS_TEST_ARGS_testCommandLineArguments --another-bool-variable @@ -1216,7 +1216,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) FOREACH(test ${KWSYS_CXX_TESTS}) ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}}) SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST}) - ENDFOREACH(test) + ENDFOREACH() # Process tests. ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c) @@ -1224,15 +1224,15 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_NAMESPACE}_c) IF(NOT CYGWIN) SET(KWSYS_TEST_PROCESS_7 7) - ENDIF(NOT CYGWIN) + ENDIF() FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7}) ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n}) SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST}) SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120) - ENDFOREACH(n) + ENDFOREACH() # Some Apple compilers produce bad optimizations in this source. - IF(APPLE AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|LLVM)$") + IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$") SET_SOURCE_FILES_PROPERTIES(testProcess.c PROPERTIES COMPILE_FLAGS -O0) ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL") # Tell IBM XL not to warn about our test infinite loop @@ -1263,5 +1263,5 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON) ENDIF() - ENDIF(BUILD_TESTING) -ENDIF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) + ENDIF() +ENDIF() diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst new file mode 100644 index 0000000..e097b76 --- /dev/null +++ b/Source/kwsys/CONTRIBUTING.rst @@ -0,0 +1,35 @@ +Contributing to KWSys +********************* + +Overview +======== + +KWSys is kept in its own Git repository and shared by several projects +via copies in their source trees. Changes to KWSys should not be made +directly in a host project, except perhaps in maintenance branches. + +Please visit + + http://public.kitware.com/Wiki/KWSys/Git + +to contribute changes directly to KWSys upstream. Once changes are +reviewed, tested, and integrated there then the copies of KWSys within +dependent projects can be updated to get the changes. + +Issues +====== + +KWSys has no independent issue tracker. After encountering an issue +(bug) please try to submit a patch using the above instructions. +Otherwise please report the issue to the tracker for the project that +hosts the copy of KWSys in which the problem was found. + +License +======= + +We do not require any formal copyright assignment or contributor license +agreement. Any contributions intentionally sent upstream are presumed +to be offerred under terms of the OSI-approved BSD 3-clause License. +See `Copyright.txt`_ for details. + +.. _`Copyright.txt`: Copyright.txt diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx index 741bcba..04b2866 100644 --- a/Source/kwsys/Directory.cxx +++ b/Source/kwsys/Directory.cxx @@ -203,13 +203,18 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& na #include <sys/types.h> #include <dirent.h> -/* There is a problem with the Portland compiler, large file -support and glibc/Linux system headers: -http://www.pgroup.com/userforum/viewtopic.php? -p=1992&sid=f16167f51964f1a68fe5041b8eb213b6 -*/ -#if defined(__PGI) && defined(__USE_FILE_OFFSET64) -# define dirent dirent64 +// PGI with glibc has trouble with dirent and large file support: +// http://www.pgroup.com/userforum/viewtopic.php? +// p=1992&sid=f16167f51964f1a68fe5041b8eb213b6 +// Work around the problem by mapping dirent the same way as readdir. +#if defined(__PGI) && defined(__GLIBC__) +# define kwsys_dirent_readdir dirent +# define kwsys_dirent_readdir64 dirent64 +# define kwsys_dirent kwsys_dirent_lookup(readdir) +# define kwsys_dirent_lookup(x) kwsys_dirent_lookup_delay(x) +# define kwsys_dirent_lookup_delay(x) kwsys_dirent_##x +#else +# define kwsys_dirent dirent #endif namespace KWSYS_NAMESPACE @@ -226,7 +231,7 @@ bool Directory::Load(const kwsys_stl::string& name) return 0; } - for (dirent* d = readdir(dir); d; d = readdir(dir) ) + for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) ) { this->Internal->Files.push_back(d->d_name); } @@ -240,7 +245,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const kwsys_stl::string& na DIR* dir = opendir(name.c_str()); unsigned long count = 0; - for (dirent* d = readdir(dir); d; d = readdir(dir) ) + for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) ) { count++; } diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in index 0acb191..1bcf90e 100644 --- a/Source/kwsys/Directory.hxx.in +++ b/Source/kwsys/Directory.hxx.in @@ -18,7 +18,6 @@ /* Define these macros temporarily to keep the code readable. */ #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS # define kwsys_stl @KWSYS_NAMESPACE@_stl -# define kwsys_ios @KWSYS_NAMESPACE@_ios #endif namespace @KWSYS_NAMESPACE@ @@ -87,7 +86,6 @@ private: /* Undefine temporary macros. */ #if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS # undef kwsys_stl -# undef kwsys_ios #endif #endif diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx index 44cf6af..66c7d57 100644 --- a/Source/kwsys/DynamicLoader.cxx +++ b/Source/kwsys/DynamicLoader.cxx @@ -40,9 +40,9 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { - return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L); + return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L); } //---------------------------------------------------------------------------- @@ -53,7 +53,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer -DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym) +DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { void* addr; int status; @@ -62,7 +62,7 @@ DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sy * TYPE_DATA Look for a symbol in the data segment (for example, variables). * TYPE_UNDEFINED Look for any symbol. */ - status = shl_findsym (&lib, sym, TYPE_UNDEFINED, &addr); + status = shl_findsym (&lib, sym.c_str(), TYPE_UNDEFINED, &addr); void* result = (status < 0) ? (void*)0 : addr; // Hack to cast pointer-to-data to pointer-to-function. @@ -111,18 +111,18 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { NSObjectFileImageReturnCode rc; NSObjectFileImage image = 0; - rc = NSCreateObjectFileImageFromFile(libname, &image); + rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image); // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file if( rc != NSObjectFileImageSuccess ) { return 0; } - NSModule handle = NSLinkModule(image, libname, + NSModule handle = NSLinkModule(image, libname.c_str(), NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(image); return handle; @@ -142,14 +142,14 @@ int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { void *result=0; // Need to prepend symbols with '_' on Apple-gcc compilers - size_t len = strlen(sym); + size_t len = sym.size(); char *rsym = new char[len + 1 + 1]; strcpy(rsym, "_"); - strcat(rsym+1, sym); + strcat(rsym+1, sym.c_str()); NSSymbol symbol = NSLookupSymbolInModule(lib, rsym); if(symbol) @@ -183,13 +183,13 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname) { DynamicLoader::LibraryHandle lh; - int length = MultiByteToWideChar(CP_UTF8, 0, libname, -1, NULL, 0); + int length = MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, NULL, 0); wchar_t* wchars = new wchar_t[length+1]; wchars[0] = '\0'; - MultiByteToWideChar(CP_UTF8, 0, libname, -1, wchars, length); + MultiByteToWideChar(CP_UTF8, 0, libname.c_str(), -1, wchars, length); lh = LoadLibraryW(wchars); delete [] wchars; return lh; @@ -203,7 +203,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { // TODO: The calling convention affects the name of the symbol. We // should have a tool to help get the symbol with the desired @@ -230,12 +230,12 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( void *result; #if defined(__BORLANDC__) || defined(__WATCOMC__) // Need to prepend symbols with '_' - size_t len = strlen(sym); + size_t len = sym.size(); char *rsym = new char[len + 1 + 1]; strcpy(rsym, "_"); - strcat(rsym, sym); + strcat(rsym, sym.c_str()); #else - const char *rsym = sym; + const char *rsym = sym.c_str(); #endif result = (void*)GetProcAddress(lib, rsym); #if defined(__BORLANDC__) || defined(__WATCOMC__) @@ -298,11 +298,11 @@ namespace KWSYS_NAMESPACE static image_id last_dynamic_err = B_OK; //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { // image_id's are integers, errors are negative. Add one just in case we // get a valid image_id of zero (is that even possible?). - image_id rc = load_add_on(libname); + image_id rc = load_add_on(libname.c_str()); if (rc < 0) { last_dynamic_err = rc; @@ -336,7 +336,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { // Hack to cast pointer-to-data to pointer-to-function. union @@ -356,7 +356,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( // !!! FIXME: BeOS can do function-only lookups...does this ever // !!! FIXME: actually _want_ a data symbol lookup, or was this union // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only). - status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid); + status_t rc = get_image_symbol(lib-1,sym.c_str(),B_SYMBOL_TYPE_ANY,&result.pvoid); if (rc != B_OK) { last_dynamic_err = rc; @@ -389,7 +389,7 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { return 0; } @@ -407,7 +407,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { return 0; } @@ -433,12 +433,12 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { - char *name = (char *)calloc(1, strlen(libname) + 1); + char *name = (char *)calloc(1, libname.size() + 1); dld_init(program_invocation_name); - strncpy(name, libname, strlen(libname)); - dld_link(libname); + strncpy(name, libname.c_str(), libname.size()); + dld_link(libname.c_str()); return (void *)name; } @@ -452,7 +452,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { // Hack to cast pointer-to-data to pointer-to-function. union @@ -460,7 +460,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( void* pvoid; DynamicLoader::SymbolPointer psym; } result; - result.pvoid = dld_get_symbol(sym); + result.pvoid = dld_get_symbol(sym.c_str()); return result.psym; } @@ -485,9 +485,9 @@ namespace KWSYS_NAMESPACE { //---------------------------------------------------------------------------- -DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname ) +DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const kwsys_stl::string& libname ) { - return dlopen(libname, RTLD_LAZY); + return dlopen(libname.c_str(), RTLD_LAZY); } //---------------------------------------------------------------------------- @@ -504,7 +504,7 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) //---------------------------------------------------------------------------- DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( - DynamicLoader::LibraryHandle lib, const char* sym) + DynamicLoader::LibraryHandle lib, const kwsys_stl::string& sym) { // Hack to cast pointer-to-data to pointer-to-function. union @@ -512,7 +512,7 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( void* pvoid; DynamicLoader::SymbolPointer psym; } result; - result.pvoid = dlsym(lib, sym); + result.pvoid = dlsym(lib, sym.c_str()); return result.psym; } diff --git a/Source/kwsys/DynamicLoader.hxx.in b/Source/kwsys/DynamicLoader.hxx.in index 64468ec..75811ab 100644 --- a/Source/kwsys/DynamicLoader.hxx.in +++ b/Source/kwsys/DynamicLoader.hxx.in @@ -13,6 +13,7 @@ #define @KWSYS_NAMESPACE@_DynamicLoader_hxx #include <@KWSYS_NAMESPACE@/Configure.h> +#include <@KWSYS_NAMESPACE@/stl/string> #if defined(__hpux) #include <dl.h> @@ -27,6 +28,11 @@ #include <be/kernel/image.h> #endif +/* Define these macros temporarily to keep the code readable. */ +#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define kwsys_stl @KWSYS_NAMESPACE@_stl +#endif + namespace @KWSYS_NAMESPACE@ { /** \class DynamicLoader @@ -77,14 +83,14 @@ public: /** Load a dynamic library into the current process. * The returned LibraryHandle can be used to access the symbols in the * library. */ - static LibraryHandle OpenLibrary(const char*); + static LibraryHandle OpenLibrary(const kwsys_stl::string&); /** Attempt to detach a dynamic library from the * process. A value of true is returned if it is sucessful. */ static int CloseLibrary(LibraryHandle); /** Find the address of the symbol in the given library. */ - static SymbolPointer GetSymbolAddress(LibraryHandle, const char*); + static SymbolPointer GetSymbolAddress(LibraryHandle, const kwsys_stl::string&); /** Return the default module prefix for the current platform. */ static const char* LibPrefix() { return "@KWSYS_DynamicLoader_PREFIX@"; } @@ -98,4 +104,9 @@ public: } // namespace @KWSYS_NAMESPACE@ +/* Undefine temporary macros. */ +#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# undef kwsys_stl +#endif + #endif diff --git a/Source/kwsys/EncodingC.c b/Source/kwsys/EncodingC.c index cda78e2..ba2cec2 100644 --- a/Source/kwsys/EncodingC.c +++ b/Source/kwsys/EncodingC.c @@ -44,7 +44,7 @@ wchar_t* kwsysEncoding_DupToWide(const char* str) size_t length = kwsysEncoding_mbstowcs(NULL, str, 0) + 1; if(length > 0) { - ret = malloc((length)*sizeof(wchar_t)); + ret = (wchar_t*)malloc((length)*sizeof(wchar_t)); ret[0] = 0; kwsysEncoding_mbstowcs(ret, str, length); } @@ -71,7 +71,7 @@ char* kwsysEncoding_DupToNarrow(const wchar_t* str) size_t length = kwsysEncoding_wcstombs(0, str, 0) + 1; if(length > 0) { - ret = malloc(length); + ret = (char*)malloc(length); ret[0] = 0; kwsysEncoding_wcstombs(ret, str, length); } diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in index 45425ff..37055d6 100644 --- a/Source/kwsys/FStream.hxx.in +++ b/Source/kwsys/FStream.hxx.in @@ -18,6 +18,11 @@ namespace @KWSYS_NAMESPACE@ { #if defined(_MSC_VER) && _MSC_VER >= 1400 +# if defined(_NOEXCEPT) +# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT +# else +# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT +# endif template<typename CharType,typename Traits> class basic_filebuf : public std::basic_filebuf<CharType,Traits> { @@ -85,7 +90,7 @@ namespace @KWSYS_NAMESPACE@ return buf_; } - ~basic_ifstream() + ~basic_ifstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { buf_->close(); delete buf_; @@ -147,7 +152,7 @@ class basic_ofstream : public std::basic_ostream<CharType,Traits> { return buf_.get(); } - ~basic_ofstream() + ~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { buf_->close(); delete buf_; @@ -160,6 +165,7 @@ class basic_ofstream : public std::basic_ostream<CharType,Traits> typedef basic_ifstream<char> ifstream; typedef basic_ofstream<char> ofstream; +# undef @KWSYS_NAMESPACE@_FStream_NOEXCEPT #else using @KWSYS_NAMESPACE@_ios_namespace::ofstream; using @KWSYS_NAMESPACE@_ios_namespace::ifstream; diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 0916d2e..5a96aed 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -501,7 +501,7 @@ void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const kwsys_stl: { if ( !this->Relative.empty() ) { - files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file.c_str())); + files.push_back(kwsys::SystemTools::RelativePath(this->Relative, file)); } else { diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index ca9d424..1be6d02 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -547,7 +547,7 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file) } if(file) { - *pfile = malloc(strlen(file)+1); + *pfile = (char*)malloc(strlen(file)+1); if(!*pfile) { return 0; @@ -1468,7 +1468,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp) cp->RealWorkingDirectoryLength = 4096; #endif cp->RealWorkingDirectory = - malloc((size_t)(cp->RealWorkingDirectoryLength)); + (char*)malloc((size_t)(cp->RealWorkingDirectoryLength)); if(!cp->RealWorkingDirectory) { return 0; diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c index ef71f26..c2965ea 100644 --- a/Source/kwsys/ProcessWin32.c +++ b/Source/kwsys/ProcessWin32.c @@ -340,7 +340,11 @@ kwsysProcess* kwsysProcess_New(void) osv.dwOSVersionInfoSize = sizeof(osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif GetVersionEx(&osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx @@ -2382,7 +2386,11 @@ static kwsysProcess_List* kwsysProcess_List_New(void) osv.dwOSVersionInfoSize = sizeof(osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif GetVersionEx(&osv); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx diff --git a/Source/kwsys/README.txt b/Source/kwsys/README.txt index ba03f8d..b8191f7 100644 --- a/Source/kwsys/README.txt +++ b/Source/kwsys/README.txt @@ -8,3 +8,5 @@ details. You are probably reading this file in the source tree of a surrounding project. In that case, see "../README.kwsys" for details of using KWSys in your project. + +See CONTRIBUTING.rst for instructions to contribute KWSys changes. diff --git a/Source/kwsys/SharedForward.h.in b/Source/kwsys/SharedForward.h.in index 7ff29b4..f22fa58 100644 --- a/Source/kwsys/SharedForward.h.in +++ b/Source/kwsys/SharedForward.h.in @@ -65,6 +65,15 @@ See the comments below for specific explanations of each macro. */ +/* Disable -Wcast-qual warnings since they are too hard to fix in a + cross-platform way. */ +#if defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wcast-qual") +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wcast-qual" +# endif +#endif + /*--------------------------------------------------------------------------*/ /* Full path to the directory in which this executable is built. Do @@ -813,7 +822,7 @@ static void kwsys_shared_forward_print_failure(char const* const* argv) } /* Static storage space to store the updated environment variable. */ -static char kwsys_shared_forward_ldpath[KWSYS_SHARED_FORWARD_MAXPATH*16] = KWSYS_SHARED_FORWARD_LDPATH "="; +static char kwsys_shared_forward_ldpath[65535] = KWSYS_SHARED_FORWARD_LDPATH "="; /*--------------------------------------------------------------------------*/ /* Main driver function to be called from main. */ @@ -917,6 +926,13 @@ static int @KWSYS_NAMESPACE@_shared_forward_to_real(int argc, char** argv_in) return 1; } +/* Restore warning stack. */ +#if defined(__clang__) && defined(__has_warning) +# if __has_warning("-Wcast-qual") +# pragma clang diagnostic pop +# endif +#endif + #else # error "@KWSYS_NAMESPACE@/SharedForward.h should be included only once." #endif diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 84b5f39..9c7ceee 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -443,7 +443,7 @@ public: }; protected: - // Functions. + // For windows bool RetrieveCPUFeatures(); bool RetrieveCPUIdentity(); bool RetrieveCPUCacheDetails(); @@ -457,6 +457,7 @@ protected: bool RetrieveClassicalCPUIdentity(); bool RetrieveExtendedCPUIdentity(); + // Processor information Manufacturer ChipManufacturer; CPUFeatures Features; ID ChipID; @@ -464,11 +465,11 @@ protected: unsigned int NumberOfLogicalCPU; unsigned int NumberOfPhysicalCPU; - int CPUCount(); + int CPUCount(); // For windows unsigned char LogicalCPUPerPhysicalCPU(); - unsigned char GetAPICId(); + unsigned char GetAPICId(); // For windows bool IsHyperThreadingSupported(); - static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); + static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows // For Linux and Cygwin, /proc/cpuinfo formats are slightly different bool RetreiveInformationFromCpuInfoFile(); @@ -3753,9 +3754,9 @@ bool SystemInformationImplementation::QueryWindowsMemory() } # define MEM_VAL(value) ull##value # endif - tv = ms.MEM_VAL(TotalVirtual); + tv = ms.MEM_VAL(TotalPageFile); tp = ms.MEM_VAL(TotalPhys); - av = ms.MEM_VAL(AvailVirtual); + av = ms.MEM_VAL(AvailPageFile); ap = ms.MEM_VAL(AvailPhys); this->TotalVirtualMemory = tv>>10>>10; this->TotalPhysicalMemory = tp>>10>>10; @@ -3913,7 +3914,7 @@ bool SystemInformationImplementation::QueryCygwinMemory() bool SystemInformationImplementation::QueryAIXMemory() { -#if defined(_AIX) +#if defined(_AIX) && defined(_SC_AIX_REALMEM) long c = sysconf(_SC_AIX_REALMEM); if (c <= 0) { @@ -5068,7 +5069,11 @@ bool SystemInformationImplementation::QueryOSInformation() osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEXW); #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif bOsVersionInfoEx = GetVersionExW ((OSVERSIONINFOW*)&osvi); if (!bOsVersionInfoEx) @@ -5156,7 +5161,7 @@ bool SystemInformationImplementation::QueryOSInformation() } } - sprintf (operatingSystem, "%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); + sprintf (operatingSystem, "%ls (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); this->OSVersion = operatingSystem; } else @@ -5205,7 +5210,7 @@ bool SystemInformationImplementation::QueryOSInformation() if (osvi.dwMajorVersion <= 4) { // NB: NT 4.0 and earlier. - sprintf (operatingSystem, "version %ld.%ld %s (Build %ld)", + sprintf (operatingSystem, "version %ld.%ld %ls (Build %ld)", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.szCSDVersion, @@ -5236,7 +5241,7 @@ bool SystemInformationImplementation::QueryOSInformation() else { // Windows 2000 and everything else. - sprintf (operatingSystem,"%s (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); + sprintf (operatingSystem,"%ls (Build %ld)", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); this->OSVersion = operatingSystem; } break; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index b1221e3..2708211 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -16,6 +16,14 @@ # define _XOPEN_SOURCE_EXTENDED #endif +#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) +# define KWSYS_WINDOWS_DIRS +#else +# if defined(__SUNPRO_CC) +# include <fcntl.h> +# endif +#endif + #include "kwsysPrivate.h" #include KWSYS_HEADER(RegularExpression.hxx) #include KWSYS_HEADER(SystemTools.hxx) @@ -205,8 +213,7 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft) } #endif -#if defined(_WIN32) && (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)) - +#ifdef KWSYS_WINDOWS_DIRS #include <wctype.h> inline int Mkdir(const kwsys_stl::string& dir) @@ -222,7 +229,7 @@ inline int Rmdir(const kwsys_stl::string& dir) inline const char* Getcwd(char* buf, unsigned int len) { std::vector<wchar_t> w_buf(len); - if(const wchar_t* ret = _wgetcwd(&w_buf[0], len)) + if(_wgetcwd(&w_buf[0], len)) { // make sure the drive letter is capital if(wcslen(&w_buf[0]) > 1 && w_buf[1] == L':') @@ -385,6 +392,11 @@ const char* SystemTools::GetEnv(const char* key) return getenv(key); } +const char* SystemTools::GetEnv(const kwsys_stl::string& key) +{ + return SystemTools::GetEnv(key.c_str()); +} + bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result) { const char* v = getenv(key); @@ -399,6 +411,11 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result) } } +bool SystemTools::GetEnv(const kwsys_stl::string& key, kwsys_stl::string& result) +{ + return SystemTools::GetEnv(key.c_str(), result); +} + //---------------------------------------------------------------------------- #if defined(__CYGWIN__) || defined(__GLIBC__) @@ -410,27 +427,28 @@ bool SystemTools::GetEnv(const char* key, kwsys_stl::string& result) #if KWSYS_CXX_HAS_UNSETENV /* unsetenv("A") removes A from the environment. On older platforms it returns void instead of int. */ -static int kwsysUnPutEnv(const char* env) +static int kwsysUnPutEnv(const kwsys_stl::string& env) { - if(const char* eq = strchr(env, '=')) + size_t pos = env.find('='); + if(pos != env.npos) { - std::string name(env, eq-env); + std::string name = env.substr(0, pos); unsetenv(name.c_str()); } else { - unsetenv(env); + unsetenv(env.c_str()); } return 0; } #elif defined(KWSYS_PUTENV_EMPTY) || defined(KWSYS_PUTENV_NAME) /* putenv("A=") or putenv("A") removes A from the environment. */ -static int kwsysUnPutEnv(const char* env) +static int kwsysUnPutEnv(const kwsys_stl::string& env) { int err = 0; - const char* eq = strchr(env, '='); - size_t const len = eq? (size_t)(eq-env) : strlen(env); + size_t pos = env.find('='); + size_t const len = pos == env.npos ? env.size() : pos; # ifdef KWSYS_PUTENV_EMPTY size_t const sz = len + 2; # else @@ -442,7 +460,7 @@ static int kwsysUnPutEnv(const char* env) { return -1; } - strncpy(buf, env, len); + strncpy(buf, env.c_str(), len); # ifdef KWSYS_PUTENV_EMPTY buf[len] = '='; buf[len+1] = 0; @@ -471,17 +489,17 @@ static int kwsysUnPutEnv(const char* env) #else /* Manipulate the "environ" global directly. */ -static int kwsysUnPutEnv(const char* env) +static int kwsysUnPutEnv(const kwsys_stl::string& env) { - const char* eq = strchr(env, '='); - size_t const len = eq? (size_t)(eq-env) : strlen(env); + size_t pos = env.find('='); + size_t const len = pos == env.npos ? env.size() : pos; int in = 0; int out = 0; while(environ[in]) { if(strlen(environ[in]) > len && environ[in][len] == '=' && - strncmp(env, environ[in], len) == 0) + strncmp(env.c_str(), environ[in], len) == 0) { ++in; } @@ -504,12 +522,13 @@ static int kwsysUnPutEnv(const char* env) /* setenv("A", "B", 1) will set A=B in the environment and makes its own copies of the strings. */ -bool SystemTools::PutEnv(const char* env) +bool SystemTools::PutEnv(const kwsys_stl::string& env) { - if(const char* eq = strchr(env, '=')) + size_t pos = env.find('='); + if(pos != env.npos) { - std::string name(env, eq-env); - return setenv(name.c_str(), eq+1, 1) == 0; + std::string name = env.substr(0, pos); + return setenv(name.c_str(), env.c_str() + pos + 1, 1) == 0; } else { @@ -517,7 +536,7 @@ bool SystemTools::PutEnv(const char* env) } } -bool SystemTools::UnPutEnv(const char* env) +bool SystemTools::UnPutEnv(const kwsys_stl::string& env) { return kwsysUnPutEnv(env) == 0; } @@ -603,14 +622,14 @@ public: static kwsysEnv kwsysEnvInstance; -bool SystemTools::PutEnv(const char* env) +bool SystemTools::PutEnv(const kwsys_stl::string& env) { - return kwsysEnvInstance.Put(env); + return kwsysEnvInstance.Put(env.c_str()); } -bool SystemTools::UnPutEnv(const char* env) +bool SystemTools::UnPutEnv(const kwsys_stl::string& env) { - return kwsysEnvInstance.UnPut(env); + return kwsysEnvInstance.UnPut(env.c_str()); } #endif @@ -689,8 +708,35 @@ bool SystemTools::MakeDirectory(const kwsys_stl::string& path) // replace replace with with as many times as it shows up in source. // write the result into source. void SystemTools::ReplaceString(kwsys_stl::string& source, - const char* replace, - const char* with) + const kwsys_stl::string& replace, + const kwsys_stl::string& with) +{ + // do while hangs if replaceSize is 0 + if (replace.empty()) + { + return; + } + + SystemTools::ReplaceString(source, replace.c_str(), replace.size(), with); +} + +void SystemTools::ReplaceString(kwsys_stl::string& source, + const char* replace, + const char* with) +{ + // do while hangs if replaceSize is 0 + if (!*replace) + { + return; + } + + SystemTools::ReplaceString(source, replace, strlen(replace), with ? with : ""); +} + +void SystemTools::ReplaceString(kwsys_stl::string& source, + const char* replace, + size_t replaceSize, + const kwsys_stl::string& with) { const char *src = source.c_str(); char *searchPos = const_cast<char *>(strstr(src,replace)); @@ -702,12 +748,6 @@ void SystemTools::ReplaceString(kwsys_stl::string& source, } // perform replacements until done - size_t replaceSize = strlen(replace); - // do while hangs if replaceSize is 0 - if(replaceSize == 0) - { - return; - } char *orig = strdup(src); char *currentPos = orig; searchPos = searchPos - src + orig; @@ -739,20 +779,20 @@ void SystemTools::ReplaceString(kwsys_stl::string& source, #endif #if defined(_WIN32) && !defined(__CYGWIN__) -static bool SystemToolsParseRegistryKey(const char* key, +static bool SystemToolsParseRegistryKey(const kwsys_stl::string& key, HKEY& primaryKey, kwsys_stl::string& second, kwsys_stl::string& valuename) { kwsys_stl::string primary = key; - size_t start = primary.find("\\"); + size_t start = primary.find('\\'); if (start == kwsys_stl::string::npos) { return false; } - size_t valuenamepos = primary.find(";"); + size_t valuenamepos = primary.find(';'); if (valuenamepos != kwsys_stl::string::npos) { valuename = primary.substr(valuenamepos+1); @@ -810,7 +850,7 @@ static DWORD SystemToolsMakeRegistryMode(DWORD mode, #if defined(_WIN32) && !defined(__CYGWIN__) bool -SystemTools::GetRegistrySubKeys(const char *key, +SystemTools::GetRegistrySubKeys(const kwsys_stl::string& key, kwsys_stl::vector<kwsys_stl::string>& subkeys, KeyWOW64 view) { @@ -849,7 +889,7 @@ SystemTools::GetRegistrySubKeys(const char *key, return true; } #else -bool SystemTools::GetRegistrySubKeys(const char *, +bool SystemTools::GetRegistrySubKeys(const kwsys_stl::string&, kwsys_stl::vector<kwsys_stl::string>&, KeyWOW64) { @@ -865,7 +905,7 @@ bool SystemTools::GetRegistrySubKeys(const char *, // => will return the data of the "Root" value of the key #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, +bool SystemTools::ReadRegistryValue(const kwsys_stl::string& key, kwsys_stl::string &value, KeyWOW64 view) { bool valueset = false; @@ -922,7 +962,7 @@ bool SystemTools::ReadRegistryValue(const char *key, kwsys_stl::string &value, return valueset; } #else -bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &, +bool SystemTools::ReadRegistryValue(const kwsys_stl::string&, kwsys_stl::string &, KeyWOW64) { return false; @@ -938,7 +978,8 @@ bool SystemTools::ReadRegistryValue(const char *, kwsys_stl::string &, // => will set the data of the "Root" value of the key #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::WriteRegistryValue(const char *key, const char *value, +bool SystemTools::WriteRegistryValue(const kwsys_stl::string& key, + const kwsys_stl::string& value, KeyWOW64 view) { HKEY primaryKey = HKEY_CURRENT_USER; @@ -978,7 +1019,7 @@ bool SystemTools::WriteRegistryValue(const char *key, const char *value, return false; } #else -bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64) +bool SystemTools::WriteRegistryValue(const kwsys_stl::string&, const kwsys_stl::string&, KeyWOW64) { return false; } @@ -992,7 +1033,7 @@ bool SystemTools::WriteRegistryValue(const char *, const char *, KeyWOW64) // => will delete the data of the "Root" value of the key #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) +bool SystemTools::DeleteRegistryValue(const kwsys_stl::string& key, KeyWOW64 view) { HKEY primaryKey = HKEY_CURRENT_USER; kwsys_stl::string second; @@ -1023,7 +1064,7 @@ bool SystemTools::DeleteRegistryValue(const char *key, KeyWOW64 view) return false; } #else -bool SystemTools::DeleteRegistryValue(const char *, KeyWOW64) +bool SystemTools::DeleteRegistryValue(const kwsys_stl::string&, KeyWOW64) { return false; } @@ -2245,12 +2286,13 @@ bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_st SystemTools::MakeDirectory(destination_dir); // Open files - -#if defined(_WIN32) || defined(__CYGWIN__) - kwsys::ifstream fin(source.c_str(), - kwsys_ios::ios::binary | kwsys_ios::ios::in); +#if defined(_WIN32) + kwsys::ifstream fin(Encoding::ToNarrow( + SystemTools::ConvertToWindowsExtendedPath(source)).c_str(), + kwsys_ios::ios::in | kwsys_ios_binary); #else - kwsys::ifstream fin(source.c_str()); + kwsys::ifstream fin(source.c_str(), + kwsys_ios::ios::in | kwsys_ios_binary); #endif if(!fin) { @@ -2263,12 +2305,13 @@ bool SystemTools::CopyFileAlways(const kwsys_stl::string& source, const kwsys_st // that do not allow file removal can be modified. SystemTools::RemoveFile(real_destination); -#if defined(_WIN32) || defined(__CYGWIN__) - kwsys::ofstream fout(real_destination.c_str(), - kwsys_ios::ios::binary | kwsys_ios::ios::out | kwsys_ios::ios::trunc); +#if defined(_WIN32) + kwsys::ofstream fout(Encoding::ToNarrow( + SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(), + kwsys_ios::ios::out | kwsys_ios::ios::trunc | kwsys_ios_binary); #else kwsys::ofstream fout(real_destination.c_str(), - kwsys_ios::ios::out | kwsys_ios::ios::trunc); + kwsys_ios::ios::out | kwsys_ios::ios::trunc | kwsys_ios_binary); #endif if(!fout) { @@ -2379,7 +2422,7 @@ bool SystemTools::CopyADirectory(const kwsys_stl::string& source, const kwsys_st // return size of file; also returns zero if no file exists -unsigned long SystemTools::FileLength(const char* filename) +unsigned long SystemTools::FileLength(const kwsys_stl::string& filename) { unsigned long length = 0; #ifdef _WIN32 @@ -2397,7 +2440,7 @@ unsigned long SystemTools::FileLength(const char* filename) } #else struct stat fs; - if (stat(filename, &fs) == 0) + if (stat(filename.c_str(), &fs) == 0) { length = static_cast<unsigned long>(fs.st_size); } @@ -2663,7 +2706,7 @@ size_t SystemTools::GetMaximumFilePathLength() * found. Otherwise, the empty string is returned. */ kwsys_stl::string SystemTools -::FindName(const char* name, +::FindName(const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& userPaths, bool no_system_path) { @@ -2716,7 +2759,7 @@ kwsys_stl::string SystemTools * found. Otherwise, the empty string is returned. */ kwsys_stl::string SystemTools -::FindFile(const char* name, +::FindFile(const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& userPaths, bool no_system_path) { @@ -2735,7 +2778,7 @@ kwsys_stl::string SystemTools * found. Otherwise, the empty string is returned. */ kwsys_stl::string SystemTools -::FindDirectory(const char* name, +::FindDirectory(const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& userPaths, bool no_system_path) { @@ -3078,29 +3121,29 @@ bool SystemTools::FileIsSymlink(const kwsys_stl::string& name) } #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::CreateSymlink(const char*, const char*) +bool SystemTools::CreateSymlink(const kwsys_stl::string&, const kwsys_stl::string&) { return false; } #else -bool SystemTools::CreateSymlink(const char* origName, const char* newName) +bool SystemTools::CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName) { - return symlink(origName, newName) >= 0; + return symlink(origName.c_str(), newName.c_str()) >= 0; } #endif #if defined(_WIN32) && !defined(__CYGWIN__) -bool SystemTools::ReadSymlink(const char*, kwsys_stl::string&) +bool SystemTools::ReadSymlink(const kwsys_stl::string&, kwsys_stl::string&) { return false; } #else -bool SystemTools::ReadSymlink(const char* newName, +bool SystemTools::ReadSymlink(const kwsys_stl::string& newName, kwsys_stl::string& origName) { char buf[KWSYS_SYSTEMTOOLS_MAXPATH+1]; int count = - static_cast<int>(readlink(newName, buf, KWSYS_SYSTEMTOOLS_MAXPATH)); + static_cast<int>(readlink(newName.c_str(), buf, KWSYS_SYSTEMTOOLS_MAXPATH)); if(count >= 0) { // Add null-terminator. @@ -3136,14 +3179,14 @@ kwsys_stl::string SystemTools::GetCurrentWorkingDirectory(bool collapse) return path; } -kwsys_stl::string SystemTools::GetProgramPath(const char* in_name) +kwsys_stl::string SystemTools::GetProgramPath(const kwsys_stl::string& in_name) { kwsys_stl::string dir, file; SystemTools::SplitProgramPath(in_name, dir, file); return dir; } -bool SystemTools::SplitProgramPath(const char* in_name, +bool SystemTools::SplitProgramPath(const kwsys_stl::string& in_name, kwsys_stl::string& dir, kwsys_stl::string& file, bool) @@ -3409,7 +3452,62 @@ kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path SystemTools::CheckTranslationPath(newPath); #ifdef _WIN32 - newPath = SystemTools::GetActualCaseForPath(newPath.c_str()); + newPath = SystemTools::GetActualCaseForPath(newPath); + SystemTools::ConvertToUnixSlashes(newPath); +#endif + // Return the reconstructed path. + return newPath; +} + +kwsys_stl::string SystemTools::CollapseFullPath(const kwsys_stl::string& in_path, + const kwsys_stl::string& in_base) +{ + // Collect the output path components. + kwsys_stl::vector<kwsys_stl::string> out_components; + + // Split the input path components. + kwsys_stl::vector<kwsys_stl::string> path_components; + SystemTools::SplitPath(in_path, path_components); + + // If the input path is relative, start with a base path. + if(path_components[0].length() == 0) + { + kwsys_stl::vector<kwsys_stl::string> base_components; + // Use the given base path. + SystemTools::SplitPath(in_base, base_components); + + // Append base path components to the output path. + out_components.push_back(base_components[0]); + SystemToolsAppendComponents(out_components, + base_components.begin()+1, + base_components.end()); + } + + // Append input path components to the output path. + SystemToolsAppendComponents(out_components, + path_components.begin(), + path_components.end()); + + // Transform the path back to a string. + kwsys_stl::string newPath = SystemTools::JoinPath(out_components); + + // Update the translation table with this potentially new path. I am not + // sure why this line is here, it seems really questionable, but yet I + // would put good money that if I remove it something will break, basically + // from what I can see it created a mapping from the collapsed path, to be + // replaced by the input path, which almost completely does the opposite of + // this function, the only thing preventing this from happening a lot is + // that if the in_path has a .. in it, then it is not added to the + // translation table. So for most calls this either does nothing due to the + // .. or it adds a translation between identical paths as nothing was + // collapsed, so I am going to try to comment it out, and see what hits the + // fan, hopefully quickly. + // Commented out line below: + //SystemTools::AddTranslationPath(newPath, in_path); + + SystemTools::CheckTranslationPath(newPath); +#ifdef _WIN32 + newPath = SystemTools::GetActualCaseForPath(newPath); SystemTools::ConvertToUnixSlashes(newPath); #endif // Return the reconstructed path. @@ -3569,7 +3667,7 @@ static int GetCasePathName(const kwsys_stl::string & pathIn, //---------------------------------------------------------------------------- -kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p) +kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p) { #ifndef _WIN32 return p; @@ -3930,7 +4028,7 @@ kwsys_stl::string SystemTools::GetFilenameName(const kwsys_stl::string& filename kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& filename) { kwsys_stl::string name = SystemTools::GetFilenameName(filename); - kwsys_stl::string::size_type dot_pos = name.find("."); + kwsys_stl::string::size_type dot_pos = name.find('.'); if(dot_pos != kwsys_stl::string::npos) { return name.substr(dot_pos); @@ -3948,7 +4046,7 @@ kwsys_stl::string SystemTools::GetFilenameExtension(const kwsys_stl::string& fil kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string& filename) { kwsys_stl::string name = SystemTools::GetFilenameName(filename); - kwsys_stl::string::size_type dot_pos = name.rfind("."); + kwsys_stl::string::size_type dot_pos = name.rfind('.'); if(dot_pos != kwsys_stl::string::npos) { return name.substr(dot_pos); @@ -3966,7 +4064,7 @@ kwsys_stl::string SystemTools::GetFilenameLastExtension(const kwsys_stl::string& kwsys_stl::string SystemTools::GetFilenameWithoutExtension(const kwsys_stl::string& filename) { kwsys_stl::string name = SystemTools::GetFilenameName(filename); - kwsys_stl::string::size_type dot_pos = name.find("."); + kwsys_stl::string::size_type dot_pos = name.find('.'); if(dot_pos != kwsys_stl::string::npos) { return name.substr(0, dot_pos); @@ -3987,7 +4085,7 @@ kwsys_stl::string SystemTools::GetFilenameWithoutLastExtension(const kwsys_stl::string& filename) { kwsys_stl::string name = SystemTools::GetFilenameName(filename); - kwsys_stl::string::size_type dot_pos = name.rfind("."); + kwsys_stl::string::size_type dot_pos = name.rfind('.'); if(dot_pos != kwsys_stl::string::npos) { return name.substr(0, dot_pos); @@ -4276,7 +4374,7 @@ bool SystemTools::GetShortPath(const kwsys_stl::string& path, kwsys_stl::string& #endif } -void SystemTools::SplitProgramFromArgs(const char* path, +void SystemTools::SplitProgramFromArgs(const kwsys_stl::string& path, kwsys_stl::string& program, kwsys_stl::string& args) { // see if this is a full path to a program @@ -4352,7 +4450,7 @@ kwsys_stl::string SystemTools::GetCurrentDateTime(const char* format) return kwsys_stl::string(buf); } -kwsys_stl::string SystemTools::MakeCidentifier(const char* s) +kwsys_stl::string SystemTools::MakeCidentifier(const kwsys_stl::string& s) { kwsys_stl::string str(s); if (str.find_first_of("0123456789") == 0) @@ -4634,7 +4732,11 @@ kwsys_stl::string SystemTools::GetOperatingSystemNameAndVersion() #ifdef KWSYS_WINDOWS_DEPRECATED_GetVersionEx # pragma warning (push) -# pragma warning (disable:4996) +# ifdef __INTEL_COMPILER +# pragma warning (disable:1478) +# else +# pragma warning (disable:4996) +# endif #endif bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&osvi); if (!bOsVersionInfoEx) diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index e88bc8f..beb2a7e 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -89,9 +89,9 @@ public: * then an underscore is prepended. Note that this can produce * identifiers that the standard reserves (_[A-Z].* and __.*). */ - static kwsys_stl::string MakeCidentifier(const char* s); + static kwsys_stl::string MakeCidentifier(const kwsys_stl::string& s); - static kwsys_stl::string MakeCindentifier(const char* s) + static kwsys_stl::string MakeCindentifier(const kwsys_stl::string& s) { return MakeCidentifier(s); } @@ -102,6 +102,9 @@ public: static void ReplaceString(kwsys_stl::string& source, const char* replace, const char* with); + static void ReplaceString(kwsys_stl::string& source, + const kwsys_stl::string& replace, + const kwsys_stl::string& with); /** * Return a capitalized string (i.e the first letter is uppercased, @@ -306,7 +309,7 @@ public: /** * Return file length */ - static unsigned long FileLength(const char *filename); + static unsigned long FileLength(const kwsys_stl::string& filename); /** Change the modification time or create a file @@ -335,15 +338,15 @@ public: * does not exist path is returned unchanged. This does nothing * on unix but return path. */ - static kwsys_stl::string GetActualCaseForPath(const char* path); + static kwsys_stl::string GetActualCaseForPath(const kwsys_stl::string& path); /** * Given the path to a program executable, get the directory part of * the path with the file stripped off. If there is no directory * part, the empty string is returned. */ - static kwsys_stl::string GetProgramPath(const char*); - static bool SplitProgramPath(const char* in_name, + static kwsys_stl::string GetProgramPath(const kwsys_stl::string&); + static bool SplitProgramPath(const kwsys_stl::string& in_name, kwsys_stl::string& dir, kwsys_stl::string& file, bool errorReport = true); @@ -376,6 +379,8 @@ public: static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative); static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative, const char* in_base); + static kwsys_stl::string CollapseFullPath(const kwsys_stl::string& in_relative, + const kwsys_stl::string& in_base); /** * Get the real path for a given path, removing all symlinks. In @@ -446,7 +451,7 @@ public: * Split a program from its arguments and handle spaces in the paths */ static void SplitProgramFromArgs( - const char* path, + const kwsys_stl::string& path, kwsys_stl::string& program, kwsys_stl::string& args); /** @@ -582,7 +587,7 @@ public: * Find a file in the system PATH, with optional extra paths */ static kwsys_stl::string FindFile( - const char* name, + const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& path = kwsys_stl::vector<kwsys_stl::string>(), bool no_system_path = false); @@ -591,7 +596,7 @@ public: * Find a directory in the system PATH, with optional extra paths */ static kwsys_stl::string FindDirectory( - const char* name, + const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& path = kwsys_stl::vector<kwsys_stl::string>(), bool no_system_path = false); @@ -662,13 +667,13 @@ public: * Create a symbolic link if the platform supports it. Returns whether * creation succeded. */ - static bool CreateSymlink(const char* origName, const char* newName); + static bool CreateSymlink(const kwsys_stl::string& origName, const kwsys_stl::string& newName); /** * Read the contents of a symbolic link. Returns whether reading * succeded. */ - static bool ReadSymlink(const char* newName, kwsys_stl::string& origName); + static bool ReadSymlink(const kwsys_stl::string& newName, kwsys_stl::string& origName); /** * Try to locate the file 'filename' in the directory 'dir'. @@ -750,26 +755,26 @@ public: /** * Get a list of subkeys. */ - static bool GetRegistrySubKeys(const char *key, + static bool GetRegistrySubKeys(const kwsys_stl::string& key, kwsys_stl::vector<kwsys_stl::string>& subkeys, KeyWOW64 view = KeyWOW64_Default); /** * Read a registry value */ - static bool ReadRegistryValue(const char *key, kwsys_stl::string &value, + static bool ReadRegistryValue(const kwsys_stl::string& key, kwsys_stl::string &value, KeyWOW64 view = KeyWOW64_Default); /** * Write a registry value */ - static bool WriteRegistryValue(const char *key, const char *value, + static bool WriteRegistryValue(const kwsys_stl::string& key, const kwsys_stl::string& value, KeyWOW64 view = KeyWOW64_Default); /** * Delete a registry value */ - static bool DeleteRegistryValue(const char *key, + static bool DeleteRegistryValue(const kwsys_stl::string& key, KeyWOW64 view = KeyWOW64_Default); /** ----------------------------------------------------------------- @@ -789,15 +794,17 @@ public: * Read an environment variable */ static const char* GetEnv(const char* key); + static const char* GetEnv(const kwsys_stl::string& key); static bool GetEnv(const char* key, kwsys_stl::string& result); + static bool GetEnv(const kwsys_stl::string& key, kwsys_stl::string& result); /** Put a string into the environment of the form var=value */ - static bool PutEnv(const char* env); + static bool PutEnv(const kwsys_stl::string& env); /** Remove a string from the environment. Input is of the form "var" or "var=value" (value is ignored). */ - static bool UnPutEnv(const char* env); + static bool UnPutEnv(const kwsys_stl::string& env); /** * Get current working directory CWD @@ -906,6 +913,14 @@ private: } /** + * Actual implementation of ReplaceString. + */ + static void ReplaceString(kwsys_stl::string& source, + const char* replace, + size_t replaceSize, + const kwsys_stl::string& with); + + /** * Actual implementation of FileIsFullPath. */ static bool FileIsFullPath(const char*, size_t); @@ -915,7 +930,7 @@ private: * optional extra paths. */ static kwsys_stl::string FindName( - const char* name, + const kwsys_stl::string& name, const kwsys_stl::vector<kwsys_stl::string>& path = kwsys_stl::vector<kwsys_stl::string>(), bool no_system_path = false); diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index e13003f..d13f79a 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -175,6 +175,7 @@ static const char* kwsysTerminalVT100Names[] = "xterm-88color", "xterm-color", "xterm-debian", + "xterm-termite", 0 }; diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake index 16bc969..0da0f63 100644 --- a/Source/kwsys/kwsysPlatformTests.cmake +++ b/Source/kwsys/kwsysPlatformTests.cmake @@ -25,39 +25,39 @@ MACRO(KWSYS_PLATFORM_TEST lang var description invert) FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "${description} compiled with the following output:\n${OUTPUT}\n\n") - ELSE(${var}_COMPILED) + ELSE() FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${description} failed to compile with the following output:\n${OUTPUT}\n\n") - ENDIF(${var}_COMPILED) + ENDIF() IF(${invert} MATCHES INVERT) IF(${var}_COMPILED) MESSAGE(STATUS "${description} - no") - ELSE(${var}_COMPILED) + ELSE() MESSAGE(STATUS "${description} - yes") - ENDIF(${var}_COMPILED) - ELSE(${invert} MATCHES INVERT) + ENDIF() + ELSE() IF(${var}_COMPILED) MESSAGE(STATUS "${description} - yes") - ELSE(${var}_COMPILED) + ELSE() MESSAGE(STATUS "${description} - no") - ENDIF(${var}_COMPILED) - ENDIF(${invert} MATCHES INVERT) + ENDIF() + ENDIF() ENDIF() IF(${invert} MATCHES INVERT) IF(${var}_COMPILED) SET(${var} 0) - ELSE(${var}_COMPILED) + ELSE() SET(${var} 1) - ENDIF(${var}_COMPILED) - ELSE(${invert} MATCHES INVERT) + ENDIF() + ELSE() IF(${var}_COMPILED) SET(${var} 1) - ELSE(${var}_COMPILED) + ELSE() SET(${var} 0) - ENDIF(${var}_COMPILED) - ENDIF(${invert} MATCHES INVERT) -ENDMACRO(KWSYS_PLATFORM_TEST) + ENDIF() + ENDIF() +ENDMACRO() MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert) IF(NOT DEFINED ${var}) @@ -74,63 +74,63 @@ MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert) FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n") - ELSE(${var}) + ELSE() FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "${description} compiled and ran with the following output:\n${OUTPUT}\n\n") - ENDIF(${var}) - ELSE(${var}_COMPILED) + ENDIF() + ELSE() FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${description} failed to compile with the following output:\n${OUTPUT}\n\n") SET(${var} -1 CACHE INTERNAL "${description} failed to compile.") - ENDIF(${var}_COMPILED) + ENDIF() IF(${invert} MATCHES INVERT) IF(${var}_COMPILED) IF(${var}) MESSAGE(STATUS "${description} - yes") - ELSE(${var}) + ELSE() MESSAGE(STATUS "${description} - no") - ENDIF(${var}) - ELSE(${var}_COMPILED) + ENDIF() + ELSE() MESSAGE(STATUS "${description} - failed to compile") - ENDIF(${var}_COMPILED) - ELSE(${invert} MATCHES INVERT) + ENDIF() + ELSE() IF(${var}_COMPILED) IF(${var}) MESSAGE(STATUS "${description} - no") - ELSE(${var}) + ELSE() MESSAGE(STATUS "${description} - yes") - ENDIF(${var}) - ELSE(${var}_COMPILED) + ENDIF() + ELSE() MESSAGE(STATUS "${description} - failed to compile") - ENDIF(${var}_COMPILED) - ENDIF(${invert} MATCHES INVERT) + ENDIF() + ENDIF() ENDIF() IF(${invert} MATCHES INVERT) IF(${var}_COMPILED) IF(${var}) SET(${var} 1) - ELSE(${var}) + ELSE() SET(${var} 0) - ENDIF(${var}) - ELSE(${var}_COMPILED) + ENDIF() + ELSE() SET(${var} 1) - ENDIF(${var}_COMPILED) - ELSE(${invert} MATCHES INVERT) + ENDIF() + ELSE() IF(${var}_COMPILED) IF(${var}) SET(${var} 0) - ELSE(${var}) + ELSE() SET(${var} 1) - ENDIF(${var}) - ELSE(${var}_COMPILED) + ENDIF() + ELSE() SET(${var} 0) - ENDIF(${var}_COMPILED) - ENDIF(${invert} MATCHES INVERT) -ENDMACRO(KWSYS_PLATFORM_TEST_RUN) + ENDIF() + ENDIF() +ENDMACRO() MACRO(KWSYS_PLATFORM_C_TEST var description invert) SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES}) @@ -138,7 +138,7 @@ MACRO(KWSYS_PLATFORM_C_TEST var description invert) KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}") SET(KWSYS_PLATFORM_TEST_DEFINES) SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO(KWSYS_PLATFORM_C_TEST) +ENDMACRO() MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert) SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES}) @@ -146,7 +146,7 @@ MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert) KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}") SET(KWSYS_PLATFORM_TEST_DEFINES) SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO(KWSYS_PLATFORM_C_TEST_RUN) +ENDMACRO() MACRO(KWSYS_PLATFORM_CXX_TEST var description invert) SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES}) @@ -156,7 +156,7 @@ MACRO(KWSYS_PLATFORM_CXX_TEST var description invert) SET(KWSYS_PLATFORM_TEST_DEFINES) SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES) -ENDMACRO(KWSYS_PLATFORM_CXX_TEST) +ENDMACRO() MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert) SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES}) @@ -164,7 +164,7 @@ MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert) KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}") SET(KWSYS_PLATFORM_TEST_DEFINES) SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS) -ENDMACRO(KWSYS_PLATFORM_CXX_TEST_RUN) +ENDMACRO() #----------------------------------------------------------------------------- # KWSYS_PLATFORM_INFO_TEST(lang var description) diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx index 3f947f3..82620da 100644 --- a/Source/kwsys/kwsysPlatformTestsCXX.cxx +++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx @@ -548,6 +548,10 @@ int main() #if (defined(__GNUC__) || defined(__PGI)) && !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif +#if defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130 \ + && __linux && __SUNPRO_CC_COMPAT == 'G' +# include <iostream> +#endif #include <cxxabi.h> int main() { diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index b41532b..42b6249 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -124,7 +124,7 @@ static bool CheckFileOperations() res = false; } - if (kwsys::SystemTools::FileLength(testBinFile.c_str()) != 766) + if (kwsys::SystemTools::FileLength(testBinFile) != 766) { kwsys_ios::cerr << "Problem with FileLength - incorrect length for: " @@ -512,7 +512,7 @@ static bool CheckStringOperations() //---------------------------------------------------------------------------- -static bool CheckPutEnv(const char* env, const char* name, const char* value) +static bool CheckPutEnv(const kwsys_stl::string& env, const char* name, const char* value) { if(!kwsys::SystemTools::PutEnv(env)) { diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt index 8df331e..78e9e17 100644 --- a/Tests/BuildDepends/CMakeLists.txt +++ b/Tests/BuildDepends/CMakeLists.txt @@ -28,10 +28,6 @@ function(help_xcode_depends) endif() endfunction() -if("${CMAKE_GENERATOR}" MATCHES "Ninja") - set(HELP_NINJA 1) # TODO Why is this needed? -endif() - # The Intel compiler causes the MSVC linker to crash during # incremental linking, so avoid the /INCREMENTAL:YES flag. if(WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") @@ -69,6 +65,7 @@ file(WRITE ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_exe.h set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_depends_no_shared_check.txt) file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external original\n") +file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in original\n") help_xcode_depends() @@ -181,6 +178,19 @@ else() "external.out is missing") endif() +if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt) + file(STRINGS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt multi1_out) + if("${multi1_out}" STREQUAL "multi1-in original") + message(STATUS "multi1-out2-copy.txt contains '${multi1_out}'") + else() + message(SEND_ERROR "Project did not initially build properly: " + "multi1-out2-copy.txt contains '${multi1_out}'") + endif() +else() + message(SEND_ERROR "Project did not initially build properly: " + "multi1-out2-copy.txt is missing") +endif() + message("Waiting 3 seconds...") execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 3) @@ -206,6 +216,7 @@ if(TEST_LINK_DEPENDS) endif() file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external changed\n") +file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in changed\n") help_xcode_depends() @@ -218,7 +229,7 @@ try_compile(RESULT OUTPUT_VARIABLE OUTPUT) # Xcode is in serious need of help here -if(HELP_XCODE OR HELP_NINJA) +if(HELP_XCODE) try_compile(RESULT ${BuildDepends_BINARY_DIR}/Project ${BuildDepends_SOURCE_DIR}/Project @@ -323,3 +334,16 @@ else() message(SEND_ERROR "Project did not rebuild properly: " "external.out is missing") endif() + +if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt) + file(STRINGS ${BuildDepends_BINARY_DIR}/Project/multi1-out2-copy.txt multi1_out) + if("${multi1_out}" STREQUAL "multi1-in changed") + message(STATUS "multi1-out2-copy.txt contains '${multi1_out}'") + else() + message(SEND_ERROR "Project did not rebuild properly: " + "multi1-out2-copy.txt contains '${multi1_out}'") + endif() +else() + message(SEND_ERROR "Project did not rebuild properly: " + "multi1-out2-copy.txt is missing") +endif() diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt index 9ee4a43..cb9fbf8 100644 --- a/Tests/BuildDepends/Project/CMakeLists.txt +++ b/Tests/BuildDepends/Project/CMakeLists.txt @@ -151,3 +151,16 @@ ExternalProject_Add(ExternalBuild -Dexternal_out=${CMAKE_CURRENT_BINARY_DIR}/external.out INSTALL_COMMAND "" ) + +add_custom_command( + OUTPUT multi1-out1.txt multi1-out2.txt + COMMAND ${CMAKE_COMMAND} -E copy multi1-in.txt multi1-out1.txt + COMMAND ${CMAKE_COMMAND} -E copy multi1-in.txt multi1-out2.txt + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/multi1-in.txt + ) +add_custom_command( + OUTPUT multi1-out2-copy.txt + COMMAND ${CMAKE_COMMAND} -E copy multi1-out2.txt multi1-out2-copy.txt + DEPENDS multi1-out2.txt + ) +add_custom_target(multi1 ALL DEPENDS multi1-out2-copy.txt) diff --git a/Tests/CFBundleTest/VerifyResult.cmake b/Tests/CFBundleTest/VerifyResult.cmake index e622900..e637bb1 100644 --- a/Tests/CFBundleTest/VerifyResult.cmake +++ b/Tests/CFBundleTest/VerifyResult.cmake @@ -14,13 +14,10 @@ message(STATUS "CTEST_CONFIGURATION_TYPE='${CTEST_CONFIGURATION_TYPE}'") message(STATUS "dir='${dir}'") message(STATUS "gen='${gen}'") -if(gen MATCHES "Make" OR - "${CTEST_CONFIGURATION_TYPE}" STREQUAL "" OR - "${CTEST_CONFIGURATION_TYPE}" STREQUAL "." OR - "${CTEST_CONFIGURATION_TYPE}" STREQUAL "NoConfig") - set(expected_filename "${dir}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest") -else() +if(gen STREQUAL "Xcode") set(expected_filename "${dir}/${CTEST_CONFIGURATION_TYPE}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest") +else() + set(expected_filename "${dir}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest") endif() if(NOT EXISTS "${expected_filename}") diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt index 8c99f64..7ef3c03 100644 --- a/Tests/CMakeLib/CMakeLists.txt +++ b/Tests/CMakeLib/CMakeLists.txt @@ -48,3 +48,5 @@ if(TEST_CompileCommandOutput) add_executable(runcompilecommands run_compile_commands.cxx) target_link_libraries(runcompilecommands CMakeLib) endif() + +add_subdirectory(PseudoMemcheck) diff --git a/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt new file mode 100644 index 0000000..c53befc --- /dev/null +++ b/Tests/CMakeLib/PseudoMemcheck/CMakeLists.txt @@ -0,0 +1,41 @@ +foreach (_retval 0 1) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY) +endforeach () + +include_directories(${CMake_SOURCE_DIR}/Source ${CMake_BINARY_DIR}/Source) + +# create binaries that we will use as a pseudo memory checker +add_executable(pseudo_valgrind "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") +set_target_properties(pseudo_valgrind PROPERTIES OUTPUT_NAME valgrind) +target_link_libraries(pseudo_valgrind CMakeLib) + +add_executable(pseudo_purify "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") +set_target_properties(pseudo_purify PROPERTIES OUTPUT_NAME purify) +target_link_libraries(pseudo_purify CMakeLib) +add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") +set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC) +target_link_libraries(pseudo_BC CMakeLib) + +# binary to be used as pre- and post-memcheck command that fails +add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx") +target_link_libraries(memcheck_fail CMakeLib) + +# Binaries that are used as memchecker that do not write the expected +# output file. Need to be in their own subdirectory as they have the +# same filenames. +add_subdirectory(NoLog) + +# Xcode 2.x forgets to create the output directory before linking +# the individual architectures. +if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]") + foreach(t + memcheck_fail + pseudo_BC + pseudo_purify + pseudo_valgrind + ) + add_custom_command(TARGET ${t} + PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}" + ) + endforeach() +endif() diff --git a/Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt b/Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt index 3a45bfe..3a45bfe 100644 --- a/Tests/CTestTestMemcheck/NoLogDummyChecker/CMakeLists.txt +++ b/Tests/CMakeLib/PseudoMemcheck/NoLog/CMakeLists.txt diff --git a/Tests/CTestTestMemcheck/memtester.cxx.in b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in index 43c0ba7..43c0ba7 100644 --- a/Tests/CTestTestMemcheck/memtester.cxx.in +++ b/Tests/CMakeLib/PseudoMemcheck/memtester.cxx.in diff --git a/Tests/CMakeLib/testXMLSafe.cxx b/Tests/CMakeLib/testXMLSafe.cxx index 60442fa..9e4960c 100644 --- a/Tests/CMakeLib/testXMLSafe.cxx +++ b/Tests/CMakeLib/testXMLSafe.cxx @@ -34,7 +34,7 @@ int testXMLSafe(int, char*[]) for(test_pair const* p = pairs; p->in; ++p) { cmXMLSafe xs(p->in); - cmOStringStream oss; + std::ostringstream oss; oss << xs; std::string out = oss.str(); if(out != p->out) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 40fef07..3aecd9b 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -110,10 +110,6 @@ if(BUILD_TESTING) add_subdirectory(FindPackageModeMakefileTest) - if(NOT CMake_TEST_EXTERNAL_CMAKE) - add_subdirectory(CTestTestMemcheck) - endif() - # Collect a list of all test build directories. set(TEST_BUILD_DIRS) @@ -171,7 +167,7 @@ if(BUILD_TESTING) OUTPUT_VARIABLE OSX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(OSX_VERSION MATCHES "^10\\.[0123]" OR OSX_VERSION MATCHES "ProductVersion:\t10\\.[0123]") + if(OSX_VERSION VERSION_LESS 10.4) message(STATUS "Forcing CTEST_TEST_CPACK=OFF on OSX < 10.4") message(STATUS "OSX_VERSION='${OSX_VERSION}'") set(CTEST_TEST_CPACK OFF) @@ -255,6 +251,7 @@ if(BUILD_TESTING) endif() ADD_TEST_MACRO(COnly COnly) ADD_TEST_MACRO(CxxOnly CxxOnly) + ADD_TEST_MACRO(CxxSubdirC CxxSubdirC) ADD_TEST_MACRO(IPO COnly/COnly) ADD_TEST_MACRO(OutDir runtime/OutDir) ADD_TEST_MACRO(ObjectLibrary UseCshared) @@ -291,12 +288,13 @@ if(BUILD_TESTING) ADD_TEST_MACRO(ConfigSources ConfigSources) endif() ADD_TEST_MACRO(SourcesProperty SourcesProperty) + ADD_TEST_MACRO(SourceFileProperty SourceFileProperty) if(CMAKE_CXX_COMPILER_ID STREQUAL GNU - AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) + AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) set(runCxxDialectTest 1) endif() if(CMAKE_CXX_COMPILER_ID STREQUAL Clang - AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.9) + AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) if(NOT APPLE OR POLICY CMP0025) set(runCxxDialectTest 1) endif() @@ -690,7 +688,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release FAIL_REGULAR_EXPRESSION "Unexpected: ") list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ArgumentExpansion") - add_test(GeneratorExpression ${CMAKE_CTEST_COMMAND} + add_test(GeneratorExpression + ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} --build-and-test "${CMake_SOURCE_DIR}/Tests/GeneratorExpression" "${CMake_BINARY_DIR}/Tests/GeneratorExpression" @@ -715,6 +714,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand") + ADD_TEST_MACRO(CustomCommandByproducts CustomCommandByproducts) + ADD_TEST_MACRO(EmptyDepends ${CMAKE_CTEST_COMMAND}) add_test(CustomCommandWorkingDirectory ${CMAKE_CTEST_COMMAND} @@ -950,7 +951,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set(CPackRun_CPackGen "-DCPackGen=${CPackGen}") foreach(CPackComponentWay ${CWAYLST}) set(CPackRun_CPackComponentWay "-DCPackComponentWay=${CPackComponentWay}") - add_test(CPackComponentsForAll-${CPackGen}-${CPackComponentWay} ${CMAKE_CTEST_COMMAND} + add_test(CPackComponentsForAll-${CPackGen}-${CPackComponentWay} + ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} --build-and-test "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll" "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}" @@ -1242,6 +1244,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release endif() endif() + if(CMake_TEST_FindGSL) + add_subdirectory(FindGSL) + endif() + if(CMake_TEST_FindJsonCpp) + add_subdirectory(FindJsonCpp) + endif() + find_package(GTK2 QUIET) if(GTK2_FOUND) add_subdirectory(FindGTK2) @@ -1781,6 +1790,27 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release endif() if(WIN32) + # Macro to search for available Windows CE SDKs in the windows Registry + macro(select_wince_sdk selected_reg selected_sdk) + if(CMAKE_HOST_WIN32) + execute_process(COMMAND reg QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows CE Tools\\SDKs" + OUTPUT_VARIABLE sdk_reg + ERROR_VARIABLE my_err) + string(REGEX REPLACE "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Wow6432Node\\\\Microsoft\\\\Windows CE Tools\\\\SDKs\\\\" ";" sdk_list "${sdk_reg}") + list(LENGTH sdk_list sdk_list_len) + if (${sdk_list_len} GREATER 1) + list(GET sdk_list 1 _sdk) # The first entry is always empty due to the regex replace above + string(STRIP ${_sdk} _sdk) # Make sure there is no newline in the SDK name + endif() + # Build a key to be used by get_filename_component that is pointing to the SDK directory + set(_reg "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows CE Tools\\SDKs\\${_sdk}]") + + # Set return values + set(${selected_reg} ${_reg}) + set(${selected_sdk} ${_sdk}) + endif(CMAKE_HOST_WIN32) + endmacro(select_wince_sdk) + set(reg_vs10 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;InstallDir]") set(reg_vs11 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0;InstallDir]") set(reg_vs12 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\12.0;InstallDir]") @@ -1788,8 +1818,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set(reg_ws81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.1;InstallationFolder]") set(reg_wp80 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.0;InstallationFolder]") set(reg_wp81 "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\WindowsPhone\\v8.1;InstallationFolder]") + select_wince_sdk(reg_wince wince_sdk) set(reg_tegra "[HKEY_LOCAL_MACHINE\\SOFTWARE\\NVIDIA Corporation\\Nsight Tegra;sdkRoot]") - foreach(reg vs10 vs11 vs12 ws80 ws81 wp80 wp81 tegra) + foreach(reg vs10 vs11 vs12 ws80 ws81 wp80 wp81 wince tegra) get_filename_component(r "${reg_${reg}}" ABSOLUTE) if(IS_DIRECTORY "${r}") set(${reg} 1) @@ -1835,6 +1866,35 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release endif() endif() + if(WIN32 AND wince) + macro(add_test_VSWinCE name generator systemName systemVersion generatorPlatform) + # TODO: Fix the tutorial to make it work in cross compile + # currently the MakeTable is build for target and can not be used on the host + # This happens in part 5 so we build only part 1-4 of the tutorial + foreach(STP RANGE 1 4) + add_test(NAME "TutorialStep${STP}.${name}" COMMAND ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Tutorial/Step${STP}" + "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}_${name}" + --build-generator "${generator}" + --build-project Tutorial + --build-config $<CONFIGURATION> + --build-options -DCMAKE_SYSTEM_NAME=${systemName} + -DCMAKE_SYSTEM_VERSION=${systemVersion} + -DCMAKE_GENERATOR_PLATFORM=${generatorPlatform}) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Tutorial/Step${STP}_${name}") + endforeach() + endmacro() + + if(vs11) + add_test_VSWinCE(vs11-ce80-ARM "Visual Studio 11 2012" WindowsCE 8.0 ${wince_sdk}) + endif() + + if(vs12) + add_test_VSWinCE(vs12-ce80-ARM "Visual Studio 12 2013" WindowsCE 8.0 ${wince_sdk}) + endif() + endif() + if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ") macro(add_test_VSNsightTegra name generator) add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND} @@ -1879,16 +1939,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ${BundleTestInstallDir}/Applications/SecondBundleExe.app/Contents/MacOS/SecondBundleExe) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleTest") - add_test(CFBundleTest ${CMAKE_CTEST_COMMAND} + add_test(NAME CFBundleTest COMMAND ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/CFBundleTest" "${CMake_BINARY_DIR}/Tests/CFBundleTest" --build-two-config ${build_generator_args} --build-project CFBundleTest + --build-config $<CONFIGURATION> --build-options ${build_options} --test-command - ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=\${CTEST_CONFIGURATION_TYPE} + ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=$<CONFIGURATION> -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest -Dgen=${CMAKE_GENERATOR} -P ${CMake_SOURCE_DIR}/Tests/CFBundleTest/VerifyResult.cmake) @@ -1990,7 +2051,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release PASS_REGULAR_EXPRESSION "uninitialized variable 'USED_VARIABLE'") list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/WarnUninitialized") - add_test(TestsWorkingDirectory ${CMAKE_CTEST_COMMAND} + add_test(TestsWorkingDirectory + ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} --build-and-test "${CMake_SOURCE_DIR}/Tests/TestsWorkingDirectory" "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory" diff --git a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in index 59b2890..33fe5f3 100644 --- a/Tests/CMakeTests/CheckSourceTreeTest.cmake.in +++ b/Tests/CMakeTests/CheckSourceTreeTest.cmake.in @@ -268,12 +268,12 @@ if(NOT ov STREQUAL "") if(consider) if(is_git_checkout) - if(line MATCHES "^#[ \t]*modified:") + if(line MATCHES "^#?[ \t]*modified:") message(" locally modified file detected...") set(modifications 1) endif() - if(line MATCHES "^# Untracked") + if(line MATCHES "^(# )?Untracked") message(" locally non-added file/directory detected...") set(nonadditions 1) endif() diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in index a9fe428..92e70c3 100644 --- a/Tests/CMakeTests/StringTest.cmake.in +++ b/Tests/CMakeTests/StringTest.cmake.in @@ -63,7 +63,7 @@ check_cmake_test(String # Execute each test listed in StringTestScript.cmake: # set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake") -set(number_of_tests_expected 69) +set(number_of_tests_expected 70) include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake") execute_all_script_tests(${scriptname} number_of_tests_executed) @@ -75,6 +75,6 @@ message(STATUS "scriptname='${scriptname}'") message(STATUS "number_of_tests_executed='${number_of_tests_executed}'") message(STATUS "number_of_tests_expected='${number_of_tests_expected}'") -if(number_of_tests_executed LESS number_of_tests_expected) +if(NOT number_of_tests_executed EQUAL number_of_tests_expected) message(FATAL_ERROR "error: some test cases were skipped") endif() diff --git a/Tests/CMakeTests/StringTestScript.cmake b/Tests/CMakeTests/StringTestScript.cmake index a562e71..44d5653 100644 --- a/Tests/CMakeTests/StringTestScript.cmake +++ b/Tests/CMakeTests/StringTestScript.cmake @@ -122,14 +122,17 @@ elseif(testname STREQUAL substring_not_enough_args) # fail elseif(testname STREQUAL substring_begin_too_large) # fail string(SUBSTRING "abcdefg" 25 100 v) -elseif(testname STREQUAL substring_end_too_large) # fail +elseif(testname STREQUAL substring_end_larger_than_strlen) # pass string(SUBSTRING "abcdefg" 1 100 v) elseif(testname STREQUAL substring_begin_less_than_zero) # fail - string(SUBSTRING "abcdefg" -2 4 v) + string(SUBSTRING "abcdefg" -1 4 v) -elseif(testname STREQUAL substring_end_less_than_begin) # fail - string(SUBSTRING "abcdefg" 6 3 v) +elseif(testname STREQUAL substring_end_less_than_zero) # pass + string(SUBSTRING "abcdefg" 0 -1 v) + +elseif(testname STREQUAL substring_end_less_than_begin) # pass + string(SUBSTRING "abcdefg" 6 0 v) elseif(testname STREQUAL length_not_enough_args) # fail string(LENGTH) diff --git a/Tests/CMakeTests/VersionTest.cmake.in b/Tests/CMakeTests/VersionTest.cmake.in index 9e31cb4..4e946ab 100644 --- a/Tests/CMakeTests/VersionTest.cmake.in +++ b/Tests/CMakeTests/VersionTest.cmake.in @@ -8,9 +8,85 @@ else() message("CMAKE_VERSION=[${CMAKE_VERSION}] is not less than [${min_ver}]") endif() -set(v 1.2.3.4.5.6.7) -if("${v}.8" VERSION_LESS "${v}.9") - message(STATUS "${v}.8 is less than ${v}.9") -else() - message(FATAL_ERROR "${v}.8 is not less than ${v}.9?") -endif() +set(EQUALV "1 1") +list(APPEND EQUALV "1.0 1") +list(APPEND EQUALV "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 1") +list(APPEND EQUALV "1.2.3.4.5.6.7 1.2.3.4.5.6.7") +list(APPEND EQUALV "1.2.3.4.5.6.7.8.9 1.2.3.4.5.6.7.8.9") + +foreach(v IN LISTS EQUALV) + string(REGEX MATCH "(.*) (.*)" _dummy "${v}") + # modify any of the operands to see the negative check also works + if("${CMAKE_MATCH_1}.2" VERSION_EQUAL CMAKE_MATCH_2) + message(FATAL_ERROR "${CMAKE_MATCH_1}.2 is equal ${CMAKE_MATCH_2}?") + else() + message(STATUS "${CMAKE_MATCH_1}.2 is not equal ${CMAKE_MATCH_2}") + endif() + + if(CMAKE_MATCH_1 VERSION_EQUAL "${CMAKE_MATCH_2}.2") + message(FATAL_ERROR "${CMAKE_MATCH_1} is equal ${CMAKE_MATCH_2}.2?") + else() + message(STATUS "${CMAKE_MATCH_1} is not equal ${CMAKE_MATCH_2}.2") + endif() +endforeach() + +# test the negative outcomes first, due to the implementation the positive +# allow some additional strings to pass that would not fail for the negative +# tests + +list(APPEND EQUALV "1a 1") +list(APPEND EQUALV "1.1a 1.1") +list(APPEND EQUALV "1.0a 1") +list(APPEND EQUALV "1a 1.0") + +foreach(v IN LISTS EQUALV) + # check equal versions + string(REGEX MATCH "(.*) (.*)" _dummy "${v}") + if(CMAKE_MATCH_1 VERSION_EQUAL CMAKE_MATCH_2) + message(STATUS "${CMAKE_MATCH_1} is equal ${CMAKE_MATCH_2}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_1} is not equal ${CMAKE_MATCH_2}?") + endif() + + # still equal, but inverted order of operands + string(REGEX MATCH "(.*) (.*)" _dummy "${v}") + if(CMAKE_MATCH_2 VERSION_EQUAL CMAKE_MATCH_1) + message(STATUS "${CMAKE_MATCH_2} is equal ${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_2} is not equal ${CMAKE_MATCH_1}?") + endif() +endforeach() + +set(LESSV "1.2.3.4.5.6.7.8 1.2.3.4.5.6.7.9") +list(APPEND LESSV "1.2.3.4.5.6.7 1.2.3.4.5.6.7.9") +list(APPEND LESSV "1 1.0.0.1") +foreach(v IN LISTS LESSV) + string(REGEX MATCH "(.*) (.*)" _dummy "${v}") + # check less + if(CMAKE_MATCH_1 VERSION_LESS CMAKE_MATCH_2) + message(STATUS "${CMAKE_MATCH_1} is less than ${CMAKE_MATCH_2}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_1} is not less than ${CMAKE_MATCH_2}?") + endif() + + # check greater + if(CMAKE_MATCH_2 VERSION_GREATER CMAKE_MATCH_1) + message(STATUS "${CMAKE_MATCH_2} is greater than ${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_2} is not greater than ${CMAKE_MATCH_1}?") + endif() + + # check less negative case + if(NOT CMAKE_MATCH_2 VERSION_LESS CMAKE_MATCH_1) + message(STATUS "${CMAKE_MATCH_2} is not less than ${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_2} is less than ${CMAKE_MATCH_1}?") + endif() + + # check greater negative case + if(NOT CMAKE_MATCH_1 VERSION_GREATER CMAKE_MATCH_2) + message(STATUS "${CMAKE_MATCH_1} is not greater than ${CMAKE_MATCH_2}") + else() + message(FATAL_ERROR "${CMAKE_MATCH_1} is greater than ${CMAKE_MATCH_2}?") + endif() +endforeach() diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt b/Tests/CTestTestMemcheck/CMakeLists.txt deleted file mode 100644 index 2023e74..0000000 --- a/Tests/CTestTestMemcheck/CMakeLists.txt +++ /dev/null @@ -1,290 +0,0 @@ -REGEX_ESCAPE_STRING(CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") - -get_filename_component(CTEST_REALPATH_CMAKE_CURRENT_BINARY_DIR - "${CMAKE_CURRENT_BINARY_DIR}" REALPATH -) - -REGEX_ESCAPE_STRING(CTEST_ESCAPED_REALPATH_CMAKE_CURRENT_BINARY_DIR - "${CTEST_REALPATH_CMAKE_CURRENT_BINARY_DIR}" -) - -foreach (_retval 0 1) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/memtester.cxx.in" "${CMAKE_CURRENT_BINARY_DIR}/ret${_retval}.cxx" @ONLY) -endforeach () - -include_directories(${CMake_SOURCE_DIR}/Source ${CMake_BINARY_DIR}/Source) - -# create binaries that we will use as a pseudo memory checker -add_executable(pseudo_valgrind "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") -set_target_properties(pseudo_valgrind PROPERTIES OUTPUT_NAME valgrind) -target_link_libraries(pseudo_valgrind CMakeLib) - -add_executable(pseudo_purify "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") -set_target_properties(pseudo_purify PROPERTIES OUTPUT_NAME purify) -target_link_libraries(pseudo_purify CMakeLib) -add_executable(pseudo_BC "${CMAKE_CURRENT_BINARY_DIR}/ret0.cxx") -set_target_properties(pseudo_BC PROPERTIES OUTPUT_NAME BC) -target_link_libraries(pseudo_BC CMakeLib) - -# binary to be used as pre- and post-memcheck command that fails -add_executable(memcheck_fail "${CMAKE_CURRENT_BINARY_DIR}/ret1.cxx") -target_link_libraries(memcheck_fail CMakeLib) - -# Binaries that are used as memchecker that do not write the expected -# output file. Need to be in their own subdirectory as they have the -# same filenames. -add_subdirectory(NoLogDummyChecker) - -if(APPLE) - # filter out additional messages by Guard Malloc integrated in Xcode - set(guard_malloc_msg "ctest\\([0-9]+\\) malloc: ") - set(guard_malloc_lines "(${guard_malloc_msg}[^\n]*\n)*") - set(guard_malloc_output "${guard_malloc_msg}|") -else() - set(guard_malloc_msg "") - set(guard_malloc_lines "") - set(guard_malloc_output "") -endif() - -# When this entire test runs under coverage or memcheck tools -# they may add output to the end, so match known cases: -# - Bullseye adds a "BullseyeCoverage..." line. -# - Valgrind memcheck may add extra "==..." lines. -set(other_tool_output "((${guard_malloc_output}BullseyeCoverage|==)[^\n]*\n)*") - -string(REPLACE "\r\n" "\n" ctest_and_tool_outputs " -1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+\\.[0-9]+ sec -${guard_malloc_lines} -100% tests passed, 0 tests failed out of 1 -.* --- Processing memory checking output:( ) -${guard_malloc_lines}Memory checking results: -${other_tool_output}") - -function(gen_mc_test_internal NAME CHECKER) - set(SUBTEST_NAME "${NAME}") - set(CHECKER_COMMAND "${CHECKER}") - foreach(_file IN ITEMS CMakeLists.txt CTestConfig.cmake test.cmake) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_file}.in" - "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/${_file}" @ONLY) - endforeach() - add_test(NAME CTestTestMemcheck${NAME} - COMMAND ${CMAKE_CTEST_COMMAND} - -C $<CONFIGURATION> - -S "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake" -V - --output-log "${CMAKE_CURRENT_BINARY_DIR}/${NAME}/testOutput.log" - ${ARGN} - ) -endfunction(gen_mc_test_internal) - -function(gen_mc_test NAME CHECKER) - gen_mc_test_internal(${NAME} "${CHECKER}" - -D PSEUDO_BC=$<TARGET_FILE:pseudo_BC> - -D PSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify> - -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind> - -D ERROR_COMMAND=$<TARGET_FILE:memcheck_fail> - ${ARGN} - ) -endfunction(gen_mc_test) - -function(gen_mcnl_test NAME CHECKER) - gen_mc_test_internal(${NAME} ${CHECKER} - -D PSEUDO_BC=$<TARGET_FILE:pseudonl_BC> - -D PSEUDO_PURIFY=$<TARGET_FILE:pseudonl_purify> - -D PSEUDO_VALGRIND=$<TARGET_FILE:pseudonl_valgrind> - ${ARGN} - ) - set_tests_properties(CTestTestMemcheck${NAME} - PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n") -endfunction(gen_mcnl_test) - -unset(CTEST_EXTRA_CONFIG) -unset(CTEST_EXTRA_CODE) -unset(CMAKELISTS_EXTRA_CODE) - -#----------------------------------------------------------------------------- -# add ThreadSanitizer test -set(CTEST_EXTRA_CODE -"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\") -") -set(CMAKELISTS_EXTRA_CODE -"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" --P \"${CMAKE_CURRENT_SOURCE_DIR}/testThreadSanitizer.cmake\") -") -gen_mc_test_internal(DummyThreadSanitizer "" -DMEMCHECK_TYPE=ThreadSanitizer) -set_tests_properties(CTestTestMemcheckDummyThreadSanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*data race.* - 1.*data race on vptr .ctor/dtor vs virtual call. - 1.*heap-use-after-free - 1.*thread leak - 1.*destroy of a locked mutex - 1.*double lock of a mutex - 1.*unlock of an unlocked mutex .or by a wrong thread. - 1.*read lock of a write locked mutex - 1.*read unlock of a write locked mutex - 1.*signal-unsafe call inside of a signal - 1.*signal handler spoils errno - 1.*lock-order-inversion .potential deadlock. - 1.*") -set(CMAKELISTS_EXTRA_CODE ) -set(CTEST_EXTRA_CODE) - -#----------------------------------------------------------------------------- -# add LeakSanitizer test -set(CTEST_EXTRA_CODE -"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") -") -set(CMAKELISTS_EXTRA_CODE -"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" --P \"${CMAKE_CURRENT_SOURCE_DIR}/testLeakSanitizer.cmake\") -") -gen_mc_test_internal(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) -set(CMAKELISTS_EXTRA_CODE ) -set(CTEST_EXTRA_CODE) -set_tests_properties(CTestTestMemcheckDummyLeakSanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*Direct leak - 2.*Indirect leak - 1.*") - -#----------------------------------------------------------------------------- -# add AddressSanitizer test -set(CTEST_EXTRA_CODE -"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") -") -set(CMAKELISTS_EXTRA_CODE -"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" --P \"${CMAKE_CURRENT_SOURCE_DIR}/testAddressSanitizer.cmake\") -") -gen_mc_test_internal(DummyAddressSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) -set(CMAKELISTS_EXTRA_CODE ) -set(CTEST_EXTRA_CODE) -set_tests_properties(CTestTestMemcheckDummyAddressSanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*heap-buffer-overflow - 1.*") - -#----------------------------------------------------------------------------- -# add MemorySanitizer test -set(CTEST_EXTRA_CODE -"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") -") - -set(CMAKELISTS_EXTRA_CODE -"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" --P \"${CMAKE_CURRENT_SOURCE_DIR}/testMemorySanitizer.cmake\") -") -gen_mc_test_internal(DummyMemorySanitizer "" -DMEMCHECK_TYPE=MemorySanitizer) -set(CMAKELISTS_EXTRA_CODE ) -set(CTEST_EXTRA_CODE) -set_tests_properties(CTestTestMemcheckDummyMemorySanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*use-of-uninitialized-value - 1.*") - -#----------------------------------------------------------------------------- -# add UndefinedBehaviorSanitizer test -set(CTEST_EXTRA_CODE -"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1\") -") - -set(CMAKELISTS_EXTRA_CODE -"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" --P \"${CMAKE_CURRENT_SOURCE_DIR}/testUndefinedBehaviorSanitizer.cmake\") -") -gen_mc_test_internal(DummyUndefinedBehaviorSanitizer "" -DMEMCHECK_TYPE=UndefinedBehaviorSanitizer) -set(CMAKELISTS_EXTRA_CODE ) -set(CTEST_EXTRA_CODE) -set_tests_properties(CTestTestMemcheckDummyUndefinedBehaviorSanitizer PROPERTIES - PASS_REGULAR_EXPRESSION - ".*Memory checking results:.*left shift of negative value -256 - 1.*") - -#----------------------------------------------------------------------------- - -gen_mc_test(DummyPurify "\${PSEUDO_PURIFY}") -gen_mc_test(DummyValgrind "\${PSEUDO_VALGRIND}") -gen_mc_test(DummyBC "\${PSEUDO_BC}") -gen_mcnl_test(DummyPurifyNoLogfile "\${PSEUDO_PURIFY}") -gen_mcnl_test(DummyValgrindNoLogfile "\${PSEUDO_VALGRIND}") -gen_mcnl_test(DummyBCNoLogfile "\${PSEUDO_BC}") - -set(CTEST_EXTRA_CODE "string(REPLACE \" \" \"\\\\ \" PRE_POST_COMMAND \"\${CTEST_MEMORYCHECK_COMMAND}\") - -set(CTEST_CUSTOM_PRE_MEMCHECK \"\${PRE_POST_COMMAND} pre command\") -set(CTEST_CUSTOM_POST_MEMCHECK \"\${PRE_POST_COMMAND} post command \") -") -gen_mc_test(DummyValgrindPrePost "\${PSEUDO_VALGRIND}") - -set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_POST_MEMCHECK \"\${ERROR_COMMAND}\")") -gen_mc_test(DummyValgrindFailPost "\${PSEUDO_VALGRIND}") - -set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_PRE_MEMCHECK \"\${ERROR_COMMAND}\")") -gen_mc_test(DummyValgrindFailPre "\${PSEUDO_VALGRIND}") - -unset(CTEST_EXTRA_CODE) -set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n") -set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)") -gen_mc_test(DummyValgrindIgnoreMemcheck "\${PSEUDO_VALGRIND}") - -unset(CTEST_EXTRA_CONFIG) -gen_mc_test(DummyValgrindTwoTargets "\${PSEUDO_VALGRIND}" "-VV") - -set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")") -unset(CMAKELISTS_EXTRA_CODE) -gen_mc_test(DummyValgrindInvalidSupFile "\${PSEUDO_VALGRIND}") - -# CTest will add the logfile option before any custom options. Set the logfile -# again, this time to an empty string. This will cause the logfile to be -# missing, which will be the prove for us that the custom option is indeed used. -set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")") -gen_mc_test(DummyValgrindCustomOptions "\${PSEUDO_VALGRIND}") - -unset(CTEST_EXTRA_CONFIG) -gen_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe") - -gen_mc_test(Unknown "${CMAKE_COMMAND}") - -string(REPLACE "\\" "\\\\" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND}") -string(REPLACE "(" "\\(" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}") -string(REPLACE ")" "\\)" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}") -string(REPLACE "+" "\\+" CMAKE_COMMAND_ESCAPED "${CMAKE_COMMAND_ESCAPED}") - -set_tests_properties(CTestTestMemcheckUnknown PROPERTIES - PASS_REGULAR_EXPRESSION "Do not understand memory checker: ${CMAKE_COMMAND_ESCAPED}\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/Unknown/test.cmake\n") - -set_tests_properties(CTestTestMemcheckNotExist PROPERTIES - PASS_REGULAR_EXPRESSION "Memory checker \\(MemoryCheckCommand\\) not set, or cannot find the specified program.") - -# It is a valid result if valgrind does not output any files (can e.g. happen -# if you have not compiled in debug mode), so these tests will not fail. -set_tests_properties(CTestTestMemcheckDummyValgrind - CTestTestMemcheckDummyValgrindPrePost - CTestTestMemcheckDummyPurify - PROPERTIES - PASS_REGULAR_EXPRESSION "${ctest_and_tool_outputs}$") - -foreach (_pp Pre Post) - string(TOLOWER ${_pp} _pp_lower) - set_tests_properties(CTestTestMemcheckDummyValgrindFail${_pp} - PROPERTIES - PASS_REGULAR_EXPRESSION "\nProblem running command: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}[^\n]*fail[^\n]*\n(.*\n)?Problem executing ${_pp_lower}-memcheck command\\(s\\\).\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindFail${_pp}/test.cmake\n") -endforeach () - -set_tests_properties(CTestTestMemcheckDummyValgrindIgnoreMemcheck - PROPERTIES - PASS_REGULAR_EXPRESSION "\n2/2 Test #2: RunCMakeAgain .*${ctest_and_tool_outputs}$") - -set_tests_properties(CTestTestMemcheckDummyBC PROPERTIES - PASS_REGULAR_EXPRESSION "\n1/1 MemCheck #1: RunCMake \\.+ Passed +[0-9]+.[0-9]+ sec\n${guard_malloc_lines}\n100% tests passed, 0 tests failed out of 1\n(.*\n)?Error parsing XML in stream at line 1: no element found\n") - -set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_REALPATH_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n") - -set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES - PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n") - -set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES - PASS_REGULAR_EXPRESSION - "\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n") - - -# Xcode 2.x forgets to create the output directory before linking -# the individual architectures. -if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]") - foreach(t - memcheck_fail - pseudo_BC - pseudo_purify - pseudo_valgrind - ) - add_custom_command(TARGET ${t} - PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}" - ) - endforeach() -endif() diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt index d02ddaf..aacf4c1 100644 --- a/Tests/CompileFeatures/CMakeLists.txt +++ b/Tests/CompileFeatures/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.1) project(CompileFeatures) @@ -31,13 +31,62 @@ foreach(feature ${cxx_features}) run_test(${feature} CXX) endforeach() -if (CMAKE_CXX_COMPILER_ID STREQUAL GNU +if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) + # AppleClang prior to 5.1 does not set any preprocessor define to distinguish + # c++1y from c++11, so CMake does not support c++1y features before AppleClang 5.1. + list(REMOVE_ITEM CXX_non_features + cxx_attribute_deprecated + cxx_binary_literals + ) +endif() + +if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2) + # AppleClang prior to 4.1 reports false for __has_feature(cxx_local_type_template_args) + # and __has_feature(cxx_unrestricted_unions) but it happens to pass these tests. + list(REMOVE_ITEM CXX_non_features + cxx_local_type_template_args + cxx_unrestricted_unions + ) +endif() + +if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro) + list(REMOVE_ITEM CXX_non_features + cxx_attribute_deprecated + cxx_contextual_conversions + cxx_extended_friend_declarations + cxx_long_long_type + cxx_sizeof_member + cxx_variadic_macros + ) +endif() + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.5) + # The cxx_raw_string_literals feature happens to work in some distributions + # of GNU 4.4, but it is first documented as available with GNU 4.5. + list(REMOVE_ITEM CXX_non_features + cxx_raw_string_literals + ) +endif() +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) + # The cxx_constexpr feature happens to work (for *this* testcase) with + # GNU 4.5, but it is first documented as available with GNU 4.6. + list(REMOVE_ITEM CXX_non_features + cxx_constexpr + ) +endif() +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + # The cxx_alignof feature happens to work (for *this* testcase) with + # GNU 4.7, but it is first documented as available with GNU 4.8. list(REMOVE_ITEM CXX_non_features cxx_alignof ) endif() -if (CMAKE_CXX_COMPILER_ID STREQUAL GNU +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) # GNU prior to 4.9 does not set any preprocessor define to distinguish # c++1y from c++11, so CMake does not support c++1y features before GNU 4.9. @@ -62,8 +111,9 @@ foreach(lang CXX C) try_compile(${feature}_works "${CMAKE_CURRENT_BINARY_DIR}/${feature}_test" "${CMAKE_CURRENT_SOURCE_DIR}/feature_test.${${lang}_ext}" - COMPILE_DEFINITIONS "-DTEST=${CMAKE_CURRENT_SOURCE_DIR}/${feature}.${${lang}_ext}" + COMPILE_DEFINITIONS "-DTEST=${feature}.${${lang}_ext}" CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD=${${lang}_standard_flag}" + "-DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE OUTPUT ) if (${feature}_works) @@ -77,36 +127,133 @@ foreach(lang CXX C) endif() endforeach() -add_executable(CompileFeatures main.cpp) -set_property(TARGET CompileFeatures - PROPERTY COMPILE_FEATURES "cxx_auto_type" -) -set_property(TARGET CompileFeatures - PROPERTY CXX_STANDARD_REQUIRED TRUE -) - -add_executable(GenexCompileFeatures main.cpp) -set_property(TARGET GenexCompileFeatures - PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>" -) - -add_library(iface INTERFACE) -set_property(TARGET iface - PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type" -) -add_executable(IfaceCompileFeatures main.cpp) -target_link_libraries(IfaceCompileFeatures iface) - -add_executable(CompileFeaturesGenex genex_test.cpp) -set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11) -target_compile_definitions(CompileFeaturesGenex PRIVATE HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>) - -add_executable(CompileFeaturesGenex2 genex_test.cpp) -target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_constexpr) -target_compile_definitions(CompileFeaturesGenex2 PRIVATE HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>) - -add_library(noexcept_iface INTERFACE) -target_compile_features(noexcept_iface INTERFACE cxx_noexcept) -add_executable(CompileFeaturesGenex3 genex_test.cpp) -target_link_libraries(CompileFeaturesGenex3 PRIVATE noexcept_iface) -target_compile_definitions(CompileFeaturesGenex3 PRIVATE HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override>) +if (CMAKE_C_COMPILE_FEATURES) + string(FIND "${CMAKE_C_FLAGS}" "-std=" std_flag_idx) + if (std_flag_idx EQUAL -1) + add_executable(default_dialect_C default_dialect.c) + target_compile_definitions(default_dialect_C PRIVATE + DEFAULT_C11=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},11> + DEFAULT_C99=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},99> + DEFAULT_C90=$<EQUAL:${CMAKE_C_STANDARD_DEFAULT},90> + ) + endif() +endif() + +if (CMAKE_CXX_COMPILE_FEATURES) + string(FIND "${CMAKE_CXX_FLAGS}" "-std=" std_flag_idx) + if (std_flag_idx EQUAL -1) + add_executable(default_dialect default_dialect.cpp) + target_compile_definitions(default_dialect PRIVATE + DEFAULT_CXX14=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},14> + DEFAULT_CXX11=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},11> + DEFAULT_CXX98=$<EQUAL:${CMAKE_CXX_STANDARD_DEFAULT},98> + ) + endif() + + add_executable(CompileFeatures main.cpp) + set_property(TARGET CompileFeatures + PROPERTY COMPILE_FEATURES "cxx_auto_type" + ) + set_property(TARGET CompileFeatures + PROPERTY CXX_STANDARD_REQUIRED TRUE + ) + + add_executable(GenexCompileFeatures main.cpp) + set_property(TARGET GenexCompileFeatures + PROPERTY COMPILE_FEATURES "$<1:cxx_auto_type>;$<0:not_a_feature>" + ) + + add_library(iface INTERFACE) + set_property(TARGET iface + PROPERTY INTERFACE_COMPILE_FEATURES "cxx_auto_type" + ) + add_executable(IfaceCompileFeatures main.cpp) + target_link_libraries(IfaceCompileFeatures iface) + + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=1 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1 + ) + elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=0 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0 + ) + else() + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=0 + -DEXPECT_INHERITING_CONSTRUCTORS=0 + -DEXPECT_FINAL=0 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0 + ) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=1 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1 + ) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=1 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1 + ) + else() + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=0 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=0 + ) + endif() + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + add_definitions( + -DEXPECT_OVERRIDE_CONTROL=1 + -DEXPECT_INHERITING_CONSTRUCTORS=1 + -DEXPECT_FINAL=1 + -DEXPECT_INHERITING_CONSTRUCTORS_AND_FINAL=1 + ) + endif() + + add_executable(CompileFeaturesGenex genex_test.cpp) + set_property(TARGET CompileFeaturesGenex PROPERTY CXX_STANDARD 11) + target_compile_definitions(CompileFeaturesGenex PRIVATE + HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override> + HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type> + HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors> + HAVE_FINAL=$<COMPILE_FEATURES:cxx_final> + HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final> + ) + + add_executable(CompileFeaturesGenex2 genex_test.cpp) + target_compile_features(CompileFeaturesGenex2 PRIVATE cxx_static_assert) + target_compile_definitions(CompileFeaturesGenex2 PRIVATE + HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override> + HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type> + HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors> + HAVE_FINAL=$<COMPILE_FEATURES:cxx_final> + HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final> + ) + + add_library(static_assert_iface INTERFACE) + target_compile_features(static_assert_iface INTERFACE cxx_static_assert) + add_executable(CompileFeaturesGenex3 genex_test.cpp) + target_link_libraries(CompileFeaturesGenex3 PRIVATE static_assert_iface) + target_compile_definitions(CompileFeaturesGenex3 PRIVATE + HAVE_OVERRIDE_CONTROL=$<COMPILE_FEATURES:cxx_final,cxx_override> + HAVE_AUTO_TYPE=$<COMPILE_FEATURES:cxx_auto_type> + HAVE_INHERITING_CONSTRUCTORS=$<COMPILE_FEATURES:cxx_inheriting_constructors> + HAVE_FINAL=$<COMPILE_FEATURES:cxx_final> + HAVE_INHERITING_CONSTRUCTORS_AND_FINAL=$<COMPILE_FEATURES:cxx_inheriting_constructors,cxx_final> + ) +endif() diff --git a/Tests/CompileFeatures/cxx_auto_type.cpp b/Tests/CompileFeatures/cxx_auto_type.cpp index 7dbf04f..1f36a79 100644 --- a/Tests/CompileFeatures/cxx_auto_type.cpp +++ b/Tests/CompileFeatures/cxx_auto_type.cpp @@ -1,5 +1,12 @@ +double foo_ = 3.14; + +double& foo() +{ + return foo_; +} + void someFunc() { - auto x = 3.14; + auto& x = foo(); } diff --git a/Tests/CompileFeatures/cxx_generalized_initializers.cpp b/Tests/CompileFeatures/cxx_generalized_initializers.cpp index 8013ef5..7bf356b 100644 --- a/Tests/CompileFeatures/cxx_generalized_initializers.cpp +++ b/Tests/CompileFeatures/cxx_generalized_initializers.cpp @@ -8,6 +8,7 @@ namespace std { const _E* __begin_; size_t __size_; + initializer_list(const int*, long unsigned int) {} }; } diff --git a/Tests/CompileFeatures/cxx_inheriting_constructors.cpp b/Tests/CompileFeatures/cxx_inheriting_constructors.cpp index a83b624..cfce880 100644 --- a/Tests/CompileFeatures/cxx_inheriting_constructors.cpp +++ b/Tests/CompileFeatures/cxx_inheriting_constructors.cpp @@ -13,6 +13,6 @@ struct B : public A void someFunc() { - int i; + int i = 0; B b(i); } diff --git a/Tests/CompileFeatures/cxx_variadic_templates.cpp b/Tests/CompileFeatures/cxx_variadic_templates.cpp index 1d5a706..e1f641b 100644 --- a/Tests/CompileFeatures/cxx_variadic_templates.cpp +++ b/Tests/CompileFeatures/cxx_variadic_templates.cpp @@ -1,21 +1,30 @@ -template<int I, int... Is> +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 407) +#define OLD_GNU +#endif + +#ifdef OLD_GNU +template<int... Is> struct Interface; +#endif -template<int I> -struct Interface<I> +template<int I, int... Is> +struct Interface +#ifdef OLD_GNU + <I, Is...> +#endif { static int accumulate() { - return I; + return I + Interface<Is...>::accumulate(); } }; -template<int I, int... Is> -struct Interface +template<int I> +struct Interface<I> { static int accumulate() { - return I + Interface<Is...>::accumulate(); + return I; } }; diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c new file mode 100644 index 0000000..1b39dec --- /dev/null +++ b/Tests/CompileFeatures/default_dialect.c @@ -0,0 +1,22 @@ + +#if DEFAULT_C11 +# if __STDC_VERSION__ != 201112L +# error Unexpected value for __STDC_VERSION__. +# endif +#elif DEFAULT_C99 +# if __STDC_VERSION__ != 199901L +# error Unexpected value for __STDC_VERSION__. +# endif +#else +# if !DEFAULT_C90 +# error Buildsystem error +# endif +# if defined(__STDC_VERSION__) +# error Unexpected __STDC_VERSION__ definition +# endif +#endif + +int main() +{ + return 0; +} diff --git a/Tests/CompileFeatures/default_dialect.cpp b/Tests/CompileFeatures/default_dialect.cpp new file mode 100644 index 0000000..a2ca268 --- /dev/null +++ b/Tests/CompileFeatures/default_dialect.cpp @@ -0,0 +1,25 @@ + +template<long l> +struct Outputter; + +#if DEFAULT_CXX14 +# if __cplusplus != 201402L +Outputter<__cplusplus> o; +# endif +#elif DEFAULT_CXX11 +# if __cplusplus != 201103L +Outputter<__cplusplus> o; +# endif +#else +# if !DEFAULT_CXX98 +# error Buildsystem error +# endif +# if __cplusplus != 199711L && __cplusplus != 1 && !defined(__GXX_EXPERIMENTAL_CXX0X__) +Outputter<__cplusplus> o; +# endif +#endif + +int main() +{ + return 0; +} diff --git a/Tests/CompileFeatures/feature_test.c b/Tests/CompileFeatures/feature_test.c new file mode 100644 index 0000000..4147f1f --- /dev/null +++ b/Tests/CompileFeatures/feature_test.c @@ -0,0 +1,10 @@ + +#define STRINGIFY_IMPL(X) #X +#define STRINGIFY(X) STRINGIFY_IMPL(X) + +#include STRINGIFY(TEST) + +int main(void) +{ + return 0; +} diff --git a/Tests/CompileFeatures/genex_test.cpp b/Tests/CompileFeatures/genex_test.cpp index ca38883..d9c8eec 100644 --- a/Tests/CompileFeatures/genex_test.cpp +++ b/Tests/CompileFeatures/genex_test.cpp @@ -1,6 +1,8 @@ #if !HAVE_OVERRIDE_CONTROL +#if EXPECT_OVERRIDE_CONTROL #error "Expect override control feature" +#endif #else struct A @@ -15,6 +17,40 @@ struct B final : A #endif +#if !HAVE_AUTO_TYPE +# error Expect cxx_auto_type support +#endif + +#if !HAVE_INHERITING_CONSTRUCTORS +# if EXPECT_INHERITING_CONSTRUCTORS +# error Expect cxx_inheriting_constructors support +# endif +#else +# if !EXPECT_INHERITING_CONSTRUCTORS +# error Expect no cxx_inheriting_constructors support +# endif +#endif + +#if !HAVE_FINAL +# if EXPECT_FINAL +# error Expect cxx_final support +# endif +#else +# if !EXPECT_FINAL +# error Expect no cxx_final support +# endif +#endif + +#if !HAVE_INHERITING_CONSTRUCTORS_AND_FINAL +# if EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL +# error Expect cxx_inheriting_constructors and cxx_final support +# endif +#else +# if !EXPECT_INHERITING_CONSTRUCTORS_AND_FINAL +# error Expect no combined cxx_inheriting_constructors and cxx_final support +# endif +#endif + int main() { diff --git a/Tests/CompileFeatures/main.c b/Tests/CompileFeatures/main.c deleted file mode 100644 index 831c5eb2..0000000 --- a/Tests/CompileFeatures/main.c +++ /dev/null @@ -1,12 +0,0 @@ - -int foo(int * restrict a, int * restrict b) -{ - (void)a; - (void)b; - return 0; -} - -int main() -{ - return 0; -} diff --git a/Tests/Complex/Executable/CMakeLists.txt b/Tests/Complex/Executable/CMakeLists.txt index bf23d4a..508221c 100644 --- a/Tests/Complex/Executable/CMakeLists.txt +++ b/Tests/Complex/Executable/CMakeLists.txt @@ -89,18 +89,22 @@ remove_definitions(-DCOMPLEX_DEFINED) # Test pre-build/pre-link/post-build rules for an executable. add_custom_command(TARGET complex PRE_BUILD COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/prebuild.txt") + ARGS "Executable/prebuild.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex PRE_LINK COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt") + ARGS "Executable/prelink.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex POST_BUILD COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt") + ARGS "Executable/postbuild.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy - "${Complex_BINARY_DIR}/Executable/postbuild.txt" - "${Complex_BINARY_DIR}/Executable/postbuild2.txt") + "Executable/postbuild.txt" + "Executable/postbuild2.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") set_source_files_properties(complex COMPILE_FLAGS diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx index 31442ba..ec222a5 100644 --- a/Tests/Complex/Executable/complex.cxx +++ b/Tests/Complex/Executable/complex.cxx @@ -716,14 +716,14 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Library/prebuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/prelink.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/postbuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/postbuild2.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/prebuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/prelink.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/postbuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/postbuild2.txt"); + TestAndRemoveFile("Library/prebuild.txt"); + TestAndRemoveFile("Library/prelink.txt"); + TestAndRemoveFile("Library/postbuild.txt"); + TestAndRemoveFile("Library/postbuild2.txt"); + TestAndRemoveFile("Executable/prebuild.txt"); + TestAndRemoveFile("Executable/prelink.txt"); + TestAndRemoveFile("Executable/postbuild.txt"); + TestAndRemoveFile("Executable/postbuild2.txt"); // ---------------------------------------------------------------------- // A custom target has been created (see Library/). @@ -733,12 +733,12 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Library/custom_target1.txt"); + TestAndRemoveFile("Library/custom_target1.txt"); // ---------------------------------------------------------------------- // A directory has been created. - TestDir(BINARY_DIR "/make_dir"); + TestDir("make_dir"); // ---------------------------------------------------------------------- // Test OUTPUT_REQUIRED_FILES @@ -749,7 +749,7 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Executable/Temp/complex-required.txt"); + TestAndRemoveFile("Executable/Temp/complex-required.txt"); // ---------------------------------------------------------------------- // Test FIND_LIBRARY diff --git a/Tests/ComplexOneConfig/Executable/CMakeLists.txt b/Tests/ComplexOneConfig/Executable/CMakeLists.txt index 01f1005..e910f20 100644 --- a/Tests/ComplexOneConfig/Executable/CMakeLists.txt +++ b/Tests/ComplexOneConfig/Executable/CMakeLists.txt @@ -89,18 +89,22 @@ remove_definitions(-DCOMPLEX_DEFINED) # Test pre-build/pre-link/post-build rules for an executable. add_custom_command(TARGET complex PRE_BUILD COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/prebuild.txt") + ARGS "Executable/prebuild.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex PRE_BUILD COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/prelink.txt") + ARGS "Executable/prelink.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex POST_BUILD COMMAND ${CREATE_FILE_EXE} - ARGS "${Complex_BINARY_DIR}/Executable/postbuild.txt") + ARGS "Executable/postbuild.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") add_custom_command(TARGET complex POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy - "${Complex_BINARY_DIR}/Executable/postbuild.txt" - "${Complex_BINARY_DIR}/Executable/postbuild2.txt") + "Executable/postbuild.txt" + "Executable/postbuild2.txt" + WORKING_DIRECTORY "${Complex_BINARY_DIR}") set_source_files_properties(complex COMPILE_FLAGS diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx index 31442ba..ec222a5 100644 --- a/Tests/ComplexOneConfig/Executable/complex.cxx +++ b/Tests/ComplexOneConfig/Executable/complex.cxx @@ -716,14 +716,14 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Library/prebuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/prelink.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/postbuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Library/postbuild2.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/prebuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/prelink.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/postbuild.txt"); - TestAndRemoveFile(BINARY_DIR "/Executable/postbuild2.txt"); + TestAndRemoveFile("Library/prebuild.txt"); + TestAndRemoveFile("Library/prelink.txt"); + TestAndRemoveFile("Library/postbuild.txt"); + TestAndRemoveFile("Library/postbuild2.txt"); + TestAndRemoveFile("Executable/prebuild.txt"); + TestAndRemoveFile("Executable/prelink.txt"); + TestAndRemoveFile("Executable/postbuild.txt"); + TestAndRemoveFile("Executable/postbuild2.txt"); // ---------------------------------------------------------------------- // A custom target has been created (see Library/). @@ -733,12 +733,12 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Library/custom_target1.txt"); + TestAndRemoveFile("Library/custom_target1.txt"); // ---------------------------------------------------------------------- // A directory has been created. - TestDir(BINARY_DIR "/make_dir"); + TestDir("make_dir"); // ---------------------------------------------------------------------- // Test OUTPUT_REQUIRED_FILES @@ -749,7 +749,7 @@ int main() // the file was removed the last time 'complex' was run, and it is // only created during a build. - TestAndRemoveFile(BINARY_DIR "/Executable/Temp/complex-required.txt"); + TestAndRemoveFile("Executable/Temp/complex-required.txt"); // ---------------------------------------------------------------------- // Test FIND_LIBRARY diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index c272257..748aad8 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -5,9 +5,9 @@ project(ConfigSources) add_library(iface INTERFACE) set_property(TARGET iface PROPERTY INTERFACE_SOURCES - iface_src.cpp - $<$<CONFIG:Debug>:iface_debug_src.cpp> - $<$<CONFIG:Release>:does_not_exist.cpp> + "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp" + "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp>" + "$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp>" ) add_executable(ConfigSources diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index b97cd16..57ffeec 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -117,6 +117,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E echo " Copying doc1pre.txt to doc2post.txt." COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1pre.txt ${PROJECT_BINARY_DIR}/doc2post.txt + BYPRODUCTS ${PROJECT_BINARY_DIR}/doc2post.txt COMMENT "Running TDocument post-build commands" ) @@ -163,13 +164,6 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/not_included.h ${PROJECT_BINARY_DIR}/not_included.h ) -# Tell the executable where to find not_included.h. -configure_file( - ${PROJECT_SOURCE_DIR}/config.h.in - ${PROJECT_BINARY_DIR}/config.h - @ONLY - ) - # add the executable add_executable(CustomCommand ${PROJECT_BINARY_DIR}/foo.h @@ -483,3 +477,26 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}") add_library(NormDepends "${gen_file}") + +# Test that USES_TERMINAL is parsed correctly. +# It seems much more difficult to test that USES_TERMINAL actually gives +# the subprocess console access, as test output is piped through CTest, +# and CTest itself might not be connected to the console. + +set(gen_file "${gen_path}/bar2.cxx") + +add_custom_command( + OUTPUT "${gen_file}" + DEPENDS "${gen_path}" + COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}" + VERBATIM + USES_TERMINAL +) + +add_library(UseConsole "${gen_file}") + +add_custom_target(UseConsoleTarget ALL + COMMAND ${CMAKE_COMMAND} -E echo "Custom console target." + VERBATIM + USES_TERMINAL +) diff --git a/Tests/CustomCommand/config.h.in b/Tests/CustomCommand/config.h.in deleted file mode 100644 index 86c97bd..0000000 --- a/Tests/CustomCommand/config.h.in +++ /dev/null @@ -1 +0,0 @@ -#define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@" diff --git a/Tests/CustomCommand/foo.in b/Tests/CustomCommand/foo.in index 0c5021c..e43aed1 100644 --- a/Tests/CustomCommand/foo.in +++ b/Tests/CustomCommand/foo.in @@ -1,6 +1,5 @@ #include "doc1.h" #include "foo.h" -#include "config.h" #include <stdio.h> @@ -11,7 +10,7 @@ int main () { if (generated()*wrapped()*doc() == 3*5*7) { - FILE* fin = fopen(PROJECT_BINARY_DIR "/not_included.h", "r"); + FILE* fin = fopen("not_included.h", "r"); if(fin) { fclose(fin); diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt new file mode 100644 index 0000000..884f8c2 --- /dev/null +++ b/Tests/CustomCommandByproducts/CMakeLists.txt @@ -0,0 +1,127 @@ +cmake_minimum_required(VERSION 3.1) +project(CustomCommandByproducts C) + +# Generate a byproduct in a rule that runs in the target consuming it. +add_custom_command( + OUTPUT timestamp1.txt + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct1.c.in byproduct1.c + BYPRODUCTS byproduct1.c + COMMAND ${CMAKE_COMMAND} -E touch timestamp1.txt + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct1.c.in + ) + +# Generate a byproduct in a rule that runs in a dependency of the consumer. +add_custom_command( + OUTPUT timestamp2.txt + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in byproduct2.c + BYPRODUCTS byproduct2.c + COMMAND ${CMAKE_COMMAND} -E touch timestamp2.txt + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/byproduct2.c.in + ) +add_custom_target(Producer2 DEPENDS timestamp2.txt) + +# Generate a byproduct in a custom target. +add_custom_target(Producer3_4 + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct3.c.in byproduct3.c + BYPRODUCTS byproduct3.c + ) + +# Generate a byproduct in a custom target POST_BUILD command. +add_custom_command( + TARGET Producer3_4 POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct4.c.in byproduct4.c + BYPRODUCTS byproduct4.c + ) + +add_executable(ProducerExe ProducerExe.c) + +# Generate a byproduct in an executable POST_BUILD command. +add_custom_command( + TARGET ProducerExe POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct5.c.in byproduct5.c + BYPRODUCTS byproduct5.c + ) + +# Generate a byproduct in an executable PRE_LINK command. +add_custom_command( + TARGET ProducerExe PRE_LINK + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct6.c.in byproduct6.c + BYPRODUCTS byproduct6.c + ) + +# Generate a byproduct in an executable PRE_BUILD command. +add_custom_command( + TARGET ProducerExe PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct7.c.in byproduct7.c + BYPRODUCTS byproduct7.c + ) + +# Generate a byproduct in a custom command that consumes other byproducts. +add_custom_command(OUTPUT timestamp8.txt + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct8.c.in byproduct8.c + COMMAND ${CMAKE_COMMAND} -E touch timestamp8.txt + BYPRODUCTS byproduct8.c + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/byproduct2.c + ${CMAKE_CURRENT_BINARY_DIR}/byproduct3.c + ${CMAKE_CURRENT_BINARY_DIR}/byproduct4.c + ${CMAKE_CURRENT_BINARY_DIR}/byproduct5.c + ${CMAKE_CURRENT_BINARY_DIR}/byproduct6.c + ${CMAKE_CURRENT_BINARY_DIR}/byproduct7.c + ${CMAKE_CURRENT_SOURCE_DIR}/byproduct8.c.in + ) + +# Generate the library file of an imported target as a byproduct +# of an external project. +if(CMAKE_CONFIGURATION_TYPES) + set(cfg /${CMAKE_CFG_INTDIR}) +else() + set(cfg) +endif() +set(ExternalLibrary_LIBRARY + ${CMAKE_CURRENT_BINARY_DIR}/External-build${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX} + ) +include(ExternalProject) +ExternalProject_Add(ExternalTarget + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/External-build" + PREFIX "${CMAKE_CURRENT_BINARY_DIR}/External-build/root" + DOWNLOAD_COMMAND "" + INSTALL_COMMAND "" + BUILD_BYPRODUCTS "${ExternalLibrary_LIBRARY}" + ) +add_library(ExternalLibrary STATIC IMPORTED) +set_property(TARGET ExternalLibrary PROPERTY IMPORTED_LOCATION ${ExternalLibrary_LIBRARY}) +add_dependencies(ExternalLibrary ExternalTarget) + +# Add an executable consuming all the byproducts. +add_executable(CustomCommandByproducts + CustomCommandByproducts.c + byproduct1.c timestamp1.txt + byproduct2.c + byproduct3.c + byproduct4.c + byproduct5.c + byproduct6.c + byproduct7.c + byproduct8.c timestamp8.txt + ) +add_dependencies(CustomCommandByproducts Producer2) +add_dependencies(CustomCommandByproducts Producer3_4) +add_dependencies(CustomCommandByproducts ProducerExe) +target_link_libraries(CustomCommandByproducts ExternalLibrary) + +if(CMAKE_GENERATOR STREQUAL "Ninja") + add_custom_target(CheckNinja ALL + COMMENT "Checking build.ninja" + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/ninja-check.cmake + ) +endif() diff --git a/Tests/CustomCommandByproducts/CustomCommandByproducts.c b/Tests/CustomCommandByproducts/CustomCommandByproducts.c new file mode 100644 index 0000000..1916427 --- /dev/null +++ b/Tests/CustomCommandByproducts/CustomCommandByproducts.c @@ -0,0 +1,23 @@ +extern int byproduct1(void); +extern int byproduct2(void); +extern int byproduct3(void); +extern int byproduct4(void); +extern int byproduct5(void); +extern int byproduct6(void); +extern int byproduct7(void); +extern int byproduct8(void); +extern int ExternalLibrary(void); +int main(void) +{ + return ( + byproduct1() + + byproduct2() + + byproduct3() + + byproduct4() + + byproduct5() + + byproduct6() + + byproduct7() + + byproduct8() + + ExternalLibrary() + + 0); +} diff --git a/Tests/CustomCommandByproducts/External/CMakeLists.txt b/Tests/CustomCommandByproducts/External/CMakeLists.txt new file mode 100644 index 0000000..feaa12e --- /dev/null +++ b/Tests/CustomCommandByproducts/External/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(External C) + +add_library(ExternalLibrary STATIC ExternalLibrary.c) diff --git a/Tests/CustomCommandByproducts/External/ExternalLibrary.c b/Tests/CustomCommandByproducts/External/ExternalLibrary.c new file mode 100644 index 0000000..a1dacf0 --- /dev/null +++ b/Tests/CustomCommandByproducts/External/ExternalLibrary.c @@ -0,0 +1 @@ +int ExternalLibrary(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/ProducerExe.c b/Tests/CustomCommandByproducts/ProducerExe.c new file mode 100644 index 0000000..78f2de1 --- /dev/null +++ b/Tests/CustomCommandByproducts/ProducerExe.c @@ -0,0 +1 @@ +int main(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct1.c.in b/Tests/CustomCommandByproducts/byproduct1.c.in new file mode 100644 index 0000000..5c3cc24 --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct1.c.in @@ -0,0 +1 @@ +int byproduct1(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct2.c.in b/Tests/CustomCommandByproducts/byproduct2.c.in new file mode 100644 index 0000000..eeb69ef --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct2.c.in @@ -0,0 +1 @@ +int byproduct2(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct3.c.in b/Tests/CustomCommandByproducts/byproduct3.c.in new file mode 100644 index 0000000..7d15310 --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct3.c.in @@ -0,0 +1 @@ +int byproduct3(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct4.c.in b/Tests/CustomCommandByproducts/byproduct4.c.in new file mode 100644 index 0000000..8b243dd --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct4.c.in @@ -0,0 +1 @@ +int byproduct4(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct5.c.in b/Tests/CustomCommandByproducts/byproduct5.c.in new file mode 100644 index 0000000..47f5990 --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct5.c.in @@ -0,0 +1 @@ +int byproduct5(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct6.c.in b/Tests/CustomCommandByproducts/byproduct6.c.in new file mode 100644 index 0000000..d70c14f --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct6.c.in @@ -0,0 +1 @@ +int byproduct6(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct7.c.in b/Tests/CustomCommandByproducts/byproduct7.c.in new file mode 100644 index 0000000..0be5006 --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct7.c.in @@ -0,0 +1 @@ +int byproduct7(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/byproduct8.c.in b/Tests/CustomCommandByproducts/byproduct8.c.in new file mode 100644 index 0000000..abefd62 --- /dev/null +++ b/Tests/CustomCommandByproducts/byproduct8.c.in @@ -0,0 +1 @@ +int byproduct8(void) { return 0; } diff --git a/Tests/CustomCommandByproducts/ninja-check.cmake b/Tests/CustomCommandByproducts/ninja-check.cmake new file mode 100644 index 0000000..2fc3cc2 --- /dev/null +++ b/Tests/CustomCommandByproducts/ninja-check.cmake @@ -0,0 +1,20 @@ +file(READ build.ninja build_ninja) +if("${build_ninja}" MATCHES [====[ +# Unknown Build Time Dependencies. +# Tell Ninja that they may appear as side effects of build rules +# otherwise ordered by order-only dependencies. + +((build [^:]*: phony [^\n]* +)*)# ========]====]) + set(phony "${CMAKE_MATCH_1}") + if(NOT phony) + message(STATUS "build.ninja correctly does not have extra phony rules") + else() + string(REGEX REPLACE "\n+$" "" phony "${phony}") + string(REGEX REPLACE "\n" "\n " phony " ${phony}") + message(FATAL_ERROR "build.ninja incorrectly has extra phony rules:\n" + "${phony}") + endif() +else() + message(FATAL_ERROR "build.ninja is incorrectly missing expected block") +endif() diff --git a/Tests/CxxSubdirC/CMakeLists.txt b/Tests/CxxSubdirC/CMakeLists.txt new file mode 100644 index 0000000..52474f8 --- /dev/null +++ b/Tests/CxxSubdirC/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.0) +project(CxxSubdirC CXX) +add_subdirectory(Cdir) +add_executable(CxxSubdirC main.cxx $<TARGET_OBJECTS:Cobj>) diff --git a/Tests/CxxSubdirC/Cdir/CMakeLists.txt b/Tests/CxxSubdirC/Cdir/CMakeLists.txt new file mode 100644 index 0000000..08a8757 --- /dev/null +++ b/Tests/CxxSubdirC/Cdir/CMakeLists.txt @@ -0,0 +1,2 @@ +enable_language(C) +add_library(Cobj OBJECT Cobj.c) diff --git a/Tests/CxxSubdirC/Cdir/Cobj.c b/Tests/CxxSubdirC/Cdir/Cobj.c new file mode 100644 index 0000000..75a0045 --- /dev/null +++ b/Tests/CxxSubdirC/Cdir/Cobj.c @@ -0,0 +1 @@ +int Cobj(void) { return 0; } diff --git a/Tests/CxxSubdirC/main.cxx b/Tests/CxxSubdirC/main.cxx new file mode 100644 index 0000000..049220f --- /dev/null +++ b/Tests/CxxSubdirC/main.cxx @@ -0,0 +1,2 @@ +extern "C" int Cobj(void); +int main() { return Cobj(); } diff --git a/Tests/Dependency/CMakeLists.txt b/Tests/Dependency/CMakeLists.txt index ef42048..ebc2d10 100644 --- a/Tests/Dependency/CMakeLists.txt +++ b/Tests/Dependency/CMakeLists.txt @@ -51,3 +51,4 @@ add_subdirectory(Case1) add_subdirectory(Case2) add_subdirectory(Case3) add_subdirectory(Case4) +add_subdirectory(Case5) diff --git a/Tests/Dependency/Case5/CMakeLists.txt b/Tests/Dependency/Case5/CMakeLists.txt new file mode 100644 index 0000000..e954b02 --- /dev/null +++ b/Tests/Dependency/Case5/CMakeLists.txt @@ -0,0 +1,8 @@ +project(CASE5 C) + +add_library(case5Foo SHARED foo.c) +add_library(case5Bar STATIC bar.c) +target_link_libraries(case5Bar case5Foo) + +add_executable(case5 main.c) +target_link_libraries(case5 case5Foo case5Bar) diff --git a/Tests/Dependency/Case5/bar.c b/Tests/Dependency/Case5/bar.c new file mode 100644 index 0000000..4cb1b1b --- /dev/null +++ b/Tests/Dependency/Case5/bar.c @@ -0,0 +1,12 @@ +#ifdef _WIN32 +__declspec(dllimport) +#endif +void foo(void); + +#include <stdio.h> + +void bar(void) +{ + foo(); + printf("bar()\n"); +} diff --git a/Tests/Dependency/Case5/foo.c b/Tests/Dependency/Case5/foo.c new file mode 100644 index 0000000..794833d --- /dev/null +++ b/Tests/Dependency/Case5/foo.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#ifdef _WIN32 +__declspec(dllexport) +#endif +void foo(void) +{ + printf("foo()\n"); +} diff --git a/Tests/Dependency/Case5/main.c b/Tests/Dependency/Case5/main.c new file mode 100644 index 0000000..ae3dc95 --- /dev/null +++ b/Tests/Dependency/Case5/main.c @@ -0,0 +1,7 @@ +void bar(void); + +int main(int argc, char *argv[]) +{ + bar(); + return 0; +} diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index febdfe6..e130eca 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -508,3 +508,18 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib ) add_subdirectory(Interface) + +#----------------------------------------------------------------------------- +# Install export with absolute destination but relative pieces. +add_library(testLibAbs1 STATIC testLibAbs1.c) +target_include_directories(testLibAbs1 INTERFACE + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/abs/1a;include/abs/1b>" + ) +install( + TARGETS testLibAbs1 + EXPORT expAbs + ARCHIVE DESTINATION lib + INCLUDES DESTINATION include/abs + ) +install(DIRECTORY include/abs DESTINATION include) +install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs) diff --git a/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h new file mode 100644 index 0000000..4421227 --- /dev/null +++ b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h @@ -0,0 +1 @@ +#define testLibAbs1a diff --git a/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h new file mode 100644 index 0000000..00a2a29 --- /dev/null +++ b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h @@ -0,0 +1 @@ +#define testLibAbs1b diff --git a/Tests/ExportImport/Export/include/abs/testLibAbs1.h b/Tests/ExportImport/Export/include/abs/testLibAbs1.h new file mode 100644 index 0000000..19d80a5 --- /dev/null +++ b/Tests/ExportImport/Export/include/abs/testLibAbs1.h @@ -0,0 +1 @@ +extern int testLibAbs1(void); diff --git a/Tests/ExportImport/Export/testLibAbs1.c b/Tests/ExportImport/Export/testLibAbs1.c new file mode 100644 index 0000000..34aec75 --- /dev/null +++ b/Tests/ExportImport/Export/testLibAbs1.c @@ -0,0 +1 @@ +int testLibAbs1(void) { return 0; } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index eb0bbf8..9450c82 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -96,6 +96,16 @@ foreach(c DEBUG RELWITHDEBINFO) endforeach() #----------------------------------------------------------------------------- +include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake) + +add_executable(imp_testExeAbs1 + imp_testExeAbs1.c + ) +target_link_libraries(imp_testExeAbs1 + expAbs_testLibAbs1 + ) + +#----------------------------------------------------------------------------- # Create a custom target to generate a header for the libraries below. # Drive the header generation through an indirect chain of imported # target dependencies. diff --git a/Tests/ExportImport/Import/A/imp_testExeAbs1.c b/Tests/ExportImport/Import/A/imp_testExeAbs1.c new file mode 100644 index 0000000..069c3f0 --- /dev/null +++ b/Tests/ExportImport/Import/A/imp_testExeAbs1.c @@ -0,0 +1,15 @@ +#include "testLibAbs1.h" +#include "testLibAbs1a.h" +#include "testLibAbs1b.h" +#ifndef testLibAbs1a +# error "testLibAbs1a not defined" +#endif +#ifndef testLibAbs1b +# error "testLibAbs1b not defined" +#endif +int main() +{ + return 0 + + testLibAbs1() + ; +} diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt index f942197..9476ab4 100644 --- a/Tests/ExternalProjectLocal/CMakeLists.txt +++ b/Tests/ExternalProjectLocal/CMakeLists.txt @@ -66,10 +66,36 @@ if(can_build_tutorial_step5) ExternalProject_Add(${proj} URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> + CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF TEST_AFTER_INSTALL 1 LOG_TEST 1 ) set_property(TARGET ${proj} PROPERTY FOLDER "Local") + + set(proj TutorialStep5-Local-TestExcludeFromMainBefore) + ExternalProject_Add(${proj} + URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> + CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF + TEST_BEFORE_INSTALL 1 + TEST_EXCLUDE_FROM_MAIN 1 + STEP_TARGETS test + LOG_TEST 1 + ) + set_property(TARGET ${proj} PROPERTY FOLDER "Local") + + set(proj TutorialStep5-Local-TestExcludeFromMainAfter) + ExternalProject_Add(${proj} + URL "${CMAKE_CURRENT_SOURCE_DIR}/../Tutorial/Step5" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -G ${CMAKE_GENERATOR} <SOURCE_DIR> + CMAKE_CACHE_DEFAULT_ARGS -DUSE_MYMATH:BOOL=OFF + TEST_AFTER_INSTALL 1 + TEST_EXCLUDE_FROM_MAIN 1 + STEP_TARGETS test + LOG_TEST 1 + ) + set_property(TARGET ${proj} PROPERTY FOLDER "Local") + endif() diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt index c33e90b..fbb3388 100644 --- a/Tests/ExternalProjectUpdate/CMakeLists.txt +++ b/Tests/ExternalProjectUpdate/CMakeLists.txt @@ -19,6 +19,7 @@ set(base "${CMAKE_BINARY_DIR}/CMakeExternals") set(binary_base "${base}/Build") set_property(DIRECTORY PROPERTY EP_BASE ${base}) set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test) +set_property(DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS update) set(do_git_tests 0) @@ -68,8 +69,20 @@ if(do_git_tests) CMAKE_GENERATOR "${CMAKE_GENERATOR}" CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> INSTALL_COMMAND "" - DEPENDS "SetupLocalGITRepository" ) + ExternalProject_Add_StepDependencies(${proj} download SetupLocalGITRepository) + set_property(TARGET ${proj} PROPERTY FOLDER "GIT") + + set(proj TutorialStep2-GIT) + ExternalProject_Add(${proj} + GIT_REPOSITORY "${local_git_repo}" + GIT_TAG ${TEST_GIT_TAG} + CMAKE_GENERATOR "${CMAKE_GENERATOR}" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> + INSTALL_COMMAND "" + UPDATE_DISCONNECTED 1 + ) + ExternalProject_Add_StepDependencies(${proj} download SetupLocalGITRepository) set_property(TARGET ${proj} PROPERTY FOLDER "GIT") endif() diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index 6c7bcfe..7065f36 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -59,6 +59,102 @@ was expected." if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected}) message( FATAL_ERROR "Fetch DID occur when it was not expected.") endif() + + message( STATUS "Checking ExternalProjectUpdate to tag: ${desired_tag} (disconnected)" ) + + # Remove the FETCH_HEAD file, so we can check if it gets replaced with a 'git + # fetch'. + set( FETCH_HEAD_file ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT/.git/FETCH_HEAD ) + file( REMOVE ${FETCH_HEAD_file} ) + + # Check initial SHA + execute_process(COMMAND ${GIT_EXECUTABLE} + rev-list --max-count=1 HEAD + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT + RESULT_VARIABLE error_code + OUTPUT_VARIABLE initial_sha + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Configure + execute_process(COMMAND ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} -T "${CMAKE_GENERATOR_TOOLSET}" + -A "${CMAKE_GENERATOR_PLATFORM}" + -DTEST_GIT_TAG:STRING=${desired_tag} + ${ExternalProjectUpdate_SOURCE_DIR} + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR} + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not configure the project.") + endif() + + # Build + execute_process(COMMAND ${CMAKE_COMMAND} + --build ${ExternalProjectUpdate_BINARY_DIR} + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not build the project.") + endif() + + if( EXISTS ${FETCH_HEAD_file} ) + message( FATAL_ERROR "Fetch occured when it was not expected.") + endif() + + # Check the resulting SHA + execute_process(COMMAND ${GIT_EXECUTABLE} + rev-list --max-count=1 HEAD + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT + RESULT_VARIABLE error_code + OUTPUT_VARIABLE tag_sha + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(error_code) + message(FATAL_ERROR "Could not check the sha.") + endif() + + if(NOT (${tag_sha} STREQUAL ${initial_sha})) + message(FATAL_ERROR "Update occurred when it was not expected.") + endif() + + # Update + execute_process(COMMAND ${CMAKE_COMMAND} + --build ${ExternalProjectUpdate_BINARY_DIR} + --target TutorialStep2-GIT-update + RESULT_VARIABLE error_code + ) + if(error_code) + message(FATAL_ERROR "Could not build the project.") + endif() + + # Check the resulting SHA + execute_process(COMMAND ${GIT_EXECUTABLE} + rev-list --max-count=1 HEAD + WORKING_DIRECTORY ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep2-GIT + RESULT_VARIABLE error_code + OUTPUT_VARIABLE tag_sha + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(error_code) + message(FATAL_ERROR "Could not check the sha.") + endif() + + if(NOT (${tag_sha} STREQUAL ${resulting_sha})) + message(FATAL_ERROR "UPDATE_COMMAND produced + ${tag_sha} +when + ${resulting_sha} +was expected." + ) + endif() + + if( NOT EXISTS ${FETCH_HEAD_file} AND ${fetch_expected}) + message( FATAL_ERROR "Fetch did NOT occur when it was expected.") + endif() + if( EXISTS ${FETCH_HEAD_file} AND NOT ${fetch_expected}) + message( FATAL_ERROR "Fetch DID occur when it was not expected.") + endif() endmacro() find_package(Git) diff --git a/Tests/FindGSL/CMakeLists.txt b/Tests/FindGSL/CMakeLists.txt new file mode 100644 index 0000000..45a3471 --- /dev/null +++ b/Tests/FindGSL/CMakeLists.txt @@ -0,0 +1,9 @@ +add_test(NAME FindGSL.rng COMMAND ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindGSL/rng" + "${CMake_BINARY_DIR}/Tests/FindGSL/rng" + ${build_generator_args} + --build-project FindGSL_rng + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V + ) diff --git a/Tests/FindGSL/rng/CMakeLists.txt b/Tests/FindGSL/rng/CMakeLists.txt new file mode 100644 index 0000000..b15d6ac --- /dev/null +++ b/Tests/FindGSL/rng/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.0) +project(FindGSL_rng CXX) +include(CTest) + +find_package(GSL REQUIRED) + +add_executable(tstgslrng_tgt main.cc) +target_link_libraries(tstgslrng_tgt GSL::gsl) +add_test(NAME tstgslrng_tgt COMMAND tstgslrng_tgt) + +add_executable(tstgslrng_var main.cc) +target_link_libraries(tstgslrng_var ${GSL_LIBRARIES}) +target_include_directories(tstgslrng_var PRIVATE ${GSL_INCLUDE_DIRS}) +add_test(NAME tstgslrng_var COMMAND tstgslrng_var) diff --git a/Tests/FindGSL/rng/main.cc b/Tests/FindGSL/rng/main.cc new file mode 100644 index 0000000..72543be --- /dev/null +++ b/Tests/FindGSL/rng/main.cc @@ -0,0 +1,24 @@ +#include <math.h> +#include "gsl/gsl_rng.h" + +int main() +{ + // return code + int retval = 1; + + // create a generator + gsl_rng *generator; + generator = gsl_rng_alloc(gsl_rng_mt19937); + + // Read a value. + double const Result = gsl_rng_uniform(generator); + + // Check value + double const expectedResult( 0.999741748906672 ); + if( fabs( expectedResult - Result ) < 1.0e-6 ) + retval = 0; + + // free allocated memory + gsl_rng_free(generator); + return retval; +} diff --git a/Tests/FindJsonCpp/CMakeLists.txt b/Tests/FindJsonCpp/CMakeLists.txt new file mode 100644 index 0000000..9a1fa38 --- /dev/null +++ b/Tests/FindJsonCpp/CMakeLists.txt @@ -0,0 +1,10 @@ +add_test(NAME FindJsonCpp.Test COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindJsonCpp/Test" + "${CMake_BINARY_DIR}/Tests/FindJsonCpp/Test" + ${build_generator_args} + --build-project TestFindJsonCpp + --build-options ${build_options} + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) diff --git a/Tests/FindJsonCpp/Test/CMakeLists.txt b/Tests/FindJsonCpp/Test/CMakeLists.txt new file mode 100644 index 0000000..4e1e271 --- /dev/null +++ b/Tests/FindJsonCpp/Test/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.1) +project(TestFindJsonCpp CXX) +include(CTest) + +find_package(JsonCpp REQUIRED) + +add_executable(test_jsoncpp_tgt main.cxx) +target_link_libraries(test_jsoncpp_tgt JsonCpp::JsonCpp) +add_test(NAME test_jsoncpp_tgt COMMAND test_jsoncpp_tgt) + +add_executable(test_jsoncpp_var main.cxx) +target_include_directories(test_jsoncpp_var PRIVATE ${JsonCpp_INCLUDE_DIRS}) +target_link_libraries(test_jsoncpp_var PRIVATE ${JsonCpp_LIBRARIES}) +add_test(NAME test_jsoncpp_var COMMAND test_jsoncpp_var) diff --git a/Tests/FindJsonCpp/Test/main.cxx b/Tests/FindJsonCpp/Test/main.cxx new file mode 100644 index 0000000..0fefe32 --- /dev/null +++ b/Tests/FindJsonCpp/Test/main.cxx @@ -0,0 +1,8 @@ +#include <json/json.h> + +int main() +{ + int zero = 0; + Json::Value value(zero); + return value.asInt(); +} diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index f55e727..1b2651d 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -66,3 +66,29 @@ if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL) "${err}") endif() endif() + +# Test generation of preprocessed sources. +if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM) + if(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE) + # Skip running this part of the test on certain platforms + # until they are fixed. + set(MAYBE_ALL ALL) + list(LENGTH CMAKE_OSX_ARCHITECTURES ARCH_COUNT) + if(ARCH_COUNT GREATER 1) + # OSX does not support preprocessing more than one architecture. + set(MAYBE_ALL) + endif() + + add_executable(preprocess preprocess.F) + + # Custom target to try preprocessing invocation. + add_custom_target(test_preprocess ${MAYBE_ALL} + COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/preprocess.dir/preprocess.F.i + COMMAND ${CMAKE_MAKE_PROGRAM} preprocess.i + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake + # Remove bogus file some compilers leave behind. + COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + endif() +endif() diff --git a/Tests/FortranOnly/preprocess.F b/Tests/FortranOnly/preprocess.F new file mode 100644 index 0000000..f7df457 --- /dev/null +++ b/Tests/FortranOnly/preprocess.F @@ -0,0 +1,5 @@ + PROGRAM PREPRO +#ifndef TEST_PREPROCESSOR + PRINT *, 'Hello' +#endif + END diff --git a/Tests/FortranOnly/test_preprocess.cmake b/Tests/FortranOnly/test_preprocess.cmake new file mode 100644 index 0000000..29ebdac --- /dev/null +++ b/Tests/FortranOnly/test_preprocess.cmake @@ -0,0 +1,7 @@ +set(TEST_FILE CMakeFiles/preprocess.dir/preprocess.F.i) +file(READ ${TEST_FILE} CONTENTS) +if("${CONTENTS}" MATCHES "PRINT *") + message(STATUS "${TEST_FILE} created successfully!") +else() + message(FATAL_ERROR "${TEST_FILE} creation failed!") +endif() diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt index fe202dd..ee81419 100644 --- a/Tests/InterfaceLibrary/CMakeLists.txt +++ b/Tests/InterfaceLibrary/CMakeLists.txt @@ -22,8 +22,11 @@ add_library(objlib OBJECT obj.cpp) add_library(iface_objlib INTERFACE) target_sources(iface_objlib INTERFACE $<TARGET_OBJECTS:objlib>) +add_library(intermediate INTERFACE) +target_link_libraries(intermediate INTERFACE iface_objlib) + add_executable(InterfaceLibrary definetestexe.cpp) -target_link_libraries(InterfaceLibrary iface_nodepends headeriface subiface iface_objlib) +target_link_libraries(InterfaceLibrary iface_nodepends headeriface subiface intermediate) add_subdirectory(libsdir) diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt index ebca48e..f99f6af 100644 --- a/Tests/Module/ExternalData/CMakeLists.txt +++ b/Tests/Module/ExternalData/CMakeLists.txt @@ -10,7 +10,9 @@ if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/") endif() set(ExternalData_URL_TEMPLATES "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)" + "ExternalDataCustomScript://MyScript1/%(algo)/%(hash)" ) +set(ExternalData_CUSTOM_SCRIPT_MyScript1 "${CMAKE_CURRENT_SOURCE_DIR}/MyScript1.cmake") set(ExternalData_BINARY_ROOT "${CMAKE_CURRENT_BINARY_DIR}/ExternalData") file(REMOVE_RECURSE ${ExternalData_BINARY_ROOT}) # clean test @@ -23,6 +25,7 @@ ExternalData_Add_Test(Data1 COMMAND ${CMAKE_COMMAND} -D Data=DATA{Data.dat} ${Data1CheckSpaces} + -D DataScript=DATA{DataScript.dat} -D DataMissing=DATA{DataMissing.dat} -D DataMissingWithAssociated=DATA{DataMissing.dat,Data.dat} -D SeriesA=DATA{SeriesA.dat,:} diff --git a/Tests/Module/ExternalData/Data1Check.cmake b/Tests/Module/ExternalData/Data1Check.cmake index 485b5c6..a7aa4ae 100644 --- a/Tests/Module/ExternalData/Data1Check.cmake +++ b/Tests/Module/ExternalData/Data1Check.cmake @@ -8,6 +8,10 @@ if(DEFINED DataSpace) message(SEND_ERROR "Input file:\n ${DataSpace}\ndoes not have expected content, but [[${lines}]]") endif() endif() +file(STRINGS "${DataScript}" lines LIMIT_INPUT 1024) +if(NOT "x${lines}" STREQUAL "xDataScript") + message(SEND_ERROR "Input file:\n ${DataScript}\ndoes not have expected content, but [[${lines}]]") +endif() if(DataMissing) if(EXISTS "${DataMissing}") message(SEND_ERROR diff --git a/Tests/Module/ExternalData/DataScript.dat.md5 b/Tests/Module/ExternalData/DataScript.dat.md5 new file mode 100644 index 0000000..74b4616 --- /dev/null +++ b/Tests/Module/ExternalData/DataScript.dat.md5 @@ -0,0 +1 @@ +fd95c03719e8626c0d10a818f9996dc5 diff --git a/Tests/Module/ExternalData/MyScript1.cmake b/Tests/Module/ExternalData/MyScript1.cmake new file mode 100644 index 0000000..242c64d --- /dev/null +++ b/Tests/Module/ExternalData/MyScript1.cmake @@ -0,0 +1,5 @@ +if(ExternalData_CUSTOM_LOCATION STREQUAL "MD5/fd95c03719e8626c0d10a818f9996dc5") + file(WRITE "${ExternalData_CUSTOM_FILE}" "DataScript") +else() + set(ExternalData_CUSTOM_ERROR "no ${ExternalData_CUSTOM_LOCATION} known") +endif() diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index 645cc65..78c4a6a 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0.0) +cmake_minimum_required(VERSION 3.1.0) project(WriteCompilerDetectionHeader) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -11,7 +11,7 @@ get_property(c_known_features GLOBAL PROPERTY CMAKE_C_KNOWN_FEATURES) write_compiler_detection_header( FILE "${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h" PREFIX TEST - COMPILERS GNU Clang + COMPILERS GNU Clang AppleClang SunPro VERSION 3.1 PROLOG "// something" EPILOG "// more" @@ -25,12 +25,14 @@ if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES) ) add_executable(WriteCompilerDetectionHeader "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp") - include(CheckCXXSourceCompiles) - check_cxx_source_compiles("#include \"${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h\"\nint main() { return 0; }\n" - file_include_works - ) - if (file_include_works) - message(SEND_ERROR "Inclusion of ${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h was expected to cause an error, but did not.") + if(UNIX OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + include(CheckCXXSourceCompiles) + check_cxx_source_compiles("#include \"${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h\"\nint main() { return 0; }\n" + file_include_works + ) + if (file_include_works) + message(SEND_ERROR "Inclusion of ${CMAKE_CURRENT_BINARY_DIR}/test_compiler_detection.h was expected to cause an error, but did not.") + endif() endif() return() endif() @@ -56,17 +58,43 @@ macro(set_defines target true_defs false_defs) ) endmacro() -if (CMAKE_CXX_COMPILER_ID STREQUAL GNU - OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" + OR CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") # False for C++98 mode. list(APPEND false_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS) list(APPEND false_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES) endif() +if (CMAKE_C_COMPILER_ID STREQUAL "GNU" + OR CMAKE_C_COMPILER_ID STREQUAL "Clang" + OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang") + add_executable(C_undefined c_undefined.c) + set_property(TARGET C_undefined PROPERTY C_STANDARD 90) + target_compile_options(C_undefined PRIVATE -Werror=undef) +endif() + add_executable(WriteCompilerDetectionHeader main.cpp) set_property(TARGET WriteCompilerDetectionHeader PROPERTY CXX_STANDARD 98) set_defines(WriteCompilerDetectionHeader "${true_defs}" "${false_defs}") +write_compiler_detection_header( + FILE "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/multi_file_compiler_detection.h" + PREFIX MULTI + OUTPUT_FILES_VAR multi_files + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files/compiler_support" + COMPILERS GNU Clang AppleClang SunPro + VERSION 3.1 + FEATURES + ${cxx_known_features} ${c_known_features} +) + +add_executable(multi_files multi_files.cpp) +set_property(TARGET multi_files PROPERTY CXX_STANDARD 98) +target_include_directories(multi_files PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files) +set_defines(multi_files "${true_defs}" "${false_defs}") + if(MSVC) return() # MSVC has only one mode. endif() @@ -86,3 +114,8 @@ endif() add_executable(WriteCompilerDetectionHeader_11 main.cpp) set_property(TARGET WriteCompilerDetectionHeader_11 PROPERTY CXX_STANDARD 11) set_defines(WriteCompilerDetectionHeader_11 "${true_defs}" "${false_defs}") + +add_executable(multi_files_11 multi_files.cpp) +set_property(TARGET multi_files_11 PROPERTY CXX_STANDARD 11) +target_include_directories(multi_files_11 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compiler_multi_files) +set_defines(multi_files_11 "${true_defs}" "${false_defs}") diff --git a/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c b/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c new file mode 100644 index 0000000..487e66d --- /dev/null +++ b/Tests/Module/WriteCompilerDetectionHeader/c_undefined.c @@ -0,0 +1,7 @@ + +#include "test_compiler_detection.h" + +int main() +{ + return 0; +} diff --git a/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h b/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h new file mode 100644 index 0000000..8b547d8 --- /dev/null +++ b/Tests/Module/WriteCompilerDetectionHeader/compile_tests.h @@ -0,0 +1,25 @@ + +#define JOIN_IMPL(A, B) A ## B +#define JOIN(A, B) JOIN_IMPL(A, B) + +#define CHECK(FEATURE) (JOIN(PREFIX, JOIN(_COMPILER_, FEATURE)) == JOIN(EXPECTED_COMPILER_, FEATURE)) + +#if !CHECK(CXX_DELEGATING_CONSTRUCTORS) +#error cxx_delegating_constructors expected availability did not match. +#endif + +#if !CHECK(CXX_VARIADIC_TEMPLATES) +#error cxx_variadic_templates expected availability did not match. +#endif + +#if !CHECK(VERSION_MAJOR) +#error Compiler major version did not match. +#endif + +#if !CHECK(VERSION_MINOR) +#error Compiler minor version did not match. +#endif + +#if !CHECK(VERSION_PATCH) +#error Compiler patch version did not match. +#endif diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp index b807ad5..192094c 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/main.cpp +++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp @@ -1,28 +1,11 @@ #include "test_compiler_detection.h" -#define JOIN_IMPL(A, B) A ## B -#define JOIN(A, B) JOIN_IMPL(A, B) -#define CHECK(FEATURE) (JOIN(TEST_COMPILER_, FEATURE) == JOIN(EXPECTED_COMPILER_, FEATURE)) +#define PREFIX TEST +#include "compile_tests.h" -#if !CHECK(CXX_DELEGATING_CONSTRUCTORS) -#error cxx_delegating_constructors expected availability did not match. -#endif - -#if !CHECK(CXX_VARIADIC_TEMPLATES) -#error cxx_variadic_templates expected availability did not match. -#endif - -#if !CHECK(VERSION_MAJOR) -#error Compiler major version did not match. -#endif - -#if !CHECK(VERSION_MINOR) -#error Compiler minor version did not match. -#endif - -#if !CHECK(VERSION_PATCH) -#error Compiler patch version did not match. +#ifdef TEST_COMPILER_C_STATIC_ASSERT +#error Expect no C features defined #endif int main() diff --git a/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp new file mode 100644 index 0000000..1635091 --- /dev/null +++ b/Tests/Module/WriteCompilerDetectionHeader/multi_files.cpp @@ -0,0 +1,14 @@ + +#include "multi_file_compiler_detection.h" + +#define PREFIX MULTI +#include "compile_tests.h" + +#ifdef MULTI_COMPILER_C_STATIC_ASSERT +#error Expect no C features defined +#endif + +int main() +{ + return 0; +} diff --git a/Tests/OutDir/OutDir.cmake b/Tests/OutDir/OutDir.cmake index e1e6b7f..a1f13e7 100644 --- a/Tests/OutDir/OutDir.cmake +++ b/Tests/OutDir/OutDir.cmake @@ -16,13 +16,17 @@ find_program(CONLY_EXE PATHS ${top}/runtime NO_DEFAULT_PATH) +file(RELATIVE_PATH TESTC1_LIB_FILE "${top}" "${TESTC1_LIB}") +file(RELATIVE_PATH TESTC2_LIB_FILE "${top}" "${TESTC2_LIB}") +file(RELATIVE_PATH CONLY_EXE_FILE "${top}" "${CONLY_EXE}") + file(WRITE ${top}/OutDir.h "/* Generated by ${CMAKE_CURRENT_LIST_FILE} */ #ifndef OutDir_h #define OutDir_h -#define TESTC1_LIB \"${TESTC1_LIB}\" -#define TESTC2_LIB \"${TESTC2_LIB}\" -#define CONLY_EXE \"${CONLY_EXE}\" +#define TESTC1_LIB \"${TESTC1_LIB_FILE}\" +#define TESTC2_LIB \"${TESTC2_LIB_FILE}\" +#define CONLY_EXE \"${CONLY_EXE_FILE}\" #endif ") diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index a60b556..0dc98e3 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -73,6 +73,12 @@ if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]" AND NOT CMAKE_CONFIGURATION_ add_definitions(-DTEST_DEBUG_CLASS) endif() +# The -no-protection option disables the generation of include guards. Verify +# that setting the source file property has an effect by using this and +# issue an error in the preprocessor in calwidget.cpp if the include guard +# is defined. +set_source_files_properties(calwidget.ui PROPERTIES AUTOUIC_OPTIONS "-no-protection") + add_executable(QtAutogen main.cpp calwidget.cpp second_widget.cpp foo.cpp blub.cpp bar.cpp abc.cpp multiplewidgets.cpp xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot> diff --git a/Tests/QtAutogen/calwidget.cpp b/Tests/QtAutogen/calwidget.cpp index defde20..5f59994 100644 --- a/Tests/QtAutogen/calwidget.cpp +++ b/Tests/QtAutogen/calwidget.cpp @@ -50,6 +50,9 @@ #include "calwidget.h" #include "ui_calwidget.h" + #ifdef UI_CALWIDGET_H + #error Definition of UI_CALWIDGET_H should be disabled by file option. + #endif Window::Window() : ui(new Ui::Window) diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt index 12cd3c7..8f85fbf 100644 --- a/Tests/RunCMake/CMP0019/CMakeLists.txt +++ b/Tests/RunCMake/CMP0019/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 2.8.4) project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt new file mode 100644 index 0000000..0996cb6 --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt @@ -0,0 +1,12 @@ +CMake Warning \(dev\) at LOCATION-and-TARGET_OBJECTS.cmake:[0-9]+ \(get_target_property\): + Policy CMP0026 is not set: Disallow use of the LOCATION target property. + Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy + command to set the policy and suppress this warning. + + The LOCATION property should not be read from target "bar". Use the target + name directly with add_custom_command, or use the generator expression + \$<TARGET_FILE>, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake new file mode 100644 index 0000000..3d8eb73 --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(foo OBJECT empty.cpp) +add_executable(bar $<TARGET_OBJECTS:foo>) +get_target_property(location bar LOCATION) diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake index 7c2582f..fc58ea5 100644 --- a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake @@ -10,3 +10,4 @@ run_cmake(CMP0026-LOCATION-CONFIG-NEW) run_cmake(CMP0026-LOCATION-CONFIG-OLD) run_cmake(CMP0026-LOCATION-CONFIG-WARN) run_cmake(ObjlibNotDefined) +run_cmake(LOCATION-and-TARGET_OBJECTS) diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt new file mode 100644 index 0000000..27e8140 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0055-NEW-Out-of-Scope.cmake:4 \(break\): + A BREAK command was found outside of a proper FOREACH or WHILE loop scope. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake new file mode 100644 index 0000000..53ac214 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Out-of-Scope.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0055 NEW) + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt new file mode 100644 index 0000000..32947af --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0055-NEW-Reject-Arguments.cmake:5 \(break\): + The BREAK command does not accept any arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake new file mode 100644 index 0000000..52eaa6a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-NEW-Reject-Arguments.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0055 NEW) + +foreach(i RANGE 1 2) + break(1) +endforeach()
\ No newline at end of file diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake new file mode 100644 index 0000000..57195c2 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope.cmake @@ -0,0 +1,4 @@ + +cmake_policy(SET CMP0055 OLD) + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake new file mode 100644 index 0000000..d8fdddf --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments.cmake @@ -0,0 +1,6 @@ + +cmake_policy(SET CMP0055 OLD) + +foreach(i RANGE 1 2) + break(1) +endforeach()
\ No newline at end of file diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt new file mode 100644 index 0000000..ad850ac --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMP0055-WARN-Out-of-Scope.cmake:2 \(break\): + Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake + --help-policy CMP0055" for policy details. Use the cmake_policy command to + set the policy and suppress this warning. + + A BREAK command was found outside of a proper FOREACH or WHILE loop scope. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake new file mode 100644 index 0000000..373a95a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Out-of-Scope.cmake @@ -0,0 +1,2 @@ + +break() diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt new file mode 100644 index 0000000..3cc686d --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMP0055-WARN-Reject-Arguments.cmake:3 \(break\): + Policy CMP0055 is not set: Strict checking for break\(\) command. Run "cmake + --help-policy CMP0055" for policy details. Use the cmake_policy command to + set the policy and suppress this warning. + + The BREAK command does not accept any arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake new file mode 100644 index 0000000..ec6b90f --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMP0055-WARN-Reject-Arguments.cmake @@ -0,0 +1,4 @@ + +foreach(i RANGE 1 2) + break(1) +endforeach() diff --git a/Tests/RunCMake/CMP0055/CMakeLists.txt b/Tests/RunCMake/CMP0055/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/CMP0055/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0055/RunCMakeTest.cmake b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake new file mode 100644 index 0000000..efcfcab --- /dev/null +++ b/Tests/RunCMake/CMP0055/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(CMP0055-OLD-Out-of-Scope) +run_cmake(CMP0055-NEW-Out-of-Scope) +run_cmake(CMP0055-WARN-Out-of-Scope) + +run_cmake(CMP0055-OLD-Reject-Arguments) +run_cmake(CMP0055-NEW-Reject-Arguments) +run_cmake(CMP0055-WARN-Reject-Arguments) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index fd3bb03..3a61751 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -1,7 +1,7 @@ # See adjacent README.rst for documentation of this test infrastructure. macro(add_RunCMake_test test) - add_test(RunCMake.${test} ${CMAKE_CMAKE_COMMAND} + add_test(NAME RunCMake.${test} COMMAND ${CMAKE_CMAKE_COMMAND} -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR} -DRunCMake_GENERATOR=${CMAKE_GENERATOR} -DRunCMake_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} @@ -9,6 +9,7 @@ macro(add_RunCMake_test test) -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test} -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test} ${${test}_ARGS} + ${ARGN} -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake" ) endmacro() @@ -49,7 +50,22 @@ add_RunCMake_test(CMP0050) add_RunCMake_test(CMP0051) add_RunCMake_test(CMP0053) add_RunCMake_test(CMP0054) +add_RunCMake_test(CMP0055) add_RunCMake_test(CTest) +add_RunCMake_test(CTestSubmit) + +if(NOT CMake_TEST_EXTERNAL_CMAKE) + add_RunCMake_test(CTestMemcheck + -DPSEUDO_BC=$<TARGET_FILE:pseudo_BC> + -DPSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify> + -DPSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind> + -DPSEUDO_BC_NOLOG=$<TARGET_FILE:pseudonl_BC> + -DPSEUDO_PURIFY_NOLOG=$<TARGET_FILE:pseudonl_purify> + -DPSEUDO_VALGRIND_NOLOG=$<TARGET_FILE:pseudonl_valgrind> + -DMEMCHECK_FAIL=$<TARGET_FILE:memcheck_fail> + ) +endif() + if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja") add_RunCMake_test(CompilerChange) endif() @@ -95,19 +111,25 @@ endif() add_RunCMake_test(CompatibleInterface) add_RunCMake_test(Syntax) +add_RunCMake_test(add_custom_command) +add_RunCMake_test(add_custom_target) add_RunCMake_test(add_dependencies) add_RunCMake_test(build_command) add_RunCMake_test(export) add_RunCMake_test(cmake_minimum_required) +add_RunCMake_test(continue) add_RunCMake_test(file) +add_RunCMake_test(find_library) add_RunCMake_test(find_package) add_RunCMake_test(get_filename_component) +add_RunCMake_test(get_property) add_RunCMake_test(if) add_RunCMake_test(include) add_RunCMake_test(include_directories) add_RunCMake_test(list) add_RunCMake_test(message) add_RunCMake_test(project) +add_RunCMake_test(return) add_RunCMake_test(string) add_RunCMake_test(try_compile) add_RunCMake_test(set) @@ -125,8 +147,7 @@ if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0) add_RunCMake_test(IncompatibleQt) endif() if (QT4_FOUND) - set(ObsoleteQtMacros_ARGS -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) - add_RunCMake_test(ObsoleteQtMacros) + add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif() find_package(PkgConfig QUIET) @@ -153,3 +174,4 @@ add_RunCMake_test(CommandLine) add_RunCMake_test(install) add_RunCMake_test(CPackInstallProperties) +add_RunCMake_test(ExternalProject) diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt.in b/Tests/RunCMake/CTestMemcheck/CMakeLists.txt.in index d15d148..d15d148 100644 --- a/Tests/CTestTestMemcheck/CMakeLists.txt.in +++ b/Tests/RunCMake/CTestMemcheck/CMakeLists.txt.in diff --git a/Tests/CTestTestMemcheck/CTestConfig.cmake.in b/Tests/RunCMake/CTestMemcheck/CTestConfig.cmake.in index 19c76c2..19c76c2 100644 --- a/Tests/CTestTestMemcheck/CTestConfig.cmake.in +++ b/Tests/RunCMake/CTestMemcheck/CTestConfig.cmake.in diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-result.txt b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt new file mode 100644 index 0000000..725270c --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stdout.txt new file mode 100644 index 0000000..1d255d0 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stdout.txt @@ -0,0 +1,2 @@ +Memory checking results: +heap-buffer-overflow - 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-result.txt b/Tests/RunCMake/CTestMemcheck/DummyBC-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBC-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyBC-stderr.txt new file mode 100644 index 0000000..24f536a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBC-stderr.txt @@ -0,0 +1 @@ +Error parsing XML in stream at line 1: no element found diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyBC-stdout.txt new file mode 100644 index 0000000..5829613 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBC-stdout.txt @@ -0,0 +1,3 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-result.txt b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stderr.txt new file mode 100644 index 0000000..634e331 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stderr.txt @@ -0,0 +1,3 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-build/Testing/Temporary/MemoryChecker.1.log +.*Error parsing XML in stream at line 1: no element found +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stdout.txt new file mode 100644 index 0000000..5829613 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stdout.txt @@ -0,0 +1,3 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-result.txt b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stderr.txt new file mode 100644 index 0000000..520222f --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stdout.txt new file mode 100644 index 0000000..97a8a9b --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stdout.txt @@ -0,0 +1,3 @@ +Memory checking results: +Direct leak - 2 +Indirect leak - 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-result.txt b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stderr.txt new file mode 100644 index 0000000..29c6ec7 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stdout.txt new file mode 100644 index 0000000..64390c7 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stdout.txt @@ -0,0 +1,2 @@ +Memory checking results: +use-of-uninitialized-value - 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurify-result.txt b/Tests/RunCMake/CTestMemcheck/DummyPurify-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurify-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurify-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyPurify-stderr.txt new file mode 100644 index 0000000..14bc228 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurify-stderr.txt @@ -0,0 +1,3 @@ +^((^| +)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ +]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurify-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyPurify-stdout.txt new file mode 100644 index 0000000..dabb004 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurify-stdout.txt @@ -0,0 +1,6 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-result.txt b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt new file mode 100644 index 0000000..2506f35 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-build/Testing/Temporary/MemoryChecker.1.log +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stdout.txt new file mode 100644 index 0000000..5829613 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stdout.txt @@ -0,0 +1,3 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-result.txt b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stderr.txt new file mode 100644 index 0000000..ca23692 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stdout.txt new file mode 100644 index 0000000..c3af1f9 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stdout.txt @@ -0,0 +1,13 @@ +Memory checking results: +data race - 1 +data race on vptr \(ctor/dtor vs virtual call\) - 1 +heap-use-after-free - 1 +thread leak - 1 +destroy of a locked mutex - 1 +double lock of a mutex - 1 +unlock of an unlocked mutex \(or by a wrong thread\) - 1 +read lock of a write locked mutex - 1 +read unlock of a write locked mutex - 1 +signal-unsafe call inside of a signal - 1 +signal handler spoils errno - 1 +lock-order-inversion \(potential deadlock\) - 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-result.txt b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stderr.txt new file mode 100644 index 0000000..fd684da --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stdout.txt new file mode 100644 index 0000000..b3473bf --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stdout.txt @@ -0,0 +1,2 @@ +Memory checking results: +left shift of negative value -256 - 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrind-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrind-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrind-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrind-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrind-stderr.txt new file mode 100644 index 0000000..14bc228 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrind-stderr.txt @@ -0,0 +1,3 @@ +^((^| +)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ +]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrind-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrind-stdout.txt new file mode 100644 index 0000000..dabb004 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrind-stdout.txt @@ -0,0 +1,6 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt new file mode 100644 index 0000000..1a2ee5c --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-build/Testing/Temporary/MemoryChecker.1.log +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stdout.txt new file mode 100644 index 0000000..dabb004 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stdout.txt @@ -0,0 +1,6 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stderr.txt new file mode 100644 index 0000000..2d078ef --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stderr.txt @@ -0,0 +1,3 @@ +Problem running command: .*memcheck_fail.* +Problem executing post-memcheck command\(s\). +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stdout.txt new file mode 100644 index 0000000..dabb004 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stdout.txt @@ -0,0 +1,6 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stderr.txt new file mode 100644 index 0000000..43ccb2e --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stderr.txt @@ -0,0 +1,3 @@ +Problem running command: .*memcheck_fail.* +Problem executing pre-memcheck command\(s\). +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stdout.txt new file mode 100644 index 0000000..9a6a1d6 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-build diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt new file mode 100644 index 0000000..14bc228 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt @@ -0,0 +1,3 @@ +^((^| +)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ +]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stdout.txt new file mode 100644 index 0000000..5a5675c --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stdout.txt @@ -0,0 +1,7 @@ +2/2 Test #2: RunCMakeAgain .* +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt new file mode 100644 index 0000000..d8d1ff0 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory checker suppression file: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-build/does-not-exist +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stdout.txt new file mode 100644 index 0000000..d46912e --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-build$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt new file mode 100644 index 0000000..321a2a5 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-build/Testing/Temporary/MemoryChecker.1.log +Error in read script: .*/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stdout.txt new file mode 100644 index 0000000..5829613 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stdout.txt @@ -0,0 +1,3 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stderr.txt new file mode 100644 index 0000000..14bc228 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stderr.txt @@ -0,0 +1,3 @@ +^((^| +)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ +]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stdout.txt new file mode 100644 index 0000000..dabb004 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stdout.txt @@ -0,0 +1,6 @@ +1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec + +100% tests passed, 0 tests failed out of 1 +.* +-- Processing memory checking output:( ) +Memory checking results: diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-result.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt new file mode 100644 index 0000000..14bc228 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt @@ -0,0 +1,3 @@ +^((^| +)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ +]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stdout.txt new file mode 100644 index 0000000..3e0fdb2 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stdout.txt @@ -0,0 +1,8 @@ +Memory check project .*/DummyValgrindTwoTargets-build +.* + *Start 1: RunCMake +(.* +)?Memory check command: .* \"--log-file=.*/DummyValgrindTwoTargets-build/Testing/Temporary/MemoryChecker.1.log\" \"-q\".* + *Start 2: RunCMakeAgain +(.* +)?Memory check command: .* \"--log-file=.*/DummyValgrindTwoTargets-build/Testing/Temporary/MemoryChecker.2.log\" \"-q\".* diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-result.txt b/Tests/RunCMake/CTestMemcheck/NotExist-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/NotExist-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-stderr.txt b/Tests/RunCMake/CTestMemcheck/NotExist-stderr.txt new file mode 100644 index 0000000..0af5b7a --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/NotExist-stderr.txt @@ -0,0 +1 @@ +Memory checker \(MemoryCheckCommand\) not set, or cannot find the specified program\. diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt b/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt new file mode 100644 index 0000000..9e92266 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/CTestMemcheck/NotExist-build$ diff --git a/Tests/RunCMake/CTestMemcheck/RunCMakeTest.cmake b/Tests/RunCMake/CTestMemcheck/RunCMakeTest.cmake new file mode 100644 index 0000000..6485de8 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/RunCMakeTest.cmake @@ -0,0 +1,144 @@ +include(RunCMake) + +set(SITE test-site) +set(BUILDNAME test-build) +set(COVERAGE_COMMAND "") + +function(run_mc_test SUBTEST_NAME CHECKER_COMMAND) + configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in + ${RunCMake_BINARY_DIR}/${SUBTEST_NAME}/test.cmake @ONLY) + configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in + ${RunCMake_BINARY_DIR}/${SUBTEST_NAME}/CTestConfig.cmake @ONLY) + configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in + ${RunCMake_BINARY_DIR}/${SUBTEST_NAME}/CMakeLists.txt @ONLY) + run_cmake_command(${SUBTEST_NAME} ${CMAKE_CTEST_COMMAND} + -C Debug + -S ${RunCMake_BINARY_DIR}/${SUBTEST_NAME}/test.cmake + -V + --output-log ${RunCMake_BINARY_DIR}/${SUBTEST_NAME}-build/testOutput.log + ${ARGN} + ) +endfunction() + +unset(CTEST_EXTRA_CONFIG) +unset(CTEST_EXTRA_CODE) +unset(CMAKELISTS_EXTRA_CODE) + +#----------------------------------------------------------------------------- +# add ThreadSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\") +") +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\" +-P \"${RunCMake_SOURCE_DIR}/testThreadSanitizer.cmake\") +") +run_mc_test(DummyThreadSanitizer "" -DMEMCHECK_TYPE=ThreadSanitizer) +unset(CMAKELISTS_EXTRA_CODE) +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +# add LeakSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") +") +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\" +-P \"${RunCMake_SOURCE_DIR}/testLeakSanitizer.cmake\") +") +run_mc_test(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) +unset(CMAKELISTS_EXTRA_CODE) +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +# add AddressSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") +") +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\" +-P \"${RunCMake_SOURCE_DIR}/testAddressSanitizer.cmake\") +") +run_mc_test(DummyAddressSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer) +unset(CMAKELISTS_EXTRA_CODE) +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +# add MemorySanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\") +") +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\" +-P \"${RunCMake_SOURCE_DIR}/testMemorySanitizer.cmake\") +") +run_mc_test(DummyMemorySanitizer "" -DMEMCHECK_TYPE=MemorySanitizer) +unset(CMAKELISTS_EXTRA_CODE) +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +# add UndefinedBehaviorSanitizer test +set(CTEST_EXTRA_CODE +"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1\") +") +set(CMAKELISTS_EXTRA_CODE +"add_test(NAME TestSan COMMAND \"\${CMAKE_COMMAND}\" +-P \"${RunCMake_SOURCE_DIR}/testUndefinedBehaviorSanitizer.cmake\") +") +run_mc_test(DummyUndefinedBehaviorSanitizer "" -DMEMCHECK_TYPE=UndefinedBehaviorSanitizer) +unset(CMAKELISTS_EXTRA_CODE) +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CTEST_EXTRA_CODE "string(REPLACE \" \" \"\\\\ \" PRE_POST_COMMAND \"\${CTEST_MEMORYCHECK_COMMAND}\") + +set(CTEST_CUSTOM_PRE_MEMCHECK \"\${PRE_POST_COMMAND} pre command\") +set(CTEST_CUSTOM_POST_MEMCHECK \"\${PRE_POST_COMMAND} post command \") +") +run_mc_test(DummyValgrindPrePost "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_POST_MEMCHECK \"${MEMCHECK_FAIL}\")") +run_mc_test(DummyValgrindFailPost "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CTEST_EXTRA_CODE "set(CTEST_CUSTOM_PRE_MEMCHECK \"${MEMCHECK_FAIL}\")") +run_mc_test(DummyValgrindFailPre "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n") +set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)") +run_mc_test(DummyValgrindIgnoreMemcheck "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CONFIG) +unset(CMAKELISTS_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)") +run_mc_test(DummyValgrindTwoTargets "${PSEUDO_VALGRIND}" "-VV") +unset(CMAKELISTS_EXTRA_CODE) + +#----------------------------------------------------------------------------- +set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")") +run_mc_test(DummyValgrindInvalidSupFile "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CONFIG) + +#----------------------------------------------------------------------------- +# CTest will add the logfile option before any custom options. Set the logfile +# again, this time to an empty string. This will cause the logfile to be +# missing, which will be the prove for us that the custom option is indeed used. +set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")") +run_mc_test(DummyValgrindCustomOptions "${PSEUDO_VALGRIND}") +unset(CTEST_EXTRA_CONFIG) + +#----------------------------------------------------------------------------- +run_mc_test(DummyPurify "${PSEUDO_PURIFY}") +run_mc_test(DummyValgrind "${PSEUDO_VALGRIND}") +run_mc_test(DummyBC "${PSEUDO_BC}") +run_mc_test(DummyPurifyNoLogFile "${PSEUDO_PURIFY_NOLOG}") +run_mc_test(DummyValgrindNoLogFile "${PSEUDO_VALGRIND_NOLOG}") +run_mc_test(DummyBCNoLogFile "${PSEUDO_BC_NOLOG}") +run_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe") +run_mc_test(Unknown "\${CMAKE_COMMAND}") diff --git a/Tests/RunCMake/CTestMemcheck/Unknown-result.txt b/Tests/RunCMake/CTestMemcheck/Unknown-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/Unknown-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt b/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt new file mode 100644 index 0000000..2beea2d --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt @@ -0,0 +1,2 @@ +Do not understand memory checker: .*/cmake.* +Error in read script: .*/Tests/RunCMake/CTestMemcheck/Unknown/test.cmake diff --git a/Tests/RunCMake/CTestMemcheck/Unknown-stdout.txt b/Tests/RunCMake/CTestMemcheck/Unknown-stdout.txt new file mode 100644 index 0000000..7ea1af0 --- /dev/null +++ b/Tests/RunCMake/CTestMemcheck/Unknown-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/CTestMemcheck/Unknown-build$ diff --git a/Tests/CTestTestMemcheck/test.cmake.in b/Tests/RunCMake/CTestMemcheck/test.cmake.in index f2ffd06..622d709 100644 --- a/Tests/CTestTestMemcheck/test.cmake.in +++ b/Tests/RunCMake/CTestMemcheck/test.cmake.in @@ -1,16 +1,14 @@ cmake_minimum_required(VERSION 2.8.9) # Settings: -set(CTEST_DASHBOARD_ROOT "@CMAKE_CURRENT_BINARY_DIR@") set(CTEST_SITE "@SITE@") set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Memcheck@SUBTEST_NAME@") -set(CTEST_SOURCE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/@SUBTEST_NAME@") -set(CTEST_BINARY_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/@SUBTEST_NAME@") -set(CTEST_CVS_COMMAND "@CVSCOMMAND@") -set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") -set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@") -set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_GENERATOR_TOOLSET@") +set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@SUBTEST_NAME@") +set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@SUBTEST_NAME@-build") +set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@") set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") diff --git a/Tests/CTestTestMemcheck/testAddressSanitizer.cmake b/Tests/RunCMake/CTestMemcheck/testAddressSanitizer.cmake index 3082e4b..3082e4b 100644 --- a/Tests/CTestTestMemcheck/testAddressSanitizer.cmake +++ b/Tests/RunCMake/CTestMemcheck/testAddressSanitizer.cmake diff --git a/Tests/CTestTestMemcheck/testLeakSanitizer.cmake b/Tests/RunCMake/CTestMemcheck/testLeakSanitizer.cmake index 02030be..02030be 100644 --- a/Tests/CTestTestMemcheck/testLeakSanitizer.cmake +++ b/Tests/RunCMake/CTestMemcheck/testLeakSanitizer.cmake diff --git a/Tests/CTestTestMemcheck/testMemorySanitizer.cmake b/Tests/RunCMake/CTestMemcheck/testMemorySanitizer.cmake index c87af9a..c87af9a 100644 --- a/Tests/CTestTestMemcheck/testMemorySanitizer.cmake +++ b/Tests/RunCMake/CTestMemcheck/testMemorySanitizer.cmake diff --git a/Tests/CTestTestMemcheck/testThreadSanitizer.cmake b/Tests/RunCMake/CTestMemcheck/testThreadSanitizer.cmake index d591931..d591931 100644 --- a/Tests/CTestTestMemcheck/testThreadSanitizer.cmake +++ b/Tests/RunCMake/CTestMemcheck/testThreadSanitizer.cmake diff --git a/Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake b/Tests/RunCMake/CTestMemcheck/testUndefinedBehaviorSanitizer.cmake index 8ef3c0a..8ef3c0a 100644 --- a/Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake +++ b/Tests/RunCMake/CTestMemcheck/testUndefinedBehaviorSanitizer.cmake diff --git a/Tests/RunCMake/CTestSubmit/BadArg-result.txt b/Tests/RunCMake/CTestSubmit/BadArg-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadArg-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt b/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt new file mode 100644 index 0000000..68812ab --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/BadArg/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "bad-arg". diff --git a/Tests/RunCMake/CTestSubmit/BadFILES-result.txt b/Tests/RunCMake/CTestSubmit/BadFILES-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadFILES-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/BadFILES-stderr.txt b/Tests/RunCMake/CTestSubmit/BadFILES-stderr.txt new file mode 100644 index 0000000..703224b --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadFILES-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/BadFILES/test.cmake:[0-9]+ \(ctest_submit\): + File "bad-file" does not exist. Cannot submit a non-existent file. diff --git a/Tests/RunCMake/CTestSubmit/BadPARTS-result.txt b/Tests/RunCMake/CTestSubmit/BadPARTS-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadPARTS-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/BadPARTS-stderr.txt b/Tests/RunCMake/CTestSubmit/BadPARTS-stderr.txt new file mode 100644 index 0000000..4e491a9 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/BadPARTS-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/BadPARTS/test.cmake:[0-9]+ \(ctest_submit\): + Part name "bad-part" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt new file mode 100644 index 0000000..48177e2 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadFILES/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "FILES". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt new file mode 100644 index 0000000..77df44f --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt @@ -0,0 +1 @@ +Only http and https are supported for CDASH_UPLOAD diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt new file mode 100644 index 0000000..af95b5c --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt @@ -0,0 +1 @@ +Upload file not specified diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt new file mode 100644 index 0000000..497ead2 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadPARTS/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "PARTS". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt new file mode 100644 index 0000000..8c4e6b1 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "RETRY_COUNT". diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt new file mode 100644 index 0000000..6c56399 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY/test.cmake:[0-9]+ \(ctest_submit\): + ctest_submit called with unknown argument "RETRY_DELAY". diff --git a/Tests/RunCMake/CTestSubmit/CMakeLists.txt.in b/Tests/RunCMake/CTestSubmit/CMakeLists.txt.in new file mode 100644 index 0000000..96e6c13 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestSubmit@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in b/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in new file mode 100644 index 0000000..378a85a --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in @@ -0,0 +1,6 @@ +set(CTEST_PROJECT_NAME "CTestSubmit@CASE_NAME@") + +# Intentionally leave out other upload-related CTestConfig.cmake settings +# so that any ctest_submit calls fail with an error message. +set(CTEST_DROP_METHOD "@CASE_DROP_METHOD@") +set(CTEST_DROP_SITE "@CASE_DROP_SITE@") diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt new file mode 100644 index 0000000..b451315 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt @@ -0,0 +1,4 @@ +Missing arguments for submit via cp: +.* + Problems when submitting via CP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-cp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt new file mode 100644 index 0000000..fa6e004 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt @@ -0,0 +1 @@ +Submit files \(using cp\) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt new file mode 100644 index 0000000..a622fac --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via FTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-ftp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt new file mode 100644 index 0000000..345bb62 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using ftp\) + Using FTP submit method + Drop site: ftp:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt new file mode 100644 index 0000000..6870d2e --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via HTTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-http/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt new file mode 100644 index 0000000..c7f35c5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using http\) + Using HTTP submit method + Drop site:http:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt new file mode 100644 index 0000000..a3c0cd5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt @@ -0,0 +1,3 @@ +Error message was: .* + Problems when submitting via HTTP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-https/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt new file mode 100644 index 0000000..19f8234 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt @@ -0,0 +1,3 @@ +Submit files \(using https\) + Using HTTP submit method + Drop site:https:// diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt new file mode 100644 index 0000000..42b8f50 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt @@ -0,0 +1,2 @@ + Problems when submitting via SCP +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-scp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt new file mode 100644 index 0000000..ec2ce92 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt @@ -0,0 +1 @@ +Submit files \(using scp\) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt new file mode 100644 index 0000000..020b615 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt @@ -0,0 +1,2 @@ + (Problems when submitting via XML-RPC|Submission method "xmlrpc" not compiled into CTest!) +Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt new file mode 100644 index 0000000..ed2acb5 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt @@ -0,0 +1 @@ +Submit files \(using xmlrpc\) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt new file mode 100644 index 0000000..dfa7e33 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/PARTSCDashUpload/test.cmake:[0-9]+ \(ctest_submit\): + Part name "CDASH_UPLOAD" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt new file mode 100644 index 0000000..42becaf --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType/test.cmake:[0-9]+ \(ctest_submit\): + Part name "CDASH_UPLOAD_TYPE" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-result.txt b/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-stderr.txt b/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-stderr.txt new file mode 100644 index 0000000..d56793e --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE/test.cmake:[0-9]+ \(ctest_submit\): + Called with more than one value for RETURN_VALUE diff --git a/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake b/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake new file mode 100644 index 0000000..797365d --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake @@ -0,0 +1,62 @@ +include(RunCMake) + +# Default case parameters. +set(CASE_DROP_METHOD "http") +set(CASE_DROP_SITE "-no-site-") +set(CASE_CTEST_SUBMIT_ARGS "") + +function(run_ctest CASE_NAME) + configure_file(${RunCMake_SOURCE_DIR}/test.cmake.in + ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake @ONLY) + configure_file(${RunCMake_SOURCE_DIR}/CTestConfig.cmake.in + ${RunCMake_BINARY_DIR}/${CASE_NAME}/CTestConfig.cmake @ONLY) + configure_file(${RunCMake_SOURCE_DIR}/CMakeLists.txt.in + ${RunCMake_BINARY_DIR}/${CASE_NAME}/CMakeLists.txt @ONLY) + run_cmake_command(${CASE_NAME} ${CMAKE_CTEST_COMMAND} + -C Debug + -S ${RunCMake_BINARY_DIR}/${CASE_NAME}/test.cmake + -V + --output-log ${RunCMake_BINARY_DIR}/${CASE_NAME}-build/testOutput.log + ${ARGN} + ) +endfunction() + +#----------------------------------------------------------------------------- +# Test bad argument combinations. + +function(run_ctest_submit CASE_NAME) + set(CASE_CTEST_SUBMIT_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_submit(BadArg bad-arg) +run_ctest_submit(BadPARTS PARTS bad-part) +run_ctest_submit(BadFILES FILES bad-file) +run_ctest_submit(RepeatRETURN_VALUE RETURN_VALUE res RETURN_VALUE res) +run_ctest_submit(PARTSCDashUpload PARTS Configure CDASH_UPLOAD) +run_ctest_submit(PARTSCDashUploadType PARTS Configure CDASH_UPLOAD_TYPE) +run_ctest_submit(CDashUploadPARTS CDASH_UPLOAD bad-upload PARTS) +run_ctest_submit(CDashUploadFILES CDASH_UPLOAD bad-upload FILES) +run_ctest_submit(CDashUploadRETRY_COUNT CDASH_UPLOAD bad-upload RETRY_COUNT) +run_ctest_submit(CDashUploadRETRY_DELAY CDASH_UPLOAD bad-upload RETRY_DELAY) +run_ctest_submit(CDashUploadNone CDASH_UPLOAD) + +function(run_ctest_CDashUploadFTP) + set(CASE_DROP_METHOD ftp) + run_ctest_submit(CDashUploadFTP CDASH_UPLOAD ${CMAKE_CURRENT_LIST_FILE}) +endfunction() +run_ctest_CDashUploadFTP() + +#----------------------------------------------------------------------------- +# Test failed drops by various protocols + +function(run_ctest_submit_FailDrop CASE_DROP_METHOD) + run_ctest(FailDrop-${CASE_DROP_METHOD}) +endfunction() + +run_ctest_submit_FailDrop(cp) +run_ctest_submit_FailDrop(ftp) +run_ctest_submit_FailDrop(http) +run_ctest_submit_FailDrop(https) +run_ctest_submit_FailDrop(scp) +run_ctest_submit_FailDrop(xmlrpc) diff --git a/Tests/RunCMake/CTestSubmit/test.cmake.in b/Tests/RunCMake/CTestSubmit/test.cmake.in new file mode 100644 index 0000000..ba826f1 --- /dev/null +++ b/Tests/RunCMake/CTestSubmit/test.cmake.in @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.1) + +set(CTEST_SITE "test-site") +set(CTEST_BUILD_NAME "test-build-name") +set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@") +set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build") +set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@") +set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") + +ctest_start(Experimental) +ctest_configure() + +set(ctest_submit_args "@CASE_CTEST_SUBMIT_ARGS@") +ctest_submit(${ctest_submit_args}) diff --git a/Tests/RunCMake/CheckModules/CMakeLists.txt b/Tests/RunCMake/CheckModules/CMakeLists.txt index 72abfc8..9872df2 100644 --- a/Tests/RunCMake/CheckModules/CMakeLists.txt +++ b/Tests/RunCMake/CheckModules/CMakeLists.txt @@ -1,3 +1,4 @@ cmake_minimum_required(VERSION 2.8.11) +cmake_policy(SET CMP0054 NEW) project(${RunCMake_TEST} NONE) include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CommandLine/CMakeLists.txt b/Tests/RunCMake/CommandLine/CMakeLists.txt new file mode 100644 index 0000000..2897109 --- /dev/null +++ b/Tests/RunCMake/CommandLine/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt b/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt new file mode 100644 index 0000000..bba64bc --- /dev/null +++ b/Tests/RunCMake/CommandLine/D_nested_cache-stderr.txt @@ -0,0 +1 @@ +^-->-DBAR:BOOL=BAZ<--$ diff --git a/Tests/RunCMake/CommandLine/D_nested_cache.cmake b/Tests/RunCMake/CommandLine/D_nested_cache.cmake new file mode 100644 index 0000000..9b57284 --- /dev/null +++ b/Tests/RunCMake/CommandLine/D_nested_cache.cmake @@ -0,0 +1 @@ +message("-->${FOO}<--") diff --git a/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt b/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt new file mode 100644 index 0000000..bba64bc --- /dev/null +++ b/Tests/RunCMake/CommandLine/D_typed_nested_cache-stderr.txt @@ -0,0 +1 @@ +^-->-DBAR:BOOL=BAZ<--$ diff --git a/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake b/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake new file mode 100644 index 0000000..9b57284 --- /dev/null +++ b/Tests/RunCMake/CommandLine/D_typed_nested_cache.cmake @@ -0,0 +1 @@ +message("-->${FOO}<--") diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-stderr.txt new file mode 100644 index 0000000..ca925f1 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: unable to parse mtime 'bad' +CMake Error: Problem creating tar: bad.tar$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-result.txt b/Tests/RunCMake/CommandLine/E_tar-bad-opt1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-opt1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-bad-opt1-stderr.txt new file mode 100644 index 0000000..35133c8 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-bad-opt1-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Unknown option to -E tar: --bad$ diff --git a/Tests/RunCMake/CommandLine/E_tar-end-opt1-result.txt b/Tests/RunCMake/CommandLine/E_tar-end-opt1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-end-opt1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-end-opt1-stderr.txt b/Tests/RunCMake/CommandLine/E_tar-end-opt1-stderr.txt new file mode 100644 index 0000000..1fddf6d --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_tar-end-opt1-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: archive_read_disk_entry_from_file '--bad':.* +CMake Error: Problem creating tar: bad.tar$ diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 5622a5b..2994f16 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -1,5 +1,11 @@ include(RunCMake) +run_cmake_command(E_tar-bad-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar --bad) +run_cmake_command(E_tar-bad-mtime1 ${CMAKE_COMMAND} -E tar cvf bad.tar --mtime=bad .) +run_cmake_command(E_tar-end-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar -- --bad) +run_cmake_command(E_tar-end-opt2 ${CMAKE_COMMAND} -E tar cvf bad.tar --) +run_cmake_command(E_tar-mtime ${CMAKE_COMMAND} -E tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC") + run_cmake_command(build-no-cache ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}) run_cmake_command(build-no-generator @@ -37,9 +43,19 @@ run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1) run_cmake_command(E_env-set ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-set.cmake) run_cmake_command(E_env-unset ${CMAKE_COMMAND} -E env TEST_ENV=1 ${CMAKE_COMMAND} -E env --unset=TEST_ENV ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-unset.cmake) +set(RunCMake_DEFAULT_stderr ".") run_cmake_command(E_sleep-no-args ${CMAKE_COMMAND} -E sleep) +unset(RunCMake_DEFAULT_stderr) run_cmake_command(E_sleep-bad-arg1 ${CMAKE_COMMAND} -E sleep x) run_cmake_command(E_sleep-bad-arg2 ${CMAKE_COMMAND} -E sleep 1 -1) run_cmake_command(E_sleep-one-tenth ${CMAKE_COMMAND} -E sleep 0.1) run_cmake_command(P_directory ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}) + +set(RunCMake_TEST_OPTIONS + "-DFOO=-DBAR:BOOL=BAZ") +run_cmake(D_nested_cache) + +set(RunCMake_TEST_OPTIONS + "-DFOO:STRING=-DBAR:BOOL=BAZ") +run_cmake(D_typed_nested_cache) diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake index 9d56bc0..09594bd 100644 --- a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake +++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycle.cmake @@ -3,13 +3,13 @@ add_library(empty1 empty.cpp) add_library(empty2 INTERFACE) add_library(empty3 INTERFACE) -target_compile_features(empty3 INTERFACE cxx_constexpr) +target_compile_features(empty3 INTERFACE cxx_static_assert) target_link_libraries(empty1 - # When starting, $<COMPILE_FEATURES:cxx_final> is '0', so 'freeze' the + # When starting, $<COMPILE_FEATURES:cxx_auto_type> is '0', so 'freeze' the # CXX_STANDARD at 98 during computation. - $<$<COMPILE_FEATURES:cxx_final>:empty2> - # This would add cxx_constexpr, but that would require CXX_STANDARD = 11, + $<$<COMPILE_FEATURES:cxx_auto_type>:empty2> + # This would add cxx_static_assert, but that would require CXX_STANDARD = 11, # which is not allowed after freeze. Report an error. empty3 ) diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake index 0df548b..bbcf4e0 100644 --- a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake +++ b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved.cmake @@ -3,12 +3,12 @@ add_library(empty1 empty.cpp) add_library(empty2 INTERFACE) add_library(empty3 INTERFACE) -target_compile_features(empty3 INTERFACE cxx_constexpr) +target_compile_features(empty3 INTERFACE cxx_static_assert) target_link_libraries(empty1 - $<$<COMPILE_FEATURES:cxx_final>:empty2> + $<$<COMPILE_FEATURES:cxx_nullptr>:empty2> empty3 ) # This, or populating the COMPILE_FEATURES property with a feature in the -# same standard as cxx_final, solves the cycle above. +# same standard as cxx_nullptr, solves the cycle above. set_property(TARGET empty1 PROPERTY CXX_STANDARD 11) diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake b/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake index c6707c1..b544b99 100644 --- a/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake +++ b/Tests/RunCMake/CompileFeatures/NonValidTarget1.cmake @@ -7,7 +7,7 @@ else() set(expected_result 0) endif() -add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file${HAVE_FINAL}.cpp" +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file${expected_result}.cpp" COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.cpp" ) diff --git a/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake b/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake index eb84692..c41bf57 100644 --- a/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake +++ b/Tests/RunCMake/CompileFeatures/NonValidTarget2.cmake @@ -4,5 +4,7 @@ set(genexvar $<COMPILE_FEATURES:cxx_final>) add_custom_target(copy_target COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.txt" ) +set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/copied_file0.cpp" PROPERTY GENERATED 1) +set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/copied_file1.cpp" PROPERTY GENERATED 1) add_library(empty "${CMAKE_CURRENT_BINARY_DIR}/copied_file${genexvar}.cpp") diff --git a/Tests/RunCMake/ExternalData/BadCustom1-result.txt b/Tests/RunCMake/ExternalData/BadCustom1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt new file mode 100644 index 0000000..5d2986d --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom1-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Bad ExternalDataCustomScript key '0BadKey' in URL template: + + ExternalDataCustomScript://0BadKey/%\(algo\)/%\(hash\) + + The key must be a valid C identifier. +Call Stack \(most recent call first\): + BadCustom1.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalData/BadCustom1.cmake b/Tests/RunCMake/ExternalData/BadCustom1.cmake new file mode 100644 index 0000000..ec94fc1 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom1.cmake @@ -0,0 +1,5 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "ExternalDataCustomScript://0BadKey/%(algo)/%(hash)" + ) +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/ExternalData/BadCustom2-result.txt b/Tests/RunCMake/ExternalData/BadCustom2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt new file mode 100644 index 0000000..4d59ca9 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom2-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Bad ExternalDataCustomScript key '' in URL template: + + ExternalDataCustomScript:///%\(algo\)/%\(hash\) + + The key must be a valid C identifier. +Call Stack \(most recent call first\): + BadCustom2.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalData/BadCustom2.cmake b/Tests/RunCMake/ExternalData/BadCustom2.cmake new file mode 100644 index 0000000..1ed7646 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom2.cmake @@ -0,0 +1,5 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "ExternalDataCustomScript:///%(algo)/%(hash)" + ) +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/ExternalData/BadCustom3-result.txt b/Tests/RunCMake/ExternalData/BadCustom3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt new file mode 100644 index 0000000..460814b --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom3-stderr.txt @@ -0,0 +1,7 @@ +^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + No ExternalData_CUSTOM_SCRIPT_MissingKey is set for URL template: + + ExternalDataCustomScript://MissingKey/%\(algo\)/%\(hash\) +Call Stack \(most recent call first\): + BadCustom3.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalData/BadCustom3.cmake b/Tests/RunCMake/ExternalData/BadCustom3.cmake new file mode 100644 index 0000000..b4f2fb8 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom3.cmake @@ -0,0 +1,5 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "ExternalDataCustomScript://MissingKey/%(algo)/%(hash)" + ) +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/ExternalData/BadCustom4-result.txt b/Tests/RunCMake/ExternalData/BadCustom4-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt b/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt new file mode 100644 index 0000000..b83bcee --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom4-stderr.txt @@ -0,0 +1,7 @@ +^CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + No ExternalData_CUSTOM_SCRIPT_RelPathKey is not set to a full path: + + RelPathScript.cmake +Call Stack \(most recent call first\): + BadCustom4.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/ExternalData/BadCustom4.cmake b/Tests/RunCMake/ExternalData/BadCustom4.cmake new file mode 100644 index 0000000..0cc5521 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadCustom4.cmake @@ -0,0 +1,6 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "ExternalDataCustomScript://RelPathKey/%(algo)/%(hash)" + ) +set(ExternalData_CUSTOM_SCRIPT_RelPathKey "RelPathScript.cmake") +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake index 04e3d59..7afd289 100644 --- a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake @@ -1,5 +1,9 @@ include(RunCMake) +run_cmake(BadCustom1) +run_cmake(BadCustom2) +run_cmake(BadCustom3) +run_cmake(BadCustom4) run_cmake(BadHashAlgo1) run_cmake(BadOption1) run_cmake(BadOption2) diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake new file mode 100644 index 0000000..38683f1 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies.cmake @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION ${CMAKE_VERSION}) + +include(ExternalProject) + +ExternalProject_Add(BAR URL https://cmake.org/bar.tar.gz) + +ExternalProject_Add(FOO URL https://cmake.org/foo.tar.gz STEP_TARGETS update) +ExternalProject_Add_Step(FOO do_something COMMAND ${CMAKE_COMMAND} -E echo "Doing something") +ExternalProject_Add_Step(FOO do_something_else COMMAND ${CMAKE_COMMAND} -E echo "Doing something else") +ExternalProject_Add_StepTargets(FOO do_something) + +# download and do_something_else are not targets, but the file-level +# dependency are set. +ExternalProject_Add_StepDependencies(FOO download BAR) +ExternalProject_Add_StepDependencies(FOO do_something_else BAR) + +# update and do_something are targets, therefore both file-level and +# target-level dependencies are set. +ExternalProject_Add_StepDependencies(FOO update BAR) +ExternalProject_Add_StepDependencies(FOO do_something BAR) diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake new file mode 100644 index 0000000..264c3f0 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_no_target.cmake @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION ${CMAKE_VERSION}) + +include(ExternalProject) + +ExternalProject_Add(BAR URL https://cmake.org/bar.tar.gz) + +ExternalProject_Add(FOO URL https://cmake.org/foo.tar.gz STEP_TARGETS update) +ExternalProject_Add_Step(FOO do_something COMMAND ${CMAKE_COMMAND} -E echo "Doing something") +ExternalProject_Add_Step(FOO do_something_else COMMAND ${CMAKE_COMMAND} -E echo "Doing something else") +ExternalProject_Add_StepTargets(FOO do_something) diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake new file mode 100644 index 0000000..bf9b12d --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_ARGS.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + +set(_tmp_dir "${CMAKE_CURRENT_BINARY_DIR}/tmp") +set(_cache_file "${_tmp_dir}/FOO-cache.cmake") + +ExternalProject_Add(FOO TMP_DIR "${_tmp_dir}" + DOWNLOAD_COMMAND "" + CMAKE_CACHE_ARGS "-DFOO:STRING=BAR") + +if(NOT EXISTS "${_cache_file}") + message(FATAL_ERROR "Initial cache not created") +endif() + +file(READ "${_cache_file}" _cache) + +if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\) + message(FATAL_ERROR "Cannot find FOO argument in cache") +endif() +if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE) + message(FATAL_ERROR "Expected forced FOO argument") +endif() diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake new file mode 100644 index 0000000..c216664 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_DEFAULT_ARGS.cmake @@ -0,0 +1,21 @@ +include(ExternalProject) + +set(_tmp_dir "${CMAKE_CURRENT_BINARY_DIR}/tmp") +set(_cache_file "${_tmp_dir}/FOO-cache.cmake") + +ExternalProject_Add(FOO TMP_DIR "${_tmp_dir}" + DOWNLOAD_COMMAND "" + CMAKE_CACHE_DEFAULT_ARGS "-DFOO:STRING=BAR") + +if(NOT EXISTS "${_cache_file}") + message(FATAL_ERROR "Initial cache not created") +endif() + +file(READ "${_cache_file}" _cache) + +if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\) + message(FATAL_ERROR "Cannot find FOO argument in cache") +endif() +if("${CMAKE_MATCH_0}" MATCHES FORCE) + message(FATAL_ERROR "Expected not forced FOO argument") +endif() diff --git a/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake new file mode 100644 index 0000000..894e183 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CMAKE_CACHE_mix.cmake @@ -0,0 +1,29 @@ +include(ExternalProject) + +set(_tmp_dir "${CMAKE_CURRENT_BINARY_DIR}/tmp") +set(_cache_file "${_tmp_dir}/FOO-cache.cmake") + +ExternalProject_Add(FOO TMP_DIR "${_tmp_dir}" + DOWNLOAD_COMMAND "" + CMAKE_CACHE_ARGS "-DFOO:STRING=BAR" + CMAKE_CACHE_DEFAULT_ARGS "-DBAR:STRING=BAZ") + +if(NOT EXISTS "${_cache_file}") + message(FATAL_ERROR "Initial cache not created") +endif() + +file(READ "${_cache_file}" _cache) + +if(NOT "${_cache}" MATCHES "set\\(FOO \"BAR\".+\\)") # \(\) + message(FATAL_ERROR "Cannot find FOO argument in cache") +endif() +if(NOT "${CMAKE_MATCH_0}" MATCHES FORCE) + message(FATAL_ERROR "Expected forced FOO argument") +endif() + +if(NOT "${_cache}" MATCHES "set\\(BAR \"BAZ\".+\\)") # \(\) + message(FATAL_ERROR "Cannot find BAR argument in cache") +endif() +if("${CMAKE_MATCH_0}" MATCHES FORCE) + message(FATAL_ERROR "Expected not forced BAR argument") +endif() diff --git a/Tests/RunCMake/ExternalProject/CMakeLists.txt b/Tests/RunCMake/ExternalProject/CMakeLists.txt new file mode 100644 index 0000000..c585733 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION ${CMAKE_VERSION}) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt new file mode 100644 index 0000000..4cb051d --- /dev/null +++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt @@ -0,0 +1,36 @@ +CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): + Using NO_DEPENDS for "configure" step might break parallel builds +Call Stack \(most recent call first\): + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\) + NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): + Using NO_DEPENDS for "build" step might break parallel builds +Call Stack \(most recent call first\): + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\) + NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): + Using NO_DEPENDS for "install" step might break parallel builds +Call Stack \(most recent call first\): + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\) + NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): + Using NO_DEPENDS for "test" step might break parallel builds +Call Stack \(most recent call first\): + NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake b/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake new file mode 100644 index 0000000..57626d6 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS.cmake @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 2.8.12) + +include(ExternalProject RESULT_VARIABLE GOO) + +set_property(DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS download patch update configure build) + +ExternalProject_Add(FOO + URL https://example.org/foo.tar.gz) + +ExternalProject_Add(BAR + URL https://example.org/bar.tar.gz + TEST_COMMAND echo test + INDEPENDENT_STEP_TARGETS install) +# This one should not give a warning +ExternalProject_Add_Step(BAR bar + COMMAND echo bar) + +ExternalProject_Add_StepTargets(BAR NO_DEPENDS test bar) diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake new file mode 100644 index 0000000..0f5dcef --- /dev/null +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -0,0 +1,8 @@ +include(RunCMake) + +run_cmake(CMAKE_CACHE_ARGS) +run_cmake(CMAKE_CACHE_DEFAULT_ARGS) +run_cmake(CMAKE_CACHE_mix) +run_cmake(NO_DEPENDS) +run_cmake(Add_StepDependencies) +run_cmake(Add_StepDependencies_no_target) diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake index bb7743c..e9b2a7a 100644 --- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake +++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake @@ -14,6 +14,7 @@ run_cmake(exact_1.2.3) run_cmake(exact_1.2.3.4) # now test every component with an invalid version +set(RunCMake_DEFAULT_stderr ".") run_cmake(exact_0) run_cmake(exact_2) run_cmake(exact_1.1) @@ -22,6 +23,7 @@ run_cmake(exact_1.2.2) run_cmake(exact_1.2.4) run_cmake(exact_1.2.3.3) run_cmake(exact_1.2.3.5) +unset(RunCMake_DEFAULT_stderr) # check if searching for a version 0 works list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DPseudo_VERSION=0") diff --git a/Tests/RunCMake/File_Generate/CarryPermissions-result.txt b/Tests/RunCMake/File_Generate/CarryPermissions-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/File_Generate/CarryPermissions-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt b/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/File_Generate/CarryPermissions.cmake b/Tests/RunCMake/File_Generate/CarryPermissions.cmake new file mode 100644 index 0000000..a04334f --- /dev/null +++ b/Tests/RunCMake/File_Generate/CarryPermissions.cmake @@ -0,0 +1,5 @@ + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output_script.sh" + INPUT "${CMAKE_CURRENT_SOURCE_DIR}/input_script.sh" +) diff --git a/Tests/RunCMake/File_Generate/GenerateSource-result.txt b/Tests/RunCMake/File_Generate/GenerateSource-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/File_Generate/GenerateSource-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt b/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/File_Generate/GenerateSource.cmake b/Tests/RunCMake/File_Generate/GenerateSource.cmake new file mode 100644 index 0000000..147a7f6 --- /dev/null +++ b/Tests/RunCMake/File_Generate/GenerateSource.cmake @@ -0,0 +1,12 @@ + +enable_language(CXX) + +# Ensure re-generation +file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp") + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/main.cpp" + CONTENT "int main() { return 0; }\n" +) + +add_executable(mn "${CMAKE_CURRENT_BINARY_DIR}/main.cpp") diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt new file mode 100644 index 0000000..d3aa973 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects-stderr.txt @@ -0,0 +1,9 @@ +CMake Error at OutputNameMatchesObjects.cmake:2 \(file\): + Error evaluating generator expression: + + \$<TARGET_OBJECTS:foo> + + The evaluation of the TARGET_OBJECTS generator expression is only suitable + for consumption by CMake. It is not suitable for writing out elsewhere. +Call Stack \(most recent call first\): + CMakeLists.txt:6 \(include\) diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake new file mode 100644 index 0000000..d807450 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesObjects.cmake @@ -0,0 +1,10 @@ + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_OBJECTS:foo>>somefile.cpp" + CONTENT "static const char content[] = \"$<TARGET_OBJECTS:foo>\";\n" +) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/input.txt" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/input.txt" "${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(foo empty.cpp "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp" "${CMAKE_CURRENT_BINARY_DIR}/input.txt") diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake new file mode 100644 index 0000000..ce601da --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources.cmake @@ -0,0 +1,14 @@ + +enable_language(CXX) + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_PROPERTY:foo,SOURCES>>somefile.cpp" + CONTENT "static const char content[] = \"$<TARGET_PROPERTY:foo,SOURCES>\";\n" +) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated.cpp" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/generated.cpp" "${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(foo empty.cpp "${CMAKE_CURRENT_BINARY_DIR}/generated.cpp") + +add_executable(bar "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp") diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt new file mode 100644 index 0000000..cefb4e5 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources-stderr.txt @@ -0,0 +1,7 @@ +CMake Error in CMakeLists.txt: + Evaluation output file + + ".*Tests/RunCMake/File_Generate/OutputNameMatchesSources-build/1somefile.cpp" + + depends on the sources of a target it is used in. This is a dependency + loop and is not allowed. diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake b/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake new file mode 100644 index 0000000..2feb9d1 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutputNameMatchesSources.cmake @@ -0,0 +1,12 @@ + +enable_language(CXX) + +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$<BOOL:$<TARGET_PROPERTY:foo,SOURCES>>somefile.cpp" + CONTENT "static const char content[] = \"$<TARGET_PROPERTY:foo,SOURCES>\";\n" +) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp" "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp") + +add_executable(foo "${CMAKE_CURRENT_BINARY_DIR}/1somefile.cpp" "${CMAKE_CURRENT_BINARY_DIR}/renamed.cpp") diff --git a/Tests/RunCMake/File_Generate/ReRunCMake-result.txt b/Tests/RunCMake/File_Generate/ReRunCMake-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/File_Generate/ReRunCMake-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt b/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/File_Generate/ReRunCMake.cmake b/Tests/RunCMake/File_Generate/ReRunCMake.cmake new file mode 100644 index 0000000..109d60e --- /dev/null +++ b/Tests/RunCMake/File_Generate/ReRunCMake.cmake @@ -0,0 +1,5 @@ + +file(GENERATE + OUTPUT output_file.txt + INPUT "${CMAKE_CURRENT_BINARY_DIR}/input_file.txt" +) diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index dee0692..97f93d5 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -8,6 +8,14 @@ run_cmake(EmptyCondition1) run_cmake(EmptyCondition2) run_cmake(BadCondition) run_cmake(DebugEvaluate) +run_cmake(GenerateSource) +run_cmake(OutputNameMatchesSources) +run_cmake(OutputNameMatchesObjects) +run_cmake(OutputNameMatchesOtherSources) +file(READ "${RunCMake_BINARY_DIR}/OutputNameMatchesOtherSources-build/1somefile.cpp" file_contents) +if (NOT file_contents MATCHES "generated.cpp.rule") + message(SEND_ERROR "Rule file not in target sources! ${file_contents}") +endif() set(timeformat "%Y%j%H%M%S") @@ -35,3 +43,52 @@ unset(RunCMake_TEST_NO_CLEAN) if (NOT timestamp_after STREQUAL timestamp) message(SEND_ERROR "WriteIfDifferent changed output file.") endif() + +if (UNIX AND EXISTS /bin/sh) + set(RunCMake_TEST_NO_CLEAN ON) + run_cmake(CarryPermissions) + execute_process( + COMMAND "${RunCMake_BINARY_DIR}/CarryPermissions-build/output_script.sh" + OUTPUT_VARIABLE script_output + RESULT_VARIABLE script_result + ERROR_VARIABLE script_error + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if (script_result) + message(SEND_ERROR "Generated script did not execute correctly: [${script_result}]\n${script_output}\n====\n${script_error}") + endif() + if (NOT script_output STREQUAL SUCCESS) + message(SEND_ERROR "Generated script did not execute correctly:\n${script_output}\n====\n${script_error}") + endif() +endif() + +if (RunCMake_GENERATOR MATCHES Makefiles) + file(MAKE_DIRECTORY "${RunCMake_BINARY_DIR}/ReRunCMake-build/") + file(WRITE "${RunCMake_BINARY_DIR}/ReRunCMake-build/input_file.txt" "InitialContent\n") + + set(RunCMake_TEST_NO_CLEAN ON) + run_cmake(ReRunCMake) + unset(RunCMake_TEST_NO_CLEAN) + file(TIMESTAMP "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt" timestamp ${timeformat}) + if(NOT timestamp) + message(SEND_ERROR "Could not get timestamp for \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"") + endif() + + execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) + + file(WRITE "${RunCMake_BINARY_DIR}/ReRunCMake-build/input_file.txt" "ChangedContent\n") + execute_process(COMMAND ${CMAKE_COMMAND} --build "${RunCMake_BINARY_DIR}/ReRunCMake-build/") + file(READ "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt" out_content) + + if(NOT out_content STREQUAL "ChangedContent\n") + message(SEND_ERROR "File did not change: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"") + endif() + + + file(REMOVE "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt") + execute_process(COMMAND ${CMAKE_COMMAND} --build "${RunCMake_BINARY_DIR}/ReRunCMake-build/") + + if (NOT EXISTS "${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt") + message(SEND_ERROR "File did not re-generate: \"${RunCMake_BINARY_DIR}/ReRunCMake-build/output_file.txt\"") + endif() +endif() diff --git a/Tests/RunCMake/File_Generate/empty.cpp b/Tests/RunCMake/File_Generate/empty.cpp new file mode 100644 index 0000000..bfbbdde --- /dev/null +++ b/Tests/RunCMake/File_Generate/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/File_Generate/input_script.sh b/Tests/RunCMake/File_Generate/input_script.sh new file mode 100755 index 0000000..2cc0983 --- /dev/null +++ b/Tests/RunCMake/File_Generate/input_script.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "$<$<STREQUAL:foo,foo>:SUCCESS>" diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake index 748d14f..2a588bc 100644 --- a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake +++ b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-check.cmake @@ -1,4 +1,4 @@ -file(STRINGS ${RunCMake_TEST_BINARY_DIR}/test.txt TEST_TXT) +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/test.txt TEST_TXT ENCODING UTF-8) list(GET TEST_TXT 0 PDB_PATH) list(GET TEST_TXT 1 PDB_NAME) diff --git a/Tests/RunCMake/Languages/CMakeLists.txt b/Tests/RunCMake/Languages/CMakeLists.txt index 12cd3c7..8996fef 100644 --- a/Tests/RunCMake/Languages/CMakeLists.txt +++ b/Tests/RunCMake/Languages/CMakeLists.txt @@ -1,3 +1,4 @@ cmake_minimum_required(VERSION 2.8.4) +cmake_policy(SET CMP0042 NEW) project(${RunCMake_TEST} NONE) include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt index 3a7f480..03c002e 100644 --- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt @@ -6,4 +6,4 @@ CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\): LINKER_LANGUAGE target property can not be used while evaluating link libraries for a static library Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt index d8bc238..be3b12c 100644 --- a/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt +++ b/Tests/RunCMake/Languages/link-libraries-TARGET_FILE-genex-stderr.txt @@ -6,4 +6,4 @@ CMake Error at link-libraries-TARGET_FILE-genex.cmake:[0-9]+ \(target_link_libra Expressions which require the linker language may not be used while evaluating link libraries Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/README.rst b/Tests/RunCMake/README.rst index 536cff2..e801a86 100644 --- a/Tests/RunCMake/README.rst +++ b/Tests/RunCMake/README.rst @@ -41,7 +41,7 @@ but do not actually build anything. To add a test: ``<SubTest>-stdout.txt`` Regex matching expected stdout content ``<SubTest>-stderr.txt`` - Regex matching expected stderr content + Regex matching expected stderr content, if not "^$" ``<SubTest>-check.cmake`` Custom result check. diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 56d69c8..1625741 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -25,6 +25,13 @@ function(run_cmake test) unset(expect_std${o}) endif() endforeach() + if (NOT expect_stderr) + if (NOT RunCMake_DEFAULT_stderr) + set(RunCMake_DEFAULT_stderr "^$") + endif() + set(expect_stderr ${RunCMake_DEFAULT_stderr}) + endif() + if (NOT RunCMake_TEST_SOURCE_DIR) set(RunCMake_TEST_SOURCE_DIR "${top_src}") endif() @@ -65,7 +72,7 @@ function(run_cmake test) ) endif() set(msg "") - if(NOT "${actual_result}" STREQUAL "${expect_result}") + if(NOT "${actual_result}" MATCHES "${expect_result}") set(msg "${msg}Result is [${actual_result}], not [${expect_result}].\n") endif() foreach(o out err) @@ -86,6 +93,10 @@ function(run_cmake test) if(RunCMake_TEST_FAILED) set(msg "${RunCMake_TEST_FAILED}\n${msg}") endif() + if(msg AND RunCMake_TEST_COMMAND) + string(REPLACE ";" "\" \"" command "\"${RunCMake_TEST_COMMAND}\"") + set(msg "${msg}Command was:\n command> ${command}\n") + endif() if(msg) string(REGEX REPLACE "\n" "\n actual-out> " actual_out " actual-out> ${actual_stdout}") string(REGEX REPLACE "\n" "\n actual-err> " actual_err " actual-err> ${actual_stderr}") diff --git a/Tests/RunCMake/TargetSources/ExportBuild-result.txt b/Tests/RunCMake/TargetSources/ExportBuild-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportBuild-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt b/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt new file mode 100644 index 0000000..0d65a55 --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt @@ -0,0 +1 @@ +CMake Error: Target "iface" has a populated INTERFACE_SOURCES property. This is not currently supported. diff --git a/Tests/RunCMake/TargetSources/ExportBuild.cmake b/Tests/RunCMake/TargetSources/ExportBuild.cmake new file mode 100644 index 0000000..b626aa6 --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportBuild.cmake @@ -0,0 +1,5 @@ + +add_library(iface INTERFACE) +target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp") + +export(TARGETS iface FILE ${CMAKE_CURRENT_BINARY_DIR}/targets.cmake) diff --git a/Tests/RunCMake/TargetSources/ExportInstall-result.txt b/Tests/RunCMake/TargetSources/ExportInstall-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportInstall-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt b/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt new file mode 100644 index 0000000..0d65a55 --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt @@ -0,0 +1 @@ +CMake Error: Target "iface" has a populated INTERFACE_SOURCES property. This is not currently supported. diff --git a/Tests/RunCMake/TargetSources/ExportInstall.cmake b/Tests/RunCMake/TargetSources/ExportInstall.cmake new file mode 100644 index 0000000..8e7c9f9 --- /dev/null +++ b/Tests/RunCMake/TargetSources/ExportInstall.cmake @@ -0,0 +1,6 @@ + +add_library(iface INTERFACE) +target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp") + +install(TARGETS iface EXPORT exp) +install(EXPORT exp DESTINATION cmake) diff --git a/Tests/RunCMake/TargetSources/OriginDebug.cmake b/Tests/RunCMake/TargetSources/OriginDebug.cmake index 5fe9ba7..d40a1d8 100644 --- a/Tests/RunCMake/TargetSources/OriginDebug.cmake +++ b/Tests/RunCMake/TargetSources/OriginDebug.cmake @@ -7,7 +7,7 @@ set(CMAKE_DEBUG_TARGET_PROPERTIES SOURCES) add_library(iface INTERFACE) set_property(TARGET iface PROPERTY INTERFACE_SOURCES - empty_1.cpp + "${CMAKE_CURRENT_SOURCE_DIR}/empty_1.cpp" ) add_library(OriginDebug empty_2.cpp) diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt b/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt b/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt new file mode 100644 index 0000000..d47dd4d --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt @@ -0,0 +1,4 @@ +CMake Error in CMakeLists.txt: + Target "iface" contains relative path in its INTERFACE_SOURCES: + + "empty_1.cpp" diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake new file mode 100644 index 0000000..8bb6149 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake @@ -0,0 +1,6 @@ + +add_library(iface INTERFACE) +target_sources(iface INTERFACE empty_1.cpp) + +add_executable(main main.cpp) +target_link_libraries(main iface) diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake index 1d2eaec..1b4ef0b 100644 --- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake +++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake @@ -8,3 +8,6 @@ else() endif() run_cmake(CMP0026-LOCATION) +run_cmake(RelativePathInInterface) +run_cmake(ExportBuild) +run_cmake(ExportInstall) diff --git a/Tests/RunCMake/TargetSources/main.cpp b/Tests/RunCMake/TargetSources/main.cpp new file mode 100644 index 0000000..766b775 --- /dev/null +++ b/Tests/RunCMake/TargetSources/main.cpp @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt new file mode 100644 index 0000000..6658d5d --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\): + The compiler-specific output directory must be within the same directory as + the main file. +Call Stack \(most recent call first\): + MultiBadOutDir.cmake:4 \(write_compiler_detection_header\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake new file mode 100644 index 0000000..b545bee --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiBadOutDir.cmake @@ -0,0 +1,12 @@ + +include(WriteCompilerDetectionHeader) + +write_compiler_detection_header( + FILE "${CMAKE_CURRENT_BINARY_DIR}/dir/somefile" + PREFIX Pref + OUTPUT_FILES_VAR outfiles + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}" + COMPILERS GNU + VERSION 3.1 + FEATURES cxx_auto_type +) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt new file mode 100644 index 0000000..50f9b6f --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\): + If OUTPUT_DIR is specified, then OUTPUT_FILES_VAR must also be specified. +Call Stack \(most recent call first\): + MultiNoOutFileVar.cmake:4 \(write_compiler_detection_header\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake new file mode 100644 index 0000000..e42b0ed --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutFileVar.cmake @@ -0,0 +1,11 @@ + +include(WriteCompilerDetectionHeader) + +write_compiler_detection_header( + FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile" + PREFIX Pref + OUTPUT_DIR outfiles + COMPILERS GNU + VERSION 3.1 + FEATURES cxx_auto_type +) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt new file mode 100644 index 0000000..1c83a1a --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at .*Modules/WriteCompilerDetectionHeader.cmake:[0-9]+ \(message\): + If OUTPUT_FILES_VAR is specified, then OUTPUT_DIR must also be specified. +Call Stack \(most recent call first\): + MultiNoOutdir.cmake:4 \(write_compiler_detection_header\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake new file mode 100644 index 0000000..e8c2ae1 --- /dev/null +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/MultiNoOutdir.cmake @@ -0,0 +1,11 @@ + +include(WriteCompilerDetectionHeader) + +write_compiler_detection_header( + FILE "${CMAKE_CURRENT_BINARY_DIR}/somefile" + PREFIX Pref + OUTPUT_FILES_VAR outfiles + COMPILERS GNU + VERSION 3.1 + FEATURES cxx_auto_type +) diff --git a/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake b/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake index 6dded44..a834e6d 100644 --- a/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake +++ b/Tests/RunCMake/WriteCompilerDetectionHeader/RunCMakeTest.cmake @@ -12,3 +12,7 @@ run_cmake(InvalidFeature) run_cmake(InvalidCXXFeature) run_cmake(EmptyPrefix) run_cmake(InvalidPrefix) +run_cmake(MultiNoOutdir) +run_cmake(MultiNoOutFileVar) +set(NO_CACHE TRUE) +run_cmake(MultiBadOutDir) diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt b/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNoOutput-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt new file mode 100644 index 0000000..abbfc5a --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNoOutput-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at AppendNoOutput.cmake:1 \(add_custom_command\): + add_custom_command given APPEND option with no OUTPUT. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake b/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake new file mode 100644 index 0000000..c6c716b --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNoOutput.cmake @@ -0,0 +1 @@ +add_custom_command(TARGET x APPEND DEPENDS a b c d) diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt new file mode 100644 index 0000000..96d0972 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNotOutput-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at AppendNotOutput.cmake:1 \(add_custom_command\): + add_custom_command given APPEND option with output.* + which is not already a custom command output. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake b/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake new file mode 100644 index 0000000..cc16129 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/AppendNotOutput.cmake @@ -0,0 +1 @@ +add_custom_command(OUTPUT out APPEND DEPENDS dep) diff --git a/Tests/RunCMake/add_custom_command/BadArgument-result.txt b/Tests/RunCMake/add_custom_command/BadArgument-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadArgument-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt b/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt new file mode 100644 index 0000000..04c5350 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadArgument-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at BadArgument.cmake:1 \(add_custom_command\): + add_custom_command Wrong syntax. Unknown type of argument. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/BadArgument.cmake b/Tests/RunCMake/add_custom_command/BadArgument.cmake new file mode 100644 index 0000000..d9e7bd4 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/BadArgument.cmake @@ -0,0 +1 @@ +add_custom_command(bad_arg OUTPUT a b c d) diff --git a/Tests/RunCMake/add_custom_command/CMakeLists.txt b/Tests/RunCMake/add_custom_command/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/add_custom_command/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/add_custom_command/NoArguments-result.txt b/Tests/RunCMake/add_custom_command/NoArguments-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoArguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt b/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt new file mode 100644 index 0000000..11e0cb0 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoArguments-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoArguments.cmake:1 \(add_custom_command\): + add_custom_command called with wrong number of arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/NoArguments.cmake b/Tests/RunCMake/add_custom_command/NoArguments.cmake new file mode 100644 index 0000000..8781a87 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoArguments.cmake @@ -0,0 +1 @@ +add_custom_command() diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt new file mode 100644 index 0000000..6a5c0a3 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoOutputOrTarget.cmake:1 \(add_custom_command\): + add_custom_command Wrong syntax. A TARGET or OUTPUT must be specified. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake b/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake new file mode 100644 index 0000000..933ee32 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/NoOutputOrTarget.cmake @@ -0,0 +1 @@ +add_custom_command(COMMAND echo a b c d) diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt b/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/OutputAndTarget-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt b/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt new file mode 100644 index 0000000..632880e --- /dev/null +++ b/Tests/RunCMake/add_custom_command/OutputAndTarget-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at OutputAndTarget.cmake:1 \(add_custom_command\): + add_custom_command Wrong syntax. A TARGET and OUTPUT can not both be + specified. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake b/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake new file mode 100644 index 0000000..55806f3 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/OutputAndTarget.cmake @@ -0,0 +1 @@ +add_custom_command(OUTPUT out TARGET target) diff --git a/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake new file mode 100644 index 0000000..2f5c938 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCMake) + +run_cmake(AppendNoOutput) +run_cmake(AppendNotOutput) +run_cmake(BadArgument) +run_cmake(NoArguments) +run_cmake(NoOutputOrTarget) +run_cmake(OutputAndTarget) +run_cmake(SourceByproducts) +run_cmake(SourceUsesTerminal) diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt b/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceByproducts-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt b/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt new file mode 100644 index 0000000..a9cd64c --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceByproducts-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at SourceByproducts.cmake:1 \(add_custom_command\): + add_custom_command BYPRODUCTS may not be specified with SOURCE signatures +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/SourceByproducts.cmake b/Tests/RunCMake/add_custom_command/SourceByproducts.cmake new file mode 100644 index 0000000..824f41d --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceByproducts.cmake @@ -0,0 +1 @@ +add_custom_command(SOURCE t TARGET t BYPRODUCTS b) diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt new file mode 100644 index 0000000..1a76c54 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at SourceUsesTerminal.cmake:1 \(add_custom_command\): + add_custom_command USES_TERMINAL may not be used with SOURCE signatures +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake new file mode 100644 index 0000000..295fab1 --- /dev/null +++ b/Tests/RunCMake/add_custom_command/SourceUsesTerminal.cmake @@ -0,0 +1 @@ +add_custom_command(SOURCE t TARGET t USES_TERMINAL) diff --git a/Tests/RunCMake/add_custom_target/BadTargetName-result.txt b/Tests/RunCMake/add_custom_target/BadTargetName-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadTargetName-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt b/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt new file mode 100644 index 0000000..f352457 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadTargetName-stderr.txt @@ -0,0 +1,17 @@ +CMake Error at BadTargetName.cmake:1 \(add_custom_target\): + add_custom_target called with target name containing a "#". This character + is not allowed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadTargetName.cmake:2 \(add_custom_target\): + add_custom_target called with target name containing a "<". This character + is not allowed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at BadTargetName.cmake:3 \(add_custom_target\): + add_custom_target called with target name containing a ">". This character + is not allowed. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/BadTargetName.cmake b/Tests/RunCMake/add_custom_target/BadTargetName.cmake new file mode 100644 index 0000000..c4381a2 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/BadTargetName.cmake @@ -0,0 +1,3 @@ +add_custom_target("#") +add_custom_target("<") +add_custom_target(">") diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt new file mode 100644 index 0000000..6c80ca6 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at ByproductsNoCommand.cmake:1 \(add_custom_target\): + BYPRODUCTS may not be specified without any COMMAND +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake b/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake new file mode 100644 index 0000000..6c142a2 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/ByproductsNoCommand.cmake @@ -0,0 +1 @@ +add_custom_target(MyTarget BYPRODUCTS a b c d) diff --git a/Tests/RunCMake/add_custom_target/CMakeLists.txt b/Tests/RunCMake/add_custom_target/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/add_custom_target/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/add_custom_target/NoArguments-result.txt b/Tests/RunCMake/add_custom_target/NoArguments-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/NoArguments-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt b/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt new file mode 100644 index 0000000..2230093 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/NoArguments-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoArguments.cmake:1 \(add_custom_target\): + add_custom_target called with incorrect number of arguments +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/NoArguments.cmake b/Tests/RunCMake/add_custom_target/NoArguments.cmake new file mode 100644 index 0000000..ec6a212 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/NoArguments.cmake @@ -0,0 +1 @@ +add_custom_target() diff --git a/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake new file mode 100644 index 0000000..92c4a38 --- /dev/null +++ b/Tests/RunCMake/add_custom_target/RunCMakeTest.cmake @@ -0,0 +1,6 @@ +include(RunCMake) + +run_cmake(NoArguments) +run_cmake(BadTargetName) +run_cmake(ByproductsNoCommand) +run_cmake(UsesTerminalNoCommand) diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt new file mode 100644 index 0000000..beafa7c --- /dev/null +++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at UsesTerminalNoCommand.cmake:1 \(add_custom_target\): + USES_TERMINAL may not be specified without any COMMAND +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake new file mode 100644 index 0000000..b0c207b --- /dev/null +++ b/Tests/RunCMake/add_custom_target/UsesTerminalNoCommand.cmake @@ -0,0 +1 @@ +add_custom_target(MyTarget USES_TERMINAL) diff --git a/Tests/RunCMake/configure_file/RunCMakeTest.cmake b/Tests/RunCMake/configure_file/RunCMakeTest.cmake index c8bfa57..c010256 100644 --- a/Tests/RunCMake/configure_file/RunCMakeTest.cmake +++ b/Tests/RunCMake/configure_file/RunCMakeTest.cmake @@ -6,3 +6,4 @@ run_cmake(UTF16LE-BOM) run_cmake(UTF16BE-BOM) run_cmake(UTF32LE-BOM) run_cmake(UTF32BE-BOM) +run_cmake(UnknownArg) diff --git a/Tests/RunCMake/configure_file/UnknownArg-stderr.txt b/Tests/RunCMake/configure_file/UnknownArg-stderr.txt new file mode 100644 index 0000000..46930c0 --- /dev/null +++ b/Tests/RunCMake/configure_file/UnknownArg-stderr.txt @@ -0,0 +1,10 @@ +CMake Warning \(dev\) at UnknownArg.cmake:1 \(configure_file\): + configure_file called with unknown argument\(s\): + + COPY_ONLY + COPYFILE + COPY_FILE + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/configure_file/UnknownArg.cmake b/Tests/RunCMake/configure_file/UnknownArg.cmake new file mode 100644 index 0000000..5125c83 --- /dev/null +++ b/Tests/RunCMake/configure_file/UnknownArg.cmake @@ -0,0 +1,2 @@ +configure_file(${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in UnknownArg.txt + @ONLY COPYONLY COPY_ONLY COPYFILE COPY_FILE) diff --git a/Tests/RunCMake/continue/CMakeLists.txt b/Tests/RunCMake/continue/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/continue/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/continue/ContinueForEachInLists.cmake b/Tests/RunCMake/continue/ContinueForEachInLists.cmake new file mode 100644 index 0000000..fbd7359 --- /dev/null +++ b/Tests/RunCMake/continue/ContinueForEachInLists.cmake @@ -0,0 +1,10 @@ +list(APPEND foo 1 2 3 4 5) + +message(STATUS "start") +foreach(iter IN LISTS foo) + if("${iter}" EQUAL 1 OR "${iter}" EQUAL 3 OR "${iter}" EQUAL 5) + continue() + endif() + message(STATUS "${iter}") +endforeach() +message(STATUS "end") diff --git a/Tests/RunCMake/continue/ContinueForeach-stdout.txt b/Tests/RunCMake/continue/ContinueForeach-stdout.txt new file mode 100644 index 0000000..955b859 --- /dev/null +++ b/Tests/RunCMake/continue/ContinueForeach-stdout.txt @@ -0,0 +1,4 @@ +-- start +-- 2 +-- 4 +-- end diff --git a/Tests/RunCMake/continue/ContinueForeach.cmake b/Tests/RunCMake/continue/ContinueForeach.cmake new file mode 100644 index 0000000..9b3e17f --- /dev/null +++ b/Tests/RunCMake/continue/ContinueForeach.cmake @@ -0,0 +1,8 @@ +message(STATUS "start") +foreach(iter RANGE 1 5) + if("${iter}" EQUAL 1 OR "${iter}" EQUAL 3 OR "${iter}" EQUAL 5) + continue() + endif() + message(STATUS "${iter}") +endforeach() +message(STATUS "end") diff --git a/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt b/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt new file mode 100644 index 0000000..adb02bc --- /dev/null +++ b/Tests/RunCMake/continue/ContinueNestedForeach-stdout.txt @@ -0,0 +1,6 @@ +-- start +-- 7 2 +-- 7 4 +-- 9 2 +-- 9 4 +-- end diff --git a/Tests/RunCMake/continue/ContinueNestedForeach.cmake b/Tests/RunCMake/continue/ContinueNestedForeach.cmake new file mode 100644 index 0000000..de7c51b --- /dev/null +++ b/Tests/RunCMake/continue/ContinueNestedForeach.cmake @@ -0,0 +1,13 @@ +message(STATUS "start") +foreach(outer RANGE 7 9) + if("${outer}" EQUAL 8) + continue() + endif() + foreach(inner RANGE 1 5) + if("${inner}" EQUAL 1 OR "${inner}" EQUAL 3 OR "${inner}" EQUAL 5) + continue() + endif() + message(STATUS "${outer} ${inner}") + endforeach() +endforeach() +message(STATUS "end") diff --git a/Tests/RunCMake/continue/ContinueWhile-stdout.txt b/Tests/RunCMake/continue/ContinueWhile-stdout.txt new file mode 100644 index 0000000..f99b2a1 --- /dev/null +++ b/Tests/RunCMake/continue/ContinueWhile-stdout.txt @@ -0,0 +1,6 @@ +-- start +-- a +-- aa +-- aaaa +-- aaaaa +-- end diff --git a/Tests/RunCMake/continue/ContinueWhile.cmake b/Tests/RunCMake/continue/ContinueWhile.cmake new file mode 100644 index 0000000..c1fa87a --- /dev/null +++ b/Tests/RunCMake/continue/ContinueWhile.cmake @@ -0,0 +1,10 @@ +message(STATUS "start") +unset(iter) +while(NOT "${iter}" STREQUAL "aaaaa") + set(iter "${iter}a") + if("${iter}" STREQUAL "aaa") + continue() + endif() + message(STATUS "${iter}") +endwhile() +message(STATUS "end") diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt b/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/continue/NoArgumentsToContinue-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt b/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt new file mode 100644 index 0000000..66be4629 --- /dev/null +++ b/Tests/RunCMake/continue/NoArgumentsToContinue-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at NoArgumentsToContinue.cmake:2 \(continue\): + The CONTINUE command does not accept any arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/continue/NoArgumentsToContinue.cmake b/Tests/RunCMake/continue/NoArgumentsToContinue.cmake new file mode 100644 index 0000000..609804d --- /dev/null +++ b/Tests/RunCMake/continue/NoArgumentsToContinue.cmake @@ -0,0 +1,3 @@ +foreach(i RANGE 1 2) + continue(1) +endforeach() diff --git a/Tests/RunCMake/continue/NoEnclosingBlock-result.txt b/Tests/RunCMake/continue/NoEnclosingBlock-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlock-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt b/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt new file mode 100644 index 0000000..24caf57 --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlock-stderr.txt @@ -0,0 +1,5 @@ +CMake Error at NoEnclosingBlock.cmake:1 \(continue\): + A CONTINUE command was found outside of a proper FOREACH or WHILE loop + scope. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/continue/NoEnclosingBlock.cmake b/Tests/RunCMake/continue/NoEnclosingBlock.cmake new file mode 100644 index 0000000..9661e0d --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlock.cmake @@ -0,0 +1 @@ +continue() diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt new file mode 100644 index 0000000..af4f3b6 --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at NoEnclosingBlockInFunction.cmake:2 \(continue\): + A CONTINUE command was found outside of a proper FOREACH or WHILE loop + scope. +Call Stack \(most recent call first\): + NoEnclosingBlockInFunction.cmake:6 \(foo\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake b/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake new file mode 100644 index 0000000..eb2a098 --- /dev/null +++ b/Tests/RunCMake/continue/NoEnclosingBlockInFunction.cmake @@ -0,0 +1,8 @@ +function(foo) + continue() +endfunction(foo) + +foreach(i RANGE 1 2) + foo() + message(STATUS "Hello World") +endforeach() diff --git a/Tests/RunCMake/continue/RunCMakeTest.cmake b/Tests/RunCMake/continue/RunCMakeTest.cmake new file mode 100644 index 0000000..37caf9c --- /dev/null +++ b/Tests/RunCMake/continue/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(ContinueForeach) +run_cmake(ContinueForEachInLists) +run_cmake(ContinueNestedForeach) +run_cmake(ContinueWhile) +run_cmake(NoArgumentsToContinue) +run_cmake(NoEnclosingBlock) +run_cmake(NoEnclosingBlockInFunction) diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt b/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-file-create-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt b/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt new file mode 100644 index 0000000..72b7fe0 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-file-create-fail-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at LOCK-error-file-create-fail\.cmake:[0-9]+ \(file\): + file + + ".*" + + creation failed \(check permissions\)\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake b/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake new file mode 100644 index 0000000..4868cfe --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-file-create-fail.cmake @@ -0,0 +1,3 @@ +set(tmp "${CMAKE_CURRENT_BINARY_DIR}/temp-directory") +file(MAKE_DIRECTORY "${tmp}") +file(LOCK "${tmp}") diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt b/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt b/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt new file mode 100644 index 0000000..85136b4 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at LOCK-error-guard-incorrect\.cmake:[0-9]+ \(file\): + expected FUNCTION, FILE or PROCESS after GUARD, but got: + + "FUNCTIO"\. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake b/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake new file mode 100644 index 0000000..51daa7c --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-guard-incorrect.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD FUNCTIO) diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt new file mode 100644 index 0000000..c6ae1e0 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-incorrect-timeout\.cmake:[0-9]+ \(file\): + TIMEOUT value "qwerty" is not an unsigned integer\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt new file mode 100644 index 0000000..6ea2507 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-incorrect-timeout-trail\.cmake:[0-9]+ \(file\): + TIMEOUT value "123xyz" is not an unsigned integer\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake new file mode 100644 index 0000000..c4f1b75 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout-trail.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT 123xyz) diff --git a/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake b/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake new file mode 100644 index 0000000..d882467 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-incorrect-timeout.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT qwerty) diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt b/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-lock-fail-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt b/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt new file mode 100644 index 0000000..a7b0447 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-lock-fail-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at LOCK-error-lock-fail.cmake:[0-9]+ \(file\): + directory + + ".*" + + creation failed \(check permissions\)\. diff --git a/Tests/RunCMake/file/LOCK-error-lock-fail.cmake b/Tests/RunCMake/file/LOCK-error-lock-fail.cmake new file mode 100644 index 0000000..aa7f663 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-lock-fail.cmake @@ -0,0 +1,6 @@ +set(lfile "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock") +FILE(WRITE "${lfile}" "") + +# Try to lock file '${lfile}/cmake.lock'. Since `lfile` is not a directory +# expected that operation will fail. +file(LOCK "${lfile}" DIRECTORY) diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-negative-timeout-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt new file mode 100644 index 0000000..0d159c1 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-negative-timeout-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-negative-timeout\.cmake:[0-9]+ \(file\): + TIMEOUT value "-2" is not an unsigned integer\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake b/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake new file mode 100644 index 0000000..6a0f190 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-negative-timeout.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT -2) diff --git a/Tests/RunCMake/file/LOCK-error-no-function-result.txt b/Tests/RunCMake/file/LOCK-error-no-function-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-function-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt new file mode 100644 index 0000000..51ed12d --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-function-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at LOCK-error-no-function\.cmake:[0-9]+ \(file\): + error locking file + + ".*" + + 'GUARD FUNCTION' not used in function definition\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-no-function.cmake b/Tests/RunCMake/file/LOCK-error-no-function.cmake new file mode 100644 index 0000000..1b8b06a --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-function.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD FUNCTION) diff --git a/Tests/RunCMake/file/LOCK-error-no-guard-result.txt b/Tests/RunCMake/file/LOCK-error-no-guard-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-guard-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt new file mode 100644 index 0000000..41177ce --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-guard-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-no-guard\.cmake:[0-9]+ \(file\): + expected FUNCTION, FILE or PROCESS after GUARD +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-no-guard.cmake b/Tests/RunCMake/file/LOCK-error-no-guard.cmake new file mode 100644 index 0000000..48ffc5e --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-guard.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" GUARD) diff --git a/Tests/RunCMake/file/LOCK-error-no-path-result.txt b/Tests/RunCMake/file/LOCK-error-no-path-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-path-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt new file mode 100644 index 0000000..2247aa6 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-path-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-no-path.cmake:[0-9]+ \(file\): + file must be called with at least two arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-no-path.cmake b/Tests/RunCMake/file/LOCK-error-no-path.cmake new file mode 100644 index 0000000..12d79b7 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-path.cmake @@ -0,0 +1 @@ +file(LOCK) diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt b/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-result-variable-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt new file mode 100644 index 0000000..b38e23c --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-result-variable-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-no-result-variable\.cmake:[0-9]+ \(file\): + expected variable name after RESULT_VARIABLE +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake b/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake new file mode 100644 index 0000000..e6ac18d --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-result-variable.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" RESULT_VARIABLE) diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-timeout-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt new file mode 100644 index 0000000..f34d46f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-timeout-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at LOCK-error-no-timeout\.cmake:[0-9]+ \(file\): + expected timeout value after TIMEOUT +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-no-timeout.cmake b/Tests/RunCMake/file/LOCK-error-no-timeout.cmake new file mode 100644 index 0000000..1618192 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-no-timeout.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock" TIMEOUT) diff --git a/Tests/RunCMake/file/LOCK-error-timeout-result.txt b/Tests/RunCMake/file/LOCK-error-timeout-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-timeout-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt b/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt new file mode 100644 index 0000000..4ad1f04 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-timeout-stderr.txt @@ -0,0 +1,12 @@ +Output:[ ]* +Error: CMake Error at .*.timeout-script\.cmake:[0-9]+ \(file\): + error locking file + + ".*" + + Timeout reached\. ++ +CMake Error at LOCK-error-timeout\.cmake:[0-9]+ \(message\): + Result: 1 +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt b/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-timeout-stdout.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/file/LOCK-error-timeout.cmake b/Tests/RunCMake/file/LOCK-error-timeout.cmake new file mode 100644 index 0000000..b6b9476 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-timeout.cmake @@ -0,0 +1,17 @@ +set(script "${CMAKE_CURRENT_LIST_DIR}/timeout-script.cmake") +set(file_to_lock "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock") + +file(LOCK "${file_to_lock}") +execute_process( + COMMAND "${CMAKE_COMMAND}" "-Dfile_to_lock=${file_to_lock}" -P "${script}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_VARIABLE error +) + +message("Output: ${output}") +message("Error: ${error}") + +if(NOT result EQUAL 0) + message(FATAL_ERROR "Result: ${result}") +endif() diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt b/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-unknown-option-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt b/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt new file mode 100644 index 0000000..ad596af --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-unknown-option-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at LOCK-error-unknown-option\.cmake:[0-9]+ \(file\): + expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT + + but got: "UNKNOWN"\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]* \(include\) diff --git a/Tests/RunCMake/file/LOCK-error-unknown-option.cmake b/Tests/RunCMake/file/LOCK-error-unknown-option.cmake new file mode 100644 index 0000000..88ef002 --- /dev/null +++ b/Tests/RunCMake/file/LOCK-error-unknown-option.cmake @@ -0,0 +1 @@ +file(LOCK "${CMAKE_CURRENT_BINARY_DIR}/temp-file" UNKNOWN) diff --git a/Tests/RunCMake/file/LOCK-stdout.txt b/Tests/RunCMake/file/LOCK-stdout.txt new file mode 100644 index 0000000..416126a --- /dev/null +++ b/Tests/RunCMake/file/LOCK-stdout.txt @@ -0,0 +1,11 @@ +-- Simple lock +-- Directory lock +-- Release +-- Lock function scope +-- Lock file scope +-- Lock in subdirectory +-- Lock process scope +-- Error double lock +-- Ok +-- Timeout 0 +-- Timeout not 0 diff --git a/Tests/RunCMake/file/LOCK.cmake b/Tests/RunCMake/file/LOCK.cmake new file mode 100644 index 0000000..8eff084 --- /dev/null +++ b/Tests/RunCMake/file/LOCK.cmake @@ -0,0 +1,40 @@ +set(lfile "${CMAKE_CURRENT_BINARY_DIR}/file-to-lock") +set(ldir "${CMAKE_CURRENT_BINARY_DIR}/dir-to-lock") + +message(STATUS "Simple lock") +file(LOCK ${lfile}) + +message(STATUS "Directory lock") +file(LOCK ${ldir} DIRECTORY) + +message(STATUS "Release") +file(LOCK ${lfile} RELEASE) + +function(foo) + file(LOCK "${lfile}" GUARD FUNCTION) +endfunction() + +message(STATUS "Lock function scope") +foo() + +message(STATUS "Lock file scope") +add_subdirectory(subdir_test_unlock) + +message(STATUS "Lock process scope") +file(LOCK "${lfile}" GUARD PROCESS) + +message(STATUS "Error double lock") +file(LOCK "${lfile}" RESULT_VARIABLE lock_result) +if(lock_result STREQUAL "File already locked") + message(STATUS "Ok") +else() + message(STATUS FATAL_ERROR "Expected error message") +endif() + +message(STATUS "Timeout 0") +file(LOCK "${lfile}" RELEASE) +file(LOCK "${lfile}" TIMEOUT 0) + +message(STATUS "Timeout not 0") +file(LOCK "${lfile}" RELEASE) +file(LOCK "${lfile}" TIMEOUT 3) diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index bf14263..14819e7 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -3,3 +3,17 @@ include(RunCMake) run_cmake(INSTALL-DIRECTORY) run_cmake(INSTALL-MESSAGE-bad) run_cmake(FileOpenFailRead) +run_cmake(LOCK) +run_cmake(LOCK-error-file-create-fail) +run_cmake(LOCK-error-guard-incorrect) +run_cmake(LOCK-error-incorrect-timeout) +run_cmake(LOCK-error-incorrect-timeout-trail) +run_cmake(LOCK-error-lock-fail) +run_cmake(LOCK-error-negative-timeout) +run_cmake(LOCK-error-no-function) +run_cmake(LOCK-error-no-guard) +run_cmake(LOCK-error-no-path) +run_cmake(LOCK-error-no-result-variable) +run_cmake(LOCK-error-no-timeout) +run_cmake(LOCK-error-timeout) +run_cmake(LOCK-error-unknown-option) diff --git a/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt b/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt new file mode 100644 index 0000000..c167cd7 --- /dev/null +++ b/Tests/RunCMake/file/subdir_test_unlock/CMakeLists.txt @@ -0,0 +1,2 @@ +message(STATUS "Lock in subdirectory") +file(LOCK "${lfile}" GUARD FILE) diff --git a/Tests/RunCMake/file/timeout-script.cmake b/Tests/RunCMake/file/timeout-script.cmake new file mode 100644 index 0000000..e07dbf0 --- /dev/null +++ b/Tests/RunCMake/file/timeout-script.cmake @@ -0,0 +1,5 @@ +if(NOT file_to_lock) + message(FATAL_ERROR "file_to_lock is empty") +endif() + +file(LOCK "${file_to_lock}" TIMEOUT 1) diff --git a/Tests/RunCMake/find_library/CMakeLists.txt b/Tests/RunCMake/find_library/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/find_library/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/find_library/Created-stderr.txt b/Tests/RunCMake/find_library/Created-stderr.txt new file mode 100644 index 0000000..67b3474 --- /dev/null +++ b/Tests/RunCMake/find_library/Created-stderr.txt @@ -0,0 +1,2 @@ +CREATED_LIBRARY='CREATED_LIBRARY-NOTFOUND' +CREATED_LIBRARY='[^']*/Tests/RunCMake/find_library/Created-build/lib/libcreated.a' diff --git a/Tests/RunCMake/find_library/Created.cmake b/Tests/RunCMake/find_library/Created.cmake new file mode 100644 index 0000000..c0fd823 --- /dev/null +++ b/Tests/RunCMake/find_library/Created.cmake @@ -0,0 +1,16 @@ +list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib) +list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a) +find_library(CREATED_LIBRARY + NAMES created + PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib + NO_DEFAULT_PATH + ) +message("CREATED_LIBRARY='${CREATED_LIBRARY}'") +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libcreated.a" "created") +find_library(CREATED_LIBRARY + NAMES created + PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib + NO_DEFAULT_PATH + ) +message("CREATED_LIBRARY='${CREATED_LIBRARY}'") diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake new file mode 100644 index 0000000..4000679 --- /dev/null +++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(Created) diff --git a/Tests/RunCMake/get_property/CMakeLists.txt b/Tests/RunCMake/get_property/CMakeLists.txt new file mode 100644 index 0000000..12cd3c7 --- /dev/null +++ b/Tests/RunCMake/get_property/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.4) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/get_property/RunCMakeTest.cmake b/Tests/RunCMake/get_property/RunCMakeTest.cmake new file mode 100644 index 0000000..1964824 --- /dev/null +++ b/Tests/RunCMake/get_property/RunCMakeTest.cmake @@ -0,0 +1,9 @@ +include(RunCMake) + +run_cmake(cache_properties) +run_cmake(directory_properties) +run_cmake(global_properties) +run_cmake(install_properties) +run_cmake(source_properties) +run_cmake(target_properties) +run_cmake(test_properties) diff --git a/Tests/RunCMake/get_property/cache_properties-stderr.txt b/Tests/RunCMake/get_property/cache_properties-stderr.txt new file mode 100644 index 0000000..ee019c6 --- /dev/null +++ b/Tests/RunCMake/get_property/cache_properties-stderr.txt @@ -0,0 +1,3 @@ +^get_property: --><-- +get_property: -->TRUE<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/cache_properties.cmake b/Tests/RunCMake/get_property/cache_properties.cmake new file mode 100644 index 0000000..bf3e7ab --- /dev/null +++ b/Tests/RunCMake/get_property/cache_properties.cmake @@ -0,0 +1,15 @@ +function (check_cache_property var prop) + get_property(gp_val + CACHE "${var}" + PROPERTY "${prop}") + + message("get_property: -->${gp_val}<--") +endfunction () + +set(var val CACHE STRING "doc") +set_property(CACHE var PROPERTY VALUE "") # empty +set_property(CACHE var PROPERTY ADVANCED TRUE) + +check_cache_property(var VALUE) +check_cache_property(var ADVANCED) +check_cache_property(var noexist) diff --git a/Tests/RunCMake/get_property/directory_properties-stderr.txt b/Tests/RunCMake/get_property/directory_properties-stderr.txt new file mode 100644 index 0000000..80c9877 --- /dev/null +++ b/Tests/RunCMake/get_property/directory_properties-stderr.txt @@ -0,0 +1,6 @@ +^get_directory_property: --><-- +get_property: --><-- +get_directory_property: -->value<-- +get_property: -->value<-- +get_directory_property: --><-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/directory_properties.cmake b/Tests/RunCMake/get_property/directory_properties.cmake new file mode 100644 index 0000000..b0a9b1b --- /dev/null +++ b/Tests/RunCMake/get_property/directory_properties.cmake @@ -0,0 +1,15 @@ +function (check_directory_property dir prop) + get_directory_property(gdp_val DIRECTORY "${dir}" "${prop}") + get_property(gp_val + DIRECTORY "${dir}" + PROPERTY "${prop}") + + message("get_directory_property: -->${gdp_val}<--") + message("get_property: -->${gp_val}<--") +endfunction () + +set_directory_properties(PROPERTIES empty "" custom value) + +check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" empty) +check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" custom) +check_directory_property("${CMAKE_CURRENT_SOURCE_DIR}" noexist) diff --git a/Tests/RunCMake/get_property/global_properties-stderr.txt b/Tests/RunCMake/get_property/global_properties-stderr.txt new file mode 100644 index 0000000..4c08ad7 --- /dev/null +++ b/Tests/RunCMake/get_property/global_properties-stderr.txt @@ -0,0 +1,6 @@ +^get_cmake_property: --><-- +get_property: --><-- +get_cmake_property: -->value<-- +get_property: -->value<-- +get_cmake_property: -->NOTFOUND<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/global_properties.cmake b/Tests/RunCMake/get_property/global_properties.cmake new file mode 100644 index 0000000..2073136 --- /dev/null +++ b/Tests/RunCMake/get_property/global_properties.cmake @@ -0,0 +1,16 @@ +function (check_global_property prop) + get_cmake_property(gcp_val "${prop}") + get_property(gp_val + GLOBAL + PROPERTY "${prop}") + + message("get_cmake_property: -->${gcp_val}<--") + message("get_property: -->${gp_val}<--") +endfunction () + +set_property(GLOBAL PROPERTY empty "") +set_property(GLOBAL PROPERTY custom value) + +check_global_property(empty) +check_global_property(custom) +check_global_property(noexist) diff --git a/Tests/RunCMake/get_property/install_properties-stderr.txt b/Tests/RunCMake/get_property/install_properties-stderr.txt new file mode 100644 index 0000000..b1a2987 --- /dev/null +++ b/Tests/RunCMake/get_property/install_properties-stderr.txt @@ -0,0 +1,3 @@ +^get_property: --><-- +get_property: -->value<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/install_properties.cmake b/Tests/RunCMake/get_property/install_properties.cmake new file mode 100644 index 0000000..aa89225 --- /dev/null +++ b/Tests/RunCMake/get_property/install_properties.cmake @@ -0,0 +1,18 @@ +function (check_install_property file prop) + get_property(gp_val + INSTALL "${file}" + PROPERTY "${prop}") + + message("get_property: -->${gp_val}<--") +endfunction () + +install( + FILES "${CMAKE_CURRENT_LIST_FILE}" + DESTINATION "${CMAKE_CURRENT_LIST_DIR}" + RENAME "installed-file-dest") +set_property(INSTALL "${CMAKE_CURRENT_LIST_FILE}" PROPERTY empty "") +set_property(INSTALL "${CMAKE_CURRENT_LIST_FILE}" PROPERTY custom value) + +check_install_property("${CMAKE_CURRENT_LIST_FILE}" empty) +check_install_property("${CMAKE_CURRENT_LIST_FILE}" custom) +check_install_property("${CMAKE_CURRENT_LIST_FILE}" noexist) diff --git a/Tests/RunCMake/get_property/source_properties-stderr.txt b/Tests/RunCMake/get_property/source_properties-stderr.txt new file mode 100644 index 0000000..0a46f96 --- /dev/null +++ b/Tests/RunCMake/get_property/source_properties-stderr.txt @@ -0,0 +1,6 @@ +^get_source_file_property: --><-- +get_property: --><-- +get_source_file_property: -->value<-- +get_property: -->value<-- +get_source_file_property: -->NOTFOUND<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/source_properties.cmake b/Tests/RunCMake/get_property/source_properties.cmake new file mode 100644 index 0000000..263ffe1 --- /dev/null +++ b/Tests/RunCMake/get_property/source_properties.cmake @@ -0,0 +1,15 @@ +function (check_source_file_property file prop) + get_source_file_property(gsfp_val "${file}" "${prop}") + get_property(gp_val + SOURCE "${file}" + PROPERTY "${prop}") + + message("get_source_file_property: -->${gsfp_val}<--") + message("get_property: -->${gp_val}<--") +endfunction () + +set_source_files_properties(file.c PROPERTIES empty "" custom value) + +check_source_file_property(file.c empty) +check_source_file_property(file.c custom) +check_source_file_property(file.c noexist) diff --git a/Tests/RunCMake/get_property/target_properties-stderr.txt b/Tests/RunCMake/get_property/target_properties-stderr.txt new file mode 100644 index 0000000..d0981ac --- /dev/null +++ b/Tests/RunCMake/get_property/target_properties-stderr.txt @@ -0,0 +1,6 @@ +^get_target_property: --><-- +get_property: --><-- +get_target_property: -->value<-- +get_property: -->value<-- +get_target_property: -->gtp_val-NOTFOUND<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/target_properties.cmake b/Tests/RunCMake/get_property/target_properties.cmake new file mode 100644 index 0000000..c5a141d --- /dev/null +++ b/Tests/RunCMake/get_property/target_properties.cmake @@ -0,0 +1,16 @@ +function (check_target_property target prop) + get_target_property(gtp_val "${target}" "${prop}") + get_property(gp_val + TARGET "${target}" + PROPERTY "${prop}") + + message("get_target_property: -->${gtp_val}<--") + message("get_property: -->${gp_val}<--") +endfunction () + +add_custom_target(tgt) +set_target_properties(tgt PROPERTIES empty "" custom value) + +check_target_property(tgt empty) +check_target_property(tgt custom) +check_target_property(tgt noexist) diff --git a/Tests/RunCMake/get_property/test_properties-stderr.txt b/Tests/RunCMake/get_property/test_properties-stderr.txt new file mode 100644 index 0000000..a447280 --- /dev/null +++ b/Tests/RunCMake/get_property/test_properties-stderr.txt @@ -0,0 +1,6 @@ +^get_test_property: --><-- +get_property: --><-- +get_test_property: -->value<-- +get_property: -->value<-- +get_test_property: -->NOTFOUND<-- +get_property: --><--$ diff --git a/Tests/RunCMake/get_property/test_properties.cmake b/Tests/RunCMake/get_property/test_properties.cmake new file mode 100644 index 0000000..1d0295c --- /dev/null +++ b/Tests/RunCMake/get_property/test_properties.cmake @@ -0,0 +1,17 @@ +function (check_test_property test prop) + get_test_property("${test}" "${prop}" gtp_val) + get_property(gp_val + TEST "${test}" + PROPERTY "${prop}") + + message("get_test_property: -->${gtp_val}<--") + message("get_property: -->${gp_val}<--") +endfunction () + +include(CTest) +add_test(NAME test COMMAND "${CMAKE_COMMAND}" --help) +set_tests_properties(test PROPERTIES empty "" custom value) + +check_test_property(test empty) +check_test_property(test custom) +check_test_property(test noexist) diff --git a/Tests/RunCMake/return/CMakeLists.txt b/Tests/RunCMake/return/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/return/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/return/ReturnFromForeach-result.txt b/Tests/RunCMake/return/ReturnFromForeach-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/return/ReturnFromForeach-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/return/ReturnFromForeach.cmake b/Tests/RunCMake/return/ReturnFromForeach.cmake new file mode 100644 index 0000000..c71cf33 --- /dev/null +++ b/Tests/RunCMake/return/ReturnFromForeach.cmake @@ -0,0 +1,10 @@ +function(foo) + foreach(i RANGE 1 3) + foreach(j RANGE 1 3) + return() + message(FATAL_ERROR "unexpected") + endforeach() + endforeach() +endfunction(foo) + +foo() diff --git a/Tests/RunCMake/return/RunCMakeTest.cmake b/Tests/RunCMake/return/RunCMakeTest.cmake new file mode 100644 index 0000000..2cc6c9d --- /dev/null +++ b/Tests/RunCMake/return/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(ReturnFromForeach) diff --git a/Tests/RunCMake/string/RegexClear-stderr.txt b/Tests/RunCMake/string/RegexClear-stderr.txt new file mode 100644 index 0000000..22b0159 --- /dev/null +++ b/Tests/RunCMake/string/RegexClear-stderr.txt @@ -0,0 +1,54 @@ +^Matched string properly +results from: setting up initial state +CMAKE_MATCH_0: -->01<-- +CMAKE_MATCH_1: -->0<-- +CMAKE_MATCH_2: -->1<-- +CMAKE_MATCH_COUNT: -->2<-- +Matched string properly +results from: making a match inside of find_package +CMAKE_MATCH_0: -->01<-- +CMAKE_MATCH_1: -->0<-- +CMAKE_MATCH_2: -->1<-- +CMAKE_MATCH_COUNT: -->2<-- +Matched nothing properly +results from: making a failure inside of find_package +CMAKE_MATCH_0: --><-- +CMAKE_MATCH_1: --><-- +CMAKE_MATCH_2: --><-- +CMAKE_MATCH_COUNT: -->0<-- +Matched nothing properly +results from: checking after find_package +CMAKE_MATCH_0: --><-- +CMAKE_MATCH_1: --><-- +CMAKE_MATCH_2: --><-- +CMAKE_MATCH_COUNT: -->0<-- +Matched nothing properly +results from: clearing out results with a failing match +CMAKE_MATCH_0: --><-- +CMAKE_MATCH_1: --><-- +CMAKE_MATCH_2: --><-- +CMAKE_MATCH_COUNT: -->0<-- +Matched string properly +results from: making a successful match before add_subdirectory +CMAKE_MATCH_0: -->01<-- +CMAKE_MATCH_1: -->0<-- +CMAKE_MATCH_2: -->1<-- +CMAKE_MATCH_COUNT: -->2<-- +Matched string properly +results from: check for success in add_subdirectory +CMAKE_MATCH_0: -->01<-- +CMAKE_MATCH_1: -->0<-- +CMAKE_MATCH_2: -->1<-- +CMAKE_MATCH_COUNT: -->2<-- +Matched nothing properly +results from: failing inside of add_subdirectory +CMAKE_MATCH_0: --><-- +CMAKE_MATCH_1: --><-- +CMAKE_MATCH_2: --><-- +CMAKE_MATCH_COUNT: -->0<-- +Matched string properly +results from: ensuring the subdirectory did not interfere with the parent +CMAKE_MATCH_0: -->01<-- +CMAKE_MATCH_1: -->0<-- +CMAKE_MATCH_2: -->1<-- +CMAKE_MATCH_COUNT: -->2<--$ diff --git a/Tests/RunCMake/string/RegexClear.cmake b/Tests/RunCMake/string/RegexClear.cmake new file mode 100644 index 0000000..d5edaac --- /dev/null +++ b/Tests/RunCMake/string/RegexClear.cmake @@ -0,0 +1,54 @@ +cmake_minimum_required (VERSION 3.0) +project (RegexClear C) + +function (output_results msg) + message("results from: ${msg}") + message("CMAKE_MATCH_0: -->${CMAKE_MATCH_0}<--") + message("CMAKE_MATCH_1: -->${CMAKE_MATCH_1}<--") + message("CMAKE_MATCH_2: -->${CMAKE_MATCH_2}<--") + message("CMAKE_MATCH_COUNT: -->${CMAKE_MATCH_COUNT}<--") +endfunction () + +function (check_for_success msg) + if (CMAKE_MATCH_1 STREQUAL "0" AND + CMAKE_MATCH_2 STREQUAL "1") + message("Matched string properly") + else () + message("Failed to match properly") + endif () + output_results("${msg}") +endfunction () + +function (check_for_failure msg) + if (CMAKE_MATCH_1 STREQUAL "" AND + CMAKE_MATCH_2 STREQUAL "") + message("Matched nothing properly") + else () + message("Found a match where there should be none") + endif () + output_results("${msg}") +endfunction () + +macro (do_regex_success msg) + string(REGEX MATCH "(0)(1)" output "01") + check_for_success("${msg}") +endmacro () + +macro (do_regex_failure msg) + string(REGEX MATCH "(0)(1)" output "12") + check_for_failure("${msg}") +endmacro () + +do_regex_success("setting up initial state") + +list(INSERT CMAKE_MODULE_PATH 0 + "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +find_package(dummy) # Ensure cmMakefile::PushScope/PopScope work. + +check_for_failure("checking after find_package") +do_regex_failure("clearing out results with a failing match") +do_regex_success("making a successful match before add_subdirectory") + +add_subdirectory(subdir) + +check_for_success("ensuring the subdirectory did not interfere with the parent") # Ensure that the subdir didn't mess with this scope. diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake index e83db27..fc913c6 100644 --- a/Tests/RunCMake/string/RunCMakeTest.cmake +++ b/Tests/RunCMake/string/RunCMakeTest.cmake @@ -10,3 +10,5 @@ run_cmake(UuidBadNamespace) run_cmake(UuidMissingNameValue) run_cmake(UuidMissingTypeValue) run_cmake(UuidBadType) + +run_cmake(RegexClear) diff --git a/Tests/RunCMake/string/cmake/Finddummy.cmake b/Tests/RunCMake/string/cmake/Finddummy.cmake new file mode 100644 index 0000000..4cbc1fb --- /dev/null +++ b/Tests/RunCMake/string/cmake/Finddummy.cmake @@ -0,0 +1,4 @@ +check_for_success("making a match inside of find_package") +do_regex_failure("making a failure inside of find_package") + +set(dummy_FOUND 1) diff --git a/Tests/RunCMake/string/subdir/CMakeLists.txt b/Tests/RunCMake/string/subdir/CMakeLists.txt new file mode 100644 index 0000000..5573308 --- /dev/null +++ b/Tests/RunCMake/string/subdir/CMakeLists.txt @@ -0,0 +1,2 @@ +check_for_success("check for success in add_subdirectory") +do_regex_failure("failing inside of add_subdirectory") diff --git a/Tests/RunCMake/try_compile/CMP0056-stderr.txt b/Tests/RunCMake/try_compile/CMP0056-stderr.txt new file mode 100644 index 0000000..5c1f0e4 --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056-stderr.txt @@ -0,0 +1,13 @@ +before try_compile with CMP0056 WARN-default +after try_compile with CMP0056 WARN-default +* +CMake Warning \(dev\) at CMP0056.cmake:[0-9]+ \(try_compile\): + Policy CMP0056 is not set: Honor link flags in try_compile\(\) source-file + signature. Run "cmake --help-policy CMP0056" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + For compatibility with older versions of CMake, try_compile is not honoring + caller link flags \(e.g. CMAKE_EXE_LINKER_FLAGS\) in the test project. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/try_compile/CMP0056-stdout.txt b/Tests/RunCMake/try_compile/CMP0056-stdout.txt new file mode 100644 index 0000000..89e7c43 --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056-stdout.txt @@ -0,0 +1,4 @@ +-- try_compile with CMP0056 WARN-default worked as expected +-- try_compile with CMP0056 WARN-enabled worked as expected +-- try_compile with CMP0056 OLD worked as expected +-- try_compile with CMP0056 NEW worked as expected diff --git a/Tests/RunCMake/try_compile/CMP0056.cmake b/Tests/RunCMake/try_compile/CMP0056.cmake new file mode 100644 index 0000000..e8d3d4a --- /dev/null +++ b/Tests/RunCMake/try_compile/CMP0056.cmake @@ -0,0 +1,67 @@ +enable_language(C) +set(obj "${CMAKE_C_OUTPUT_EXTENSION}") +if(BORLAND) + set(pre -) +endif() +set(CMAKE_EXE_LINKER_FLAGS ${pre}BADFLAG${obj}) + +#----------------------------------------------------------------------------- +message("before try_compile with CMP0056 WARN-default") +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 WARN-default worked as expected") +endif() +message("after try_compile with CMP0056 WARN-default") + +#----------------------------------------------------------------------------- +set(CMAKE_POLICY_WARNING_CMP0056 ON) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 WARN-enabled worked as expected") +endif() + +#----------------------------------------------------------------------------- +cmake_policy(SET CMP0056 OLD) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(NOT RESULT) + message(FATAL_ERROR "try_compile failed but should have passed:\n${out}") +elseif("x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile output mentions BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 OLD worked as expected") +endif() + +#----------------------------------------------------------------------------- +cmake_policy(SET CMP0056 NEW) +try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/src.c + OUTPUT_VARIABLE out + ) +string(REPLACE "\n" "\n " out " ${out}") +if(RESULT) + message(FATAL_ERROR "try_compile passed but should have failed:\n${out}") +elseif(NOT "x${out}" MATCHES "BADFLAG") + message(FATAL_ERROR "try_compile did not fail with BADFLAG:\n${out}") +else() + message(STATUS "try_compile with CMP0056 NEW worked as expected") +endif() diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake index c934458..06096b2 100644 --- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake @@ -15,3 +15,5 @@ run_cmake(BadSources1) run_cmake(BadSources2) run_cmake(NonSourceCopyFile) run_cmake(NonSourceCompileDefinitions) + +run_cmake(CMP0056) diff --git a/Tests/SourceFileProperty/CMakeLists.txt b/Tests/SourceFileProperty/CMakeLists.txt new file mode 100644 index 0000000..1b6506d --- /dev/null +++ b/Tests/SourceFileProperty/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.0) +project(SourceFileProperty C) + +set(sources) + +if (EXISTS icasetest.c) + # If a file exists by this name, use it. + set_source_files_properties(icasetest.c + PROPERTIES + COMPILE_FLAGS -DNEEDED_TO_WORK) +else () + # Work on case-sensitive file systems as well. + set_source_files_properties(main.c + PROPERTIES + COMPILE_FLAGS -DNO_NEED_TO_CALL) +endif () +list(APPEND sources ICaseTest.c) + +add_executable(SourceFileProperty main.c ${sources}) diff --git a/Tests/SourceFileProperty/ICaseTest.c b/Tests/SourceFileProperty/ICaseTest.c new file mode 100644 index 0000000..454c721 --- /dev/null +++ b/Tests/SourceFileProperty/ICaseTest.c @@ -0,0 +1,7 @@ + +#ifdef NEEDED_TO_WORK +int icasetest() +{ + return 0; +} +#endif diff --git a/Tests/SourceFileProperty/main.c b/Tests/SourceFileProperty/main.c new file mode 100644 index 0000000..b853408 --- /dev/null +++ b/Tests/SourceFileProperty/main.c @@ -0,0 +1,13 @@ + +#ifndef NO_NEED_TO_CALL +extern int icasetest(); +#endif + +int main(int argc, char** argv) +{ +#ifdef NO_NEED_TO_CALL + return 0; +#else + return icasetest(); +#endif +} diff --git a/Tests/SourcesProperty/CMakeLists.txt b/Tests/SourcesProperty/CMakeLists.txt index 6c99e00..d1c35d8 100644 --- a/Tests/SourcesProperty/CMakeLists.txt +++ b/Tests/SourcesProperty/CMakeLists.txt @@ -4,7 +4,9 @@ cmake_minimum_required(VERSION 3.0) project(SourcesProperty) add_library(iface INTERFACE) -set_property(TARGET iface PROPERTY INTERFACE_SOURCES iface.cpp) +set_property(TARGET iface PROPERTY INTERFACE_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/iface.cpp" +) add_executable(SourcesProperty main.cpp) target_link_libraries(SourcesProperty iface) diff --git a/Tests/Tutorial/Step2/tutorial.cxx b/Tests/Tutorial/Step2/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step2/tutorial.cxx +++ b/Tests/Tutorial/Step2/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/Tutorial/Step3/tutorial.cxx b/Tests/Tutorial/Step3/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step3/tutorial.cxx +++ b/Tests/Tutorial/Step3/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/Tutorial/Step4/tutorial.cxx b/Tests/Tutorial/Step4/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step4/tutorial.cxx +++ b/Tests/Tutorial/Step4/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/Tutorial/Step5/tutorial.cxx b/Tests/Tutorial/Step5/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step5/tutorial.cxx +++ b/Tests/Tutorial/Step5/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/Tutorial/Step6/tutorial.cxx b/Tests/Tutorial/Step6/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step6/tutorial.cxx +++ b/Tests/Tutorial/Step6/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/Tutorial/Step7/tutorial.cxx b/Tests/Tutorial/Step7/tutorial.cxx index 82b416f..c27da0b 100644 --- a/Tests/Tutorial/Step7/tutorial.cxx +++ b/Tests/Tutorial/Step7/tutorial.cxx @@ -21,12 +21,16 @@ int main (int argc, char *argv[]) } double inputValue = atof(argv[1]); + double outputValue = 0; + if(inputValue >= 0) + { #ifdef USE_MYMATH - double outputValue = mysqrt(inputValue); + outputValue = mysqrt(inputValue); #else - double outputValue = sqrt(inputValue); + outputValue = sqrt(inputValue); #endif + } fprintf(stdout,"The square root of %g is %g\n", inputValue, outputValue); diff --git a/Tests/VSNsightTegra/CMakeLists.txt b/Tests/VSNsightTegra/CMakeLists.txt index 570733b..10f55d9 100644 --- a/Tests/VSNsightTegra/CMakeLists.txt +++ b/Tests/VSNsightTegra/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.0) project(VSNsightTegra C CXX) +set(CMAKE_ANDROID_API_MIN 9) set(CMAKE_ANDROID_API 15) set(CMAKE_ANDROID_GUI 1) diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt index 0041c75..7227fcc 100644 --- a/Tests/VSWinStorePhone/CMakeLists.txt +++ b/Tests/VSWinStorePhone/CMakeLists.txt @@ -86,6 +86,9 @@ if (WINDOWS_PHONE8) elseif (NOT "${PLATFORM}" STREQUAL "DESKTOP") set(CONTENT_FILES ${CONTENT_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${APP_MANIFEST_NAME} + ) + + set(ASSET_FILES ${ASSET_FILES} Direct3DApp1/Assets/Logo.png Direct3DApp1/Assets/SmallLogo.png Direct3DApp1/Assets/SplashScreen.png @@ -94,16 +97,24 @@ elseif (NOT "${PLATFORM}" STREQUAL "DESKTOP") endif() set(RESOURCE_FILES - ${CONTENT_FILES} ${DEBUG_CONTENT_FILES} ${RELEASE_CONTENT_FILES} + ${CONTENT_FILES} ${DEBUG_CONTENT_FILES} ${RELEASE_CONTENT_FILES} ${ASSET_FILES} Direct3DApp1/Direct3DApp1_TemporaryKey.pfx) set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1) +set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1) +set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets") set_property(SOURCE ${DEBUG_CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT $<CONFIG:Debug>) set_property(SOURCE ${RELEASE_CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>) set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_TYPE Pixel) +set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainPS) +set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3) + set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_TYPE Vertex) +set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainVS) +set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3) + source_group("Source Files" FILES ${SOURCE_FILES}) source_group("Header Files" FILES ${HEADER_FILES}) diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl index d61e2c8..6796da1 100644 --- a/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl +++ b/Tests/VSWinStorePhone/Direct3DApp1/SimplePixelShader.hlsl @@ -4,7 +4,7 @@ struct PixelShaderInput float3 color : COLOR0; }; -float4 main(PixelShaderInput input) : SV_TARGET +float4 mainPS(PixelShaderInput input) : SV_TARGET { return float4(input.color,1.0f); } diff --git a/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl index 65d60e5..0963060 100644 --- a/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl +++ b/Tests/VSWinStorePhone/Direct3DApp1/SimpleVertexShader.hlsl @@ -17,7 +17,7 @@ struct VertexShaderOutput float3 color : COLOR0; }; -VertexShaderOutput main(VertexShaderInput input) +VertexShaderOutput mainVS(VertexShaderInput input) { VertexShaderOutput output; float4 pos = float4(input.pos, 1.0f); diff --git a/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in index d3cb21f..68172fa 100644 --- a/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in +++ b/Tests/VSWinStorePhone/cmake/Package_vc11.store.appxmanifest.in @@ -4,7 +4,7 @@ <Properties> <DisplayName>@SHORT_NAME@</DisplayName> <PublisherDisplayName>mgong</PublisherDisplayName> - <Logo>StoreLogo.png</Logo> + <Logo>Assets/StoreLogo.png</Logo> </Properties> <Prerequisites> <OSMinVersion>6.2.1</OSMinVersion> @@ -15,9 +15,9 @@ </Resources> <Applications> <Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="@SHORT_NAME@.App"> - <VisualElements DisplayName="@SHORT_NAME@" Description="@SHORT_NAME@" BackgroundColor="#336699" ForegroundText="light" Logo="Logo.png" SmallLogo="SmallLogo.png"> + <VisualElements DisplayName="@SHORT_NAME@" Description="@SHORT_NAME@" BackgroundColor="#336699" ForegroundText="light" Logo="Assets/Logo.png" SmallLogo="Assets/SmallLogo.png"> <DefaultTile ShowName="allLogos" ShortName="@SHORT_NAME@" /> - <SplashScreen Image="SplashScreen.png" /> + <SplashScreen Image="Assets/SplashScreen.png" /> </VisualElements> </Application> </Applications> diff --git a/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in index 495f18e..08205f5 100644 --- a/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in +++ b/Tests/VSWinStorePhone/cmake/Package_vc12.store.appxmanifest.in @@ -4,7 +4,7 @@ <Properties> <DisplayName>@SHORT_NAME@</DisplayName> <PublisherDisplayName>mgong</PublisherDisplayName> - <Logo>StoreLogo.png</Logo> + <Logo>Assets/StoreLogo.png</Logo> </Properties> <Prerequisites> <OSMinVersion>6.3</OSMinVersion> @@ -20,14 +20,14 @@ Description="@SHORT_NAME@" BackgroundColor="#336699" ForegroundText="light" - Square150x150Logo="Logo.png" - Square30x30Logo="SmallLogo.png"> + Square150x150Logo="Assets/Logo.png" + Square30x30Logo="Assets/SmallLogo.png"> <m2:DefaultTile ShortName="@SHORT_NAME@"> <m2:ShowNameOnTiles> <m2:ShowOn Tile="square150x150Logo" /> </m2:ShowNameOnTiles> </m2:DefaultTile> - <m2:SplashScreen Image="SplashScreen.png" /> + <m2:SplashScreen Image="Assets/SplashScreen.png" /> </m2:VisualElements> </Application> </Applications> diff --git a/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in b/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in index 2d4d389..d47d43c 100644 --- a/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in +++ b/Tests/VSWinStorePhone/cmake/Package_vc12.wp.appxmanifest.in @@ -6,7 +6,7 @@ <Properties> <DisplayName>@SHORT_NAME@</DisplayName> <PublisherDisplayName>mgong</PublisherDisplayName> - <Logo>StoreLogo.png</Logo> + <Logo>Assets/StoreLogo.png</Logo> </Properties> <Prerequisites> <OSMinVersion>6.3.1</OSMinVersion> @@ -22,14 +22,14 @@ Description="@SHORT_NAME@" BackgroundColor="#336699" ForegroundText="light" - Square150x150Logo="Logo.png" - Square30x30Logo="SmallLogo.png"> + Square150x150Logo="Assets/Logo.png" + Square30x30Logo="Assets/SmallLogo.png"> <m2:DefaultTile ShortName="@SHORT_NAME@"> <m2:ShowNameOnTiles> <m2:ShowOn Tile="square150x150Logo" /> </m2:ShowNameOnTiles> </m2:DefaultTile> - <m2:SplashScreen Image="SplashScreen.png" /> + <m2:SplashScreen Image="Assets/SplashScreen.png" /> </m2:VisualElements> </Application> </Applications> diff --git a/Utilities/Release/create-cmake-release.cmake b/Utilities/Release/create-cmake-release.cmake index a3f7032..19f4cb1 100644 --- a/Utilities/Release/create-cmake-release.cmake +++ b/Utilities/Release/create-cmake-release.cmake @@ -10,6 +10,7 @@ set(RELEASE_SCRIPTS_BATCH_1 dashmacmini2_release.cmake # Mac Darwin universal ppc;i386 dashmacmini5_release.cmake # Mac Darwin64 universal x86_64;i386 magrathea_release.cmake # Linux + linux64_release.cmake # Linux x86_64 ibm_aix_release.cmake # AIX ) diff --git a/Utilities/Release/dash2win64_release.cmake b/Utilities/Release/dash2win64_release.cmake index 848e2f4..345870b 100644 --- a/Utilities/Release/dash2win64_release.cmake +++ b/Utilities/Release/dash2win64_release.cmake @@ -7,8 +7,13 @@ set(CPACK_BINARY_GENERATORS "NSIS ZIP") set(CPACK_SOURCE_GENERATORS "ZIP") set(MAKE_PROGRAM "make") set(MAKE "${MAKE_PROGRAM} -j8") +if(CMAKE_CREATE_VERSION STREQUAL "nightly") + set(CMAKE_USE_OPENSSL OFF) +else() + set(CMAKE_USE_OPENSSL ON) +endif() set(INITIAL_CACHE "CMAKE_BUILD_TYPE:STRING=Release -CMAKE_USE_OPENSSL:BOOL=ON +CMAKE_USE_OPENSSL:BOOL=${CMAKE_USE_OPENSSL} CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE CMAKE_Fortran_COMPILER:FILEPATH=FALSE CMAKE_GENERATOR:INTERNAL=Unix Makefiles diff --git a/Utilities/Release/dashmacmini5_release.cmake b/Utilities/Release/dashmacmini5_release.cmake index 6c9b8f4..910fcbd 100644 --- a/Utilities/Release/dashmacmini5_release.cmake +++ b/Utilities/Release/dashmacmini5_release.cmake @@ -8,16 +8,21 @@ set(MAKE "${MAKE_PROGRAM} -j5") set(CPACK_BINARY_GENERATORS "DragNDrop TGZ TZ") set(CPACK_SOURCE_GENERATORS "TGZ TZ") set(CPACK_DMG_FORMAT "UDBZ") #build using bzip2 for smaller package size +if(CMAKE_CREATE_VERSION STREQUAL "nightly") + set(CMAKE_USE_OPENSSL OFF) +else() + set(CMAKE_USE_OPENSSL ON) +endif() set(INITIAL_CACHE " -CMAKE_USE_OPENSSL:BOOL=ON +CMAKE_USE_OPENSSL:BOOL=${CMAKE_USE_OPENSSL} OPENSSL_CRYPTO_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1g-install/lib/libcrypto.a OPENSSL_INCLUDE_DIR:PATH=/Users/kitware/openssl-1.0.1g-install/include OPENSSL_SSL_LIBRARY:FILEPATH=/Users/kitware/openssl-1.0.1g-install/lib/libssl.a CMAKE_BUILD_TYPE:STRING=Release CMAKE_OSX_ARCHITECTURES:STRING=x86_64 -CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.5 +CMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.6 CMAKE_SKIP_BOOTSTRAP_TEST:STRING=TRUE -CPACK_SYSTEM_NAME:STRING=Darwin64-universal +CPACK_SYSTEM_NAME:STRING=Darwin-x86_64 BUILD_QtDialog:BOOL=TRUE CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE QT_QMAKE_EXECUTABLE:FILEPATH=/Users/kitware/Support/qt-4.8.0/install/bin/qmake diff --git a/Utilities/Release/linux64_release.cmake b/Utilities/Release/linux64_release.cmake new file mode 100644 index 0000000..513f42f --- /dev/null +++ b/Utilities/Release/linux64_release.cmake @@ -0,0 +1,23 @@ +set(PROCESSORS 4) +set(HOST linux64) +set(MAKE_PROGRAM "make") +set(CC /opt/gcc-4.9.2/bin/gcc) +set(CXX /opt/gcc-4.9.2/bin/g++) +set(CFLAGS "") +set(CXXFLAGS "") +set(INITIAL_CACHE " +CMAKE_BUILD_TYPE:STRING=Release +CURSES_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libncurses.a +CURSES_INCLUDE_PATH:PATH=/home/kitware/ncurses-5.9/include +FORM_LIBRARY:FILEPATH=/home/kitware/ncurses-5.9/lib/libform.a +CMAKE_USE_OPENSSL:BOOL=ON +OPENSSL_CRYPTO_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1j/lib/libcrypto.a +OPENSSL_INCLUDE_DIR:PATH=/home/kitware/openssl-1.0.1j/include +OPENSSL_SSL_LIBRARY:FILEPATH=/home/kitware/openssl-1.0.1j/lib/libssl.a +CPACK_SYSTEM_NAME:STRING=Linux-x86_64 +BUILD_QtDialog:BOOL:=TRUE +CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL:BOOL=TRUE +QT_QMAKE_EXECUTABLE:FILEPATH=/home/kitware/qt-4.8.6/bin/qmake +") +get_filename_component(path "${CMAKE_CURRENT_LIST_FILE}" PATH) +include(${path}/release_cmake.cmake) diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index 2629bb3..5c0406d 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -130,8 +130,8 @@ class _cmake_index_entry: def __init__(self, desc): self.desc = desc - def __call__(self, title, targetid): - return ('pair', u'%s ; %s' % (self.desc, title), targetid, 'main') + def __call__(self, title, targetid, main = 'main'): + return ('pair', u'%s ; %s' % (self.desc, title), targetid, main) _cmake_index_objs = { 'command': _cmake_index_entry('command'), @@ -201,8 +201,13 @@ class CMakeTransform(Transform): if make_index_entry: title = self.parse_title(env.docname) # Insert the object link target. - targetid = '%s:%s' % (objtype, title) + if objtype == 'command': + targetname = title.lower() + else: + targetname = title + targetid = '%s:%s' % (objtype, targetname) targetnode = nodes.target('', '', ids=[targetid]) + self.document.note_explicit_target(targetnode) self.document.insert(0, targetnode) # Insert the object index entry. indexnode = addnodes.index() @@ -219,7 +224,11 @@ class CMakeObject(ObjectDescription): return sig def add_target_and_index(self, name, sig, signode): - targetid = '%s:%s' % (self.objtype, name) + if self.objtype == 'command': + targetname = name.lower() + else: + targetname = name + targetid = '%s:%s' % (self.objtype, targetname) if targetid not in self.state.document.ids: signode['names'].append(targetid) signode['ids'].append(targetid) @@ -257,6 +266,49 @@ class CMakeXRefRole(XRefRole): break return XRefRole.__call__(self, typ, rawtext, text, *args, **keys) + # We cannot insert index nodes using the result_nodes method + # because CMakeXRefRole is processed before substitution_reference + # nodes are evaluated so target nodes (with 'ids' fields) would be + # duplicated in each evaluted substitution replacement. The + # docutils substitution transform does not allow this. Instead we + # use our own CMakeXRefTransform below to add index entries after + # substitutions are completed. + # + # def result_nodes(self, document, env, node, is_ref): + # pass + +class CMakeXRefTransform(Transform): + + # Run this transform early since we insert nodes we want + # treated as if they were written in the documents, but + # after the sphinx (210) and docutils (220) substitutions. + default_priority = 221 + + def apply(self): + env = self.document.settings.env + + # Find CMake cross-reference nodes and add index and target + # nodes for them. + for ref in self.document.traverse(addnodes.pending_xref): + if not ref['refdomain'] == 'cmake': + continue + + objtype = ref['reftype'] + make_index_entry = _cmake_index_objs.get(objtype) + if not make_index_entry: + continue + + objname = ref['reftarget'] + targetnum = env.new_serialno('index-%s:%s' % (objtype, objname)) + + targetid = 'index-%s-%s:%s' % (targetnum, objtype, objname) + targetnode = nodes.target('', '', ids=[targetid]) + self.document.note_explicit_target(targetnode) + + indexnode = addnodes.index() + indexnode['entries'] = [make_index_entry(objname, targetid, '')] + ref.replace_self([indexnode, targetnode, ref]) + class CMakeDomain(Domain): """CMake domain.""" name = 'cmake' @@ -336,4 +388,5 @@ class CMakeDomain(Domain): def setup(app): app.add_directive('cmake-module', CMakeModule) app.add_transform(CMakeTransform) + app.add_transform(CMakeXRefTransform) app.add_domain(CMakeDomain) diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in index d81bbcf..eb24a6e 100644 --- a/Utilities/Sphinx/conf.py.in +++ b/Utilities/Sphinx/conf.py.in @@ -31,6 +31,8 @@ exclude_patterns = [] extensions = ['cmake'] templates_path = ['@conf_path@/templates'] +nitpicky = True + cmake_manuals = sorted(glob.glob(r'@conf_docs@/manual/*.rst')) cmake_manual_description = re.compile('^\.\. cmake-manual-description:(.*)$') man_pages = [] @@ -60,7 +62,7 @@ html_style = 'cmake.css' html_theme = 'default' html_title = 'CMake %s Documentation' % release html_short_title = '%s Documentation' % release -html_favicon = 'cmake-favicon.ico' +html_favicon = '@conf_path@/static/cmake-favicon.ico' # Not supported yet by sphinx: # https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable # qthelp_namespace = "org.cmake" diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py index 7715e53..3fe3fcb 100755 --- a/Utilities/Sphinx/create_identifiers.py +++ b/Utilities/Sphinx/create_identifiers.py @@ -34,7 +34,7 @@ for line in lines: for domain_object_string, domain_object_type in mapping: if "<keyword name=\"" + domain_object_string + "\"" in line: - if not "id=\"" in line: + if not "id=\"" in line and not "#index-" in line: prefix = "<keyword name=\"" + domain_object_string + "\" " part1, part2 = line.split(prefix) head, tail = part2.split("#" + domain_object_type + ":") diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in index b0b5779..0cb6809 100644 --- a/Utilities/cmThirdParty.h.in +++ b/Utilities/cmThirdParty.h.in @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cmThirdParty_h -#define __cmThirdParty_h +#ifndef cmThirdParty_h +#define cmThirdParty_h /* Whether CMake is using its own utility libraries. */ #cmakedefine CMAKE_USE_SYSTEM_CURL @@ -19,6 +19,8 @@ #cmakedefine CMAKE_USE_SYSTEM_BZIP2 #cmakedefine CMAKE_USE_SYSTEM_LIBARCHIVE #cmakedefine CMAKE_USE_SYSTEM_LIBLZMA +#cmakedefine CMAKE_USE_SYSTEM_FORM +#cmakedefine CMAKE_USE_SYSTEM_JSONCPP #cmakedefine CTEST_USE_XMLRPC #endif diff --git a/Utilities/cm_bzlib.h b/Utilities/cm_bzlib.h index d1fffa1..5678025 100644 --- a/Utilities/cm_bzlib.h +++ b/Utilities/cm_bzlib.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_bzlib_h -#define __cm_bzlib_h +#ifndef cm_bzlib_h +#define cm_bzlib_h /* Use the bzip2 library configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_curl.h b/Utilities/cm_curl.h index a3b049b..c9835e7 100644 --- a/Utilities/cm_curl.h +++ b/Utilities/cm_curl.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_curl_h -#define __cm_curl_h +#ifndef cm_curl_h +#define cm_curl_h /* Use the curl library configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_expat.h b/Utilities/cm_expat.h index 91f4a7b..f361541 100644 --- a/Utilities/cm_expat.h +++ b/Utilities/cm_expat.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_expat_h -#define __cm_expat_h +#ifndef cm_expat_h +#define cm_expat_h /* Use the expat library configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_jsoncpp_reader.h b/Utilities/cm_jsoncpp_reader.h new file mode 100644 index 0000000..22f2d81 --- /dev/null +++ b/Utilities/cm_jsoncpp_reader.h @@ -0,0 +1,23 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cm_jsoncpp_reader_h +#define cm_jsoncpp_reader_h + +/* Use the jsoncpp library configured for CMake. */ +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/reader.h> +#else +# include <cmjsoncpp/include/json/reader.h> +#endif + +#endif diff --git a/Utilities/cm_jsoncpp_value.h b/Utilities/cm_jsoncpp_value.h new file mode 100644 index 0000000..b4cf620 --- /dev/null +++ b/Utilities/cm_jsoncpp_value.h @@ -0,0 +1,23 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cm_jsoncpp_value_h +#define cm_jsoncpp_value_h + +/* Use the jsoncpp library configured for CMake. */ +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/value.h> +#else +# include <cmjsoncpp/include/json/value.h> +#endif + +#endif diff --git a/Utilities/cm_jsoncpp_writer.h b/Utilities/cm_jsoncpp_writer.h new file mode 100644 index 0000000..c99a0d0 --- /dev/null +++ b/Utilities/cm_jsoncpp_writer.h @@ -0,0 +1,23 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cm_jsoncpp_writer_h +#define cm_jsoncpp_writer_h + +/* Use the jsoncpp library configured for CMake. */ +#include "cmThirdParty.h" +#ifdef CMAKE_USE_SYSTEM_JSONCPP +# include <json/writer.h> +#else +# include <cmjsoncpp/include/json/writer.h> +#endif + +#endif diff --git a/Utilities/cm_libarchive.h b/Utilities/cm_libarchive.h index 1469bae..0f18c91 100644 --- a/Utilities/cm_libarchive.h +++ b/Utilities/cm_libarchive.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_libarchive_h -#define __cm_libarchive_h +#ifndef cm_libarchive_h +#define cm_libarchive_h /* Use the libarchive configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_lzma.h b/Utilities/cm_lzma.h index c11c916..02d7e4f 100644 --- a/Utilities/cm_lzma.h +++ b/Utilities/cm_lzma.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_lzma_h -#define __cm_lzma_h +#ifndef cm_lzma_h +#define cm_lzma_h /* Use the liblzma configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_xmlrpc.h b/Utilities/cm_xmlrpc.h index a6b375d..ac461f9 100644 --- a/Utilities/cm_xmlrpc.h +++ b/Utilities/cm_xmlrpc.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_xmlrpc_h -#define __cm_xmlrpc_h +#ifndef cm_xmlrpc_h +#define cm_xmlrpc_h /* Use the xmlrpc library configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cm_zlib.h b/Utilities/cm_zlib.h index fb5832e..1b5c06e 100644 --- a/Utilities/cm_zlib.h +++ b/Utilities/cm_zlib.h @@ -9,8 +9,8 @@ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more information. ============================================================================*/ -#ifndef __cm_zlib_h -#define __cm_zlib_h +#ifndef cm_zlib_h +#define cm_zlib_h /* Use the zlib library configured for CMake. */ #include "cmThirdParty.h" diff --git a/Utilities/cmcompress/cmcompress.h b/Utilities/cmcompress/cmcompress.h index fdb0d90..4cd3a1c 100644 --- a/Utilities/cmcompress/cmcompress.h +++ b/Utilities/cmcompress/cmcompress.h @@ -35,8 +35,8 @@ * SUCH DAMAGE. */ -#ifndef __cmcompress__h_ -#define __cmcompress__h_ +#ifndef cmcompress__h_ +#define cmcompress__h_ #include <stdio.h> @@ -192,4 +192,4 @@ extern "C" #endif -#endif /* __cmcompress__h_ */ +#endif /* cmcompress__h_ */ diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index eaf276b..0db741e 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -460,7 +460,30 @@ if(CMAKE_USE_OPENSSL) add_definitions(-DCURL_CA_BUNDLE="${CURL_CA_BUNDLE}") endif() endif(OPENSSL_FOUND) -endif(CMAKE_USE_OPENSSL) +elseif(WIN32) + # Use Windows SSL/TLS native implementation. + add_definitions(-DUSE_SCHANNEL) + set(USE_WINDOWS_SSPI 1) +elseif(APPLE) + # Use OS X SSL/TLS native implementation if available on target version. + if(CMAKE_OSX_DEPLOYMENT_TARGET) + set(OSX_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET}) + else() + execute_process( + COMMAND sw_vers -productVersion + OUTPUT_VARIABLE OSX_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + if(NOT OSX_VERSION VERSION_LESS 10.6 AND + CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + add_definitions(-DUSE_DARWINSSL) + list(APPEND CURL_LIBS + "-framework CoreFoundation" + "-framework Security" + ) + endif() +endif() #libSSH2 option(CMAKE_USE_LIBSSH2 "Use libSSH2" ON) diff --git a/Utilities/cmjsoncpp/.gitattributes b/Utilities/cmjsoncpp/.gitattributes new file mode 100644 index 0000000..562b12e --- /dev/null +++ b/Utilities/cmjsoncpp/.gitattributes @@ -0,0 +1 @@ +* -whitespace diff --git a/Utilities/cmjsoncpp/CMakeLists.txt b/Utilities/cmjsoncpp/CMakeLists.txt new file mode 100644 index 0000000..1c863f8 --- /dev/null +++ b/Utilities/cmjsoncpp/CMakeLists.txt @@ -0,0 +1,25 @@ +project(JsonCpp CXX) + +# Disable warnings to avoid changing 3rd party code. +if(CMAKE_CXX_COMPILER_ID MATCHES + "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "PathScale") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -woffall") +endif() + +set(JSONCPP_SOURCES + src/lib_json/json_batchallocator.h + src/lib_json/json_reader.cpp + src/lib_json/json_tool.h + src/lib_json/json_value.cpp + src/lib_json/json_valueiterator.inl + src/lib_json/json_writer.cpp + ) + +include_directories( + ${JsonCpp_SOURCE_DIR}/include + ${KWSYS_HEADER_ROOT} + ) + +add_library(cmjsoncpp ${JSONCPP_SOURCES}) diff --git a/Utilities/cmjsoncpp/LICENSE b/Utilities/cmjsoncpp/LICENSE new file mode 100644 index 0000000..ca2bfe1 --- /dev/null +++ b/Utilities/cmjsoncpp/LICENSE @@ -0,0 +1,55 @@ +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, +this software is released into the Public Domain. + +In jurisdictions which do not recognize Public Domain property (e.g. Germany as of +2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is +released under the terms of the MIT License (see below). + +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual +Public Domain/MIT License conditions described here, as they choose. + +The MIT License is about as close to Public Domain as a license can get, and is +described in clear, concise terms at: + + http://en.wikipedia.org/wiki/MIT_License + +The full text of the MIT License follows: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +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. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. diff --git a/Utilities/cmjsoncpp/README-CMake.txt b/Utilities/cmjsoncpp/README-CMake.txt new file mode 100644 index 0000000..bf74094 --- /dev/null +++ b/Utilities/cmjsoncpp/README-CMake.txt @@ -0,0 +1,66 @@ +The Utilities/cmjsoncpp directory contains a reduced distribution +of the jsoncpp source tree with only the library source code and +CMake build system. It is not a submodule; the actual content is part +of our source tree and changes can be made and committed directly. + +We update from upstream using Git's "subtree" merge strategy. A +special branch contains commits of upstream jsoncpp snapshots and +nothing else. No Git ref points explicitly to the head of this +branch, but it is merged into our history. + +Update jsoncpp from upstream as follows. Create a local branch to +explicitly reference the upstream snapshot branch head: + + git branch jsoncpp-upstream 53f6ccb0 + +Use a temporary directory to checkout the branch: + + mkdir jsoncpp-tmp + cd jsoncpp-tmp + git init + git pull .. jsoncpp-upstream + rm -rf * + +Now place the (reduced) jsoncpp content in this directory. See +instructions shown by + + git log 53f6ccb0 + +for help extracting the content from the upstream svn repo. Then run +the following commands to commit the new version. Substitute the +appropriate date and version number: + + git add --all + + GIT_AUTHOR_NAME='JsonCpp Upstream' \ + GIT_AUTHOR_EMAIL='kwrobot@kitware.com' \ + GIT_AUTHOR_DATE='Thu Nov 20 08:45:58 2014 -0600' \ + git commit -m 'JsonCpp 1.0.0 (reduced)' && + git commit --amend + +Edit the commit message to describe the procedure used to obtain the +content. Then push the changes back up to the main local repository: + + git push .. HEAD:jsoncpp-upstream + cd .. + rm -rf jsoncpp-tmp + +Create a topic in the main repository on which to perform the update: + + git checkout -b update-jsoncpp master + +Merge the jsoncpp-upstream branch as a subtree: + + git merge -s recursive -X subtree=Utilities/cmjsoncpp \ + jsoncpp-upstream + +If there are conflicts, resolve them and commit. Build and test the +tree. Commit any additional changes needed to succeed. + +Finally, run + + git rev-parse --short=8 jsoncpp-upstream + +to get the commit from which the jsoncpp-upstream branch must be started +on the next update. Edit the "git branch jsoncpp-upstream" line above to +record it, and commit this file. diff --git a/Utilities/cmjsoncpp/include/json/assertions.h b/Utilities/cmjsoncpp/include/json/assertions.h new file mode 100644 index 0000000..37a3ff5 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/assertions.h @@ -0,0 +1,41 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED +#define CPPTL_JSON_ASSERTIONS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +#include <stdlib.h> + +#if JSON_USE_EXCEPTION +#include <stdexcept> +#define JSON_ASSERT(condition) \ + assert(condition); // @todo <= change this into an exception throw +#define JSON_FAIL_MESSAGE(message) throw std::runtime_error(message); +#else // JSON_USE_EXCEPTION +#define JSON_ASSERT(condition) assert(condition); + +// The call to assert() will show the failure message in debug builds. In +// release bugs we write to invalid memory in order to crash hard, so that a +// debugger or crash reporter gets the chance to take over. We still call exit() +// afterward in order to tell the compiler that this macro doesn't return. +#define JSON_FAIL_MESSAGE(message) \ + { \ + assert(false&& message); \ + strcpy(reinterpret_cast<char*>(666), message); \ + exit(123); \ + } + +#endif + +#define JSON_ASSERT_MESSAGE(condition, message) \ + if (!(condition)) { \ + JSON_FAIL_MESSAGE(message) \ + } + +#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/config.h b/Utilities/cmjsoncpp/include/json/config.h new file mode 100644 index 0000000..6847ceb --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/config.h @@ -0,0 +1,119 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_CONFIG_H_INCLUDED +#define JSON_CONFIG_H_INCLUDED + +// Include KWSys Large File Support configuration. +#include <cmsys/Configure.h> + +#if defined(_MSC_VER) +# pragma warning(push,1) +#endif + +/// If defined, indicates that json library is embedded in CppTL library. +//# define JSON_IN_CPPTL 1 + +/// If defined, indicates that json may leverage CppTL library +//# define JSON_USE_CPPTL 1 +/// If defined, indicates that cpptl vector based map should be used instead of +/// std::map +/// as Value container. +//# define JSON_USE_CPPTL_SMALLMAP 1 +/// If defined, indicates that Json specific container should be used +/// (hash table & simple deque container with customizable allocator). +/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332 +//# define JSON_VALUE_USE_INTERNAL_MAP 1 +/// Force usage of standard new/malloc based allocator instead of memory pool +/// based allocator. +/// The memory pools allocator used optimization (initializing Value and +/// ValueInternalLink +/// as if it was a POD) that may cause some validation tool to report errors. +/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. +//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1 + +// If non-zero, the library uses exceptions to report bad input instead of C +// assertion macros. The default is to use exceptions. +#ifndef JSON_USE_EXCEPTION +#define JSON_USE_EXCEPTION 1 +#endif + +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgated header. +// #define JSON_IS_AMALGAMATION + +#ifdef JSON_IN_CPPTL +#include <cpptl/config.h> +#ifndef JSON_USE_CPPTL +#define JSON_USE_CPPTL 1 +#endif +#endif + +#ifdef JSON_IN_CPPTL +#define JSON_API CPPTL_API +#elif defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#elif defined(JSON_DLL) +#if defined(_MSC_VER) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_IN_CPPTL +#if !defined(JSON_API) +#define JSON_API +#endif + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for +// integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +#if defined(_MSC_VER) && _MSC_VER <= 1200 // MSVC 6 +// Microsoft Visual Studio 6 only support conversion from __int64 to double +// (no conversion from unsigned __int64). +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' +// characters in the debug information) +// All projects I've ever seen with VS6 were using this globally (not bothering +// with pragma push/pop). +#pragma warning(disable : 4786) +#endif // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 + +#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 +/// Indicates that the following function is deprecated. +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +namespace Json { +typedef int Int; +typedef unsigned int UInt; +#if defined(JSON_NO_INT64) +typedef int LargestInt; +typedef unsigned int LargestUInt; +#undef JSON_HAS_INT64 +#else // if defined(JSON_NO_INT64) +// For Microsoft Visual use specific types as long long is not supported +#if defined(_MSC_VER) // Microsoft Visual Studio +typedef __int64 Int64; +typedef unsigned __int64 UInt64; +#else // if defined(_MSC_VER) // Other platforms, use long long +typedef long long int Int64; +typedef unsigned long long int UInt64; +#endif // if defined(_MSC_VER) +typedef Int64 LargestInt; +typedef UInt64 LargestUInt; +#define JSON_HAS_INT64 +#endif // if defined(JSON_NO_INT64) +} // end namespace Json + +#endif // JSON_CONFIG_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/features.h b/Utilities/cmjsoncpp/include/json/features.h new file mode 100644 index 0000000..1bb7bb6 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/features.h @@ -0,0 +1,57 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_FEATURES_H_INCLUDED +#define CPPTL_JSON_FEATURES_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +/** \brief Configuration passed to reader and writer. + * This configuration object can be used to force the Reader or Writer + * to behave in a standard conforming way. + */ +class JSON_API Features { +public: + /** \brief A configuration that allows all features and assumes all strings + * are UTF-8. + * - C & C++ comments are allowed + * - Root object can be any JSON value + * - Assumes Value strings are encoded in UTF-8 + */ + static Features all(); + + /** \brief A configuration that is strictly compatible with the JSON + * specification. + * - Comments are forbidden. + * - Root object must be either an array or an object value. + * - Assumes Value strings are encoded in UTF-8 + */ + static Features strictMode(); + + /** \brief Initialize the configuration like JsonConfig::allFeatures; + */ + Features(); + + /// \c true if comments are allowed. Default: \c true. + bool allowComments_; + + /// \c true if root must be either an array or an object value. Default: \c + /// false. + bool strictRoot_; + + /// \c true if dropped null placeholders are allowed. Default: \c false. + bool allowDroppedNullPlaceholders_; + + /// \c true if numeric object key are allowed. Default: \c false. + bool allowNumericKeys_; +}; + +} // namespace Json + +#endif // CPPTL_JSON_FEATURES_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/forwards.h b/Utilities/cmjsoncpp/include/json/forwards.h new file mode 100644 index 0000000..84a26cd --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/forwards.h @@ -0,0 +1,43 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_FORWARDS_H_INCLUDED +#define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// writer.h +class FastWriter; +class StyledWriter; + +// reader.h +class Reader; + +// features.h +class Features; + +// value.h +typedef unsigned int ArrayIndex; +class StaticString; +class Path; +class PathArgument; +class Value; +class ValueIteratorBase; +class ValueIterator; +class ValueConstIterator; +#ifdef JSON_VALUE_USE_INTERNAL_MAP +class ValueMapAllocator; +class ValueInternalLink; +class ValueInternalArray; +class ValueInternalMap; +#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP + +} // namespace Json + +#endif // JSON_FORWARDS_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/json.h b/Utilities/cmjsoncpp/include/json/json.h new file mode 100644 index 0000000..f89bc62 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/json.h @@ -0,0 +1,14 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_JSON_H_INCLUDED +#define JSON_JSON_H_INCLUDED + +#include "value.h" +#include "reader.h" +#include "writer.h" +#include "features.h" + +#endif // JSON_JSON_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/reader.h b/Utilities/cmjsoncpp/include/json/reader.h new file mode 100644 index 0000000..95237d1 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/reader.h @@ -0,0 +1,274 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_READER_H_INCLUDED +#define CPPTL_JSON_READER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "features.h" +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <deque> +#include <iosfwd> +#include <stack> +#include <string> + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a + *Value. + * + */ +class JSON_API Reader { +public: + typedef char Char; + typedef const Char* Location; + + /** \brief An error tagged with where in the JSON text it was encountered. + * + * The offsets give the [start, limit) range of bytes within the text. Note + * that this is bytes, not codepoints. + * + */ + struct StructuredError { + size_t offset_start; + size_t offset_limit; + std::string message; + }; + + /** \brief Constructs a Reader allowing all features + * for parsing. + */ + Reader(); + + /** \brief Constructs a Reader allowing the specified feature set + * for parsing. + */ + Reader(const Features& features); + + /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> + * document. + * \param document UTF-8 encoded string containing the document to read. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + * back during + * serialization, \c false to discard comments. + * This parameter is ignored if + * Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + * error occurred. + */ + bool + parse(const std::string& document, Value& root, bool collectComments = true); + + /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> + document. + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the + document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + document to read. + \ Must be >= beginDoc. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them + back during + * serialization, \c false to discard comments. + * This parameter is ignored if + Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an + error occurred. + */ + bool parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments = true); + + /// \brief Parse from input stream. + /// \see Json::operator>>(std::istream&, Json::Value&). + bool parse(std::istream& is, Value& root, bool collectComments = true); + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + */ + std::string getFormatedErrorMessages() const; + + /** \brief Returns a user friendly string that list errors in the parsed + * document. + * \return Formatted error message with the list of errors with their location + * in + * the parsed document. An empty string is returned if no error + * occurred + * during parsing. + */ + std::string getFormattedErrorMessages() const; + + /** \brief Returns a vector of structured erros encounted while parsing. + * \return A (possibly empty) vector of StructuredError objects. Currently + * only one error can be returned, but the caller should tolerate + * multiple + * errors. This can occur if the parser recovers from a non-fatal + * parse error and then encounters additional errors. + */ + std::vector<StructuredError> getStructuredErrors() const; + + /** \brief Add a semantic error message. + * \param value JSON Value location associated with the error + * \param message The error message. + * \return \c true if the error was successfully added, \c false if the + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const std::string& message); + + /** \brief Add a semantic error message with extra context. + * \param value JSON Value location associated with the error + * \param message The error message. + * \param extra Additional JSON Value location to contextualize the error + * \return \c true if the error was successfully added, \c false if either + * Value offset exceeds the document size. + */ + bool pushError(const Value& value, const std::string& message, const Value& extra); + + /** \brief Return whether there are any errors. + * \return \c true if there are no errors to report \c false if + * errors have occurred. + */ + bool good() const; + +private: + enum TokenType { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo { + public: + Token token_; + std::string message_; + Location extra_; + }; + + typedef std::deque<ErrorInfo> Errors; + + bool expectToken(TokenType type, Token& token, const char* message); + bool readToken(Token& token); + void skipSpaces(); + bool match(Location pattern, int patternLength); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + void readNumber(); + bool readValue(); + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, std::string& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode); + bool addError(const std::string& message, Token& token, Location extra = 0); + bool recoverFromError(TokenType skipUntilToken); + bool addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken); + void skipUntilSpace(); + Value& currentValue(); + Char getNextChar(); + void + getLocationLineAndColumn(Location location, int& line, int& column) const; + std::string getLocationLineAndColumn(Location location) const; + void addComment(Location begin, Location end, CommentPlacement placement); + void skipCommentTokens(Token& token); + + typedef std::stack<Value*> Nodes; + Nodes nodes_; + Errors errors_; + std::string document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value* lastValue_; + std::string commentsBefore_; + Features features_; + bool collectComments_; +}; + +/** \brief Read from 'sin' into 'root'. + + Always keep comments from the input JSON. + + This can be used to read a file into a particular sub-object. + For example: + \code + Json::Value root; + cin >> root["dir"]["file"]; + cout << root; + \endcode + Result: + \verbatim + { + "dir": { + "file": { + // The input stream JSON would be nested here. + } + } + } + \endverbatim + \throw std::exception on parse error. + \see Json::operator<<() +*/ +JSON_API std::istream& operator>>(std::istream&, Value&); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_READER_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/value.h b/Utilities/cmjsoncpp/include/json/value.h new file mode 100644 index 0000000..197a856 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/value.h @@ -0,0 +1,1088 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef CPPTL_JSON_H_INCLUDED +#define CPPTL_JSON_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "forwards.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <string> +#include <vector> + +#ifndef JSON_USE_CPPTL_SMALLMAP +#include <map> +#else +#include <cpptl/smallmap.h> +#endif +#ifdef JSON_USE_CPPTL +#include <cpptl/forwards.h> +#endif + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +/** \brief JSON (JavaScript Object Notation). + */ +namespace Json { + +/** \brief Type of the value held by a Value object. + */ +enum ValueType { + nullValue = 0, ///< 'null' value + intValue, ///< signed integer value + uintValue, ///< unsigned integer value + realValue, ///< double value + stringValue, ///< UTF-8 string value + booleanValue, ///< bool value + arrayValue, ///< array value (ordered list) + objectValue ///< object value (collection of name/value pairs). +}; + +enum CommentPlacement { + commentBefore = 0, ///< a comment placed on the line before a value + commentAfterOnSameLine, ///< a comment just after a value on the same line + commentAfter, ///< a comment on the line after a value (only make sense for + /// root value) + numberOfCommentPlacement +}; + +//# ifdef JSON_USE_CPPTL +// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames; +// typedef CppTL::AnyEnumerator<const Value &> EnumValues; +//# endif + +/** \brief Lightweight wrapper to tag static string. + * + * Value constructor and objectValue member assignement takes advantage of the + * StaticString and avoid the cost of string duplication when storing the + * string or the member name. + * + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ +class JSON_API StaticString { +public: + explicit StaticString(const char* czstring) : str_(czstring) {} + + operator const char*() const { return str_; } + + const char* c_str() const { return str_; } + +private: + const char* str_; +}; + +/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value. + * + * This class is a discriminated union wrapper that can represents a: + * - signed integer [range: Value::minInt - Value::maxInt] + * - unsigned integer (range: 0 - Value::maxUInt) + * - double + * - UTF-8 string + * - boolean + * - 'null' + * - an ordered list of Value + * - collection of name/value pairs (javascript object) + * + * The type of the held value is represented by a #ValueType and + * can be obtained using type(). + * + * values of an #objectValue or #arrayValue can be accessed using operator[]() + *methods. + * Non const methods will automatically create the a #nullValue element + * if it does not exist. + * The sequence of an #arrayValue will be automatically resize and initialized + * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. + * + * The get() methods can be used to obtanis default value in the case the + *required element + * does not exist. + * + * It is possible to iterate over the list of a #objectValue values using + * the getMemberNames() method. + */ +class JSON_API Value { + friend class ValueIteratorBase; +#ifdef JSON_VALUE_USE_INTERNAL_MAP + friend class ValueInternalLink; + friend class ValueInternalMap; +#endif +public: + typedef std::vector<std::string> Members; + typedef ValueIterator iterator; + typedef ValueConstIterator const_iterator; + typedef Json::UInt UInt; + typedef Json::Int Int; +#if defined(JSON_HAS_INT64) + typedef Json::UInt64 UInt64; + typedef Json::Int64 Int64; +#endif // defined(JSON_HAS_INT64) + typedef Json::LargestInt LargestInt; + typedef Json::LargestUInt LargestUInt; + typedef Json::ArrayIndex ArrayIndex; + + static const Value& null; + /// Minimum signed integer value that can be stored in a Json::Value. + static const LargestInt minLargestInt; + /// Maximum signed integer value that can be stored in a Json::Value. + static const LargestInt maxLargestInt; + /// Maximum unsigned integer value that can be stored in a Json::Value. + static const LargestUInt maxLargestUInt; + + /// Minimum signed int value that can be stored in a Json::Value. + static const Int minInt; + /// Maximum signed int value that can be stored in a Json::Value. + static const Int maxInt; + /// Maximum unsigned int value that can be stored in a Json::Value. + static const UInt maxUInt; + +#if defined(JSON_HAS_INT64) + /// Minimum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 minInt64; + /// Maximum signed 64 bits int value that can be stored in a Json::Value. + static const Int64 maxInt64; + /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. + static const UInt64 maxUInt64; +#endif // defined(JSON_HAS_INT64) + +private: +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION +#ifndef JSON_VALUE_USE_INTERNAL_MAP + class CZString { + public: + enum DuplicationPolicy { + noDuplication = 0, + duplicate, + duplicateOnCopy + }; + CZString(ArrayIndex index); + CZString(const char* cstr, DuplicationPolicy allocate); + CZString(const CZString& other); + ~CZString(); + CZString& operator=(CZString other); + bool operator<(const CZString& other) const; + bool operator==(const CZString& other) const; + ArrayIndex index() const; + const char* c_str() const; + bool isStaticString() const; + + private: + void swap(CZString& other); + const char* cstr_; + ArrayIndex index_; + }; + +public: +#ifndef JSON_USE_CPPTL_SMALLMAP + typedef std::map<CZString, Value> ObjectValues; +#else + typedef CppTL::SmallMap<CZString, Value> ObjectValues; +#endif // ifndef JSON_USE_CPPTL_SMALLMAP +#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +public: + /** \brief Create a default Value of the given type. + + This is a very useful constructor. + To create an empty array, pass arrayValue. + To create an empty object, pass objectValue. + Another Value can then be set to this one by assignment. +This is useful since clear() and resize() will not alter types. + + Examples: +\code +Json::Value null_value; // null +Json::Value arr_value(Json::arrayValue); // [] +Json::Value obj_value(Json::objectValue); // {} +\endcode + */ + Value(ValueType type = nullValue); + Value(Int value); + Value(UInt value); +#if defined(JSON_HAS_INT64) + Value(Int64 value); + Value(UInt64 value); +#endif // if defined(JSON_HAS_INT64) + Value(double value); + Value(const char* value); + Value(const char* beginValue, const char* endValue); + /** \brief Constructs a value from a static string. + + * Like other value string constructor but do not duplicate the string for + * internal storage. The given string must remain alive after the call to this + * constructor. + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * \endcode + */ + Value(const StaticString& value); + Value(const std::string& value); +#ifdef JSON_USE_CPPTL + Value(const CppTL::ConstString& value); +#endif + Value(bool value); + Value(const Value& other); + ~Value(); + + Value& operator=(Value other); + /// Swap values. + /// \note Currently, comments are intentionally not swapped, for + /// both logic and efficiency. + void swap(Value& other); + + ValueType type() const; + + bool operator<(const Value& other) const; + bool operator<=(const Value& other) const; + bool operator>=(const Value& other) const; + bool operator>(const Value& other) const; + + bool operator==(const Value& other) const; + bool operator!=(const Value& other) const; + + int compare(const Value& other) const; + + const char* asCString() const; + std::string asString() const; +#ifdef JSON_USE_CPPTL + CppTL::ConstString asConstString() const; +#endif + Int asInt() const; + UInt asUInt() const; +#if defined(JSON_HAS_INT64) + Int64 asInt64() const; + UInt64 asUInt64() const; +#endif // if defined(JSON_HAS_INT64) + LargestInt asLargestInt() const; + LargestUInt asLargestUInt() const; + float asFloat() const; + double asDouble() const; + bool asBool() const; + + bool isNull() const; + bool isBool() const; + bool isInt() const; + bool isInt64() const; + bool isUInt() const; + bool isUInt64() const; + bool isIntegral() const; + bool isDouble() const; + bool isNumeric() const; + bool isString() const; + bool isArray() const; + bool isObject() const; + + bool isConvertibleTo(ValueType other) const; + + /// Number of values in array or object + ArrayIndex size() const; + + /// \brief Return true if empty array, empty object, or null; + /// otherwise, false. + bool empty() const; + + /// Return isNull() + bool operator!() const; + + /// Remove all object members and array elements. + /// \pre type() is arrayValue, objectValue, or nullValue + /// \post type() is unchanged + void clear(); + + /// Resize the array to size elements. + /// New elements are initialized to null. + /// May only be called on nullValue or arrayValue. + /// \pre type() is arrayValue or nullValue + /// \post type() is arrayValue + void resize(ArrayIndex size); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](ArrayIndex index); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are + /// inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value& operator[](int index); + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](ArrayIndex index) const; + + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value& operator[](int index) const; + + /// If the array contains at least index+1 elements, returns the element + /// value, + /// otherwise returns defaultValue. + Value get(ArrayIndex index, const Value& defaultValue) const; + /// Return true if index < size(). + bool isValidIndex(ArrayIndex index) const; + /// \brief Append value to array at the end. + /// + /// Equivalent to jsonvalue[jsonvalue.size()] = value; + Value& append(const Value& value); + + /// Access an object value by name, create a null member if it does not exist. + Value& operator[](const char* key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const char* key) const; + /// Access an object value by name, create a null member if it does not exist. + Value& operator[](const std::string& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const std::string& key) const; + /** \brief Access an object value by name, create a null member if it does not + exist. + + * If the object as no entry for that name, then the member name used to store + * the new entry is not duplicated. + * Example of use: + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + Value& operator[](const StaticString& key); +#ifdef JSON_USE_CPPTL + /// Access an object value by name, create a null member if it does not exist. + Value& operator[](const CppTL::ConstString& key); + /// Access an object value by name, returns null if there is no member with + /// that name. + const Value& operator[](const CppTL::ConstString& key) const; +#endif + /// Return the member named key if it exist, defaultValue otherwise. + Value get(const char* key, const Value& defaultValue) const; + /// Return the member named key if it exist, defaultValue otherwise. + Value get(const std::string& key, const Value& defaultValue) const; +#ifdef JSON_USE_CPPTL + /// Return the member named key if it exist, defaultValue otherwise. + Value get(const CppTL::ConstString& key, const Value& defaultValue) const; +#endif + /// \brief Remove and return the named member. + /// + /// Do nothing if it did not exist. + /// \return the removed Value, or null. + /// \pre type() is objectValue or nullValue + /// \post type() is unchanged + Value removeMember(const char* key); + /// Same as removeMember(const char*) + Value removeMember(const std::string& key); + + /// Return true if the object has a member named key. + bool isMember(const char* key) const; + /// Return true if the object has a member named key. + bool isMember(const std::string& key) const; +#ifdef JSON_USE_CPPTL + /// Return true if the object has a member named key. + bool isMember(const CppTL::ConstString& key) const; +#endif + + /// \brief Return a list of the member names. + /// + /// If null, return an empty list. + /// \pre type() is objectValue or nullValue + /// \post if type() was nullValue, it remains nullValue + Members getMemberNames() const; + + //# ifdef JSON_USE_CPPTL + // EnumMemberNames enumMemberNames() const; + // EnumValues enumValues() const; + //# endif + + /// Comments must be //... or /* ... */ + void setComment(const char* comment, CommentPlacement placement); + /// Comments must be //... or /* ... */ + void setComment(const std::string& comment, CommentPlacement placement); + bool hasComment(CommentPlacement placement) const; + /// Include delimiters and embedded newlines. + std::string getComment(CommentPlacement placement) const; + + std::string toStyledString() const; + + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); + + // Accessors for the [start, limit) range of bytes within the JSON text from + // which this value was parsed, if any. + void setOffsetStart(size_t start); + void setOffsetLimit(size_t limit); + size_t getOffsetStart() const; + size_t getOffsetLimit() const; + +private: + void initBasic(ValueType type, bool allocated = false); + + Value& resolveReference(const char* key, bool isStatic); + +#ifdef JSON_VALUE_USE_INTERNAL_MAP + inline bool isItemAvailable() const { return itemIsUsed_ == 0; } + + inline void setItemUsed(bool isUsed = true) { itemIsUsed_ = isUsed ? 1 : 0; } + + inline bool isMemberNameStatic() const { return memberNameIsStatic_ == 0; } + + inline void setMemberNameIsStatic(bool isStatic) { + memberNameIsStatic_ = isStatic ? 1 : 0; + } +#endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP + +private: + struct CommentInfo { + CommentInfo(); + ~CommentInfo(); + + void setComment(const char* text); + + char* comment_; + }; + + // struct MemberNamesTransform + //{ + // typedef const char *result_type; + // const char *operator()( const CZString &name ) const + // { + // return name.c_str(); + // } + //}; + + union ValueHolder { + LargestInt int_; + LargestUInt uint_; + double real_; + bool bool_; + char* string_; +#ifdef JSON_VALUE_USE_INTERNAL_MAP + ValueInternalArray* array_; + ValueInternalMap* map_; +#else + ObjectValues* map_; +#endif + } value_; + ValueType type_ : 8; + int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. +#ifdef JSON_VALUE_USE_INTERNAL_MAP + unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container. + int memberNameIsStatic_ : 1; // used by the ValueInternalMap container. +#endif + CommentInfo* comments_; + + // [start, limit) byte offsets in the source JSON text from which this Value + // was extracted. + size_t start_; + size_t limit_; +}; + +/** \brief Experimental and untested: represents an element of the "path" to + * access a node. + */ +class JSON_API PathArgument { +public: + friend class Path; + + PathArgument(); + PathArgument(ArrayIndex index); + PathArgument(const char* key); + PathArgument(const std::string& key); + +private: + enum Kind { + kindNone = 0, + kindIndex, + kindKey + }; + std::string key_; + ArrayIndex index_; + Kind kind_; +}; + +/** \brief Experimental and untested: represents a "path" to access a node. + * + * Syntax: + * - "." => root node + * - ".[n]" => elements at index 'n' of root node (an array value) + * - ".name" => member named 'name' of root node (an object value) + * - ".name1.name2.name3" + * - ".[0][1][2].name1[3]" + * - ".%" => member name is provided as parameter + * - ".[%]" => index is provied as parameter + */ +class JSON_API Path { +public: + Path(const std::string& path, + const PathArgument& a1 = PathArgument(), + const PathArgument& a2 = PathArgument(), + const PathArgument& a3 = PathArgument(), + const PathArgument& a4 = PathArgument(), + const PathArgument& a5 = PathArgument()); + + const Value& resolve(const Value& root) const; + Value resolve(const Value& root, const Value& defaultValue) const; + /// Creates the "path" to access the specified node and returns a reference on + /// the node. + Value& make(Value& root) const; + +private: + typedef std::vector<const PathArgument*> InArgs; + typedef std::vector<PathArgument> Args; + + void makePath(const std::string& path, const InArgs& in); + void addPathInArg(const std::string& path, + const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind); + void invalidPath(const std::string& path, int location); + + Args args_; +}; + +#ifdef JSON_VALUE_USE_INTERNAL_MAP +/** \brief Allocator to customize Value internal map. + * Below is an example of a simple implementation (default implementation + actually + * use memory pool for speed). + * \code + class DefaultValueMapAllocator : public ValueMapAllocator + { + public: // overridden from ValueMapAllocator + virtual ValueInternalMap *newMap() + { + return new ValueInternalMap(); + } + + virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) + { + return new ValueInternalMap( other ); + } + + virtual void destructMap( ValueInternalMap *map ) + { + delete map; + } + + virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) + { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets( ValueInternalLink *links ) + { + delete [] links; + } + + virtual ValueInternalLink *allocateMapLink() + { + return new ValueInternalLink(); + } + + virtual void releaseMapLink( ValueInternalLink *link ) + { + delete link; + } + }; + * \endcode + */ +class JSON_API ValueMapAllocator { +public: + virtual ~ValueMapAllocator(); + virtual ValueInternalMap* newMap() = 0; + virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) = 0; + virtual void destructMap(ValueInternalMap* map) = 0; + virtual ValueInternalLink* allocateMapBuckets(unsigned int size) = 0; + virtual void releaseMapBuckets(ValueInternalLink* links) = 0; + virtual ValueInternalLink* allocateMapLink() = 0; + virtual void releaseMapLink(ValueInternalLink* link) = 0; +}; + +/** \brief ValueInternalMap hash-map bucket chain link (for internal use only). + * \internal previous_ & next_ allows for bidirectional traversal. + */ +class JSON_API ValueInternalLink { +public: + enum { + itemPerLink = 6 + }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture. + enum InternalFlags { + flagAvailable = 0, + flagUsed = 1 + }; + + ValueInternalLink(); + + ~ValueInternalLink(); + + Value items_[itemPerLink]; + char* keys_[itemPerLink]; + ValueInternalLink* previous_; + ValueInternalLink* next_; +}; + +/** \brief A linked page based hash-table implementation used internally by + *Value. + * \internal ValueInternalMap is a tradional bucket based hash-table, with a + *linked + * list in each bucket to handle collision. There is an addional twist in that + * each node of the collision linked list is a page containing a fixed amount of + * value. This provides a better compromise between memory usage and speed. + * + * Each bucket is made up of a chained list of ValueInternalLink. The last + * link of a given bucket can be found in the 'previous_' field of the following + *bucket. + * The last link of the last bucket is stored in tailLink_ as it has no + *following bucket. + * Only the last link of a bucket may contains 'available' item. The last link + *always + * contains at least one element unless is it the bucket one very first link. + */ +class JSON_API ValueInternalMap { + friend class ValueIteratorBase; + friend class Value; + +public: + typedef unsigned int HashKey; + typedef unsigned int BucketIndex; + +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + struct IteratorState { + IteratorState() : map_(0), link_(0), itemIndex_(0), bucketIndex_(0) {} + ValueInternalMap* map_; + ValueInternalLink* link_; + BucketIndex itemIndex_; + BucketIndex bucketIndex_; + }; +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + + ValueInternalMap(); + ValueInternalMap(const ValueInternalMap& other); + ValueInternalMap& operator=(ValueInternalMap other); + ~ValueInternalMap(); + + void swap(ValueInternalMap& other); + + BucketIndex size() const; + + void clear(); + + bool reserveDelta(BucketIndex growth); + + bool reserve(BucketIndex newItemCount); + + const Value* find(const char* key) const; + + Value* find(const char* key); + + Value& resolveReference(const char* key, bool isStatic); + + void remove(const char* key); + + void doActualRemove(ValueInternalLink* link, + BucketIndex index, + BucketIndex bucketIndex); + + ValueInternalLink*& getLastLinkInBucket(BucketIndex bucketIndex); + + Value& setNewItem(const char* key, + bool isStatic, + ValueInternalLink* link, + BucketIndex index); + + Value& unsafeAdd(const char* key, bool isStatic, HashKey hashedKey); + + HashKey hash(const char* key) const; + + int compare(const ValueInternalMap& other) const; + +private: + void makeBeginIterator(IteratorState& it) const; + void makeEndIterator(IteratorState& it) const; + static bool equals(const IteratorState& x, const IteratorState& other); + static void increment(IteratorState& iterator); + static void incrementBucket(IteratorState& iterator); + static void decrement(IteratorState& iterator); + static const char* key(const IteratorState& iterator); + static const char* key(const IteratorState& iterator, bool& isStatic); + static Value& value(const IteratorState& iterator); + static int distance(const IteratorState& x, const IteratorState& y); + +private: + ValueInternalLink* buckets_; + ValueInternalLink* tailLink_; + BucketIndex bucketsSize_; + BucketIndex itemCount_; +}; + +/** \brief A simplified deque implementation used internally by Value. +* \internal +* It is based on a list of fixed "page", each page contains a fixed number of +*items. +* Instead of using a linked-list, a array of pointer is used for fast item +*look-up. +* Look-up for an element is as follow: +* - compute page index: pageIndex = itemIndex / itemsPerPage +* - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage] +* +* Insertion is amortized constant time (only the array containing the index of +*pointers +* need to be reallocated when items are appended). +*/ +class JSON_API ValueInternalArray { + friend class Value; + friend class ValueIteratorBase; + +public: + enum { + itemsPerPage = 8 + }; // should be a power of 2 for fast divide and modulo. + typedef Value::ArrayIndex ArrayIndex; + typedef unsigned int PageIndex; + +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + struct IteratorState // Must be a POD + { + IteratorState() : array_(0), currentPageIndex_(0), currentItemIndex_(0) {} + ValueInternalArray* array_; + Value** currentPageIndex_; + unsigned int currentItemIndex_; + }; +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + + ValueInternalArray(); + ValueInternalArray(const ValueInternalArray& other); + ValueInternalArray& operator=(ValueInternalArray other); + ~ValueInternalArray(); + void swap(ValueInternalArray& other); + + void clear(); + void resize(ArrayIndex newSize); + + Value& resolveReference(ArrayIndex index); + + Value* find(ArrayIndex index) const; + + ArrayIndex size() const; + + int compare(const ValueInternalArray& other) const; + +private: + static bool equals(const IteratorState& x, const IteratorState& other); + static void increment(IteratorState& iterator); + static void decrement(IteratorState& iterator); + static Value& dereference(const IteratorState& iterator); + static Value& unsafeDereference(const IteratorState& iterator); + static int distance(const IteratorState& x, const IteratorState& y); + static ArrayIndex indexOf(const IteratorState& iterator); + void makeBeginIterator(IteratorState& it) const; + void makeEndIterator(IteratorState& it) const; + void makeIterator(IteratorState& it, ArrayIndex index) const; + + void makeIndexValid(ArrayIndex index); + + Value** pages_; + ArrayIndex size_; + PageIndex pageCount_; +}; + +/** \brief Experimental: do not use. Allocator to customize Value internal +array. + * Below is an example of a simple implementation (actual implementation use + * memory pool). + \code +class DefaultValueArrayAllocator : public ValueArrayAllocator +{ +public: // overridden from ValueArrayAllocator +virtual ~DefaultValueArrayAllocator() +{ +} + +virtual ValueInternalArray *newArray() +{ + return new ValueInternalArray(); +} + +virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) +{ + return new ValueInternalArray( other ); +} + +virtual void destruct( ValueInternalArray *array ) +{ + delete array; +} + +virtual void reallocateArrayPageIndex( Value **&indexes, + ValueInternalArray::PageIndex +&indexCount, + ValueInternalArray::PageIndex +minNewIndexCount ) +{ + ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; + if ( minNewIndexCount > newIndexCount ) + newIndexCount = minNewIndexCount; + void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); + if ( !newIndexes ) + throw std::bad_alloc(); + indexCount = newIndexCount; + indexes = static_cast<Value **>( newIndexes ); +} +virtual void releaseArrayPageIndex( Value **indexes, + ValueInternalArray::PageIndex indexCount ) +{ + if ( indexes ) + free( indexes ); +} + +virtual Value *allocateArrayPage() +{ + return static_cast<Value *>( malloc( sizeof(Value) * +ValueInternalArray::itemsPerPage ) ); +} + +virtual void releaseArrayPage( Value *value ) +{ + if ( value ) + free( value ); +} +}; + \endcode + */ +class JSON_API ValueArrayAllocator { +public: + virtual ~ValueArrayAllocator(); + virtual ValueInternalArray* newArray() = 0; + virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) = 0; + virtual void destructArray(ValueInternalArray* array) = 0; + /** \brief Reallocate array page index. + * Reallocates an array of pointer on each page. + * \param indexes [input] pointer on the current index. May be \c NULL. + * [output] pointer on the new index of at least + * \a minNewIndexCount pages. + * \param indexCount [input] current number of pages in the index. + * [output] number of page the reallocated index can handle. + * \b MUST be >= \a minNewIndexCount. + * \param minNewIndexCount Minimum number of page the new index must be able + * to + * handle. + */ + virtual void + reallocateArrayPageIndex(Value**& indexes, + ValueInternalArray::PageIndex& indexCount, + ValueInternalArray::PageIndex minNewIndexCount) = 0; + virtual void + releaseArrayPageIndex(Value** indexes, + ValueInternalArray::PageIndex indexCount) = 0; + virtual Value* allocateArrayPage() = 0; + virtual void releaseArrayPage(Value* value) = 0; +}; +#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP + +/** \brief base class for Value iterators. + * + */ +class JSON_API ValueIteratorBase { +public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef unsigned int size_t; + typedef int difference_type; + typedef ValueIteratorBase SelfType; + + ValueIteratorBase(); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueIteratorBase(const Value::ObjectValues::iterator& current); +#else + ValueIteratorBase(const ValueInternalArray::IteratorState& state); + ValueIteratorBase(const ValueInternalMap::IteratorState& state); +#endif + + bool operator==(const SelfType& other) const { return isEqual(other); } + + bool operator!=(const SelfType& other) const { return !isEqual(other); } + + difference_type operator-(const SelfType& other) const { + return computeDistance(other); + } + + /// Return either the index or the member name of the referenced value as a + /// Value. + Value key() const; + + /// Return the index of the referenced Value. -1 if it is not an arrayValue. + UInt index() const; + + /// Return the member name of the referenced Value. "" if it is not an + /// objectValue. + const char* memberName() const; + +protected: + Value& deref() const; + + void increment(); + + void decrement(); + + difference_type computeDistance(const SelfType& other) const; + + bool isEqual(const SelfType& other) const; + + void copy(const SelfType& other); + +private: +#ifndef JSON_VALUE_USE_INTERNAL_MAP + Value::ObjectValues::iterator current_; + // Indicates that iterator is for a null value. + bool isNull_; +#else + union { + ValueInternalArray::IteratorState array_; + ValueInternalMap::IteratorState map_; + } iterator_; + bool isArray_; +#endif +}; + +/** \brief const iterator for object and array value. + * + */ +class JSON_API ValueConstIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef const Value value_type; + typedef unsigned int size_t; + typedef int difference_type; + typedef const Value& reference; + typedef const Value* pointer; + typedef ValueConstIterator SelfType; + + ValueConstIterator(); + +private: +/*! \internal Use by Value to create an iterator. + */ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueConstIterator(const Value::ObjectValues::iterator& current); +#else + ValueConstIterator(const ValueInternalArray::IteratorState& state); + ValueConstIterator(const ValueInternalMap::IteratorState& state); +#endif +public: + SelfType& operator=(const ValueIteratorBase& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +/** \brief Iterator for object and array value. + */ +class JSON_API ValueIterator : public ValueIteratorBase { + friend class Value; + +public: + typedef Value value_type; + typedef unsigned int size_t; + typedef int difference_type; + typedef Value& reference; + typedef Value* pointer; + typedef ValueIterator SelfType; + + ValueIterator(); + ValueIterator(const ValueConstIterator& other); + ValueIterator(const ValueIterator& other); + +private: +/*! \internal Use by Value to create an iterator. + */ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueIterator(const Value::ObjectValues::iterator& current); +#else + ValueIterator(const ValueInternalArray::IteratorState& state); + ValueIterator(const ValueInternalMap::IteratorState& state); +#endif +public: + SelfType& operator=(const SelfType& other); + + SelfType operator++(int) { + SelfType temp(*this); + ++*this; + return temp; + } + + SelfType operator--(int) { + SelfType temp(*this); + --*this; + return temp; + } + + SelfType& operator--() { + decrement(); + return *this; + } + + SelfType& operator++() { + increment(); + return *this; + } + + reference operator*() const { return deref(); } + + pointer operator->() const { return &deref(); } +}; + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // CPPTL_JSON_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/version.h b/Utilities/cmjsoncpp/include/json/version.h new file mode 100644 index 0000000..6fe0682 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/version.h @@ -0,0 +1,14 @@ +// DO NOT EDIT. This file is generated by CMake from "version" +// and "version.h.in" files. +// Run CMake configure step to update it. +#ifndef JSON_VERSION_H_INCLUDED +# define JSON_VERSION_H_INCLUDED + +# define JSONCPP_VERSION_STRING "1.0.0" +# define JSONCPP_VERSION_MAJOR 1 +# define JSONCPP_VERSION_MINOR 0 +# define JSONCPP_VERSION_PATCH 0 +# define JSONCPP_VERSION_QUALIFIER +# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) + +#endif // JSON_VERSION_H_INCLUDED diff --git a/Utilities/cmjsoncpp/include/json/writer.h b/Utilities/cmjsoncpp/include/json/writer.h new file mode 100644 index 0000000..10863b0 --- /dev/null +++ b/Utilities/cmjsoncpp/include/json/writer.h @@ -0,0 +1,213 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSON_WRITER_H_INCLUDED +#define JSON_WRITER_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +#include "value.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <iosfwd> +#include <vector> +#include <string> + +// Disable warning C4251: <data member>: <type> needs to have dll-interface to +// be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(push) +#pragma warning(disable : 4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +namespace Json { + +class Value; + +/** \brief Abstract class for writers. + */ +class JSON_API Writer { +public: + virtual ~Writer(); + + virtual std::string write(const Value& root) = 0; +}; + +/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format + *without formatting (not human friendly). + * + * The JSON document is written in a single line. It is not intended for 'human' + *consumption, + * but may be usefull to support feature such as RPC where bandwith is limited. + * \sa Reader, Value + */ +class JSON_API FastWriter : public Writer { +public: + FastWriter(); + virtual ~FastWriter() {} + + void enableYAMLCompatibility(); + + /** \brief Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's Javascript, it makes for smaller output and the + * browser can handle the output just fine. + */ + void dropNullPlaceholders(); + + void omitEndingLineFeed(); + +public: // overridden from Writer + virtual std::string write(const Value& root); + +private: + void writeValue(const Value& value); + + std::string document_; + bool yamlCompatiblityEnabled_; + bool dropNullPlaceholders_; + bool omitEndingLineFeed_; +}; + +/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a + *human friendly way. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + *line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + *types, + * and all the values fit on one lines, then print the array on a single + *line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + *#CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + */ +class JSON_API StyledWriter : public Writer { +public: + StyledWriter(); + virtual ~StyledWriter() {} + +public: // overridden from Writer + /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. + * \param root Value to serialize. + * \return String containing the JSON document that represents the root value. + */ + virtual std::string write(const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const std::string& value); + void writeIndent(); + void writeWithIndent(const std::string& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static std::string normalizeEOL(const std::string& text); + + typedef std::vector<std::string> ChildValues; + + ChildValues childValues_; + std::string document_; + std::string indentString_; + int rightMargin_; + int indentSize_; + bool addChildValues_; +}; + +/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a + human friendly way, + to a stream rather than to a string. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per + line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value + types, + * and all the values fit on one lines, then print the array on a single + line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their + #CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + */ +class JSON_API StyledStreamWriter { +public: + StyledStreamWriter(std::string indentation = "\t"); + ~StyledStreamWriter() {} + +public: + /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. + * \param out Stream to write to. (Can be ostringstream, e.g.) + * \param root Value to serialize. + * \note There is no point in deriving from Writer, since write() should not + * return a value. + */ + void write(std::ostream& out, const Value& root); + +private: + void writeValue(const Value& value); + void writeArrayValue(const Value& value); + bool isMultineArray(const Value& value); + void pushValue(const std::string& value); + void writeIndent(); + void writeWithIndent(const std::string& value); + void indent(); + void unindent(); + void writeCommentBeforeValue(const Value& root); + void writeCommentAfterValueOnSameLine(const Value& root); + bool hasCommentForValue(const Value& value); + static std::string normalizeEOL(const std::string& text); + + typedef std::vector<std::string> ChildValues; + + ChildValues childValues_; + std::ostream* document_; + std::string indentString_; + int rightMargin_; + std::string indentation_; + bool addChildValues_; +}; + +#if defined(JSON_HAS_INT64) +std::string JSON_API valueToString(Int value); +std::string JSON_API valueToString(UInt value); +#endif // if defined(JSON_HAS_INT64) +std::string JSON_API valueToString(LargestInt value); +std::string JSON_API valueToString(LargestUInt value); +std::string JSON_API valueToString(double value); +std::string JSON_API valueToString(bool value); +std::string JSON_API valueToQuotedString(const char* value); + +/// \brief Output using the StyledStreamWriter. +/// \see Json::operator>>() +JSON_API std::ostream& operator<<(std::ostream&, const Value& root); + +} // namespace Json + +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +#pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + +#endif // JSON_WRITER_H_INCLUDED diff --git a/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h b/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h new file mode 100644 index 0000000..2fbef7a8 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_batchallocator.h @@ -0,0 +1,121 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED +#define JSONCPP_BATCHALLOCATOR_H_INCLUDED + +#include <stdlib.h> +#include <assert.h> + +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +namespace Json { + +/* Fast memory allocator. + * + * This memory allocator allocates memory for a batch of object (specified by + * the page size, the number of object in each page). + * + * It does not allow the destruction of a single object. All the allocated + * objects can be destroyed at once. The memory can be either released or reused + * for future allocation. + * + * The in-place new operator must be used to construct the object using the + * pointer returned by allocate. + */ +template <typename AllocatedType, const unsigned int objectPerAllocation> +class BatchAllocator { +public: + BatchAllocator(unsigned int objectsPerPage = 255) + : freeHead_(0), objectsPerPage_(objectsPerPage) { + // printf( "Size: %d => %s\n", sizeof(AllocatedType), + // typeid(AllocatedType).name() ); + assert(sizeof(AllocatedType) * objectPerAllocation >= + sizeof(AllocatedType*)); // We must be able to store a slist in the + // object free space. + assert(objectsPerPage >= 16); + batches_ = allocateBatch(0); // allocated a dummy page + currentBatch_ = batches_; + } + + ~BatchAllocator() { + for (BatchInfo* batch = batches_; batch;) { + BatchInfo* nextBatch = batch->next_; + free(batch); + batch = nextBatch; + } + } + + /// allocate space for an array of objectPerAllocation object. + /// @warning it is the responsability of the caller to call objects + /// constructors. + AllocatedType* allocate() { + if (freeHead_) // returns node from free list. + { + AllocatedType* object = freeHead_; + freeHead_ = *(AllocatedType**)object; + return object; + } + if (currentBatch_->used_ == currentBatch_->end_) { + currentBatch_ = currentBatch_->next_; + while (currentBatch_ && currentBatch_->used_ == currentBatch_->end_) + currentBatch_ = currentBatch_->next_; + + if (!currentBatch_) // no free batch found, allocate a new one + { + currentBatch_ = allocateBatch(objectsPerPage_); + currentBatch_->next_ = batches_; // insert at the head of the list + batches_ = currentBatch_; + } + } + AllocatedType* allocated = currentBatch_->used_; + currentBatch_->used_ += objectPerAllocation; + return allocated; + } + + /// Release the object. + /// @warning it is the responsability of the caller to actually destruct the + /// object. + void release(AllocatedType* object) { + assert(object != 0); + *(AllocatedType**)object = freeHead_; + freeHead_ = object; + } + +private: + struct BatchInfo { + BatchInfo* next_; + AllocatedType* used_; + AllocatedType* end_; + AllocatedType buffer_[objectPerAllocation]; + }; + + // disabled copy constructor and assignement operator. + BatchAllocator(const BatchAllocator&); + void operator=(const BatchAllocator&); + + static BatchInfo* allocateBatch(unsigned int objectsPerPage) { + const unsigned int mallocSize = + sizeof(BatchInfo) - sizeof(AllocatedType) * objectPerAllocation + + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage; + BatchInfo* batch = static_cast<BatchInfo*>(malloc(mallocSize)); + batch->next_ = 0; + batch->used_ = batch->buffer_; + batch->end_ = batch->buffer_ + objectsPerPage; + return batch; + } + + BatchInfo* batches_; + BatchInfo* currentBatch_; + /// Head of a single linked list within the allocated space of freeed object + AllocatedType* freeHead_; + unsigned int objectsPerPage_; +}; + +} // namespace Json + +#endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION + +#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED diff --git a/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl b/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl new file mode 100644 index 0000000..9ee15e9 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_internalarray.inl @@ -0,0 +1,360 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +// included by json_value.cpp + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueInternalArray +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueArrayAllocator::~ValueArrayAllocator() {} + +// ////////////////////////////////////////////////////////////////// +// class DefaultValueArrayAllocator +// ////////////////////////////////////////////////////////////////// +#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +class DefaultValueArrayAllocator : public ValueArrayAllocator { +public: // overridden from ValueArrayAllocator + virtual ~DefaultValueArrayAllocator() {} + + virtual ValueInternalArray* newArray() { return new ValueInternalArray(); } + + virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) { + return new ValueInternalArray(other); + } + + virtual void destructArray(ValueInternalArray* array) { delete array; } + + virtual void + reallocateArrayPageIndex(Value**& indexes, + ValueInternalArray::PageIndex& indexCount, + ValueInternalArray::PageIndex minNewIndexCount) { + ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1; + if (minNewIndexCount > newIndexCount) + newIndexCount = minNewIndexCount; + void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount); + JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); + indexCount = newIndexCount; + indexes = static_cast<Value**>(newIndexes); + } + virtual void releaseArrayPageIndex(Value** indexes, + ValueInternalArray::PageIndex indexCount) { + if (indexes) + free(indexes); + } + + virtual Value* allocateArrayPage() { + return static_cast<Value*>( + malloc(sizeof(Value) * ValueInternalArray::itemsPerPage)); + } + + virtual void releaseArrayPage(Value* value) { + if (value) + free(value); + } +}; + +#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +/// @todo make this thread-safe (lock when accessign batch allocator) +class DefaultValueArrayAllocator : public ValueArrayAllocator { +public: // overridden from ValueArrayAllocator + virtual ~DefaultValueArrayAllocator() {} + + virtual ValueInternalArray* newArray() { + ValueInternalArray* array = arraysAllocator_.allocate(); + new (array) ValueInternalArray(); // placement new + return array; + } + + virtual ValueInternalArray* newArrayCopy(const ValueInternalArray& other) { + ValueInternalArray* array = arraysAllocator_.allocate(); + new (array) ValueInternalArray(other); // placement new + return array; + } + + virtual void destructArray(ValueInternalArray* array) { + if (array) { + array->~ValueInternalArray(); + arraysAllocator_.release(array); + } + } + + virtual void + reallocateArrayPageIndex(Value**& indexes, + ValueInternalArray::PageIndex& indexCount, + ValueInternalArray::PageIndex minNewIndexCount) { + ValueInternalArray::PageIndex newIndexCount = (indexCount * 3) / 2 + 1; + if (minNewIndexCount > newIndexCount) + newIndexCount = minNewIndexCount; + void* newIndexes = realloc(indexes, sizeof(Value*) * newIndexCount); + JSON_ASSERT_MESSAGE(newIndexes, "Couldn't realloc."); + indexCount = newIndexCount; + indexes = static_cast<Value**>(newIndexes); + } + virtual void releaseArrayPageIndex(Value** indexes, + ValueInternalArray::PageIndex indexCount) { + if (indexes) + free(indexes); + } + + virtual Value* allocateArrayPage() { + return static_cast<Value*>(pagesAllocator_.allocate()); + } + + virtual void releaseArrayPage(Value* value) { + if (value) + pagesAllocator_.release(value); + } + +private: + BatchAllocator<ValueInternalArray, 1> arraysAllocator_; + BatchAllocator<Value, ValueInternalArray::itemsPerPage> pagesAllocator_; +}; +#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR + +static ValueArrayAllocator*& arrayAllocator() { + static DefaultValueArrayAllocator defaultAllocator; + static ValueArrayAllocator* arrayAllocator = &defaultAllocator; + return arrayAllocator; +} + +static struct DummyArrayAllocatorInitializer { + DummyArrayAllocatorInitializer() { + arrayAllocator(); // ensure arrayAllocator() statics are initialized before + // main(). + } +} dummyArrayAllocatorInitializer; + +// ////////////////////////////////////////////////////////////////// +// class ValueInternalArray +// ////////////////////////////////////////////////////////////////// +bool ValueInternalArray::equals(const IteratorState& x, + const IteratorState& other) { + return x.array_ == other.array_ && + x.currentItemIndex_ == other.currentItemIndex_ && + x.currentPageIndex_ == other.currentPageIndex_; +} + +void ValueInternalArray::increment(IteratorState& it) { + JSON_ASSERT_MESSAGE( + it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage + + it.currentItemIndex_ != + it.array_->size_, + "ValueInternalArray::increment(): moving iterator beyond end"); + ++(it.currentItemIndex_); + if (it.currentItemIndex_ == itemsPerPage) { + it.currentItemIndex_ = 0; + ++(it.currentPageIndex_); + } +} + +void ValueInternalArray::decrement(IteratorState& it) { + JSON_ASSERT_MESSAGE( + it.array_ && it.currentPageIndex_ == it.array_->pages_ && + it.currentItemIndex_ == 0, + "ValueInternalArray::decrement(): moving iterator beyond end"); + if (it.currentItemIndex_ == 0) { + it.currentItemIndex_ = itemsPerPage - 1; + --(it.currentPageIndex_); + } else { + --(it.currentItemIndex_); + } +} + +Value& ValueInternalArray::unsafeDereference(const IteratorState& it) { + return (*(it.currentPageIndex_))[it.currentItemIndex_]; +} + +Value& ValueInternalArray::dereference(const IteratorState& it) { + JSON_ASSERT_MESSAGE( + it.array_ && (it.currentPageIndex_ - it.array_->pages_) * itemsPerPage + + it.currentItemIndex_ < + it.array_->size_, + "ValueInternalArray::dereference(): dereferencing invalid iterator"); + return unsafeDereference(it); +} + +void ValueInternalArray::makeBeginIterator(IteratorState& it) const { + it.array_ = const_cast<ValueInternalArray*>(this); + it.currentItemIndex_ = 0; + it.currentPageIndex_ = pages_; +} + +void ValueInternalArray::makeIterator(IteratorState& it, + ArrayIndex index) const { + it.array_ = const_cast<ValueInternalArray*>(this); + it.currentItemIndex_ = index % itemsPerPage; + it.currentPageIndex_ = pages_ + index / itemsPerPage; +} + +void ValueInternalArray::makeEndIterator(IteratorState& it) const { + makeIterator(it, size_); +} + +ValueInternalArray::ValueInternalArray() : pages_(0), size_(0), pageCount_(0) {} + +ValueInternalArray::ValueInternalArray(const ValueInternalArray& other) + : pages_(0), size_(other.size_), pageCount_(0) { + PageIndex minNewPages = other.size_ / itemsPerPage; + arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages); + JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages, + "ValueInternalArray::reserve(): bad reallocation"); + IteratorState itOther; + other.makeBeginIterator(itOther); + Value* value; + for (ArrayIndex index = 0; index < size_; ++index, increment(itOther)) { + if (index % itemsPerPage == 0) { + PageIndex pageIndex = index / itemsPerPage; + value = arrayAllocator()->allocateArrayPage(); + pages_[pageIndex] = value; + } + new (value) Value(dereference(itOther)); + } +} + +ValueInternalArray& ValueInternalArray::operator=(ValueInternalArray other) { + swap(other); + return *this; +} + +ValueInternalArray::~ValueInternalArray() { + // destroy all constructed items + IteratorState it; + IteratorState itEnd; + makeBeginIterator(it); + makeEndIterator(itEnd); + for (; !equals(it, itEnd); increment(it)) { + Value* value = &dereference(it); + value->~Value(); + } + // release all pages + PageIndex lastPageIndex = size_ / itemsPerPage; + for (PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex) + arrayAllocator()->releaseArrayPage(pages_[pageIndex]); + // release pages index + arrayAllocator()->releaseArrayPageIndex(pages_, pageCount_); +} + +void ValueInternalArray::swap(ValueInternalArray& other) { + Value** tempPages = pages_; + pages_ = other.pages_; + other.pages_ = tempPages; + ArrayIndex tempSize = size_; + size_ = other.size_; + other.size_ = tempSize; + PageIndex tempPageCount = pageCount_; + pageCount_ = other.pageCount_; + other.pageCount_ = tempPageCount; +} + +void ValueInternalArray::clear() { + ValueInternalArray dummy; + swap(dummy); +} + +void ValueInternalArray::resize(ArrayIndex newSize) { + if (newSize == 0) + clear(); + else if (newSize < size_) { + IteratorState it; + IteratorState itEnd; + makeIterator(it, newSize); + makeIterator(itEnd, size_); + for (; !equals(it, itEnd); increment(it)) { + Value* value = &dereference(it); + value->~Value(); + } + PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; + PageIndex lastPageIndex = size_ / itemsPerPage; + for (; pageIndex < lastPageIndex; ++pageIndex) + arrayAllocator()->releaseArrayPage(pages_[pageIndex]); + size_ = newSize; + } else if (newSize > size_) + resolveReference(newSize); +} + +void ValueInternalArray::makeIndexValid(ArrayIndex index) { + // Need to enlarge page index ? + if (index >= pageCount_ * itemsPerPage) { + PageIndex minNewPages = (index + 1) / itemsPerPage; + arrayAllocator()->reallocateArrayPageIndex(pages_, pageCount_, minNewPages); + JSON_ASSERT_MESSAGE(pageCount_ >= minNewPages, + "ValueInternalArray::reserve(): bad reallocation"); + } + + // Need to allocate new pages ? + ArrayIndex nextPageIndex = (size_ % itemsPerPage) != 0 + ? size_ - (size_ % itemsPerPage) + itemsPerPage + : size_; + if (nextPageIndex <= index) { + PageIndex pageIndex = nextPageIndex / itemsPerPage; + PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; + for (; pageToAllocate-- > 0; ++pageIndex) + pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); + } + + // Initialize all new entries + IteratorState it; + IteratorState itEnd; + makeIterator(it, size_); + size_ = index + 1; + makeIterator(itEnd, size_); + for (; !equals(it, itEnd); increment(it)) { + Value* value = &dereference(it); + new (value) Value(); // Construct a default value using placement new + } +} + +Value& ValueInternalArray::resolveReference(ArrayIndex index) { + if (index >= size_) + makeIndexValid(index); + return pages_[index / itemsPerPage][index % itemsPerPage]; +} + +Value* ValueInternalArray::find(ArrayIndex index) const { + if (index >= size_) + return 0; + return &(pages_[index / itemsPerPage][index % itemsPerPage]); +} + +ValueInternalArray::ArrayIndex ValueInternalArray::size() const { + return size_; +} + +int ValueInternalArray::distance(const IteratorState& x, + const IteratorState& y) { + return indexOf(y) - indexOf(x); +} + +ValueInternalArray::ArrayIndex +ValueInternalArray::indexOf(const IteratorState& iterator) { + if (!iterator.array_) + return ArrayIndex(-1); + return ArrayIndex((iterator.currentPageIndex_ - iterator.array_->pages_) * + itemsPerPage + + iterator.currentItemIndex_); +} + +int ValueInternalArray::compare(const ValueInternalArray& other) const { + int sizeDiff(size_ - other.size_); + if (sizeDiff != 0) + return sizeDiff; + + for (ArrayIndex index = 0; index < size_; ++index) { + int diff = pages_[index / itemsPerPage][index % itemsPerPage].compare( + other.pages_[index / itemsPerPage][index % itemsPerPage]); + if (diff != 0) + return diff; + } + return 0; +} + +} // namespace Json diff --git a/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl b/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl new file mode 100644 index 0000000..ef3f330 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_internalmap.inl @@ -0,0 +1,473 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +// included by json_value.cpp + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueInternalMap +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/** \internal MUST be safely initialized using memset( this, 0, + * sizeof(ValueInternalLink) ); + * This optimization is used by the fast allocator. + */ +ValueInternalLink::ValueInternalLink() : previous_(0), next_(0) {} + +ValueInternalLink::~ValueInternalLink() { + for (int index = 0; index < itemPerLink; ++index) { + if (!items_[index].isItemAvailable()) { + if (!items_[index].isMemberNameStatic()) + free(keys_[index]); + } else + break; + } +} + +ValueMapAllocator::~ValueMapAllocator() {} + +#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +class DefaultValueMapAllocator : public ValueMapAllocator { +public: // overridden from ValueMapAllocator + virtual ValueInternalMap* newMap() { return new ValueInternalMap(); } + + virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) { + return new ValueInternalMap(other); + } + + virtual void destructMap(ValueInternalMap* map) { delete map; } + + virtual ValueInternalLink* allocateMapBuckets(unsigned int size) { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; } + + virtual ValueInternalLink* allocateMapLink() { + return new ValueInternalLink(); + } + + virtual void releaseMapLink(ValueInternalLink* link) { delete link; } +}; +#else +/// @todo make this thread-safe (lock when accessign batch allocator) +class DefaultValueMapAllocator : public ValueMapAllocator { +public: // overridden from ValueMapAllocator + virtual ValueInternalMap* newMap() { + ValueInternalMap* map = mapsAllocator_.allocate(); + new (map) ValueInternalMap(); // placement new + return map; + } + + virtual ValueInternalMap* newMapCopy(const ValueInternalMap& other) { + ValueInternalMap* map = mapsAllocator_.allocate(); + new (map) ValueInternalMap(other); // placement new + return map; + } + + virtual void destructMap(ValueInternalMap* map) { + if (map) { + map->~ValueInternalMap(); + mapsAllocator_.release(map); + } + } + + virtual ValueInternalLink* allocateMapBuckets(unsigned int size) { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets(ValueInternalLink* links) { delete[] links; } + + virtual ValueInternalLink* allocateMapLink() { + ValueInternalLink* link = linksAllocator_.allocate(); + memset(link, 0, sizeof(ValueInternalLink)); + return link; + } + + virtual void releaseMapLink(ValueInternalLink* link) { + link->~ValueInternalLink(); + linksAllocator_.release(link); + } + +private: + BatchAllocator<ValueInternalMap, 1> mapsAllocator_; + BatchAllocator<ValueInternalLink, 1> linksAllocator_; +}; +#endif + +static ValueMapAllocator*& mapAllocator() { + static DefaultValueMapAllocator defaultAllocator; + static ValueMapAllocator* mapAllocator = &defaultAllocator; + return mapAllocator; +} + +static struct DummyMapAllocatorInitializer { + DummyMapAllocatorInitializer() { + mapAllocator(); // ensure mapAllocator() statics are initialized before + // main(). + } +} dummyMapAllocatorInitializer; + +// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32. + +/* +use linked list hash map. +buckets array is a container. +linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124) +value have extra state: valid, available, deleted +*/ + +ValueInternalMap::ValueInternalMap() + : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) {} + +ValueInternalMap::ValueInternalMap(const ValueInternalMap& other) + : buckets_(0), tailLink_(0), bucketsSize_(0), itemCount_(0) { + reserve(other.itemCount_); + IteratorState it; + IteratorState itEnd; + other.makeBeginIterator(it); + other.makeEndIterator(itEnd); + for (; !equals(it, itEnd); increment(it)) { + bool isStatic; + const char* memberName = key(it, isStatic); + const Value& aValue = value(it); + resolveReference(memberName, isStatic) = aValue; + } +} + +ValueInternalMap& ValueInternalMap::operator=(ValueInternalMap other) { + swap(other); + return *this; +} + +ValueInternalMap::~ValueInternalMap() { + if (buckets_) { + for (BucketIndex bucketIndex = 0; bucketIndex < bucketsSize_; + ++bucketIndex) { + ValueInternalLink* link = buckets_[bucketIndex].next_; + while (link) { + ValueInternalLink* linkToRelease = link; + link = link->next_; + mapAllocator()->releaseMapLink(linkToRelease); + } + } + mapAllocator()->releaseMapBuckets(buckets_); + } +} + +void ValueInternalMap::swap(ValueInternalMap& other) { + ValueInternalLink* tempBuckets = buckets_; + buckets_ = other.buckets_; + other.buckets_ = tempBuckets; + ValueInternalLink* tempTailLink = tailLink_; + tailLink_ = other.tailLink_; + other.tailLink_ = tempTailLink; + BucketIndex tempBucketsSize = bucketsSize_; + bucketsSize_ = other.bucketsSize_; + other.bucketsSize_ = tempBucketsSize; + BucketIndex tempItemCount = itemCount_; + itemCount_ = other.itemCount_; + other.itemCount_ = tempItemCount; +} + +void ValueInternalMap::clear() { + ValueInternalMap dummy; + swap(dummy); +} + +ValueInternalMap::BucketIndex ValueInternalMap::size() const { + return itemCount_; +} + +bool ValueInternalMap::reserveDelta(BucketIndex growth) { + return reserve(itemCount_ + growth); +} + +bool ValueInternalMap::reserve(BucketIndex newItemCount) { + if (!buckets_ && newItemCount > 0) { + buckets_ = mapAllocator()->allocateMapBuckets(1); + bucketsSize_ = 1; + tailLink_ = &buckets_[0]; + } + // BucketIndex idealBucketCount = (newItemCount + + // ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink; + return true; +} + +const Value* ValueInternalMap::find(const char* key) const { + if (!bucketsSize_) + return 0; + HashKey hashedKey = hash(key); + BucketIndex bucketIndex = hashedKey % bucketsSize_; + for (const ValueInternalLink* current = &buckets_[bucketIndex]; current != 0; + current = current->next_) { + for (BucketIndex index = 0; index < ValueInternalLink::itemPerLink; + ++index) { + if (current->items_[index].isItemAvailable()) + return 0; + if (strcmp(key, current->keys_[index]) == 0) + return ¤t->items_[index]; + } + } + return 0; +} + +Value* ValueInternalMap::find(const char* key) { + const ValueInternalMap* constThis = this; + return const_cast<Value*>(constThis->find(key)); +} + +Value& ValueInternalMap::resolveReference(const char* key, bool isStatic) { + HashKey hashedKey = hash(key); + if (bucketsSize_) { + BucketIndex bucketIndex = hashedKey % bucketsSize_; + ValueInternalLink** previous = 0; + BucketIndex index; + for (ValueInternalLink* current = &buckets_[bucketIndex]; current != 0; + previous = ¤t->next_, current = current->next_) { + for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { + if (current->items_[index].isItemAvailable()) + return setNewItem(key, isStatic, current, index); + if (strcmp(key, current->keys_[index]) == 0) + return current->items_[index]; + } + } + } + + reserveDelta(1); + return unsafeAdd(key, isStatic, hashedKey); +} + +void ValueInternalMap::remove(const char* key) { + HashKey hashedKey = hash(key); + if (!bucketsSize_) + return; + BucketIndex bucketIndex = hashedKey % bucketsSize_; + for (ValueInternalLink* link = &buckets_[bucketIndex]; link != 0; + link = link->next_) { + BucketIndex index; + for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { + if (link->items_[index].isItemAvailable()) + return; + if (strcmp(key, link->keys_[index]) == 0) { + doActualRemove(link, index, bucketIndex); + return; + } + } + } +} + +void ValueInternalMap::doActualRemove(ValueInternalLink* link, + BucketIndex index, + BucketIndex bucketIndex) { + // find last item of the bucket and swap it with the 'removed' one. + // set removed items flags to 'available'. + // if last page only contains 'available' items, then desallocate it (it's + // empty) + ValueInternalLink*& lastLink = getLastLinkInBucket(index); + BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1 + for (; lastItemIndex < ValueInternalLink::itemPerLink; + ++lastItemIndex) // may be optimized with dicotomic search + { + if (lastLink->items_[lastItemIndex].isItemAvailable()) + break; + } + + BucketIndex lastUsedIndex = lastItemIndex - 1; + Value* valueToDelete = &link->items_[index]; + Value* valueToPreserve = &lastLink->items_[lastUsedIndex]; + if (valueToDelete != valueToPreserve) + valueToDelete->swap(*valueToPreserve); + if (lastUsedIndex == 0) // page is now empty + { // remove it from bucket linked list and delete it. + ValueInternalLink* linkPreviousToLast = lastLink->previous_; + if (linkPreviousToLast != 0) // can not deleted bucket link. + { + mapAllocator()->releaseMapLink(lastLink); + linkPreviousToLast->next_ = 0; + lastLink = linkPreviousToLast; + } + } else { + Value dummy; + valueToPreserve->swap(dummy); // restore deleted to default Value. + valueToPreserve->setItemUsed(false); + } + --itemCount_; +} + +ValueInternalLink*& +ValueInternalMap::getLastLinkInBucket(BucketIndex bucketIndex) { + if (bucketIndex == bucketsSize_ - 1) + return tailLink_; + ValueInternalLink*& previous = buckets_[bucketIndex + 1].previous_; + if (!previous) + previous = &buckets_[bucketIndex]; + return previous; +} + +Value& ValueInternalMap::setNewItem(const char* key, + bool isStatic, + ValueInternalLink* link, + BucketIndex index) { + char* duplicatedKey = makeMemberName(key); + ++itemCount_; + link->keys_[index] = duplicatedKey; + link->items_[index].setItemUsed(); + link->items_[index].setMemberNameIsStatic(isStatic); + return link->items_[index]; // items already default constructed. +} + +Value& +ValueInternalMap::unsafeAdd(const char* key, bool isStatic, HashKey hashedKey) { + JSON_ASSERT_MESSAGE(bucketsSize_ > 0, + "ValueInternalMap::unsafeAdd(): internal logic error."); + BucketIndex bucketIndex = hashedKey % bucketsSize_; + ValueInternalLink*& previousLink = getLastLinkInBucket(bucketIndex); + ValueInternalLink* link = previousLink; + BucketIndex index; + for (index = 0; index < ValueInternalLink::itemPerLink; ++index) { + if (link->items_[index].isItemAvailable()) + break; + } + if (index == ValueInternalLink::itemPerLink) // need to add a new page + { + ValueInternalLink* newLink = mapAllocator()->allocateMapLink(); + index = 0; + link->next_ = newLink; + previousLink = newLink; + link = newLink; + } + return setNewItem(key, isStatic, link, index); +} + +ValueInternalMap::HashKey ValueInternalMap::hash(const char* key) const { + HashKey hash = 0; + while (*key) + hash += *key++ * 37; + return hash; +} + +int ValueInternalMap::compare(const ValueInternalMap& other) const { + int sizeDiff(itemCount_ - other.itemCount_); + if (sizeDiff != 0) + return sizeDiff; + // Strict order guaranty is required. Compare all keys FIRST, then compare + // values. + IteratorState it; + IteratorState itEnd; + makeBeginIterator(it); + makeEndIterator(itEnd); + for (; !equals(it, itEnd); increment(it)) { + if (!other.find(key(it))) + return 1; + } + + // All keys are equals, let's compare values + makeBeginIterator(it); + for (; !equals(it, itEnd); increment(it)) { + const Value* otherValue = other.find(key(it)); + int valueDiff = value(it).compare(*otherValue); + if (valueDiff != 0) + return valueDiff; + } + return 0; +} + +void ValueInternalMap::makeBeginIterator(IteratorState& it) const { + it.map_ = const_cast<ValueInternalMap*>(this); + it.bucketIndex_ = 0; + it.itemIndex_ = 0; + it.link_ = buckets_; +} + +void ValueInternalMap::makeEndIterator(IteratorState& it) const { + it.map_ = const_cast<ValueInternalMap*>(this); + it.bucketIndex_ = bucketsSize_; + it.itemIndex_ = 0; + it.link_ = 0; +} + +bool ValueInternalMap::equals(const IteratorState& x, + const IteratorState& other) { + return x.map_ == other.map_ && x.bucketIndex_ == other.bucketIndex_ && + x.link_ == other.link_ && x.itemIndex_ == other.itemIndex_; +} + +void ValueInternalMap::incrementBucket(IteratorState& iterator) { + ++iterator.bucketIndex_; + JSON_ASSERT_MESSAGE( + iterator.bucketIndex_ <= iterator.map_->bucketsSize_, + "ValueInternalMap::increment(): attempting to iterate beyond end."); + if (iterator.bucketIndex_ == iterator.map_->bucketsSize_) + iterator.link_ = 0; + else + iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]); + iterator.itemIndex_ = 0; +} + +void ValueInternalMap::increment(IteratorState& iterator) { + JSON_ASSERT_MESSAGE(iterator.map_, + "Attempting to iterator using invalid iterator."); + ++iterator.itemIndex_; + if (iterator.itemIndex_ == ValueInternalLink::itemPerLink) { + JSON_ASSERT_MESSAGE( + iterator.link_ != 0, + "ValueInternalMap::increment(): attempting to iterate beyond end."); + iterator.link_ = iterator.link_->next_; + if (iterator.link_ == 0) + incrementBucket(iterator); + } else if (iterator.link_->items_[iterator.itemIndex_].isItemAvailable()) { + incrementBucket(iterator); + } +} + +void ValueInternalMap::decrement(IteratorState& iterator) { + if (iterator.itemIndex_ == 0) { + JSON_ASSERT_MESSAGE(iterator.map_, + "Attempting to iterate using invalid iterator."); + if (iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_]) { + JSON_ASSERT_MESSAGE(iterator.bucketIndex_ > 0, + "Attempting to iterate beyond beginning."); + --(iterator.bucketIndex_); + } + iterator.link_ = iterator.link_->previous_; + iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1; + } +} + +const char* ValueInternalMap::key(const IteratorState& iterator) { + JSON_ASSERT_MESSAGE(iterator.link_, + "Attempting to iterate using invalid iterator."); + return iterator.link_->keys_[iterator.itemIndex_]; +} + +const char* ValueInternalMap::key(const IteratorState& iterator, + bool& isStatic) { + JSON_ASSERT_MESSAGE(iterator.link_, + "Attempting to iterate using invalid iterator."); + isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic(); + return iterator.link_->keys_[iterator.itemIndex_]; +} + +Value& ValueInternalMap::value(const IteratorState& iterator) { + JSON_ASSERT_MESSAGE(iterator.link_, + "Attempting to iterate using invalid iterator."); + return iterator.link_->items_[iterator.itemIndex_]; +} + +int ValueInternalMap::distance(const IteratorState& x, const IteratorState& y) { + int offset = 0; + IteratorState it = x; + while (!equals(it, y)) + increment(it); + return offset; +} + +} // namespace Json diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp new file mode 100644 index 0000000..41896a7 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp @@ -0,0 +1,885 @@ +// Copyright 2007-2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include <json/assertions.h> +#include <json/reader.h> +#include <json/value.h> +#include "json_tool.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <utility> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <istream> + +#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below +#define snprintf _snprintf +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +namespace Json { + +// Implementation of class Features +// //////////////////////////////// + +Features::Features() + : allowComments_(true), strictRoot_(false), + allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} + +Features Features::all() { return Features(); } + +Features Features::strictMode() { + Features features; + features.allowComments_ = false; + features.strictRoot_ = true; + features.allowDroppedNullPlaceholders_ = false; + features.allowNumericKeys_ = false; + return features; +} + +// Implementation of class Reader +// //////////////////////////////// + +static inline bool in(Reader::Char c, + Reader::Char c1, + Reader::Char c2, + Reader::Char c3, + Reader::Char c4) { + return c == c1 || c == c2 || c == c3 || c == c4; +} + +static inline bool in(Reader::Char c, + Reader::Char c1, + Reader::Char c2, + Reader::Char c3, + Reader::Char c4, + Reader::Char c5) { + return c == c1 || c == c2 || c == c3 || c == c4 || c == c5; +} + +static bool containsNewLine(Reader::Location begin, Reader::Location end) { + for (; begin < end; ++begin) + if (*begin == '\n' || *begin == '\r') + return true; + return false; +} + +// Class Reader +// ////////////////////////////////////////////////////////////////// + +Reader::Reader() + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(Features::all()), + collectComments_() {} + +Reader::Reader(const Features& features) + : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), commentsBefore_(), features_(features), collectComments_() { +} + +bool +Reader::parse(const std::string& document, Value& root, bool collectComments) { + document_ = document; + const char* begin = document_.c_str(); + const char* end = begin + document_.length(); + return parse(begin, end, root, collectComments); +} + +bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { + // std::istream_iterator<char> begin(sin); + // std::istream_iterator<char> end; + // Those would allow streamed input from a file, if parse() were a + // template function. + + // Since std::string is reference-counted, this at least does not + // create an extra copy. + std::string doc; + std::getline(sin, doc, (char)EOF); + return parse(doc, root, collectComments); +} + +bool Reader::parse(const char* beginDoc, + const char* endDoc, + Value& root, + bool collectComments) { + if (!features_.allowComments_) { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_ = ""; + errors_.clear(); + while (!nodes_.empty()) + nodes_.pop(); + nodes_.push(&root); + + bool successful = readValue(); + Token token; + skipCommentTokens(token); + if (collectComments_ && !commentsBefore_.empty()) + root.setComment(commentsBefore_, commentAfter); + if (features_.strictRoot_) { + if (!root.isArray() && !root.isObject()) { + // Set error location to start of doc, ideally should be first token found + // in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( + "A valid JSON document must be either an array or an object value.", + token); + return false; + } + } + return successful; +} + +bool Reader::readValue() { + Token token; + skipCommentTokens(token); + bool successful = true; + + if (collectComments_ && !commentsBefore_.empty()) { + // Remove newline characters at the end of the comments + size_t lastNonNewline = commentsBefore_.find_last_not_of("\r\n"); + if (lastNonNewline != std::string::npos) { + commentsBefore_.erase(lastNonNewline + 1); + } else { + commentsBefore_.clear(); + } + + currentValue().setComment(commentsBefore_, commentBefore); + commentsBefore_ = ""; + } + + switch (token.type_) { + case tokenObjectBegin: + successful = readObject(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenArrayBegin: + successful = readArray(token); + currentValue().setOffsetLimit(current_ - begin_); + break; + case tokenNumber: + successful = decodeNumber(token); + break; + case tokenString: + successful = decodeString(token); + break; + case tokenTrue: + currentValue() = true; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + break; + case tokenFalse: + currentValue() = false; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + break; + case tokenNull: + currentValue() = Value(); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + break; + case tokenArraySeparator: + if (features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + currentValue() = Value(); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } + // Else, fall through... + default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return addError("Syntax error: value, object or array expected.", token); + } + + if (collectComments_) { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); + } + + return successful; +} + +void Reader::skipCommentTokens(Token& token) { + if (features_.allowComments_) { + do { + readToken(token); + } while (token.type_ == tokenComment); + } else { + readToken(token); + } +} + +bool Reader::expectToken(TokenType type, Token& token, const char* message) { + readToken(token); + if (token.type_ != type) + return addError(message, token); + return true; +} + +bool Reader::readToken(Token& token) { + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch (c) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if (!ok) + token.type_ = tokenError; + token.end_ = current_; + return true; +} + +void Reader::skipSpaces() { + while (current_ != end_) { + Char c = *current_; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n') + ++current_; + else + break; + } +} + +bool Reader::match(Location pattern, int patternLength) { + if (end_ - current_ < patternLength) + return false; + int index = patternLength; + while (index--) + if (current_[index] != pattern[index]) + return false; + current_ += patternLength; + return true; +} + +bool Reader::readComment() { + Location commentBegin = current_ - 1; + Char c = getNextChar(); + bool successful = false; + if (c == '*') + successful = readCStyleComment(); + else if (c == '/') + successful = readCppStyleComment(); + if (!successful) + return false; + + if (collectComments_) { + CommentPlacement placement = commentBefore; + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, current_)) + placement = commentAfterOnSameLine; + } + + addComment(commentBegin, current_, placement); + } + return true; +} + +void +Reader::addComment(Location begin, Location end, CommentPlacement placement) { + assert(collectComments_); + if (placement == commentAfterOnSameLine) { + assert(lastValue_ != 0); + lastValue_->setComment(std::string(begin, end), placement); + } else { + commentsBefore_ += std::string(begin, end); + } +} + +bool Reader::readCStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '*' && *current_ == '/') + break; + } + return getNextChar() == '/'; +} + +bool Reader::readCppStyleComment() { + while (current_ != end_) { + Char c = getNextChar(); + if (c == '\r' || c == '\n') + break; + } + return true; +} + +void Reader::readNumber() { + while (current_ != end_) { + if (!(*current_ >= '0' && *current_ <= '9') && + !in(*current_, '.', 'e', 'E', '+', '-')) + break; + ++current_; + } +} + +bool Reader::readString() { + Char c = 0; + while (current_ != end_) { + c = getNextChar(); + if (c == '\\') + getNextChar(); + else if (c == '"') + break; + } + return c == '"'; +} + +bool Reader::readObject(Token& tokenStart) { + Token tokenName; + std::string name; + currentValue() = Value(objectValue); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + while (readToken(tokenName)) { + bool initialTokenOk = true; + while (tokenName.type_ == tokenComment && initialTokenOk) + initialTokenOk = readToken(tokenName); + if (!initialTokenOk) + break; + if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + return true; + name = ""; + if (tokenName.type_ == tokenString) { + if (!decodeString(tokenName, name)) + return recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + Value numberName; + if (!decodeNumber(tokenName, numberName)) + return recoverFromError(tokenObjectEnd); + name = numberName.asString(); + } else { + break; + } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover( + "Missing ':' after object member name", colon, tokenObjectEnd); + } + Value& value = currentValue()[name]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenObjectEnd); + + Token comma; + if (!readToken(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment)) { + return addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + } + bool finalizeTokenOk = true; + while (comma.type_ == tokenComment && finalizeTokenOk) + finalizeTokenOk = readToken(comma); + if (comma.type_ == tokenObjectEnd) + return true; + } + return addErrorAndRecover( + "Missing '}' or object member name", tokenName, tokenObjectEnd); +} + +bool Reader::readArray(Token& tokenStart) { + currentValue() = Value(arrayValue); + currentValue().setOffsetStart(tokenStart.start_ - begin_); + skipSpaces(); + if (*current_ == ']') // empty array + { + Token endArray; + readToken(endArray); + return true; + } + int index = 0; + for (;;) { + Value& value = currentValue()[index++]; + nodes_.push(&value); + bool ok = readValue(); + nodes_.pop(); + if (!ok) // error already set + return recoverFromError(tokenArrayEnd); + + Token token; + // Accept Comment after last item in the array. + ok = readToken(token); + while (token.type_ == tokenComment && ok) { + ok = readToken(token); + } + bool badTokenType = + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + if (!ok || badTokenType) { + return addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + } + if (token.type_ == tokenArrayEnd) + break; + } + return true; +} + +bool Reader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeNumber(Token& token, Value& decoded) { + bool isDouble = false; + for (Location inspect = token.start_; inspect != token.end_; ++inspect) { + isDouble = isDouble || in(*inspect, '.', 'e', 'E', '+') || + (*inspect == '-' && inspect != token.start_); + } + if (isDouble) + return decodeDouble(token, decoded); + // Attempts to parse the number as an integer. If the number is + // larger than the maximum supported value of an integer then + // we decode the number as a double. + Location current = token.start_; + bool isNegative = *current == '-'; + if (isNegative) + ++current; + Value::LargestUInt maxIntegerValue = + isNegative ? Value::LargestUInt(-Value::minLargestInt) + : Value::maxLargestUInt; + Value::LargestUInt threshold = maxIntegerValue / 10; + Value::LargestUInt value = 0; + while (current < token.end_) { + Char c = *current++; + if (c < '0' || c > '9') + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + Value::UInt digit(c - '0'); + if (value >= threshold) { + // We've hit or exceeded the max value divided by 10 (rounded down). If + // a) we've only just touched the limit, b) this is the last digit, and + // c) it's small enough to fit in that rounding delta, we're okay. + // Otherwise treat this number as a double to avoid overflow. + if (value > threshold || current != token.end_ || + digit > maxIntegerValue % 10) { + return decodeDouble(token, decoded); + } + } + value = value * 10 + digit; + } + if (isNegative) + decoded = -Value::LargestInt(value); + else if (value <= Value::LargestUInt(Value::maxInt)) + decoded = Value::LargestInt(value); + else + decoded = value; + return true; +} + +bool Reader::decodeDouble(Token& token) { + Value decoded; + if (!decodeDouble(token, decoded)) + return false; + currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeDouble(Token& token, Value& decoded) { + double value = 0; + const int bufferSize = 32; + int count; + int length = int(token.end_ - token.start_); + + // Sanity check to avoid buffer overflow exploits. + if (length < 0) { + return addError("Unable to parse token length", token); + } + + // Avoid using a string constant for the format control string given to + // sscanf, as this can cause hard to debug crashes on OS X. See here for more + // info: + // + // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html + char format[] = "%lf"; + + if (length <= bufferSize) { + Char buffer[bufferSize + 1]; + memcpy(buffer, token.start_, length); + buffer[length] = 0; + count = sscanf(buffer, format, &value); + } else { + std::string buffer(token.start_, token.end_); + count = sscanf(buffer.c_str(), format, &value); + } + + if (count != 1) + return addError("'" + std::string(token.start_, token.end_) + + "' is not a number.", + token); + decoded = value; + return true; +} + +bool Reader::decodeString(Token& token) { + std::string decoded; + if (!decodeString(token, decoded)) + return false; + currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + +bool Reader::decodeString(Token& token, std::string& decoded) { + decoded.reserve(token.end_ - token.start_ - 2); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while (current != end) { + Char c = *current++; + if (c == '"') + break; + else if (c == '\\') { + if (current == end) + return addError("Empty escape sequence in string", token, current); + Char escape = *current++; + switch (escape) { + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return addError("Bad escape sequence in string", token, current); + } + } else { + decoded += c; + } + } + return true; +} + +bool Reader::decodeUnicodeCodePoint(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + + if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) { + // surrogate pairs + if (end - current < 6) + return addError( + "additional six characters expected to parse unicode surrogate pair.", + token, + current); + unsigned int surrogatePair; + if (*(current++) == '\\' && *(current++) == 'u') { + if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } else + return false; + } else + return addError("expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, + current); + } + return true; +} + +bool Reader::decodeUnicodeEscapeSequence(Token& token, + Location& current, + Location end, + unsigned int& unicode) { + if (end - current < 4) + return addError( + "Bad unicode escape sequence in string: four digits expected.", + token, + current); + unicode = 0; + for (int index = 0; index < 4; ++index) { + Char c = *current++; + unicode *= 16; + if (c >= '0' && c <= '9') + unicode += c - '0'; + else if (c >= 'a' && c <= 'f') + unicode += c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + unicode += c - 'A' + 10; + else + return addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, + current); + } + return true; +} + +bool +Reader::addError(const std::string& message, Token& token, Location extra) { + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back(info); + return false; +} + +bool Reader::recoverFromError(TokenType skipUntilToken) { + int errorCount = int(errors_.size()); + Token skip; + for (;;) { + if (!readToken(skip)) + errors_.resize(errorCount); // discard errors caused by recovery + if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) + break; + } + errors_.resize(errorCount); + return false; +} + +bool Reader::addErrorAndRecover(const std::string& message, + Token& token, + TokenType skipUntilToken) { + addError(message, token); + return recoverFromError(skipUntilToken); +} + +Value& Reader::currentValue() { return *(nodes_.top()); } + +Reader::Char Reader::getNextChar() { + if (current_ == end_) + return 0; + return *current_++; +} + +void Reader::getLocationLineAndColumn(Location location, + int& line, + int& column) const { + Location current = begin_; + Location lastLineStart = current; + line = 0; + while (current < location && current != end_) { + Char c = *current++; + if (c == '\r') { + if (*current == '\n') + ++current; + lastLineStart = current; + ++line; + } else if (c == '\n') { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + +std::string Reader::getLocationLineAndColumn(Location location) const { + int line, column; + getLocationLineAndColumn(location, line, column); + char buffer[18 + 16 + 16 + 1]; +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) +#if defined(WINCE) + _snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#else + sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif +#else + snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif + return buffer; +} + +// Deprecated. Preserved for backward compatibility +std::string Reader::getFormatedErrorMessages() const { + return getFormattedErrorMessages(); +} + +std::string Reader::getFormattedErrorMessages() const { + std::string formattedMessage; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + formattedMessage += + "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if (error.extra_) + formattedMessage += + "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + } + return formattedMessage; +} + +std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { + std::vector<Reader::StructuredError> allErrors; + for (Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError) { + const ErrorInfo& error = *itError; + Reader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + +bool Reader::pushError(const Value& value, const std::string& message) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = end_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = 0; + errors_.push_back(info); + return true; +} + +bool Reader::pushError(const Value& value, const std::string& message, const Value& extra) { + size_t length = end_ - begin_; + if(value.getOffsetStart() > length + || value.getOffsetLimit() > length + || extra.getOffsetLimit() > length) + return false; + Token token; + token.type_ = tokenError; + token.start_ = begin_ + value.getOffsetStart(); + token.end_ = begin_ + value.getOffsetLimit(); + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = begin_ + extra.getOffsetStart(); + errors_.push_back(info); + return true; +} + +bool Reader::good() const { + return !errors_.size(); +} + +std::istream& operator>>(std::istream& sin, Value& root) { + Json::Reader reader; + bool ok = reader.parse(sin, root, true); + if (!ok) { + fprintf(stderr, + "Error from reader: %s", + reader.getFormattedErrorMessages().c_str()); + + JSON_FAIL_MESSAGE("reader error"); + } + return sin; +} + +} // namespace Json diff --git a/Utilities/cmjsoncpp/src/lib_json/json_tool.h b/Utilities/cmjsoncpp/src/lib_json/json_tool.h new file mode 100644 index 0000000..f9b61c3 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_tool.h @@ -0,0 +1,87 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED +#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED + +/* This header provides common string manipulation support, such as UTF-8, + * portable conversion from/to string... + * + * It is an internal header that must not be exposed. + */ + +namespace Json { + +/// Converts a unicode code-point to UTF-8. +static inline std::string codePointToUTF8(unsigned int cp) { + std::string result; + + // based on description from http://en.wikipedia.org/wiki/UTF-8 + + if (cp <= 0x7f) { + result.resize(1); + result[0] = static_cast<char>(cp); + } else if (cp <= 0x7FF) { + result.resize(2); + result[1] = static_cast<char>(0x80 | (0x3f & cp)); + result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); + } else if (cp <= 0xFFFF) { + result.resize(3); + result[2] = static_cast<char>(0x80 | (0x3f & cp)); + result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6))); + result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12))); + } else if (cp <= 0x10FFFF) { + result.resize(4); + result[3] = static_cast<char>(0x80 | (0x3f & cp)); + result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); + result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); + result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); + } + + return result; +} + +/// Returns true if ch is a control character (in range [0,32[). +static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; } + +enum { + /// Constant that specify the size of the buffer that must be passed to + /// uintToString. + uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1 +}; + +// Defines a char buffer for use with uintToString(). +typedef char UIntToStringBuffer[uintToStringBufferSize]; + +/** Converts an unsigned integer to string. + * @param value Unsigned interger to convert to string + * @param current Input/Output string buffer. + * Must have at least uintToStringBufferSize chars free. + */ +static inline void uintToString(LargestUInt value, char*& current) { + *--current = 0; + do { + *--current = char(value % 10) + '0'; + value /= 10; + } while (value != 0); +} + +/** Change ',' to '.' everywhere in buffer. + * + * We had a sophisticated way, but it did not work in WinCE. + * @see https://github.com/open-source-parsers/jsoncpp/pull/9 + */ +static inline void fixNumericLocale(char* begin, char* end) { + while (begin < end) { + if (*begin == ',') { + *begin = '.'; + } + ++begin; + } +} + +} // namespace Json { + +#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp new file mode 100644 index 0000000..478afe1 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp @@ -0,0 +1,1482 @@ +// Copyright 2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include <json/assertions.h> +#include <json/value.h> +#include <json/writer.h> +#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +#include "json_batchallocator.h" +#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <math.h> +#include <sstream> +#include <utility> +#include <string.h> +#include <assert.h> +#ifdef JSON_USE_CPPTL +#include <cpptl/conststring.h> +#endif +#include <cstddef> // size_t + +#define JSON_ASSERT_UNREACHABLE assert(false) + +namespace Json { + +// This is a walkaround to avoid the static initialization of Value::null. +// kNull must be word-aligned to avoid crashing on ARM. We use an alignment of +// 8 (instead of 4) as a bit of future-proofing. +#if defined(__ARMEL__) +#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +#else +#define ALIGNAS(byte_alignment) +#endif +static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; +const unsigned char& kNullRef = kNull[0]; +const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); + +const Int Value::minInt = Int(~(UInt(-1) / 2)); +const Int Value::maxInt = Int(UInt(-1) / 2); +const UInt Value::maxUInt = UInt(-1); +#if defined(JSON_HAS_INT64) +const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); +const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); +const UInt64 Value::maxUInt64 = UInt64(-1); +// The constant is hard-coded because some compiler have trouble +// converting Value::maxUInt64 to a double correctly (AIX/xlC). +// Assumes that UInt64 is a 64 bits integer. +static const double maxUInt64AsDouble = 18446744073709551615.0; +#endif // defined(JSON_HAS_INT64) +const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); +const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); +const LargestUInt Value::maxLargestUInt = LargestUInt(-1); + +/// Unknown size marker +static const unsigned int unknown = (unsigned)-1; + +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +template <typename T, typename U> +static inline bool InRange(double d, T min, U max) { + return d >= min && d <= max; +} +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +static inline double integerToDouble(Json::UInt64 value) { + return static_cast<double>(Int64(value / 2)) * 2.0 + Int64(value & 1); +} + +template <typename T> static inline double integerToDouble(T value) { + return static_cast<double>(value); +} + +template <typename T, typename U> +static inline bool InRange(double d, T min, U max) { + return d >= integerToDouble(min) && d <= integerToDouble(max); +} +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + +/** Duplicates the specified string value. + * @param value Pointer to the string to duplicate. Must be zero-terminated if + * length is "unknown". + * @param length Length of the value. if equals to unknown, then it will be + * computed using strlen(value). + * @return Pointer on the duplicate instance of string. + */ +static inline char* duplicateStringValue(const char* value, + unsigned int length = unknown) { + if (length == unknown) + length = (unsigned int)strlen(value); + + // Avoid an integer overflow in the call to malloc below by limiting length + // to a sane value. + if (length >= (unsigned)Value::maxInt) + length = Value::maxInt - 1; + + char* newString = static_cast<char*>(malloc(length + 1)); + JSON_ASSERT_MESSAGE(newString != 0, + "in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); + memcpy(newString, value, length); + newString[length] = 0; + return newString; +} + +/** Free the string duplicated by duplicateStringValue(). + */ +static inline void releaseStringValue(char* value) { free(value); } + +} // namespace Json + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ValueInternals... +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +#if !defined(JSON_IS_AMALGAMATION) +#ifdef JSON_VALUE_USE_INTERNAL_MAP +#include "json_internalarray.inl" +#include "json_internalmap.inl" +#endif // JSON_VALUE_USE_INTERNAL_MAP + +#include "json_valueiterator.inl" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CommentInfo +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +Value::CommentInfo::CommentInfo() : comment_(0) {} + +Value::CommentInfo::~CommentInfo() { + if (comment_) + releaseStringValue(comment_); +} + +void Value::CommentInfo::setComment(const char* text) { + if (comment_) + releaseStringValue(comment_); + JSON_ASSERT(text != 0); + JSON_ASSERT_MESSAGE( + text[0] == '\0' || text[0] == '/', + "in Json::Value::setComment(): Comments must start with /"); + // It seems that /**/ style comments are acceptable as well. + comment_ = duplicateStringValue(text); +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CZString +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +#ifndef JSON_VALUE_USE_INTERNAL_MAP + +// Notes: index_ indicates if the string was allocated when +// a string is stored. + +Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {} + +Value::CZString::CZString(const char* cstr, DuplicationPolicy allocate) + : cstr_(allocate == duplicate ? duplicateStringValue(cstr) : cstr), + index_(allocate) {} + +Value::CZString::CZString(const CZString& other) + : cstr_(other.index_ != noDuplication && other.cstr_ != 0 + ? duplicateStringValue(other.cstr_) + : other.cstr_), + index_(other.cstr_ + ? static_cast<ArrayIndex>(other.index_ == noDuplication + ? noDuplication : duplicate) + : other.index_) {} + +Value::CZString::~CZString() { + if (cstr_ && index_ == duplicate) + releaseStringValue(const_cast<char*>(cstr_)); +} + +void Value::CZString::swap(CZString& other) { + std::swap(cstr_, other.cstr_); + std::swap(index_, other.index_); +} + +Value::CZString& Value::CZString::operator=(CZString other) { + swap(other); + return *this; +} + +bool Value::CZString::operator<(const CZString& other) const { + if (cstr_) { + assert(other.cstr_); + return strcmp(cstr_, other.cstr_) < 0; + } + return index_ < other.index_; +} + +bool Value::CZString::operator==(const CZString& other) const { + if (cstr_) { + assert(other.cstr_); + return strcmp(cstr_, other.cstr_) == 0; + } + return index_ == other.index_; +} + +ArrayIndex Value::CZString::index() const { return index_; } + +const char* Value::CZString::c_str() const { return cstr_; } + +bool Value::CZString::isStaticString() const { return index_ == noDuplication; } + +#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::Value +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/*! \internal Default constructor initialization must be equivalent to: + * memset( this, 0, sizeof(Value) ) + * This optimization is used in ValueInternalMap fast allocator. + */ +Value::Value(ValueType type) { + initBasic(type); + switch (type) { + case nullValue: + break; + case intValue: + case uintValue: + value_.int_ = 0; + break; + case realValue: + value_.real_ = 0.0; + break; + case stringValue: + value_.string_ = 0; + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(); + break; +#else + case arrayValue: + value_.array_ = arrayAllocator()->newArray(); + break; + case objectValue: + value_.map_ = mapAllocator()->newMap(); + break; +#endif + case booleanValue: + value_.bool_ = false; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + +Value::Value(Int value) { + initBasic(intValue); + value_.int_ = value; +} + +Value::Value(UInt value) { + initBasic(uintValue); + value_.uint_ = value; +} +#if defined(JSON_HAS_INT64) +Value::Value(Int64 value) { + initBasic(intValue); + value_.int_ = value; +} +Value::Value(UInt64 value) { + initBasic(uintValue); + value_.uint_ = value; +} +#endif // defined(JSON_HAS_INT64) + +Value::Value(double value) { + initBasic(realValue); + value_.real_ = value; +} + +Value::Value(const char* value) { + initBasic(stringValue, true); + value_.string_ = duplicateStringValue(value); +} + +Value::Value(const char* beginValue, const char* endValue) { + initBasic(stringValue, true); + value_.string_ = + duplicateStringValue(beginValue, (unsigned int)(endValue - beginValue)); +} + +Value::Value(const std::string& value) { + initBasic(stringValue, true); + value_.string_ = + duplicateStringValue(value.c_str(), (unsigned int)value.length()); +} + +Value::Value(const StaticString& value) { + initBasic(stringValue); + value_.string_ = const_cast<char*>(value.c_str()); +} + +#ifdef JSON_USE_CPPTL +Value::Value(const CppTL::ConstString& value) { + initBasic(stringValue, true); + value_.string_ = duplicateStringValue(value, value.length()); +} +#endif + +Value::Value(bool value) { + initBasic(booleanValue); + value_.bool_ = value; +} + +Value::Value(const Value& other) + : type_(other.type_), allocated_(false) +#ifdef JSON_VALUE_USE_INTERNAL_MAP + , + itemIsUsed_(0) +#endif + , + comments_(0), start_(other.start_), limit_(other.limit_) { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if (other.value_.string_) { + value_.string_ = duplicateStringValue(other.value_.string_); + allocated_ = true; + } else { + value_.string_ = 0; + allocated_ = false; + } + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(*other.value_.map_); + break; +#else + case arrayValue: + value_.array_ = arrayAllocator()->newArrayCopy(*other.value_.array_); + break; + case objectValue: + value_.map_ = mapAllocator()->newMapCopy(*other.value_.map_); + break; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + if (other.comments_) { + comments_ = new CommentInfo[numberOfCommentPlacement]; + for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { + const CommentInfo& otherComment = other.comments_[comment]; + if (otherComment.comment_) + comments_[comment].setComment(otherComment.comment_); + } + } +} + +Value::~Value() { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if (allocated_) + releaseStringValue(value_.string_); + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + delete value_.map_; + break; +#else + case arrayValue: + arrayAllocator()->destructArray(value_.array_); + break; + case objectValue: + mapAllocator()->destructMap(value_.map_); + break; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + + if (comments_) + delete[] comments_; +} + +Value& Value::operator=(Value other) { + swap(other); + return *this; +} + +void Value::swap(Value& other) { + ValueType temp = type_; + type_ = other.type_; + other.type_ = temp; + std::swap(value_, other.value_); + int temp2 = allocated_; + allocated_ = other.allocated_; + other.allocated_ = temp2; + std::swap(start_, other.start_); + std::swap(limit_, other.limit_); +} + +ValueType Value::type() const { return type_; } + +int Value::compare(const Value& other) const { + if (*this < other) + return -1; + if (*this > other) + return 1; + return 0; +} + +bool Value::operator<(const Value& other) const { + int typeDelta = type_ - other.type_; + if (typeDelta) + return typeDelta < 0 ? true : false; + switch (type_) { + case nullValue: + return false; + case intValue: + return value_.int_ < other.value_.int_; + case uintValue: + return value_.uint_ < other.value_.uint_; + case realValue: + return value_.real_ < other.value_.real_; + case booleanValue: + return value_.bool_ < other.value_.bool_; + case stringValue: + return (value_.string_ == 0 && other.value_.string_) || + (other.value_.string_ && value_.string_ && + strcmp(value_.string_, other.value_.string_) < 0); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: { + int delta = int(value_.map_->size() - other.value_.map_->size()); + if (delta) + return delta < 0; + return (*value_.map_) < (*other.value_.map_); + } +#else + case arrayValue: + return value_.array_->compare(*(other.value_.array_)) < 0; + case objectValue: + return value_.map_->compare(*(other.value_.map_)) < 0; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator<=(const Value& other) const { return !(other < *this); } + +bool Value::operator>=(const Value& other) const { return !(*this < other); } + +bool Value::operator>(const Value& other) const { return other < *this; } + +bool Value::operator==(const Value& other) const { + // if ( type_ != other.type_ ) + // GCC 2.95.3 says: + // attempt to take address of bit-field structure member `Json::Value::type_' + // Beats me, but a temp solves the problem. + int temp = other.type_; + if (type_ != temp) + return false; + switch (type_) { + case nullValue: + return true; + case intValue: + return value_.int_ == other.value_.int_; + case uintValue: + return value_.uint_ == other.value_.uint_; + case realValue: + return value_.real_ == other.value_.real_; + case booleanValue: + return value_.bool_ == other.value_.bool_; + case stringValue: + return (value_.string_ == other.value_.string_) || + (other.value_.string_ && value_.string_ && + strcmp(value_.string_, other.value_.string_) == 0); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + return value_.map_->size() == other.value_.map_->size() && + (*value_.map_) == (*other.value_.map_); +#else + case arrayValue: + return value_.array_->compare(*(other.value_.array_)) == 0; + case objectValue: + return value_.map_->compare(*(other.value_.map_)) == 0; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable +} + +bool Value::operator!=(const Value& other) const { return !(*this == other); } + +const char* Value::asCString() const { + JSON_ASSERT_MESSAGE(type_ == stringValue, + "in Json::Value::asCString(): requires stringValue"); + return value_.string_; +} + +std::string Value::asString() const { + switch (type_) { + case nullValue: + return ""; + case stringValue: + return value_.string_ ? value_.string_ : ""; + case booleanValue: + return value_.bool_ ? "true" : "false"; + case intValue: + return valueToString(value_.int_); + case uintValue: + return valueToString(value_.uint_); + case realValue: + return valueToString(value_.real_); + default: + JSON_FAIL_MESSAGE("Type is not convertible to string"); + } +} + +#ifdef JSON_USE_CPPTL +CppTL::ConstString Value::asConstString() const { + return CppTL::ConstString(asString().c_str()); +} +#endif + +Value::Int Value::asInt() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); + return Int(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); + return Int(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), + "double out of Int range"); + return Int(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int."); +} + +Value::UInt Value::asUInt() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); + return UInt(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); + return UInt(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), + "double out of UInt range"); + return UInt(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt."); +} + +#if defined(JSON_HAS_INT64) + +Value::Int64 Value::asInt64() const { + switch (type_) { + case intValue: + return Int64(value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); + return Int64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), + "double out of Int64 range"); + return Int64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to Int64."); +} + +Value::UInt64 Value::asUInt64() const { + switch (type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); + return UInt64(value_.int_); + case uintValue: + return UInt64(value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), + "double out of UInt64 range"); + return UInt64(value_.real_); + case nullValue: + return 0; + case booleanValue: + return value_.bool_ ? 1 : 0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); +} +#endif // if defined(JSON_HAS_INT64) + +LargestInt Value::asLargestInt() const { +#if defined(JSON_NO_INT64) + return asInt(); +#else + return asInt64(); +#endif +} + +LargestUInt Value::asLargestUInt() const { +#if defined(JSON_NO_INT64) + return asUInt(); +#else + return asUInt64(); +#endif +} + +double Value::asDouble() const { + switch (type_) { + case intValue: + return static_cast<double>(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<double>(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return integerToDouble(value_.uint_); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return value_.real_; + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0 : 0.0; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to double."); +} + +float Value::asFloat() const { + switch (type_) { + case intValue: + return static_cast<float>(value_.int_); + case uintValue: +#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return static_cast<float>(value_.uint_); +#else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + return integerToDouble(value_.uint_); +#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) + case realValue: + return static_cast<float>(value_.real_); + case nullValue: + return 0.0; + case booleanValue: + return value_.bool_ ? 1.0f : 0.0f; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to float."); +} + +bool Value::asBool() const { + switch (type_) { + case booleanValue: + return value_.bool_; + case nullValue: + return false; + case intValue: + return value_.int_ ? true : false; + case uintValue: + return value_.uint_ ? true : false; + case realValue: + return value_.real_ ? true : false; + default: + break; + } + JSON_FAIL_MESSAGE("Value is not convertible to bool."); +} + +bool Value::isConvertibleTo(ValueType other) const { + switch (other) { + case nullValue: + return (isNumeric() && asDouble() == 0.0) || + (type_ == booleanValue && value_.bool_ == false) || + (type_ == stringValue && asString() == "") || + (type_ == arrayValue && value_.map_->size() == 0) || + (type_ == objectValue && value_.map_->size() == 0) || + type_ == nullValue; + case intValue: + return isInt() || + (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || + type_ == booleanValue || type_ == nullValue; + case uintValue: + return isUInt() || + (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || + type_ == booleanValue || type_ == nullValue; + case realValue: + return isNumeric() || type_ == booleanValue || type_ == nullValue; + case booleanValue: + return isNumeric() || type_ == booleanValue || type_ == nullValue; + case stringValue: + return isNumeric() || type_ == booleanValue || type_ == stringValue || + type_ == nullValue; + case arrayValue: + return type_ == arrayValue || type_ == nullValue; + case objectValue: + return type_ == objectValue || type_ == nullValue; + } + JSON_ASSERT_UNREACHABLE; + return false; +} + +/// Number of values in array or object +ArrayIndex Value::size() const { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + case stringValue: + return 0; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: // size of the array is highest index + 1 + if (!value_.map_->empty()) { + ObjectValues::const_iterator itLast = value_.map_->end(); + --itLast; + return (*itLast).first.index() + 1; + } + return 0; + case objectValue: + return ArrayIndex(value_.map_->size()); +#else + case arrayValue: + return Int(value_.array_->size()); + case objectValue: + return Int(value_.map_->size()); +#endif + } + JSON_ASSERT_UNREACHABLE; + return 0; // unreachable; +} + +bool Value::empty() const { + if (isNull() || isArray() || isObject()) + return size() == 0u; + else + return false; +} + +bool Value::operator!() const { return isNull(); } + +void Value::clear() { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || + type_ == objectValue, + "in Json::Value::clear(): requires complex value"); + start_ = 0; + limit_ = 0; + switch (type_) { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_->clear(); + break; +#else + case arrayValue: + value_.array_->clear(); + break; + case objectValue: + value_.map_->clear(); + break; +#endif + default: + break; + } +} + +void Value::resize(ArrayIndex newSize) { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, + "in Json::Value::resize(): requires arrayValue"); + if (type_ == nullValue) + *this = Value(arrayValue); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + ArrayIndex oldSize = size(); + if (newSize == 0) + clear(); + else if (newSize > oldSize) + (*this)[newSize - 1]; + else { + for (ArrayIndex index = newSize; index < oldSize; ++index) { + value_.map_->erase(index); + } + assert(size() == newSize); + } +#else + value_.array_->resize(newSize); +#endif +} + +Value& Value::operator[](ArrayIndex index) { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex): requires arrayValue"); + if (type_ == nullValue) + *this = Value(arrayValue); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString key(index); + ObjectValues::iterator it = value_.map_->lower_bound(key); + if (it != value_.map_->end() && (*it).first == key) + return (*it).second; + + ObjectValues::value_type defaultValue(key, null); + it = value_.map_->insert(it, defaultValue); + return (*it).second; +#else + return value_.array_->resolveReference(index); +#endif +} + +Value& Value::operator[](int index) { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index): index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +const Value& Value::operator[](ArrayIndex index) const { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); + if (type_ == nullValue) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString key(index); + ObjectValues::const_iterator it = value_.map_->find(key); + if (it == value_.map_->end()) + return null; + return (*it).second; +#else + Value* value = value_.array_->find(index); + return value ? *value : null; +#endif +} + +const Value& Value::operator[](int index) const { + JSON_ASSERT_MESSAGE( + index >= 0, + "in Json::Value::operator[](int index) const: index cannot be negative"); + return (*this)[ArrayIndex(index)]; +} + +Value& Value::operator[](const char* key) { + return resolveReference(key, false); +} + +void Value::initBasic(ValueType type, bool allocated) { + type_ = type; + allocated_ = allocated; +#ifdef JSON_VALUE_USE_INTERNAL_MAP + itemIsUsed_ = 0; +#endif + comments_ = 0; + start_ = 0; + limit_ = 0; +} + +Value& Value::resolveReference(const char* key, bool isStatic) { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::resolveReference(): requires objectValue"); + if (type_ == nullValue) + *this = Value(objectValue); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey( + key, isStatic ? CZString::noDuplication : CZString::duplicateOnCopy); + ObjectValues::iterator it = value_.map_->lower_bound(actualKey); + if (it != value_.map_->end() && (*it).first == actualKey) + return (*it).second; + + ObjectValues::value_type defaultValue(actualKey, null); + it = value_.map_->insert(it, defaultValue); + Value& value = (*it).second; + return value; +#else + return value_.map_->resolveReference(key, isStatic); +#endif +} + +Value Value::get(ArrayIndex index, const Value& defaultValue) const { + const Value* value = &((*this)[index]); + return value == &null ? defaultValue : *value; +} + +bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } + +const Value& Value::operator[](const char* key) const { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::operator[](char const*)const: requires objectValue"); + if (type_ == nullValue) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey(key, CZString::noDuplication); + ObjectValues::const_iterator it = value_.map_->find(actualKey); + if (it == value_.map_->end()) + return null; + return (*it).second; +#else + const Value* value = value_.map_->find(key); + return value ? *value : null; +#endif +} + +Value& Value::operator[](const std::string& key) { + return (*this)[key.c_str()]; +} + +const Value& Value::operator[](const std::string& key) const { + return (*this)[key.c_str()]; +} + +Value& Value::operator[](const StaticString& key) { + return resolveReference(key, true); +} + +#ifdef JSON_USE_CPPTL +Value& Value::operator[](const CppTL::ConstString& key) { + return (*this)[key.c_str()]; +} + +const Value& Value::operator[](const CppTL::ConstString& key) const { + return (*this)[key.c_str()]; +} +#endif + +Value& Value::append(const Value& value) { return (*this)[size()] = value; } + +Value Value::get(const char* key, const Value& defaultValue) const { + const Value* value = &((*this)[key]); + return value == &null ? defaultValue : *value; +} + +Value Value::get(const std::string& key, const Value& defaultValue) const { + return get(key.c_str(), defaultValue); +} + +Value Value::removeMember(const char* key) { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + "in Json::Value::removeMember(): requires objectValue"); + if (type_ == nullValue) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey(key, CZString::noDuplication); + ObjectValues::iterator it = value_.map_->find(actualKey); + if (it == value_.map_->end()) + return null; + Value old(it->second); + value_.map_->erase(it); + return old; +#else + Value* value = value_.map_->find(key); + if (value) { + Value old(*value); + value_.map_.remove(key); + return old; + } else { + return null; + } +#endif +} + +Value Value::removeMember(const std::string& key) { + return removeMember(key.c_str()); +} + +#ifdef JSON_USE_CPPTL +Value Value::get(const CppTL::ConstString& key, + const Value& defaultValue) const { + return get(key.c_str(), defaultValue); +} +#endif + +bool Value::isMember(const char* key) const { + const Value* value = &((*this)[key]); + return value != &null; +} + +bool Value::isMember(const std::string& key) const { + return isMember(key.c_str()); +} + +#ifdef JSON_USE_CPPTL +bool Value::isMember(const CppTL::ConstString& key) const { + return isMember(key.c_str()); +} +#endif + +Value::Members Value::getMemberNames() const { + JSON_ASSERT_MESSAGE( + type_ == nullValue || type_ == objectValue, + "in Json::Value::getMemberNames(), value must be objectValue"); + if (type_ == nullValue) + return Value::Members(); + Members members; + members.reserve(value_.map_->size()); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + ObjectValues::const_iterator it = value_.map_->begin(); + ObjectValues::const_iterator itEnd = value_.map_->end(); + for (; it != itEnd; ++it) + members.push_back(std::string((*it).first.c_str())); +#else + ValueInternalMap::IteratorState it; + ValueInternalMap::IteratorState itEnd; + value_.map_->makeBeginIterator(it); + value_.map_->makeEndIterator(itEnd); + for (; !ValueInternalMap::equals(it, itEnd); ValueInternalMap::increment(it)) + members.push_back(std::string(ValueInternalMap::key(it))); +#endif + return members; +} +// +//# ifdef JSON_USE_CPPTL +// EnumMemberNames +// Value::enumMemberNames() const +//{ +// if ( type_ == objectValue ) +// { +// return CppTL::Enum::any( CppTL::Enum::transform( +// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), +// MemberNamesTransform() ) ); +// } +// return EnumMemberNames(); +//} +// +// +// EnumValues +// Value::enumValues() const +//{ +// if ( type_ == objectValue || type_ == arrayValue ) +// return CppTL::Enum::anyValues( *(value_.map_), +// CppTL::Type<const Value &>() ); +// return EnumValues(); +//} +// +//# endif + +static bool IsIntegral(double d) { + double integral_part; + return modf(d, &integral_part) == 0.0; +} + +bool Value::isNull() const { return type_ == nullValue; } + +bool Value::isBool() const { return type_ == booleanValue; } + +bool Value::isInt() const { + switch (type_) { + case intValue: + return value_.int_ >= minInt && value_.int_ <= maxInt; + case uintValue: + return value_.uint_ <= UInt(maxInt); + case realValue: + return value_.real_ >= minInt && value_.real_ <= maxInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isUInt() const { + switch (type_) { + case intValue: + return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); + case uintValue: + return value_.uint_ <= maxUInt; + case realValue: + return value_.real_ >= 0 && value_.real_ <= maxUInt && + IsIntegral(value_.real_); + default: + break; + } + return false; +} + +bool Value::isInt64() const { +#if defined(JSON_HAS_INT64) + switch (type_) { + case intValue: + return true; + case uintValue: + return value_.uint_ <= UInt64(maxInt64); + case realValue: + // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a + // double, so double(maxInt64) will be rounded up to 2^63. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= double(minInt64) && + value_.real_ < double(maxInt64) && IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isUInt64() const { +#if defined(JSON_HAS_INT64) + switch (type_) { + case intValue: + return value_.int_ >= 0; + case uintValue: + return true; + case realValue: + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && + IsIntegral(value_.real_); + default: + break; + } +#endif // JSON_HAS_INT64 + return false; +} + +bool Value::isIntegral() const { +#if defined(JSON_HAS_INT64) + return isInt64() || isUInt64(); +#else + return isInt() || isUInt(); +#endif +} + +bool Value::isDouble() const { return type_ == realValue || isIntegral(); } + +bool Value::isNumeric() const { return isIntegral() || isDouble(); } + +bool Value::isString() const { return type_ == stringValue; } + +bool Value::isArray() const { return type_ == arrayValue; } + +bool Value::isObject() const { return type_ == objectValue; } + +void Value::setComment(const char* comment, CommentPlacement placement) { + if (!comments_) + comments_ = new CommentInfo[numberOfCommentPlacement]; + comments_[placement].setComment(comment); +} + +void Value::setComment(const std::string& comment, CommentPlacement placement) { + setComment(comment.c_str(), placement); +} + +bool Value::hasComment(CommentPlacement placement) const { + return comments_ != 0 && comments_[placement].comment_ != 0; +} + +std::string Value::getComment(CommentPlacement placement) const { + if (hasComment(placement)) + return comments_[placement].comment_; + return ""; +} + +void Value::setOffsetStart(size_t start) { start_ = start; } + +void Value::setOffsetLimit(size_t limit) { limit_ = limit; } + +size_t Value::getOffsetStart() const { return start_; } + +size_t Value::getOffsetLimit() const { return limit_; } + +std::string Value::toStyledString() const { + StyledWriter writer; + return writer.write(*this); +} + +Value::const_iterator Value::begin() const { + switch (type_) { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if (value_.array_) { + ValueInternalArray::IteratorState it; + value_.array_->makeBeginIterator(it); + return const_iterator(it); + } + break; + case objectValue: + if (value_.map_) { + ValueInternalMap::IteratorState it; + value_.map_->makeBeginIterator(it); + return const_iterator(it); + } + break; +#else + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->begin()); + break; +#endif + default: + break; + } + return const_iterator(); +} + +Value::const_iterator Value::end() const { + switch (type_) { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if (value_.array_) { + ValueInternalArray::IteratorState it; + value_.array_->makeEndIterator(it); + return const_iterator(it); + } + break; + case objectValue: + if (value_.map_) { + ValueInternalMap::IteratorState it; + value_.map_->makeEndIterator(it); + return const_iterator(it); + } + break; +#else + case arrayValue: + case objectValue: + if (value_.map_) + return const_iterator(value_.map_->end()); + break; +#endif + default: + break; + } + return const_iterator(); +} + +Value::iterator Value::begin() { + switch (type_) { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if (value_.array_) { + ValueInternalArray::IteratorState it; + value_.array_->makeBeginIterator(it); + return iterator(it); + } + break; + case objectValue: + if (value_.map_) { + ValueInternalMap::IteratorState it; + value_.map_->makeBeginIterator(it); + return iterator(it); + } + break; +#else + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->begin()); + break; +#endif + default: + break; + } + return iterator(); +} + +Value::iterator Value::end() { + switch (type_) { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if (value_.array_) { + ValueInternalArray::IteratorState it; + value_.array_->makeEndIterator(it); + return iterator(it); + } + break; + case objectValue: + if (value_.map_) { + ValueInternalMap::IteratorState it; + value_.map_->makeEndIterator(it); + return iterator(it); + } + break; +#else + case arrayValue: + case objectValue: + if (value_.map_) + return iterator(value_.map_->end()); + break; +#endif + default: + break; + } + return iterator(); +} + +// class PathArgument +// ////////////////////////////////////////////////////////////////// + +PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} + +PathArgument::PathArgument(ArrayIndex index) + : key_(), index_(index), kind_(kindIndex) {} + +PathArgument::PathArgument(const char* key) + : key_(key), index_(), kind_(kindKey) {} + +PathArgument::PathArgument(const std::string& key) + : key_(key.c_str()), index_(), kind_(kindKey) {} + +// class Path +// ////////////////////////////////////////////////////////////////// + +Path::Path(const std::string& path, + const PathArgument& a1, + const PathArgument& a2, + const PathArgument& a3, + const PathArgument& a4, + const PathArgument& a5) { + InArgs in; + in.push_back(&a1); + in.push_back(&a2); + in.push_back(&a3); + in.push_back(&a4); + in.push_back(&a5); + makePath(path, in); +} + +void Path::makePath(const std::string& path, const InArgs& in) { + const char* current = path.c_str(); + const char* end = current + path.length(); + InArgs::const_iterator itInArg = in.begin(); + while (current != end) { + if (*current == '[') { + ++current; + if (*current == '%') + addPathInArg(path, in, itInArg, PathArgument::kindIndex); + else { + ArrayIndex index = 0; + for (; current != end && *current >= '0' && *current <= '9'; ++current) + index = index * 10 + ArrayIndex(*current - '0'); + args_.push_back(index); + } + if (current == end || *current++ != ']') + invalidPath(path, int(current - path.c_str())); + } else if (*current == '%') { + addPathInArg(path, in, itInArg, PathArgument::kindKey); + ++current; + } else if (*current == '.') { + ++current; + } else { + const char* beginName = current; + while (current != end && !strchr("[.", *current)) + ++current; + args_.push_back(std::string(beginName, current)); + } + } +} + +void Path::addPathInArg(const std::string& /*path*/, + const InArgs& in, + InArgs::const_iterator& itInArg, + PathArgument::Kind kind) { + if (itInArg == in.end()) { + // Error: missing argument %d + } else if ((*itInArg)->kind_ != kind) { + // Error: bad argument type + } else { + args_.push_back(**itInArg); + } +} + +void Path::invalidPath(const std::string& /*path*/, int /*location*/) { + // Error: invalid path. +} + +const Value& Path::resolve(const Value& root) const { + const Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) { + // Error: unable to resolve path (array value expected at position... + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: unable to resolve path (object value expected at position...) + } + node = &((*node)[arg.key_]); + if (node == &Value::null) { + // Error: unable to resolve path (object has no member named '' at + // position...) + } + } + } + return *node; +} + +Value Path::resolve(const Value& root, const Value& defaultValue) const { + const Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray() || !node->isValidIndex(arg.index_)) + return defaultValue; + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) + return defaultValue; + node = &((*node)[arg.key_]); + if (node == &Value::null) + return defaultValue; + } + } + return *node; +} + +Value& Path::make(Value& root) const { + Value* node = &root; + for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + const PathArgument& arg = *it; + if (arg.kind_ == PathArgument::kindIndex) { + if (!node->isArray()) { + // Error: node is not an array at position ... + } + node = &((*node)[arg.index_]); + } else if (arg.kind_ == PathArgument::kindKey) { + if (!node->isObject()) { + // Error: node is not an object at position... + } + node = &((*node)[arg.key_]); + } + } + return *node; +} + +} // namespace Json diff --git a/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl b/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl new file mode 100644 index 0000000..a9f7df6 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_valueiterator.inl @@ -0,0 +1,241 @@ +// Copyright 2007-2010 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +// included by json_value.cpp + +namespace Json { + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIteratorBase +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIteratorBase::ValueIteratorBase() +#ifndef JSON_VALUE_USE_INTERNAL_MAP + : current_(), isNull_(true) { +} +#else + : isArray_(true), isNull_(true) { + iterator_.array_ = ValueInternalArray::IteratorState(); +} +#endif + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueIteratorBase::ValueIteratorBase( + const Value::ObjectValues::iterator& current) + : current_(current), isNull_(false) {} +#else +ValueIteratorBase::ValueIteratorBase( + const ValueInternalArray::IteratorState& state) + : isArray_(true) { + iterator_.array_ = state; +} + +ValueIteratorBase::ValueIteratorBase( + const ValueInternalMap::IteratorState& state) + : isArray_(false) { + iterator_.map_ = state; +} +#endif + +Value& ValueIteratorBase::deref() const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + return current_->second; +#else + if (isArray_) + return ValueInternalArray::dereference(iterator_.array_); + return ValueInternalMap::value(iterator_.map_); +#endif +} + +void ValueIteratorBase::increment() { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + ++current_; +#else + if (isArray_) + ValueInternalArray::increment(iterator_.array_); + ValueInternalMap::increment(iterator_.map_); +#endif +} + +void ValueIteratorBase::decrement() { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + --current_; +#else + if (isArray_) + ValueInternalArray::decrement(iterator_.array_); + ValueInternalMap::decrement(iterator_.map_); +#endif +} + +ValueIteratorBase::difference_type +ValueIteratorBase::computeDistance(const SelfType& other) const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP +#ifdef JSON_USE_CPPTL_SMALLMAP + return current_ - other.current_; +#else + // Iterator for null value are initialized using the default + // constructor, which initialize current_ to the default + // std::map::iterator. As begin() and end() are two instance + // of the default std::map::iterator, they can not be compared. + // To allow this, we handle this comparison specifically. + if (isNull_ && other.isNull_) { + return 0; + } + + // Usage of std::distance is not portable (does not compile with Sun Studio 12 + // RogueWave STL, + // which is the one used by default). + // Using a portable hand-made version for non random iterator instead: + // return difference_type( std::distance( current_, other.current_ ) ); + difference_type myDistance = 0; + for (Value::ObjectValues::iterator it = current_; it != other.current_; + ++it) { + ++myDistance; + } + return myDistance; +#endif +#else + if (isArray_) + return ValueInternalArray::distance(iterator_.array_, + other.iterator_.array_); + return ValueInternalMap::distance(iterator_.map_, other.iterator_.map_); +#endif +} + +bool ValueIteratorBase::isEqual(const SelfType& other) const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + if (isNull_) { + return other.isNull_; + } + return current_ == other.current_; +#else + if (isArray_) + return ValueInternalArray::equals(iterator_.array_, other.iterator_.array_); + return ValueInternalMap::equals(iterator_.map_, other.iterator_.map_); +#endif +} + +void ValueIteratorBase::copy(const SelfType& other) { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + current_ = other.current_; + isNull_ = other.isNull_; +#else + if (isArray_) + iterator_.array_ = other.iterator_.array_; + iterator_.map_ = other.iterator_.map_; +#endif +} + +Value ValueIteratorBase::key() const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const Value::CZString czstring = (*current_).first; + if (czstring.c_str()) { + if (czstring.isStaticString()) + return Value(StaticString(czstring.c_str())); + return Value(czstring.c_str()); + } + return Value(czstring.index()); +#else + if (isArray_) + return Value(ValueInternalArray::indexOf(iterator_.array_)); + bool isStatic; + const char* memberName = ValueInternalMap::key(iterator_.map_, isStatic); + if (isStatic) + return Value(StaticString(memberName)); + return Value(memberName); +#endif +} + +UInt ValueIteratorBase::index() const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const Value::CZString czstring = (*current_).first; + if (!czstring.c_str()) + return czstring.index(); + return Value::UInt(-1); +#else + if (isArray_) + return Value::UInt(ValueInternalArray::indexOf(iterator_.array_)); + return Value::UInt(-1); +#endif +} + +const char* ValueIteratorBase::memberName() const { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const char* name = (*current_).first.c_str(); + return name ? name : ""; +#else + if (!isArray_) + return ValueInternalMap::key(iterator_.map_); + return ""; +#endif +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueConstIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueConstIterator::ValueConstIterator() {} + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueConstIterator::ValueConstIterator( + const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} +#else +ValueConstIterator::ValueConstIterator( + const ValueInternalArray::IteratorState& state) + : ValueIteratorBase(state) {} + +ValueConstIterator::ValueConstIterator( + const ValueInternalMap::IteratorState& state) + : ValueIteratorBase(state) {} +#endif + +ValueConstIterator& ValueConstIterator:: +operator=(const ValueIteratorBase& other) { + copy(other); + return *this; +} + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIterator::ValueIterator() {} + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) + : ValueIteratorBase(current) {} +#else +ValueIterator::ValueIterator(const ValueInternalArray::IteratorState& state) + : ValueIteratorBase(state) {} + +ValueIterator::ValueIterator(const ValueInternalMap::IteratorState& state) + : ValueIteratorBase(state) {} +#endif + +ValueIterator::ValueIterator(const ValueConstIterator& other) + : ValueIteratorBase(other) {} + +ValueIterator::ValueIterator(const ValueIterator& other) + : ValueIteratorBase(other) {} + +ValueIterator& ValueIterator::operator=(const SelfType& other) { + copy(other); + return *this; +} + +} // namespace Json diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp new file mode 100644 index 0000000..7f8e6f1 --- /dev/null +++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp @@ -0,0 +1,703 @@ +// Copyright 2011 Baptiste Lepilleur +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#if !defined(JSON_IS_AMALGAMATION) +#include <json/writer.h> +#include "json_tool.h" +#endif // if !defined(JSON_IS_AMALGAMATION) +#include <utility> +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <sstream> +#include <iomanip> +#include <math.h> + +#if defined(_MSC_VER) && _MSC_VER < 1500 // VC++ 8.0 and below +#include <float.h> +#define isfinite _finite +#define snprintf _snprintf +#endif + +// Solaris +#if defined(__sun) +# include <ieeefp.h> +# define isfinite finite +#endif + +// Ancient glibc +#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2 +# if !defined(isfinite) +# define isfinite __finite +# endif +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +// Disable warning about strdup being deprecated. +#pragma warning(disable : 4996) +#endif + +namespace Json { + +static bool containsControlCharacter(const char* str) { + while (*str) { + if (isControlCharacter(*(str++))) + return true; + } + return false; +} + +std::string valueToString(LargestInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + bool isNegative = value < 0; + if (isNegative) + value = -value; + uintToString(LargestUInt(value), current); + if (isNegative) + *--current = '-'; + assert(current >= buffer); + return current; +} + +std::string valueToString(LargestUInt value) { + UIntToStringBuffer buffer; + char* current = buffer + sizeof(buffer); + uintToString(value, current); + assert(current >= buffer); + return current; +} + +#if defined(JSON_HAS_INT64) + +std::string valueToString(Int value) { + return valueToString(LargestInt(value)); +} + +std::string valueToString(UInt value) { + return valueToString(LargestUInt(value)); +} + +#endif // # if defined(JSON_HAS_INT64) + +std::string valueToString(double value) { + // Allocate a buffer that is more than large enough to store the 16 digits of + // precision requested below. + char buffer[32]; + int len = -1; + +// Print into the buffer. We need not request the alternative representation +// that always has a decimal point because JSON doesn't distingish the +// concepts of reals and integers. +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with + // visual studio 2005 to + // avoid warning. +#if defined(WINCE) + len = _snprintf(buffer, sizeof(buffer), "%.16g", value); +#else + len = sprintf_s(buffer, sizeof(buffer), "%.16g", value); +#endif +#else + if (isfinite(value)) { + len = snprintf(buffer, sizeof(buffer), "%.16g", value); + } else { + // IEEE standard states that NaN values will not compare to themselves + if (value != value) { + len = snprintf(buffer, sizeof(buffer), "null"); + } else if (value < 0) { + len = snprintf(buffer, sizeof(buffer), "-1e+9999"); + } else { + len = snprintf(buffer, sizeof(buffer), "1e+9999"); + } + // For those, we do not need to call fixNumLoc, but it is fast. + } +#endif + assert(len >= 0); + fixNumericLocale(buffer, buffer + len); + return buffer; +} + +std::string valueToString(bool value) { return value ? "true" : "false"; } + +std::string valueToQuotedString(const char* value) { + if (value == NULL) + return ""; + // Not sure how to handle unicode... + if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && + !containsControlCharacter(value)) + return std::string("\"") + value + "\""; + // We have to walk value and escape any special characters. + // Appending to std::string is not efficient, but this should be rare. + // (Note: forward slashes are *not* rare, but I am not escaping them.) + std::string::size_type maxsize = + strlen(value) * 2 + 3; // allescaped+quotes+NULL + std::string result; + result.reserve(maxsize); // to avoid lots of mallocs + result += "\""; + for (const char* c = value; *c != 0; ++c) { + switch (*c) { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something. + // blep notes: actually escaping \/ may be useful in javascript to avoid </ + // sequence. + // Should add a flag to allow this compatibility mode and prevent this + // sequence from occurring. + default: + if (isControlCharacter(*c)) { + std::ostringstream oss; + oss << "\\u" << std::hex << std::uppercase << std::setfill('0') + << std::setw(4) << static_cast<int>(*c); + result += oss.str(); + } else { + result += *c; + } + break; + } + } + result += "\""; + return result; +} + +// Class Writer +// ////////////////////////////////////////////////////////////////// +Writer::~Writer() {} + +// Class FastWriter +// ////////////////////////////////////////////////////////////////// + +FastWriter::FastWriter() + : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false), + omitEndingLineFeed_(false) {} + +void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; } + +void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } + +void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } + +std::string FastWriter::write(const Value& root) { + document_ = ""; + writeValue(root); + if (!omitEndingLineFeed_) + document_ += "\n"; + return document_; +} + +void FastWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + if (!dropNullPlaceholders_) + document_ += "null"; + break; + case intValue: + document_ += valueToString(value.asLargestInt()); + break; + case uintValue: + document_ += valueToString(value.asLargestUInt()); + break; + case realValue: + document_ += valueToString(value.asDouble()); + break; + case stringValue: + document_ += valueToQuotedString(value.asCString()); + break; + case booleanValue: + document_ += valueToString(value.asBool()); + break; + case arrayValue: { + document_ += '['; + int size = value.size(); + for (int index = 0; index < size; ++index) { + if (index > 0) + document_ += ','; + writeValue(value[index]); + } + document_ += ']'; + } break; + case objectValue: { + Value::Members members(value.getMemberNames()); + document_ += '{'; + for (Value::Members::iterator it = members.begin(); it != members.end(); + ++it) { + const std::string& name = *it; + if (it != members.begin()) + document_ += ','; + document_ += valueToQuotedString(name.c_str()); + document_ += yamlCompatiblityEnabled_ ? ": " : ":"; + writeValue(value[name]); + } + document_ += '}'; + } break; + } +} + +// Class StyledWriter +// ////////////////////////////////////////////////////////////////// + +StyledWriter::StyledWriter() + : rightMargin_(74), indentSize_(3), addChildValues_() {} + +std::string StyledWriter::write(const Value& root) { + document_ = ""; + addChildValues_ = false; + indentString_ = ""; + writeCommentBeforeValue(root); + writeValue(root); + writeCommentAfterValueOnSameLine(root); + document_ += "\n"; + return document_; +} + +void StyledWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: + pushValue(valueToQuotedString(value.asCString())); + break; + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const std::string& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + document_ += " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + writeIndent(); + writeValue(childValue); + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + document_ += ','; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + document_ += "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + document_ += ", "; + document_ += childValues_[index]; + } + document_ += " ]"; + } + } +} + +bool StyledWriter::isMultineArray(const Value& value) { + int size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (int index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = + isMultiLine || ((childValue.isArray() || childValue.isObject()) && + childValue.size() > 0); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (int index = 0; index < size; ++index) { + writeValue(value[index]); + lineLength += int(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledWriter::pushValue(const std::string& value) { + if (addChildValues_) + childValues_.push_back(value); + else + document_ += value; +} + +void StyledWriter::writeIndent() { + if (!document_.empty()) { + char last = document_[document_.length() - 1]; + if (last == ' ') // already indented + return; + if (last != '\n') // Comments may add new-line + document_ += '\n'; + } + document_ += indentString_; +} + +void StyledWriter::writeWithIndent(const std::string& value) { + writeIndent(); + document_ += value; +} + +void StyledWriter::indent() { indentString_ += std::string(indentSize_, ' '); } + +void StyledWriter::unindent() { + assert(int(indentString_.size()) >= indentSize_); + indentString_.resize(indentString_.size() - indentSize_); +} + +void StyledWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + + document_ += "\n"; + writeIndent(); + std::string normalizedComment = normalizeEOL(root.getComment(commentBefore)); + std::string::const_iterator iter = normalizedComment.begin(); + while (iter != normalizedComment.end()) { + document_ += *iter; + if (*iter == '\n' && *(iter + 1) == '/') + writeIndent(); + ++iter; + } + + // Comments are stripped of newlines, so add one here + document_ += "\n"; +} + +void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + document_ += " " + normalizeEOL(root.getComment(commentAfterOnSameLine)); + + if (root.hasComment(commentAfter)) { + document_ += "\n"; + document_ += normalizeEOL(root.getComment(commentAfter)); + document_ += "\n"; + } +} + +bool StyledWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +std::string StyledWriter::normalizeEOL(const std::string& text) { + std::string normalized; + normalized.reserve(text.length()); + const char* begin = text.c_str(); + const char* end = begin + text.length(); + const char* current = begin; + while (current != end) { + char c = *current++; + if (c == '\r') // mac or dos EOL + { + if (*current == '\n') // convert dos EOL + ++current; + normalized += '\n'; + } else // handle unix EOL & other char + normalized += c; + } + return normalized; +} + +// Class StyledStreamWriter +// ////////////////////////////////////////////////////////////////// + +StyledStreamWriter::StyledStreamWriter(std::string indentation) + : document_(NULL), rightMargin_(74), indentation_(indentation), + addChildValues_() {} + +void StyledStreamWriter::write(std::ostream& out, const Value& root) { + document_ = &out; + addChildValues_ = false; + indentString_ = ""; + writeCommentBeforeValue(root); + writeValue(root); + writeCommentAfterValueOnSameLine(root); + *document_ << "\n"; + document_ = NULL; // Forget the stream, for safety. +} + +void StyledStreamWriter::writeValue(const Value& value) { + switch (value.type()) { + case nullValue: + pushValue("null"); + break; + case intValue: + pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + pushValue(valueToString(value.asDouble())); + break; + case stringValue: + pushValue(valueToQuotedString(value.asCString())); + break; + case booleanValue: + pushValue(valueToString(value.asBool())); + break; + case arrayValue: + writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + pushValue("{}"); + else { + writeWithIndent("{"); + indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const std::string& name = *it; + const Value& childValue = value[name]; + writeCommentBeforeValue(childValue); + writeWithIndent(valueToQuotedString(name.c_str())); + *document_ << " : "; + writeValue(childValue); + if (++it == members.end()) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("}"); + } + } break; + } +} + +void StyledStreamWriter::writeArrayValue(const Value& value) { + unsigned size = value.size(); + if (size == 0) + pushValue("[]"); + else { + bool isArrayMultiLine = isMultineArray(value); + if (isArrayMultiLine) { + writeWithIndent("["); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index = 0; + for (;;) { + const Value& childValue = value[index]; + writeCommentBeforeValue(childValue); + if (hasChildValue) + writeWithIndent(childValues_[index]); + else { + writeIndent(); + writeValue(childValue); + } + if (++index == size) { + writeCommentAfterValueOnSameLine(childValue); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine(childValue); + } + unindent(); + writeWithIndent("]"); + } else // output on a single line + { + assert(childValues_.size() == size); + *document_ << "[ "; + for (unsigned index = 0; index < size; ++index) { + if (index > 0) + *document_ << ", "; + *document_ << childValues_[index]; + } + *document_ << " ]"; + } + } +} + +bool StyledStreamWriter::isMultineArray(const Value& value) { + int size = value.size(); + bool isMultiLine = size * 3 >= rightMargin_; + childValues_.clear(); + for (int index = 0; index < size && !isMultiLine; ++index) { + const Value& childValue = value[index]; + isMultiLine = + isMultiLine || ((childValue.isArray() || childValue.isObject()) && + childValue.size() > 0); + } + if (!isMultiLine) // check if line length > max line length + { + childValues_.reserve(size); + addChildValues_ = true; + int lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' + for (int index = 0; index < size; ++index) { + writeValue(value[index]); + lineLength += int(childValues_[index].length()); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + +void StyledStreamWriter::pushValue(const std::string& value) { + if (addChildValues_) + childValues_.push_back(value); + else + *document_ << value; +} + +void StyledStreamWriter::writeIndent() { + /* + Some comments in this method would have been nice. ;-) + + if ( !document_.empty() ) + { + char last = document_[document_.length()-1]; + if ( last == ' ' ) // already indented + return; + if ( last != '\n' ) // Comments may add new-line + *document_ << '\n'; + } + */ + *document_ << '\n' << indentString_; +} + +void StyledStreamWriter::writeWithIndent(const std::string& value) { + writeIndent(); + *document_ << value; +} + +void StyledStreamWriter::indent() { indentString_ += indentation_; } + +void StyledStreamWriter::unindent() { + assert(indentString_.size() >= indentation_.size()); + indentString_.resize(indentString_.size() - indentation_.size()); +} + +void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { + if (!root.hasComment(commentBefore)) + return; + *document_ << normalizeEOL(root.getComment(commentBefore)); + *document_ << "\n"; +} + +void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) { + if (root.hasComment(commentAfterOnSameLine)) + *document_ << " " + normalizeEOL(root.getComment(commentAfterOnSameLine)); + + if (root.hasComment(commentAfter)) { + *document_ << "\n"; + *document_ << normalizeEOL(root.getComment(commentAfter)); + *document_ << "\n"; + } +} + +bool StyledStreamWriter::hasCommentForValue(const Value& value) { + return value.hasComment(commentBefore) || + value.hasComment(commentAfterOnSameLine) || + value.hasComment(commentAfter); +} + +std::string StyledStreamWriter::normalizeEOL(const std::string& text) { + std::string normalized; + normalized.reserve(text.length()); + const char* begin = text.c_str(); + const char* end = begin + text.length(); + const char* current = begin; + while (current != end) { + char c = *current++; + if (c == '\r') // mac or dos EOL + { + if (*current == '\n') // convert dos EOL + ++current; + normalized += '\n'; + } else // handle unix EOL & other char + normalized += c; + } + return normalized; +} + +std::ostream& operator<<(std::ostream& sout, const Value& root) { + Json::StyledStreamWriter writer; + writer.write(sout, root); + return sout; +} + +} // namespace Json diff --git a/Utilities/cmlibarchive/libarchive/archive_getdate.c b/Utilities/cmlibarchive/libarchive/archive_getdate.c index aaa9d6f..f665e2d 100644 --- a/Utilities/cmlibarchive/libarchive/archive_getdate.c +++ b/Utilities/cmlibarchive/libarchive/archive_getdate.c @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #include <time.h> /* This file defines a single public function. */ -time_t __archive_get_date(time_t now, char *); +time_t __archive_get_date(time_t now, const char *); /* Basic time units. */ #define EPOCH 1970 @@ -782,7 +782,7 @@ RelativeMonth(time_t Start, time_t Timezone, time_t RelMonth) * Tokenizer. */ static int -nexttoken(char **in, time_t *value) +nexttoken(const char **in, time_t *value) { char c; char buff[64]; @@ -809,7 +809,7 @@ nexttoken(char **in, time_t *value) /* Try the next token in the word table first. */ /* This allows us to match "2nd", for example. */ { - char *src = *in; + const char *src = *in; const struct LEXICON *tp; unsigned i = 0; @@ -894,7 +894,7 @@ difftm (struct tm *a, struct tm *b) * TODO: tokens[] array should be dynamically sized. */ time_t -__archive_get_date(time_t now, char *p) +__archive_get_date(time_t now, const char *p) { struct token tokens[256]; struct gdstate _gds; diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt index c03147f..d991438 100644 --- a/Utilities/cmliblzma/CMakeLists.txt +++ b/Utilities/cmliblzma/CMakeLists.txt @@ -95,6 +95,7 @@ CHECK_TYPE_SIZE("unsigned short" SIZE_OF_UNSIGNED_SHORT) CHECK_TYPE_SIZE("unsigned" SIZE_OF_UNSIGNED) CHECK_TYPE_SIZE("unsigned long" SIZE_OF_UNSIGNED_LONG) CHECK_TYPE_SIZE("unsigned long long" SIZE_OF_UNSIGNED_LONG_LONG) +CHECK_TYPE_SIZE("size_t" SIZE_OF_SIZE_T) CHECK_TYPE_SIZE("__int64" __INT64) CHECK_TYPE_SIZE("unsigned __int64" UNSIGNED___INT64) diff --git a/Utilities/cmliblzma/common/sysdefs.h b/Utilities/cmliblzma/common/sysdefs.h index c84f01c..a6edea8 100644 --- a/Utilities/cmliblzma/common/sysdefs.h +++ b/Utilities/cmliblzma/common/sysdefs.h @@ -124,9 +124,9 @@ // The code currently assumes that size_t is either 32-bit or 64-bit. #ifndef SIZE_MAX -# if SIZEOF_SIZE_T == 4 +# if SIZE_OF_SIZE_T == 4 # define SIZE_MAX UINT32_MAX -# elif SIZEOF_SIZE_T == 8 +# elif SIZE_OF_SIZE_T == 8 # define SIZE_MAX UINT64_MAX # else # error size_t is not 32-bit or 64-bit diff --git a/Utilities/cmliblzma/config.h.in b/Utilities/cmliblzma/config.h.in index b197f27..017c435 100644 --- a/Utilities/cmliblzma/config.h.in +++ b/Utilities/cmliblzma/config.h.in @@ -29,6 +29,7 @@ @SIZE_OF_UNSIGNED_CODE@ @SIZE_OF_UNSIGNED_LONG_CODE@ @SIZE_OF_UNSIGNED_LONG_LONG_CODE@ +@SIZE_OF_SIZE_T_CODE@ /* * If we lack int64_t, define it to the first of __int64, int, long, and long long @@ -277,9 +278,6 @@ typedef uint64_t uintmax_t; /* Define to 1 if the system has the type `_Bool'. */ #cmakedefine HAVE__BOOL 1 -/* The size of `size_t', as computed by sizeof. */ -#cmakedefine SIZEOF_SIZE_T @SIZEOF_SIZE_T@ - /* Define to 1 if the system supports fast unaligned access to 16-bit and 32-bit integers. */ #define TUKLIB_FAST_UNALIGNED_ACCESS 1 diff --git a/Utilities/cmzlib/CMakeLists.txt b/Utilities/cmzlib/CMakeLists.txt index 66e8be2..0be48f1 100644 --- a/Utilities/cmzlib/CMakeLists.txt +++ b/Utilities/cmzlib/CMakeLists.txt @@ -1,5 +1,13 @@ PROJECT(CMZLIB) +# Disable warnings to avoid changing 3rd party code. +if(CMAKE_C_COMPILER_ID MATCHES + "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") +elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") +endif() + INCLUDE_DIRECTORIES( "${CMZLIB_SOURCE_DIR}" "${CMZLIB_SOURCE_DIR}/.." @@ -122,17 +122,32 @@ else cmake_system_openvms=false fi +# Determine whether this is HP-UX +if echo "${cmake_system}" | grep HP-UX >/dev/null 2>&1; then + cmake_system_hpux=true +else + cmake_system_hpux=false +fi + # Determine whether this is Linux if echo "${cmake_system}" | grep Linux >/dev/null 2>&1; then cmake_system_linux=true - # find out if it is a HP PA-RISC machine +else + cmake_system_linux=false + fi + +# Determine whether this is a PA-RISC machine +# This only works for Linux or HP-UX, not other PA-RISC OSs (BSD maybe?). Also +# may falsely detect parisc on HP-UX m68k +cmake_machine_parisc=false +if ${cmake_system_linux}; then if uname -m | grep parisc >/dev/null 2>&1; then cmake_machine_parisc=true - else - cmake_machine_parisc=false fi -else - cmake_system_linux=false +elif ${cmake_system_hpux}; then + if uname -m | grep ia64 >/dev/null 2>&1; then : ; else + cmake_machine_parisc=true + fi fi # Choose the generator to use for bootstrapping. @@ -225,7 +240,6 @@ CMAKE_UNUSED_SOURCES="\ " CMAKE_CXX_SOURCES="\ - cmStandardIncludes \ cmake \ cmakemain \ cmcmd \ @@ -744,11 +758,13 @@ if ${cmake_system_haiku}; then cmake_ld_flags="${LDFLAGS} -lroot -lbe" fi -if ${cmake_system_linux}; then - # avoid binutils problem with large binaries, e.g. when building CMake in debug mode - # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50230 - if ${cmake_machine_parisc}; then - cmake_ld_flags="${LDFLAGS} -Wl,--unique=.text._*" +# Workaround for short jump tables on PA-RISC +if ${cmake_machine_parisc}; then + if ${cmake_c_compiler_is_gnu}; then + cmake_c_flags="${CFLAGS} -mlong-calls" + fi + if ${cmake_cxx_compiler_is_gnu}; then + cmake_cxx_flags="${CXXFLAGS} -mlong-calls" fi fi @@ -1137,6 +1153,35 @@ if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then cmake_test_flags= fi + +if [ "x${cmake_cxx_compiler_is_gnu}" != "x1" ]; then + # Are we SolarisStudio? + + TMPFILE=`cmake_tmp_file` + echo ' + #if defined(__SUNPRO_CC) + #include <iostream> + int main() { std::cout << "This is SolarisStudio" << std::endl; return 0;} + #endif + ' > ${TMPFILE}.cxx + cmake_cxx_compiler_is_solarisstudio=0 + if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} " "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then + cmake_cxx_compiler_is_solarisstudio=1 + fi + if [ "x${cmake_cxx_compiler_is_solarisstudio}" = "x1" ]; then + echo "${cmake_cxx_compiler} is SolarisStudio compiler" + else + echo "${cmake_cxx_compiler} is not SolarisStudio compiler" + fi + rm -f "${TMPFILE}.cxx" + + if [ "x${cmake_cxx_compiler_is_solarisstudio}" = "x1" ]; then + cmake_cxx_flags="${cmake_cxx_flags} -library=stlport4" + fi +fi + + # Test for kwsys features KWSYS_NAME_IS_KWSYS=0 KWSYS_BUILD_SHARED=0 @@ -1445,35 +1490,6 @@ cmake_compiler_settings_comment="/* cmake_report cmConfigure.h${_tmp} "${cmake_compiler_settings_comment}" -if [ "x$KWSYS_STL_HAVE_STD" = "x1" ]; then - cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_STD_NAMESPACE */" -else - cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_STD_NAMESPACE 1" -fi - -if [ "x$KWSYS_IOS_USE_ANSI" = "x1" ]; then - cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_STREAM_HEADERS */" -else - cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_STREAM_HEADERS 1" -fi - -if [ "x$KWSYS_IOS_USE_SSTREAM" = "x1" ]; then - cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_STRING_STREAM */" -else - cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_STRING_STREAM 1" -fi - -# Test for ansi FOR scope -if cmake_try_run "${cmake_cxx_compiler}" \ - "${cmake_cxx_flags}" \ - "${cmake_source_dir}/Modules/TestForAnsiForScope.cxx" >> cmake_bootstrap.log 2>&1; then - cmake_report cmConfigure.h${_tmp} "/* #undef CMAKE_NO_ANSI_FOR_SCOPE */" - echo "${cmake_cxx_compiler} has ANSI for scoping" -else - cmake_report cmConfigure.h${_tmp} "#define CMAKE_NO_ANSI_FOR_SCOPE 1" - echo "${cmake_cxx_compiler} does not have ANSI for scoping" -fi - # When bootstrapping on MinGW with MSYS we must convert the source # directory to a windows path. if ${cmake_system_mingw}; then |