diff options
901 files changed, 13818 insertions, 6055 deletions
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index 57ed4ca..5600b35 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -87,4 +87,34 @@ if("${CPACK_GENERATOR}" STREQUAL "WIX") if(patch MATCHES "^[0-9]+$" AND patch LESS 65535) set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${patch}") endif() + + set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "http://www.cmake.org") + + set(CPACK_WIX_PROPERTY_ARPCONTACT "@CPACK_PACKAGE_CONTACT@") + + set(CPACK_WIX_PROPERTY_ARPCOMMENTS + "CMake is a cross-platform, open-source build system." + ) + + set(CPACK_WIX_PRODUCT_ICON + "@CMake_SOURCE_DIR@/Utilities/Release/CMakeLogo.ico" + ) + + set_property(INSTALL "@CMAKE_DOC_DIR@/html/index.html" PROPERTY + CPACK_START_MENU_SHORTCUTS "CMake Documentation" + ) + + set_property(INSTALL "cmake.org.html" PROPERTY + CPACK_START_MENU_SHORTCUTS "CMake Web Site" + ) + + set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high") + + set(CPACK_WIX_UI_BANNER + "@CMake_SOURCE_DIR@/Utilities/Release/cpack_wix_ui_banner.jpg" + ) + + set(CPACK_WIX_UI_DIALOG + "@CMake_SOURCE_DIR@/Utilities/Release/cpack_wix_ui_dialog.jpg" + ) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 1250a94..d86ae96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,10 +37,10 @@ if("${CMake_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") endif() # Use most-recent available language dialects with GNU and Clang -if(NOT DEFINED CMAKE_C_STANDARD) +if(NOT DEFINED CMAKE_C_STANDARD AND NOT CMake_NO_C_STANDARD) set(CMAKE_C_STANDARD 11) endif() -if(NOT DEFINED CMAKE_CXX_STANDARD) +if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index f499be1..d716498 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -53,6 +53,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION "CMakeSetupManifest.xml.*manifest authoring warning.*Unrecognized Element" "cc-3968 CC: WARNING File.*" # "implicit" truncation by static_cast "ld: warning: directory not found for option .-(F|L)" + "ld: warning: in .*/libgcc.a, file is not of required architecture" "warning.*This version of Mac OS X is unsupported" "clang.*: warning: argument unused during compilation: .-g" "note: in expansion of macro" # diagnostic context note @@ -62,6 +63,18 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION # Ignore clang's summary warning, assuming prior text has matched some # other warning expression: "[0-9,]+ warnings? generated." + +# scanbuild exceptions + "char_traits.h:.*: warning: Null pointer argument in call to string length function" + "stl_construct.h:.*: warning: Forming reference to null pointer" + ".*stl_uninitialized.h:75:19: warning: Forming reference to null pointer.*" + ".*stl_vector.h:.*: warning: Returning null reference.*" + "warning: Value stored to 'yymsg' is never read" + "warning: Value stored to 'yytoken' is never read" + "index_encoder.c.241.2. warning: Value stored to .out_start. is never read" + "index.c.*warning: Access to field.*results in a dereference of a null pointer.*loaded from variable.*" + "cm_sha2.*warning: Value stored to.*is never read" + "testProcess.*warning: Dereference of null pointer .loaded from variable .invalidAddress.." ) if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode") diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt index 5889e90..9358329 100644 --- a/Help/command/FIND_XXX.txt +++ b/Help/command/FIND_XXX.txt @@ -53,6 +53,10 @@ If NO_DEFAULT_PATH is not specified, the search process is as follows: .. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace:: <prefix>/|XXX_SUBDIR| for each <prefix> in CMAKE_PREFIX_PATH +.. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace:: + <prefix>/|XXX_SUBDIR| for each <prefix>/[s]bin in PATH, and + <entry>/|XXX_SUBDIR| for other entries in PATH + .. |CMAKE_SYSTEM_PREFIX_PATH_XXX_SUBDIR| replace:: <prefix>/|XXX_SUBDIR| for each <prefix> in CMAKE_SYSTEM_PREFIX_PATH diff --git a/Help/command/add_dependencies.rst b/Help/command/add_dependencies.rst index 10997ec..c3583cf 100644 --- a/Help/command/add_dependencies.rst +++ b/Help/command/add_dependencies.rst @@ -7,13 +7,16 @@ Add a dependency between top-level targets. add_dependencies(<target> [<target-dependency>]...) -Make a top-level <target> depend on other top-level targets to ensure -that they build before <target> does. A top-level target is one -created by ADD_EXECUTABLE, ADD_LIBRARY, or ADD_CUSTOM_TARGET. -Dependencies added to an IMPORTED target are followed transitively in -its place since the target itself does not build. +Make a top-level ``<target>`` depend on other top-level targets to +ensure that they build before ``<target>`` does. A top-level target +is one created by one of the :command:`add_executable`, +:command:`add_library`, or :command:`add_custom_target` commands. -See the DEPENDS option of ADD_CUSTOM_TARGET and ADD_CUSTOM_COMMAND for -adding file-level dependencies in custom rules. See the -OBJECT_DEPENDS option in SET_SOURCE_FILES_PROPERTIES to add file-level -dependencies to object files. +Dependencies added to an :ref:`imported target <Imported Targets>` +or an :ref:`interface library <Interface Libraries>` are followed +transitively in its place since the target itself does not build. + +See the ``DEPENDS`` option of :command:`add_custom_target` and +:command:`add_custom_command` commands for adding file-level +dependencies in custom rules. See the :prop_sf:`OBJECT_DEPENDS` +source file property to add file-level dependencies to object files. diff --git a/Help/command/ctest_build.rst b/Help/command/ctest_build.rst index 4a95cdd..e7a54d1 100644 --- a/Help/command/ctest_build.rst +++ b/Help/command/ctest_build.rst @@ -23,6 +23,11 @@ The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. +The QUIET option suppresses any CTest-specific non-error output +that would have been printed to the console otherwise. The summary +of warnings / errors, as well as the output from the native build tool +is unaffected by this option. + If set, the contents of the variable CTEST_BUILD_FLAGS are passed as additional arguments to the underlying build command. This can e.g. be used to trigger a parallel build using the -j option of make. See diff --git a/Help/command/ctest_configure.rst b/Help/command/ctest_configure.rst index 2c4e305..61d9320 100644 --- a/Help/command/ctest_configure.rst +++ b/Help/command/ctest_configure.rst @@ -6,7 +6,7 @@ Configure the project build tree. :: ctest_configure([BUILD build_dir] [SOURCE source_dir] [APPEND] - [OPTIONS options] [RETURN_VALUE res]) + [OPTIONS options] [RETURN_VALUE res] [QUIET]) Configures the given build directory and stores results in Configure.xml. If no BUILD is given, the CTEST_BINARY_DIRECTORY @@ -19,3 +19,7 @@ build tool. The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. + +The QUIET option suppresses any CTest-specific non-error messages +that would have otherwise been printed to the console. Output from +the underlying configure command is not affected. diff --git a/Help/command/ctest_coverage.rst b/Help/command/ctest_coverage.rst index 4c90f9c..bac5c1c 100644 --- a/Help/command/ctest_coverage.rst +++ b/Help/command/ctest_coverage.rst @@ -18,3 +18,8 @@ files labeled with at least one of the labels specified. The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. + +The QUIET option suppresses any CTest-specific non-error output +that would have been printed to the console otherwise. The summary +indicating how many lines of code were covered is unaffected by this +option. diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst index ca47ed0..56a2490 100644 --- a/Help/command/ctest_memcheck.rst +++ b/Help/command/ctest_memcheck.rst @@ -26,3 +26,7 @@ the number of tests to be run in parallel. The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. + +The QUIET option suppresses any CTest-specific non-error messages +that would have otherwise been printed to the console. Output from +the underlying tests are not affected. diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst index d7472db..b5c7b34 100644 --- a/Help/command/ctest_start.rst +++ b/Help/command/ctest_start.rst @@ -5,7 +5,7 @@ Starts the testing for a given model :: - ctest_start(Model [TRACK <track>] [APPEND] [source [binary]]) + ctest_start(Model [TRACK <track>] [APPEND] [source [binary]] [QUIET]) Starts the testing for a given model. The command should be called after the binary directory is initialized. If the 'source' and @@ -14,7 +14,8 @@ after the binary directory is initialized. If the 'source' and If the track is specified, the submissions will go to the specified track. If APPEND is used, the existing TAG is used rather than creating a new one based -on the current time stamp. +on the current time stamp. If QUIET is used, CTest will suppress any +non-error messages that it otherwise would have printed to the console. If the :variable:`CTEST_CHECKOUT_COMMAND` variable (or the :variable:`CTEST_CVS_CHECKOUT` variable) diff --git a/Help/command/ctest_submit.rst b/Help/command/ctest_submit.rst index 2b83ed9..6fa1191 100644 --- a/Help/command/ctest_submit.rst +++ b/Help/command/ctest_submit.rst @@ -9,6 +9,7 @@ Submit results to a dashboard server. [RETRY_COUNT count] [RETRY_DELAY delay] [RETURN_VALUE res] + [QUIET] ) By default all available parts are submitted if no PARTS or FILES are @@ -38,6 +39,9 @@ timed-out submission before attempting to re-submit. The RETRY_COUNT option specifies how many times to retry a timed-out submission. +The QUIET option suppresses all non-error messages that would have +otherwise been printed by this call to ctest_submit(). + Submit to CDash Upload API ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst index 5f28083..ee76e91 100644 --- a/Help/command/ctest_test.rst +++ b/Help/command/ctest_test.rst @@ -31,3 +31,9 @@ tests should all stop running. The APPEND option marks results for append to those previously submitted to a dashboard server since the last ctest_start. Append semantics are defined by the dashboard server in use. + +The QUIET option suppresses any CTest-specific non-error messages +that would have otherwise been printed to the console. Output from +the underlying test command is not affected. Summary info detailing +the percentage of passing tests is also unaffected by the QUIET +option. diff --git a/Help/command/ctest_update.rst b/Help/command/ctest_update.rst index d34e192..01e357b 100644 --- a/Help/command/ctest_update.rst +++ b/Help/command/ctest_update.rst @@ -5,9 +5,14 @@ Update the work tree from version control. :: - ctest_update([SOURCE source] [RETURN_VALUE res]) + ctest_update([SOURCE source] [RETURN_VALUE res] [QUIET]) Updates the given source directory and stores results in Update.xml. If no SOURCE is given, the CTEST_SOURCE_DIRECTORY variable is used. The RETURN_VALUE option specifies a variable in which to store the result, which is the number of files updated or -1 on error. + +If QUIET is specified then CTest will suppress most non-error +messages that it would have otherwise printed to the console. +CTest will still report the new revision of the repository +and any conflicting files that were found. diff --git a/Help/command/ctest_upload.rst b/Help/command/ctest_upload.rst index 9156af5..fcd9fe4 100644 --- a/Help/command/ctest_upload.rst +++ b/Help/command/ctest_upload.rst @@ -5,7 +5,10 @@ Upload files to a dashboard server. :: - ctest_upload(FILES ...) + ctest_upload(FILES ... [QUIET]) Pass a list of files to be sent along with the build results to the dashboard server. + +The QUIET option suppresses any CTest-specific non-error output +that would have been printed to the console otherwise. diff --git a/Help/command/file.rst b/Help/command/file.rst index 73d4cfa..2fe7414 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -92,9 +92,12 @@ store it in a ``<variable>``. :: - file(GLOB <variable> [RELATIVE <path>] [<globbing-expressions>...]) - file(GLOB_RECURSE <variable> [RELATIVE <path>] - [FOLLOW_SYMLINKS] [<globbing-expressions>...]) + file(GLOB <variable> + [LIST_DIRECTORIES true|false] [RELATIVE <path>] + [<globbing-expressions>...]) + file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS] + [LIST_DIRECTORIES true|false] [RELATIVE <path>] + [<globbing-expressions>...]) Generate a list of files that match the ``<globbing-expressions>`` and store it into the ``<variable>``. Globbing expressions are similar to @@ -102,6 +105,9 @@ regular expressions, but much simpler. If ``RELATIVE`` flag is specified, the results will be returned as relative paths to the given path. +By default ``GLOB`` lists directories - directories are omited in result if +``LIST_DIRECTORIES`` is set to false. + .. note:: We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is @@ -119,6 +125,11 @@ matched directory and match the files. Subdirectories that are symlinks are only traversed if ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to ``NEW``. +By default ``GLOB_RECURSE`` omits directories from result list - setting +``LIST_DIRECTORIES`` to true adds directories to result list. +If ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to +``OLD`` then ``LIST_DIRECTORIES`` treats symlinks as directories. + Examples of recursive globbing include:: /dir/*.py - match all python files in /dir and subdirectories diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst index db7e151..be309a5 100644 --- a/Help/command/find_file.rst +++ b/Help/command/find_file.rst @@ -13,7 +13,10 @@ find_file .. |CMAKE_XXX_PATH| replace:: CMAKE_INCLUDE_PATH .. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: PATH and INCLUDE +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in INCLUDE, + <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and + |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, + and the directories in PATH itself. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst index 91342ba..09df688 100644 --- a/Help/command/find_library.rst +++ b/Help/command/find_library.rst @@ -13,7 +13,10 @@ find_library .. |CMAKE_XXX_PATH| replace:: CMAKE_LIBRARY_PATH .. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: PATH and LIB +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in LIB, + <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and + |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, + and the directories in PATH itself. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: <prefix>/lib/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst index 95d49e7..b5a6e37 100644 --- a/Help/command/find_path.rst +++ b/Help/command/find_path.rst @@ -13,7 +13,10 @@ find_path .. |CMAKE_XXX_PATH| replace:: CMAKE_INCLUDE_PATH .. |CMAKE_XXX_MAC_PATH| replace:: CMAKE_FRAMEWORK_PATH -.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: PATH and INCLUDE +.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: Directories in INCLUDE, + <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and + |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR|, + and the directories in PATH itself. .. |CMAKE_SYSTEM_PREFIX_PATH_XXX| replace:: <prefix>/include/<arch> if CMAKE_LIBRARY_ARCHITECTURE is set, and diff --git a/Help/command/function.rst b/Help/command/function.rst index b18e03c..7ffdfee 100644 --- a/Help/command/function.rst +++ b/Help/command/function.rst @@ -1,9 +1,7 @@ function -------- -Start recording a function for later invocation as a command. - -:: +Start recording a function for later invocation as a command:: function(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) @@ -11,21 +9,28 @@ Start recording a function for later invocation as a command. ... endfunction(<name>) -Define a function named <name> that takes arguments named arg1 arg2 -arg3 (...). Commands listed after function, but before the matching -endfunction, are not invoked until the function is invoked. When it -is invoked, the commands recorded in the function are first modified -by replacing formal parameters (${arg1}) with the arguments passed, -and then invoked as normal commands. In addition to referencing the -formal parameters you can reference the variable ARGC which will be -set to the number of arguments passed into the function as well as -ARGV0 ARGV1 ARGV2 ... which will have the actual values of the -arguments passed in. This facilitates creating functions with -optional arguments. Additionally ARGV holds the list of all arguments -given to the function and ARGN holds the list of arguments past the -last expected argument. +Define a function named ``<name>`` that takes arguments named ``arg1``, +``arg2``, ``arg3``, (...). +Commands listed after function, but before the matching +:command:`endfunction()`, are not invoked until the function is invoked. +When it is invoked, the commands recorded in the function are first +modified by replacing formal parameters (``${arg1}``) with the arguments +passed, and then invoked as normal commands. +In addition to referencing the formal parameters you can reference the +``ARGC`` variable which will be set to the number of arguments passed +into the function as well as ``ARGV0``, ``ARGV1``, ``ARGV2``, ... which +will have the actual values of the arguments passed in. +This facilitates creating functions with optional arguments. +Additionally ``ARGV`` holds the list of all arguments given to the +function and ``ARGN`` holds the list of arguments past the last expected +argument. +Referencing to ``ARGV#`` arguments beyond ``ARGC`` have undefined +behavior. Checking that ``ARGC`` is greater than ``#`` is the only way +to ensure that ``ARGV#`` was passed to the function as an extra +argument. -A function opens a new scope: see set(var PARENT_SCOPE) for details. +A function opens a new scope: see :command:`set(var PARENT_SCOPE)` for +details. -See the cmake_policy() command documentation for the behavior of -policies inside functions. +See the :command:`cmake_policy()` command documentation for the behavior +of policies inside functions. diff --git a/Help/command/install.rst b/Help/command/install.rst index 5dd5aaa..c99ed73 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -159,6 +159,10 @@ file itself, call ``install(EXPORT)``, documented below. Installing a target with the :prop_tgt:`EXCLUDE_FROM_ALL` target property set to ``TRUE`` has undefined behavior. +The install destination given to the target install ``DESTINATION`` may +use "generator expressions" with the syntax ``$<...>``. See the +:manual:`cmake-generator-expressions(7)` manual for available expressions. + Installing Files ^^^^^^^^^^^^^^^^ diff --git a/Help/command/macro.rst b/Help/command/macro.rst index 258dc50..6bee69c 100644 --- a/Help/command/macro.rst +++ b/Help/command/macro.rst @@ -1,9 +1,7 @@ macro ----- -Start recording a macro for later invocation as a command. - -:: +Start recording a macro for later invocation as a command:: macro(<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) @@ -11,22 +9,28 @@ Start recording a macro for later invocation as a command. ... endmacro(<name>) -Define a macro named <name> that takes arguments named arg1 arg2 arg3 -(...). Commands listed after macro, but before the matching endmacro, -are not invoked until the macro is invoked. When it is invoked, the -commands recorded in the macro are first modified by replacing formal -parameters (``${arg1}``) with the arguments passed, and then invoked as -normal commands. In addition to referencing the formal parameters you -can reference the values ``${ARGC}`` which will be set to the number of -arguments passed into the function as well as ``${ARGV0}`` ``${ARGV1}`` -``${ARGV2}`` ... which will have the actual values of the arguments -passed in. This facilitates creating macros with optional arguments. +Define a macro named ``<name>`` that takes arguments named ``arg1``, +``arg2``, ``arg3``, (...). +Commands listed after macro, but before the matching +:command:`endmacro()`, are not invoked until the macro is invoked. +When it is invoked, the commands recorded in the macro are first +modified by replacing formal parameters (``${arg1}``) with the arguments +passed, and then invoked as normal commands. +In addition to referencing the formal parameters you can reference the +values ``${ARGC}`` which will be set to the number of arguments passed +into the function as well as ``${ARGV0}``, ``${ARGV1}``, ``${ARGV2}``, +... which will have the actual values of the arguments passed in. +This facilitates creating macros with optional arguments. Additionally ``${ARGV}`` holds the list of all arguments given to the macro and ``${ARGN}`` holds the list of arguments past the last expected argument. +Referencing to ``${ARGV#}`` arguments beyond ``${ARGC}`` have undefined +behavior. Checking that ``${ARGC}`` is greater than ``#`` is the only +way to ensure that ``${ARGV#}`` was passed to the function as an extra +argument. -See the cmake_policy() command documentation for the behavior of -policies inside macros. +See the :command:`cmake_policy()` command documentation for the behavior +of policies inside macros. Macro Argument Caveats ^^^^^^^^^^^^^^^^^^^^^^ @@ -37,10 +41,15 @@ replacements much like the C preprocessor would do with a macro. Therefore you will NOT be able to use commands like:: if(ARGV1) # ARGV1 is not a variable + if(DEFINED ARGV2) # ARGV2 is not a variable + if(ARGC GREATER 2) # ARGC is not a variable foreach(loop_var IN LISTS ARGN) # ARGN is not a variable -In the first case you can use ``if(${ARGV1})``, in the second case, you can -use ``foreach(loop_var ${ARGN})`` but this will skip empty arguments. +In the first case, you can use ``if(${ARGV1})``. +In the second and third case, the proper way to check if an optional +variable was passed to the macro is to use ``if(${ARGC} GREATER 2)``. +In the last case, you can use ``foreach(loop_var ${ARGN})`` but this +will skip empty arguments. If you need to include them, you can use:: set(list_var "${ARGN}") diff --git a/Help/command/set.rst b/Help/command/set.rst index 7a59550..d04b880 100644 --- a/Help/command/set.rst +++ b/Help/command/set.rst @@ -1,116 +1,89 @@ set --- -Set a CMake, cache or environment variable to a given value. +Set a normal, cache, or environment variable to a given value. +See the :ref:`cmake-language(7) variables <CMake Language Variables>` +documentation for the scopes and interaction of normal variables +and cache entries. + +Signatures of this command that specify a ``<value>...`` placeholder +expect zero or more arguments. Multiple arguments will be joined as +a :ref:`;-list <CMake Language Lists>` to form the actual variable +value to be set. Zero arguments will cause normal variables to be +unset. See the :command:`unset` command to unset variables explicitly. + +Set Normal Variable +^^^^^^^^^^^^^^^^^^^ :: - set(<variable> <value> - [[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE]) + set(<variable> <value>... [PARENT_SCOPE]) + +Set the given ``<variable>`` in the current function or directory scope. -Within CMake sets <variable> to the value <value>. <value> is -expanded before <variable> is set to it. Normally, set will set a -regular CMake variable. If CACHE is present, then the <variable> is -put in the cache instead, unless it is already in the cache. See -section 'Variable types in CMake' below for details of regular and -cache variables and their interactions. If CACHE is used, <type> and -<docstring> are required. <type> is used by the CMake GUI to choose a -widget with which the user sets a value. The value for <type> may be -one of +If the ``PARENT_SCOPE`` option is given the variable will be set in +the scope above the current scope. Each new directory or function +creates a new scope. This command will set the value of a variable +into the parent directory or calling function (whichever is applicable +to the case at hand). + +Set Cache Entry +^^^^^^^^^^^^^^^ :: - FILEPATH = File chooser dialog. - PATH = Directory chooser dialog. - STRING = Arbitrary string. - BOOL = Boolean ON/OFF checkbox. - INTERNAL = No GUI entry (used for persistent variables). + set(<variable> <value>... CACHE <type> <docstring> [FORCE]) -If <type> is INTERNAL, the cache variable is marked as internal, and -will not be shown to the user in tools like cmake-gui. This is -intended for values that should be persisted in the cache, but which -users should not normally change. INTERNAL implies FORCE. +Set the given cache ``<variable>`` (cache entry). Since cache entries +are meant to provide user-settable values this does not overwrite +existing cache entries by default. Use the ``FORCE`` option to +overwrite existing entries. -Normally, set(...CACHE...) creates cache variables, but does not -modify them. If FORCE is specified, the value of the cache variable -is set, even if the variable is already in the cache. This should -normally be avoided, as it will remove any changes to the cache -variable's value by the user. +The ``<type>`` must be specified as one of: -If PARENT_SCOPE is present, the variable will be set in the scope -above the current scope. Each new directory or function creates a new -scope. This command will set the value of a variable into the parent -directory or calling function (whichever is applicable to the case at -hand). PARENT_SCOPE cannot be combined with CACHE. +``BOOL`` + Boolean ``ON/OFF`` value. :manual:`cmake-gui(1)` offers a checkbox. -If <value> is not specified then the variable is removed instead of -set. See also: the unset() command. +``FILEPATH`` + Path to a file on disk. :manual:`cmake-gui(1)` offers a file dialog. -:: +``PATH`` + Path to a directory on disk. :manual:`cmake-gui(1)` offers a file dialog. - set(<variable> <value1> ... <valueN>) +``STRING`` + A line of text. :manual:`cmake-gui(1)` offers a text field or a + drop-down selection if the :prop_cache:`STRINGS` cache entry + property is set. -In this case <variable> is set to a semicolon separated list of -values. +``INTERNAL`` + A line of text. :manual:`cmake-gui(1)` does not show internal entries. + They may be used to store variables persistently across runs. + Use of this type implies ``FORCE``. -<variable> can be an environment variable such as: +The ``<docstring>`` must be specified as a line of text providing +a quick summary of the option for presentation to :manual:`cmake-gui(1)` +users. + +If the cache entry does not exist prior to the call or the ``FORCE`` +option is given then the cache entry will be set to the given value. +Furthermore, any normal variable binding in the current scope will +be removed to expose the newly cached value to any immediately +following evaluation. + +It is possible for the cache entry to exist prior to the call but +have no type set if it was created on the :manual:`cmake(1)` command +line by a user through the ``-D<var>=<value>`` option without +specifying a type. In this case the ``set`` command will add the +type. Furthermore, if the ``<type>`` is ``PATH`` or ``FILEPATH`` +and the ``<value>`` provided on the command line is a relative path, +then the ``set`` command will treat the path as relative to the +current working directory and convert it to an absolute path. + +Set Environment Variable +^^^^^^^^^^^^^^^^^^^^^^^^ :: - set( ENV{PATH} /home/martink ) - -in which case the environment variable will be set. - -*** Variable types in CMake *** - -In CMake there are two types of variables: normal variables and cache -variables. Normal variables are meant for the internal use of the -script (just like variables in most programming languages); they are -not persisted across CMake runs. Cache variables (unless set with -INTERNAL) are mostly intended for configuration settings where the -first CMake run determines a suitable default value, which the user -can then override, by editing the cache with tools such as ccmake or -cmake-gui. Cache variables are stored in the CMake cache file, and -are persisted across CMake runs. - -Both types can exist at the same time with the same name but different -values. When ${FOO} is evaluated, CMake first looks for a normal -variable 'FOO' in scope and uses it if set. If and only if no normal -variable exists then it falls back to the cache variable 'FOO'. - -Some examples: - -The code 'set(FOO "x")' sets the normal variable 'FOO'. It does not -touch the cache, but it will hide any existing cache value 'FOO'. - -The code 'set(FOO "x" CACHE ...)' checks for 'FOO' in the cache, -ignoring any normal variable of the same name. If 'FOO' is in the -cache then nothing happens to either the normal variable or the cache -variable. If 'FOO' is not in the cache, then it is added to the -cache. - -Finally, whenever a cache variable is added or modified by a command, -CMake also *removes* the normal variable of the same name from the -current scope so that an immediately following evaluation of it will -expose the newly cached value. - -Normally projects should avoid using normal and cache variables of the -same name, as this interaction can be hard to follow. However, in -some situations it can be useful. One example (used by some -projects): - -A project has a subproject in its source tree. The child project has -its own CMakeLists.txt, which is included from the parent -CMakeLists.txt using add_subdirectory(). Now, if the parent and the -child project provide the same option (for example a compiler option), -the parent gets the first chance to add a user-editable option to the -cache. Normally, the child would then use the same value that the -parent uses. However, it may be necessary to hard-code the value for -the child project's option while still allowing the user to edit the -value used by the parent project. The parent project can achieve this -simply by setting a normal variable with the same name as the option -in a scope sufficient to hide the option's cache variable from the -child completely. The parent has already set the cache variable, so -the child's set(...CACHE...) will do nothing, and evaluating the -option variable will use the value from the normal variable, which -hides the cache variable. + set(ENV{<variable>} <value>...) + +Set the current process environment ``<variable>`` to the given value. diff --git a/Help/command/target_compile_definitions.rst b/Help/command/target_compile_definitions.rst index 3c9fe87..8bd3233 100644 --- a/Help/command/target_compile_definitions.rst +++ b/Help/command/target_compile_definitions.rst @@ -9,7 +9,7 @@ Add compile definitions to a target. <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) -Specify compile definitions to use when compiling a given <target. The +Specify compile definitions 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 :ref:`Imported Target <Imported Targets>`. diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst index 3362c5d..73e01e7 100644 --- a/Help/command/target_compile_options.rst +++ b/Help/command/target_compile_options.rst @@ -20,8 +20,8 @@ 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 -:prop_tgt:` target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties. +:prop_dir:`directory <COMPILE_OPTIONS>` and +:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties. The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC`` diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst index 832240a..d6f148d 100644 --- a/Help/command/target_sources.rst +++ b/Help/command/target_sources.rst @@ -22,10 +22,6 @@ 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/Qbs.rst b/Help/generator/Qbs.rst new file mode 100644 index 0000000..e569b77 --- /dev/null +++ b/Help/generator/Qbs.rst @@ -0,0 +1,25 @@ +Qbs +--- + +Generates Qbs project files. + +Project files for Qbs will be created in the top directory and +in every subdirectory which features a CMakeLists.txt file containing +a PROJECT() call. Additionally a hierarchy of makefiles is generated +into the build tree. The appropriate make program can build the +project through the default make target. A "make install" target is +also provided. + +This "extra" generator may be specified as: + +``Qbs - MinGW Makefiles`` + Generate with :generator:`MinGW Makefiles`. + +``Qbs - NMake Makefiles`` + Generate with :generator:`NMake Makefiles`. + +``Qbs - Ninja`` + Generate with :generator:`Ninja`. + +``Qbs - Unix Makefiles`` + Generate with :generator:`Unix Makefiles`. diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt index 363d0aa..986b541 100644 --- a/Help/manual/OPTIONS_BUILD.txt +++ b/Help/manual/OPTIONS_BUILD.txt @@ -10,7 +10,7 @@ containing SET commands that use the CACHE option, not a cache-format file. -``-D <var>:<type>=<value>`` +``-D <var>:<type>=<value>, -D <var>=<value>`` Create a cmake cache entry. When cmake is first run in an empty build tree, it creates a @@ -19,6 +19,14 @@ takes priority over the project's default value. The option may be repeated for as many cache entries as desired. + If the ``:<type>`` portion is given it must be one of the types + specified by the :command:`set` command documentation for its + ``CACHE`` signature. + If the ``:<type>`` portion is omitted the entry will be created + with no type if it does not exist with a type already. If a + command in the project sets the type to ``PATH`` or ``FILEPATH`` + then the ``<value>`` will be converted to an absolute path. + ``-U <globbing_expr>`` Remove matching entries from CMake cache. diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index e18250c..7bffa42 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -28,34 +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. -Template Parameter Defaults ---------------------------- - -On ancient compilers, C++ template must use template parameters in function -arguments. If no parameter of that type is needed, the common workaround is -to add a defaulted pointer to the type to the templated function. However, -this does not work with other ancient compilers: - -.. code-block:: c++ - - template<typename PropertyType> - PropertyType getTypedProperty(cmTarget* tgt, const char* prop, - PropertyType* = 0) // Wrong - { - - } - -.. code-block:: c++ - - template<typename PropertyType> - PropertyType getTypedProperty(cmTarget* tgt, const char* prop, - PropertyType*) // Ok - { - - } - -and invoke it with the value ``0`` explicitly in all cases. - size_t ------ diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c47a7c4..477a132 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -40,10 +40,6 @@ otherwise expands to nothing. Available logical expressions are: -``$<0:...>`` - Empty string (ignores ``...``) -``$<1:...>`` - Content of ``...`` ``$<BOOL:...>`` ``1`` if the ``...`` is true, else ``0`` ``$<AND:?[,?]...>`` @@ -93,6 +89,46 @@ Available logical expressions are: for the 'head' target, an error is reported. See the :manual:`cmake-compile-features(7)` manual for information on compile features. +``$<COMPILE_LANGUAGE:lang>`` + ``1`` when the language used for compilation unit matches ``lang``, + otherwise ``0``. This expression used to specify compile options for + source files of a particular language in a target. For example, to specify + the use of the ``-fno-exceptions`` compile option (compiler id checks + elided): + + .. code-block:: cmake + + add_executable(myapp main.cpp foo.c bar.cpp) + target_compile_options(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions> + ) + + This generator expression has limited use because it is not possible to + use it with the Visual Studio generators. Portable buildsystems would + not use this expression, and would create separate libraries for each + source file language instead: + + .. code-block:: cmake + + add_library(myapp_c foo.c) + add_library(myapp_cxx foo.c) + target_compile_options(myapp_cxx PUBLIC -fno-exceptions) + add_executable(myapp main.cpp) + target_link_libraries(myapp myapp_c myapp_cxx) + + The ``Makefile`` and ``Ninja`` based generators can also use this + expression to specify compile-language specific compile definitions + and include directories: + + .. code-block:: cmake + + add_executable(myapp main.cpp foo.c bar.cpp) + target_compile_definitions(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:COMPILING_CXX> + ) + target_include_directories(myapp + PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers> + ) Informational Expressions ========================= @@ -174,6 +210,10 @@ Available informational expressions are: ``$<INSTALL_PREFIX>`` Content of the install prefix when the target is exported via :command:`install(EXPORT)` and empty otherwise. +``$<COMPILE_LANGUAGE>`` + The compile language of source files when evaluating compile options. See + the unary version for notes about portability of this generator + expression. Output Expressions ================== @@ -197,6 +237,10 @@ where ``${prop}`` refers to a helper variable:: Available output expressions are: +``$<0:...>`` + Empty string (ignores ``...``) +``$<1:...>`` + Content of ``...`` ``$<JOIN:list,...>`` Joins the list with the content of ``...`` ``$<ANGLE-R>`` diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst index bda7eef..804229b 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -85,3 +85,4 @@ The following extra generators are known to CMake. /generator/KDevelop3 /generator/Kate /generator/Sublime Text 2 + /generator/Qbs diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst index 3e0297c..41542c9 100644 --- a/Help/manual/cmake-language.7.rst +++ b/Help/manual/cmake-language.7.rst @@ -485,6 +485,8 @@ The :command:`macro`/:command:`endmacro`, and :command:`function`/:command:`endfunction` commands delimit code blocks to be recorded for later invocation as commands. +.. _`CMake Language Variables`: + Variables ========= @@ -538,6 +540,8 @@ The :manual:`cmake-variables(7)` manual documents many variables that are provided by CMake or have meaning to CMake when set by project code. +.. _`CMake Language Lists`: + Lists ===== diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 965eede..c9219d5 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -22,6 +22,7 @@ All Modules /module/CheckCXXSourceCompiles /module/CheckCXXSourceRuns /module/CheckCXXSymbolExists + /module/CheckFortranCompilerFlag /module/CheckFortranFunctionExists /module/CheckFortranSourceCompiles /module/CheckFunctionExists @@ -211,6 +212,7 @@ All Modules /module/FindWish /module/FindwxWidgets /module/FindwxWindows + /module/FindXCTest /module/FindXercesC /module/FindX11 /module/FindXMLRPC diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 96f39e6..d2960de 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -114,3 +114,6 @@ All Policies /policy/CMP0054 /policy/CMP0055 /policy/CMP0056 + /policy/CMP0057 + /policy/CMP0058 + /policy/CMP0059 diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 25f989f..1dff33e 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -243,6 +243,7 @@ Properties on Targets /prop_tgt/VS_WINRT_REFERENCES /prop_tgt/WIN32_EXECUTABLE /prop_tgt/XCODE_ATTRIBUTE_an-attribute + /prop_tgt/XCTEST Properties on Tests =================== @@ -320,8 +321,11 @@ Properties on Installed Files .. toctree:: :maxdepth: 1 + /prop_inst/CPACK_DESKTOP_SHORTCUTS.rst /prop_inst/CPACK_NEVER_OVERWRITE.rst /prop_inst/CPACK_PERMANENT.rst + /prop_inst/CPACK_START_MENU_SHORTCUTS.rst + /prop_inst/CPACK_STARTUP_SHORTCUTS.rst /prop_inst/CPACK_WIX_ACL.rst diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst index cc132c2..dd3bcfb 100644 --- a/Help/manual/ctest.1.rst +++ b/Help/manual/ctest.1.rst @@ -194,6 +194,11 @@ Options subsequent calls to ctest with the --rerun-failed option will run the set of tests that most recently failed (if any). +``--repeat-until-fail <n>`` + Require each test to run ``<n>`` times without failing in order to pass. + + This is useful in finding sporadic failures in test cases. + ``--max-width <width>`` Set the max width for a test name to output diff --git a/Help/module/CheckFortranCompilerFlag.rst b/Help/module/CheckFortranCompilerFlag.rst new file mode 100644 index 0000000..58bf6ec --- /dev/null +++ b/Help/module/CheckFortranCompilerFlag.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CheckFortranCompilerFlag.cmake diff --git a/Help/module/FindXCTest.rst b/Help/module/FindXCTest.rst new file mode 100644 index 0000000..ff6273c --- /dev/null +++ b/Help/module/FindXCTest.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindXCTest.cmake diff --git a/Help/policy/CMP0057.rst b/Help/policy/CMP0057.rst new file mode 100644 index 0000000..5cf0784 --- /dev/null +++ b/Help/policy/CMP0057.rst @@ -0,0 +1,21 @@ +CMP0057 +------- + +Disallow multiple ``MAIN_DEPENDENCY`` specifications for the same file. + +CMake 3.3 and above no longer allow the same input file to be used +as a ``MAIN_DEPENDENCY`` in more than one custom command. + +Listing the same input file more than once in this context has not been +supported by earlier versions either and would lead to build time issues +but was not diagnosed. + +The ``OLD`` behavior for this policy is to allow using the same input file +in a ``MAIN_DEPENDENCY`` specfication more than once. +The ``NEW`` behavior is to disallow using the same input file in a +``MAIN_DEPENDENCY`` specification more than once. + +This policy was introduced in CMake version 3.3. +CMake version |release| warns when the policy is not set and uses +``OLD`` behavior. Use the :command:`cmake_policy` command to set +it to ``OLD`` or ``NEW`` explicitly. diff --git a/Help/policy/CMP0058.rst b/Help/policy/CMP0058.rst new file mode 100644 index 0000000..0f20383 --- /dev/null +++ b/Help/policy/CMP0058.rst @@ -0,0 +1,108 @@ +CMP0058 +------- + +Ninja requires custom command byproducts to be explicit. + +When an intermediate file generated during the build is consumed +by an expensive operation or a large tree of dependents, one may +reduce the work needed for an incremental rebuild by updating the +file timestamp only when its content changes. With this approach +the generation rule must have a separate output file that is always +updated with a new timestamp that is newer than any dependencies of +the rule so that the build tool re-runs the rule only when the input +changes. We refer to the separate output file as a rule's *witness* +and the generated file as a rule's *byproduct*. + +Byproducts may not be listed as outputs because their timestamps are +allowed to be older than the inputs. No build tools (like ``make``) +that existed when CMake was designed have a way to express byproducts. +Therefore CMake versions prior to 3.2 had no way to specify them. +Projects typically left byproducts undeclared in the rules that +generate them. For example: + +.. code-block:: cmake + + add_custom_command( + OUTPUT witness.txt + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/input.txt + byproduct.txt # timestamp may not change + COMMAND ${CMAKE_COMMAND} -E touch witness.txt + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt + ) + add_custom_target(Provider DEPENDS witness.txt) + add_custom_command( + OUTPUT generated.c + COMMAND expensive-task -i byproduct.txt -o generated.c + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt + ) + add_library(Consumer generated.c) + add_dependencies(Consumer Provider) + +This works well for all generators except :generator:`Ninja`. +The Ninja build tool sees a rule listing ``byproduct.txt`` +as a dependency and no rule listing it as an output. Ninja then +complains that there is no way to satisfy the dependency and +stops building even though there are order-only dependencies +that ensure ``byproduct.txt`` will exist before its consumers +need it. See discussion of this problem in `Ninja Issue 760`_ +for further details on why Ninja works this way. + +.. _`Ninja Issue 760`: https://github.com/martine/ninja/issues/760 + +Instead of leaving byproducts undeclared in the rules that generate +them, Ninja expects byproducts to be listed along with other outputs. +Such rules may be marked with a ``restat`` option that tells Ninja +to check the timestamps of outputs after the rules run. This +prevents byproducts whose timestamps do not change from causing +their dependents to re-build unnecessarily. + +Since the above approach does not tell CMake what custom command +generates ``byproduct.txt``, the Ninja generator does not have +enough information to add the byproduct as an output of any rule. +CMake 2.8.12 and above work around this problem and allow projects +using the above approach to build by generating ``phony`` build +rules to tell Ninja to tolerate such missing files. However, this +workaround prevents Ninja from diagnosing a dependency that is +really missing. It also works poorly in in-source builds where +every custom command dependency, even on source files, needs to +be treated this way because CMake does not have enough information +to know which files are generated as byproducts of custom commands. + +CMake 3.2 introduced the ``BYPRODUCTS`` option to the +:command:`add_custom_command` and :command:`add_custom_target` +commands. This option allows byproducts to be specified explicitly: + +.. code-block:: cmake + + add_custom_command( + OUTPUT witness.txt + BYPRODUCTS byproduct.txt # explicit byproduct specification + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/input.txt + byproduct.txt # timestamp may not change + ... + +The ``BYPRODUCTS`` option is used by the :generator:`Ninja` generator +to list byproducts among the outputs of the custom commands that +generate them, and is ignored by other generators. + +CMake 3.3 and above prefer to require projects to specify custom +command byproducts explicitly so that it can avoid using the +``phony`` rule workaround altogether. Policy ``CMP0058`` was +introduced to provide compatibility with existing projects that +still need the workaround. + +This policy has no effect on generators other than :generator:`Ninja`. +The ``OLD`` behavior for this policy is to generate Ninja ``phony`` +rules for unknown dependencies in the build tree. The ``NEW`` +behavior for this policy is to not generate these and instead +require projects to specify custom command ``BYPRODUCTS`` explicitly. + +This policy was introduced in CMake version 3.3. +CMake version |release| warns when it sees unknown dependencies in +out-of-source build trees if the policy is not set and then uses +``OLD`` behavior. Use the :command:`cmake_policy` command to set +the policy to ``OLD`` or ``NEW`` explicitly. The policy setting +must be in scope at the end of the top-level ``CMakeLists.txt`` +file of the project and has global effect. diff --git a/Help/policy/CMP0059.rst b/Help/policy/CMP0059.rst new file mode 100644 index 0000000..e40f450 --- /dev/null +++ b/Help/policy/CMP0059.rst @@ -0,0 +1,17 @@ +CMP0059 +------- + +Don't treat ``DEFINITIONS`` as a built-in directory property. + +CMake 3.3 and above no longer make a list of definitions available through +the :prop_dir:`DEFINITIONS` directory property. The +:prop_dir:`COMPILE_DEFINITIONS` directory property may be used instead. + +The ``OLD`` behavior for this policy is to provide the list of flags given +so far to the :command:`add_definitions` command. The ``NEW`` behavior is +to behave as a normal user-defined directory property. + +This policy was introduced in CMake version 3.3. +CMake version |release| warns when the policy is not set and uses +``OLD`` behavior. Use the :command:`cmake_policy` command to set +it to ``OLD`` or ``NEW`` explicitly. diff --git a/Help/prop_dir/COMPILE_OPTIONS.rst b/Help/prop_dir/COMPILE_OPTIONS.rst index 5530860..877deb0 100644 --- a/Help/prop_dir/COMPILE_OPTIONS.rst +++ b/Help/prop_dir/COMPILE_OPTIONS.rst @@ -3,8 +3,8 @@ COMPILE_OPTIONS 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 holds a :ref:`;-list <CMake Language Lists>` of options +given so far to the :command:`add_compile_options` command. 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 diff --git a/Help/prop_dir/DEFINITIONS.rst b/Help/prop_dir/DEFINITIONS.rst index 22f7c15..79ac3f3 100644 --- a/Help/prop_dir/DEFINITIONS.rst +++ b/Help/prop_dir/DEFINITIONS.rst @@ -1,8 +1,13 @@ DEFINITIONS ----------- -For CMake 2.4 compatibility only. Use COMPILE_DEFINITIONS instead. +For CMake 2.4 compatibility only. Use :prop_dir:`COMPILE_DEFINITIONS` +instead. This read-only property specifies the list of flags given so far to -the add_definitions command. It is intended for debugging purposes. -Use the COMPILE_DEFINITIONS instead. +the :command:`add_definitions` command. It is intended for debugging +purposes. Use the :prop_dir:`COMPILE_DEFINITIONS` directory property +instead. + +This built-in read-only property does not exist if policy +:policy:`CMP0059` is set to ``NEW``. diff --git a/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst new file mode 100644 index 0000000..11f2c03 --- /dev/null +++ b/Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst @@ -0,0 +1,7 @@ +CPACK_DESKTOP_SHORTCUTS +----------------------- + +Species a list of shortcut names that should be created on the Desktop +for this file. + +The property is currently only supported by the WIX generator. diff --git a/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst new file mode 100644 index 0000000..8a16022 --- /dev/null +++ b/Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst @@ -0,0 +1,7 @@ +CPACK_STARTUP_SHORTCUTS +----------------------- + +Species a list of shortcut names that should be created in the Startup folder +for this file. + +The property is currently only supported by the WIX generator. diff --git a/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst new file mode 100644 index 0000000..d30ea39 --- /dev/null +++ b/Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst @@ -0,0 +1,7 @@ +CPACK_START_MENU_SHORTCUTS +-------------------------- + +Species a list of shortcut names that should be created in the Start Menu +for this file. + +The property is currently only supported by the WIX generator. diff --git a/Help/prop_tgt/COMPILE_OPTIONS.rst b/Help/prop_tgt/COMPILE_OPTIONS.rst index 27cbec1..36d786a 100644 --- a/Help/prop_tgt/COMPILE_OPTIONS.rst +++ b/Help/prop_tgt/COMPILE_OPTIONS.rst @@ -3,12 +3,13 @@ COMPILE_OPTIONS List of options to pass to the compiler. -This property specifies the list of options specified so far for this -property. +This property holds a :ref:`;-list <CMake Language Lists>` of options +specified so far for its target. Use the :command:`target_compile_options` +command to append more options. This property is intialized by the :prop_dir:`COMPILE_OPTIONS` directory -property, which is used by the generators to set the options for the -compiler. +property when a target is created, and 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_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst index 696ee95..a224b68 100644 --- a/Help/prop_tgt/INTERFACE_SOURCES.rst +++ b/Help/prop_tgt/INTERFACE_SOURCES.rst @@ -12,10 +12,6 @@ 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)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` diff --git a/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst b/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst index de98c37..7e00ac4 100644 --- a/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst +++ b/Help/prop_tgt/XCODE_ATTRIBUTE_an-attribute.rst @@ -8,3 +8,9 @@ the generated Xcode project. Ignored on other generators. See the :variable:`CMAKE_XCODE_ATTRIBUTE_<an-attribute>` variable to set attributes on all targets in a directory tree. + +Contents of ``XCODE_ATTRIBUTE_<an-attribute>`` 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/XCTEST.rst b/Help/prop_tgt/XCTEST.rst new file mode 100644 index 0000000..eb47e60 --- /dev/null +++ b/Help/prop_tgt/XCTEST.rst @@ -0,0 +1,13 @@ +XCTEST +------ + +This target is a XCTest CFBundle on the Mac. + +This property will usually get set via the :command:`xctest_add_bundle` +macro in :module:`FindXCTest` module. + +If a module library target has this property set to true it will be +built as a CFBundle when built on the Mac. It will have the directory +structure required for a CFBundle. + +This property depends on :prop_tgt:`BUNDLE` to be effective. diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/ExternalData-recursive-match.rst b/Help/release/dev/ExternalData-recursive-match.rst new file mode 100644 index 0000000..4d8c789 --- /dev/null +++ b/Help/release/dev/ExternalData-recursive-match.rst @@ -0,0 +1,7 @@ +ExternalData-recursive-match +---------------------------- + +* The :module:`ExternalData` module learned a new ``RECURSE:`` + option in ``DATA{}`` references specifying directories. + This allows an entire directory tree of associated files + to be matched. diff --git a/Help/release/dev/ExternalData-url-algo-map.rst b/Help/release/dev/ExternalData-url-algo-map.rst new file mode 100644 index 0000000..baf661f --- /dev/null +++ b/Help/release/dev/ExternalData-url-algo-map.rst @@ -0,0 +1,8 @@ +ExternalData-url-algo-map +------------------------- + +* The :module:`ExternalData` module learned a new URL template + placeholder ``%(algo:<key>)`` to allow custom mapping from + algorithm name to URL component through configuration of new + :variable:`ExternalData_URL_ALGO_<algo>_<key>` variables. + This allows more flexibility in remote URLs. diff --git a/Help/release/dev/ExternalProject-byproducts-tokens.rst b/Help/release/dev/ExternalProject-byproducts-tokens.rst new file mode 100644 index 0000000..20b4dd4 --- /dev/null +++ b/Help/release/dev/ExternalProject-byproducts-tokens.rst @@ -0,0 +1,5 @@ +ExternalProject-byproducts-tokens +--------------------------------- + +* The :module:`ExternalProject` module learned to replace tokens + like ``<BINARY_DIR>`` in the ``BYPRODUCTS`` of each step. diff --git a/Help/release/dev/FindBoost-per-config-libraries.rst b/Help/release/dev/FindBoost-per-config-libraries.rst new file mode 100644 index 0000000..e6ef70f --- /dev/null +++ b/Help/release/dev/FindBoost-per-config-libraries.rst @@ -0,0 +1,5 @@ +FindBoost-per-config-libraries +------------------------------ + +* The :module:`FindBoost` module now tracks the directories containing + libraries separately for RELEASE and DEBUG configurations. diff --git a/Help/release/dev/FindMatlab-rewrite.rst b/Help/release/dev/FindMatlab-rewrite.rst new file mode 100644 index 0000000..07727b8 --- /dev/null +++ b/Help/release/dev/FindMatlab-rewrite.rst @@ -0,0 +1,7 @@ +FindMatlab-rewrite +------------------ + +* The :module:`FindMatlab` module was completely rewritten. It learned + about versions and components and to find Matlab in a more precise and + multiplatform way. The module now offers APIs to create mex extensions, + documentation, and unit tests. diff --git a/Help/release/dev/InstallRequiredSystemLibraries-COMPONENT.rst b/Help/release/dev/InstallRequiredSystemLibraries-COMPONENT.rst new file mode 100644 index 0000000..e6ebc2d --- /dev/null +++ b/Help/release/dev/InstallRequiredSystemLibraries-COMPONENT.rst @@ -0,0 +1,6 @@ +InstallRequiredSystemLibraries-COMPONENT +---------------------------------------- + +* The :module:`InstallRequiredSystemLibraries` module learned a new + ``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT`` option to specify the + installation component. diff --git a/Help/release/dev/UseSWIG-no-MAIN_DEPENDENCY.rst b/Help/release/dev/UseSWIG-no-MAIN_DEPENDENCY.rst new file mode 100644 index 0000000..5311cf1 --- /dev/null +++ b/Help/release/dev/UseSWIG-no-MAIN_DEPENDENCY.rst @@ -0,0 +1,9 @@ +UseSWIG-no-MAIN_DEPENDENCY +-------------------------- + +* The :module:`UseSWIG` module ``SWIG_ADD_MODULE`` macro no + longer attaches the swig invocation custom command to the + ``.i`` source file in IDE projects. This is because only + one custom command can be safely attached to a given source + file, and adding multiple modules with the same ``.i`` file + for different languages requires more than one such command. diff --git a/Help/release/dev/add-CheckFortranCompilerFlag.rst b/Help/release/dev/add-CheckFortranCompilerFlag.rst new file mode 100644 index 0000000..718b53e --- /dev/null +++ b/Help/release/dev/add-CheckFortranCompilerFlag.rst @@ -0,0 +1,6 @@ +add-CheckFortranCompilerFlag +---------------------------- + +* The :module:`CheckFortranCompilerFlag` module was introduced + to check ``Fortran`` compiler flags, much like the + :module:`CheckCCompilerFlag` module already does for ``C``. diff --git a/Help/release/dev/add-extra-qbs-generator.rst b/Help/release/dev/add-extra-qbs-generator.rst new file mode 100644 index 0000000..edb441f --- /dev/null +++ b/Help/release/dev/add-extra-qbs-generator.rst @@ -0,0 +1,6 @@ +add-extra-qbs-geneator +---------------------- + +* It is now possible to generate :generator:`Qbs` project files + for use with QtCreator IDE, matching make tool must be used + to build the project through the generated makefiles. diff --git a/Help/release/dev/add_dependencies-INTERFACE-libraries.rst b/Help/release/dev/add_dependencies-INTERFACE-libraries.rst new file mode 100644 index 0000000..dfac2af --- /dev/null +++ b/Help/release/dev/add_dependencies-INTERFACE-libraries.rst @@ -0,0 +1,7 @@ +add_dependencies-INTERFACE-libraries +------------------------------------ + +* The :command:`add_dependencies` command learned to allow dependencies + to be added to :ref:`interface libraries <Interface Libraries>`. + Dependencies added to an interface library are followed transitively + in its place since the target itself does not build. diff --git a/Help/release/dev/compiler-version-Fortran.rst b/Help/release/dev/compiler-version-Fortran.rst new file mode 100644 index 0000000..e10b206 --- /dev/null +++ b/Help/release/dev/compiler-version-Fortran.rst @@ -0,0 +1,6 @@ +compiler-version-Fortran +------------------------ + +* The version of some Fortran compilers is now detected and stored in the + :variable:`CMAKE_Fortran_COMPILER_VERSION <CMAKE_<LANG>_COMPILER_VERSION>` + variable. diff --git a/Help/release/dev/cpack-rpm-basic-symlink-handling.rst b/Help/release/dev/cpack-rpm-basic-symlink-handling.rst new file mode 100644 index 0000000..3af4cf1 --- /dev/null +++ b/Help/release/dev/cpack-rpm-basic-symlink-handling.rst @@ -0,0 +1,6 @@ +cpack-rpm-basic-symlink-handling +-------------------------------- + +* The :module:`CPackRPM` module learned to package symbolic links + more cleanly and now supports directory symlinks with recent + ``rpmbuild`` versions. diff --git a/Help/release/dev/ctest-repeat-until-fail.rst b/Help/release/dev/ctest-repeat-until-fail.rst new file mode 100644 index 0000000..8a679c6 --- /dev/null +++ b/Help/release/dev/ctest-repeat-until-fail.rst @@ -0,0 +1,5 @@ +ctest-repeat-until-fail +----------------------- + +* The :manual:`ctest(1)` tool learned a new ``--repeat-until-fail <n>`` + option to help find sporadic test failures. diff --git a/Help/release/dev/export-interface-source-files.rst b/Help/release/dev/export-interface-source-files.rst new file mode 100644 index 0000000..00dcd25 --- /dev/null +++ b/Help/release/dev/export-interface-source-files.rst @@ -0,0 +1,6 @@ +export-interface-source-files +----------------------------- + +* It is now possible to export targets which populate the + :prop_tgt:`INTERFACE_SOURCES` target property using the + :command:`install(EXPORT)` and :command:`export()` commands. diff --git a/Help/release/dev/file-globbing-directory-listing.rst b/Help/release/dev/file-globbing-directory-listing.rst new file mode 100644 index 0000000..c4d7ba5 --- /dev/null +++ b/Help/release/dev/file-globbing-directory-listing.rst @@ -0,0 +1,6 @@ +file-globbing-directory-listing +------------------------------- + +* The :command:`file(GLOB)` and :command:`file(GLOB_RECURSE)` commands + learned a new ``LIST_DIRECTORIES <bool>`` option to specify whether + the glob result should include directories. diff --git a/Help/release/dev/find-command-prefix-from-PATH.rst b/Help/release/dev/find-command-prefix-from-PATH.rst new file mode 100644 index 0000000..f9aae2a --- /dev/null +++ b/Help/release/dev/find-command-prefix-from-PATH.rst @@ -0,0 +1,6 @@ +find-command-prefix-from-PATH +----------------------------- + +* The :command:`find_library`, :command:`find_path`, and :command:`find_file` + commands now search in installation prefixes derived from the ``PATH`` + environment variable. diff --git a/Help/release/dev/install-DESTINATION-genex.rst b/Help/release/dev/install-DESTINATION-genex.rst new file mode 100644 index 0000000..4c4bbed --- /dev/null +++ b/Help/release/dev/install-DESTINATION-genex.rst @@ -0,0 +1,5 @@ +install-DESTINATION-genex +------------------------- + +* The :command:`install(TARGETS)` command learned to support + generator expressions in the ``DESTINATION`` value. diff --git a/Help/release/dev/main_dependency_diagnostic.rst b/Help/release/dev/main_dependency_diagnostic.rst new file mode 100644 index 0000000..13486ef --- /dev/null +++ b/Help/release/dev/main_dependency_diagnostic.rst @@ -0,0 +1,6 @@ +main_dependency_diagnostic +-------------------------- + +* Listing the same input file as a MAIN_DEPENDENCY of a custom command + can lead to broken build time behavior. This is now diagnosed. + See policy :policy:`CMP0057`. diff --git a/Help/release/dev/makefile-DELETE_ON_ERROR.rst b/Help/release/dev/makefile-DELETE_ON_ERROR.rst new file mode 100644 index 0000000..c7c45fd --- /dev/null +++ b/Help/release/dev/makefile-DELETE_ON_ERROR.rst @@ -0,0 +1,7 @@ +makefile-DELETE_ON_ERROR +------------------------ + +* The Makefile generators now add ``.DELETE_ON_ERROR`` to the + makefiles that contain the actual build rules for files on disk. + This tells GNU make to remove rule outputs when their recipe + modifies an output but fails. diff --git a/Help/release/dev/makefile-progress-improvements.rst b/Help/release/dev/makefile-progress-improvements.rst new file mode 100644 index 0000000..9cc9706 --- /dev/null +++ b/Help/release/dev/makefile-progress-improvements.rst @@ -0,0 +1,7 @@ +makefile-progress-improvements +------------------------------ + +* With Makefile generators, the build-time progress output has been improved. + It no longer mixes progress and build rule messages during parallel builds. + The link rule messages now have progress and are displayed as bold green + instead of bold red (since red is often associated with an error message). diff --git a/Help/release/dev/mingw-compile-features.rst b/Help/release/dev/mingw-compile-features.rst new file mode 100644 index 0000000..e2ed30b --- /dev/null +++ b/Help/release/dev/mingw-compile-features.rst @@ -0,0 +1,6 @@ +mingw-compile-features +---------------------- + +* The :manual:`Compile Features <cmake-compile-features(7)>` functionality + is now aware of features supported by GNU compilers on Windows, versions + 4.4 through 5.0. diff --git a/Help/release/dev/mingw-no-find_library-dll.rst b/Help/release/dev/mingw-no-find_library-dll.rst new file mode 100644 index 0000000..1b0c19b --- /dev/null +++ b/Help/release/dev/mingw-no-find_library-dll.rst @@ -0,0 +1,8 @@ +mingw-no-find_library-dll +------------------------- + +* When building with GNU tools on Windows (MinGW tools), the + :command:`find_library` command will no longer consider + ``.dll`` files to be linkable libraries. All dynamic link + libraries are expected to provide separate ``.dll.a`` or + ``.lib`` import libraries. diff --git a/Help/release/dev/ninja-require-byproducts.rst b/Help/release/dev/ninja-require-byproducts.rst new file mode 100644 index 0000000..ccde4bc --- /dev/null +++ b/Help/release/dev/ninja-require-byproducts.rst @@ -0,0 +1,9 @@ +ninja-require-byproducts +------------------------ + +* The :generator:`Ninja` generator now requires that calls to the + :command:`add_custom_command` and :command:`add_custom_target` + commands use the ``BYPRODUCTS`` option to explicitly specify any + files generated by the custom commands that are not listed as + outputs (perhaps because their timestamps are allowed to be older + than the inputs). See policy :policy:`CMP0058`. diff --git a/Help/release/dev/remove-DEFINITIONS-directory-property.rst b/Help/release/dev/remove-DEFINITIONS-directory-property.rst new file mode 100644 index 0000000..d8e50f0 --- /dev/null +++ b/Help/release/dev/remove-DEFINITIONS-directory-property.rst @@ -0,0 +1,6 @@ +remove-DEFINITIONS-property +--------------------------- + +* The :command:`add_definitions()` command no longer causes a + :prop_dir:`DEFINITIONS` directory property to be populated. See policy + :policy:`CMP0059`. diff --git a/Help/release/dev/rpm_package_architecture.rst b/Help/release/dev/rpm_package_architecture.rst new file mode 100644 index 0000000..5bec51d --- /dev/null +++ b/Help/release/dev/rpm_package_architecture.rst @@ -0,0 +1,6 @@ +rpm_package_architecture +------------------------ + +* The :module:`CPackRPM` module learned a new + :variable:`CPACK_RPM_<component>_PACKAGE_ARCHITECTURE` variable + to specify a component-specific package architecture. diff --git a/Help/release/dev/target-language-genex.rst b/Help/release/dev/target-language-genex.rst new file mode 100644 index 0000000..ed4cb5e --- /dev/null +++ b/Help/release/dev/target-language-genex.rst @@ -0,0 +1,9 @@ +target-language-genex +--------------------- + +* A new ``COMPILE_LANGUAGE`` generator expression was introduced to + allow specification of compile options for target files based on the + :prop_sf:`LANGUAGE` of each source file. Due to limitations of the + underlying native build tools, this feature has varying support across + generators. See the :manual:`cmake-generator-expressions(7)` manual + for details. diff --git a/Help/release/dev/vs7-OutputDirectory.rst b/Help/release/dev/vs7-OutputDirectory.rst new file mode 100644 index 0000000..2725d0c --- /dev/null +++ b/Help/release/dev/vs7-OutputDirectory.rst @@ -0,0 +1,10 @@ +vs7-OutputDirectory +------------------- + +* The :variable:`CMAKE_CFG_INTDIR` variable value for Visual Studio + 7, 8, and 9 is now ``$(ConfigurationName)`` instead of ``$(OutDir)``. + This should have no effect on the intended use cases of the variable. + +* With Visual Studio 7, 8, and 9 generators the value of the ``$(OutDir)`` + placeholder no longer evaluates to the configuration name. Projects + should use ``$(ConfigurationName)`` for that instead. diff --git a/Help/release/dev/wix-shortcut-properties.rst b/Help/release/dev/wix-shortcut-properties.rst new file mode 100644 index 0000000..bdd6485 --- /dev/null +++ b/Help/release/dev/wix-shortcut-properties.rst @@ -0,0 +1,9 @@ +wix-shortcut-properties +----------------------- + +* The CPack WIX generator learned the new + :prop_inst:`CPACK_START_MENU_SHORTCUTS`, + :prop_inst:`CPACK_DESKTOP_SHORTCUTS` and + :prop_inst:`CPACK_STARTUP_SHORTCUTS` installed file properties which can + be used to install shorcuts in the Start Menu, on the Desktop and + in the Startup Folder respectively. diff --git a/Help/release/dev/xcode-attribute-genex.rst b/Help/release/dev/xcode-attribute-genex.rst new file mode 100644 index 0000000..3fd5b1c --- /dev/null +++ b/Help/release/dev/xcode-attribute-genex.rst @@ -0,0 +1,5 @@ +xcode-attribute-genex +--------------------- + +* The :prop_tgt:`XCODE_ATTRIBUTE_<an-attribute>` target property learned + to support generator expressions. diff --git a/Help/release/dev/xcode-xctest.rst b/Help/release/dev/xcode-xctest.rst new file mode 100644 index 0000000..7a2f07b --- /dev/null +++ b/Help/release/dev/xcode-xctest.rst @@ -0,0 +1,6 @@ +xcode-xctest +------------ + +* On OS X, CMake learned to create XCTest bundles to test Frameworks + and App Bundles within Xcode. The :module:`FindXCTest` module + provides convenience functions to handle :prop_tgt:`XCTEST` bundles. diff --git a/Help/release/index.rst b/Help/release/index.rst index a058bc1..45d0a69 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -5,6 +5,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst index 20435e5..55f7b01 100644 --- a/Help/variable/CMAKE_CFG_INTDIR.rst +++ b/Help/variable/CMAKE_CFG_INTDIR.rst @@ -12,11 +12,11 @@ values: :: - $(IntDir) = Visual Studio 6 - $(OutDir) = Visual Studio 7, 8, 9 - $(Configuration) = Visual Studio 10 - $(CONFIGURATION) = Xcode - . = Make-based tools + $(IntDir) = Visual Studio 6 + $(ConfigurationName) = Visual Studio 7, 8, 9 + $(Configuration) = Visual Studio 10 + $(CONFIGURATION) = Xcode + . = Make-based tools Since these values are evaluated by the native build system, this variable is suitable only for use in command lines that will be diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index fee0a7c..b7975d3 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -457,7 +457,11 @@ endfunction() function(set_bundle_key_values keys_var context item exepath dirs copyflag) - set(rpaths "${ARGV6}") + if(ARGC GREATER 6) + set(rpaths "${ARGV6}") + else() + set(rpaths "") + endif() get_filename_component(item_name "${item}" NAME) get_item_key("${item}" key) @@ -776,7 +780,12 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs) # to install_name_tool: # if(changes) - execute_process(COMMAND install_name_tool ${changes} "${resolved_embedded_item}") + set(cmd install_name_tool ${changes} "${resolved_embedded_item}") + execute_process(COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result) + if(NOT install_name_tool_result EQUAL 0) + string(REPLACE ";" "' '" msg "'${cmd}'") + message(FATAL_ERROR "Command failed:\n ${msg}") + endif() endif() endfunction() diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake index 19b2bbc..3141d60 100644 --- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake +++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake @@ -21,9 +21,9 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR) set(${_VAR} - FAIL_REGEX "unrecognized .*option" # GNU + FAIL_REGEX "[Uu]nrecogni[sz]ed .*option" # GNU, NAG FAIL_REGEX "unknown .*option" # Clang - FAIL_REGEX "ignoring unknown option" # MSVC + FAIL_REGEX "ignoring unknown option" # MSVC, Intel FAIL_REGEX "warning D9002" # MSVC, any lang FAIL_REGEX "option.*not supported" # Intel FAIL_REGEX "invalid argument .*option" # Intel @@ -35,6 +35,7 @@ macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR) FAIL_REGEX "command option .* contains an incorrect subargument" # XL FAIL_REGEX "not supported in this configuration. ignored" # AIX FAIL_REGEX "File with unknown suffix passed to linker" # PGI + FAIL_REGEX "[Uu]nknown switch" # PGI FAIL_REGEX "WARNING: unknown flag:" # Open64 FAIL_REGEX "Incorrect command line option:" # Borland FAIL_REGEX "Warning: illegal option" # SunStudio 12 diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index dfed00e..403ac08 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -409,12 +409,28 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) # Read the compiler identification string from the executable file. set(COMPILER_ID) set(COMPILER_VERSION) + set(COMPILER_VERSION_MAJOR 0) + set(COMPILER_VERSION_MINOR 0) + set(COMPILER_VERSION_PATCH 0) + set(COMPILER_VERSION_TWEAK 0) + set(HAVE_COMPILER_VERSION_MAJOR 0) + set(HAVE_COMPILER_VERSION_MINOR 0) + set(HAVE_COMPILER_VERSION_PATCH 0) + set(HAVE_COMPILER_VERSION_TWEAK 0) + set(DIGIT_VALUE_1 1) + set(DIGIT_VALUE_2 10) + set(DIGIT_VALUE_3 100) + set(DIGIT_VALUE_4 1000) + set(DIGIT_VALUE_5 10000) + set(DIGIT_VALUE_6 100000) + set(DIGIT_VALUE_7 1000000) + set(DIGIT_VALUE_8 10000000) set(PLATFORM_ID) set(ARCHITECTURE_ID) set(SIMULATE_ID) set(SIMULATE_VERSION) file(STRINGS ${file} - CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") + CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") set(COMPILER_ID_TWICE) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) if("${info}" MATCHES "INFO:compiler\\[([^]\"]*)\\]") @@ -433,6 +449,15 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}") string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}") endif() + foreach(comp MAJOR MINOR PATCH TWEAK) + foreach(digit 1 2 3 4 5 6 7 8 9) + if("${info}" MATCHES "INFO:compiler_version_${comp}_digit_${digit}\\[([0-9])\\]") + set(value ${CMAKE_MATCH_1}) + math(EXPR COMPILER_VERSION_${comp} "${COMPILER_VERSION_${comp}} + ${value} * ${DIGIT_VALUE_${digit}}") + set(HAVE_COMPILER_VERSION_${comp} 1) + endif() + endforeach() + endforeach() if("${info}" MATCHES "INFO:simulate\\[([^]\"]*)\\]") set(SIMULATE_ID "${CMAKE_MATCH_1}") endif() @@ -445,6 +470,20 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) endif() endforeach() + # Construct compiler version from components if needed. + if(NOT DEFINED COMPILER_VERSION AND HAVE_COMPILER_VERSION_MAJOR) + set(COMPILER_VERSION "${COMPILER_VERSION_MAJOR}") + if(HAVE_COMPILER_VERSION_MINOR) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_MINOR}") + if(HAVE_COMPILER_VERSION_PATCH) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_PATCH}") + if(HAVE_COMPILER_VERSION_TWEAK) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_TWEAK}") + endif() + endif() + endif() + endif() + # Detect the exact architecture from the PE header. if(WIN32) # The offset to the PE signature is stored at 0x3c. @@ -469,8 +508,6 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(ARCHITECTURE_ID "SH4") elseif(peheader STREQUAL "50450000a801") set(ARCHITECTURE_ID "SH5") - elseif(peheader STREQUAL "50450000c201") - set(ARCHITECTURE_ID "THUMB") endif() endif() diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index a4bb86c..3a27127 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -119,6 +119,47 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN) set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V") set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler") + set(_version_info "") + foreach(m MAJOR MINOR PATCH TWEAK) + set(_COMP "_${m}") + set(_version_info "${_version_info} +#if defined(COMPILER_VERSION${_COMP})") + foreach(d 1 2 3 4 5 6 7 8) + set(_version_info "${_version_info} +# undef DEC +# undef HEX +# define DEC(n) DEC_${d}(n) +# define HEX(n) HEX_${d}(n) +# if COMPILER_VERSION${_COMP} == 0 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[0]' +# elif COMPILER_VERSION${_COMP} == 1 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[1]' +# elif COMPILER_VERSION${_COMP} == 2 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[2]' +# elif COMPILER_VERSION${_COMP} == 3 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[3]' +# elif COMPILER_VERSION${_COMP} == 4 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[4]' +# elif COMPILER_VERSION${_COMP} == 5 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[5]' +# elif COMPILER_VERSION${_COMP} == 6 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[6]' +# elif COMPILER_VERSION${_COMP} == 7 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[7]' +# elif COMPILER_VERSION${_COMP} == 8 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[8]' +# elif COMPILER_VERSION${_COMP} == 9 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[9]' +# endif +") + endforeach() + set(_version_info "${_version_info} +#endif") + endforeach() + set(CMAKE_Fortran_COMPILER_ID_VERSION_INFO "${_version_info}") + unset(_version_info) + unset(_COMP) + # Try to identify the compiler. set(CMAKE_Fortran_COMPILER_ID) include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 5349505..2533d3f 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -4,6 +4,17 @@ #endif #if defined(__INTEL_COMPILER) || defined(__ICC) PRINT *, 'INFO:compiler[Intel]' +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif + # if defined(_MSC_VER) PRINT *, 'INFO:simulate[MSVC]' # if _MSC_VER >= 1800 @@ -22,28 +33,59 @@ PRINT *, 'INFO:simulate_version[013.00]' # endif # endif -#elif defined(__SUNPRO_F90) || defined(__SUNPRO_F95) +#elif defined(__SUNPRO_F95) + PRINT *, 'INFO:compiler[SunPro]' +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F95>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F95>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F95 & 0xF) +#elif defined(__SUNPRO_F90) PRINT *, 'INFO:compiler[SunPro]' +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F90>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F90>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F90 & 0xF) #elif defined(_CRAYFTN) PRINT *, 'INFO:compiler[Cray]' #elif defined(__G95__) PRINT *, 'INFO:compiler[G95]' +# define COMPILER_VERSION_MAJOR DEC(__G95__) +# define COMPILER_VERSION_MINOR DEC(__G95_MINOR__) #elif defined(__PATHSCALE__) PRINT *, 'INFO:compiler[PathScale]' +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif #elif defined(__ABSOFT__) PRINT *, 'INFO:compiler[Absoft]' #elif defined(__GNUC__) PRINT *, 'INFO:compiler[GNU]' +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif #elif defined(__IBMC__) # if defined(__COMPILER_VER__) PRINT *, 'INFO:compiler[zOS]' # elif __IBMC__ >= 800 PRINT *, 'INFO:compiler[XL]' +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) # else PRINT *, 'INFO:compiler[VisualAge]' +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) # endif #elif defined(__PGI) PRINT *, 'INFO:compiler[PGI]' +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif #elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) PRINT *, 'INFO:compiler[MIPSpro]' # if 0 @@ -134,4 +176,26 @@ PRINT *, 'INFO:arch[X86]' # endif #endif + +#if 0 +! Encode compiler version digits +#endif +#define DEC_8(n) (((n) / 10000000) % 10) +#define DEC_7(n) (((n) / 1000000) % 10) +#define DEC_6(n) (((n) / 100000) % 10) +#define DEC_5(n) (((n) / 10000) % 10) +#define DEC_4(n) (((n) / 1000) % 10) +#define DEC_3(n) (((n) / 100) % 10) +#define DEC_2(n) (((n) / 10) % 10) +#define DEC_1(n) (((n) ) % 10) +#define HEX_8(n) ((n)>>28 & 0xF) +#define HEX_7(n) ((n)>>24 & 0xF) +#define HEX_6(n) ((n)>>20 & 0xF) +#define HEX_5(n) ((n)>>16 & 0xF) +#define HEX_4(n) ((n)>>12 & 0xF) +#define HEX_3(n) ((n)>>8 & 0xF) +#define HEX_2(n) ((n)>>4 & 0xF) +#define HEX_1(n) ((n) & 0xF) +@CMAKE_Fortran_COMPILER_ID_VERSION_INFO@ + END diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake index 64c89b9..ff18267 100644 --- a/Modules/CMakeGraphVizOptions.cmake +++ b/Modules/CMakeGraphVizOptions.cmake @@ -10,7 +10,7 @@ # CMake # can generate graphviz files, showing the dependencies between the # targets in a project and also external libraries which are linked -# against. When CMake is run with the --graphiz=foo option, it will +# against. When CMake is run with the --graphviz=foo option, it will # produce # # * a foo.dot file showing all dependencies in the project diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index fcc13da..8abc465 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -124,7 +124,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj # We remove items that are not language-specific. set(implicit_libs "") foreach(lib IN LISTS implicit_libs_tmp) - if("${lib}" MATCHES "^(crt.*\\.o|gcc.*|System.*)$") + if("x${lib}" MATCHES "^x(crt.*\\.o|gcc.*|System.*)$") set(log "${log} remove lib [${lib}]\n") elseif(IS_ABSOLUTE "${lib}") get_filename_component(abs "${lib}" ABSOLUTE) diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index bc26c07..da99b9e 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -1,3 +1,6 @@ +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + /* Identify known platforms by name. */ #if defined(__linux) || defined(__linux__) || defined(linux) # define PLATFORM_ID "Linux" @@ -112,7 +115,13 @@ # define ARCHITECTURE_ID "X86" # elif defined(_M_ARM) -# define ARCHITECTURE_ID "ARM" +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif # elif defined(_M_MIPS) # define ARCHITECTURE_ID "MIPS" diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index ce1536e..532596d 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -314,7 +314,7 @@ macro(cpack_encode_variables) set(_CPACK_OTHER_VARIABLES_) get_cmake_property(res VARIABLES) foreach(var ${res}) - if("xxx${var}" MATCHES "xxxCPACK") + if(var MATCHES "^CPACK") set(_CPACK_OTHER_VARIABLES_ "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")") endif() diff --git a/Modules/CPackBundle.cmake b/Modules/CPackBundle.cmake index d26a0b3..b412216 100644 --- a/Modules/CPackBundle.cmake +++ b/Modules/CPackBundle.cmake @@ -52,6 +52,11 @@ # 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_BUNDLE_APPLE_CODESIGN_PARAMETER +# +# Additional parameter that will passed to codesign. +# Default value: "--deep -f" +# # .. variable:: CPACK_COMMAND_CODESIGN # # Path to the codesign(1) command used to sign applications with an diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index e3f74d8..b8d518c 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -51,11 +51,12 @@ # * Default : CPACK_PACKAGE_VERSION # # .. variable:: CPACK_RPM_PACKAGE_ARCHITECTURE +# CPACK_RPM_<component>_PACKAGE_ARCHITECTURE # # The RPM package architecture. # -# * Mandatory : NO -# * Default : - +# * Mandatory : YES +# * Default : Native architecture output by "uname -m" # # This may be set to "noarch" if you know you are building a noarch package. # @@ -407,6 +408,51 @@ # # May be used to set per component CPACK_PACKAGING_INSTALL_PREFIX for # relocatable RPM packages. +# +# .. variable:: CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION +# CPACK_RPM_NO_<COMPONENT>_INSTALL_PREFIX_RELOCATION +# +# * Mandatory : NO +# * Default : CPACK_PACKAGING_INSTALL_PREFIX or CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX +# are treated as one of relocation paths +# +# May be used to remove CPACK_PACKAGING_INSTALL_PREFIX and CPACK_RPM_<COMPONENT>_PACKAGE_PREFIX +# from relocatable RPM prefix paths. +# +# Packaging of Symbolic Links +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# CPackRPM supports packaging of symbolic links:: +# +# execute_process(COMMAND ${CMAKE_COMMAND} +# -E create_symlink <relative_path_location> <symlink_name>) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/<symlink_name> +# DESTINATION <symlink_location> COMPONENT libraries) +# +# Symbolic links will be optimized (paths will be shortened if possible) +# before being added to the package or if multiple relocation paths are +# detected, a post install symlink relocation script will be generated. +# +# Symbolic links may point to locations that are not packaged by the same +# package (either a different component or even not packaged at all) but +# those locations will be treated as if they were a part of the package +# while determining if symlink should be either created or present in a +# post install script - depending on relocation paths. +# +# Currenty there are a few limitations though: +# +# * Only symbolic links with relative path can be packaged. +# +# * For component based packaging component interdependency is not checked +# when processing symbolic links. Symbolic links pointing to content of +# a different component are treated the same way as if pointing to location +# that will not be packaged. +# +# * Symbolic links pointing to a location through one or more intermediate +# symbolic links will not be handled differently - if the intermediate +# symbolic link(s) is also on a relocatable path, relocating it during +# package installation may cause initial symbolic link to point to an +# invalid location. #============================================================================= # Copyright 2007-2009 Kitware, Inc. @@ -436,8 +482,15 @@ function(cpack_rpm_prepare_relocation_paths) # set base path prefix if(EXISTS "${WDIR}/${PATH_PREFIX}") - set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}Prefix: ${PATH_PREFIX}\n") - list(APPEND RPM_USED_PACKAGE_PREFIXES "${PATH_PREFIX}") + if(NOT CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION AND + NOT CPACK_RPM_NO_${CPACK_RPM_PACKAGE_COMPONENT}_INSTALL_PREFIX_RELOCATION) + set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}Prefix: ${PATH_PREFIX}\n") + list(APPEND RPM_USED_PACKAGE_PREFIXES "${PATH_PREFIX}") + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: removing '${PATH_PREFIX}' from relocation paths") + endif() + endif() endif() # set other path prefixes @@ -485,706 +538,979 @@ function(cpack_rpm_prepare_relocation_paths) set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}" PARENT_SCOPE) endfunction() -if(CMAKE_BINARY_DIR) - message(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.") -endif() +function(cpack_rpm_symlink_get_relocation_prefixes LOCATION PACKAGE_PREFIXES RETURN_VARIABLE) + foreach(PKG_PREFIX IN LISTS PACKAGE_PREFIXES) + string(REGEX MATCH "^${PKG_PREFIX}/.*" FOUND_ "${LOCATION}") + if(FOUND_) + list(APPEND TMP_PREFIXES "${PKG_PREFIX}") + endif() + endforeach() -if(NOT UNIX) - message(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.") -endif() + set(${RETURN_VARIABLE} "${TMP_PREFIXES}" PARENT_SCOPE) +endfunction() -# rpmbuild is the basic command for building RPM package -# it may be a simple (symbolic) link to rpm command. -find_program(RPMBUILD_EXECUTABLE rpmbuild) - -# Check version of the rpmbuild tool this would be easier to -# track bugs with users and CPackRPM debug mode. -# We may use RPM version in order to check for available version dependent features -if(RPMBUILD_EXECUTABLE) - execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --version - OUTPUT_VARIABLE _TMP_VERSION - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "^.* " "" - RPMBUILD_EXECUTABLE_VERSION - ${_TMP_VERSION}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>") - endif() -endif() +function(cpack_rpm_symlink_create_relocation_script PACKAGE_PREFIXES) + list(LENGTH PACKAGE_PREFIXES LAST_INDEX) + set(SORTED_PACKAGE_PREFIXES "${PACKAGE_PREFIXES}") + list(SORT SORTED_PACKAGE_PREFIXES) + list(REVERSE SORTED_PACKAGE_PREFIXES) + math(EXPR LAST_INDEX ${LAST_INDEX}-1) + + foreach(SYMLINK_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${SYMLINK_INDEX} SRC_PATH) + list(FIND PACKAGE_PREFIXES "${SRC_PATH}" SYMLINK_INDEX) # reverse magic + string(LENGTH "${SRC_PATH}" SRC_PATH_LEN) + + set(PARTS_CNT 0) + set(SCRIPT_PART "if [ \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}\" != \"${SRC_PATH}\" ]; then\n") + + # both paths relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + if("${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + set(INDENT "") + else() + set(SCRIPT_PART "${SCRIPT_PART} if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + set(INDENT " ") + endif() -if(NOT RPMBUILD_EXECUTABLE) - message(FATAL_ERROR "RPM package requires rpmbuild executable") -endif() + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) -# Display lsb_release output if DEBUG mode enable -# This will help to diagnose problem with CPackRPM -# because we will know on which kind of Linux we are -if(CPACK_RPM_PACKAGE_DEBUG) - find_program(LSB_RELEASE_EXECUTABLE lsb_release) - if(LSB_RELEASE_EXECUTABLE) - execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -a - OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "\n" ", " - LSB_RELEASE_OUTPUT - ${_TMP_LSB_RELEASE_OUTPUT}) - else () - set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!") + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}fi\n") + endforeach() + + if(NOT "${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + set(SCRIPT_PART "${SCRIPT_PART} fi\n") + endif() + endif() + endforeach() + + # source path relocated + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) + + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT_PART "${SCRIPT_PART} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT_PART "${SCRIPT_PART} ln -s \"${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + set(SCRIPT_PART "${SCRIPT_PART} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT_PART "${SCRIPT_PART} fi\n") + endforeach() + endif() + + if(PARTS_CNT) + set(SCRIPT "${SCRIPT_PART}") + set(SCRIPT "${SCRIPT}fi\n") + endif() + endforeach() + + # point path relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + set(SCRIPT "${SCRIPT}if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT "${SCRIPT} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT "${SCRIPT} ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"${SYMLINK_}\"\n") + set(SCRIPT "${SCRIPT} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT "${SCRIPT} fi\n") + endforeach() + + set(SCRIPT "${SCRIPT}fi\n") + endif() + endforeach() + + # no path relocated + if(_RPM_RELOCATION_SCRIPT_X_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_X) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT "${SCRIPT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT "${SCRIPT} ln -s \"${POINT_}\" \"${SYMLINK_}\"\n") + set(SCRIPT "${SCRIPT}fi\n") + endforeach() endif() - message("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}") -endif() -# We may use RPM version in the future in order -# to shut down warning about space in buildtree -# some recent RPM version should support space in different places. -# not checked [yet]. -if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*") - message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.") -endif() + set(RPM_SYMLINK_POSTINSTALL "${SCRIPT}" PARENT_SCOPE) +endfunction() -# If rpmbuild is found -# we try to discover alien since we may be on non RPM distro like Debian. -# In this case we may try to to use more advanced features -# like generating RPM directly from DEB using alien. -# FIXME feature not finished (yet) -find_program(ALIEN_EXECUTABLE alien) -if(ALIEN_EXECUTABLE) - message(STATUS "alien found, we may be on a Debian based distro.") -endif() +function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS) + list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN) + list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT) -# Are we packaging components ? -if(CPACK_RPM_PACKAGE_COMPONENT) - set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") - string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) -else() - set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "") -endif() + list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}") + list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO) -set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}") + if(SYMLINK_PATHS_COUTN) + foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX) -# -# Use user-defined RPM specific variables value -# or generate reasonable default value from -# CPACK_xxx generic values. -# The variables comes from the needed (mandatory or not) -# values found in the RPM specification file aka ".spec" file. -# The variables which may/should be defined are: -# + # source path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X") -# CPACK_RPM_PACKAGE_SUMMARY (mandatory) + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) -# CPACK_RPM_PACKAGE_SUMMARY_ is used only locally so that it can be unset each time before use otherwise -# component packaging could leak variable content between components -unset(CPACK_RPM_PACKAGE_SUMMARY_) -if(CPACK_RPM_PACKAGE_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY_ ${CPACK_RPM_PACKAGE_SUMMARY}) - unset(CPACK_RPM_PACKAGE_SUMMARY) -endif() + # both paths relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}") -#Check for component summary first. -#If not set, it will use regular package summary logic. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY}) + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() + endforeach() + elseif(POINT_PATHS_COUNT) + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) + + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() endif() -endif() -if(NOT CPACK_RPM_PACKAGE_SUMMARY) - if(CPACK_RPM_PACKAGE_SUMMARY_) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) - elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) - else() - # if neither var is defined lets use the name as summary - string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) + # no path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_X") + + # place variables into parent scope + foreach(VAR IN LISTS RELOCATION_VARS) + set(${VAR} "${${VAR}}" PARENT_SCOPE) + endforeach() + set(_RPM_RELOCATION_SCRIPT_PAIRS "${_RPM_RELOCATION_SCRIPT_PAIRS}" PARENT_SCOPE) + set(REQUIRES_SYMLINK_RELOCATION_SCRIPT "true" PARENT_SCOPE) + set(DIRECTIVE "%ghost " PARENT_SCOPE) +endfunction() + +function(cpack_rpm_prepare_install_files INSTALL_FILES_LIST WDIR PACKAGE_PREFIXES IS_RELOCATABLE) + # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir + # This is necessary to avoid duplicate files since rpmbuild does + # recursion on its own when encountering a pathname which is a directory + # which is not flagged as %dir + string(STRIP "${INSTALL_FILES_LIST}" INSTALL_FILES_LIST) + string(REPLACE "\n" ";" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(REPLACE "\"" "" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(LENGTH "${WDIR}" WDR_LEN_) + + list(SORT INSTALL_FILES_LIST) # make file order consistent on all platforms + + foreach(F IN LISTS INSTALL_FILES_LIST) + unset(DIRECTIVE) + + if(IS_SYMLINK "${WDIR}/${F}") + if(IS_RELOCATABLE) + # check that symlink has relocatable format + get_filename_component(SYMLINK_LOCATION_ "${WDIR}/${F}" DIRECTORY) + execute_process(COMMAND ls -la "${WDIR}/${F}" + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE SYMLINK_POINT_ + OUTPUT_STRIP_TRAILING_WHITESPACE) + + string(FIND "${SYMLINK_POINT_}" "->" SYMLINK_POINT_INDEX_ REVERSE) + math(EXPR SYMLINK_POINT_INDEX_ ${SYMLINK_POINT_INDEX_}+3) + string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_) + + # get destination path + string(SUBSTRING "${SYMLINK_POINT_}" ${SYMLINK_POINT_INDEX_} ${SYMLINK_POINT_LENGTH_} SYMLINK_POINT_) + + # check if path is relative or absolute + string(SUBSTRING "${SYMLINK_POINT_}" 0 1 SYMLINK_IS_ABSOLUTE_) + + if(${SYMLINK_IS_ABSOLUTE_} STREQUAL "/") + # prevent absolute paths from having /../ or /./ section inside of them + get_filename_component(SYMLINK_POINT_ "${SYMLINK_POINT_}" ABSOLUTE) + else() + # handle relative path + get_filename_component(SYMLINK_POINT_ "${SYMLINK_LOCATION_}/${SYMLINK_POINT_}" ABSOLUTE) + endif() + + string(SUBSTRING "${SYMLINK_POINT_}" ${WDR_LEN_} -1 SYMLINK_POINT_WD_) + + cpack_rpm_symlink_get_relocation_prefixes("${F}" "${PACKAGE_PREFIXES}" "SYMLINK_RELOCATIONS") + cpack_rpm_symlink_get_relocation_prefixes("${SYMLINK_POINT_WD_}" "${PACKAGE_PREFIXES}" "POINT_RELOCATIONS") + + list(LENGTH SYMLINK_RELOCATIONS SYMLINK_RELOCATIONS_COUNT) + list(LENGTH POINT_RELOCATIONS POINT_RELOCATIONS_COUNT) + + if(SYMLINK_RELOCATIONS_COUNT AND POINT_RELOCATIONS_COUNT) + # find matching + foreach(SYMLINK_RELOCATION_PREFIX IN LISTS SYMLINK_RELOCATIONS) + list(FIND POINT_RELOCATIONS "${SYMLINK_RELOCATION_PREFIX}" FOUND_INDEX) + if(NOT ${FOUND_INDEX} EQUAL -1) + break() + endif() + endforeach() + + if(NOT ${FOUND_INDEX} EQUAL -1) + # symlinks have the same subpath + if(${SYMLINK_RELOCATIONS_COUNT} EQUAL 1 AND ${POINT_RELOCATIONS_COUNT} EQUAL 1) + # permanent symlink + get_filename_component(SYMLINK_LOCATION_ "${F}" DIRECTORY) + file(RELATIVE_PATH FINAL_PATH_ ${SYMLINK_LOCATION_} ${SYMLINK_POINT_WD_}) + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${FINAL_PATH_}" "${WDIR}/${F}") + else() + # relocation subpaths + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + else() + # not on the same relocation path + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + elseif(POINT_RELOCATIONS_COUNT) + # point is relocatable + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + else() + # is not relocatable or points to non relocatable path - permanent symlink + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${SYMLINK_POINT_WD_}" "${WDIR}/${F}") + endif() + endif() + elseif(IS_DIRECTORY "${WDIR}/${F}") + set(DIRECTIVE "%dir ") + endif() + + set(INSTALL_FILES "${INSTALL_FILES}${DIRECTIVE}\"${F}\"\n") + endforeach() + + if(REQUIRES_SYMLINK_RELOCATION_SCRIPT) + cpack_rpm_symlink_create_relocation_script("${PACKAGE_PREFIXES}") endif() + + set(RPM_SYMLINK_POSTINSTALL "${RPM_SYMLINK_POSTINSTALL}" PARENT_SCOPE) + set(CPACK_RPM_INSTALL_FILES "${INSTALL_FILES}" PARENT_SCOPE) +endfunction() + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.") endif() -# CPACK_RPM_PACKAGE_NAME (mandatory) -if(NOT CPACK_RPM_PACKAGE_NAME) - string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) +if(NOT UNIX) + message(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.") endif() -# CPACK_RPM_PACKAGE_VERSION (mandatory) -if(NOT CPACK_RPM_PACKAGE_VERSION) - if(NOT CPACK_PACKAGE_VERSION) - message(FATAL_ERROR "RPM package requires a package version") +function(cpack_rpm_generate_package) + # rpmbuild is the basic command for building RPM package + # it may be a simple (symbolic) link to rpm command. + find_program(RPMBUILD_EXECUTABLE rpmbuild) + + # Check version of the rpmbuild tool this would be easier to + # track bugs with users and CPackRPM debug mode. + # We may use RPM version in order to check for available version dependent features + if(RPMBUILD_EXECUTABLE) + execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --version + OUTPUT_VARIABLE _TMP_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "^.* " "" + RPMBUILD_EXECUTABLE_VERSION + ${_TMP_VERSION}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>") + endif() endif() - set(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}) -endif() -# Replace '-' in version with '_' -# '-' character is an Illegal RPM version character -# it is illegal because it is used to separate -# RPM "Version" from RPM "Release" -string(REPLACE "-" "_" CPACK_RPM_PACKAGE_VERSION ${CPACK_RPM_PACKAGE_VERSION}) - -# CPACK_RPM_PACKAGE_ARCHITECTURE (optional) -if(CPACK_RPM_PACKAGE_ARCHITECTURE) - set(TMP_RPM_BUILDARCH "Buildarch: ${CPACK_RPM_PACKAGE_ARCHITECTURE}") - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}") + + if(NOT RPMBUILD_EXECUTABLE) + message(FATAL_ERROR "RPM package requires rpmbuild executable") endif() -else() - set(TMP_RPM_BUILDARCH "") -endif() -# CPACK_RPM_PACKAGE_RELEASE -# The RPM release is the numbering of the RPM package ITSELF -# this is the version of the PACKAGING and NOT the version -# of the CONTENT of the package. -# You may well need to generate a new RPM package release -# without changing the version of the packaged software. -# This is the case when the packaging is buggy (not) the software :=) -# If not set, 1 is a good candidate -if(NOT CPACK_RPM_PACKAGE_RELEASE) - set(CPACK_RPM_PACKAGE_RELEASE 1) -endif() + # Display lsb_release output if DEBUG mode enable + # This will help to diagnose problem with CPackRPM + # because we will know on which kind of Linux we are + if(CPACK_RPM_PACKAGE_DEBUG) + find_program(LSB_RELEASE_EXECUTABLE lsb_release) + if(LSB_RELEASE_EXECUTABLE) + execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -a + OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "\n" ", " + LSB_RELEASE_OUTPUT + ${_TMP_LSB_RELEASE_OUTPUT}) + else () + set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!") + endif() + message("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}") + endif() -# CPACK_RPM_PACKAGE_LICENSE -if(NOT CPACK_RPM_PACKAGE_LICENSE) - set(CPACK_RPM_PACKAGE_LICENSE "unknown") -endif() + # We may use RPM version in the future in order + # to shut down warning about space in buildtree + # some recent RPM version should support space in different places. + # not checked [yet]. + if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*") + message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.") + endif() -# CPACK_RPM_PACKAGE_GROUP -if(NOT CPACK_RPM_PACKAGE_GROUP) - set(CPACK_RPM_PACKAGE_GROUP "unknown") -endif() + # If rpmbuild is found + # we try to discover alien since we may be on non RPM distro like Debian. + # In this case we may try to to use more advanced features + # like generating RPM directly from DEB using alien. + # FIXME feature not finished (yet) + find_program(ALIEN_EXECUTABLE alien) + if(ALIEN_EXECUTABLE) + message(STATUS "alien found, we may be on a Debian based distro.") + endif() -# CPACK_RPM_PACKAGE_VENDOR -if(NOT CPACK_RPM_PACKAGE_VENDOR) - if(CPACK_PACKAGE_VENDOR) - set(CPACK_RPM_PACKAGE_VENDOR "${CPACK_PACKAGE_VENDOR}") + # Are we packaging components ? + if(CPACK_RPM_PACKAGE_COMPONENT) + set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") + string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) else() - set(CPACK_RPM_PACKAGE_VENDOR "unknown") + set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "") endif() -endif() -# CPACK_RPM_PACKAGE_SOURCE -# The name of the source tarball in case we generate a source RPM + set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}") -# CPACK_RPM_PACKAGE_DESCRIPTION -# The variable content may be either -# - explicitly given by the user or -# - filled with the content of CPACK_PACKAGE_DESCRIPTION_FILE -# if it is defined -# - set to a default value -# + # + # Use user-defined RPM specific variables value + # or generate reasonable default value from + # CPACK_xxx generic values. + # The variables comes from the needed (mandatory or not) + # values found in the RPM specification file aka ".spec" file. + # The variables which may/should be defined are: + # -# CPACK_RPM_PACKAGE_DESCRIPTION_ is used only locally so that it can be unset each time before use otherwise -# component packaging could leak variable content between components -unset(CPACK_RPM_PACKAGE_DESCRIPTION_) -if(CPACK_RPM_PACKAGE_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION_ ${CPACK_RPM_PACKAGE_DESCRIPTION}) - unset(CPACK_RPM_PACKAGE_DESCRIPTION) -endif() + # CPACK_RPM_PACKAGE_SUMMARY (mandatory) -#Check for a component description first. -#If not set, it will use regular package description logic. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION}) - elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION}) + #Check for component summary first. + #If not set, it will use regular package summary logic. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY}) + endif() endif() -endif() -if(NOT CPACK_RPM_PACKAGE_DESCRIPTION) - if(CPACK_RPM_PACKAGE_DESCRIPTION_) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) - elseif(CPACK_PACKAGE_DESCRIPTION_FILE) - file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION) - else () - set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available") - endif () -endif () + if(NOT CPACK_RPM_PACKAGE_SUMMARY) + if(CPACK_PACKAGE_DESCRIPTION_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + else() + # if neither var is defined lets use the name as summary + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) + endif() + endif() -# CPACK_RPM_COMPRESSION_TYPE -# -if (CPACK_RPM_COMPRESSION_TYPE) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: User Specified RPM compression type: ${CPACK_RPM_COMPRESSION_TYPE}") - endif() - if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma") - set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio") - endif() - if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz") - set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio") - endif() - if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2") - set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio") - endif() - if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip") - set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio") - endif() -else() - set(CPACK_RPM_COMPRESSION_TYPE_TMP "") -endif() + # CPACK_RPM_PACKAGE_NAME (mandatory) + if(NOT CPACK_RPM_PACKAGE_NAME) + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) + endif() -if(CPACK_PACKAGE_RELOCATABLE) - set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) -endif() -if(CPACK_RPM_PACKAGE_RELOCATABLE) - unset(TMP_RPM_PREFIXES) + # CPACK_RPM_PACKAGE_VERSION (mandatory) + if(NOT CPACK_RPM_PACKAGE_VERSION) + if(NOT CPACK_PACKAGE_VERSION) + message(FATAL_ERROR "RPM package requires a package version") + endif() + set(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}) + endif() + # Replace '-' in version with '_' + # '-' character is an Illegal RPM version character + # it is illegal because it is used to separate + # RPM "Version" from RPM "Release" + string(REPLACE "-" "_" CPACK_RPM_PACKAGE_VERSION ${CPACK_RPM_PACKAGE_VERSION}) + + # CPACK_RPM_PACKAGE_ARCHITECTURE (mandatory) + if(NOT CPACK_RPM_PACKAGE_ARCHITECTURE) + execute_process(COMMAND uname "-m" + OUTPUT_VARIABLE CPACK_RPM_PACKAGE_ARCHITECTURE + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}") + endif() + endif() - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Trying to build a relocatable package") + set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE}) + + #prefer component architecture + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE) + set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using component build arch = ${_CPACK_RPM_PACKAGE_ARCHITECTURE}") + endif() + endif() endif() - if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) - message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.") + if(${_CPACK_RPM_PACKAGE_ARCHITECTURE} STREQUAL "noarch") + set(TMP_RPM_BUILDARCH "Buildarch: ${_CPACK_RPM_PACKAGE_ARCHITECTURE}") else() - set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files) - cpack_rpm_prepare_relocation_paths() + set(TMP_RPM_BUILDARCH "") + endif() + + # CPACK_RPM_PACKAGE_RELEASE + # The RPM release is the numbering of the RPM package ITSELF + # this is the version of the PACKAGING and NOT the version + # of the CONTENT of the package. + # You may well need to generate a new RPM package release + # without changing the version of the packaged software. + # This is the case when the packaging is buggy (not) the software :=) + # If not set, 1 is a good candidate + if(NOT CPACK_RPM_PACKAGE_RELEASE) + set(CPACK_RPM_PACKAGE_RELEASE 1) + endif() + + # CPACK_RPM_PACKAGE_LICENSE + if(NOT CPACK_RPM_PACKAGE_LICENSE) + set(CPACK_RPM_PACKAGE_LICENSE "unknown") + endif() + + # CPACK_RPM_PACKAGE_GROUP + if(NOT CPACK_RPM_PACKAGE_GROUP) + set(CPACK_RPM_PACKAGE_GROUP "unknown") + endif() + + # CPACK_RPM_PACKAGE_VENDOR + if(NOT CPACK_RPM_PACKAGE_VENDOR) + if(CPACK_PACKAGE_VENDOR) + set(CPACK_RPM_PACKAGE_VENDOR "${CPACK_PACKAGE_VENDOR}") + else() + set(CPACK_RPM_PACKAGE_VENDOR "unknown") + endif() endif() -endif() -# Check if additional fields for RPM spec header are given -# There may be some COMPONENT specific variables as well -# If component specific var is not provided we use the global one -# for each component -foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + # CPACK_RPM_PACKAGE_SOURCE + # The name of the source tarball in case we generate a source RPM + + # CPACK_RPM_PACKAGE_DESCRIPTION + # The variable content may be either + # - explicitly given by the user or + # - filled with the content of CPACK_PACKAGE_DESCRIPTION_FILE + # if it is defined + # - set to a default value + # + + #Check for a component description first. + #If not set, it will use regular package description logic. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION}) + elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION}) + endif() + endif() + + if(NOT CPACK_RPM_PACKAGE_DESCRIPTION) + if(CPACK_PACKAGE_DESCRIPTION_FILE) + file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION) + else () + set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available") + endif () + endif () + + # CPACK_RPM_COMPRESSION_TYPE + # + if (CPACK_RPM_COMPRESSION_TYPE) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User Specified RPM compression type: ${CPACK_RPM_COMPRESSION_TYPE}") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio") + endif() + else() + set(CPACK_RPM_COMPRESSION_TYPE_TMP "") + endif() + + if(CPACK_PACKAGE_RELOCATABLE) + set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) + endif() + if(CPACK_RPM_PACKAGE_RELOCATABLE) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}") + message("CPackRPM:Debug: Trying to build a relocatable package") endif() - if(CPACK_RPM_PACKAGE_COMPONENT) - if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}") - endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}}) - else() - if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) + message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.") + else() + set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files) + cpack_rpm_prepare_relocation_paths() + endif() + endif() + + # Check if additional fields for RPM spec header are given + # There may be some COMPONENT specific variables as well + # If component specific var is not provided we use the global one + # for each component + foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}") + endif() + if(CPACK_RPM_PACKAGE_COMPONENT) + if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined") - message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}") + endif() + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}}) + else() + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined") + message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + endif() + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) + endif() + else() + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") endif() - endif() - else() - if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) - endif() - 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(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}") - # The following keywords require parentheses around the "pre" or "post" suffix in the final RPM spec file. - set(SCRIPTS_REQUIREMENTS_LIST REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) - list(FIND SCRIPTS_REQUIREMENTS_LIST ${_RPM_SPEC_HEADER} IS_SCRIPTS_REQUIREMENT_FOUND) - if(NOT ${IS_SCRIPTS_REQUIREMENT_FOUND} EQUAL -1) - string(REPLACE "_" "(" _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}") - set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME})") + # 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(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}") + # The following keywords require parentheses around the "pre" or "post" suffix in the final RPM spec file. + set(SCRIPTS_REQUIREMENTS_LIST REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + list(FIND SCRIPTS_REQUIREMENTS_LIST ${_RPM_SPEC_HEADER} IS_SCRIPTS_REQUIREMENT_FOUND) + if(NOT ${IS_SCRIPTS_REQUIREMENT_FOUND} EQUAL -1) + string(REPLACE "_" "(" _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}") + set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME})") + endif() + if(CPACK_RPM_PACKAGE_DEBUG) + 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}") + unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) endif() + endforeach() + + # CPACK_RPM_SPEC_INSTALL_POST + # May be used to define a RPM post intallation script + # for example setting it to "/bin/true" may prevent + # rpmbuild from stripping binaries. + if(CPACK_RPM_SPEC_INSTALL_POST) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") + message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}") endif() - set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") - unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) + set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}") endif() -endforeach() -# CPACK_RPM_SPEC_INSTALL_POST -# May be used to define a RPM post intallation script -# for example setting it to "/bin/true" may prevent -# rpmbuild from stripping binaries. -if(CPACK_RPM_SPEC_INSTALL_POST) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}") - endif() - set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}") -endif() - -# CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE) -# CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE) -# May be used to embed a post (un)installation script in the spec file. -# The refered script file(s) will be read and directly -# put after the %post or %postun section -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE) - set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE}) + # CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE) + # CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE) + # May be used to embed a post (un)installation script in the spec file. + # The refered script file(s) will be read and directly + # put after the %post or %postun section + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE) + set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) + endif() + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE) + set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) + endif() else() set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) - endif() - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE) - set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE}) - else() set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) endif() -else() - set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) - set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) -endif() -# Handle post-install file if it has been specified -if(CPACK_RPM_POST_INSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE}) - file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL) + # Handle post-install file if it has been specified + if(CPACK_RPM_POST_INSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE}) + file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no post install file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_POSTINSTALL "") endif() -else() - # reset SPEC var value if no post install file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_POSTINSTALL "") -endif() -# Handle post-uninstall file if it has been specified -if(CPACK_RPM_POST_UNINSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE}) - file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL) + # Handle post-uninstall file if it has been specified + if(CPACK_RPM_POST_UNINSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE}) + file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no post uninstall file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_POSTUNINSTALL "") endif() -else() - # reset SPEC var value if no post uninstall file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_POSTUNINSTALL "") -endif() -# CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE) -# CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE) -# May be used to embed a pre (un)installation script in the spec file. -# The refered script file(s) will be read and directly -# put after the %pre or %preun section -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE) - set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE}) + # CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE) + # CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE) + # May be used to embed a pre (un)installation script in the spec file. + # The refered script file(s) will be read and directly + # put after the %pre or %preun section + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE) + set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) + endif() + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE) + set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) + endif() else() set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) - endif() - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE) - set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE}) - else() set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) endif() -else() - set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) - set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) -endif() -# Handle pre-install file if it has been specified -if(CPACK_RPM_PRE_INSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE}) - file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL) + # Handle pre-install file if it has been specified + if(CPACK_RPM_PRE_INSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE}) + file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no pre-install file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_PREINSTALL "") endif() -else() - # reset SPEC var value if no pre-install file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_PREINSTALL "") -endif() -# Handle pre-uninstall file if it has been specified -if(CPACK_RPM_PRE_UNINSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE}) - file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL) + # Handle pre-uninstall file if it has been specified + if(CPACK_RPM_PRE_UNINSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE}) + file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no pre-uninstall file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_PREUNINSTALL "") endif() -else() - # reset SPEC var value if no pre-uninstall file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_PREUNINSTALL "") -endif() -# CPACK_RPM_CHANGELOG_FILE -# May be used to embed a changelog in the spec file. -# The refered file will be read and directly put after the %changelog section -if(CPACK_RPM_CHANGELOG_FILE) - if(EXISTS ${CPACK_RPM_CHANGELOG_FILE}) - file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG) + # CPACK_RPM_CHANGELOG_FILE + # May be used to embed a changelog in the spec file. + # The refered file will be read and directly put after the %changelog section + if(CPACK_RPM_CHANGELOG_FILE) + if(EXISTS ${CPACK_RPM_CHANGELOG_FILE}) + file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG) + else() + message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring") + endif() else() - message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring") - endif() -else() - set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)") -endif() - -# CPACK_RPM_SPEC_MORE_DEFINE -# This is a generated spec rpm file spaceholder -if(CPACK_RPM_SPEC_MORE_DEFINE) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: User defined more define spec line specified:\n ${CPACK_RPM_SPEC_MORE_DEFINE}") + set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)") endif() -endif() -# Now we may create the RPM build tree structure -set(CPACK_RPM_ROOTDIR "${CPACK_TOPLEVEL_DIRECTORY}") -message(STATUS "CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=${CPACK_RPM_ROOTDIR}") -# Prepare RPM build tree -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/tmp) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/BUILD) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/RPMS) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SOURCES) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SPECS) -file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SRPMS) - -#set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm") -set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}") -# it seems rpmbuild can't handle spaces in the path -# neither escaping (as below) nor putting quotes around the path seem to help -#string(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") -set(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") - -# if we are creating a relocatable package, omit parent directories of -# CPACK_RPM_PACKAGE_PREFIX. This is achieved by building a "filter list" -# which is passed to the find command that generates the content-list -if(CPACK_RPM_PACKAGE_RELOCATABLE) - # get a list of the elements in CPACK_RPM_PACKAGE_PREFIXES that are - # destinct parent paths of other relocation paths and remove the - # final element (so the install-prefix dir itself is not omitted - # from the RPM's content-list) - list(SORT RPM_USED_PACKAGE_PREFIXES) - set(_DISTINCT_PATH "NOT_SET") - foreach(_RPM_RELOCATION_PREFIX ${RPM_USED_PACKAGE_PREFIXES}) - if(NOT "${_RPM_RELOCATION_PREFIX}" MATCHES "${_DISTINCT_PATH}/.*") - set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}") - - string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS ".${_RPM_RELOCATION_PREFIX}") - list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1) - unset(_TMP_LIST) - # Now generate all of the parent dirs of the relocation path - foreach(_PREFIX_PATH_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS}) - list(APPEND _TMP_LIST "${_PREFIX_PATH_ELEM}") - string(REPLACE ";" "/" _OMIT_DIR "${_TMP_LIST}") - list(FIND _RPM_DIRS_TO_OMIT "${_OMIT_DIR}" _DUPLICATE_FOUND) - if(_DUPLICATE_FOUND EQUAL -1) - set(_OMIT_DIR "-o -path ${_OMIT_DIR}") - separate_arguments(_OMIT_DIR) - list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR}) - endif() - endforeach() + # CPACK_RPM_SPEC_MORE_DEFINE + # This is a generated spec rpm file spaceholder + if(CPACK_RPM_SPEC_MORE_DEFINE) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User defined more define spec line specified:\n ${CPACK_RPM_SPEC_MORE_DEFINE}") endif() - endforeach() -endif() - -if (CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Initial list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") -endif() + endif() -if (NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) - set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include) - if (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION) - message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.") - list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}") + # Now we may create the RPM build tree structure + set(CPACK_RPM_ROOTDIR "${CPACK_TOPLEVEL_DIRECTORY}") + message(STATUS "CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=${CPACK_RPM_ROOTDIR}") + # Prepare RPM build tree + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/tmp) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/BUILD) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/RPMS) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SOURCES) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SPECS) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SRPMS) + + #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${_CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm") + set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}") + # it seems rpmbuild can't handle spaces in the path + # neither escaping (as below) nor putting quotes around the path seem to help + #string(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") + set(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") + + # if we are creating a relocatable package, omit parent directories of + # CPACK_RPM_PACKAGE_PREFIX. This is achieved by building a "filter list" + # which is passed to the find command that generates the content-list + if(CPACK_RPM_PACKAGE_RELOCATABLE) + # get a list of the elements in CPACK_RPM_PACKAGE_PREFIXES that are + # destinct parent paths of other relocation paths and remove the + # final element (so the install-prefix dir itself is not omitted + # from the RPM's content-list) + set(SORTED_RPM_USED_PACKAGE_PREFIXES "${RPM_USED_PACKAGE_PREFIXES}") + list(SORT SORTED_RPM_USED_PACKAGE_PREFIXES) + set(_DISTINCT_PATH "NOT_SET") + foreach(_RPM_RELOCATION_PREFIX ${SORTED_RPM_USED_PACKAGE_PREFIXES}) + if(NOT "${_RPM_RELOCATION_PREFIX}" MATCHES "${_DISTINCT_PATH}/.*") + set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}") + + string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS ".${_RPM_RELOCATION_PREFIX}") + list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1) + unset(_TMP_LIST) + # Now generate all of the parent dirs of the relocation path + foreach(_PREFIX_PATH_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS}) + list(APPEND _TMP_LIST "${_PREFIX_PATH_ELEM}") + string(REPLACE ";" "/" _OMIT_DIR "${_TMP_LIST}") + list(FIND _RPM_DIRS_TO_OMIT "${_OMIT_DIR}" _DUPLICATE_FOUND) + if(_DUPLICATE_FOUND EQUAL -1) + set(_OMIT_DIR "-o -path ${_OMIT_DIR}") + separate_arguments(_OMIT_DIR) + list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR}) + endif() + endforeach() + endif() + endforeach() endif() -endif() -if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) if (CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}") - endif() - foreach(_DIR ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}) - list(APPEND _RPM_DIRS_TO_OMIT "-o;-path;.${_DIR}") - endforeach() -endif() -if (CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") -endif() + message("CPackRPM:Debug: Initial list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") + endif() + + if (NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include) + if (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION) + message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.") + list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}") + endif() + endif() -# Use files tree to construct files command (spec file) -# We should not forget to include symlinks (thus -o -type l) -# We should include directory as well (thus -type d) -# but not the main local dir "." (thus -a -not -name ".") -# We must remove the './' due to the local search and escape the -# file name by enclosing it between double quotes (thus the sed) -# Then we must authorize any man pages extension (adding * at the end) -# because rpmbuild may automatically compress those files -execute_process(COMMAND find . -type f -o -type l -o (-type d -a -not ( -name "." ${_RPM_DIRS_TO_OMIT} ) ) - COMMAND sed s:.*/man.*/.*:&*: - COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/ - WORKING_DIRECTORY "${WDIR}" - OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES) - -# In component case, put CPACK_ABSOLUTE_DESTINATION_FILES_<COMPONENT> -# into CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL -# otherwise, put CPACK_ABSOLUTE_DESTINATION_FILES -# This must be done BEFORE the CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL handling -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_ABSOLUTE_DESTINATION_FILES) - set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}") - set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${${COMPONENT_FILES_TAG}}") - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Handling Absolute Destination Files: <${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}>") - message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + if (CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}") endif() + foreach(_DIR ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}) + list(APPEND _RPM_DIRS_TO_OMIT "-o;-path;.${_DIR}") + endforeach() endif() -else() - if(CPACK_ABSOLUTE_DESTINATION_FILES) - set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}") + if (CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") endif() -endif() -# In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST) - set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") - message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + # Use files tree to construct files command (spec file) + # We should not forget to include symlinks (thus -o -type l) + # We should include directory as well (thus -type d) + # but not the main local dir "." (thus -a -not -name ".") + # We must remove the './' due to the local search and escape the + # file name by enclosing it between double quotes (thus the sed) + # Then we must authorize any man pages extension (adding * at the end) + # because rpmbuild may automatically compress those files + execute_process(COMMAND find . -type f -o -type l -o (-type d -a -not ( -name "." ${_RPM_DIRS_TO_OMIT} ) ) + COMMAND sed s:.*/man.*/.*:&*: + COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/ + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES) + + # In component case, put CPACK_ABSOLUTE_DESTINATION_FILES_<COMPONENT> + # into CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + # otherwise, put CPACK_ABSOLUTE_DESTINATION_FILES + # This must be done BEFORE the CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL handling + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_ABSOLUTE_DESTINATION_FILES) + set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}") + set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${${COMPONENT_FILES_TAG}}") + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling Absolute Destination Files: <${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}>") + message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + endif() endif() else() - set(CPACK_RPM_USER_FILELIST_INTERNAL "") + if(CPACK_ABSOLUTE_DESTINATION_FILES) + set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}") + endif() endif() -else() - if(CPACK_RPM_USER_FILELIST) - set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}") + + # In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST) + set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") + message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + endif() + else() + set(CPACK_RPM_USER_FILELIST_INTERNAL "") + endif() else() - set(CPACK_RPM_USER_FILELIST_INTERNAL "") + if(CPACK_RPM_USER_FILELIST) + set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}") + else() + set(CPACK_RPM_USER_FILELIST_INTERNAL "") + endif() endif() -endif() -# Handle user specified file line list in CPACK_RPM_USER_FILELIST_INTERNAL -# Remove those files from CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL -# or CPACK_RPM_INSTALL_FILES, -# hence it must be done before these auto-generated lists are processed. -if(CPACK_RPM_USER_FILELIST_INTERNAL) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") - endif() + # Handle user specified file line list in CPACK_RPM_USER_FILELIST_INTERNAL + # Remove those files from CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + # or CPACK_RPM_INSTALL_FILES, + # hence it must be done before these auto-generated lists are processed. + if(CPACK_RPM_USER_FILELIST_INTERNAL) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") + endif() + + # Create CMake list from CPACK_RPM_INSTALL_FILES + string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) + string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST + "${CPACK_RPM_INSTALL_FILES_LIST}") + string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST + "${CPACK_RPM_INSTALL_FILES_LIST}") + + set(CPACK_RPM_USER_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_USER_FILELIST_INTERNAL) + string(REGEX REPLACE "%[A-Za-z0-9\(\),-]* " "" F_PATH ${F}) + string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F}) - # Create CMake list from CPACK_RPM_INSTALL_FILES - string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) - string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") - string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>") + endif() + if(F_PREFIX) + set(F_PREFIX "${F_PREFIX} ") + endif() + # Rebuild the user list file + set(CPACK_RPM_USER_INSTALL_FILES "${CPACK_RPM_USER_INSTALL_FILES}${F_PREFIX}\"${F_PATH}\"\n") + + # Remove from CPACK_RPM_INSTALL_FILES and CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${F_PATH}) + # ABSOLUTE destination files list may not exists at all + if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH}) + endif() + + endforeach() - set(CPACK_RPM_USER_INSTALL_FILES "") - foreach(F IN LISTS CPACK_RPM_USER_FILELIST_INTERNAL) - string(REGEX REPLACE "%[A-Za-z0-9\(\),-]* " "" F_PATH ${F}) - string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F}) + # Rebuild CPACK_RPM_INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endforeach() + else() + set(CPACK_RPM_USER_INSTALL_FILES "") + endif() + if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>") + message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}") endif() - if(F_PREFIX) - set(F_PREFIX "${F_PREFIX} ") - endif() - # Rebuild the user list file - set(CPACK_RPM_USER_INSTALL_FILES "${CPACK_RPM_USER_INSTALL_FILES}${F_PREFIX}\"${F_PATH}\"\n") - - # Remove from CPACK_RPM_INSTALL_FILES and CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL - list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${F_PATH}) - # ABSOLUTE destination files list may not exists at all - if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) - list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH}) + # Remove trailing space + string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) + # Transform endline separated - string into CMake List + string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") + # Remove unecessary quotes + string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") + # Remove ABSOLUTE install file from INSTALL FILE LIST + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}) + # Rebuild INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endforeach() + # Build ABSOLUTE_INSTALL_FILES + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n") + endforeach() + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}") + message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}") endif() + else() + # reset vars in order to avoid leakage of value(s) from one component to another + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + endif() - endforeach() + # Prepare install files + cpack_rpm_prepare_install_files( + "${CPACK_RPM_INSTALL_FILES}" + "${WDIR}" + "${RPM_USED_PACKAGE_PREFIXES}" + "${CPACK_RPM_PACKAGE_RELOCATABLE}" + ) - # Rebuild CPACK_RPM_INSTALL_FILES - set(CPACK_RPM_INSTALL_FILES "") - foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") - endforeach() -else() - set(CPACK_RPM_USER_INSTALL_FILES "") -endif() + # The name of the final spec file to be used by rpmbuild + set(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec") -if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}") - endif() - # Remove trailing space - string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) - # Transform endline separated - string into CMake List - string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") - # Remove unecessary quotes - string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") - # Remove ABSOLUTE install file from INSTALL FILE LIST - list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}) - # Rebuild INSTALL_FILES - set(CPACK_RPM_INSTALL_FILES "") - foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") - endforeach() - # Build ABSOLUTE_INSTALL_FILES - set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") - foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) - set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n") - endforeach() + # Print out some debug information if we were asked for that if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}") - message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}") - endif() -else() - # reset vars in order to avoid leakage of value(s) from one component to another - set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") -endif() - -# Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir -# This is necessary to avoid duplicate files since rpmbuild do -# recursion on its own when encountering a pathname which is a directory -# which is not flagged as %dir -string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) -string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") -string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") -set(CPACK_RPM_INSTALL_FILES "") -foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - if(IS_DIRECTORY "${WDIR}/${F}") - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}%dir \"${F}\"\n") - else() - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + message("CPackRPM:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}") + message("CPackRPM:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}") + message("CPackRPM:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}") + message("CPackRPM:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}") + message("CPackRPM:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}") + message("CPackRPM:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}") + message("CPackRPM:Debug: CPACK_RPM_BINARY_SPECFILE = ${CPACK_RPM_BINARY_SPECFILE}") + message("CPackRPM:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}") + message("CPackRPM:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}") endif() -endforeach() -set(CPACK_RPM_INSTALL_FILES_LIST "") - -# The name of the final spec file to be used by rpmbuild -set(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec") - -# Print out some debug information if we were asked for that -if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}") - message("CPackRPM:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}") - message("CPackRPM:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}") - message("CPackRPM:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}") - message("CPackRPM:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}") - message("CPackRPM:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}") - message("CPackRPM:Debug: CPACK_RPM_BINARY_SPECFILE = ${CPACK_RPM_BINARY_SPECFILE}") - message("CPackRPM:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}") - message("CPackRPM:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}") -endif() -# protect @ in pathname in order to avoid their -# interpretation during the configure_file step -set(CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES}") -set(PROTECTED_AT "@") -string(REPLACE "@" "\@PROTECTED_AT\@" CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES_LIST}") -set(CPACK_RPM_INSTALL_FILES_LIST "") + # + # USER generated/provided spec file handling. + # -# -# USER generated/provided spec file handling. -# - -# We can have a component specific spec file. -if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE) - set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE}) -endif() + # We can have a component specific spec file. + if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE) + set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE}) + endif() -# We should generate a USER spec file template: -# - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE -# - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE -if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) - file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in + # We should generate a USER spec file template: + # - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE + # - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE + if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in "# -*- rpm-spec -*- BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@ Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@ @@ -1239,6 +1565,7 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT %clean %post +\@RPM_SYMLINK_POSTINSTALL\@ \@CPACK_RPM_SPEC_POSTINSTALL\@ %postun @@ -1259,65 +1586,54 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT %changelog \@CPACK_RPM_SPEC_CHANGELOG\@ ") - # Stop here if we were asked to only generate a template USER spec file - # The generated file may then be used as a template by user who wants - # to customize their own spec file. - if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE) - message(FATAL_ERROR "CPackRPM: STOP here Generated USER binary spec file templare is: ${CPACK_RPM_BINARY_SPECFILE}.in") + # Stop here if we were asked to only generate a template USER spec file + # The generated file may then be used as a template by user who wants + # to customize their own spec file. + if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE) + message(FATAL_ERROR "CPackRPM: STOP here Generated USER binary spec file templare is: ${CPACK_RPM_BINARY_SPECFILE}.in") + endif() endif() -endif() - -# After that we may either use a user provided spec file -# or generate one using appropriate variables value. -if(CPACK_RPM_USER_BINARY_SPECFILE) - # User may have specified SPECFILE just use it - message("CPackRPM: Will use USER specified spec file: ${CPACK_RPM_USER_BINARY_SPECFILE}") - # The user provided file is processed for @var replacement - configure_file(${CPACK_RPM_USER_BINARY_SPECFILE} ${CPACK_RPM_BINARY_SPECFILE} @ONLY) -else() - # No User specified spec file, will use the generated spec file - message("CPackRPM: Will use GENERATED spec file: ${CPACK_RPM_BINARY_SPECFILE}") - # Note the just created file is processed for @var replacement - configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY) -endif() -# remove AT protection -unset(PROTECTED_AT) - -if(RPMBUILD_EXECUTABLE) - # Now call rpmbuild using the SPECFILE - execute_process( - COMMAND "${RPMBUILD_EXECUTABLE}" -bb - --define "_topdir ${CPACK_RPM_DIRECTORY}" - --buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" - "${CPACK_RPM_BINARY_SPECFILE}" - WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" - RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT - ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err" - OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") - if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT) - file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err RPMBUILDERR) - file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out RPMBUILDOUT) - message("CPackRPM:Debug: You may consult rpmbuild logs in: ") - message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err") - message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") - message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") - message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + # After that we may either use a user provided spec file + # or generate one using appropriate variables value. + if(CPACK_RPM_USER_BINARY_SPECFILE) + # User may have specified SPECFILE just use it + message("CPackRPM: Will use USER specified spec file: ${CPACK_RPM_USER_BINARY_SPECFILE}") + # The user provided file is processed for @var replacement + configure_file(${CPACK_RPM_USER_BINARY_SPECFILE} ${CPACK_RPM_BINARY_SPECFILE} @ONLY) + else() + # No User specified spec file, will use the generated spec file + message("CPackRPM: Will use GENERATED spec file: ${CPACK_RPM_BINARY_SPECFILE}") + # Note the just created file is processed for @var replacement + configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY) endif() -else() - if(ALIEN_EXECUTABLE) - message(FATAL_ERROR "RPM packaging through alien not done (yet)") + + if(RPMBUILD_EXECUTABLE) + # Now call rpmbuild using the SPECFILE + execute_process( + COMMAND "${RPMBUILD_EXECUTABLE}" -bb + --define "_topdir ${CPACK_RPM_DIRECTORY}" + --buildroot "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" + --target "${_CPACK_RPM_PACKAGE_ARCHITECTURE}" + "${CPACK_RPM_BINARY_SPECFILE}" + WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" + RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT + ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err" + OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") + if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err RPMBUILDERR) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out RPMBUILDOUT) + message("CPackRPM:Debug: You may consult rpmbuild logs in: ") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err") + message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") + message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + endif() + else() + if(ALIEN_EXECUTABLE) + message(FATAL_ERROR "RPM packaging through alien not done (yet)") + endif() endif() -endif() +endfunction() -# reset variables from temporary variables -if(CPACK_RPM_PACKAGE_SUMMARY_) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) -else() - unset(CPACK_RPM_PACKAGE_SUMMARY) -endif() -if(CPACK_RPM_PACKAGE_DESCRIPTION_) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) -else() - unset(CPACK_RPM_PACKAGE_DESCRIPTION) -endif() +cpack_rpm_generate_package() diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake index 0a47e19..5fe51a6 100644 --- a/Modules/CPackWIX.cmake +++ b/Modules/CPackWIX.cmake @@ -148,6 +148,11 @@ # Currently fragments can be injected into most # Component, File and Directory elements. # +# The following additional special Ids can be used: +# +# * ``#PRODUCT`` for the ``<Product>`` element. +# * ``#PRODUCTFEATURE`` for the root ``<Feature>`` element. +# # The following example illustrates how this works. # # Given that the WiX generator creates the following XML element: @@ -233,7 +238,7 @@ # * ARPSIZE - Size (in kilobytes) of the application #============================================================================= -# Copyright 2014 Kitware, Inc. +# Copyright 2014-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index a607c52..4519627 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -45,6 +45,10 @@ # Specify options to be passed to gcov. The ``gcov`` command # is run as ``gcov <options>... -o <gcov-dir> <file>.gcda``. # If not specified, the default option is just ``-b``. +# +# ``QUIET`` +# Suppress non-error messages that otherwise would have been +# printed out by this function. #============================================================================= # Copyright 2014-2015 Kitware, Inc. @@ -60,7 +64,7 @@ # License text for the above reference.) include(CMakeParseArguments) function(ctest_coverage_collect_gcov) - set(options "") + set(options QUIET) set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND) set(multiValueArgs GCOV_OPTIONS) cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}" @@ -106,8 +110,10 @@ function(ctest_coverage_collect_gcov) # 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.") + if (NOT GCOV_QUIET) + message("ctest_coverage_collect_gcov: No .gcda files found, " + "ignoring coverage request.") + endif() return() endif() # setup the dir for the coverage files @@ -130,7 +136,9 @@ function(ctest_coverage_collect_gcov) WORKING_DIRECTORY ${coverage_dir}) endforeach() if(NOT "${res}" EQUAL 0) - message(STATUS "Error running gcov: ${res} ${out}") + if (NOT GCOV_QUIET) + message(STATUS "Error running gcov: ${res} ${out}") + endif() endif() # create json file with project information file(WRITE ${coverage_dir}/data.json @@ -151,8 +159,15 @@ function(ctest_coverage_collect_gcov) ${coverage_dir}/data.json ${label_files} ") + + if (GCOV_QUIET) + set(tar_opts "cfj") + else() + set(tar_opts "cvfj") + endif() + execute_process(COMMAND - ${CMAKE_COMMAND} -E tar cvfj ${GCOV_TARBALL} + ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL} "--mtime=1970-01-01 0:0:0 UTC" --files-from=${coverage_dir}/coverage_file_list.txt WORKING_DIRECTORY ${binary_dir}) diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake index 53f3454..750e4fb 100644 --- a/Modules/CheckCCompilerFlag.cmake +++ b/Modules/CheckCCompilerFlag.cmake @@ -13,7 +13,7 @@ # Will be created as an internal cache variable. # # This internally calls the check_c_source_compiles macro and sets -# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for +# CMAKE_REQUIRED_FLAGS to <flag>. See help for # CheckCSourceCompiles for a listing of variables that can otherwise # modify the build. The result only tells that the compiler does not # give an error message when it encounters the flag. If the flag has @@ -38,8 +38,8 @@ include(CheckCSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT) - set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${_FLAG}") # Normalize locale during test compilation. set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) @@ -60,5 +60,5 @@ macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT) unset(_CheckCCompilerFlag_LOCALE_VARS) unset(_CheckCCompilerFlag_COMMON_PATTERNS) - set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") + set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") endmacro () diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake index fab3a05..71b3fd2 100644 --- a/Modules/CheckCXXCompilerFlag.cmake +++ b/Modules/CheckCXXCompilerFlag.cmake @@ -12,7 +12,7 @@ # <var> - variable to store the result # # This internally calls the check_cxx_source_compiles macro and sets -# CMAKE_REQUIRED_DEFINITIONS to <flag>. See help for +# CMAKE_REQUIRED_FLAGS to <flag>. See help for # CheckCXXSourceCompiles for a listing of variables that can otherwise # modify the build. The result only tells that the compiler does not # give an error message when it encounters the flag. If the flag has @@ -37,8 +37,8 @@ include(CheckCXXSourceCompiles) include(CMakeCheckCompilerFlagCommonPatterns) macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) - set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${_FLAG}") # Normalize locale during test compilation. set(_CheckCXXCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) @@ -59,6 +59,6 @@ macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) unset(_CheckCXXCompilerFlag_LOCALE_VARS) unset(_CheckCXXCompilerFlag_COMMON_PATTERNS) - set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") + set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") endmacro () diff --git a/Modules/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake new file mode 100644 index 0000000..c476661 --- /dev/null +++ b/Modules/CheckFortranCompilerFlag.cmake @@ -0,0 +1,66 @@ +#.rst: +# CheckFortranCompilerFlag +# ------------------------ +# +# Check whether the Fortran compiler supports a given flag. +# +# CHECK_Fortran_COMPILER_FLAG(<flag> <var>) +# +# :: +# +# <flag> - the compiler flag +# <var> - variable to store the result +# Will be created as an internal cache variable. +# +# This internally calls the check_fortran_source_compiles macro and +# sets CMAKE_REQUIRED_FLAGS to <flag>. See help for +# CheckFortranSourceCompiles for a listing of variables that can +# otherwise modify the build. The result only tells that the compiler +# does not give an error message when it encounters the flag. If the +# flag has any effect or even a specific one is beyond the scope of +# this module. + +#============================================================================= +# Copyright 2015 Nicolas Bock <nicolasbock@gmail.com> +# Copyright 2006-2011 Kitware, Inc. +# Copyright 2006 Alexander Neundorf <neundorf@kde.org> +# Copyright 2011 Matthias Kretz <kretz@kde.org> +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# 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(CheckFortranSourceCompiles) +include(CMakeCheckCompilerFlagCommonPatterns) + +macro (CHECK_Fortran_COMPILER_FLAG _FLAG _RESULT) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${_FLAG}") + + # Normalize locale during test compilation. + set(_CheckFortranCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) + foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS}) + set(_CheckFortranCompilerFlag_SAVED_${v} "$ENV{${v}}") + set(ENV{${v}} C) + endforeach() + CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckFortranCompilerFlag_COMMON_PATTERNS) + CHECK_Fortran_SOURCE_COMPILES(" program test\n stop\n end program" ${_RESULT} + # Some compilers do not fail with a bad flag + FAIL_REGEX "command line option .* is valid for .* but not for Fortran" # GNU + ${_CheckFortranCompilerFlag_COMMON_PATTERNS} + ) + foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS}) + set(ENV{${v}} ${_CheckFortranCompilerFlag_SAVED_${v}}) + unset(_CheckFortranCompilerFlag_SAVED_${v}) + endforeach() + unset(_CheckFortranCompilerFlag_LOCALE_VARS) + unset(_CheckFortranCompilerFlag_COMMON_PATTERNS) + + set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endmacro () diff --git a/Modules/CheckStructHasMember.cmake b/Modules/CheckStructHasMember.cmake index de31d2c..6c15205 100644 --- a/Modules/CheckStructHasMember.cmake +++ b/Modules/CheckStructHasMember.cmake @@ -69,7 +69,7 @@ macro (CHECK_STRUCT_HAS_MEMBER _STRUCT _MEMBER _HEADER _RESULT) ${_INCLUDE_FILES} int main() { - (void)((${_STRUCT} *)0)->${_MEMBER}; + (void)sizeof(((${_STRUCT} *)0)->${_MEMBER}); return 0; } ") diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 86a31e4..2dc02f0 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -44,10 +44,10 @@ macro(cmake_record_cxx_compile_features) endmacro() set(_result 0) - if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + if (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 CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) if (_result EQUAL 0) _get_gcc_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() diff --git a/Modules/Compiler/GNU-Fortran.cmake b/Modules/Compiler/GNU-Fortran.cmake index dfd7927..e9c8a59 100644 --- a/Modules/Compiler/GNU-Fortran.cmake +++ b/Modules/Compiler/GNU-Fortran.cmake @@ -8,5 +8,8 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form") set(CMAKE_Fortran_FLAGS_MINSIZEREL_INIT "-Os") set(CMAKE_Fortran_FLAGS_RELEASE_INIT "-O3") +# No -isystem for Fortran because it will not find .mod files. +unset(CMAKE_INCLUDE_SYSTEM_FLAG_Fortran) + # Fortran-specific feature flags. set(CMAKE_Fortran_MODDIR_FLAG -J) diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake index c5b5203..92252cb 100644 --- a/Modules/Compiler/SunPro-C.cmake +++ b/Modules/Compiler/SunPro-C.cmake @@ -1,7 +1,6 @@ set(CMAKE_C_VERBOSE_FLAG "-#") set(CMAKE_C_COMPILE_OPTIONS_PIC -KPIC) -set(CMAKE_C_COMPILE_OPTIONS_PIE -KPIE) set(CMAKE_SHARED_LIBRARY_C_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-R") diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake index c7bc734..022b4d4 100644 --- a/Modules/Compiler/SunPro-CXX.cmake +++ b/Modules/Compiler/SunPro-CXX.cmake @@ -1,7 +1,6 @@ set(CMAKE_CXX_VERBOSE_FLAG "-v") set(CMAKE_CXX_COMPILE_OPTIONS_PIC -KPIC) -set(CMAKE_CXX_COMPILE_OPTIONS_PIE -KPIE) set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-R") diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake index e4db1e8..196aae4 100644 --- a/Modules/Compiler/SunPro-Fortran.cmake +++ b/Modules/Compiler/SunPro-Fortran.cmake @@ -2,6 +2,7 @@ set(CMAKE_Fortran_VERBOSE_FLAG "-v") set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-fixed") set(CMAKE_Fortran_FORMAT_FREE_FLAG "-free") +set(CMAKE_Fortran_COMPILE_OPTIONS_PIC "-KPIC") set(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-KPIC") set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-G") set(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-R") diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in index 7f686a2..20f3da3 100644 --- a/Modules/CompilerId/Xcode-3.pbxproj.in +++ b/Modules/CompilerId/Xcode-3.pbxproj.in @@ -79,7 +79,6 @@ 1DEB928A08733DD80010E9CD = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; ONLY_ACTIVE_ARCH = YES; CODE_SIGNING_REQUIRED = NO; CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)"; diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake index b1a2370..de475e4 100644 --- a/Modules/DeployQt4.cmake +++ b/Modules/DeployQt4.cmake @@ -126,7 +126,10 @@ function(write_qt4_conf qt_conf_dir qt_conf_contents) endfunction() function(resolve_qt4_paths paths_var) - set(executable_path ${ARGV1}) + unset(executable_path) + if(ARGC GREATER 1) + set(executable_path ${ARGV1}) + endif() set(paths_resolved) foreach(path ${${paths_var}}) @@ -144,11 +147,26 @@ function(resolve_qt4_paths paths_var) endfunction() function(fixup_qt4_executable executable) - set(qtplugins ${ARGV1}) - set(libs ${ARGV2}) - set(dirs ${ARGV3}) - set(plugins_dir ${ARGV4}) - set(request_qt_conf ${ARGV5}) + unset(qtplugins) + if(ARGC GREATER 1) + set(qtplugins ${ARGV1}) + endif() + unset(libs) + if(ARGC GREATER 2) + set(libs ${ARGV2}) + endif() + unset(dirs) + if(ARGC GREATER 3) + set(dirs ${ARGV3}) + endif() + unset(plugins_dir) + if(ARGC GREATER 4) + set(plugins_dir ${ARGV4}) + endif() + unset(request_qt_conf) + if(ARGC GREATER 5) + set(request_qt_conf ${ARGV5}) + endif() message(STATUS "fixup_qt4_executable") message(STATUS " executable='${executable}'") @@ -169,7 +187,7 @@ function(fixup_qt4_executable executable) set(qt_conf_dir "${executable}/Contents/Resources") set(executable_path "${executable}") set(write_qt_conf TRUE) - if(NOT plugins_dir) + if(NOT DEFINED plugins_dir) set(plugins_dir "${DeployQt4_apple_plugins_dir}") endif() else() @@ -204,9 +222,19 @@ function(fixup_qt4_executable executable) endfunction() function(install_qt4_plugin_path plugin executable copy installed_plugin_path_var) - set(plugins_dir ${ARGV4}) - set(component ${ARGV5}) - set(configurations ${ARGV6}) + unset(plugins_dir) + if(ARGC GREATER 4) + set(plugins_dir ${ARGV4}) + endif() + unset(component) + if(ARGC GREATER 5) + set(component ${ARGV5}) + endif() + unset(configurations) + if(ARGC GREATER 6) + set(configurations ${ARGV6}) + endif() + if(EXISTS "${plugin}") if(APPLE) if(NOT plugins_dir) @@ -253,8 +281,15 @@ function(install_qt4_plugin_path plugin executable copy installed_plugin_path_va endfunction() function(install_qt4_plugin plugin executable copy installed_plugin_path_var) - set(plugins_dir ${ARGV4}) - set(component ${ARGV5}) + unset(plugins_dir) + if(ARGC GREATER 4) + set(plugins_dir ${ARGV4}) + endif() + unset(component) + if(ARGC GREATER 5) + set(component ${ARGV5}) + endif() + if(EXISTS "${plugin}") install_qt4_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}") else() @@ -287,12 +322,31 @@ function(install_qt4_plugin plugin executable copy installed_plugin_path_var) endfunction() function(install_qt4_executable executable) - set(qtplugins ${ARGV1}) - set(libs ${ARGV2}) - set(dirs ${ARGV3}) - set(plugins_dir ${ARGV4}) - set(request_qt_conf ${ARGV5}) - set(component ${ARGV6}) + unset(qtplugins) + if(ARGC GREATER 1) + set(qtplugins ${ARGV1}) + endif() + unset(libs) + if(ARGC GREATER 2) + set(libs ${ARGV2}) + endif() + unset(dirs) + if(ARGC GREATER 3) + set(dirs ${ARGV3}) + endif() + unset(plugins_dir) + if(ARGC GREATER 4) + set(plugins_dir ${ARGV4}) + endif() + unset(request_qt_conf) + if(ARGC GREATER 5) + set(request_qt_conf ${ARGV5}) + endif() + unset(component) + if(ARGC GREATER 6) + set(component ${ARGV6}) + endif() + if(QT_LIBRARY_DIR) list(APPEND dirs "${QT_LIBRARY_DIR}") endif() diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake index 741db81..883ab69 100644 --- a/Modules/ExternalData.cmake +++ b/Modules/ExternalData.cmake @@ -155,13 +155,23 @@ calling any of the functions provided by this module. inactivity timeout, in seconds, with a default of ``60`` seconds. Set to ``0`` to disable enforcement. +.. variable:: ExternalData_URL_ALGO_<algo>_<key> + + Specify a custom URL component to be substituted for URL template + placeholders of the form ``%(algo:<key>)``, where ``<key>`` is a + valid C identifier, when fetching an object referenced via hash + algorithm ``<algo>``. If not defined, the default URL component + is just ``<algo>`` for any ``<key>``. + .. 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)``. + value for ``%(hash)``. Alternatively one may use ``%(algo:<key>)`` + with ``ExternalData_URL_ALGO_<algo>_<key>`` variables to gain more + flexibility in remote URLs. Referencing Files ^^^^^^^^^^^^^^^^^ @@ -234,7 +244,8 @@ 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. +source directory. In order to match associated files in subdirectories, +specify a ``RECURSE:`` option, e.g. ``DATA{MyDataDir/,RECURSE:,REGEX:.*}``. Hash Algorithms ^^^^^^^^^^^^^^^ @@ -349,6 +360,25 @@ function(ExternalData_add_target target) "The key must be a valid C identifier.") endif() endif() + + # Store custom algorithm name to URL component maps. + if("${url_template}" MATCHES "%\\(algo:([^)]*)\\)") + set(key "${CMAKE_MATCH_1}") + if(key MATCHES "^[A-Za-z_][A-Za-z0-9_]*$") + string(REPLACE "|" ";" _algos "${_ExternalData_REGEX_ALGO}") + foreach(algo ${_algos}) + if(DEFINED ExternalData_URL_ALGO_${algo}_${key}) + string(CONCAT _ExternalData_CONFIG_CODE "${_ExternalData_CONFIG_CODE}\n" + "set(ExternalData_URL_ALGO_${algo}_${key} \"${ExternalData_URL_ALGO_${algo}_${key}}\")") + endif() + endforeach() + else() + message(FATAL_ERROR + "Bad %(algo:${key}) in URL template:\n" + " ${url_template}\n" + "The transform name must be a valid C identifier.") + endif() + endif() endforeach() # Store configuration for use by build-time script. @@ -568,6 +598,7 @@ function(_ExternalData_arg target arg options var_file) # Process options. set(series_option "") + set(recurse_option "") set(associated_files "") set(associated_regex "") foreach(opt ${options}) @@ -577,6 +608,9 @@ function(_ExternalData_arg target arg options var_file) elseif(opt STREQUAL ":") # Activate series matching. set(series_option "${opt}") + elseif(opt STREQUAL "RECURSE:") + # Activate recursive matching in directories. + set(recurse_option "${opt}") elseif("x${opt}" MATCHES "^[^][:/*?]+$") # Specific associated file. list(APPEND associated_files "${opt}") @@ -593,6 +627,9 @@ function(_ExternalData_arg target arg options var_file) if(associated_files OR associated_regex) message(FATAL_ERROR "Series option \"${series_option}\" not allowed with associated files.") endif() + if(recurse_option) + message(FATAL_ERROR "Recurse option \"${recurse_option}\" allowed only with directories.") + endif() # Load a whole file series. _ExternalData_arg_series() elseif(data_is_directory) @@ -605,6 +642,9 @@ function(_ExternalData_arg target arg options var_file) "must list associated files.") endif() else() + if(recurse_option) + message(FATAL_ERROR "Recurse option \"${recurse_option}\" allowed only with directories.") + endif() # Load the named data file. _ExternalData_arg_single() if(associated_files OR associated_regex) @@ -652,11 +692,18 @@ macro(_ExternalData_arg_associated) set(reldir "${reldir}/") endif() _ExternalData_exact_regex(reldir_regex "${reldir}") + if(recurse_option) + set(glob GLOB_RECURSE) + set(reldir_regex "${reldir_regex}(.+/)?") + else() + set(glob GLOB) + endif() # Find files named explicitly. foreach(file ${associated_files}) _ExternalData_exact_regex(file_regex "${file}") - _ExternalData_arg_find_files("${reldir}${file}" "${reldir_regex}${file_regex}") + _ExternalData_arg_find_files(${glob} "${reldir}${file}" + "${reldir_regex}${file_regex}") endforeach() # Find files matching the given regular expressions. @@ -666,13 +713,13 @@ macro(_ExternalData_arg_associated) set(all "${all}${sep}${reldir_regex}${regex}") set(sep "|") endforeach() - _ExternalData_arg_find_files("${reldir}" "${all}") + _ExternalData_arg_find_files(${glob} "${reldir}" "${all}") endmacro() macro(_ExternalData_arg_single) # Match only the named data by itself. _ExternalData_exact_regex(data_regex "${reldata}") - _ExternalData_arg_find_files("${reldata}" "${data_regex}") + _ExternalData_arg_find_files(GLOB "${reldata}" "${data_regex}") endmacro() macro(_ExternalData_arg_series) @@ -727,12 +774,15 @@ macro(_ExternalData_arg_series) # Then match base, number, and extension. _ExternalData_exact_regex(series_base "${relbase}") _ExternalData_exact_regex(series_ext "${ext}") - _ExternalData_arg_find_files("${relbase}*${ext}" + _ExternalData_arg_find_files(GLOB "${relbase}*${ext}" "${series_base}${series_match}${series_ext}") endmacro() -function(_ExternalData_arg_find_files pattern regex) - file(GLOB globbed RELATIVE "${top_src}" "${top_src}/${pattern}*") +function(_ExternalData_arg_find_files glob pattern regex) + cmake_policy(PUSH) + cmake_policy(SET CMP0009 NEW) + file(${glob} globbed RELATIVE "${top_src}" "${top_src}/${pattern}*") + cmake_policy(POP) foreach(entry IN LISTS globbed) if("x${entry}" MATCHES "^x(.*)(\\.(${_ExternalData_REGEX_EXT}))$") set(relname "${CMAKE_MATCH_1}") @@ -904,6 +954,16 @@ function(_ExternalData_download_object name hash algo var_obj) foreach(url_template IN LISTS ExternalData_URL_TEMPLATES) string(REPLACE "%(hash)" "${hash}" url_tmp "${url_template}") string(REPLACE "%(algo)" "${algo}" url "${url_tmp}") + if(url MATCHES "^(.*)%\\(algo:([A-Za-z_][A-Za-z0-9_]*)\\)(.*)$") + set(lhs "${CMAKE_MATCH_1}") + set(key "${CMAKE_MATCH_2}") + set(rhs "${CMAKE_MATCH_3}") + if(DEFINED ExternalData_URL_ALGO_${algo}_${key}) + set(url "${lhs}${ExternalData_URL_ALGO_${algo}_${key}}${rhs}") + else() + set(url "${lhs}${algo}${rhs}") + endif() + endif() message(STATUS "Fetching \"${url}\"") if(url MATCHES "^ExternalDataCustomScript://([A-Za-z_][A-Za-z0-9_]*)/(.*)$") _ExternalData_custom_fetch("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "${tmp}" err errMsg) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 74e8ae2..0c73d41 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -251,8 +251,8 @@ Create custom targets to build projects in external trees ``LOG 1`` Wrap step in script to log output - The command line, comment, and working directory of every standard and - custom step is processed to replace tokens ``<SOURCE_DIR>``, + The command line, comment, working directory, and byproducts of every + standard and custom step are processed to replace tokens ``<SOURCE_DIR>``, ``<BINARY_DIR>``, ``<INSTALL_DIR>``, and ``<TMP_DIR>`` with corresponding property values. @@ -1197,7 +1197,10 @@ function(_ep_get_build_command name step cmd_var) else() set(cmd "${CMAKE_COMMAND}") endif() - set(args --build ${binary_dir} --config ${CMAKE_CFG_INTDIR}) + set(args --build ".") + if (CMAKE_CFG_INTDIR AND NOT CMAKE_CFG_INTDIR STREQUAL ".") + list(APPEND args --config "${CMAKE_CFG_INTDIR}") + endif () if(step STREQUAL "INSTALL") list(APPEND args --target install) endif() @@ -1360,7 +1363,7 @@ endfunction() function(ExternalProject_Add_StepTargets name) set(steps ${ARGN}) - if("${ARGV1}" STREQUAL "NO_DEPENDS") + if(ARGC GREATER 1 AND "${ARGV1}" STREQUAL "NO_DEPENDS") set(no_deps 1) list(REMOVE_AT steps 0) endif() @@ -1443,7 +1446,7 @@ function(ExternalProject_Add_Step name step) endif() # Replace location tags. - _ep_replace_location_tags(${name} comment command work_dir) + _ep_replace_location_tags(${name} comment command work_dir byproducts) # Custom comment? get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET) diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index 3eea9db..dc31086 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -379,6 +379,9 @@ function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet) set(_currentFeatureText "") get_property(_EnabledFeatures GLOBAL PROPERTY ${_property}) + if(_EnabledFeatures) + list(REMOVE_DUPLICATES _EnabledFeatures) + endif(_EnabledFeatures) foreach(_currentFeature ${_EnabledFeatures}) @@ -559,8 +562,14 @@ endfunction() # The stuff below is only kept for compatibility function(SET_PACKAGE_INFO _name _desc) - set(_url "${ARGV2}") - set(_purpose "${ARGV3}") + unset(_url) + unset(_purpose) + if(ARGC GREATER 2) + set(_url "${ARGV2}") + endif() + if(ARGC GREATER 3) + set(_purpose "${ARGV3}") + endif() set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" ) if(NOT _url STREQUAL "") set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_url}" ) diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 99293c1..466090b 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -49,7 +49,8 @@ # and saves search results persistently in CMake cache entries:: # # Boost_INCLUDE_DIR - Directory containing Boost headers -# Boost_LIBRARY_DIR - Directory containing Boost libraries +# Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries +# Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries # Boost_<C>_LIBRARY_DEBUG - Component <C> library debug variant # Boost_<C>_LIBRARY_RELEASE - Component <C> library release variant # @@ -65,7 +66,8 @@ # using the above hints (excluding BOOST_INCLUDEDIR and # Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR, # and the library name configuration settings below. It saves the -# library directory in Boost_LIBRARY_DIR and individual library +# library directories in Boost_LIBRARY_DIR_DEBUG and +# Boost_LIBRARY_DIR_RELEASE and individual library # locations in Boost_<C>_LIBRARY_DEBUG and Boost_<C>_LIBRARY_RELEASE. # When one changes settings used by previous searches in the same build # tree (excluding environment variables) this module discards previous @@ -118,6 +120,8 @@ # "/usr/lib/libboost_system.so". This does not # affect linking and should not be enabled unless # the user needs this information. +# Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and +# Boost_LIBRARY_DIR_DEBUG. # # On Visual Studio and Borland compilers Boost headers request automatic # linking to corresponding libraries. This requires matching libraries @@ -283,6 +287,14 @@ macro(_Boost_ADJUST_LIB_VARS basename) ) endmacro() +# Detect changes in used variables. +# Compares the current variable value with the last one. +# In short form: +# v != v_LAST -> CHANGED = 1 +# v is defined, v_LAST not -> CHANGED = 1 +# v is not defined, but v_LAST is -> CHANGED = 1 +# otherwise -> CHANGED = 0 +# CHANGED is returned in variable named ${changed_var} macro(_Boost_CHANGE_DETECT changed_var) set(${changed_var} 0) foreach(v ${ARGN}) @@ -305,23 +317,33 @@ macro(_Boost_CHANGE_DETECT changed_var) endforeach() endmacro() -macro(_Boost_FIND_LIBRARY var) +# +# Find the given library (var). +# Use 'build_type' to support different lib paths for RELEASE or DEBUG builds +# +macro(_Boost_FIND_LIBRARY var build_type) + find_library(${var} ${ARGN}) if(${var}) - # If this is the first library found then save Boost_LIBRARY_DIR. - if(NOT Boost_LIBRARY_DIR) + # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. + if(NOT Boost_LIBRARY_DIR_${build_type}) get_filename_component(_dir "${${var}}" PATH) - set(Boost_LIBRARY_DIR "${_dir}" CACHE PATH "Boost library directory" FORCE) + set(Boost_LIBRARY_DIR_${build_type} "${_dir}" CACHE PATH "Boost library directory ${build_type}" FORCE) endif() elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) - # Try component-specific hints but do not save Boost_LIBRARY_DIR. + # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN}) endif() - # If Boost_LIBRARY_DIR is known then search only there. - if(Boost_LIBRARY_DIR) - set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there. + if(Boost_LIBRARY_DIR_${build_type}) + set(_boost_LIBRARY_SEARCH_DIRS_${build_type} ${Boost_LIBRARY_DIR_${build_type}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " Boost_LIBRARY_DIR_${build_type} = ${Boost_LIBRARY_DIR_${build_type}}" + " _boost_LIBRARY_SEARCH_DIRS_${build_type} = ${_boost_LIBRARY_SEARCH_DIRS_${build_type}}") + endif() endif() endmacro() @@ -456,6 +478,16 @@ endfunction() # main. #------------------------------------------------------------------------------- + +# If the user sets Boost_LIBRARY_DIR, use it as the default for both +# configurations. +if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}") +endif() +if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}") +endif() + if(NOT DEFINED Boost_USE_MULTITHREADED) set(Boost_USE_MULTITHREADED TRUE) endif() @@ -846,49 +878,54 @@ endif() # ------------------------------------------------------------------------ # Begin finding boost libraries # ------------------------------------------------------------------------ -set(_Boost_VARS_LIB BOOST_LIBRARYDIR Boost_LIBRARY_DIR) -_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR ${_Boost_VARS_DIR} ${_Boost_VARS_LIB} Boost_INCLUDE_DIR) -# Clear Boost_LIBRARY_DIR if it did not change but other input affecting the -# location did. We will find a new one based on the new inputs. -if(_Boost_CHANGE_LIBDIR AND NOT _Boost_LIBRARY_DIR_CHANGED) - unset(Boost_LIBRARY_DIR CACHE) -endif() -if(Boost_LIBRARY_DIR) - set(_boost_LIBRARY_SEARCH_DIRS ${Boost_LIBRARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) -else() - set(_boost_LIBRARY_SEARCH_DIRS "") - if(BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_LIBRARYDIR}) - elseif(_ENV_BOOST_LIBRARYDIR) - list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_LIBRARYDIR}) - endif() - - if(BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib) - elseif(_ENV_BOOST_ROOT) - list(APPEND _boost_LIBRARY_SEARCH_DIRS ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib) +foreach(c DEBUG RELEASE) + set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c}) + _Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR) + # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the + # location did. We will find a new one based on the new inputs. + if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED) + unset(Boost_LIBRARY_DIR_${c} CACHE) endif() - list(APPEND _boost_LIBRARY_SEARCH_DIRS - ${Boost_INCLUDE_DIR}/lib - ${Boost_INCLUDE_DIR}/../lib - ${Boost_INCLUDE_DIR}/stage/lib - ) - if( Boost_NO_SYSTEM_PATHS ) - list(APPEND _boost_LIBRARY_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH) + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value. + if(Boost_LIBRARY_DIR_${c}) + set(_boost_LIBRARY_SEARCH_DIRS_${c} ${Boost_LIBRARY_DIR_${c}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) else() - list(APPEND _boost_LIBRARY_SEARCH_DIRS PATHS - C:/boost/lib - C:/boost - /sw/local/lib + set(_boost_LIBRARY_SEARCH_DIRS_${c} "") + if(BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR}) + elseif(_ENV_BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR}) + endif() + + if(BOOST_ROOT) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib) + elseif(_ENV_BOOST_ROOT) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib) + endif() + + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} + ${Boost_INCLUDE_DIR}/lib + ${Boost_INCLUDE_DIR}/../lib + ${Boost_INCLUDE_DIR}/stage/lib ) + if( Boost_NO_SYSTEM_PATHS ) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH) + else() + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} PATHS + C:/boost/lib + C:/boost + /sw/local/lib + ) + endif() endif() -endif() +endforeach() if(Boost_DEBUG) message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " - "_boost_LIBRARY_SEARCH_DIRS = ${_boost_LIBRARY_SEARCH_DIRS}") + "_boost_LIBRARY_SEARCH_DIRS_RELEASE = ${_boost_LIBRARY_SEARCH_DIRS_RELEASE}" + "_boost_LIBRARY_SEARCH_DIRS_DEBUG = ${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") endif() # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES @@ -1002,10 +1039,16 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}") endif() + # if Boost_LIBRARY_DIR_RELEASE is not defined, + # but Boost_LIBRARY_DIR_DEBUG is, look there first for RELEASE libs + if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG}) + endif() + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}") + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}") - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE RELEASE NAMES ${_boost_RELEASE_NAMES} HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} NAMES_PER_DIR @@ -1038,10 +1081,16 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}") endif() + # if Boost_LIBRARY_DIR_DEBUG is not defined, + # but Boost_LIBRARY_DIR_RELEASE is, look there first for DEBUG libs + if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE}) + endif() + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. - string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS}") + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") - _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG DEBUG NAMES ${_boost_DEBUG_NAMES} HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} NAMES_PER_DIR @@ -1067,7 +1116,16 @@ endif() # ------------------------------------------------------------------------ set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) -set(Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR}) +set(Boost_LIBRARY_DIRS) +if(Boost_LIBRARY_DIR_RELEASE) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE}) +endif() +if(Boost_LIBRARY_DIR_DEBUG) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG}) +endif() +if(Boost_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS) +endif() # The above setting of Boost_FOUND was based only on the header files. # Update it for the requested component libraries. diff --git a/Modules/FindHg.cmake b/Modules/FindHg.cmake index 34d763e..bdbb79b 100644 --- a/Modules/FindHg.cmake +++ b/Modules/FindHg.cmake @@ -63,11 +63,21 @@ find_program(HG_EXECUTABLE mark_as_advanced(HG_EXECUTABLE) if(HG_EXECUTABLE) + set(_saved_lc_all "$ENV{LC_ALL}") + set(ENV{LC_ALL} "C") + + set(_saved_language "$ENV{LANGUAGE}") + set(ENV{LANGUAGE}) + execute_process(COMMAND ${HG_EXECUTABLE} --version OUTPUT_VARIABLE hg_version ERROR_QUIET RESULT_VARIABLE hg_result OUTPUT_STRIP_TRAILING_WHITESPACE) + + set(ENV{LC_ALL} ${_saved_lc_all}) + set(ENV{LANGUAGE} ${_saved_language}) + if(hg_result MATCHES "is not a valid Win32 application") set_property(CACHE HG_EXECUTABLE PROPERTY VALUE "HG_EXECUTABLE-NOTFOUND") endif() diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake index 261ebdb..3547628 100644 --- a/Modules/FindMFC.cmake +++ b/Modules/FindMFC.cmake @@ -36,7 +36,7 @@ if(WIN32 AND NOT UNIX AND NOT BORLAND AND NOT MINGW) endif() if(MFC_ATTEMPT_TRY_COMPILE) - if("MFC_HAVE_MFC" MATCHES "^MFC_HAVE_MFC$") + if(NOT DEFINED MFC_HAVE_MFC) set(CHECK_INCLUDE_FILE_VAR "afxwin.h") configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 474556e..d08423b 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -2,20 +2,208 @@ # FindMatlab # ---------- # -# this module looks for Matlab +# Finds Matlab installations and provides Matlab tools and libraries to cmake. # -# Defines: +# This package first intention is to find the libraries associated with Matlab +# in order to be able to build Matlab extensions (mex files). It can also be +# used: # -# :: +# * run specific commands in Matlab +# * declare Matlab unit test +# * retrieve various information from Matlab (mex extensions, versions and +# release queries, ...) # -# MATLAB_INCLUDE_DIR: include path for mex.h, engine.h -# MATLAB_LIBRARIES: required libraries: libmex, etc -# MATLAB_MEX_LIBRARY: path to libmex.lib -# MATLAB_MX_LIBRARY: path to libmx.lib -# MATLAB_ENG_LIBRARY: path to libeng.lib +# The module supports the following components: +# +# * ``MX_LIBRARY`` and ``ENG_LIBRARY`` respectively the MX and ENG libraries of +# Matlab +# * ``MAIN_PROGRAM`` the Matlab binary program. +# +# .. note:: +# +# The version given to the :command:`find_package` directive is the Matlab +# **version**, which should not be confused with the Matlab *release* name +# (eg. `R2014`). +# The :command:`matlab_get_version_from_release_name` and +# :command:`matlab_get_release_name_from_version` allow a mapping +# from the release name to the version. +# +# The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give +# the path of the desired Matlab version. Otherwise, the behaviour is platform +# specific: +# +# * Windows: The installed versions of Matlab are retrieved from the +# Windows registry +# * OS X: The installed versions of Matlab are given by the MATLAB +# paths in ``/Application``. If no such application is found, it falls back +# to the one that might be accessible from the PATH. +# * Unix: The desired Matlab should be accessible from the PATH. +# +# Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set. +# When a Matlab binary is found automatically and the ``MATLAB_VERSION`` +# is not given, the version is queried from Matlab directly. +# On Windows, it can make a window running Matlab appear. +# +# The mapping of the release names and the version of Matlab is performed by +# defining pairs (name, version). The variable +# :variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to +# the :command:`find_package` in order to handle additional versions. +# +# A Matlab scripts can be added to the set of tests using the +# :command:`matlab_add_unit_test`. By default, the Matlab unit test framework +# will be used (>= 2013a) to run this script, but regular ``.m`` files +# returning an exit code can be used as well (0 indicating a success). +# +# Module Input Variables +# ---------------------- +# +# Users or projects may set the following variables to configure the module +# behaviour: +# +# :variable:`Matlab_ROOT_DIR` +# the root of the Matlab installation. +# :variable:`MATLAB_FIND_DEBUG` +# outputs debug information +# :variable:`MATLAB_ADDITIONAL_VERSIONS` +# additional versions of Matlab for the automatic retrieval of the installed +# versions. +# +# Variables defined by the module +# ------------------------------- +# +# Result variables +# ^^^^^^^^^^^^^^^^ +# +# ``Matlab_FOUND`` +# ``TRUE`` if the Matlab installation is found, ``FALSE`` +# otherwise. All variable below are defined if Matlab is found. +# ``Matlab_ROOT_DIR`` +# the final root of the Matlab installation determined by the FindMatlab +# module. +# ``Matlab_MAIN_PROGRAM`` +# the Matlab binary program. Available only if the component ``MAIN_PROGRAM`` +# is given in the :command:`find_package` directive. +# ``Matlab_INCLUDE_DIRS`` +# the path of the Matlab libraries headers +# ``Matlab_MEX_LIBRARY`` +# library for mex, always available. +# ``Matlab_MX_LIBRARY`` +# mx library of Matlab (arrays). Available only if the component +# ``MX_LIBRARY`` has been requested. +# ``Matlab_ENG_LIBRARY`` +# Matlab engine library. Available only if the component ``ENG_LIBRARY`` +# is requested. +# ``Matlab_LIBRARIES`` +# the whole set of libraries of Matlab +# ``Matlab_MEX_COMPILER`` +# the mex compiler of Matlab. Currently not used. +# Available only if the component ``MEX_COMPILER`` is asked +# +# Cached variables +# ^^^^^^^^^^^^^^^^ +# +# ``Matlab_MEX_EXTENSION`` +# the extension of the mex files for the current platform (given by Matlab). +# ``Matlab_ROOT_DIR`` +# the location of the root of the Matlab installation found. If this value +# is changed by the user, the result variables are recomputed. +# +# Provided macros +# --------------- +# +# :command:`matlab_get_version_from_release_name` +# returns the version from the release name +# :command:`matlab_get_release_name_from_version` +# returns the release name from the Matlab version +# +# Provided functions +# ------------------ +# +# :command:`matlab_add_mex` +# adds a target compiling a MEX file. +# :command:`matlab_add_unit_test` +# adds a Matlab unit test file as a test to the project. +# :command:`matlab_extract_all_installed_versions_from_registry` +# parses the registry for all Matlab versions. Available on Windows only. +# The part of the registry parsed is dependent on the host processor +# :command:`matlab_get_all_valid_matlab_roots_from_registry` +# returns all the possible Matlab paths, according to a previously +# given list. Only the existing/accessible paths are kept. This is mainly +# useful for the searching all possible Matlab installation. +# :command:`matlab_get_mex_suffix` +# returns the suffix to be used for the mex files +# (platform/architecture dependant) +# :command:`matlab_get_version_from_matlab_run` +# returns the version of Matlab, given the full directory of the Matlab program. +# +# +# Known issues +# ------------ +# +# **Symbol clash in a MEX target** +# By default, every symbols inside a MEX +# file defined with the command :command:`matlab_add_mex` have hidden +# visibility, except for the entry point. This is the default behaviour of +# the MEX compiler, which lowers the risk of symbol collision between the +# libraries shipped with Matlab, and the libraries to which the MEX file is +# linking to. This is also the default on Windows platforms. +# +# However, this is not sufficient in certain case, where for instance your +# MEX file is linking against libraries that are already loaded by Matlab, +# even if those libraries have different SONAMES. +# A possible solution is to hide the symbols of the libraries to which the +# MEX target is linking to. This can be achieved in GNU GCC compilers with +# the linker option ``-Wl,--exclude-libs,ALL``. +# +# **Tests using GPU resources** +# in case your MEX file is using the GPU and +# in order to be able to run unit tests on this MEX file, the GPU resources +# should be properly released by Matlab. A possible solution is to make +# Matlab aware of the use of the GPU resources in the session, which can be +# performed by a command such as ``D = gpuDevice()`` at the beginning of +# the test script (or via a fixture). +# +# +# Reference +# -------------- +# +# .. variable:: Matlab_ROOT_DIR +# +# The root folder of the Matlab installation. If set before the call to +# :command:`find_package`, the module will look for the components in that +# path. If not set, then an automatic search of Matlab +# will be performed. If set, it should point to a valid version of Matlab. +# +# .. variable:: MATLAB_FIND_DEBUG +# +# If set, the lookup of Matlab and the intermediate configuration steps are +# outputted to the console. +# +# .. variable:: MATLAB_ADDITIONAL_VERSIONS +# +# If set, specifies additional versions of Matlab that may be looked for. +# The variable should be a list of strings, organised by pairs of release +# name and versions, such as follows:: +# +# set(MATLAB_ADDITIONAL_VERSIONS +# "release_name1=corresponding_version1" +# "release_name2=corresponding_version2" +# ... +# ) +# +# Example:: +# +# set(MATLAB_ADDITIONAL_VERSIONS +# "R2013b=8.2" +# "R2013a=8.1" +# "R2012b=8.0") +# +# The order of entries in this list matters when several versions of +# Matlab are installed. The priority is set according to the ordering in +# this list. #============================================================================= -# Copyright 2005-2009 Kitware, Inc. +# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -27,102 +215,1247 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -set(MATLAB_FOUND 0) -if(WIN32) - if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6") - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc60") +set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}") + +include(FindPackageHandleStandardArgs) +include(CheckCXXCompilerFlag) + + +# The currently supported versions. Other version can be added by the user by +# providing MATLAB_ADDITIONAL_VERSIONS +if(NOT MATLAB_ADDITIONAL_VERSIONS) + set(MATLAB_ADDITIONAL_VERSIONS) +endif() + +set(MATLAB_VERSIONS_MAPPING + "R2014a=8.3" + "R2013b=8.2" + "R2013a=8.1" + "R2012b=8.0" + "R2012a=7.14" + + "R2011b=7.13" + "R2011a=7.12" + "R2010b=7.11" + + ${MATLAB_ADDITIONAL_VERSIONS} + ) + + +# temporary folder for all Matlab runs +set(_matlab_temporary_folder ${CMAKE_BINARY_DIR}/Matlab) + +if(NOT EXISTS "${_matlab_temporary_folder}") + file(MAKE_DIRECTORY "${_matlab_temporary_folder}") +endif() + +#.rst: +# .. command:: matlab_get_version_from_release_name +# +# Returns the version of Matlab (17.58) from a release name (R2017k) +macro (matlab_get_version_from_release_name release_name version_name) + + string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) + + set(${version_name} "") + if(NOT _matched STREQUAL "") + set(${version_name} ${CMAKE_MATCH_1}) else() - if(${CMAKE_GENERATOR} MATCHES "Visual Studio 7") - # Assume people are generally using 7.1, - # if using 7.0 need to link to: ../extern/lib/win32/microsoft/msvc70 - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc71") - else() - if(${CMAKE_GENERATOR} MATCHES "Borland") - # Same here, there are also: bcc50 and bcc51 directories - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/bcc54") - else() - if(MATLAB_FIND_REQUIRED) - message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}") - endif() + message(WARNING "The release name ${release_name} is not registered") + endif() + unset(_matched) + +endmacro() + + + + + +#.rst: +# .. command:: matlab_get_release_name_from_version +# +# Returns the release name (R2017k) from the version of Matlab (17.58) +macro (matlab_get_release_name_from_version version release_name) + + set(${release_name} "") + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=${version}" _matched ${_var}) + if(NOT _matched STREQUAL "") + set(${release_name} ${CMAKE_MATCH_1}) + break() + endif() + endforeach(_var) + + unset(_var) + unset(_matched) + if(${release_name} STREQUAL "") + message(WARNING "The version ${version} is not registered") + endif() + +endmacro() + + + + + +# extracts all the supported release names (R2017k...) of Matlab +# internal use +macro(matlab_get_supported_releases list_releases) + set(${list_releases}) + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) + if(NOT _matched STREQUAL "") + list(APPEND ${list_releases} ${CMAKE_MATCH_1}) + endif() + unset(_matched) + unset(CMAKE_MATCH_1) + endforeach(_var) + unset(_var) +endmacro() + + + +# extracts all the supported versions of Matlab +# internal use +macro(matlab_get_supported_versions list_versions) + set(${list_versions}) + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) + if(NOT _matched STREQUAL "") + list(APPEND ${list_versions} ${CMAKE_MATCH_2}) + endif() + unset(_matched) + unset(CMAKE_MATCH_1) + endforeach(_var) + unset(_var) +endmacro() + + +#.rst: +# .. command:: matlab_extract_all_installed_versions_from_registry +# +# This function parses the registry and founds the Matlab versions that are +# installed. The found versions are returned in `matlab_versions`. +# Set `win64` to `TRUE` if the 64 bit version of Matlab should be looked for +# The returned list contains all versions under +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` or an empty list in case an error +# occurred (or nothing found). +# +# .. note:: +# +# Only the versions are provided. No check is made over the existence of the +# installation referenced in the registry, +# +function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions) + + if(NOT CMAKE_HOST_WIN32) + message(FATAL_ERROR "This macro can only be called by a windows host (call to reg.exe") + endif() + + + if(${win64} AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "64") + set(APPEND_REG "/reg:64") + else() + set(APPEND_REG "/reg:32") + endif() + + # /reg:64 should be added on 64 bits capable OSs in order to enable the + # redirection of 64 bits applications + execute_process( + COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\MATLAB /f * /k ${APPEND_REG} + RESULT_VARIABLE resultMatlab + OUTPUT_VARIABLE varMatlab + ERROR_VARIABLE errMatlab + INPUT_FILE NUL + ) + + + set(matlabs_from_registry) + if(${resultMatlab} EQUAL 0) + + string( + REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" + matlab_versions_regex ${varMatlab}) + + foreach(match IN LISTS matlab_versions_regex) + string( + REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" + current_match ${match}) + + set(_matlab_current_version ${CMAKE_MATCH_1}) + set(current_matlab_version_major ${CMAKE_MATCH_2}) + set(current_matlab_version_minor ${CMAKE_MATCH_4}) + if(NOT current_matlab_version_minor) + set(current_matlab_version_minor "0") endif() + + list(APPEND matlabs_from_registry ${_matlab_current_version}) + unset(_matlab_current_version) + endforeach(match) + + endif() + + if(matlabs_from_registry) + list(REMOVE_DUPLICATES matlabs_from_registry) + list(SORT matlabs_from_registry) + list(REVERSE matlabs_from_registry) + endif() + + set(${matlab_versions} ${matlabs_from_registry} PARENT_SCOPE) + +endfunction() + + + +# (internal) +macro(extract_matlab_versions_from_registry_brute_force matlab_versions) + # get the supported versions + set(matlab_supported_versions) + matlab_get_supported_versions(matlab_supported_versions) + + + # this is a manual population of the versions we want to look for + # this can be done as is, but preferably with the call to + # matlab_get_supported_versions and variable + + # populating the versions we want to look for + # set(matlab_supported_versions) + + # # Matlab 7 + # set(matlab_major 7) + # foreach(current_matlab_minor RANGE 4 20) + # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") + # endforeach(current_matlab_minor) + + # # Matlab 8 + # set(matlab_major 8) + # foreach(current_matlab_minor RANGE 0 5) + # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") + # endforeach(current_matlab_minor) + + # # taking into account the possible additional versions provided by the user + # if(DEFINED MATLAB_ADDITIONAL_VERSIONS) + # list(APPEND matlab_supported_versions MATLAB_ADDITIONAL_VERSIONS) + # endif() + + + # we order from more recent to older + if(matlab_supported_versions) + list(REMOVE_DUPLICATES matlab_supported_versions) + list(SORT matlab_supported_versions) + list(REVERSE matlab_supported_versions) + endif() + + + set(${matlab_versions} ${matlab_supported_versions}) + + +endmacro() + + + + +#.rst: +# .. command:: matlab_get_all_valid_matlab_roots_from_registry +# +# Populates the Matlab root with valid versions of Matlab. +# The returned matlab_roots is organized in pairs +# ``(version_number,matlab_root_path)``. +# +# :: +# +# matlab_get_all_valid_matlab_roots_from_registry( +# matlab_versions +# matlab_roots) +# +# ``matlab_versions`` +# the versions of each of the Matlab installations +# ``matlab_roots`` +# the location of each of the Matlab installations +function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots) + + # The matlab_versions comes either from + # extract_matlab_versions_from_registry_brute_force or + # matlab_extract_all_installed_versions_from_registry. + + + set(_matlab_roots_list ) + foreach(_matlab_current_version ${matlab_versions}) + get_filename_component( + current_MATLAB_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]" + ABSOLUTE) + + if(EXISTS ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list ${_matlab_current_version} ${current_MATLAB_ROOT}) endif() + + endforeach(_matlab_current_version) + unset(_matlab_current_version) + set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE) + unset(_matlab_roots_list) +endfunction() + +#.rst: +# .. command:: matlab_get_mex_suffix +# +# Returns the extension of the mex files (the suffixes). +# This function should not be called before the appropriate Matlab root has +# been found. +# +# :: +# +# matlab_get_mex_suffix( +# matlab_root +# mex_suffix) +# +# ``matlab_root`` +# the root of the Matlab installation +# ``mex_suffix`` +# the variable name in which the suffix will be returned. +function(matlab_get_mex_suffix matlab_root mex_suffix) + + # todo setup the extension properly. Currently I do not know if this is + # sufficient for all win32 distributions. + # there is also CMAKE_EXECUTABLE_SUFFIX that could be tweaked + set(mexext_suffix "") + if(WIN32) + list(APPEND mexext_suffix ".bat") + endif() + + # we first try without suffix, since cmake does not understand a list with + # one empty string element + find_program( + Matlab_MEXEXTENSIONS_PROG + NAMES mexext + PATHS ${matlab_root}/bin + DOC "Matlab MEX extension provider" + NO_DEFAULT_PATH + ) + + foreach(current_mexext_suffix IN LISTS mexext_suffix) + if(NOT DEFINED Matlab_MEXEXTENSIONS_PROG OR NOT Matlab_MEXEXTENSIONS_PROG) + # this call should populate the cache automatically + find_program( + Matlab_MEXEXTENSIONS_PROG + "mexext${current_mexext_suffix}" + PATHS ${matlab_root}/bin + DOC "Matlab MEX extension provider" + NO_DEFAULT_PATH + ) + endif() + endforeach(current_mexext_suffix) + + + # the program has been found? + if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG})) + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot found mexext program. Matlab root is ${matlab_root}") + endif() + unset(Matlab_MEXEXTENSIONS_PROG CACHE) + return() endif() - find_library(MATLAB_MEX_LIBRARY - libmex - ${MATLAB_ROOT} + + set(_matlab_mex_extension) + + set(devnull) + if(UNIX) + set(devnull INPUT_FILE /dev/null) + elseif(WIN32) + set(devnull INPUT_FILE NUL) + endif() + + execute_process( + COMMAND ${Matlab_MEXEXTENSIONS_PROG} + OUTPUT_VARIABLE _matlab_mex_extension + ERROR_VARIABLE _matlab_mex_extension_error + ${devnull}) + string(STRIP ${_matlab_mex_extension} _matlab_mex_extension) + + unset(Matlab_MEXEXTENSIONS_PROG CACHE) + set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE) +endfunction() + + + + +#.rst: +# .. command:: matlab_get_version_from_matlab_run +# +# This function runs Matlab program specified on arguments and extracts its +# version. +# +# :: +# +# matlab_get_version_from_matlab_run( +# matlab_binary_path +# matlab_list_versions) +# +# ``matlab_binary_path`` +# the location of the `matlab` binary executable +# ``matlab_list_versions`` +# the version extracted from Matlab +function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions) + + set(${matlab_list_versions} "" PARENT_SCOPE) + + + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}") + endif() + + if(EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Removing previous ${_matlab_temporary_folder}/matlabVersionLog.cmaketmp file") + endif() + file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + endif() + + + # the log file is needed since on windows the command executes in a new + # window and it is not possible to get back the answer of Matlab + # the -wait command is needed on windows, otherwise the call returns + # immediately after the program launches itself. + if(WIN32) + set(_matlab_additional_commands "-wait") + endif() + + set(devnull) + if(UNIX) + set(devnull INPUT_FILE /dev/null) + elseif(WIN32) + set(devnull INPUT_FILE NUL) + endif() + + # timeout set to 30 seconds, in case it does not start + # note as said before OUTPUT_VARIABLE cannot be used in a platform + # independent manner however, not setting it would flush the output of Matlab + # in the current console (unix variant) + execute_process( + COMMAND "${matlab_binary_program}" -nosplash -nojvm ${_matlab_additional_commands} -logfile "matlabVersionLog.cmaketmp" -nodesktop -nodisplay -r "version, exit" + OUTPUT_VARIABLE _matlab_version_from_cmd_dummy + RESULT_VARIABLE _matlab_result_version_call + ERROR_VARIABLE _matlab_result_version_call_error + TIMEOUT 30 + WORKING_DIRECTORY "${_matlab_temporary_folder}" + ${devnull} ) - find_library(MATLAB_MX_LIBRARY - libmx - ${MATLAB_ROOT} + + + if(${_matlab_result_version_call}) + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call returned with error ${_matlab_result_version_call}.") + endif() + return() + elseif(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.") + endif() + return() + endif() + + # if successful, read back the log + file(READ "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp" _matlab_version_from_cmd) + file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + + set(index -1) + string(FIND ${_matlab_version_from_cmd} "ans" index) + if(index EQUAL -1) + + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot find the version of Matlab returned by the run.") + endif() + + else() + set(matlab_list_of_all_versions_tmp) + + string(SUBSTRING ${_matlab_version_from_cmd} ${index} -1 substring_ans) + string( + REGEX MATCHALL "ans[\r\n\t ]*=[\r\n\t ]*([0-9]+(\\.[0-9]+)?)" + matlab_versions_regex + ${substring_ans}) + foreach(match IN LISTS matlab_versions_regex) + string( + REGEX MATCH "ans[\r\n\t ]*=[\r\n\t ]*(([0-9]+)(\\.([0-9]+))?)" + current_match ${match}) + + list(APPEND matlab_list_of_all_versions_tmp ${CMAKE_MATCH_1}) + endforeach() + if(matlab_list_of_all_versions_tmp) + list(REMOVE_DUPLICATES matlab_list_of_all_versions_tmp) + endif() + set(${matlab_list_versions} ${matlab_list_of_all_versions_tmp} PARENT_SCOPE) + + endif() + +endfunction() + + +#.rst: +# .. command:: matlab_add_unit_test +# +# Adds a Matlab unit test to the test set of cmake/ctest. +# This command requires the component ``MAIN_PROGRAM``. +# The unit test uses the Matlab unittest framework (default, available +# starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK`` +# is given. +# +# The function expects one Matlab test script file to be given. +# In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file +# should contain the script to be run, plus an exit command with the exit +# value. This exit value will be passed to the ctest framework (0 success, +# non 0 failure). Additional arguments accepted by :command:`add_test` can be +# passed through ``TEST_ARGS`` (eg. ``CONFIGURATION <config> ...``). +# +# :: +# +# matlab_add_unit_test( +# NAME <name> +# UNITTEST_FILE matlab_file_containing_unittest.m +# [UNITTEST_PRECOMMAND matlab_command_to_run] +# [TIMEOUT timeout] +# [ADDITIONAL_PATH path1 [path2 ...]] +# [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]] +# [TEST_ARGS arg1 [arg2 ...]] +# [NO_UNITTEST_FRAMEWORK] +# ) +# +# The function arguments are: +# +# ``NAME`` +# name of the unittest in ctest. +# ``UNITTEST_FILE`` +# the matlab unittest file. Its path will be automatically +# added to the Matlab path. +# ``UNITTEST_PRECOMMAND`` +# Matlab script command to be ran before the file +# containing the test (eg. GPU device initialisation based on CMake +# variables). +# ``TIMEOUT`` +# the test timeout in seconds. Defaults to 180 seconds as the +# Matlab unit test may hang. +# ``ADDITIONAL_PATH`` +# a list of paths to add to the Matlab path prior to +# running the unit test. +# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS`` +# a list of additional option in order +# to run Matlab from the command line. +# ``TEST_ARGS`` +# Additional options provided to the add_test command. These +# options are added to the default options (eg. "CONFIGURATIONS Release") +# ``NO_UNITTEST_FRAMEWORK`` +# when set, indicates that the test should not +# use the unittest framework of Matlab (available for versions >= R2013a). +# +function(matlab_add_unit_test) + + if(NOT Matlab_MAIN_PROGRAM) + message(FATAL_ERROR "[MATLAB] This functionality needs the MAIN_PROGRAM component (not default)") + endif() + + set(options NO_UNITTEST_FRAMEWORK) + set(oneValueArgs NAME UNITTEST_PRECOMMAND UNITTEST_FILE TIMEOUT) + set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS) + + set(prefix _matlab_unittest_prefix) + cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if(NOT ${prefix}_NAME) + message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty") + endif() + + add_test(NAME ${${prefix}_NAME} + COMMAND ${CMAKE_COMMAND} + -Dtest_name=${${prefix}_NAME} + -Dadditional_paths=${${prefix}_ADDITIONAL_PATH} + -Dtest_timeout=${${prefix}_TIMEOUT} + -Doutput_directory=${_matlab_temporary_folder} + -DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM} + -Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK} + -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS} + -Dunittest_file_to_run=${${prefix}_UNITTEST_FILE} + -Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND} + -P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake + ${${prefix}_TEST_ARGS} + ${${prefix}_UNPARSED_ARGUMENTS} + ) +endfunction() + + +#.rst: +# .. command:: matlab_add_mex +# +# Adds a Matlab MEX target. +# This commands compiles the given sources with the current tool-chain in +# order to produce a MEX file. The final name of the produced output may be +# specified, as well as additional link libraries, and a documentation entry +# for the MEX file. Remaining arguments of the call are passed to the +# :command:`add_library` command. +# +# :: +# +# matlab_add_mex( +# NAME <name> +# SRC src1 [src2 ...] +# [OUTPUT_NAME output_name] +# [DOCUMENTATION file.txt] +# [LINK_TO target1 target2 ...] +# [...] +# ) +# +# ``NAME`` +# name of the target. +# ``SRC`` +# list of tje source files. +# ``LINK_TO`` +# a list of additional link dependencies. The target links to ``libmex`` +# by default. If ``Matlab_MX_LIBRARY`` is defined, it also +# links to ``libmx``. +# ``OUTPUT_NAME`` +# if given, overrides the default name. The default name is +# the name of the target without any prefix and +# with ``Matlab_MEX_EXTENSION`` suffix. +# ``DOCUMENTATION`` +# if given, the file ``file.txt`` will be considered as +# being the documentation file for the MEX file. This file is copied into +# the same folder without any processing, with the same name as the final +# mex file, and with extension `.m`. In that case, typing ``help <name>`` +# in Matlab prints the documentation contained in this file. +# +# The documentation file is not processed and should be in the following +# format: +# +# :: +# +# % This is the documentation +# function ret = mex_target_output_name(input1) +# +function(matlab_add_mex ) + + if(NOT WIN32) + # we do not need all this on Windows + # pthread options + check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD) + # we should use try_compile instead, the link flags are discarded from + # this compiler_flag function. + #check_cxx_compiler_flag(-Wl,--exclude-libs,ALL HAS_SYMBOL_HIDING_CAPABILITY) + + endif() + + set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME) + set(multiValueArgs LINK_TO SRC) + + set(prefix _matlab_addmex_prefix) + cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if(NOT ${prefix}_NAME) + message(FATAL_ERROR "[MATLAB] The MEX target name cannot be empty") + endif() + + if(NOT ${prefix}_OUTPUT_NAME) + set(${prefix}_OUTPUT_NAME ${${prefix}_NAME}) + endif() + + add_library(${${prefix}_NAME} + SHARED + ${${prefix}_SRC} + ${${prefix}_DOCUMENTATION} + ${${prefix}_UNPARSED_ARGUMENTS}) + target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS}) + + if(DEFINED Matlab_MX_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_MX_LIBRARY}) + endif() + + target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${${prefix}_LINK_TO}) + set_target_properties(${${prefix}_NAME} + PROPERTIES + PREFIX "" + OUTPUT_NAME ${${prefix}_OUTPUT_NAME} + SUFFIX ".${Matlab_MEX_EXTENSION}") + + + # documentation + if(NOT ${${prefix}_DOCUMENTATION} STREQUAL "") + get_target_property(output_name ${${prefix}_NAME} OUTPUT_NAME) + add_custom_command( + TARGET ${${prefix}_NAME} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${prefix}_DOCUMENTATION} $<TARGET_FILE_DIR:${${prefix}_NAME}>/${output_name}.m + COMMENT "Copy ${${prefix}_NAME} documentation file into the output folder" ) - find_library(MATLAB_ENG_LIBRARY - libeng - ${MATLAB_ROOT} + endif() # documentation + + # entry point in the mex file + taking care of visibility and symbol clashes. + if(WIN32) + set_target_properties(${${prefix}_NAME} + PROPERTIES + DEFINE_SYMBOL "DLL_EXPORT_SYM=__declspec(dllexport)") + else() + + if(HAS_MINUS_PTHREAD AND NOT APPLE) + # Apparently, compiling with -pthread generated the proper link flags + # and some defines at compilation + target_compile_options(${${prefix}_NAME} PRIVATE "-pthread") + endif() + + + # if we do not do that, the symbols linked from eg. boost remain weak and + # then clash with the ones defined in the matlab process. So by default + # the symbols are hidden. + # This also means that for shared libraries (like MEX), the entry point + # should be explicitly declared with default visibility, otherwise Matlab + # cannot find the entry point. + # Note that this is particularly meaningful if the MEX wrapper itself + # contains symbols that are clashing with Matlab (that are compiled in the + # MEX file). In order to propagate the visibility options to the libraries + # to which the MEX file is linked against, the -Wl,--exclude-libs,ALL + # option should also be specified. + + set_target_properties(${${prefix}_NAME} + PROPERTIES + CXX_VISIBILITY_PRESET "hidden" + C_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN "hidden" ) - find_path(MATLAB_INCLUDE_DIR - "mex.h" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/include" + # get_target_property( + # _previous_link_flags + # ${${prefix}_NAME} + # LINK_FLAGS) + # if(NOT _previous_link_flags) + # set(_previous_link_flags) + # endif() + + # if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # set_target_properties(${${prefix}_NAME} + # PROPERTIES + # LINK_FLAGS "${_previous_link_flags} -Wl,--exclude-libs,ALL" + # # -Wl,--version-script=${_FindMatlab_SELF_DIR}/MatlabLinuxVisibility.map" + # ) + # elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + # # in this case, all other symbols become hidden. + # set_target_properties(${${prefix}_NAME} + # PROPERTIES + # LINK_FLAGS "${_previous_link_flags} -Wl,-exported_symbol,_mexFunction" + # #-Wl,-exported_symbols_list,${_FindMatlab_SELF_DIR}/MatlabOSXVisilibity.map" + # ) + # endif() + + + + set_target_properties(${${prefix}_NAME} + PROPERTIES + DEFINE_SYMBOL "DLL_EXPORT_SYM=__attribute__ ((visibility (\"default\")))" ) -else() - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - # Regular x86 - set(MATLAB_ROOT - /usr/local/matlab-7sp1/bin/glnx86/ - /opt/matlab-7sp1/bin/glnx86/ - $ENV{HOME}/matlab-7sp1/bin/glnx86/ - $ENV{HOME}/redhat-matlab/bin/glnx86/ + + + endif() + +endfunction() + + +# (internal) +# Used to get the version of matlab, using caching. This basically transforms the +# output of the root list, with possible unknown version, to a version +# +function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_final_version) + + # if the version is not trivial, we query matlab for that + # we keep track of the location of matlab that induced this version + #if(NOT DEFINED Matlab_PROG_VERSION_STRING_AUTO_DETECT) + # set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version") + #endif() + + if(NOT ${matlab_known_version} STREQUAL "NOTFOUND") + # the version is known, we just return it + set(${matlab_final_version} ${matlab_known_version} PARENT_SCOPE) + set(Matlab_VERSION_STRING_INTERNAL ${matlab_known_version} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + return() + endif() + + # + set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) + + # do we already have a matlab program? + if(NOT _matlab_current_program) + + set(_find_matlab_options) + if(matlab_root AND EXISTS ${matlab_root}) + set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) + endif() + + find_program( + _matlab_current_program + matlab + ${_find_matlab_options} + DOC "Matlab main program" ) + endif() + + if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program}) + # if not found, clear the dependent variables + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}") + endif() + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) + return() + endif() + + # full real path for path comparison + get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) + + # is it the same as the previous one? + if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT) + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + return() + endif() + + # update the location of the program + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT ${_matlab_main_real_path_tmp} CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + + set(matlab_list_of_all_versions) + matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + + list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) + + # set the version into the cache + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + + # warning, just in case several versions found (should not happen) + list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) + if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})") + endif() + + # return the updated value + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + +endfunction() + + + + + + + +# ################################### +# Exploring the possible Matlab_ROOTS + +# this variable will get all Matlab installations found in the current system. +set(_matlab_possible_roots) + + + +if(Matlab_ROOT_DIR) + # if the user specifies a possible root, we keep this one + + if(NOT EXISTS ${Matlab_ROOT_DIR}) + # if Matlab_ROOT_DIR specified but erroneous + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") + endif() else() - # AMD64: - set(MATLAB_ROOT - /usr/local/matlab-7sp1/bin/glnxa64/ - /opt/matlab-7sp1/bin/glnxa64/ - $ENV{HOME}/matlab7_64/bin/glnxa64/ - $ENV{HOME}/matlab-7sp1/bin/glnxa64/ - $ENV{HOME}/redhat-matlab/bin/glnxa64/ - ) + # NOTFOUND indicates the code below to search for the version automatically + if(NOT DEFINED Matlab_VERSION_STRING_INTERNAL) + list(APPEND _matlab_possible_roots "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version + else() + list(APPEND _matlab_possible_roots ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version + endif() + endif() + + +else() + + # if the user does not specify the possible installation root, we look for + # one installation using the appropriate heuristics + + if(WIN32) + + # On WIN32, we look for Matlab installation in the registry + # if unsuccessful, we look for all known revision and filter the existing + # ones. + + # testing if we are able to extract the needed information from the registry + set(_matlab_versions_from_registry) + matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry) + + # the returned list is empty, doing the search on all known versions + if(NOT _matlab_versions_from_registry) + + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") + endif() + + extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) + endif() + + # filtering the results with the registry keys + matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) + unset(_matlab_versions_from_registry) + + elseif(APPLE) + + # on mac, we look for the /Application paths + # this corresponds to the behaviour on Windows. On Linux, we do not have + # any other guess. + matlab_get_supported_releases(_matlab_releases) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported " + "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation") + endif() + + foreach(_matlab_current_release IN LISTS _matlab_releases) + set(_matlab_full_string "/Applications/MATLAB_${_matlab_current_release}.app") + if(EXISTS ${_matlab_full_string}) + set(_matlab_current_version) + matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_full_string}") + endif() + list(APPEND _matlab_possible_roots ${_matlab_current_version} ${_matlab_full_string}) + unset(_matlab_current_version) + endif() + + unset(_matlab_full_string) + endforeach(_matlab_current_release) + + unset(_matlab_current_release) + unset(_matlab_releases) + endif() - find_library(MATLAB_MEX_LIBRARY - mex - ${MATLAB_ROOT} - ) - find_library(MATLAB_MX_LIBRARY - mx - ${MATLAB_ROOT} - ) - find_library(MATLAB_ENG_LIBRARY - eng - ${MATLAB_ROOT} - ) - find_path(MATLAB_INCLUDE_DIR - "mex.h" - "/usr/local/matlab-7sp1/extern/include/" - "/opt/matlab-7sp1/extern/include/" - "$ENV{HOME}/matlab-7sp1/extern/include/" - "$ENV{HOME}/redhat-matlab/extern/include/" - ) endif() -# This is common to UNIX and Win32: -set(MATLAB_LIBRARIES - ${MATLAB_MEX_LIBRARY} - ${MATLAB_MX_LIBRARY} - ${MATLAB_ENG_LIBRARY} + + +list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) +if(_numbers_of_matlab_roots EQUAL 0) + # if we have not found anything, we fall back on the PATH + + + # At this point, we have no other choice than trying to find it from PATH. + # If set by the user, this wont change + find_program( + _matlab_main_tmp + NAMES matlab) + + + if(_matlab_main_tmp) + # we then populate the list of roots, with empty version + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] matlab found from PATH: ${_matlab_main_tmp}") + endif() + + # resolve symlinks + get_filename_component(_matlab_current_location "${_matlab_main_tmp}" REALPATH) + + # get the directory (the command below has to be run twice) + # this will be the matlab root + get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) + get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) # Matlab should be in bin + + list(APPEND _matlab_possible_roots "NOTFOUND" ${_matlab_current_location}) + + unset(_matlab_current_location) + + endif() + unset(_matlab_main_tmp CACHE) + +endif() + + + + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Matlab root folders are ${_matlab_possible_roots}") +endif() + + + + + +# take the first possible Matlab root +list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) +set(Matlab_VERSION_STRING "NOTFOUND") +if(_numbers_of_matlab_roots GREATER 0) + list(GET _matlab_possible_roots 0 Matlab_VERSION_STRING) + list(GET _matlab_possible_roots 1 Matlab_ROOT_DIR) + + # adding a warning in case of ambiguity + if(_numbers_of_matlab_roots GREATER 2 AND MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})." + " If this is not the desired behaviour, provide the -DMatlab_ROOT_DIR=... on the command line") + endif() +endif() + + +# check if the root changed against the previous defined one, if so +# clear all the cached variables +if(DEFINED Matlab_ROOT_DIR_LAST_CACHED) + + if(NOT Matlab_ROOT_DIR_LAST_CACHED STREQUAL Matlab_ROOT_DIR) + set(_Matlab_cached_vars + Matlab_INCLUDE_DIRS + Matlab_MEX_LIBRARY + Matlab_MEX_COMPILER + Matlab_MAIN_PROGRAM + Matlab_MX_LIBRARY + Matlab_ENG_LIBRARY + Matlab_MEX_EXTENSION + + # internal + Matlab_MEXEXTENSIONS_PROG + Matlab_ROOT_DIR_LAST_CACHED + #Matlab_PROG_VERSION_STRING_AUTO_DETECT + Matlab_VERSION_STRING_INTERNAL + ) + foreach(_var IN LISTS _Matlab_cached_vars) + if(DEFINED ${_var}) + unset(${_var} CACHE) + endif() + endforeach() + endif() +endif() + +set(Matlab_ROOT_DIR_LAST_CACHED ${Matlab_ROOT_DIR} CACHE INTERNAL "last Matlab root dir location") +set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path" FORCE) + +# Fix the version, in case this one is NOTFOUND +_Matlab_get_version_from_root( + "${Matlab_ROOT_DIR}" + ${Matlab_VERSION_STRING} + Matlab_VERSION_STRING ) -if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES) - set(MATLAB_FOUND 1) + + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}") +endif() + + + +if(Matlab_ROOT_DIR) + file(TO_CMAKE_PATH ${Matlab_ROOT_DIR} Matlab_ROOT_DIR) endif() -mark_as_advanced( - MATLAB_LIBRARIES - MATLAB_MEX_LIBRARY - MATLAB_MX_LIBRARY - MATLAB_ENG_LIBRARY - MATLAB_INCLUDE_DIR - MATLAB_FOUND - MATLAB_ROOT +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_matlab_64Build FALSE) +else() + set(_matlab_64Build TRUE) +endif() + +if(APPLE) + set(_matlab_bin_prefix "mac") # i should be for intel + set(_matlab_bin_suffix_32bits "i") + set(_matlab_bin_suffix_64bits "i64") +elseif(UNIX) + set(_matlab_bin_prefix "gln") + set(_matlab_bin_suffix_32bits "x86") + set(_matlab_bin_suffix_64bits "xa64") +else() + set(_matlab_bin_prefix "win") + set(_matlab_bin_suffix_32bits "32") + set(_matlab_bin_suffix_64bits "64") +endif() + + + +set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include) +if(_matlab_64Build) + set(_matlab_current_suffix ${_matlab_bin_suffix_64bits}) +else() + set(_matlab_current_suffix ${_matlab_bin_suffix_32bits}) +endif() + +set(Matlab_BINARIES_DIR + ${Matlab_ROOT_DIR}/bin/${_matlab_bin_prefix}${_matlab_current_suffix}) +set(Matlab_EXTERN_LIBRARY_DIR + ${Matlab_ROOT_DIR}/extern/lib/${_matlab_bin_prefix}${_matlab_current_suffix}) + +if(WIN32) + set(_matlab_lib_dir_for_search ${Matlab_EXTERN_LIBRARY_DIR}/microsoft) + set(_matlab_lib_prefix_for_search "lib") +else() + set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR}) + set(_matlab_lib_prefix_for_search "lib") +endif() + +unset(_matlab_64Build) + + +if(NOT DEFINED Matlab_MEX_EXTENSION) + set(_matlab_mex_extension "") + matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension) + + # This variable goes to the cache. + set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)") + unset(_matlab_mex_extension) +endif() + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] [DEBUG]_matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}") +endif() + + + +# internal +# This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope. +# This is the function to be used below instead of the find_library directives. +function(_Matlab_find_library _matlab_library_prefix) + set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} ${_matlab_library_prefix}) + find_library(${ARGN}) +endfunction() + + +set(_matlab_required_variables) + + +# the MEX library/header are required +find_path( + Matlab_INCLUDE_DIRS + mex.h + PATHS ${MATLAB_INCLUDE_DIR_TO_LOOK} + NO_DEFAULT_PATH + ) +list(APPEND _matlab_required_variables Matlab_INCLUDE_DIRS) + +_Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MEX_LIBRARY + mex + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH ) + +list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY) + +# the MEX extension is required +list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION) + +# the matlab root is required +list(APPEND _matlab_required_variables Matlab_ROOT_DIR) + + +# component Mex Compiler +list(FIND Matlab_FIND_COMPONENTS MEX_COMPILER _matlab_find_mex_compiler) +if(_matlab_find_mex_compiler GREATER -1) + find_program( + Matlab_MEX_COMPILER + "mex" + PATHS ${Matlab_BINARIES_DIR} + DOC "Matlab MEX compiler" + NO_DEFAULT_PATH + ) + + if(Matlab_MEX_COMPILER) + set(Matlab_MEX_COMPILER_FOUND TRUE) + endif() +endif() +unset(_matlab_find_mex_compiler) + +# component Matlab program +list(FIND Matlab_FIND_COMPONENTS MAIN_PROGRAM _matlab_find_matlab_program) +if(_matlab_find_matlab_program GREATER -1) + + find_program( + Matlab_MAIN_PROGRAM + matlab + PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin + DOC "Matlab main program" + NO_DEFAULT_PATH + ) + + if(Matlab_MAIN_PROGRAM) + set(Matlab_MAIN_PROGRAM_FOUND TRUE) + endif() + +endif() +unset(_matlab_find_matlab_program) + +# Component MX library +list(FIND Matlab_FIND_COMPONENTS MX_LIBRARY _matlab_find_mx) +if(_matlab_find_mx GREATER -1) + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MX_LIBRARY + mx + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + + if(Matlab_MX_LIBRARY) + set(Matlab_MX_LIBRARY_FOUND TRUE) + endif() +endif() +unset(_matlab_find_mx) + + +# Component ENG library +list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng) +if(_matlab_find_eng GREATER -1) + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_ENG_LIBRARY + eng + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + if(Matlab_ENG_LIBRARY) + set(Matlab_ENG_LIBRARY_FOUND TRUE) + endif() +endif() +unset(_matlab_find_eng) + + + + + +unset(_matlab_lib_dir_for_search) + + +set(Matlab_LIBRARIES ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${Matlab_ENG_LIBRARY}) + + +find_package_handle_standard_args( + Matlab + FOUND_VAR Matlab_FOUND + REQUIRED_VARS ${_matlab_required_variables} + VERSION_VAR Matlab_VERSION_STRING + HANDLE_COMPONENTS) + +unset(_matlab_required_variables) +unset(_matlab_bin_prefix) +unset(_matlab_bin_suffix_32bits) +unset(_matlab_bin_suffix_64bits) +unset(_matlab_current_suffix) +unset(_matlab_lib_dir_for_search) +unset(_matlab_lib_prefix_for_search) + +if(Matlab_INCLUDE_DIRS AND Matlab_LIBRARIES) + mark_as_advanced( + #Matlab_LIBRARIES + Matlab_MEX_LIBRARY + Matlab_MX_LIBRARY + Matlab_ENG_LIBRARY + Matlab_INCLUDE_DIRS + Matlab_FOUND + #Matlab_ROOT_DIR + #Matlab_VERSION_STRING + Matlab_MAIN_PROGRAM + #Matlab_MEX_EXTENSION + Matlab_MEXEXTENSIONS_PROG + Matlab_MEX_EXTENSION + #Matlab_BINARIES_DIR + ) +endif() diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 2de1fb3..bcbd17d 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -33,7 +33,7 @@ # # :: # -# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME +# FIND_PACKAGE_HANDLE_STANDARD_ARGS(<NAME> # [FOUND_VAR <resultVar>] # [REQUIRED_VARS <var1>...<varN>] # [VERSION_VAR <versionvar>] diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index bf58ede..64ccde5 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake @@ -143,7 +143,7 @@ endmacro() # - _pkgconfig_add_extra_path(_extra_paths ENV VAR) function(_pkgconfig_add_extra_path _extra_paths_var _var) set(_is_env 0) - if(_var STREQUAL "ENV") + if(ARGC GREATER 2 AND _var STREQUAL "ENV") set(_var ${ARGV2}) set(_is_env 1) endif() diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index 4be16c9..e5ea210 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -234,11 +234,16 @@ if(WIN32) set( _RUBY_MSVC_RUNTIME "90" ) endif() + set(_RUBY_ARCH_PREFIX "") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_RUBY_ARCH_PREFIX "x64-") + endif() + list(APPEND _RUBY_POSSIBLE_LIB_NAMES - "msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}" - "msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static" - "msvcrt-ruby${_RUBY_NODOT_VERSION}" - "msvcrt-ruby${_RUBY_NODOT_VERSION}-static" ) + "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}" + "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static" + "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}" + "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}-static" ) endif() find_library(RUBY_LIBRARY NAMES ${_RUBY_POSSIBLE_LIB_NAMES} HINTS ${RUBY_POSSIBLE_LIB_DIR} ) diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake new file mode 100644 index 0000000..3cd9c22 --- /dev/null +++ b/Modules/FindXCTest.cmake @@ -0,0 +1,196 @@ +#[=======================================================================[.rst: +FindXCTest +---------- + +Functions to help creating and executing XCTest bundles. + +An XCTest bundle is a CFBundle with a special product-type +and bundle extension. The Mac Developer Library provides more +information in the `Testing with Xcode`_ document. + +.. _Testing with Xcode: http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/ + +Module Functions +^^^^^^^^^^^^^^^^ + +.. command:: xctest_add_bundle + + The ``xctest_add_bundle`` function creates a XCTest bundle named + <target> which will test the target <testee>. Supported target types + for testee are Frameworks and App Bundles:: + + xctest_add_bundle( + <target> # Name of the XCTest bundle + <testee> # Target name of the testee + ) + +.. command:: xctest_add_test + + The ``xctest_add_test`` function adds an XCTest bundle to the + project to be run by :manual:`ctest(1)`. The test will be named + <name> and tests <bundle>:: + + xctest_add_test( + <name> # Test name + <bundle> # Target name of XCTest bundle + ) + +Module Variables +^^^^^^^^^^^^^^^^ + +The following variables are set by including this module: + +.. variable:: XCTest_FOUND + + True if the XCTest Framework and executable were found. + +.. variable:: XCTest_EXECUTABLE + + The path to the xctest command line tool used to execute XCTest bundles. + +.. variable:: XCTest_INCLUDE_DIRS + + The directory containing the XCTest Framework headers. + +.. variable:: XCTest_LIBRARIES + + The location of the XCTest Framework. + +#]=======================================================================] + +#============================================================================= +# Copyright 2015 Gregor Jasny +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +find_path(XCTest_INCLUDE_DIR + NAMES "XCTest/XCTest.h" + DOC "XCTest include directory") +mark_as_advanced(XCTest_INCLUDE_DIR) + +find_library(XCTest_LIBRARY + NAMES XCTest + DOC "XCTest Framework library") +mark_as_advanced(XCTest_LIBRARY) + +execute_process( + COMMAND xcrun --find xctest + OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_VARIABLE _xcrun_err) +if(_xcrun_out) + set(XCTest_EXECUTABLE "${_xcrun_out}" CACHE FILEPATH "XCTest executable") + mark_as_advanced(XCTest_EXECUTABLE) +endif() + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(XCTest + FOUND_VAR XCTest_FOUND + REQUIRED_VARS XCTest_LIBRARY XCTest_INCLUDE_DIR XCTest_EXECUTABLE) + +if(XCTest_FOUND) + set(XCTest_INCLUDE_DIRS "${XCTest_INCLUDE_DIR}") + set(XCTest_LIBRARIES "${XCTest_LIBRARY}") +endif(XCTest_FOUND) + + +function(xctest_add_bundle target testee) + if(NOT XCTest_FOUND) + message(FATAL_ERROR "XCTest is required to create a XCTest Bundle.") + endif(NOT XCTest_FOUND) + + if(NOT CMAKE_OSX_SYSROOT) + message(FATAL_ERROR "Adding XCTest bundles requires CMAKE_OSX_SYSROOT to be set.") + endif() + + add_library(${target} MODULE ${ARGN}) + + set_target_properties(${target} PROPERTIES + BUNDLE TRUE + XCTEST TRUE + XCTEST_TESTEE ${testee}) + + target_link_libraries(${target} PRIVATE "-framework Foundation") + target_link_libraries(${target} PRIVATE ${XCTest_LIBRARIES}) + target_include_directories(${target} PRIVATE ${XCTest_INCLUDE_DIRS}) + + # retrieve testee target type + if(NOT TARGET ${testee}) + message(FATAL_ERROR "${testee} is not a target.") + endif() + get_property(_testee_type TARGET ${testee} PROPERTY TYPE) + get_property(_testee_framework TARGET ${testee} PROPERTY FRAMEWORK) + get_property(_testee_macosx_bundle TARGET ${testee} PROPERTY MACOSX_BUNDLE) + + if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework) + # testee is a Framework + target_link_libraries(${target} PRIVATE ${testee}) + + elseif(_testee_type STREQUAL "EXECUTABLE" AND _testee_macosx_bundle) + # testee is an App Bundle + add_dependencies(${target} ${testee}) + if(XCODE) + set_target_properties(${target} PROPERTIES + XCODE_ATTRIBUTE_BUNDLE_LOADER "$(TEST_HOST)" + XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:${testee}>") + else(XCODE) + target_link_libraries(${target} + PRIVATE -bundle_loader $<TARGET_FILE:${testee}>) + endif(XCODE) + + else() + message(FATAL_ERROR "Testee ${testee} is of unsupported type.") + endif() +endfunction(xctest_add_bundle) + + +function(xctest_add_test name bundle) + if(NOT XCTest_EXECUTABLE) + message(FATAL_ERROR "XCTest executable is required to register a test.") + endif() + + # check that bundle is a XCTest Bundle + + if(NOT TARGET ${bundle}) + message(FATAL_ERROR "${bundle} is not a target.") + endif(NOT TARGET ${bundle}) + + get_property(_test_type TARGET ${bundle} PROPERTY TYPE) + get_property(_test_bundle TARGET ${bundle} PROPERTY BUNDLE) + get_property(_test_xctest TARGET ${bundle} PROPERTY XCTEST) + + if(NOT _test_type STREQUAL "MODULE_LIBRARY" + OR NOT _test_xctest OR NOT _test_bundle) + message(FATAL_ERROR "Test ${bundle} is not an XCTest Bundle") + endif() + + # get and check testee properties + + get_property(_testee TARGET ${bundle} PROPERTY XCTEST_TESTEE) + if(NOT TARGET ${_testee}) + message(FATAL_ERROR "${_testee} is not a target.") + endif() + + get_property(_testee_type TARGET ${_testee} PROPERTY TYPE) + get_property(_testee_framework TARGET ${_testee} PROPERTY FRAMEWORK) + + # register test + + add_test( + NAME ${name} + COMMAND ${XCTest_EXECUTABLE} $<TARGET_LINKER_FILE_DIR:${bundle}>/../..) + + # point loader to testee in case rpath is disabled + + if(_testee_type STREQUAL "SHARED_LIBRARY" AND _testee_framework) + set_property(TEST ${name} APPEND PROPERTY + ENVIRONMENT DYLD_FRAMEWORK_PATH=$<TARGET_LINKER_FILE_DIR:${_testee}>/..) + endif() +endfunction(xctest_add_test) diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index 0c6256c..aab29ea 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -395,7 +395,7 @@ function(add_compiler_export_flags) # Either return the extra flags needed in the supplied argument, or to the # CMAKE_CXX_FLAGS if no argument is supplied. - if(ARGV0) + if(ARGC GREATER 0) set(${ARGV0} "${EXTRA_FLAGS}" PARENT_SCOPE) else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS}" PARENT_SCOPE) diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 712a41c..23d486e 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -260,6 +260,13 @@ function(is_file_executable file result_var) return() endif() + # "file" version 5.22 does not print "(used shared libraries)" + # but uses "interpreter" + if("${file_ov}" MATCHES "shared object.*interpreter") + set(${result_var} 1 PARENT_SCOPE) + return() + endif() + else() message(STATUS "warning: No 'file' command, skipping execute_process...") endif() @@ -323,7 +330,11 @@ endfunction() function(gp_resolve_item context item exepath dirs resolved_item_var) set(resolved 0) set(resolved_item "${item}") - set(rpaths "${ARGV5}") + if(ARGC GREATER 5) + set(rpaths "${ARGV5}") + else() + set(rpaths "") + endif() # Is it already resolved? # @@ -474,7 +485,11 @@ endfunction() function(gp_resolved_file_type original_file file exepath dirs type_var) - set(rpaths "${ARGV5}") + if(ARGC GREATER 5) + set(rpaths "${ARGV5}") + else() + set(rpaths "") + endif() #message(STATUS "**") if(NOT IS_ABSOLUTE "${original_file}") @@ -616,7 +631,11 @@ endfunction() function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs) set(verbose 0) set(eol_char "E") - set(rpaths "${ARGV6}") + if(ARGC GREATER 6) + set(rpaths "${ARGV6}") + else() + set(rpaths "") + endif() if(NOT IS_ABSOLUTE "${target}") message("warning: target '${target}' is not absolute...") @@ -874,22 +893,22 @@ endfunction() function(list_prerequisites target) - if("${ARGV1}" STREQUAL "") - set(all 1) - else() + if(ARGC GREATER 1 AND NOT "${ARGV1}" STREQUAL "") set(all "${ARGV1}") + else() + set(all 1) endif() - if("${ARGV2}" STREQUAL "") - set(exclude_system 0) - else() + if(ARGC GREATER 2 AND NOT "${ARGV2}" STREQUAL "") set(exclude_system "${ARGV2}") + else() + set(exclude_system 0) endif() - if("${ARGV3}" STREQUAL "") - set(verbose 0) - else() + if(ARGC GREATER 3 AND NOT "${ARGV3}" STREQUAL "") set(verbose "${ARGV3}") + else() + set(verbose 0) endif() set(count 0) diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index 5afb517..c7e88ba 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -2,36 +2,49 @@ # InstallRequiredSystemLibraries # ------------------------------ # +# Include this module to search for compiler-provided system runtime +# libraries and add install rules for them. Some optional variables +# may be set prior to including the module to adjust behavior: # +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` +# Specify additional runtime libraries that may not be detected. +# After inclusion any detected libraries will be appended to this. # -# By including this file, all library files listed in the variable -# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS will be installed with -# install(PROGRAMS ...) into bin for WIN32 and lib for non-WIN32. If -# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP is set to TRUE before including -# this file, then the INSTALL command is not called. The user can use -# the variable CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS to use a custom install -# command and install them however they want. If it is the MSVC -# compiler, then the microsoft run time libraries will be found and -# automatically added to the CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS, and -# installed. If CMAKE_INSTALL_DEBUG_LIBRARIES is set and it is the MSVC -# compiler, then the debug libraries are installed when available. If -# CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY is set then only the debug -# libraries are installed when both debug and release are available. If -# CMAKE_INSTALL_MFC_LIBRARIES is set then the MFC run time libraries are -# installed as well as the CRT run time libraries. If -# CMAKE_INSTALL_OPENMP_LIBRARIES is set then the OpenMP run time libraries -# are installed as well. If -# CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION is set then the libraries are -# installed to that directory rather than the default. If -# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS is NOT set, then this -# file warns about required files that do not exist. You can set this -# variable to ON before including this file to avoid the warning. For -# example, the Visual Studio Express editions do not include the -# redistributable files, so if you include this file on a machine with -# only VS Express installed, you'll get the warning. +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP`` +# Set to TRUE to skip calling the :command:`install(PROGRAMS)` command to +# allow the includer to specify its own install rule, using the value of +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` to get the list of libraries. +# +# ``CMAKE_INSTALL_DEBUG_LIBRARIES`` +# Set to TRUE to install the debug runtime libraries when available +# with MSVC tools. +# +# ``CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY`` +# Set to TRUE to install only the debug runtime libraries with MSVC +# tools even if the release runtime libraries are also available. +# +# ``CMAKE_INSTALL_MFC_LIBRARIES`` +# Set to TRUE to install the MSVC MFC runtime libraries. +# +# ``CMAKE_INSTALL_OPENMP_LIBRARIES`` +# Set to TRUE to install the MSVC OpenMP runtime libraries +# +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION`` +# Specify the :command:`install(PROGRAMS)` command ``DESTINATION`` +# option. If not specified, the default is ``bin`` on Windows +# and ``lib`` elsewhere. +# +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS`` +# Set to TRUE to disable warnings about required library files that +# do not exist. (For example, Visual Studio Express editions may +# not provide the redistributable files.) +# +# ``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT`` +# Specify the :command:`install(PROGRAMS)` command ``COMPONENT`` +# option. If not specified, no such option will be used. #============================================================================= -# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006-2015 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -477,7 +490,13 @@ if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib) endif() endif() + if(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT) + set(_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT + COMPONENT ${CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}) + endif() install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} - DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION}) + DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION} + ${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT} + ) endif() endif() diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake new file mode 100644 index 0000000..ebccbf6 --- /dev/null +++ b/Modules/MatlabTestsRedirect.cmake @@ -0,0 +1,92 @@ +# This is an undocumented internal helper for the FindMatlab +# module ``matlab_add_unit_test`` command. + +#============================================================================= +# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society +# +# 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.) + + +# Usage: cmake +# -Dtest_timeout=180 +# -Dworking_directory="." +# -Doutput_directory= +# -Dadditional_paths="" +# -Dno_unittest_framework="" +# -DMatlab_PROGRAM=matlab_exe_location +# -DMatlab_ADDITIONNAL_STARTUP_OPTIONS="" +# -Dtest_name=name_of_the_test +# -Dcmd_to_run_before_test="" +# -Dunittest_file_to_run +# -P FindMatlab_TestsRedirect.cmake + +set(Matlab_UNIT_TESTS_CMD -nosplash -nojvm -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS}) +if(WIN32) + set(Matlab_UNIT_TESTS_CMD ${Matlab_UNIT_TESTS_CMD} -wait) +endif() + +if(NOT test_timeout) + set(test_timeout 180) +endif() + +if(NOT cmd_to_run_before_test) + set(cmd_to_run_before_test) +endif() + +get_filename_component(unittest_file_directory "${unittest_file_to_run}" DIRECTORY) +get_filename_component(unittest_file_to_run_name "${unittest_file_to_run}" NAME_WE) + +set(concat_string '${unittest_file_directory}') +foreach(s IN LISTS additional_paths) + if(NOT "${s}" STREQUAL "") + set(concat_string "${concat_string}, '${s}'") + endif() +endforeach() + +set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))") +if(no_unittest_framework) + set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)") +endif() + +set(Matlab_SCRIPT_TO_RUN + "addpath(${concat_string}), path, ${cmd_to_run_before_test}, ${unittest_to_run}" + ) + +set(Matlab_LOG_FILE "${output_directory}/${test_name}.log") + +set(devnull) +if(UNIX) + set(devnull INPUT_FILE /dev/null) +elseif(WIN32) + set(devnull INPUT_FILE NUL) +endif() + +execute_process( + COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${test_name}.log" -r "${Matlab_SCRIPT_TO_RUN}" + RESULT_VARIABLE res + TIMEOUT ${test_timeout} + OUTPUT_QUIET # we do not want the output twice + WORKING_DIRECTORY "${output_directory}" + ${devnull} + ) + +if(NOT EXISTS ${Matlab_LOG_FILE}) + message( FATAL_ERROR "[MATLAB] ERROR: cannot find the log file ${Matlab_LOG_FILE}") +endif() + +# print the output in any case. +file(READ ${Matlab_LOG_FILE} matlab_log_content) +message("Matlab test ${name_of_the_test} output:\n${matlab_log_content}") # if we put FATAL_ERROR here, the file is indented. + + +if(NOT (res EQUAL 0)) + message( FATAL_ERROR "[MATLAB] TEST FAILED" ) +endif() diff --git a/Modules/Platform/BlueGeneQ-base.cmake b/Modules/Platform/BlueGeneQ-base.cmake new file mode 100644 index 0000000..fa8dc52 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-base.cmake @@ -0,0 +1,177 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +# +# Blue Gene/Q base platform file. +# +# NOTE: Do not set your platform to "BlueGeneQ-base". This file is +# included by the real platform files. Use one of these two platforms +# instead: +# +# BlueGeneQ-dynamic For dynamically linked executables +# BlueGeneQ-static For statically linked executables +# +# The platform you choose doesn't affect whether or not you can build +# shared or static libraries -- it ONLY changs whether exeuatbles are linked +# statically or dynamically. +# +# This platform file tries its best to adhere to the behavior of the MPI +# compiler wrappers included with the latest BG/P drivers. +# + +# +# This adds directories that find commands should specifically ignore +# for cross compiles. Most of these directories are the includeand +# lib directories for the frontend on BG/P systems. Not ignoring +# these can cause things like FindX11 to find a frontend PPC version +# mistakenly. We use this on BG instead of re-rooting because backend +# libraries are typically strewn about the filesystem, and we can't +# re-root ALL backend libraries to a single place. +# +set(CMAKE_SYSTEM_IGNORE_PATH + /lib /lib64 /include + /usr/lib /usr/lib64 /usr/include + /usr/local/lib /usr/local/lib64 /usr/local/include + /usr/X11/lib /usr/X11/lib64 /usr/X11/include + /usr/lib/X11 /usr/lib64/X11 /usr/include/X11 + /usr/X11R6/lib /usr/X11R6/lib64 /usr/X11R6/include + /usr/X11R7/lib /usr/X11R7/lib64 /usr/X11R7/include +) + +# +# Indicate that this is a unix-like system +# +set(UNIX 1) + +# +# Library prefixes, suffixes, extra libs. +# +set(CMAKE_LINK_LIBRARY_SUFFIX "") +set(CMAKE_STATIC_LIBRARY_PREFIX "lib") # lib +set(CMAKE_STATIC_LIBRARY_SUFFIX ".a") # .a + +set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so +set(CMAKE_EXECUTABLE_SUFFIX "") # .exe + +set(CMAKE_DL_LIBS "dl") + +# +# BG/Q supports dynamic libraries regardless of whether we're building +# static or dynamic *executables*. +# +set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) +set(CMAKE_FIND_LIBRARY_PREFIXES "lib") + +# +# For BGQ builds, we're cross compiling, but we don't want to re-root things +# (e.g. with CMAKE_FIND_ROOT_PATH) because users may have libraries anywhere on +# the shared filesystems, and this may lie outside the root. Instead, we set the +# system directories so that the various system BG CNK library locations are +# searched first. This is not the clearest thing in the world, given IBM's driver +# layout, but this should cover all the standard ones. +# +macro(__BlueGeneQ_common_setup compiler_id lang) + # Need to use the version of the comm lib compiled with the right compiler. + set(__BlueGeneQ_commlib_dir gcc) + if (${compiler_id} STREQUAL XL) + set(__BlueGeneQ_commlib_dir xl) + endif() + + set(CMAKE_SYSTEM_LIBRARY_PATH + /bgsys/drivers/ppcfloor/comm/default/lib # default comm layer (used by mpi compiler wrappers) + /bgsys/drivers/ppcfloor/comm/${__BlueGeneQ_commlib_dir}/lib # PAMI, other lower-level comm libraries + /bgsys/drivers/ppcfloor/gnu-linux/lib # CNK python installation directory + /bgsys/drivers/ppcfloor/gnu-linux/powerpc64-bgq-linux/lib # CNK Linux image -- standard runtime libs, pthread, etc. + ) + + # Add all the system include paths. + set(CMAKE_SYSTEM_INCLUDE_PATH + /bgsys/drivers/ppcfloor/comm/sys/include + /bgsys/drivers/ppcfloor/ + /bgsys/drivers/ppcfloor/spi/include + /bgsys/drivers/ppcfloor/spi/include/kernel/cnk + /bgsys/drivers/ppcfloor/comm/${__BlueGeneQ_commlib_dir}/include + ) + + # Ensure that the system directories are included with the regular compilers, as users will expect this + # to do the same thing as the MPI compilers, which add these flags. + set(BGQ_SYSTEM_INCLUDES "") + foreach(dir ${CMAKE_SYSTEM_INCLUDE_PATH}) + set(BGQ_SYSTEM_INCLUDES "${BGQ_SYSTEM_INCLUDES} -I${dir}") + endforeach() + set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <FLAGS> -o <OBJECT> -c <SOURCE>") + set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <FLAGS> -o <OBJECT> -c <SOURCE>") + + # + # Code below does setup for shared libraries. That this is done + # regardless of whether the platform is static or dynamic -- you can make + # shared libraries even if you intend to make static executables, you just + # can't make a dynamic executable if you use the static platform file. + # + if (${compiler_id} STREQUAL XL) + # Flags for XL compilers if we explicitly detected XL + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-qpic") + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-qmkshrobj -qnostaticlink") + else() + # Assume flags for GNU compilers (if the ID is GNU *or* anything else). + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") + endif() + + # Both toolchains use the GNU linker on BG/P, so these options are shared. + set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-rpath,") + set(CMAKE_SHARED_LIBRARY_RPATH_LINK_${lang}_FLAG "-Wl,-rpath-link,") + set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,") + set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-dynamic") + set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "") # +s, flag for exe link to use shared lib + set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") # : or empty + +endmacro() + +# +# This macro needs to be called for dynamic library support. Unfortunately on BG, +# We can't support both static and dynamic links in the same platform file. The +# dynamic link platform file needs to call this explicitly to set up dynamic linking. +# +macro(__BlueGeneQ_setup_dynamic compiler_id lang) + __BlueGeneQ_common_setup(${compiler_id} ${lang}) + + if (${compiler_id} STREQUAL XL) + set(BGQ_${lang}_DYNAMIC_EXE_FLAGS "-qnostaticlink -qnostaticlink=libgcc") + else() + set(BGQ_${lang}_DYNAMIC_EXE_FLAGS "-dynamic") + endif() + + # For dynamic executables, need to provide special BG/Q arguments. + set(BGQ_${lang}_DEFAULT_EXE_FLAGS + "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + set(CMAKE_${lang}_LINK_EXECUTABLE + "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DYNAMIC_EXE_FLAGS} ${BGQ_${lang}_DEFAULT_EXE_FLAGS}") +endmacro() + +# +# This macro needs to be called for static builds. Right now it just adds -Wl,-relax +# to the link line. +# +macro(__BlueGeneQ_setup_static compiler_id lang) + __BlueGeneQ_common_setup(${compiler_id} ${lang}) + + # For static executables, use default link settings. + set(BGQ_${lang}_DEFAULT_EXE_FLAGS + "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") + set(CMAKE_${lang}_LINK_EXECUTABLE + "<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DEFAULT_EXE_FLAGS}") +endmacro() diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake new file mode 100644 index 0000000..102ac80 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-C.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(GNU C) diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake new file mode 100644 index 0000000..cd8ab24 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-CXX.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(GNU CXX) diff --git a/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake b/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake new file mode 100644 index 0000000..c029f0f --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-GNU-Fortran.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(GNU Fortran) diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake new file mode 100644 index 0000000..0077313 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-XL-C.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(XL C) diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake new file mode 100644 index 0000000..0f43cb2 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-XL-CXX.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(XL CXX) diff --git a/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake b/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake new file mode 100644 index 0000000..12e446e --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic-XL-Fortran.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_dynamic(XL Fortran) diff --git a/Modules/Platform/BlueGeneQ-dynamic.cmake b/Modules/Platform/BlueGeneQ-dynamic.cmake new file mode 100644 index 0000000..0283900 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-dynamic.cmake @@ -0,0 +1,17 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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(Platform/BlueGeneQ-base) +set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") diff --git a/Modules/Platform/BlueGeneQ-static-GNU-C.cmake b/Modules/Platform/BlueGeneQ-static-GNU-C.cmake new file mode 100644 index 0000000..70c84ba --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-GNU-C.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(GNU C) diff --git a/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake b/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake new file mode 100644 index 0000000..8f991de --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-GNU-CXX.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(GNU CXX) diff --git a/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake b/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake new file mode 100644 index 0000000..24dd9e7 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-GNU-Fortran.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(GNU Fortran) diff --git a/Modules/Platform/BlueGeneQ-static-XL-C.cmake b/Modules/Platform/BlueGeneQ-static-XL-C.cmake new file mode 100644 index 0000000..5555a68 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-XL-C.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(XL C) diff --git a/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake new file mode 100644 index 0000000..07c3c3d --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-XL-CXX.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(XL CXX) diff --git a/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake b/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake new file mode 100644 index 0000000..6f99933 --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static-XL-Fortran.cmake @@ -0,0 +1,16 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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.) + +__BlueGeneQ_setup_static(XL Fortran) diff --git a/Modules/Platform/BlueGeneQ-static.cmake b/Modules/Platform/BlueGeneQ-static.cmake new file mode 100644 index 0000000..30b530d --- /dev/null +++ b/Modules/Platform/BlueGeneQ-static.cmake @@ -0,0 +1,17 @@ + +#============================================================================= +# Copyright 2010 Kitware, Inc. +# Copyright 2010 Todd Gamblin <tgamblin@llnl.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(Platform/BlueGeneQ-base) +set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake index fe25ab2..3144ac4 100644 --- a/Modules/Platform/CYGWIN-GNU.cmake +++ b/Modules/Platform/CYGWIN-GNU.cmake @@ -25,7 +25,6 @@ set(CMAKE_CREATE_WIN32_EXE "-mwindows") set(CMAKE_GNULD_IMAGE_VERSION "-Wl,--major-image-version,<TARGET_VERSION_MAJOR>,--minor-image-version,<TARGET_VERSION_MINOR>") set(CMAKE_GENERATOR_RC windres) -enable_language(RC) macro(__cygwin_compiler_gnu lang) # Binary link rules. set(CMAKE_${lang}_CREATE_SHARED_MODULE @@ -53,4 +52,6 @@ macro(__cygwin_compiler_gnu lang) # TODO: Is -Wl,--enable-auto-import now always default? set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS} -Wl,--enable-auto-import") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS}") + + enable_language(RC) endmacro() diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index e5c5f36..4e4810a 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -166,6 +166,21 @@ if(_CMAKE_OSX_SYSROOT_PATH) ${_CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks ${_CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks ) + # add platform developer framework path if exists + foreach(_path + # Xcode 6 + ${_CMAKE_OSX_SYSROOT_PATH}/../../Library/Frameworks + # Xcode 5 iOS + ${_CMAKE_OSX_SYSROOT_PATH}/Developer/Library/Frameworks + # Xcode 5 OSX + ${_CMAKE_OSX_SYSROOT_PATH}/../../../../../Library/Frameworks + ) + get_filename_component(_abolute_path "${_path}" ABSOLUTE) + if(EXISTS "${_abolute_path}") + list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH "${_abolute_path}") + break() + endif() + endforeach() endif() list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH /Library/Frameworks diff --git a/Modules/Platform/Linux-PGI.cmake b/Modules/Platform/Linux-PGI.cmake index 3cbb35c..baa2248 100644 --- a/Modules/Platform/Linux-PGI.cmake +++ b/Modules/Platform/Linux-PGI.cmake @@ -21,7 +21,7 @@ set(__LINUX_COMPILER_PGI 1) macro(__linux_compiler_pgi lang) # Shared library compile and link flags. set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC") - set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "") set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC") set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared") endmacro() diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake index fe8e003..e40a74f 100644 --- a/Modules/Platform/Linux.cmake +++ b/Modules/Platform/Linux.cmake @@ -52,6 +52,6 @@ include(Platform/UnixPaths) # Debian has lib64 paths only for compatibility so they should not be # searched. -if(EXISTS "/etc/debian_version") +if(NOT CMAKE_CROSSCOMPILING AND EXISTS "/etc/debian_version") set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE) endif() diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index ffc5657..c827c32 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -35,7 +35,7 @@ endif() if(MINGW) set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "") - set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib") + set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib") set(CMAKE_C_STANDARD_LIBRARIES_INIT "-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32") set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") endif() @@ -61,8 +61,6 @@ if(NOT CMAKE_GENERATOR_RC AND CMAKE_GENERATOR MATCHES "Unix Makefiles") set(CMAKE_GENERATOR_RC windres) endif() -enable_language(RC) - macro(__windows_compiler_gnu lang) if(MSYS OR MINGW) @@ -139,6 +137,8 @@ macro(__windows_compiler_gnu lang) ) endforeach() endif() + + enable_language(RC) endmacro() macro(__windows_compiler_gnu_abi lang) diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 2440f89..2905cee 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -53,10 +53,6 @@ if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio") set (CMAKE_NO_BUILD_TYPE 1) endif() -# make sure to enable languages after setting configuration types -enable_language(RC) -set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>") - if("${CMAKE_GENERATOR}" MATCHES "Visual Studio") set(MSVC_IDE 1) else() @@ -131,14 +127,18 @@ endif() # default to Debug builds set(CMAKE_BUILD_TYPE_INIT Debug) +# Compute an architecture family from the architecture id. +foreach(lang C CXX) + set(_MSVC_${lang}_ARCHITECTURE_FAMILY "${MSVC_${lang}_ARCHITECTURE_ID}") + if(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^ARM") + set(_MSVC_${lang}_ARCHITECTURE_FAMILY "ARM") + elseif(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^SH") + set(_MSVC_${lang}_ARCHITECTURE_FAMILY "SHx") + endif() +endforeach() + if(WINCE) foreach(lang C CXX) - set(_MSVC_${lang}_ARCHITECTURE_FAMILY "${MSVC_${lang}_ARCHITECTURE_ID}") - if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "THUMB") - set(_MSVC_${lang}_ARCHITECTURE_FAMILY "ARM") - elseif(_MSVC_${lang}_ARCHITECTURE_FAMILY MATCHES "^SH") - set(_MSVC_${lang}_ARCHITECTURE_FAMILY "SHx") - endif() string(TOUPPER "${_MSVC_${lang}_ARCHITECTURE_FAMILY}" _MSVC_${lang}_ARCHITECTURE_FAMILY_UPPER) endforeach() @@ -150,12 +150,23 @@ if(WINCE) message(FATAL_ERROR "Invalid Windows CE version: ${CMAKE_SYSTEM_VERSION}") endif() - set(_PLATFORM_DEFINES "/D_WIN32_WCE=0x${_CE_VERSION} /DUNDER_CE") + set(_PLATFORM_DEFINES "/D_WIN32_WCE=0x${_CE_VERSION} /DUNDER_CE /DWINCE") set(_PLATFORM_DEFINES_C " /D${_MSVC_C_ARCHITECTURE_FAMILY} /D_${_MSVC_C_ARCHITECTURE_FAMILY_UPPER}_") set(_PLATFORM_DEFINES_CXX " /D${_MSVC_CXX_ARCHITECTURE_FAMILY} /D_${_MSVC_CXX_ARCHITECTURE_FAMILY_UPPER}_") set(_RTC1 "") + set(_FLAGS_C "") set(_FLAGS_CXX " /GR /EHsc") + + foreach(lang C CXX) + if(_MSVC_${lang}_ARCHITECTURE_FAMILY STREQUAL "ARM") + set(_PLATFORM_DEFINES_${lang} "${_PLATFORM_DEFINES_${lang}} /D${MSVC_${lang}_ARCHITECTURE_ID}") + if(MSVC_${lang}_ARCHITECTURE_ID MATCHES "^ARMV([45])I$") + set(_FLAGS_${lang} "${_FLAGS_${lang}} /QRarch${CMAKE_MATCH_1}T") + endif() + endif() + endforeach() + set(CMAKE_C_STANDARD_LIBRARIES_INIT "coredll.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib") set(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT} /NODEFAULTLIB:libc.lib /NODEFAULTLIB:oldnames.lib") @@ -168,7 +179,7 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE) set(_FLAGS_CXX " /DUNICODE /D_UNICODE /GR /EHsc") if(WINDOWS_PHONE) set(CMAKE_C_STANDARD_LIBRARIES_INIT "WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib") - elseif(MSVC_C_ARCHITECTURE_ID STREQUAL ARM OR MSVC_CXX_ARCHITECTURE_ID STREQUAL ARM) + elseif(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM") set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib") else() set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib") @@ -176,7 +187,7 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE) else() set(_PLATFORM_DEFINES "/DWIN32") - if(MSVC_C_ARCHITECTURE_ID STREQUAL ARM OR MSVC_CXX_ARCHITECTURE_ID STREQUAL ARM) + if(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM") set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib") elseif(MSVC_VERSION GREATER 1310) set(_RTC1 "/RTC1") @@ -200,9 +211,21 @@ set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") set (CMAKE_LINK_DEF_FILE_FLAG "/DEF:") # set the machine type if(MSVC_C_ARCHITECTURE_ID) - set(_MACHINE_ARCH_FLAG "/machine:${MSVC_C_ARCHITECTURE_ID}") + if(MSVC_C_ARCHITECTURE_ID MATCHES "^ARMV.I") + set(_MACHINE_ARCH_FLAG "/machine:THUMB") + elseif(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM") + set(_MACHINE_ARCH_FLAG "/machine:ARM") + else() + set(_MACHINE_ARCH_FLAG "/machine:${MSVC_C_ARCHITECTURE_ID}") + endif() elseif(MSVC_CXX_ARCHITECTURE_ID) - set(_MACHINE_ARCH_FLAG "/machine:${MSVC_CXX_ARCHITECTURE_ID}") + if(MSVC_CXX_ARCHITECTURE_ID MATCHES "^ARMV.I") + set(_MACHINE_ARCH_FLAG "/machine:THUMB") + elseif(_MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM") + set(_MACHINE_ARCH_FLAG "/machine:ARM") + else() + set(_MACHINE_ARCH_FLAG "/machine:${MSVC_CXX_ARCHITECTURE_ID}") + endif() elseif(MSVC_Fortran_ARCHITECTURE_ID) set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}") endif() @@ -274,4 +297,10 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG") set(CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "/MD /O1 /Ob1 /D NDEBUG") set(CMAKE_${lang}_LINKER_SUPPORTS_PDB ON) + + if(NOT CMAKE_RC_FLAGS_INIT) + set(CMAKE_RC_FLAGS_INIT "${_PLATFORM_DEFINES} ${_PLATFORM_DEFINES_${lang}}") + endif() + + enable_language(RC) endmacro() diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake index 59d88a3..0beba73 100644 --- a/Modules/Platform/Windows-df.cmake +++ b/Modules/Platform/Windows-df.cmake @@ -24,8 +24,6 @@ set(CMAKE_Fortran_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /o set(CMAKE_Fortran_COMPILE_OBJECT "<CMAKE_Fortran_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}") -set(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>") - set(CMAKE_Fortran_LINK_EXECUTABLE "<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 6516b0a..3b0a6cc 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -158,7 +158,7 @@ macro (QT4_GENERATE_MOC infile outfile ) set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}") endif() - if ("x${ARGV2}" STREQUAL "xTARGET") + if (${ARGC} GREATER 3 AND "x${ARGV2}" STREQUAL "xTARGET") set(moc_target ${ARGV3}) endif() QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}") @@ -329,7 +329,10 @@ endmacro() macro(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optionalBasename _optionalClassName) get_filename_component(_infile ${_xml_file} ABSOLUTE) - set(_optionalBasename "${ARGV4}") + unset(_optionalBasename) + if(${ARGC} GREATER 4) + set(_optionalBasename "${ARGV4}") + endif() if (_optionalBasename) set(_basename ${_optionalBasename} ) else () @@ -337,7 +340,10 @@ macro(QT4_ADD_DBUS_ADAPTOR _sources _xml_file _include _parentClass) # _optional string(TOLOWER ${_basename} _basename) endif () - set(_optionalClassName "${ARGV5}") + unset(_optionalClassName) + if(${ARGC} GREATER 5) + set(_optionalClassName "${ARGV5}") + endif() set(_header "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.h") set(_impl "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.cpp") set(_moc "${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc") diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index 3a6acd8..5eb0ca8 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -340,6 +340,13 @@ set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) function(add_jar _TARGET_NAME) + cmake_parse_arguments(_add_jar + "" + "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST" + "SOURCES;INCLUDE_JARS" + ${ARGN} + ) + # In CMake < 2.8.12, add_jar used variables which were set prior to calling # add_jar for customizing the behavior of add_jar. In order to be backwards # compatible, check if any of those variables are set, and use them to @@ -347,28 +354,21 @@ function(add_jar _TARGET_NAME) # argument will override the value set here.) # # New features should use named arguments only. - if(DEFINED CMAKE_JAVA_TARGET_VERSION) + if(NOT DEFINED _add_jar_VERSION AND DEFINED CMAKE_JAVA_TARGET_VERSION) set(_add_jar_VERSION "${CMAKE_JAVA_TARGET_VERSION}") endif() - if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) + if(NOT DEFINED _add_jar_OUTPUT_DIR AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR) set(_add_jar_OUTPUT_DIR "${CMAKE_JAVA_TARGET_OUTPUT_DIR}") endif() - if(DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME) + if(NOT DEFINED _add_jar_OUTPUT_NAME AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME) set(_add_jar_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}") # reset set(CMAKE_JAVA_TARGET_OUTPUT_NAME) endif() - if(DEFINED CMAKE_JAVA_JAR_ENTRY_POINT) + if(NOT DEFINED _add_jar_ENTRY_POINT AND DEFINED CMAKE_JAVA_JAR_ENTRY_POINT) set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}") endif() - cmake_parse_arguments(_add_jar - "" - "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST" - "SOURCES;INCLUDE_JARS" - ${ARGN} - ) - set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS}) if (NOT DEFINED _add_jar_OUTPUT_DIR) diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 7939b1f..7423418 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -204,8 +204,7 @@ macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) ${swig_include_dirs} -o "${swig_generated_file_fullname}" "${swig_source_file_fullname}" - MAIN_DEPENDENCY "${swig_source_file_fullname}" - DEPENDS ${SWIG_MODULE_${name}_EXTRA_DEPS} + DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS} COMMENT "Swig source") set_source_files_properties("${swig_generated_file_fullname}" ${swig_extra_generated_files} PROPERTIES GENERATED 1) diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in index bbb7c88..c4fc83a 100644 --- a/Modules/WIX.template.in +++ b/Modules/WIX.template.in @@ -42,5 +42,6 @@ <UIRef Id="$(var.CPACK_WIX_UI_REF)" /> <?include "properties.wxi"?> + <?include "product_fragment.wxi"?> </Product> </Wix> diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index d18f47c..f4dcb21 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -586,7 +586,7 @@ function(write_compiler_detection_header # if ${def_name} # define ${def_value} nullptr # else -# define ${def_value} static_cast<void*>(0) +# define ${def_value} 0 # endif \n") endif() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 8a83c3e..04f6a81 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -229,6 +229,8 @@ set(SRCS cmExtraKateGenerator.h cmExtraSublimeTextGenerator.cxx cmExtraSublimeTextGenerator.h + cmExtraQbsGenerator.cxx + cmExtraQbsGenerator.h cmFileLock.cxx cmFileLock.h cmFileLockPool.cxx @@ -238,12 +240,16 @@ set(SRCS cmFileTimeComparison.cxx cmFileTimeComparison.h cmGeneratedFileStream.cxx + cmGeneratorExpressionContext.cxx + cmGeneratorExpressionContext.h cmGeneratorExpressionDAGChecker.cxx cmGeneratorExpressionDAGChecker.h cmGeneratorExpressionEvaluator.cxx cmGeneratorExpressionEvaluator.h cmGeneratorExpressionLexer.cxx cmGeneratorExpressionLexer.h + cmGeneratorExpressionNode.cxx + cmGeneratorExpressionNode.h cmGeneratorExpressionParser.cxx cmGeneratorExpressionParser.h cmGeneratorExpression.cxx @@ -520,8 +526,8 @@ if(APPLE) target_link_libraries(CMakeLib "-framework CoreFoundation") endif() -# On some platforms we need the rpcrt4 library for the VS 7 generators. if(CMAKE_BUILD_ON_VISUAL_STUDIO OR MINGW) + # We need the rpcrt4 library for at least the VS7-VC10 generators. target_link_libraries(CMakeLib rpcrt4) endif() @@ -638,14 +644,25 @@ endif() if(WIN32) set(CPACK_SRCS ${CPACK_SRCS} CPack/WiX/cmCPackWIXGenerator.cxx + CPack/WiX/cmCPackWIXGenerator.h CPack/WiX/cmWIXAccessControlList.cxx + CPack/WiX/cmWIXAccessControlList.h CPack/WiX/cmWIXDirectoriesSourceWriter.cxx + CPack/WiX/cmWIXDirectoriesSourceWriter.h CPack/WiX/cmWIXFeaturesSourceWriter.cxx + CPack/WiX/cmWIXFeaturesSourceWriter.h CPack/WiX/cmWIXFilesSourceWriter.cxx + CPack/WiX/cmWIXFilesSourceWriter.h CPack/WiX/cmWIXPatch.cxx + CPack/WiX/cmWIXPatch.h CPack/WiX/cmWIXPatchParser.cxx + CPack/WiX/cmWIXPatchParser.h CPack/WiX/cmWIXRichTextFormatWriter.cxx + CPack/WiX/cmWIXRichTextFormatWriter.h + CPack/WiX/cmWIXShortcut.cxx + CPack/WiX/cmWIXShortcut.h CPack/WiX/cmWIXSourceWriter.cxx + CPack/WiX/cmWIXSourceWriter.h ) endif() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 8e7ccd1..8a93101 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 2) -set(CMake_VERSION_PATCH 1) -#set(CMake_VERSION_RC 0) +set(CMake_VERSION_PATCH 20150403) +#set(CMake_VERSION_RC 1) diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx index d9d6236..1d7afbd 100644 --- a/Source/CPack/OSXScriptLauncher.cxx +++ b/Source/CPack/OSXScriptLauncher.cxx @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { //if ( cmsys::SystemTools::FileExists( - cmsys_stl::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory(); + std::string cwd = cmsys::SystemTools::GetCurrentWorkingDirectory(); cmsys::ofstream ofs("/tmp/output.txt"); CFStringRef fileName; @@ -66,7 +66,7 @@ int main(int argc, char* argv[]) //dispose of the CF variable CFRelease(scriptFileURL); - cmsys_stl::string fullScriptPath = reinterpret_cast<char*>(path); + std::string fullScriptPath = reinterpret_cast<char*>(path); delete [] path; @@ -75,10 +75,10 @@ int main(int argc, char* argv[]) return 1; } - cmsys_stl::string scriptDirectory = cmsys::SystemTools::GetFilenamePath( + std::string scriptDirectory = cmsys::SystemTools::GetFilenamePath( fullScriptPath); ofs << fullScriptPath.c_str() << cmsys_ios::endl; - cmsys_stl::vector<const char*> args; + std::vector<const char*> args; args.push_back(fullScriptPath.c_str()); int cc; for ( cc = 1; cc < argc; ++ cc ) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 59c38e9..99eabf2 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2000-2014 Kitware, Inc., Insight Software Consortium + Copyright 2012-2015 Kitware, Inc., Insight Software Consortium Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -33,7 +33,6 @@ #include <rpc.h> // for GUID generation cmCPackWIXGenerator::cmCPackWIXGenerator(): - HasDesktopShortcuts(false), Patch(0) { @@ -257,6 +256,7 @@ bool cmCPackWIXGenerator::PackageFilesImpl() CreateWiXVariablesIncludeFile(); CreateWiXPropertiesIncludeFile(); + CreateWiXProductFragmentIncludeFile(); if(!CreateWiXSourceFiles()) { @@ -265,13 +265,30 @@ bool cmCPackWIXGenerator::PackageFilesImpl() AppendUserSuppliedExtraSources(); + std::set<std::string> usedBaseNames; + std::stringstream objectFiles; for(size_t i = 0; i < this->WixSources.size(); ++i) { std::string const& sourceFilename = this->WixSources[i]; + std::string baseName = + cmSystemTools::GetFilenameWithoutLastExtension(sourceFilename); + + unsigned int counter = 0; + std::string uniqueBaseName = baseName; + + while(usedBaseNames.find(uniqueBaseName) != usedBaseNames.end()) + { + std::stringstream tmp; + tmp << baseName << ++counter; + uniqueBaseName = tmp.str(); + } + + usedBaseNames.insert(uniqueBaseName); + std::string objectFilename = - cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj"; + this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj"; if(!RunCandleCommand(sourceFilename, objectFilename)) { @@ -385,6 +402,17 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile() } } +void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile() +{ + std::string includeFilename = + this->CPackTopLevel + "/product_fragment.wxi"; + + cmWIXSourceWriter includeFile( + this->Logger, includeFilename, true); + + this->Patch->ApplyFragment("#PRODUCT", includeFile); +} + void cmCPackWIXGenerator::CopyDefinition( cmWIXSourceWriter &source, std::string const& name) { @@ -402,7 +430,7 @@ void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source, tmp << name << "=\"" << value << '"'; source.AddProcessingInstruction("define", - cmWIXSourceWriter::WindowsCodepageToUtf8(tmp.str())); + cmWIXSourceWriter::CMakeEncodingToUtf8(tmp.str())); } bool cmCPackWIXGenerator::CreateWiXSourceFiles() @@ -463,6 +491,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.AddAttribute("Title", cpackPackageName); featureDefinitions.AddAttribute("Level", "1"); + this->Patch->ApplyFragment("#PRODUCTFEATURE", featureDefinitions); const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY"); if(package) @@ -478,18 +507,16 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.EndElement("Feature"); - bool hasShortcuts = false; + std::set<cmWIXShortcuts::Type> emittedShortcutTypes; - shortcut_map_t globalShortcuts; + cmWIXShortcuts globalShortcuts; if(Components.empty()) { AddComponentsToFeature(toplevel, "ProductFeature", directoryDefinitions, fileDefinitions, featureDefinitions, globalShortcuts); - if(globalShortcuts.size()) - { - hasShortcuts = true; - } + + globalShortcuts.AddShortcutTypes(emittedShortcutTypes); } else { @@ -504,33 +531,29 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() std::string componentFeatureId = "CM_C_" + component.Name; - shortcut_map_t featureShortcuts; + cmWIXShortcuts featureShortcuts; AddComponentsToFeature(componentPath, componentFeatureId, directoryDefinitions, fileDefinitions, featureDefinitions, featureShortcuts); - if(featureShortcuts.size()) - { - hasShortcuts = true; - } - if(featureShortcuts.size()) + featureShortcuts.AddShortcutTypes(emittedShortcutTypes); + + if(!CreateShortcuts(component.Name, componentFeatureId, + featureShortcuts, false, fileDefinitions, featureDefinitions)) { - if(!CreateStartMenuShortcuts(component.Name, componentFeatureId, - featureShortcuts, fileDefinitions, featureDefinitions)) - { - return false; - } + return false; } } } - if(hasShortcuts) + bool emitUninstallShortcut = emittedShortcutTypes.find( + cmWIXShortcuts::START_MENU) != emittedShortcutTypes.end(); + + if(!CreateShortcuts(std::string(), "ProductFeature", + globalShortcuts, emitUninstallShortcut, + fileDefinitions, featureDefinitions)) { - if(!CreateStartMenuShortcuts(std::string(), "ProductFeature", - globalShortcuts, fileDefinitions, featureDefinitions)) - { - return false; - } + return false; } featureDefinitions.EndElement("Fragment"); @@ -539,17 +562,25 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() directoryDefinitions.EndInstallationPrefixDirectory( installRootSize); - if(hasShortcuts) + if(emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) != + emittedShortcutTypes.end()) { directoryDefinitions.EmitStartMenuFolder( GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER")); } - if(this->HasDesktopShortcuts) + if(emittedShortcutTypes.find(cmWIXShortcuts::DESKTOP) != + emittedShortcutTypes.end()) { directoryDefinitions.EmitDesktopFolder(); } + if(emittedShortcutTypes.find(cmWIXShortcuts::STARTUP) != + emittedShortcutTypes.end()) + { + directoryDefinitions.EmitStartupFolder(); + } + directoryDefinitions.EndElement("Directory"); directoryDefinitions.EndElement("Fragment"); @@ -637,7 +668,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( cmWIXDirectoriesSourceWriter& directoryDefinitions, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions, - shortcut_map_t& shortcutMap) + cmWIXShortcuts& shortcuts) { featureDefinitions.BeginElement("FeatureRef"); featureDefinitions.AddAttribute("Id", featureId); @@ -670,21 +701,82 @@ bool cmCPackWIXGenerator::AddComponentsToFeature( rootPath, "INSTALL_ROOT", directoryDefinitions, fileDefinitions, featureDefinitions, cpackPackageExecutablesList, cpackPackageDesktopLinksList, - shortcutMap); + shortcuts); featureDefinitions.EndElement("FeatureRef"); return true; } -bool cmCPackWIXGenerator::CreateStartMenuShortcuts( +bool cmCPackWIXGenerator::CreateShortcuts( + std::string const& cpackComponentName, + std::string const& featureId, + cmWIXShortcuts const& shortcuts, + bool emitUninstallShortcut, + cmWIXFilesSourceWriter& fileDefinitions, + cmWIXFeaturesSourceWriter& featureDefinitions) +{ + if(!shortcuts.empty(cmWIXShortcuts::START_MENU)) + { + if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::START_MENU, + cpackComponentName, featureId, "", + shortcuts, emitUninstallShortcut, + fileDefinitions, featureDefinitions)) + { + return false; + } + } + + if(!shortcuts.empty(cmWIXShortcuts::DESKTOP)) + { + if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::DESKTOP, + cpackComponentName, featureId, "DESKTOP", + shortcuts, false, + fileDefinitions, featureDefinitions)) + { + return false; + } + } + + if(!shortcuts.empty(cmWIXShortcuts::STARTUP)) + { + if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::STARTUP, + cpackComponentName, featureId, "STARTUP", + shortcuts, false, + fileDefinitions, featureDefinitions)) + { + return false; + } + } + + return true; +} + +bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType( + cmWIXShortcuts::Type type, std::string const& cpackComponentName, std::string const& featureId, - shortcut_map_t& shortcutMap, + std::string const& idPrefix, + cmWIXShortcuts const& shortcuts, + bool emitUninstallShortcut, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions) { - bool thisHasDesktopShortcuts = false; + std::string directoryId; + switch(type) + { + case cmWIXShortcuts::START_MENU: + directoryId = "PROGRAM_MENU_FOLDER"; + break; + case cmWIXShortcuts::DESKTOP: + directoryId = "DesktopFolder"; + break; + case cmWIXShortcuts::STARTUP: + directoryId = "StartupFolder"; + break; + default: + return false; + } featureDefinitions.BeginElement("FeatureRef"); featureDefinitions.AddAttribute("Id", featureId); @@ -708,80 +800,42 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts( idSuffix += cpackComponentName; } - std::string componentId = "CM_SHORTCUT" + idSuffix; + std::string componentId = "CM_SHORTCUT"; + if(idPrefix.size()) + { + componentId += "_" + idPrefix; + } + + componentId += idSuffix; fileDefinitions.BeginElement("DirectoryRef"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.AddAttribute("Id", directoryId); fileDefinitions.BeginElement("Component"); fileDefinitions.AddAttribute("Id", componentId); fileDefinitions.AddAttribute("Guid", "*"); - for(shortcut_map_t::const_iterator - i = shortcutMap.begin(); i != shortcutMap.end(); ++i) - { - std::string const& id = i->first; - cmWIXShortcut const& shortcut = i->second; + std::string registryKey = std::string("Software\\") + + cpackVendor + "\\" + cpackPackageName; - fileDefinitions.EmitShortcut(id, shortcut, false); + shortcuts.EmitShortcuts(type, registryKey, + cpackComponentName, fileDefinitions); - if(shortcut.desktop) - { - thisHasDesktopShortcuts = true; - } + if(type == cmWIXShortcuts::START_MENU) + { + fileDefinitions.EmitRemoveFolder( + "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix); } - if(cpackComponentName.empty()) + if(emitUninstallShortcut) { fileDefinitions.EmitUninstallShortcut(cpackPackageName); } - fileDefinitions.EmitRemoveFolder( - "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix); - - std::string registryKey = - std::string("Software\\") + cpackVendor + "\\" + cpackPackageName; - - fileDefinitions.EmitStartMenuShortcutRegistryValue( - registryKey, cpackComponentName); - fileDefinitions.EndElement("Component"); fileDefinitions.EndElement("DirectoryRef"); featureDefinitions.EmitComponentRef(componentId); - - if(thisHasDesktopShortcuts) - { - this->HasDesktopShortcuts = true; - componentId = "CM_DESKTOP_SHORTCUT" + idSuffix; - - fileDefinitions.BeginElement("DirectoryRef"); - fileDefinitions.AddAttribute("Id", "DesktopFolder"); - fileDefinitions.BeginElement("Component"); - fileDefinitions.AddAttribute("Id", componentId); - fileDefinitions.AddAttribute("Guid", "*"); - - for(shortcut_map_t::const_iterator - i = shortcutMap.begin(); i != shortcutMap.end(); ++i) - { - std::string const& id = i->first; - cmWIXShortcut const& shortcut = i->second; - - if (!shortcut.desktop) - continue; - - fileDefinitions.EmitShortcut(id, shortcut, true); - } - - fileDefinitions.EmitDesktopShortcutRegistryValue( - registryKey, cpackComponentName); - - fileDefinitions.EndElement("Component"); - fileDefinitions.EndElement("DirectoryRef"); - - featureDefinitions.EmitComponentRef(componentId); - } - featureDefinitions.EndElement("FeatureRef"); return true; @@ -840,9 +894,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXDirectoriesSourceWriter& directoryDefinitions, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions, - const std::vector<std::string>& packageExecutables, - const std::vector<std::string>& desktopExecutables, - shortcut_map_t& shortcutMap) + std::vector<std::string> const& packageExecutables, + std::vector<std::string> const& desktopExecutables, + cmWIXShortcuts& shortcuts) { cmsys::Directory dir; dir.Load(topdir.c_str()); @@ -917,7 +971,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( featureDefinitions, packageExecutables, desktopExecutables, - shortcutMap); + shortcuts); this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions); directoryDefinitions.EndElement("Directory"); @@ -927,6 +981,11 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmInstalledFile const* installedFile = this->GetInstalledFile(relativePath); + if(installedFile) + { + shortcuts.CreateFromProperties(id, directoryId, *installedFile); + } + std::string componentId = fileDefinitions.EmitComponentFile( directoryId, id, fullPath, *(this->Patch), installedFile); @@ -940,9 +999,10 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( if(cmSystemTools::LowerCase(fileName) == cmSystemTools::LowerCase(executableName) + ".exe") { - cmWIXShortcut &shortcut = shortcutMap[id]; - shortcut.textLabel= textLabel; + cmWIXShortcut shortcut; + shortcut.label= textLabel; shortcut.workingDirectoryId = directoryId; + shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut); if(desktopExecutables.size() && std::find(desktopExecutables.begin(), @@ -950,7 +1010,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( executableName) != desktopExecutables.end()) { - shortcut.desktop = true; + shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut); } } } diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index 8705d40..d501609 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2000-2012 Kitware, Inc. + Copyright 2012-2015 Kitware, Inc. Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -65,7 +65,6 @@ protected: private: typedef std::map<std::string, std::string> id_map_t; typedef std::map<std::string, size_t> ambiguity_map_t; - typedef std::map<std::string, cmWIXShortcut> shortcut_map_t; typedef std::set<std::string> extension_set_t; bool InitializeWiXConfiguration(); @@ -76,6 +75,8 @@ private: void CreateWiXPropertiesIncludeFile(); + void CreateWiXProductFragmentIncludeFile(); + void CopyDefinition( cmWIXSourceWriter &source, std::string const& name); @@ -97,12 +98,23 @@ private: cmWIXDirectoriesSourceWriter& directoryDefinitions, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions, - shortcut_map_t& shortcutMap); + cmWIXShortcuts& shortcuts); - bool CreateStartMenuShortcuts( + bool CreateShortcuts( std::string const& cpackComponentName, std::string const& featureId, - shortcut_map_t& shortcutMap, + cmWIXShortcuts const& shortcuts, + bool emitUninstallShortcut, + cmWIXFilesSourceWriter& fileDefinitions, + cmWIXFeaturesSourceWriter& featureDefinitions); + + bool CreateShortcutsOfSpecificType( + cmWIXShortcuts::Type type, + std::string const& cpackComponentName, + std::string const& featureId, + std::string const& idPrefix, + cmWIXShortcuts const& shortcuts, + bool emitUninstallShortcut, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions); @@ -124,9 +136,9 @@ private: cmWIXDirectoriesSourceWriter& directoryDefinitions, cmWIXFilesSourceWriter& fileDefinitions, cmWIXFeaturesSourceWriter& featureDefinitions, - const std::vector<std::string>& pkgExecutables, - const std::vector<std::string>& desktopExecutables, - shortcut_map_t& shortcutMap); + std::vector<std::string> const& packageExecutables, + std::vector<std::string> const& desktopExecutables, + cmWIXShortcuts& shortcuts); bool RequireOption(std::string const& name, std::string& value) const; @@ -163,8 +175,6 @@ private: extension_set_t CandleExtensions; extension_set_t LightExtensions; - bool HasDesktopShortcuts; - std::string CPackTopLevel; cmWIXPatch* Patch; diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx index a93f89b..7bd4315 100644 --- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx @@ -41,6 +41,14 @@ void cmWIXDirectoriesSourceWriter::EmitDesktopFolder() EndElement("Directory"); } +void cmWIXDirectoriesSourceWriter::EmitStartupFolder() +{ + BeginElement("Directory"); + AddAttribute("Id", "StartupFolder"); + AddAttribute("Name", "Startup"); + EndElement("Directory"); +} + size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory( std::string const& programFilesFolderId, std::string const& installRootString) diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h index f51fdb4..f8c8166 100644 --- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h +++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h @@ -32,6 +32,8 @@ public: void EmitDesktopFolder(); + void EmitStartupFolder(); + size_t BeginInstallationPrefixDirectory( std::string const& programFilesFolderId, std::string const& installRootString); diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx index 1adb06a..d4698a7 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2014 Kitware, Inc. + Copyright 2014-2015 Kitware, Inc. Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -28,26 +28,22 @@ cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger, void cmWIXFilesSourceWriter::EmitShortcut( std::string const& id, cmWIXShortcut const& shortcut, - bool desktop) + std::string const& shortcutPrefix, + size_t shortcutIndex) { - std::string shortcutId; + std::stringstream shortcutId; + shortcutId << shortcutPrefix << id; - if(desktop) + if(shortcutIndex > 0) { - shortcutId = "CM_DS"; + shortcutId << "_" << shortcutIndex; } - else - { - shortcutId = "CM_S"; - } - - shortcutId += id; std::string fileId = std::string("CM_F") + id; BeginElement("Shortcut"); - AddAttribute("Id", shortcutId); - AddAttribute("Name", shortcut.textLabel); + AddAttribute("Id", shortcutId.str()); + AddAttribute("Name", shortcut.label); std::string target = "[#" + fileId + "]"; AddAttribute("Target", target); AddAttribute("WorkingDirectory", shortcut.workingDirectoryId); @@ -62,20 +58,6 @@ void cmWIXFilesSourceWriter::EmitRemoveFolder(std::string const& id) EndElement("RemoveFolder"); } -void cmWIXFilesSourceWriter::EmitStartMenuShortcutRegistryValue( - std::string const& registryKey, - std::string const& cpackComponentName) -{ - EmitInstallRegistryValue(registryKey, cpackComponentName, std::string()); -} - -void cmWIXFilesSourceWriter::EmitDesktopShortcutRegistryValue( - std::string const& registryKey, - std::string const& cpackComponentName) -{ - EmitInstallRegistryValue(registryKey, cpackComponentName, "_desktop"); -} - void cmWIXFilesSourceWriter::EmitInstallRegistryValue( std::string const& registryKey, std::string const& cpackComponentName, diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h index b0a4af8..c48bc15 100644 --- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h +++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2014 Kitware, Inc. + Copyright 2014-2015 Kitware, Inc. Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -31,17 +31,15 @@ public: void EmitShortcut( std::string const& id, cmWIXShortcut const& shortcut, - bool desktop); + std::string const& shortcutPrefix, + size_t shortcutIndex); void EmitRemoveFolder(std::string const& id); - void EmitStartMenuShortcutRegistryValue( - std::string const& registryKey, - std::string const& cpackComponentName); - - void EmitDesktopShortcutRegistryValue( + void EmitInstallRegistryValue( std::string const& registryKey, - std::string const& cpackComponentName); + std::string const& cpackComponentName, + std::string const& suffix); void EmitUninstallShortcut(std::string const& packageName); @@ -56,12 +54,6 @@ public: std::string const& filePath, cmWIXPatch &patch, cmInstalledFile const* installedFile); - -private: - void EmitInstallRegistryValue( - std::string const& registryKey, - std::string const& cpackComponentName, - std::string const& suffix); }; diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx index ef67b23..e066c28 100644 --- a/Source/CPack/WiX/cmWIXPatchParser.cxx +++ b/Source/CPack/WiX/cmWIXPatchParser.cxx @@ -132,8 +132,8 @@ void cmWIXPatchParser::ReportError(int line, int column, const char* msg) void cmWIXPatchParser::ReportValidationError(std::string const& message) { - ReportError(XML_GetCurrentLineNumber(Parser), - XML_GetCurrentColumnNumber(Parser), + ReportError(XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser)), + XML_GetCurrentColumnNumber(static_cast<XML_Parser>(this->Parser)), message.c_str()); } diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx new file mode 100644 index 0000000..d721872 --- /dev/null +++ b/Source/CPack/WiX/cmWIXShortcut.cxx @@ -0,0 +1,125 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 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 "cmWIXShortcut.h" + +#include "cmWIXFilesSourceWriter.h" + +void cmWIXShortcuts::insert( + Type type, std::string const& id, cmWIXShortcut const& shortcut) +{ + this->Shortcuts[type][id].push_back(shortcut); +} + +bool cmWIXShortcuts::empty(Type type) const +{ + return this->Shortcuts.find(type) == this->Shortcuts.end(); +} + +bool cmWIXShortcuts::EmitShortcuts( + Type type, + std::string const& registryKey, + std::string const& cpackComponentName, + cmWIXFilesSourceWriter& fileDefinitions) const +{ + shortcut_type_map_t::const_iterator i = this->Shortcuts.find(type); + + if(i == this->Shortcuts.end()) + { + return false; + } + + shortcut_id_map_t const& id_map = i->second; + + std::string shortcutPrefix; + std::string registrySuffix; + + switch(type) + { + case START_MENU: + shortcutPrefix = "CM_S"; + break; + case DESKTOP: + shortcutPrefix = "CM_DS"; + registrySuffix = "_desktop"; + break; + case STARTUP: + shortcutPrefix = "CM_SS"; + registrySuffix = "_startup"; + break; + default: + return false; + } + + for(shortcut_id_map_t::const_iterator j = id_map.begin(); + j != id_map.end(); ++j) + { + std::string const& id = j->first; + shortcut_list_t const& shortcutList = j->second; + + for(size_t shortcutListIndex = 0; + shortcutListIndex < shortcutList.size(); ++shortcutListIndex) + { + cmWIXShortcut const& shortcut = shortcutList[shortcutListIndex]; + fileDefinitions.EmitShortcut(id, shortcut, + shortcutPrefix, shortcutListIndex); + } + } + + fileDefinitions.EmitInstallRegistryValue( + registryKey, cpackComponentName, registrySuffix); + + return true; +} + +void cmWIXShortcuts::AddShortcutTypes(std::set<Type>& types) +{ + for(shortcut_type_map_t::const_iterator i = this->Shortcuts.begin(); + i != this->Shortcuts.end(); ++i) + { + types.insert(i->first); + } +} + +void cmWIXShortcuts::CreateFromProperties( + std::string const& id, + std::string const& directoryId, + cmInstalledFile const& installedFile) +{ + CreateFromProperty("CPACK_START_MENU_SHORTCUTS", + START_MENU, id, directoryId, installedFile); + + CreateFromProperty("CPACK_DESKTOP_SHORTCUTS", + DESKTOP, id, directoryId, installedFile); + + CreateFromProperty("CPACK_STARTUP_SHORTCUTS", + STARTUP, id, directoryId, installedFile); +} + +void cmWIXShortcuts::CreateFromProperty( + std::string const& propertyName, + Type type, + std::string const& id, + std::string const& directoryId, + cmInstalledFile const& installedFile) +{ + std::vector<std::string> list; + installedFile.GetPropertyAsList(propertyName, list); + + for(size_t i = 0; i < list.size(); ++i) + { + cmWIXShortcut shortcut; + shortcut.label = list[i]; + shortcut.workingDirectoryId = directoryId; + insert(type, id, shortcut); + } +} diff --git a/Source/CPack/WiX/cmWIXShortcut.h b/Source/CPack/WiX/cmWIXShortcut.h index 93095e0..5945e43 100644 --- a/Source/CPack/WiX/cmWIXShortcut.h +++ b/Source/CPack/WiX/cmWIXShortcut.h @@ -1,6 +1,6 @@ /*============================================================================ CMake - Cross Platform Makefile Generator - Copyright 2014 Kitware, Inc. + Copyright 2014-2015 Kitware, Inc. Distributed under the OSI-approved BSD License (the "License"); see accompanying file Copyright.txt for details. @@ -10,20 +10,64 @@ See the License for more information. ============================================================================*/ -#ifndef cmWIXFilesShortcut_h -#define cmWIXFilesShortcut_h +#ifndef cmWIXShortcut_h +#define cmWIXShortcut_h #include <string> +#include <map> +#include <set> +#include <vector> + +#include <cmInstalledFile.h> + +class cmWIXFilesSourceWriter; struct cmWIXShortcut { - cmWIXShortcut() - :desktop(false) - {} - - std::string textLabel; + std::string label; std::string workingDirectoryId; - bool desktop; +}; + +class cmWIXShortcuts +{ +public: + enum Type + { + START_MENU, + DESKTOP, + STARTUP + }; + + typedef std::vector<cmWIXShortcut> shortcut_list_t; + typedef std::map<std::string, shortcut_list_t> shortcut_id_map_t; + + void insert(Type type, std::string const& id, cmWIXShortcut const& shortcut); + + bool empty(Type type) const; + + bool EmitShortcuts( + Type type, + std::string const& registryKey, + std::string const& cpackComponentName, + cmWIXFilesSourceWriter& fileDefinitions) const; + + void AddShortcutTypes(std::set<Type>& types); + + void CreateFromProperties(std::string const& id, + std::string const& directoryId, cmInstalledFile const& installedFile); + +private: + typedef std::map<Type, shortcut_id_map_t> shortcut_type_map_t; + + void CreateFromProperty( + std::string const& propertyName, + Type type, + std::string const& id, + std::string const& directoryId, + cmInstalledFile const& installedFile); + + shortcut_type_map_t Shortcuts; + shortcut_id_map_t EmptyIdMap; }; #endif diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index aad19da..219fca8 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -10,6 +10,8 @@ See the License for more information. ============================================================================*/ +#include "cmStandardIncludes.h" + #include "cmWIXSourceWriter.h" #include <CPack/cmCPackGenerator.h> @@ -118,7 +120,7 @@ void cmWIXSourceWriter::AddProcessingInstruction( void cmWIXSourceWriter::AddAttribute( std::string const& key, std::string const& value) { - std::string utf8 = WindowsCodepageToUtf8(value); + std::string utf8 = CMakeEncodingToUtf8(value); File << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"'; } @@ -132,8 +134,11 @@ void cmWIXSourceWriter::AddAttributeUnlessEmpty( } } -std::string cmWIXSourceWriter::WindowsCodepageToUtf8(std::string const& value) +std::string cmWIXSourceWriter::CMakeEncodingToUtf8(std::string const& value) { +#ifdef CMAKE_ENCODING_UTF8 + return value; +#else if(value.empty()) { return std::string(); @@ -167,6 +172,7 @@ std::string cmWIXSourceWriter::WindowsCodepageToUtf8(std::string const& value) &utf8[0], static_cast<int>(utf8.size()), 0, 0); return std::string(&utf8[0], utf8.size()); +#endif } diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 3957d96..3b9999c 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -43,7 +43,7 @@ public: void AddAttributeUnlessEmpty( std::string const& key, std::string const& value); - static std::string WindowsCodepageToUtf8(std::string const& value); + static std::string CMakeEncodingToUtf8(std::string const& value); protected: cmCPackLog* Logger; diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index e2437b5..05b5cd9 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -63,6 +63,14 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive, filePrefix = this->GetOption("CPACK_PACKAGE_FILE_NAME"); filePrefix += "/"; } + const char* installPrefix = + this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"); + if(installPrefix && installPrefix[0] == '/' && installPrefix[1] != 0) + { + // add to file prefix and remove the leading '/' + filePrefix += installPrefix+1; + filePrefix += "/"; + } std::vector<std::string>::const_iterator fileIt; for (fileIt = component->Files.begin(); fileIt != component->Files.end(); ++fileIt ) diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx index e751568..b2d7019 100644 --- a/Source/CPack/cmCPackBundleGenerator.cxx +++ b/Source/CPack/cmCPackBundleGenerator.cxx @@ -214,12 +214,18 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) // codesign the application. if(!cpack_apple_cert_app.empty()) { + std::string output; 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_parameter = + this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER") + ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER") + : "--deep -f"; + const std::string sign_files = this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") ? this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES") : ""; @@ -233,18 +239,19 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) { 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 << " " << sign_parameter << " -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)) + if(!this->RunCommand(temp_sign_file_cmd, &output)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error signing file:" - << bundle_path << it->c_str() << std::endl); + << bundle_path << it->c_str() << std::endl << output << std::endl); return 0; } @@ -253,14 +260,15 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) // 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 << " " << sign_parameter << " -s \"" + << cpack_apple_cert_app; temp_sign_binary_cmd << "\" \"" << bundle_path << "\""; - if(!this->RunCommand(temp_sign_binary_cmd)) + if(!this->RunCommand(temp_sign_binary_cmd, &output)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error signing the application binary." - << std::endl); + << std::endl << output << std::endl); return 0; } @@ -268,7 +276,8 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) // 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 << "\""; + temp_codesign_cmd << " " << sign_parameter << " -s \"" + << cpack_apple_cert_app << "\""; if(this->GetOption("CPACK_BUNDLE_APPLE_ENTITLEMENTS")) { temp_codesign_cmd << " --entitlements "; @@ -276,11 +285,11 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir) } temp_codesign_cmd << " \"" << bundle_path << "\""; - if(!this->RunCommand(temp_codesign_cmd)) + if(!this->RunCommand(temp_codesign_cmd, &output)) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error signing the application package." - << std::endl); + << std::endl << output << std::endl); return 0; } diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 0a64bd5..fcf4122 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -507,6 +507,11 @@ int cmCPackDebGenerator::createDeb() //int retVal = -1; res = cmSystemTools::RunSingleCommand(cmd.c_str(), &output, &retval, toplevel.c_str(), this->GeneratorVerbose, 0); + if ( !res || retval ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running cmake -E md5sum " + << cmd << std::endl); + } // debian md5sums entries are like this: // 014f3604694729f3bf19263bac599765 usr/bin/ccmake // thus strip the full path (with the trailing slash) @@ -800,12 +805,14 @@ static int put_arobj(CF *cfp, struct stat *sb) if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime, (unsigned)uid, (unsigned)gid, - sb->st_mode, (long long)sb->st_size + lname, ARFMAG); + (unsigned)sb->st_mode, (long long)sb->st_size + lname, + ARFMAG); else { lname = 0; (void)sprintf(ar_hb, HDR2, name, (long int)sb->st_mtime, (unsigned)uid, (unsigned)gid, - sb->st_mode, (long long)sb->st_size, ARFMAG); + (unsigned)sb->st_mode, (long long)sb->st_size, + ARFMAG); } off_t size = sb->st_size; diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 1c670d2..67005ef 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -25,6 +25,7 @@ #include <cmsys/Glob.hxx> #include <cmsys/FStream.hxx> #include <algorithm> +#include <list> #if defined(__HAIKU__) #include <FindDirectory.h> @@ -654,26 +655,19 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths()); // Does this generator require pre-install? - if ( globalGenerator->GetPreinstallTargetName() ) + if (const char* preinstall = globalGenerator->GetPreinstallTargetName()) { - globalGenerator->FindMakeProgram(this->MakefileMap); - std::string cmakeMakeProgram - = this->MakefileMap->GetSafeDefinition("CMAKE_MAKE_PROGRAM"); - std::vector<std::string> buildCommand; - globalGenerator->GenerateBuildCommand(buildCommand, cmakeMakeProgram, - installProjectName, installDirectory, - globalGenerator->GetPreinstallTargetName(), - buildConfig, false); - std::string buildCommandStr = - cmSystemTools::PrintSingleCommand(buildCommand); + std::string buildCommand = + globalGenerator->GenerateCMakeBuildCommand( + preinstall, buildConfig, "", false); cmCPackLogger(cmCPackLog::LOG_DEBUG, - "- Install command: " << buildCommandStr << std::endl); + "- Install command: " << buildCommand << std::endl); cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Run preinstall target for: " << installProjectName << std::endl); std::string output; int retVal = 1; bool resB = - cmSystemTools::RunSingleCommand(buildCommand, + cmSystemTools::RunSingleCommand(buildCommand.c_str(), &output, &retVal, installDirectory.c_str(), @@ -683,12 +677,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); tmpFile += "/PreinstallOutput.log"; cmGeneratedFileStream ofs(tmpFile.c_str()); - ofs << "# Run command: " << buildCommandStr << std::endl + ofs << "# Run command: " << buildCommand << std::endl << "# Directory: " << installDirectory << std::endl << "# Output:" << std::endl << output << std::endl; cmCPackLogger(cmCPackLog::LOG_ERROR, - "Problem running install command: " << buildCommandStr + "Problem running install command: " << buildCommand << std::endl << "Please check " << tmpFile << " for errors" << std::endl); diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index a07c29a..4626142 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -46,6 +46,7 @@ #endif #include "cmCPackLog.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------- diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 8f63ca2..fe6cc95 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -654,7 +654,7 @@ bool cmCPackNSISGenerator::GetListOfSubdirectories(const char* topdir, if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") && strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),"..")) { - cmsys_stl::string fullPath = topdir; + std::string fullPath = topdir; fullPath += "/"; fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); if(cmsys::SystemTools::FileIsDirectory(fullPath) && diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index d90aeb7..0827037 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -32,8 +32,7 @@ cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() //---------------------------------------------------------------------- void cmCTestBuildAndTestHandler::Initialize() { - this->BuildTargets.erase( - this->BuildTargets.begin(), this->BuildTargets.end()); + this->BuildTargets.clear(); this->Superclass::Initialize(); } @@ -311,7 +310,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) output, this->BuildMakeProgram, config, !this->BuildNoClean, - false, remainingTime); + false, false, remainingTime); out << output; // if the build failed then return if (retVal) diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index c4df741..2b36b0a 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -58,7 +58,8 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() = this->Makefile->GetDefinition("CTEST_BUILD_COMMAND"); if ( ctestBuildCommand && *ctestBuildCommand ) { - this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand); + this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand, + this->Quiet); } else { @@ -141,10 +142,10 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() GenerateCMakeBuildCommand(cmakeBuildTarget ? cmakeBuildTarget : "", cmakeBuildConfiguration, cmakeBuildAdditionalFlags ? cmakeBuildAdditionalFlags : "", true); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "SetMakeCommand:" - << buildCommand << "\n"); - this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str()); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "SetMakeCommand:" << buildCommand << "\n", this->Quiet); + this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(), + this->Quiet); } else { @@ -168,9 +169,11 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() if(const char* useLaunchers = this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) { - this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers); + this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers, + this->Quiet); } + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index f941408..29e07ef 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -20,6 +20,7 @@ #include "cmGeneratedFileStream.h" #include "cmXMLSafe.h" #include "cmFileTimeComparison.h" +#include "cmAlgorithms.h" //#include <cmsys/RegularExpression.hxx> #include <cmsys/Process.h> @@ -286,9 +287,9 @@ std::string cmCTestBuildHandler::GetMakeCommand() { std::string makeCommand = this->CTest->GetCTestConfiguration("MakeCommand"); - cmCTestLog(this->CTest, - HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand << - "\n"); + cmCTestOptionalLog(this->CTest, + HANDLER_VERBOSE_OUTPUT, "MakeCommand:" << makeCommand << "\n", + this->Quiet); std::string configType = this->CTest->GetConfigType(); if (configType == "") @@ -312,7 +313,8 @@ std::string cmCTestBuildHandler::GetMakeCommand() //functions and commented... int cmCTestBuildHandler::ProcessHandler() { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Build project" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Build project" << std::endl, + this->Quiet); // do we have time for this if (this->CTest->GetRemainingTimeAllowed() < 120) @@ -401,12 +403,12 @@ int cmCTestBuildHandler::ProcessHandler() #define cmCTestBuildHandlerPopulateRegexVector(strings, regexes) \ regexes.clear(); \ - cmCTestLog(this->CTest, DEBUG, this << "Add " #regexes \ - << std::endl); \ + cmCTestOptionalLog(this->CTest, DEBUG, this << "Add " #regexes \ + << std::endl, this->Quiet); \ for ( it = strings.begin(); it != strings.end(); ++it ) \ { \ - cmCTestLog(this->CTest, DEBUG, "Add " #strings ": " \ - << *it << std::endl); \ + cmCTestOptionalLog(this->CTest, DEBUG, "Add " #strings ": " \ + << *it << std::endl, this->Quiet); \ regexes.push_back(it->c_str()); \ } cmCTestBuildHandlerPopulateRegexVector( @@ -472,8 +474,8 @@ int cmCTestBuildHandler::ProcessHandler() } else { - cmCTestLog(this->CTest, DEBUG, "Build with command: " << makeCommand - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Build with command: " << + makeCommand << std::endl, this->Quiet); } // Remember end build time and calculate elapsed time @@ -906,13 +908,16 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, } argv.push_back(0); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command:"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command:", + this->Quiet); std::vector<const char*>::iterator ait; for ( ait = argv.begin(); ait != argv.end() && *ait; ++ ait ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " \"" << *ait << "\""); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " \"" << *ait << + "\"", this->Quiet); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl, + this->Quiet); // Optionally use make rule launchers to record errors and warnings. LaunchHelper launchHelper(this); @@ -932,12 +937,12 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, char* data; int length; - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Each symbol represents " << tick_len << " bytes of output." << std::endl << (this->UseCTestLaunch? "" : " '!' represents an error and '*' a warning.\n") - << " " << std::flush); + << " " << std::flush, this->Quiet); // Initialize building structures this->BuildProcessingQueue.clear(); @@ -980,8 +985,9 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingQueue); this->ProcessBuffer(0, 0, tick, tick_len, ofs, &this->BuildProcessingErrorQueue); - cmCTestLog(this->CTest, OUTPUT, " Size of output: " - << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl); + cmCTestOptionalLog(this->CTest, OUTPUT, " Size of output: " + << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl, + this->Quiet); // Properly handle output of the build command cmsysProcess_WaitForExit(cp, 0); @@ -992,8 +998,8 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, if (retVal) { *retVal = cmsysProcess_GetExitValue(cp); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Command exited with the value: " << *retVal << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Command exited with the value: " << *retVal << std::endl, this->Quiet); // if a non zero return value if (*retVal) { @@ -1017,13 +1023,14 @@ int cmCTestBuildHandler::RunMakeCommand(const char* command, if (retVal) { *retVal = cmsysProcess_GetExitException(cp); - cmCTestLog(this->CTest, WARNING, "There was an exception: " << *retVal - << std::endl); + cmCTestOptionalLog(this->CTest, WARNING, "There was an exception: " << + *retVal << std::endl, this->Quiet); } } else if(result == cmsysProcess_State_Expired) { - cmCTestLog(this->CTest, WARNING, "There was a timeout" << std::endl); + cmCTestOptionalLog(this->CTest, WARNING, "There was a timeout" << + std::endl, this->Quiet); } else if(result == cmsysProcess_State_Error) { @@ -1185,13 +1192,14 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, while ( this->BuildOutputLogSize > (tick * tick_len) ) { tick ++; - cmCTestLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->LastTickChar, + this->Quiet); tickDisplayed = true; if ( tick % tick_line_len == 0 && tick > 0 ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Size: " + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Size: " << ((this->BuildOutputLogSize + 512) / 1024) << "K" << std::endl - << " "); + << " ", this->Quiet); } } if ( tickDisplayed ) @@ -1216,7 +1224,8 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) return b_REGULAR_LINE; } - cmCTestLog(this->CTest, DEBUG, "Line: [" << data << "]" << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << data << "]" << + std::endl, this->Quiet); std::vector<cmsys::RegularExpression>::iterator it; @@ -1236,9 +1245,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) if ( it->find(data) ) { errorLine = 1; - cmCTestLog(this->CTest, DEBUG, " Error Line: " << data + cmCTestOptionalLog(this->CTest, DEBUG, " Error Line: " << data << " (matches: " << this->CustomErrorMatches[wrxCnt] << ")" - << std::endl); + << std::endl, this->Quiet); break; } wrxCnt ++; @@ -1252,9 +1261,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) if ( it->find(data) ) { errorLine = 0; - cmCTestLog(this->CTest, DEBUG, " Not an error Line: " << data + cmCTestOptionalLog(this->CTest, DEBUG, " Not an error Line: " << data << " (matches: " << this->CustomErrorExceptions[wrxCnt] << ")" - << std::endl); + << std::endl, this->Quiet); break; } wrxCnt ++; @@ -1271,10 +1280,10 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) if ( it->find(data) ) { warningLine = 1; - cmCTestLog(this->CTest, DEBUG, + cmCTestOptionalLog(this->CTest, DEBUG, " Warning Line: " << data << " (matches: " << this->CustomWarningMatches[wrxCnt] << ")" - << std::endl); + << std::endl, this->Quiet); break; } wrxCnt ++; @@ -1289,9 +1298,9 @@ int cmCTestBuildHandler::ProcessSingleLine(const char* data) if ( it->find(data) ) { warningLine = 0; - cmCTestLog(this->CTest, DEBUG, " Not a warning Line: " << data + cmCTestOptionalLog(this->CTest, DEBUG, " Not a warning Line: " << data << " (matches: " << this->CustomWarningExceptions[wrxCnt] << ")" - << std::endl); + << std::endl, this->Quiet); break; } wrxCnt ++; diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index 09346f9..d13d5cf 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -19,6 +19,8 @@ #include <cmsys/RegularExpression.hxx> +#include <deque> + class cmMakefile; /** \class cmCTestBuildHandler diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 0f13263..ba4dab2 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -45,7 +45,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() if ( ctestConfigureCommand && *ctestConfigureCommand ) { this->CTest->SetCTestConfiguration("ConfigureCommand", - ctestConfigureCommand); + ctestConfigureCommand, this->Quiet); } else { @@ -141,7 +141,7 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() cmakeConfigureCommand += "\""; this->CTest->SetCTestConfiguration("ConfigureCommand", - cmakeConfigureCommand.c_str()); + cmakeConfigureCommand.c_str(), this->Quiet); } else { @@ -160,5 +160,6 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() "internal CTest error. Cannot instantiate configure handler"); return 0; } + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestConfigureHandler.cxx b/Source/CTest/cmCTestConfigureHandler.cxx index 506433f..3b444f2 100644 --- a/Source/CTest/cmCTestConfigureHandler.cxx +++ b/Source/CTest/cmCTestConfigureHandler.cxx @@ -35,7 +35,8 @@ void cmCTestConfigureHandler::Initialize() //functions and commented... int cmCTestConfigureHandler::ProcessHandler() { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Configure project" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "Configure project" << std::endl, this->Quiet); std::string cCommand = this->CTest->GetCTestConfiguration("ConfigureCommand"); if (cCommand.empty()) @@ -75,8 +76,8 @@ int cmCTestConfigureHandler::ProcessHandler() cmGeneratedFileStream ofs; this->StartLogFile("Configure", ofs); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Configure with command: " - << cCommand << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Configure with command: " << cCommand << std::endl, this->Quiet); res = this->CTest->RunMakeCommand(cCommand.c_str(), output, &retVal, buildDirectory.c_str(), 0, ofs); @@ -101,7 +102,7 @@ int cmCTestConfigureHandler::ProcessHandler() } os << "<ConfigureCommand>" << cCommand << "</ConfigureCommand>" << std::endl; - cmCTestLog(this->CTest, DEBUG, "End" << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); os << "<Log>" << cmXMLSafe(output) << "</Log>" << std::endl; std::string end_time = this->CTest->CurrentTime(); os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n" @@ -119,8 +120,8 @@ int cmCTestConfigureHandler::ProcessHandler() } else { - cmCTestLog(this->CTest, DEBUG, "Configure with command: " << cCommand - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, + "Configure with command: " << cCommand << std::endl, this->Quiet); } if (! res || retVal ) { diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx index 41f016b..f1f935b 100644 --- a/Source/CTest/cmCTestCoverageCommand.cxx +++ b/Source/CTest/cmCTestCoverageCommand.cxx @@ -24,9 +24,9 @@ cmCTestCoverageCommand::cmCTestCoverageCommand() cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler() { this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "CoverageCommand", "CTEST_COVERAGE_COMMAND"); + "CoverageCommand", "CTEST_COVERAGE_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS"); + "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS", this->Quiet); cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>( this->CTest->GetInitializedHandler("coverage")); if ( !handler ) @@ -41,6 +41,7 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler() handler->SetLabelFilter(this->Labels); } + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 08b7c66..790e488 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -176,8 +176,8 @@ bool cmCTestCoverageHandler::StartCoverageLogFile( { char covLogFilename[1024]; sprintf(covLogFilename, "CoverageLog-%d", logFileCount); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Open file: " - << covLogFilename << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Open file: " + << covLogFilename << std::endl, this->Quiet); if(!this->StartResultingXML(cmCTest::PartCoverage, covLogFilename, covLogFile)) { @@ -209,8 +209,8 @@ void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr, this->CTest->EndXML(ostr); char covLogFilename[1024]; sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: " - << covLogFilename << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Close file: " + << covLogFilename << std::endl, this->Quiet); ostr.Close(); } @@ -230,8 +230,8 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, { if ( sit->find(file) ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " File " << file - << " is excluded in CTestCustom.ctest" << std::endl;); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " File " << file + << " is excluded in CTestCustom.ctest" << std::endl;, this->Quiet); return false; } } @@ -272,8 +272,8 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, fFile.c_str(), checkDir.c_str()); if (!ndc.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc - << " so skip coverage of " << file << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc + << " so skip coverage of " << file << std::endl, this->Quiet); return false; } @@ -311,8 +311,8 @@ bool cmCTestCoverageHandler::ShouldIDoCoverage(const char* file, fFile.c_str(), checkDir.c_str()); if (!ndc.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc - << " so skip coverage of: " << file << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found: " << ndc + << " so skip coverage of: " << file << std::endl, this->Quiet); return false; } // Ok, nothing in source tree, nothing in binary tree @@ -356,13 +356,15 @@ int cmCTestCoverageHandler::ProcessHandler() cmSystemTools::ConvertToUnixSlashes(sourceDir); cmSystemTools::ConvertToUnixSlashes(binaryDir); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Performing coverage" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "Performing coverage" << std::endl, this->Quiet); cmCTestCoverageHandlerContainer cont; cont.Error = error; cont.SourceDir = sourceDir; cont.BinaryDir = binaryDir; cont.OFS = &ofs; + cont.Quiet = this->Quiet; // setup the regex exclude stuff this->CustomCoverageExcludeRegex.clear(); @@ -442,9 +444,9 @@ int cmCTestCoverageHandler::ProcessHandler() if ( file_count == 0 ) { - cmCTestLog(this->CTest, WARNING, + cmCTestOptionalLog(this->CTest, WARNING, " Cannot find any coverage files. Ignoring Coverage request." - << std::endl); + << std::endl, this->Quiet); return error; } cmGeneratedFileStream covSumFile; @@ -476,10 +478,11 @@ int cmCTestCoverageHandler::ProcessHandler() long total_untested = 0; //std::string fullSourceDir = sourceDir + "/"; //std::string fullBinaryDir = binaryDir + "/"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Accumulating results (each . represents one file):" << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Accumulating results (each . represents one file):" << std::endl, + this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); std::vector<std::string> errorsWhileAccumulating; @@ -488,14 +491,16 @@ int cmCTestCoverageHandler::ProcessHandler() fileIterator != cont.TotalCoverage.end(); ++fileIterator ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush, + this->Quiet); file_count ++; if ( file_count % 50 == 0 ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " processed: " + << file_count << " out of " - << cont.TotalCoverage.size() << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + << cont.TotalCoverage.size() << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); } const std::string fullFileName = fileIterator->first; @@ -504,15 +509,15 @@ int cmCTestCoverageHandler::ProcessHandler() sourceDir.c_str(), binaryDir.c_str()); if ( !shouldIDoCoverage ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, ".NoDartCoverage found, so skip coverage check for: " << fullFileName - << std::endl); + << std::endl, this->Quiet); continue; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Process file: " << fullFileName << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Process file: " << fullFileName << std::endl, this->Quiet); if ( !cmSystemTools::FileExists(fullFileName.c_str()) ) { @@ -556,8 +561,9 @@ int cmCTestCoverageHandler::ProcessHandler() cmCTestCoverageHandlerContainer::SingleFileCoverageVector::size_type cc; std::string line; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Actually performing coverage for: " << fullFileName << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Actually performing coverage for: " << fullFileName << std::endl, + this->Quiet); for ( cc= 0; cc < fcov.size(); cc ++ ) { if ( !cmSystemTools::GetLineFromStream(ifs, line) && @@ -641,8 +647,8 @@ int cmCTestCoverageHandler::ProcessHandler() } int untested = 0; std::string line; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Actually performing coverage for: " << *i << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Actually performing coverage for: " << *i << std::endl, this->Quiet); while (cmSystemTools::GetLineFromStream(ifs, line)) { covLogFile << "\t\t<Line Number=\"" << untested << "\" Count=\"0\">" @@ -736,8 +742,8 @@ int cmCTestCoverageHandler::ProcessHandler() //---------------------------------------------------------------------- void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Add coverage exclude regular expressions." << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Add coverage exclude regular expressions." << std::endl, this->Quiet); this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_COVERAGE_EXCLUDE", this->CustomCoverageExclude); this->CTest->PopulateCustomVector(mf, "CTEST_EXTRA_COVERAGE_GLOB", @@ -747,14 +753,14 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile *mf) it != this->CustomCoverageExclude.end(); ++ it ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage exclude: " - << *it << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Add coverage exclude: " << *it << std::endl, this->Quiet); } for ( it = this->ExtraCoverageGlobs.begin(); it != this->ExtraCoverageGlobs.end(); ++it) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Add coverage glob: " - << *it << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Add coverage glob: " << *it << std::endl, this->Quiet); } } @@ -812,16 +818,16 @@ int cmCTestCoverageHandler::HandleCoberturaCoverage( if(cmSystemTools::FileExists(coverageXMLFile.c_str())) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Parsing Cobertura XML file: " << coverageXMLFile - << std::endl); + << std::endl, this->Quiet); cov.ReadCoverageXML(coverageXMLFile.c_str()); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Cannot find Cobertura XML file: " << coverageXMLFile - << std::endl); + << std::endl, this->Quiet); } return static_cast<int>(cont->TotalCoverage.size()); } @@ -836,33 +842,33 @@ int cmCTestCoverageHandler::HandleMumpsCoverage( "/gtm_coverage.mcov"; if(cmSystemTools::FileExists(coverageFile.c_str())) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Parsing Cache Coverage: " << coverageFile - << std::endl); + << std::endl, this->Quiet); cov.ReadCoverageFile(coverageFile.c_str()); return static_cast<int>(cont->TotalCoverage.size()); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Cannot find foobar GTM coverage file: " << coverageFile - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Cannot find GTM coverage file: " << coverageFile + << std::endl, this->Quiet); } cmParseCacheCoverage ccov(*cont, this->CTest); coverageFile = this->CTest->GetBinaryDir() + "/cache_coverage.cmcov"; if(cmSystemTools::FileExists(coverageFile.c_str())) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Parsing Cache Coverage: " << coverageFile - << std::endl); + << std::endl, this->Quiet); ccov.ReadCoverageFile(coverageFile.c_str()); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find Cache coverage file: " << coverageFile - << std::endl); + << std::endl, this->Quiet); } return static_cast<int>(cont->TotalCoverage.size()); } @@ -912,15 +918,15 @@ int cmCTestCoverageHandler::HandleJacocoCoverage( files=g.GetFiles(); if (!files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Found Jacoco Files, Performing Coverage" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found Jacoco Files, Performing Coverage" << std::endl, this->Quiet); cov.LoadCoverageData(files); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find Jacoco coverage files: " << coverageFile - << std::endl); + << std::endl, this->Quiet); } return static_cast<int>(cont->TotalCoverage.size()); } @@ -945,15 +951,16 @@ int cmCTestCoverageHandler::HandleDelphiCoverage( files=g.GetFiles(); if (!files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Found Delphi HTML Files, Performing Coverage" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found Delphi HTML Files, Performing Coverage" << std::endl, + this->Quiet); cov.LoadCoverageData(files); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find Delphi coverage files: " << coverageFile - << std::endl); + << std::endl, this->Quiet); } return static_cast<int>(cont->TotalCoverage.size()); } @@ -975,15 +982,16 @@ int cmCTestCoverageHandler::HandleBlanketJSCoverage( files=g.GetFiles(); if (!files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Found BlanketJS output JSON, Performing Coverage" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found BlanketJS output JSON, Performing Coverage" << std::endl, + this->Quiet); cov.LoadCoverageData(files); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find BlanketJS coverage files: " << coverageFile - << std::endl); + << std::endl, this->Quiet); } return static_cast<int>(cont->TotalCoverage.size()); } @@ -1039,9 +1047,9 @@ int cmCTestCoverageHandler::HandleGCovCoverage( if (files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any GCov coverage files." - << std::endl); + << std::endl, this->Quiet); // No coverage files is a valid thing, so the exit code is 0 return 0; } @@ -1057,9 +1065,10 @@ int cmCTestCoverageHandler::HandleGCovCoverage( std::set<std::string> missingFiles; std::string actualSourceFile = ""; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Processing coverage (each . represents one file):" << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Processing coverage (each . represents one file):" << std::endl, + this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); int file_count = 0; // make sure output from gcov is in English! @@ -1072,7 +1081,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( // for ( it = files.begin(); it != files.end(); ++ it ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush, + this->Quiet); // Call gcov to get coverage data for this *.gcda file: // @@ -1082,8 +1092,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( "-o \"" + fileDir + "\" " + "\"" + *it + "\""; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() + << std::endl, this->Quiet); std::string output = ""; std::string errors = ""; @@ -1111,12 +1121,12 @@ int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestLog(this->CTest, ERROR_MESSAGE, "Command produced error: " << cont->Error << std::endl); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "--------------------------------------------------------------" << std::endl << output << std::endl << "--------------------------------------------------------------" - << std::endl); + << std::endl, this->Quiet); std::vector<std::string> lines; std::vector<std::string>::iterator line; @@ -1128,8 +1138,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( std::string sourceFile; std::string gcovFile; - cmCTestLog(this->CTest, DEBUG, "Line: [" << *line << "]" - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Line: [" << *line << "]" + << std::endl, this->Quiet); if (line->empty()) { @@ -1229,8 +1239,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( break; } - cmCTestLog(this->CTest, WARNING, "Warning: " << st2re4.match(1) - << " had unexpected EOF" << std::endl); + cmCTestOptionalLog(this->CTest, WARNING, "Warning: " << st2re4.match(1) + << " had unexpected EOF" << std::endl, this->Quiet); } else if ( st2re5.find(line->c_str() ) ) { @@ -1246,8 +1256,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( break; } - cmCTestLog(this->CTest, WARNING, "Warning: Cannot open file: " - << st2re5.match(1) << std::endl); + cmCTestOptionalLog(this->CTest, WARNING, "Warning: Cannot open file: " + << st2re5.match(1) << std::endl, this->Quiet); } else if ( st2re6.find(line->c_str() ) ) { @@ -1263,8 +1273,9 @@ int cmCTestCoverageHandler::HandleGCovCoverage( break; } - cmCTestLog(this->CTest, WARNING, "Warning: File: " << st2re6.match(1) - << " is newer than " << st2re6.match(2) << std::endl); + cmCTestOptionalLog(this->CTest, WARNING, "Warning: File: " + << st2re6.match(1) + << " is newer than " << st2re6.match(2) << std::endl, this->Quiet); } else { @@ -1291,8 +1302,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec = cont->TotalCoverage[actualSourceFile]; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in gcovFile: " - << gcovFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " in gcovFile: " << gcovFile << std::endl, this->Quiet); cmsys::ifstream ifile(gcovFile.c_str()); if ( ! ifile ) @@ -1366,8 +1377,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( // if ( IsFileInDir(sourceFile, cont->SourceDir) ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced s: " - << sourceFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " produced s: " << sourceFile << std::endl, this->Quiet); *cont->OFS << " produced in source dir: " << sourceFile << std::endl; actualSourceFile @@ -1375,8 +1386,8 @@ int cmCTestCoverageHandler::HandleGCovCoverage( } else if ( IsFileInDir(sourceFile, cont->BinaryDir) ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " produced b: " - << sourceFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " produced b: " << sourceFile << std::endl, this->Quiet); *cont->OFS << " produced in binary dir: " << sourceFile << std::endl; actualSourceFile @@ -1387,19 +1398,19 @@ int cmCTestCoverageHandler::HandleGCovCoverage( { if ( missingFiles.find(sourceFile) == missingFiles.end() ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Something went wrong" << std::endl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Something went wrong" << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Cannot find file: [" - << sourceFile << "]" << std::endl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + << sourceFile << "]" << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in source dir: [" << cont->SourceDir << "]" - << std::endl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " or binary dir: [" << cont->BinaryDir.size() << "]" - << std::endl); + << std::endl, this->Quiet); *cont->OFS << " Something went wrong. Cannot find file: " << sourceFile << " in source dir: " << cont->SourceDir @@ -1415,9 +1426,10 @@ int cmCTestCoverageHandler::HandleGCovCoverage( if ( file_count % 50 == 0 ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count - << " out of " << files.size() << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " processed: " + << file_count + << " out of " << files.size() << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); } } @@ -1435,22 +1447,22 @@ int cmCTestCoverageHandler::HandleLCovCoverage( = this->CTest->GetCTestConfiguration("CoverageExtraFlags"); if ( lcovCommand != "codecov" ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Not a valid Intel Coverage command." - << std::endl); + << std::endl, this->Quiet); return 0; } // There is only percentage completed output from LCOV std::string st2lcovOutputRex3 = "[0-9]+%"; cmsys::RegularExpression st2re3(st2lcovOutputRex3.c_str()); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " This is coverage command: " << lcovCommand - << std::endl); + << std::endl, this->Quiet); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " These are coverage command flags: " << lcovExtraFlags - << std::endl); + << std::endl, this->Quiet); std::vector<std::string> files; this->FindLCovFiles(files); @@ -1458,9 +1470,9 @@ int cmCTestCoverageHandler::HandleLCovCoverage( if (files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any LCov coverage files." - << std::endl); + << std::endl, this->Quiet); // No coverage files is a valid thing, so the exit code is 0 return 0; } @@ -1471,9 +1483,10 @@ int cmCTestCoverageHandler::HandleLCovCoverage( std::set<std::string> missingFiles; std::string actualSourceFile = ""; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Processing coverage (each . represents one file):" << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Processing coverage (each . represents one file):" << std::endl, + this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); int file_count = 0; // make sure output from lcov is in English! @@ -1484,16 +1497,17 @@ int cmCTestCoverageHandler::HandleLCovCoverage( // directory. It collects all *.dyn files to generate .dpi file. for ( it = files.begin(); it != files.end(); ++ it ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "." << std::flush); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "." << std::flush, + this->Quiet); std::string fileDir = cmSystemTools::GetFilenamePath(*it); cmSystemTools::ChangeDirectory(fileDir); std::string command = "\"" + lcovCommand + "\" " + lcovExtraFlags + " "; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Current coverage dir: " - << fileDir << std::endl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Current coverage dir: " << fileDir << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, command.c_str() + << std::endl, this->Quiet); std::string output = ""; std::string errors = ""; @@ -1521,12 +1535,12 @@ int cmCTestCoverageHandler::HandleLCovCoverage( cmCTestLog(this->CTest, ERROR_MESSAGE, "Command produced error: " << cont->Error << std::endl); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "--------------------------------------------------------------" << std::endl << output << std::endl << "--------------------------------------------------------------" - << std::endl); + << std::endl, this->Quiet); std::vector<std::string> lines; std::vector<std::string>::iterator line; @@ -1554,8 +1568,8 @@ int cmCTestCoverageHandler::HandleLCovCoverage( std::string daGlob; daGlob = dir; daGlob += "/*.LCOV"; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " looking for LCOV files in: " << daGlob << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " looking for LCOV files in: " << daGlob << std::endl, this->Quiet); gl.FindFiles(daGlob); // Keep a list of all LCOV files lcovFiles.insert(lcovFiles.end(), gl.GetFiles().begin(), @@ -1590,13 +1604,13 @@ int cmCTestCoverageHandler::HandleLCovCoverage( for(std::vector<std::string>::iterator t = lcovFiles.begin(); t != lcovFiles.end(); ++t) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Found LCOV File: " - << *t << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Found LCOV File: " << *t << std::endl, this->Quiet); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "SourceFile: " - << sourceFile << std::endl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "lCovFile: " - << lcovFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "SourceFile: " + << sourceFile << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "lCovFile: " + << lcovFile << std::endl, this->Quiet); // If we have some LCOV files to process if ( !lcovFile.empty() && !actualSourceFile.empty() ) @@ -1604,8 +1618,8 @@ int cmCTestCoverageHandler::HandleLCovCoverage( cmCTestCoverageHandlerContainer::SingleFileCoverageVector& vec = cont->TotalCoverage[actualSourceFile]; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " in lcovFile: " - << lcovFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " in lcovFile: " << lcovFile << std::endl, this->Quiet); cmsys::ifstream ifile(lcovFile.c_str()); if ( ! ifile ) @@ -1620,8 +1634,8 @@ int cmCTestCoverageHandler::HandleLCovCoverage( // Skip the first line cmSystemTools::GetLineFromStream(ifile, nl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "File is ready, start reading." << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "File is ready, start reading." << std::endl, this->Quiet); while ( cmSystemTools::GetLineFromStream(ifile, nl) ) { cnt ++; @@ -1679,9 +1693,10 @@ int cmCTestCoverageHandler::HandleLCovCoverage( if ( file_count % 50 == 0 ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " processed: " << file_count - << " out of " << files.size() << std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " processed: " << file_count << " out of " << files.size() + << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); } } @@ -1707,8 +1722,8 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files) // Coverage files appear next to their object files in the target // support directory. - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " globbing for coverage in: " << lmi->first << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " globbing for coverage in: " << lmi->first << std::endl, this->Quiet); std::string daGlob = lmi->first; daGlob += "/*.da"; gl.FindFiles(daGlob); @@ -1740,12 +1755,12 @@ void cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files) std::string daGlob; daGlob = prevBinaryDir; daGlob += "/*.dpi"; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " looking for dpi files in: " << daGlob << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " looking for dpi files in: " << daGlob << std::endl, this->Quiet); gl.FindFiles(daGlob); files.insert(files.end(), gl.GetFiles().begin(), gl.GetFiles().end()); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Now searching in: " << daGlob << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Now searching in: " << daGlob << std::endl, this->Quiet); } //---------------------------------------------------------------------- @@ -1761,9 +1776,9 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( if (files.empty()) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Cannot find any Python Trace.py coverage files." - << std::endl); + << std::endl, this->Quiet); // No coverage files is a valid thing, so the exit code is 0 return 0; } @@ -1791,13 +1806,13 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( std::string actualSourceFile = cmSystemTools::CollapseFullPath(fileName); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Check coverage for file: " << actualSourceFile - << std::endl); + << std::endl, this->Quiet); cmCTestCoverageHandlerContainer::SingleFileCoverageVector* vec = &cont->TotalCoverage[actualSourceFile]; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " in file: " << *fileIt << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " in file: " << *fileIt << std::endl, this->Quiet); cmsys::ifstream ifile(fileIt->c_str()); if ( ! ifile ) { @@ -1850,9 +1865,9 @@ int cmCTestCoverageHandler::HandleTracePyCoverage( // So, this will be set to 0. cov = 0; } - cmCTestLog(this->CTest, DEBUG, "Prefix: " << prefix + cmCTestOptionalLog(this->CTest, DEBUG, "Prefix: " << prefix << " cov: " << cov - << std::endl); + << std::endl, this->Quiet); // Read the line number starting at the 10th character of the gcov // output line long lineIdx = cnt; @@ -1945,18 +1960,16 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( // for each file run covbr on that file to get the coverage // information for that file std::string outputFile; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "run covbr: " - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "run covbr: " << std::endl, this->Quiet); if(!this->RunBullseyeCommand(cont, "covbr", 0, outputFile)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "error running covbr for." << "\n"); return -1; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "covbr output in " << outputFile - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "covbr output in " << outputFile << std::endl, this->Quiet); // open the output file cmsys::ifstream fin(outputFile.c_str()); if(!fin) @@ -2002,10 +2015,8 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( // only allow 100 files in each log file if ( count != 0 && count % 100 == 0 ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "start a new log file: " - << count - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "start a new log file: " << count << std::endl, this->Quiet); this->EndCoverageLogFile(covLogFile, logFileCount); logFileCount ++; if ( !this->StartCoverageLogFile(covLogFile, logFileCount) ) @@ -2021,10 +2032,9 @@ int cmCTestCoverageHandler::RunBullseyeCoverageBranch( { // we have a new file so count it in the output count++; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Produce coverage for file: " - << file << " " << count - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Produce coverage for file: " << file << " " << count + << std::endl, this->Quiet); // start the file output covLogFile << "\t<File Name=\"" << cmXMLSafe(i->first) @@ -2083,13 +2093,13 @@ int cmCTestCoverageHandler::RunBullseyeCommand( } if(arg) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run : " << program << " " << arg << "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Run : " << program << " " << arg << "\n", this->Quiet); } else { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Run : " << program << "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Run : " << program << "\n", this->Quiet); } // create a process object and start it cmCTestRunProcess runCoverageSrc; @@ -2215,17 +2225,17 @@ int cmCTestCoverageHandler::RunBullseyeSourceSummary( cont->BinaryDir.c_str()); if ( !shouldIDoCoverage ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - ".NoDartCoverage found, so skip coverage check for: " - << file - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + ".NoDartCoverage found, so skip coverage check for: " + << file + << std::endl, this->Quiet); continue; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Doing coverage for: " - << file - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Doing coverage for: " + << file + << std::endl, this->Quiet); coveredFiles.push_back(sourceFile); coveredFilesFullPath.push_back(file); @@ -2328,23 +2338,23 @@ int cmCTestCoverageHandler::HandleBullseyeCoverage( const char* covfile = cmSystemTools::GetEnv("COVFILE"); if(!covfile || strlen(covfile) == 0) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " COVFILE environment variable not found, not running " - " bullseye\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " COVFILE environment variable not found, not running " + " bullseye\n", this->Quiet); return 0; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " run covsrc with COVFILE=[" - << covfile - << "]" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " run covsrc with COVFILE=[" + << covfile + << "]" << std::endl, this->Quiet); if(!this->RunBullseyeSourceSummary(cont)) { cmCTestLog(this->CTest, ERROR_MESSAGE, "Error running bullseye summary.\n"); return 0; } - cmCTestLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 " - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "HandleBullseyeCoverage return 1 " + << std::endl, this->Quiet); return 1; } @@ -2438,8 +2448,8 @@ void cmCTestCoverageHandler::LoadLabels() std::string fileList = this->CTest->GetBinaryDir(); fileList += cmake::GetCMakeFilesDirectory(); fileList += "/TargetDirectories.txt"; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " target directory list [" << fileList << "]\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " target directory list [" << fileList << "]\n", this->Quiet); cmsys::ifstream finList(fileList.c_str()); std::string line; while(cmSystemTools::GetLineFromStream(finList, line)) @@ -2460,8 +2470,8 @@ void cmCTestCoverageHandler::LoadLabels(const char* dir) return; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " loading labels from [" << fname << "]\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " loading labels from [" << fname << "]\n", this->Quiet); bool inTarget = true; std::string source; std::string line; @@ -2542,10 +2552,10 @@ bool cmCTestCoverageHandler::IntersectsFilter(LabelSet const& labels) } std::vector<int> ids; - cmsys_stl::set_intersection + std::set_intersection (labels.begin(), labels.end(), this->LabelFilter.begin(), this->LabelFilter.end(), - cmsys_stl::back_inserter(ids)); + std::back_inserter(ids)); return !ids.empty(); } diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h index 4aec795..3258ddb 100644 --- a/Source/CTest/cmCTestCoverageHandler.h +++ b/Source/CTest/cmCTestCoverageHandler.h @@ -30,9 +30,10 @@ public: typedef std::map<std::string, SingleFileCoverageVector> TotalCoverageMap; TotalCoverageMap TotalCoverage; std::ostream* OFS; + bool Quiet; }; /** \class cmCTestCoverageHandler - * \brief A class that handles coverage computaiton for ctest + * \brief A class that handles coverage computation for ctest * */ class cmCTestCoverageHandler : public cmCTestGenericHandler diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 98bc9d7..6b84bab 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -13,6 +13,7 @@ #include "cmCTest.h" #include "cmSystemTools.h" +#include "cmAlgorithms.h" #include "cmXMLSafe.h" #include <cmsys/RegularExpression.hxx> diff --git a/Source/CTest/cmCTestGenericHandler.cxx b/Source/CTest/cmCTestGenericHandler.cxx index 13c8ca5..81eb0a8 100644 --- a/Source/CTest/cmCTestGenericHandler.cxx +++ b/Source/CTest/cmCTestGenericHandler.cxx @@ -22,6 +22,7 @@ cmCTestGenericHandler::cmCTestGenericHandler() this->CTest = 0; this->SubmitIndex = 0; this->AppendXML = false; + this->Quiet = false; } //---------------------------------------------------------------------- diff --git a/Source/CTest/cmCTestGenericHandler.h b/Source/CTest/cmCTestGenericHandler.h index 2788cba..8567dd7 100644 --- a/Source/CTest/cmCTestGenericHandler.h +++ b/Source/CTest/cmCTestGenericHandler.h @@ -87,6 +87,8 @@ public: int GetSubmitIndex() { return this->SubmitIndex; } void SetAppendXML(bool b) { this->AppendXML = b; } + void SetQuiet(bool b) { this->Quiet = b; } + bool GetQuiet() { return this->Quiet; } protected: bool StartResultingXML(cmCTest::Part part, @@ -94,6 +96,7 @@ protected: bool StartLogFile(const char* name, cmGeneratedFileStream& xofs); bool AppendXML; + bool Quiet; cmSystemTools::OutputOption HandlerVerbose; cmCTest *CTest; t_StringToString Options; diff --git a/Source/CTest/cmCTestGlobalVC.h b/Source/CTest/cmCTestGlobalVC.h index cb0d165..29e0a61 100644 --- a/Source/CTest/cmCTestGlobalVC.h +++ b/Source/CTest/cmCTestGlobalVC.h @@ -14,6 +14,8 @@ #include "cmCTestVC.h" +#include <list> + /** \class cmCTestGlobalVC * \brief Base class for handling globally-versioned trees * diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx index b886777..3003e8a 100644 --- a/Source/CTest/cmCTestHandlerCommand.cxx +++ b/Source/CTest/cmCTestHandlerCommand.cxx @@ -29,6 +29,7 @@ cmCTestHandlerCommand::cmCTestHandlerCommand() this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX"; this->Last = ct_LAST; this->AppendXML = false; + this->Quiet = false; } bool cmCTestHandlerCommand @@ -74,7 +75,7 @@ bool cmCTestHandlerCommand { this->CTest->SetCTestConfiguration("BuildDirectory", cmSystemTools::CollapseFullPath( - this->Values[ct_BUILD]).c_str()); + this->Values[ct_BUILD]).c_str(), this->Quiet); } else { @@ -84,7 +85,7 @@ bool cmCTestHandlerCommand { this-> CTest->SetCTestConfiguration("BuildDirectory", - cmSystemTools::CollapseFullPath(bdir).c_str()); + cmSystemTools::CollapseFullPath(bdir).c_str(), this->Quiet); } else { @@ -98,13 +99,14 @@ bool cmCTestHandlerCommand "Set source directory to: " << this->Values[ct_SOURCE] << std::endl); this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( - this->Values[ct_SOURCE]).c_str()); + this->Values[ct_SOURCE]).c_str(), this->Quiet); } else { this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( - this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); + this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY")).c_str(), + this->Quiet); } cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;); @@ -160,6 +162,12 @@ bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg) this->AppendXML = true; return true; } + if(arg == "QUIET") + { + this->ArgumentDoing = ArgumentDoingNone; + this->Quiet = true; + return true; + } // Check for a keyword in our argument/value table. for(unsigned int k=0; k < this->Arguments.size(); ++k) diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h index 8ef2b80..87b2cd8 100644 --- a/Source/CTest/cmCTestHandlerCommand.h +++ b/Source/CTest/cmCTestHandlerCommand.h @@ -62,6 +62,7 @@ protected: unsigned int ArgumentIndex; bool AppendXML; + bool Quiet; std::string ReturnVariable; std::vector<const char*> Arguments; diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index f144066..b379d32 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -21,16 +21,20 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() = this->CTest->GetInitializedHandler("memcheck"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE"); + "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "MemoryCheckSanitizerOptions", "CTEST_MEMORYCHECK_SANITIZER_OPTIONS"); + "MemoryCheckSanitizerOptions", "CTEST_MEMORYCHECK_SANITIZER_OPTIONS", + this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND"); + "MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS"); + "MemoryCheckCommandOptions", "CTEST_MEMORYCHECK_COMMAND_OPTIONS", + this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE"); + "MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE", + this->Quiet); + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index d4ff24f..061f3fd 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -251,8 +251,8 @@ void cmCTestMemCheckHandler::GenerateTestCommand( memcheckcommand += " " + memTesterEnvironmentVariable; args.push_back(memTesterEnvironmentVariable); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Memory check command: " - << memcheckcommand << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Memory check command: " << memcheckcommand << std::endl, this->Quiet); } //---------------------------------------------------------------------- @@ -347,7 +347,8 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile *mf) "CTEST_CUSTOM_MEMCHECK_IGNORE", this->CustomTestsIgnore); std::string cmake = cmSystemTools::GetCMakeCommand(); - this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str()); + this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(), + this->Quiet); } //---------------------------------------------------------------------- @@ -400,8 +401,8 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) << "</Test>" << std::endl; } os << "\t</TestList>\n"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, - "-- Processing memory checking output: "); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "-- Processing memory checking output: ", this->Quiet); size_t total = this->TestResults.size(); size_t step = total / 10; size_t current = 0; @@ -451,13 +452,14 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) this->WriteTestResultFooter(os, result); if ( current < cc ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush, + this->Quiet); current += step; } } - cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Memory checking results:" + << std::endl, this->Quiet); os << "\t<DefectList>" << std::endl; for ( cc = 0; cc < this->GlobalResults.size(); cc ++ ) { @@ -468,9 +470,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) #endif std::cerr.width(35); #define cerr no_cerr - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->ResultStringsLong[cc] << " - " - << this->GlobalResults[cc] << std::endl); + << this->GlobalResults[cc] << std::endl, this->Quiet); os << "\t\t<Defect Type=\"" << this->ResultStringsLong[cc] << "\"/>" << std::endl; } @@ -594,10 +596,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() } if(this->MemoryTester.empty()) { - cmCTestLog(this->CTest, WARNING, + cmCTestOptionalLog(this->CTest, WARNING, "Memory checker (MemoryCheckCommand) " "not set, or cannot find the specified program." - << std::endl); + << std::endl, this->Quiet); return false; } @@ -981,17 +983,18 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( "locked by a different thread"); std::vector<std::string::size_type> nonValGrindOutput; double sttime = cmSystemTools::GetTime(); - cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, + "Start test: " << lines.size() << std::endl, this->Quiet); std::string::size_type totalOutputSize = 0; for ( cc = 0; cc < lines.size(); cc ++ ) { - cmCTestLog(this->CTest, DEBUG, "test line " - << lines[cc] << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "test line " + << lines[cc] << std::endl, this->Quiet); if ( valgrindLine.find(lines[cc]) ) { - cmCTestLog(this->CTest, DEBUG, "valgrind line " - << lines[cc] << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "valgrind line " + << lines[cc] << std::endl, this->Quiet); int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT; if ( vgFIM.find(lines[cc]) ) { @@ -1075,10 +1078,10 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( nonValGrindOutput.begin(); i != nonValGrindOutput.end(); ++i) { totalOutputSize += lines[*i].size(); - cmCTestLog(this->CTest, DEBUG, "before xml safe " - << lines[*i] << std::endl); - cmCTestLog(this->CTest, DEBUG, "after xml safe " - << cmXMLSafe(lines[*i]) << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "before xml safe " + << lines[*i] << std::endl, this->Quiet); + cmCTestOptionalLog(this->CTest, DEBUG, "after xml safe " + << cmXMLSafe(lines[*i]) << std::endl, this->Quiet); ostr << cmXMLSafe(lines[*i]) << std::endl; if(!unlimitedOutput && totalOutputSize > static_cast<size_t>(this->CustomMaximumFailedTestOutputSize)) @@ -1091,8 +1094,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( break; // stop the copy of output if we are full } } - cmCTestLog(this->CTest, DEBUG, "End test (elapsed: " - << (cmSystemTools::GetTime() - sttime) << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "End test (elapsed: " + << (cmSystemTools::GetTime() - sttime) << std::endl, this->Quiet); log = ostr.str(); if ( defects ) { @@ -1112,7 +1115,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput( double sttime = cmSystemTools::GetTime(); std::vector<std::string> lines; cmSystemTools::Split(str.c_str(), lines); - cmCTestLog(this->CTest, DEBUG, "Start test: " << lines.size() << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, + "Start test: " << lines.size() << std::endl, this->Quiet); std::vector<std::string>::size_type cc; for ( cc = 0; cc < lines.size(); cc ++ ) { @@ -1148,8 +1152,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput( results[parser.Errors[cc]]++; defects++; } - cmCTestLog(this->CTest, DEBUG, "End test (elapsed: " - << (cmSystemTools::GetTime() - sttime) << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "End test (elapsed: " + << (cmSystemTools::GetTime() - sttime) << std::endl, this->Quiet); if(defects) { // only put the output of Bounds Checker if there were @@ -1165,9 +1169,9 @@ void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "PostProcessTest memcheck results for : " - << res.Name << std::endl); + << res.Name << std::endl, this->Quiet); if(this->MemoryTesterStyle == cmCTestMemCheckHandler::BOUNDS_CHECKER) { @@ -1192,9 +1196,9 @@ void cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "PostProcessBoundsCheckerTest for : " - << res.Name << std::endl); + << res.Name << std::endl, this->Quiet); std::vector<std::string> files; this->TestOutputFileNames(test, files); if (files.empty()) @@ -1226,11 +1230,11 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res, } cmSystemTools::Delay(1000); cmSystemTools::RemoveFile(this->BoundsCheckerDPBDFile); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: " - << this->BoundsCheckerDPBDFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: " + << this->BoundsCheckerDPBDFile << std::endl, this->Quiet); cmSystemTools::RemoveFile(this->BoundsCheckerXMLFile); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: " - << this->BoundsCheckerXMLFile << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: " + << this->BoundsCheckerXMLFile << std::endl, this->Quiet); } void @@ -1260,7 +1264,8 @@ cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res, if(this->LogWithPID) { cmSystemTools::RemoveFile(ofile); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Remove: "<< ofile <<"\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Remove: "<< ofile <<"\n", this->Quiet); } } diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index f9e8a3c..bd090db 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -16,6 +16,7 @@ #include "cmSystemTools.h" #include <stdlib.h> #include <stack> +#include <list> #include <float.h> #include <cmsys/FStream.hxx> @@ -112,13 +113,19 @@ void cmCTestMultiProcessHandler::RunTests() //--------------------------------------------------------- void cmCTestMultiProcessHandler::StartTestProcess(int test) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "test " << test << "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "test " << test << "\n", this->Quiet); this->TestRunningMap[test] = true; // mark the test as running // now remove the test itself this->EraseTest(test); this->RunningCount += GetProcessorsUsed(test); cmCTestRunTest* testRun = new cmCTestRunTest(this->TestHandler); + if(this->CTest->GetRepeatUntilFail()) + { + testRun->SetRunUntilFailOn(); + testRun->SetNumberOfRuns(this->CTest->GetTestRepeat()); + } testRun->SetIndex(test); testRun->SetTestProperties(this->Properties[test]); @@ -287,7 +294,13 @@ bool cmCTestMultiProcessHandler::CheckOutput() cmCTestRunTest* p = *i; int test = p->GetIndex(); - if(p->EndTest(this->Completed, this->Total, true)) + bool testResult = p->EndTest(this->Completed, this->Total, true); + if(p->StartAgain()) + { + this->Completed--; // remove the completed test because run again + continue; + } + if(testResult) { this->Passed->push_back(p->GetTestProperties()->Name); } @@ -638,39 +651,44 @@ void cmCTestMultiProcessHandler::PrintTestList() if(!p.Labels.empty()) //print the labels { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Labels:", + this->Quiet); } for(std::vector<std::string>::iterator label = p.Labels.begin(); label != p.Labels.end(); ++label) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " " << *label, + this->Quiet); } if(!p.Labels.empty()) //print the labels { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl, + this->Quiet); } if (this->TestHandler->MemCheck) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Memory Check"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Memory Check", + this->Quiet); } else { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Test"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Test", this->Quiet); } std::ostringstream indexStr; indexStr << " #" << p.Index << ":"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::setw(3 + getNumWidth(this->TestHandler->GetMaxIndex())) - << indexStr.str()); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); - cmCTestLog(this->CTest, HANDLER_OUTPUT, p.Name.c_str() << std::endl); + << indexStr.str(), this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " ", this->Quiet); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + p.Name.c_str() << std::endl, this->Quiet); //pop working dir cmSystemTools::ChangeDirectory(current_dir); } - cmCTestLog(this->CTest, HANDLER_OUTPUT, std::endl << "Total Tests: " - << this->Total << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl << "Total Tests: " + << this->Total << std::endl, this->Quiet); } void cmCTestMultiProcessHandler::PrintLabels() @@ -685,16 +703,19 @@ void cmCTestMultiProcessHandler::PrintLabels() if(!allLabels.empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "All Labels:" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "All Labels:" << std::endl, this->Quiet); } else { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "No Labels Exist" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "No Labels Exist" << std::endl, this->Quiet); } for(std::set<std::string>::iterator label = allLabels.begin(); label != allLabels.end(); ++label) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " " << *label << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " " << *label << std::endl, this->Quiet); } } @@ -757,8 +778,8 @@ int cmCTestMultiProcessHandler::FindMaxIndex() //Returns true if no cycles exist in the dependency graph bool cmCTestMultiProcessHandler::CheckCycles() { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Checking test dependency graph..." << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Checking test dependency graph..." << std::endl, this->Quiet); for(TestMap::iterator it = this->Tests.begin(); it != this->Tests.end(); ++it) { @@ -793,7 +814,7 @@ bool cmCTestMultiProcessHandler::CheckCycles() } } } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Checking test dependency graph end" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Checking test dependency graph end" << std::endl, this->Quiet); return true; } diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h index 605de31..6440fbc 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.h +++ b/Source/CTest/cmCTestMultiProcessHandler.h @@ -57,6 +57,8 @@ public: cmCTestTestHandler * GetTestHandler() { return this->TestHandler; } + + void SetQuiet(bool b) { this->Quiet = b; } protected: // Start the next test or tests as many as are allowed by // ParallelLevel @@ -118,6 +120,7 @@ protected: cmCTestTestHandler * TestHandler; cmCTest* CTest; bool HasCycles; + bool Quiet; }; #endif diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 314c8ad..d7da2b4 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -33,6 +33,9 @@ cmCTestRunTest::cmCTestRunTest(cmCTestTestHandler* handler) this->CompressedOutput = ""; this->CompressionRatio = 2; this->StopTimePassed = false; + this->NumberOfRunsLeft = 1; // default to 1 run of the test + this->RunUntilFail = false; // default to run the test once + this->RunAgain = false; // default to not having to run again } cmCTestRunTest::~cmCTestRunTest() @@ -357,13 +360,50 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) this->MemCheckPostProcess(); this->ComputeWeightedCost(); } - // Always push the current TestResult onto the + // If the test does not need to rerun push the current TestResult onto the // TestHandler vector - this->TestHandler->TestResults.push_back(this->TestResult); + if(!this->NeedsToRerun()) + { + this->TestHandler->TestResults.push_back(this->TestResult); + } delete this->TestProcess; return passed; } +bool cmCTestRunTest::StartAgain() +{ + if(!this->RunAgain) + { + return false; + } + this->RunAgain = false; // reset + // change to tests directory + std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory(); + cmSystemTools::ChangeDirectory(this->TestProperties->Directory); + this->StartTest(this->TotalNumberOfTests); + // change back + cmSystemTools::ChangeDirectory(current_dir); + return true; +} + +bool cmCTestRunTest::NeedsToRerun() +{ + this->NumberOfRunsLeft--; + if(this->NumberOfRunsLeft == 0) + { + return false; + } + // if number of runs left is not 0, and we are running until + // we find a failed test, then return true so the test can be + // restarted + if(this->RunUntilFail + && this->TestResult.Status == cmCTestTestHandler::COMPLETED) + { + this->RunAgain = true; + return true; + } + return false; +} //---------------------------------------------------------------------- void cmCTestRunTest::ComputeWeightedCost() { @@ -386,10 +426,11 @@ void cmCTestRunTest::MemCheckPostProcess() { return; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index - << ": process test output now: " - << this->TestProperties->Name << " " - << this->TestResult.Name << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index + << ": process test output now: " + << this->TestProperties->Name << " " + << this->TestResult.Name << std::endl, + this->TestHandler->GetQuiet()); cmCTestMemCheckHandler * handler = static_cast<cmCTestMemCheckHandler*> (this->TestHandler); handler->PostProcessTest(this->TestResult, this->Index); @@ -399,6 +440,7 @@ void cmCTestRunTest::MemCheckPostProcess() // Starts the execution of a test. Returns once it has started bool cmCTestRunTest::StartTest(size_t total) { + this->TotalNumberOfTests = total; // save for rerun case cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(2*getNumWidth(total) + 8) << "Start " << std::setw(getNumWidth(this->TestHandler->GetMaxIndex())) @@ -493,10 +535,10 @@ bool cmCTestRunTest::StartTest(size_t total) //---------------------------------------------------------------------- void cmCTestRunTest::ComputeArguments() { + this->Arguments.clear(); // reset becaue this might be a rerun std::vector<std::string>::const_iterator j = this->TestProperties->Args.begin(); ++j; // skip test name - // find the test executable if(this->TestHandler->MemCheck) { @@ -535,11 +577,26 @@ void cmCTestRunTest::ComputeArguments() } this->TestResult.FullCommandLine = testCommand; + // Print the test command in verbose mode cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl << this->Index << ": " << (this->TestHandler->MemCheck?"MemCheck":"Test") << " command: " << testCommand << std::endl); + + // Print any test-specific env vars in verbose mode + if (this->TestProperties->Environment.size()) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " + << "Environment variables: " << std::endl); + } + for(std::vector<std::string>::const_iterator e = + this->TestProperties->Environment.begin(); + e != this->TestProperties->Environment.end(); ++e) + { + cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " << *e + << std::endl); + } } //---------------------------------------------------------------------- @@ -661,8 +718,9 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout, { timeout = 0; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " - << "Test timeout computed to be: " << timeout << "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, this->Index << ": " + << "Test timeout computed to be: " << timeout << "\n", + this->TestHandler->GetQuiet()); this->TestProcess->SetTimeout(timeout); @@ -680,10 +738,28 @@ bool cmCTestRunTest::ForkProcess(double testTimeOut, bool explicitTimeout, void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) - << completed << "/"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) - << total << " "); + // if this is the last or only run of this test + // then print out completed / total + // Only issue is if a test fails and we are running until fail + // then it will never print out the completed / total, same would + // got for run until pass. Trick is when this is called we don't + // yet know if we are passing or failing. + if(this->NumberOfRunsLeft == 1) + { + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) + << completed << "/"); + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) + << total << " "); + } + // if this is one of several runs of a test just print blank space + // to keep things neat + else + { + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) + << " " << " "); + cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(getNumWidth(total)) + << " " << " "); + } if ( this->TestHandler->MemCheck ) { diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h index 476f3e1..3b5c831 100644 --- a/Source/CTest/cmCTestRunTest.h +++ b/Source/CTest/cmCTestRunTest.h @@ -27,6 +27,8 @@ public: cmCTestRunTest(cmCTestTestHandler* handler); ~cmCTestRunTest(); + void SetNumberOfRuns(int n) {this->NumberOfRunsLeft = n;} + void SetRunUntilFailOn() { this->RunUntilFail = true;} void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties * prop) { this->TestProperties = prop; } @@ -58,7 +60,10 @@ public: void ComputeArguments(); void ComputeWeightedCost(); + + bool StartAgain(); private: + bool NeedsToRerun(); void DartProcessing(); void ExeNotFound(std::string exe); // Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT) @@ -92,6 +97,10 @@ private: std::string ActualCommand; std::vector<std::string> Arguments; bool StopTimePassed; + bool RunUntilFail; + int NumberOfRunsLeft; + bool RunAgain; + size_t TotalNumberOfTests; }; inline int getNumWidth(size_t n) diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h index c6548e3..17bf7cb 100644 --- a/Source/CTest/cmCTestSVN.h +++ b/Source/CTest/cmCTestSVN.h @@ -14,6 +14,8 @@ #include "cmCTestGlobalVC.h" +#include <list> + /** \class cmCTestSVN * \brief Interaction with subversion command-line tool * diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index 8184bb4..3792953 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -454,12 +454,8 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg) if (!this->Makefile->ReadListFile(0, script.c_str()) || cmSystemTools::GetErrorOccuredFlag()) { - cmCTestLog(this->CTest, ERROR_MESSAGE, "Error in read script: " - << script - << std::endl); // Reset the error flag so that it can run more than - // one script with an error when you - // use ctest_run_script + // one script with an error when you use ctest_run_script. cmSystemTools::ResetErrorOccuredFlag(); return 2; } diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx index 8ea6cef..e19e4f4 100644 --- a/Source/CTest/cmCTestStartCommand.cxx +++ b/Source/CTest/cmCTestStartCommand.cxx @@ -20,6 +20,7 @@ cmCTestStartCommand::cmCTestStartCommand() { this->CreateNewTag = true; + this->Quiet = false; } bool cmCTestStartCommand @@ -57,6 +58,14 @@ bool cmCTestStartCommand this->CreateNewTag = false; } } + if (cnt < args.size()) + { + if (args[cnt] == "QUIET") + { + cnt ++; + this->Quiet = true; + } + } if ( cnt < args.size() ) { @@ -95,18 +104,20 @@ bool cmCTestStartCommand std::string sourceDir = cmSystemTools::CollapseFullPath(src_dir); std::string binaryDir = cmSystemTools::CollapseFullPath(bld_dir); - this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str()); - this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str()); + this->CTest->SetCTestConfiguration("SourceDirectory", sourceDir.c_str(), + this->Quiet); + this->CTest->SetCTestConfiguration("BuildDirectory", binaryDir.c_str(), + this->Quiet); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model " + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Run dashboard with model " << smodel << std::endl << " Source directory: " << src_dir << std::endl - << " Build directory: " << bld_dir << std::endl); + << " Build directory: " << bld_dir << std::endl, this->Quiet); const char* track = this->CTest->GetSpecificTrack(); if ( track ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Track: " << track << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Track: " << track << std::endl, this->Quiet); } // Log startup actions. diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h index 3b8843f..eed1962 100644 --- a/Source/CTest/cmCTestStartCommand.h +++ b/Source/CTest/cmCTestStartCommand.h @@ -34,6 +34,7 @@ public: ni->CTest = this->CTest; ni->CTestScriptHandler = this->CTestScriptHandler; ni->CreateNewTag = this->CreateNewTag; + ni->Quiet = this->Quiet; return ni; } @@ -53,6 +54,14 @@ public: } /** + * Should this invocation of ctest_start output non-error messages? + */ + bool ShouldBeQuiet() + { + return this->Quiet; + } + + /** * The name of the command as specified in CMakeList.txt. */ virtual std::string GetName() const { return "ctest_start";} @@ -62,6 +71,7 @@ public: private: bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir); bool CreateNewTag; + bool Quiet; }; diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index cc3514f..5a8090c 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -44,29 +44,33 @@ 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); + this->CTest->SetCTestConfiguration("ProjectName", ctestProjectName, + this->Quiet); + this->CTest->SetCTestConfiguration("DropMethod", ctestDropMethod, + this->Quiet); + this->CTest->SetCTestConfiguration("DropSite", ctestDropSite, this->Quiet); + this->CTest->SetCTestConfiguration("DropLocation", ctestDropLocation, + this->Quiet); this->CTest->SetCTestConfiguration("IsCDash", - ctestDropSiteCDash ? "TRUE" : "FALSE"); + ctestDropSiteCDash ? "TRUE" : "FALSE", this->Quiet); // Only propagate TriggerSite for non-CDash projects: // if ( !ctestDropSiteCDash ) { - this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite); + this->CTest->SetCTestConfiguration("TriggerSite", ctestTriggerSite, + this->Quiet); } this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "CurlOptions", "CTEST_CURL_OPTIONS"); + "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "DropSiteUser", "CTEST_DROP_SITE_USER"); + "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "DropSitePassword", "CTEST_DROP_SITE_PASSWORD"); + "DropSitePassword", "CTEST_DROP_SITE_PASSWORD", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "ScpCommand", "CTEST_SCP_COMMAND"); + "ScpCommand", "CTEST_SCP_COMMAND", this->Quiet); const char* notesFilesVariable = this->Makefile->GetDefinition("CTEST_NOTES_FILES"); @@ -145,6 +149,8 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() static_cast<cmCTestSubmitHandler*>(handler)->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF"); + handler->SetQuiet(this->Quiet); + if (this->CDashUpload) { static_cast<cmCTestSubmitHandler*>(handler)-> diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 5b52df7..d585863 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -242,9 +242,9 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); *this->LogFile << "\tUpload file: " << local_file << " to " << upload_as << std::endl; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: " - << local_file << " to " - << upload_as << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Upload file: " << local_file << " to " << upload_as << std::endl, + this->Quiet); ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); @@ -278,15 +278,15 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, if (!chunk.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" - << std::endl); + << std::endl, this->Quiet); } if (!chunkDebug.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]" - << std::endl); + << std::endl, this->Quiet); } fclose(ftpfile); @@ -318,8 +318,8 @@ bool cmCTestSubmitHandler::SubmitUsingFTP(const std::string& localprefix, } // always cleanup ::curl_easy_cleanup(curl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Uploaded: " + local_file << std::endl, this->Quiet); } } ::curl_global_cleanup(); @@ -369,14 +369,14 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, cmCurlSetCAInfo(curl); if(verifyPeerOff) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Set CURLOPT_SSL_VERIFYPEER to off\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Set CURLOPT_SSL_VERIFYPEER to off\n", this->Quiet); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); } if(verifyHostOff) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - " Set CURLOPT_SSL_VERIFYHOST to off\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Set CURLOPT_SSL_VERIFYHOST to off\n", this->Quiet); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); } @@ -482,9 +482,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, unsigned long filelen = cmSystemTools::FileLength(local_file); ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: " - << local_file << " to " - << upload_as << " Size: " << filelen << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Upload file: " << local_file << " to " + << upload_as << " Size: " << filelen << std::endl, this->Quiet); // specify target ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str()); @@ -529,16 +529,16 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, if (!chunk.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" - << std::endl); + << std::endl, this->Quiet); this->ParseResponse(chunk); } if (!chunkDebug.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]" - << std::endl); + << std::endl, this->Quiet); } // If curl failed for any reason, or checksum fails, wait and retry @@ -557,8 +557,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, for(int i = 0; i < count; i++) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Submit failed, waiting " << delay << " seconds...\n"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Submit failed, waiting " << delay << " seconds...\n", + this->Quiet); double stop = cmSystemTools::GetTime() + delay; while(cmSystemTools::GetTime() < stop) @@ -566,9 +567,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, cmSystemTools::Delay(100); } - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Retry submission: Attempt " << (i + 1) << " of " - << count << std::endl); + << count << std::endl, this->Quiet); ::fclose(ftpfile); ftpfile = cmsys::SystemTools::Fopen(local_file, "rb"); @@ -582,9 +583,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, if (!chunk.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" - << std::endl); + << std::endl, this->Quiet); this->ParseResponse(chunk); } @@ -624,8 +625,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const std::string& localprefix, } // always cleanup ::curl_easy_cleanup(curl); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Uploaded: " + local_file << std::endl, this->Quiet); } } ::curl_global_cleanup(); @@ -677,6 +678,7 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( { CURL *curl; char error_buffer[1024]; + /* In windows, this will init the winsock stuff */ ::curl_global_init(CURL_GLOBAL_ALL); @@ -756,8 +758,8 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( = url + ((url.find("?",0) == std::string::npos) ? "?" : "&") + "xmlfile=" + ofile; *this->LogFile << "Trigger url: " << turl << std::endl; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Trigger url: " - << turl << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Trigger url: " << turl << std::endl, this->Quiet); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_easy_setopt(curl, CURLOPT_URL, turl.c_str()); if ( curl_easy_perform(curl) ) @@ -786,25 +788,26 @@ bool cmCTestSubmitHandler::TriggerUsingHTTP( if (!chunk.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL output: [" << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]" - << std::endl); + << std::endl, this->Quiet); } if (!chunkDebug.empty()) { - cmCTestLog(this->CTest, DEBUG, "CURL debug output: [" + cmCTestOptionalLog(this->CTest, DEBUG, "CURL debug output: [" << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) - << "]" << std::endl); + << "]" << std::endl, this->Quiet); } // always cleanup ::curl_easy_cleanup(curl); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl, + this->Quiet); } } ::curl_global_cleanup(); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..." - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..." + << std::endl, this->Quiet); return true; } @@ -821,6 +824,7 @@ bool cmCTestSubmitHandler::SubmitUsingSCP( { return 0; } + std::vector<const char*> argv; argv.push_back(scp_command.c_str()); // Scp command argv.push_back(scp_command.c_str()); // Dummy string for file @@ -845,9 +849,9 @@ bool cmCTestSubmitHandler::SubmitUsingSCP( argv[1] = lfname.c_str(); std::string rfname = url + "/" + remoteprefix + *file; argv[2] = rfname.c_str(); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Execute \"" << argv[0] - << "\" \"" << argv[1] << "\" \"" - << argv[2] << "\"" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \"" + << argv[2] << "\"" << std::endl, this->Quiet); *this->LogFile << "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \"" << argv[2] << "\"" << std::endl; @@ -858,8 +862,8 @@ bool cmCTestSubmitHandler::SubmitUsingSCP( while(cmsysProcess_WaitForData(cp, &data, &length, 0)) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - cmCTestLogWrite(data, length)); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestLogWrite(data, length), this->Quiet); } cmsysProcess_WaitForExit(cp, 0); @@ -871,8 +875,8 @@ bool cmCTestSubmitHandler::SubmitUsingSCP( retVal = cmsysProcess_GetExitValue(cp); if ( retVal != 0 ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\tSCP returned: " - << retVal << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "\tSCP returned: " << retVal << std::endl, this->Quiet); *this->LogFile << "\tSCP returned: " << retVal << std::endl; problems ++; } @@ -927,6 +931,7 @@ bool cmCTestSubmitHandler::SubmitUsingCP( << "\tdestination: " << destination << std::endl); return 0; } + cmCTest::SetOfStrings::const_iterator file; bool problems = false; for ( file = files.begin(); file != files.end(); ++file ) @@ -936,9 +941,9 @@ bool cmCTestSubmitHandler::SubmitUsingCP( lfname += "/" + *file; std::string rfname = destination + "/" + remoteprefix + *file; cmSystemTools::CopyFileAlways(lfname, rfname); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Copy file: " + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Copy file: " << lfname << " to " - << rfname << std::endl); + << rfname << std::endl, this->Quiet); } std::string tagDoneFile = destination + "/" + remoteprefix + "DONE"; cmSystemTools::Touch(tagDoneFile, true); @@ -971,8 +976,9 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const std::string& localprefix, xmlrpc_env_init(&env); /* Call the famous server at UserLand. */ - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submitting to: " - << realURL.c_str() << " (" << remoteprefix.c_str() << ")" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submitting to: " + << realURL.c_str() << " (" << remoteprefix.c_str() << ")" << std::endl, + this->Quiet); cmCTest::SetOfStrings::const_iterator file; for ( file = files.begin(); file != files.end(); ++file ) { @@ -983,8 +989,8 @@ bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const std::string& localprefix, { local_file = localprefix + "/" + *file; } - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submit file: " - << local_file.c_str() << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submit file: " + << local_file.c_str() << std::endl, this->Quiet); struct stat st; if ( ::stat(local_file.c_str(), &st) ) { @@ -1068,12 +1074,14 @@ void cmCTestSubmitHandler::ConstructCDashURL(std::string& dropMethod, if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 ) { url += this->CTest->GetCTestConfiguration("DropSiteUser"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetCTestConfiguration("DropSiteUser").c_str()); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), + this->Quiet); if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 ) { url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", + this->Quiet); } url += "@"; } @@ -1147,8 +1155,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << "datafilesmd5[0]=" << md5sum << "&" << "type=" << curl.Escape(typeString); std::string fields = str.str(); - cmCTestLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:" - << url << "\nfile: " << file << "\n"); + cmCTestOptionalLog(this->CTest, DEBUG, "fields: " << fields << "\nurl:" + << url << "\nfile: " << file << "\n", this->Quiet); std::string response; if(!curl.HttpRequest(url, fields, response)) { @@ -1156,8 +1164,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, "Error in HttpRequest\n" << response); return -1; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Request upload response: [" << response << "]\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Request upload response: [" << response << "]\n", this->Quiet); Json::Value json; Json::Reader reader; if(!reader.parse(response, json)) @@ -1179,9 +1187,9 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, int datares = json["datafilesmd5"][0].asInt(); if(datares == 1) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "File already exists on CDash, skip upload " - << file << "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "File already exists on CDash, skip upload " << file << "\n", + this->Quiet); return 0; } } @@ -1213,8 +1221,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, << reader.getFormattedErrorMessages() << "\n"); return -1; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Upload file response: [" << response << "]\n"); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Upload file response: [" << response << "]\n", this->Quiet ); return 0; } @@ -1311,13 +1319,13 @@ int cmCTestSubmitHandler::ProcessHandler() if (!this->HTTPProxy.empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: " - << this->HTTPProxy << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: " + << this->HTTPProxy << std::endl, this->Quiet); } if (!this->FTPProxy.empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: " - << this->FTPProxy << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: " + << this->FTPProxy << std::endl, this->Quiet); } cmGeneratedFileStream ofs; this->StartLogFile("Submit", ofs); @@ -1349,16 +1357,16 @@ int cmCTestSubmitHandler::ProcessHandler() = buildDirectory + "/Testing/" + this->CTest->GetCurrentTag(); std::string::size_type glen = gpath.size() + 1; gpath = gpath + "/CoverageLog*"; - cmCTestLog(this->CTest, DEBUG, "Globbing for: " << gpath - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Globbing for: " << gpath + << std::endl, this->Quiet); if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) ) { size_t cc; for ( cc = 0; cc < gfiles.size(); cc ++ ) { gfiles[cc] = gfiles[cc].substr(glen); - cmCTestLog(this->CTest, DEBUG, "Glob file: " << gfiles[cc] - << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Glob file: " << gfiles[cc] + << std::endl, this->Quiet); this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfiles[cc].c_str()); } } @@ -1398,14 +1406,14 @@ int cmCTestSubmitHandler::ProcessHandler() cnt ++; } } - cmCTestLog(this->CTest, HANDLER_OUTPUT, "Submit files (using " + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "Submit files (using " << this->CTest->GetCTestConfiguration("DropMethod") << ")" - << std::endl); + << std::endl, this->Quiet); const char* specificTrack = this->CTest->GetSpecificTrack(); if ( specificTrack ) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Send to track: " - << specificTrack << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Send to track: " + << specificTrack << std::endl, this->Quiet); } this->SetLogFile(&ofs); @@ -1414,9 +1422,9 @@ int cmCTestSubmitHandler::ProcessHandler() if ( dropMethod == "" || dropMethod == "ftp" ) { ofs << "Using drop method: FTP" << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using FTP submit method" - << std::endl - << " Drop site: ftp://"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Using FTP submit method" << std::endl << " Drop site: ftp://", + this->Quiet); std::string url = "ftp://"; url += cmCTest::MakeURLSafe( this->CTest->GetCTestConfiguration("DropSiteUser")) + ":" + @@ -1427,18 +1435,20 @@ int cmCTestSubmitHandler::ProcessHandler() this->CTest->GetCTestConfiguration("DropLocation")); if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->CTest->GetCTestConfiguration( - "DropSiteUser").c_str()); + "DropSiteUser").c_str(), this->Quiet); if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", + this->Quiet); } - cmCTestLog(this->CTest, HANDLER_OUTPUT, "@"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet); } - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->CTest->GetCTestConfiguration("DropSite") - << this->CTest->GetCTestConfiguration("DropLocation") << std::endl); + << this->CTest->GetCTestConfiguration("DropLocation") << std::endl, + this->Quiet); if ( !this->SubmitUsingFTP(buildDirectory + "/Testing/" + this->CTest->GetCurrentTag(), files, prefix, url) ) @@ -1451,11 +1461,12 @@ int cmCTestSubmitHandler::ProcessHandler() } if(!this->CDash) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method" + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Using HTTP trigger method" << std::endl << " Trigger site: " << this->CTest->GetCTestConfiguration("TriggerSite") - << std::endl); + << std::endl, this->Quiet); if ( !this-> TriggerUsingHTTP(files, prefix, this->CTest->GetCTestConfiguration("TriggerSite"))) @@ -1465,8 +1476,8 @@ int cmCTestSubmitHandler::ProcessHandler() ofs << " Problems when triggering via HTTP" << std::endl; return -1; } - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Submission successful" << std::endl, this->Quiet); ofs << " Submission successful" << std::endl; return 0; } @@ -1476,27 +1487,30 @@ int cmCTestSubmitHandler::ProcessHandler() std::string url = dropMethod; url += "://"; ofs << "Using drop method: " << dropMethod << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP submit method" - << std::endl - << " Drop site:" << url); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Using HTTP submit method" << std::endl << " Drop site:" << url, + this->Quiet); if (!this->CTest->GetCTestConfiguration("DropSiteUser").empty()) { url += this->CTest->GetCTestConfiguration("DropSiteUser"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, - this->CTest->GetCTestConfiguration("DropSiteUser").c_str()); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + this->CTest->GetCTestConfiguration("DropSiteUser").c_str(), + this->Quiet); if (!this->CTest->GetCTestConfiguration("DropSitePassword").empty()) { url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, ":******", + this->Quiet); } url += "@"; - cmCTestLog(this->CTest, HANDLER_OUTPUT, "@"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "@", this->Quiet); } url += this->CTest->GetCTestConfiguration("DropSite") + this->CTest->GetCTestConfiguration("DropLocation"); - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, this->CTest->GetCTestConfiguration("DropSite") - << this->CTest->GetCTestConfiguration("DropLocation") << std::endl); + << this->CTest->GetCTestConfiguration("DropLocation") << std::endl, + this->Quiet); if ( !this->SubmitUsingHTTP(buildDirectory + "/Testing/" + this->CTest->GetCurrentTag(), files, prefix, url) ) { @@ -1507,11 +1521,10 @@ int cmCTestSubmitHandler::ProcessHandler() } if(!this->CDash) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method" - << std::endl - << " Trigger site: " + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Using HTTP trigger method" << std::endl << " Trigger site: " << this->CTest->GetCTestConfiguration("TriggerSite") - << std::endl); + << std::endl, this->Quiet); if ( !this-> TriggerUsingHTTP(files, prefix, this->CTest->GetCTestConfiguration("TriggerSite"))) @@ -1530,8 +1543,10 @@ int cmCTestSubmitHandler::ProcessHandler() } else { - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" << - (this->HasWarnings ? ", with warnings." : "") << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Submission successful" << + (this->HasWarnings ? ", with warnings." : "") << std::endl, + this->Quiet); ofs << " Submission successful" << (this->HasWarnings ? ", with warnings." : "") << std::endl; } @@ -1542,8 +1557,8 @@ int cmCTestSubmitHandler::ProcessHandler() { #if defined(CTEST_USE_XMLRPC) ofs << "Using drop method: XML-RPC" << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using XML-RPC submit method" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Using XML-RPC submit method" << std::endl, this->Quiet); std::string url = this->CTest->GetCTestConfiguration("DropSite"); prefix = this->CTest->GetCTestConfiguration("DropLocation"); if ( !this->SubmitUsingXMLRPC(buildDirectory + "/Testing/" + @@ -1554,8 +1569,8 @@ int cmCTestSubmitHandler::ProcessHandler() ofs << " Problems when submitting via XML-RPC" << std::endl; return -1; } - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful" + << std::endl, this->Quiet); ofs << " Submission successful" << std::endl; return 0; #else @@ -1593,8 +1608,8 @@ int cmCTestSubmitHandler::ProcessHandler() return -1; } cmSystemTools::ChangeDirectory(oldWorkingDirectory); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful" + << std::endl, this->Quiet); ofs << " Submission successful" << std::endl; return 0; } @@ -1609,8 +1624,8 @@ int cmCTestSubmitHandler::ProcessHandler() std::string oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(buildDirectory); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Change directory: " - << buildDirectory << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + " Change directory: " << buildDirectory << std::endl, this->Quiet); if ( !this->SubmitUsingCP( "Testing/"+this->CTest->GetCurrentTag(), @@ -1626,8 +1641,8 @@ int cmCTestSubmitHandler::ProcessHandler() return -1; } cmSystemTools::ChangeDirectory(oldWorkingDirectory); - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful" - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Submission successful" + << std::endl, this->Quiet); ofs << " Submission successful" << std::endl; return 0; } diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index d209094..8b357ac 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -103,6 +103,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() { this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]); } + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 925e3c9..0e84fbf 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -527,10 +527,10 @@ int cmCTestTestHandler::ProcessHandler() this->TestResults.clear(); - cmCTestLog(this->CTest, HANDLER_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, (this->MemCheck ? "Memory check" : "Test") << " project " << cmSystemTools::GetCurrentWorkingDirectory() - << std::endl); + << std::endl, this->Quiet); if ( ! this->PreProcessHandler() ) { return -1; @@ -567,13 +567,13 @@ int cmCTestTestHandler::ProcessHandler() if (this->HandlerVerbose && !passed.empty() && (this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag)) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl - << "The following tests passed:" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl + << "The following tests passed:" << std::endl, this->Quiet); for(std::vector<std::string>::iterator j = passed.begin(); j != passed.end(); ++j) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\t" << *j + << std::endl, this->Quiet); } } @@ -593,8 +593,8 @@ int cmCTestTestHandler::ProcessHandler() } char realBuf[1024]; sprintf(realBuf, "%6.2f sec", (double)(clock_finish - clock_start)); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nTotal Test time (real) = " - << realBuf << "\n" ); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + "\nTotal Test time (real) = " << realBuf << "\n", this->Quiet ); if (!failed.empty()) { @@ -614,11 +614,11 @@ int cmCTestTestHandler::ProcessHandler() if ( ftit->Status != cmCTestTestHandler::COMPLETED ) { ofs << ftit->TestCount << ":" << ftit->Name << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3) + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\t" << std::setw(3) << ftit->TestCount << " - " << ftit->Name << " (" << this->GetTestStatus(ftit->Status) << ")" - << std::endl); + << std::endl, this->Quiet); } } } @@ -700,7 +700,8 @@ void cmCTestTestHandler::PrintLabelSummary() // now print times if(!labels.empty()) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\nLabel Time Summary:", + this->Quiet); } for(std::set<std::string>::const_iterator i = labels.begin(); i != labels.end(); ++i) @@ -709,8 +710,8 @@ void cmCTestTestHandler::PrintLabelSummary() label.resize(maxlen +3, ' '); char buf[1024]; sprintf(buf, "%6.2f sec", labelTimes[*i]); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "\n" - << label << " = " << buf ); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n" + << label << " = " << buf, this->Quiet ); if ( this->LogFile ) { *this->LogFile << "\n" << *i << " = " @@ -723,7 +724,7 @@ void cmCTestTestHandler::PrintLabelSummary() { *this->LogFile << "\n"; } - cmCTestLog(this->CTest, HANDLER_OUTPUT, "\n"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "\n", this->Quiet); } } @@ -1063,6 +1064,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string> &passed, parallel->SetCTest(this->CTest); parallel->SetParallelLevel(this->CTest->GetParallelLevel()); parallel->SetTestHandler(this); + parallel->SetQuiet(this->Quiet); *this->LogFile << "Start testing: " << this->CTest->CurrentTime() << std::endl @@ -1334,8 +1336,8 @@ int cmCTestTestHandler::ExecuteCommands(std::vector<std::string>& vec) for ( it = vec.begin(); it != vec.end(); ++it ) { int retVal = 0; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << *it - << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Run command: " << + *it << std::endl, this->Quiet); if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0, cmSystemTools::OUTPUT_MERGE /*this->Verbose*/) || retVal != 0 ) @@ -1541,8 +1543,7 @@ std::string cmCTestTestHandler for(std::vector<std::string>::iterator i = failed.begin(); i != failed.end(); ++i) { - cmCTestLog(ctest, HANDLER_OUTPUT, - i->c_str() << "\n"); + cmCTestLog(ctest, HANDLER_OUTPUT, i->c_str() << "\n"); } } @@ -1571,8 +1572,8 @@ void cmCTestTestHandler::GetListOfTests() { this->ExcludeTestsRegularExpression.compile(this->ExcludeRegExp.c_str()); } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Constructing a list of tests" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Constructing a list of tests" << std::endl, this->Quiet); cmake cm; cmGlobalGenerator gg; gg.SetCMakeInstance(&cm); @@ -1628,8 +1629,8 @@ void cmCTestTestHandler::GetListOfTests() { return; } - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Done constructing a list of tests" << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Done constructing a list of tests" << std::endl, this->Quiet); } //---------------------------------------------------------------------- @@ -2016,8 +2017,8 @@ std::string cmCTestTestHandler::GenerateRegressionImages( << "><Value>File " << filename << " not found</Value></NamedMeasurement>" << std::endl; - cmCTestLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename - << "\" not found." << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "File \"" << filename + << "\" not found." << std::endl, this->Quiet); } cxml.erase(measurementfile.start(), measurementfile.end() - measurementfile.start()); @@ -2265,7 +2266,8 @@ bool cmCTestTestHandler::SetTestsProperties( bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) { const std::string& testname = args[0]; - cmCTestLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Add test: " << args[0] << std::endl, + this->Quiet); if (this->UseExcludeRegExpFlag && this->UseExcludeRegExpFirst && @@ -2288,8 +2290,8 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) } if ( found ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore memcheck: " - << *it << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Ignore memcheck: " << *it << std::endl, this->Quiet); return true; } } @@ -2308,8 +2310,8 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) } if ( found ) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: " - << *it << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Ignore test: " + << *it << std::endl, this->Quiet); return true; } } @@ -2318,8 +2320,8 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args) test.Name = testname; test.Args = args; test.Directory = cmSystemTools::GetCurrentWorkingDirectory(); - cmCTestLog(this->CTest, DEBUG, "Set test directory: " - << test.Directory << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Set test directory: " + << test.Directory << std::endl, this->Quiet); test.IsInBasedOnREOptions = true; test.WillFail = false; diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index f87466d..dfda9f1 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -20,55 +20,56 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() { this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( - this->Values[ct_SOURCE]).c_str()); + this->Values[ct_SOURCE]).c_str(), this->Quiet); } else { this->CTest->SetCTestConfiguration("SourceDirectory", cmSystemTools::CollapseFullPath( - this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str()); + this->Makefile->GetDefinition("CTEST_SOURCE_DIRECTORY")).c_str(), + this->Quiet); } std::string source_dir = this->CTest->GetCTestConfiguration("SourceDirectory"); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "UpdateCommand", "CTEST_UPDATE_COMMAND"); + "UpdateCommand", "CTEST_UPDATE_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "UpdateOptions", "CTEST_UPDATE_OPTIONS"); + "UpdateOptions", "CTEST_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "CVSCommand", "CTEST_CVS_COMMAND"); + "CVSCommand", "CTEST_CVS_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS"); + "CVSUpdateOptions", "CTEST_CVS_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "SVNCommand", "CTEST_SVN_COMMAND"); + "SVNCommand", "CTEST_SVN_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS"); + "SVNUpdateOptions", "CTEST_SVN_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "SVNOptions", "CTEST_SVN_OPTIONS"); + "SVNOptions", "CTEST_SVN_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "BZRCommand", "CTEST_BZR_COMMAND"); + "BZRCommand", "CTEST_BZR_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS"); + "BZRUpdateOptions", "CTEST_BZR_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "GITCommand", "CTEST_GIT_COMMAND"); + "GITCommand", "CTEST_GIT_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS"); + "GITUpdateOptions", "CTEST_GIT_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM"); + "GITUpdateCustom", "CTEST_GIT_UPDATE_CUSTOM", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY"); + "UpdateVersionOnly", "CTEST_UPDATE_VERSION_ONLY", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "HGCommand", "CTEST_HG_COMMAND"); + "HGCommand", "CTEST_HG_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS"); + "HGUpdateOptions", "CTEST_HG_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "P4Command", "CTEST_P4_COMMAND"); + "P4Command", "CTEST_P4_COMMAND", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "P4UpdateOptions", "CTEST_P4_UPDATE_OPTIONS"); + "P4UpdateOptions", "CTEST_P4_UPDATE_OPTIONS", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "P4Client", "CTEST_P4_CLIENT"); + "P4Client", "CTEST_P4_CLIENT", this->Quiet); this->CTest->SetCTestConfigurationFromCMakeVariable(this->Makefile, - "P4Options", "CTEST_P4_OPTIONS"); + "P4Options", "CTEST_P4_OPTIONS", this->Quiet); cmCTestGenericHandler* handler = this->CTest->GetInitializedHandler("update"); @@ -84,6 +85,7 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() return 0; } handler->SetOption("SourceDirectory", source_dir.c_str()); + handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx index 4c37c8b..b9da8a0 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -72,37 +72,37 @@ public: cmCTestUpdateHandlerLocale(); ~cmCTestUpdateHandlerLocale(); private: - std::string saveLCMessages; + std::string saveLCAll; }; cmCTestUpdateHandlerLocale::cmCTestUpdateHandlerLocale() { - const char* lcmess = cmSystemTools::GetEnv("LC_MESSAGES"); - if(lcmess) + const char* lcall = cmSystemTools::GetEnv("LC_ALL"); + if(lcall) { - saveLCMessages = lcmess; + saveLCAll = lcall; } - // if LC_MESSAGES is not set to C, then + // if LC_ALL is not set to C, then // set it, so that svn/cvs info will be in english ascii - if(! (lcmess && strcmp(lcmess, "C") == 0)) + if(! (lcall && strcmp(lcall, "C") == 0)) { - cmSystemTools::PutEnv("LC_MESSAGES=C"); + cmSystemTools::PutEnv("LC_ALL=C"); } } cmCTestUpdateHandlerLocale::~cmCTestUpdateHandlerLocale() { - // restore the value of LC_MESSAGES after running the version control + // restore the value of LC_ALL after running the version control // commands - if(!saveLCMessages.empty()) + if(!saveLCAll.empty()) { - std::string put = "LC_MESSAGES="; - put += saveLCMessages; + std::string put = "LC_ALL="; + put += saveLCAll; cmSystemTools::PutEnv(put); } else { - cmSystemTools::UnsetEnv("LC_MESSAGES"); + cmSystemTools::UnsetEnv("LC_ALL"); } } @@ -122,11 +122,13 @@ void cmCTestUpdateHandler::Initialize() //---------------------------------------------------------------------- int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type) { - cmCTestLog(this->CTest, DEBUG, "Determine update type from command: " << cmd - << " and type: " << type << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, + "Determine update type from command: " << cmd << " and type: " << type << + std::endl, this->Quiet); if ( type && *type ) { - cmCTestLog(this->CTest, DEBUG, "Type specified: " << type << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Type specified: " << type << + std::endl, this->Quiet); std::string stype = cmSystemTools::LowerCase(type); if ( stype.find("cvs") != std::string::npos ) { @@ -155,8 +157,8 @@ int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type) } else { - cmCTestLog(this->CTest, DEBUG, "Type not specified, check command: " - << cmd << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, + "Type not specified, check command: " << cmd << std::endl, this->Quiet); std::string stype = cmSystemTools::LowerCase(cmd); if ( stype.find("cvs") != std::string::npos ) { @@ -211,18 +213,19 @@ int cmCTestUpdateHandler::ProcessHandler() this->StartLogFile("Update", ofs); } - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Updating the repository: " - << sourceDirectory << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Updating the repository: " << sourceDirectory << std::endl, + this->Quiet); if(!this->SelectVCS()) { return -1; } - cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use " + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, " Use " << cmCTestUpdateHandlerUpdateToString(this->UpdateType) << " repository type" - << std::endl;); + << std::endl;, this->Quiet); // Create an object to interact with the VCS tool. cmsys::auto_ptr<cmCTestVC> vc; @@ -283,23 +286,23 @@ int cmCTestUpdateHandler::ProcessHandler() int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated); if(numUpdated) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Found " << numUpdated << " updated files\n"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Found " << numUpdated << " updated files\n", this->Quiet); } if(int numModified = vc->GetPathCount(cmCTestVC::PathModified)) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Found " << numModified << " locally modified files\n"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Found " << numModified << " locally modified files\n", this->Quiet); localModifications += numModified; } if(int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting)) { - cmCTestLog(this->CTest, HANDLER_OUTPUT, - " Found " << numConflicting << " conflicting files\n"); + cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, + " Found " << numConflicting << " conflicting files\n", this->Quiet); localModifications += numConflicting; } - cmCTestLog(this->CTest, DEBUG, "End" << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, this->Quiet); std::string end_time = this->CTest->CurrentTime(); os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n" << "\t<EndTime>" << static_cast<unsigned int>(cmSystemTools::GetTime()) @@ -331,8 +334,8 @@ int cmCTestUpdateHandler::ProcessHandler() int cmCTestUpdateHandler::DetectVCS(const char* dir) { std::string sourceDirectory = dir; - cmCTestLog(this->CTest, DEBUG, "Check directory: " - << sourceDirectory << std::endl); + cmCTestOptionalLog(this->CTest, DEBUG, "Check directory: " + << sourceDirectory << std::endl, this->Quiet); sourceDirectory += "/.svn"; if ( cmSystemTools::FileExists(sourceDirectory.c_str()) ) { diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx index 5613751..f5000dd 100644 --- a/Source/CTest/cmCTestUploadCommand.cxx +++ b/Source/CTest/cmCTestUploadCommand.cxx @@ -26,6 +26,7 @@ cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler() } static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files); + handler->SetQuiet(this->Quiet); return handler; } @@ -38,6 +39,12 @@ bool cmCTestUploadCommand::CheckArgumentKeyword(std::string const& arg) this->ArgumentDoing = ArgumentDoingFiles; return true; } + if(arg == "QUIET") + { + this->ArgumentDoing = ArgumentDoingNone; + this->Quiet = true; + return true; + } return false; } diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx index e33c387..579190a 100644 --- a/Source/CTest/cmCTestUploadHandler.cxx +++ b/Source/CTest/cmCTestUploadHandler.cxx @@ -64,8 +64,8 @@ int cmCTestUploadHandler::ProcessHandler() for ( it = this->Files.begin(); it != this->Files.end(); it ++ ) { - cmCTestLog(this->CTest, OUTPUT, - "\tUpload file: " << *it << std::endl); + cmCTestOptionalLog(this->CTest, OUTPUT, + "\tUpload file: " << *it << std::endl, this->Quiet); ofs << "<File filename=\"" << cmXMLSafe(*it) << "\">\n" << "<Content encoding=\"base64\">\n"; ofs << this->CTest->Base64EncodeFile(*it); diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 85d066b..1edd01f 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -138,12 +138,12 @@ bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files) { size_t i=0; std::string path; - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Found " << files.size() <<" Files" << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Found " << files.size() <<" Files" << std::endl, this->Coverage.Quiet); for(i=0;i<files.size();i++) { - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Reading JSON File " << files[i] << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Reading JSON File " << files[i] << std::endl, this->Coverage.Quiet); if(!this->ReadJSONFile(files[i])) { @@ -157,8 +157,8 @@ bool cmParseBlanketJSCoverage::ReadJSONFile(std::string file) { cmParseBlanketJSCoverage::JSONParser parser (this->Coverage); - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Parsing " << file << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Parsing " << file << std::endl, this->Coverage.Quiet); parser.ParseFile(file); return true; } diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx index 3642308..92bf88e 100644 --- a/Source/CTest/cmParseCacheCoverage.cxx +++ b/Source/CTest/cmParseCacheCoverage.cxx @@ -71,9 +71,9 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles() } if(nothing) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "No coverage found in: " << ci->first - << std::endl); + << std::endl, this->Coverage.Quiet); this->Coverage.TotalCoverage.erase(ci++); } else diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index e19b199..3ed5cb0 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -50,8 +50,8 @@ protected: if (this->InSources && this->InSource) { this->FilePaths.push_back(tmp); - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Adding Source: " - << tmp << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Adding Source: " << tmp << std::endl, this->Coverage.Quiet); } } @@ -74,8 +74,9 @@ protected: { if(strcmp(atts[tagCount], "filename") == 0) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: " - << atts[tagCount+1]<< std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Reading file: " << atts[tagCount+1]<< std::endl, + this->Coverage.Quiet); std::string filename = atts[tagCount+1]; this->CurFileName = ""; @@ -113,9 +114,9 @@ protected: fin.open(this->CurFileName.c_str()); if (!fin) { - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Skipping system file " << filename << - std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Skipping system file " << filename << std::endl, + this->Coverage.Quiet); this->SkipThisClass = true; break; diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index 4dfdfac..e453fe1 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -122,8 +122,9 @@ public: lastoffset = line.find('(',pos); if(lastoffset==line.npos) { - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - endnamepos << "File not found " << lastoffset << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + endnamepos << "File not found " << lastoffset << std::endl, + this->Coverage.Quiet); return false; } endnamepos = line.find(')',lastoffset); @@ -131,8 +132,9 @@ public: (endnamepos-1)-lastoffset); if(filename.find(".pas") != filename.npos) { - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Coverage found for file: " << filename << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Coverage found for file: " << filename << std::endl, + this->Coverage.Quiet); break; } pos = lastoffset+1; @@ -153,8 +155,9 @@ public: * If that doesn't find any matching files * return a failure. */ - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Unable to find file matching" << glob << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Unable to find file matching" << glob << std::endl, + this->Coverage.Quiet); return false; } FileLinesType& coverageVector = @@ -229,8 +232,8 @@ bool cmParseDelphiCoverage::LoadCoverageData( { path = files[i]; - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Reading HTML File " << path << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Reading HTML File " << path << std::endl, this->Coverage.Quiet); if(cmSystemTools::GetFilenameLastExtension(path) == ".html") { if(!this->ReadDelphiHTML(path.c_str())) diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx index 780debc..31ad9fe 100644 --- a/Source/CTest/cmParseJacocoCoverage.cxx +++ b/Source/CTest/cmParseJacocoCoverage.cxx @@ -49,8 +49,9 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser else if(name == "sourcefile") { this->FileName = atts[1]; - cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Reading file: " - << this->FileName << std::endl); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Reading file: " << this->FileName << std::endl, + this->Coverage.Quiet); for(size_t i=0;i < FilePaths.size();i++) { std::string finalpath = FilePaths[i] + "/" + this->FileName; @@ -77,7 +78,10 @@ class cmParseJacocoCoverage::XMLParser: public cmXMLParser std::string line; FileLinesType& curFileLines = this->Coverage.TotalCoverage[this->CurFileName]; - curFileLines.push_back(-1); + if(fin) + { + curFileLines.push_back(-1); + } while(cmSystemTools::GetLineFromStream(fin, line)) { curFileLines.push_back(-1); @@ -148,8 +152,8 @@ bool cmParseJacocoCoverage::LoadCoverageData( { path = files[i]; - cmCTestLog(this->CTest,HANDLER_VERBOSE_OUTPUT, - "Reading XML File " << path << std::endl); + cmCTestOptionalLog(this->CTest,HANDLER_VERBOSE_OUTPUT, + "Reading XML File " << path << std::endl, this->Coverage.Quiet); if(cmSystemTools::GetFilenameLastExtension(path) == ".xml") { if(!this->ReadJacocoXML(path.c_str())) diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index dcd0b6c..d60062e 100644 --- a/Source/CursesDialog/cmCursesMainForm.cxx +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -22,6 +22,7 @@ #include "cmCursesDummyWidget.h" #include "cmCursesCacheEntryComposite.h" #include "cmCursesLongMessageForm.h" +#include "cmAlgorithms.h" inline int ctrl(int z) diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index b59af94..9cc993a 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -45,11 +45,11 @@ if (Qt5Widgets_FOUND) get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME) get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH) get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME) - set(_qt_plugin_dest "${CMAKE_INSTALL_PREFIX}/PlugIns/${_qt_plugin_type}") + set(_qt_plugin_dest "PlugIns/${_qt_plugin_type}") install(FILES "${_qt_plugin_path}" DESTINATION "${_qt_plugin_dest}") set(${_qt_plugins_var} - "${${_qt_plugins_var}};${_qt_plugin_dest}/${_qt_plugin_file}") + "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}") else() message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found") endif() diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 82fa3a3..8a72a24 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -149,10 +149,10 @@ int main(int argc, char** argv) QStringList args = app.arguments(); if(args.count() == 2) { - cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data()); + std::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data()); // check if argument is a directory containing CMakeCache.txt - cmsys_stl::string buildFilePath = + std::string buildFilePath = cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str()); // check if argument is a CMakeCache.txt file @@ -163,7 +163,7 @@ int main(int argc, char** argv) } // check if argument is a directory containing CMakeLists.txt - cmsys_stl::string srcFilePath = + std::string srcFilePath = cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str()); if(cmSystemTools::FileExists(buildFilePath.c_str())) diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index b560452..3a74946 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -33,15 +33,6 @@ bool cmAddDependenciesCommand } if(cmTarget* target = this->Makefile->FindTargetToUse(target_name)) { - if (target->GetType() == cmTarget::INTERFACE_LIBRARY) - { - std::ostringstream e; - e << "Cannot add target-level dependencies to INTERFACE library " - "target \"" << target_name << "\".\n"; - this->SetError(e.str()); - return false; - } - std::vector<std::string>::const_iterator s = args.begin(); ++s; // skip over target_name for (; s != args.end(); ++s) diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index db2f6fb..edf82bd 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -435,11 +435,7 @@ bool cmAddLibraryCommand cmSystemTools::Message(msg.c_str() ,"Warning"); } - while (s != args.end()) - { - srclists.push_back(*s); - ++s; - } + srclists.insert(srclists.end(), s, args.end()); this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll); diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index 01598bc..9d55c1a 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -122,7 +122,7 @@ bool cmAddSubDirectoryCommand::InitialPass // Add the subdirectory using the computed full paths. this->Makefile->AddSubDirectory(srcPath, binPath, - excludeFromAll, false, true); + excludeFromAll, true); return true; } diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h new file mode 100644 index 0000000..f117475 --- /dev/null +++ b/Source/cmAlgorithms.h @@ -0,0 +1,360 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmAlgorithms_h +#define cmAlgorithms_h + +#include "cmStandardIncludes.h" + +inline bool cmHasLiteralPrefixImpl(const std::string &str1, + const char *str2, + size_t N) +{ + return strncmp(str1.c_str(), str2, N) == 0; +} + +inline bool cmHasLiteralPrefixImpl(const char* str1, + const char *str2, + size_t N) +{ + return strncmp(str1, str2, N) == 0; +} + +inline bool cmHasLiteralSuffixImpl(const std::string &str1, + const char *str2, + size_t N) +{ + size_t len = str1.size(); + return len >= N && strcmp(str1.c_str() + len - N, str2) == 0; +} + +inline bool cmHasLiteralSuffixImpl(const char* str1, + const char* str2, + size_t N) +{ + size_t len = strlen(str1); + return len >= N && strcmp(str1 + len - N, str2) == 0; +} + +template<typename T, size_t N> +const T* cmArrayBegin(const T (&a)[N]) { return a; } +template<typename T, size_t N> +const T* cmArrayEnd(const T (&a)[N]) { return a + N; } +template<typename T, size_t N> +size_t cmArraySize(const T (&)[N]) { return N; } + +template<typename T, size_t N> +bool cmHasLiteralPrefix(T str1, const char (&str2)[N]) +{ + return cmHasLiteralPrefixImpl(str1, str2, N - 1); +} + +template<typename T, size_t N> +bool cmHasLiteralSuffix(T str1, const char (&str2)[N]) +{ + return cmHasLiteralSuffixImpl(str1, str2, N - 1); +} + +struct cmStrCmp { + cmStrCmp(const char *test) : m_test(test) {} + cmStrCmp(const std::string &test) : m_test(test) {} + + bool operator()(const std::string& input) const + { + return m_test == input; + } + + bool operator()(const char * input) const + { + return strcmp(input, m_test.c_str()) == 0; + } + +private: + const std::string m_test; +}; + +template<typename FwdIt> +FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) +{ + const typename std::iterator_traits<FwdIt>::difference_type dist = + std::distance(middle, last); + std::rotate(first, middle, last); + std::advance(first, dist); + return first; +} + +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 Range, + bool valueTypeIsPair = cmIsPair<typename Range::value_type>::value> +struct DefaultDeleter +{ + void operator()(typename Range::value_type value) const { + delete value; + } +}; + +template<typename Range> +struct DefaultDeleter<Range, /* valueTypeIsPair = */ true> +{ + void operator()(typename Range::value_type value) const { + delete value.second; + } +}; + +template<typename const_iterator_> +struct Range +{ + typedef const_iterator_ const_iterator; + typedef typename std::iterator_traits<const_iterator>::value_type value_type; + typedef typename std::iterator_traits<const_iterator>::difference_type + difference_type; + Range(const_iterator begin_, const_iterator end_) + : Begin(begin_), End(end_) {} + const_iterator begin() const { return Begin; } + const_iterator end() const { return End; } + bool empty() const { return std::distance(Begin, End) == 0; } + difference_type size() const { return std::distance(Begin, End); } + Range& advance(cmIML_INT_intptr_t amount) + { + std::advance(Begin, amount); + return *this; + } + + Range& retreat(cmIML_INT_intptr_t amount) + { + std::advance(End, -amount); + return *this; + } +private: + const_iterator Begin; + const_iterator End; +}; + +template<typename FwdIt> +FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n) +{ + FwdIt m = i1; + std::advance(m, n); + return cmRotate(i1, m, i2); +} + +template<typename Range> +struct BinarySearcher +{ + typedef typename Range::value_type argument_type; + BinarySearcher(Range const& r) + : m_range(r) + { + } + + bool operator()(argument_type const& item) const + { + return std::binary_search(m_range.begin(), m_range.end(), item); + } +private: + Range const& m_range; +}; + +} + +template<typename Iter1, typename Iter2> +ContainerAlgorithms::Range<Iter1> cmRange(Iter1 begin, Iter2 end) +{ + return ContainerAlgorithms::Range<Iter1>(begin, end); +} + +template<typename Range> +ContainerAlgorithms::Range<typename Range::const_iterator> +cmRange(Range const& range) +{ + return ContainerAlgorithms::Range<typename Range::const_iterator>( + range.begin(), range.end()); +} + +template<typename Range> +void cmDeleteAll(Range const& r) +{ + std::for_each(r.begin(), r.end(), + ContainerAlgorithms::DefaultDeleter<Range>()); +} + +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; + const 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()); +}; + +template<typename Range> +typename Range::const_iterator cmRemoveN(Range& r, size_t n) +{ + return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n); +} + +template<typename Range, typename InputRange> +typename Range::const_iterator cmRemoveIndices(Range& r, InputRange const& rem) +{ + typename InputRange::const_iterator remIt = rem.begin(); + typename InputRange::const_iterator remEnd = rem.end(); + const typename Range::iterator rangeEnd = r.end(); + if (remIt == remEnd) + { + return rangeEnd; + } + + typename Range::iterator writer = r.begin(); + std::advance(writer, *remIt); + typename Range::iterator pivot = writer; + typename InputRange::value_type prevRem = *remIt; + ++remIt; + size_t count = 1; + for ( ; writer != rangeEnd && remIt != remEnd; ++count, ++remIt) + { + std::advance(pivot, *remIt - prevRem); + prevRem = *remIt; + writer = ContainerAlgorithms::RemoveN(writer, pivot, count); + } + return ContainerAlgorithms::RemoveN(writer, rangeEnd, count); +} + +template<typename Range, typename MatchRange> +typename Range::const_iterator cmRemoveMatching(Range &r, MatchRange const& m) +{ + return std::remove_if(r.begin(), r.end(), + ContainerAlgorithms::BinarySearcher<MatchRange>(m)); +} + +namespace ContainerAlgorithms { + +template<typename Range, typename T = typename Range::value_type> +struct RemoveDuplicatesAPI +{ + typedef typename Range::const_iterator const_iterator; + typedef typename Range::const_iterator value_type; + + static bool lessThan(value_type a, value_type b) { return *a < *b; } + static value_type uniqueValue(const_iterator a) { return a; } + template<typename It> + static bool valueCompare(It it, const_iterator it2) { return **it != *it2; } +}; + +template<typename Range, typename T> +struct RemoveDuplicatesAPI<Range, T*> +{ + typedef typename Range::const_iterator const_iterator; + typedef T* value_type; + + static bool lessThan(value_type a, value_type b) { return a < b; } + static value_type uniqueValue(const_iterator a) { return *a; } + template<typename It> + static bool valueCompare(It it, const_iterator it2) { return *it != *it2; } +}; + +} + +template<typename Range> +typename Range::const_iterator cmRemoveDuplicates(Range& r) +{ + typedef typename ContainerAlgorithms::RemoveDuplicatesAPI<Range> API; + typedef typename API::value_type T; + std::vector<T> unique; + unique.reserve(r.size()); + std::vector<size_t> indices; + size_t count = 0; + const typename Range::const_iterator end = r.end(); + for(typename Range::const_iterator it = r.begin(); + it != end; ++it, ++count) + { + const typename std::vector<T>::iterator low = + std::lower_bound(unique.begin(), unique.end(), + API::uniqueValue(it), API::lessThan); + if (low == unique.end() || API::valueCompare(low, it)) + { + unique.insert(low, API::uniqueValue(it)); + } + else + { + indices.push_back(count); + } + } + if (indices.empty()) + { + return end; + } + return cmRemoveIndices(r, indices); +} + +template<typename Range> +std::string cmWrap(std::string prefix, Range const& r, std::string suffix, + std::string sep) +{ + if (r.empty()) + { + return std::string(); + } + return prefix + cmJoin(r, (suffix + sep + prefix).c_str()) + suffix; +} + +template<typename Range> +std::string cmWrap(char prefix, Range const& r, char suffix, std::string sep) +{ + return cmWrap(std::string(1, prefix), r, std::string(1, suffix), sep); +} + +template<typename Range, typename T> +typename Range::const_iterator cmFindNot(Range const& r, T const& t) +{ + return std::find_if(r.begin(), r.end(), + std::bind1st(std::not_equal_to<T>(), t)); +} + +template<typename Range> +ContainerAlgorithms::Range<typename Range::const_reverse_iterator> +cmReverseRange(Range const& range) +{ + return ContainerAlgorithms::Range<typename Range::const_reverse_iterator>( + range.rbegin(), range.rend()); +} + +#endif diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index a30d992..b8238f8 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -26,7 +26,6 @@ bool cmAuxSourceDirectoryCommand::InitialPass std::string sourceListValue; std::string templateDirectory = args[0]; - this->Makefile->AddExtraDirectory(templateDirectory.c_str()); std::string tdir; if(!cmSystemTools::FileIsFullPath(templateDirectory.c_str())) { diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index d0dc30a..691d80d 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -438,15 +438,14 @@ void CCONV cmExpandSourceListArguments(void *arg, char ***resArgv, unsigned int startArgumentIndex) { - cmMakefile *mf = static_cast<cmMakefile *>(arg); + (void)arg; + (void)startArgumentIndex; std::vector<std::string> result; - std::vector<std::string> args2; int i; for (i = 0; i < numArgs; ++i) { - args2.push_back(args[i]); + result.push_back(args[i]); } - mf->ExpandSourceListArguments(args2, result, startArgumentIndex); int resargc = static_cast<int>(result.size()); char **resargv = 0; if (resargc) diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index f08b87c..df61fe6 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -26,6 +26,7 @@ #include "cmVersionMacros.h" #include "cmCTestCommand.h" #include "cmCTestStartCommand.h" +#include "cmAlgorithms.h" #include "cmCTestBuildHandler.h" #include "cmCTestBuildAndTestHandler.h" @@ -328,6 +329,8 @@ cmCTest::cmCTest() this->OutputTestOutputOnTestFailure = false; this->ComputedCompressTestOutput = false; this->ComputedCompressMemCheckOutput = false; + this->RepeatTests = 1; // default to run each test once + this->RepeatUntilFail = false; if(cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE")) { this->OutputTestOutputOnTestFailure = true; @@ -463,7 +466,13 @@ cmCTest::Part cmCTest::GetPartFromName(const char* name) //---------------------------------------------------------------------- int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) { - cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); + bool quiet = false; + if (command && command->ShouldBeQuiet()) + { + quiet = true; + } + + cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); if(!this->InteractiveDebugMode) { this->BlockTestErrorDiagnostics(); @@ -478,24 +487,23 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) this->UpdateCTestConfiguration(); - cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); + cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); if ( this->ProduceXML ) { - cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); - cmCTestLog(this, OUTPUT, - " Site: " << this->GetCTestConfiguration("Site") << std::endl - << " Build name: " - << cmCTest::SafeBuildIdField( - this->GetCTestConfiguration("BuildName")) - << std::endl); - cmCTestLog(this, DEBUG, "Produce XML is on" << std::endl); + cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); + cmCTestOptionalLog(this, OUTPUT, + " Site: " << this->GetCTestConfiguration("Site") << std::endl << + " Build name: " << cmCTest::SafeBuildIdField( + this->GetCTestConfiguration("BuildName")) << std::endl, quiet); + cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet); if ( this->TestModel == cmCTest::NIGHTLY && this->GetCTestConfiguration("NightlyStartTime").empty() ) { - cmCTestLog(this, WARNING, - "WARNING: No nightly start time found please set in" - " CTestConfig.cmake or DartConfig.cmake" << std::endl); - cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl); + cmCTestOptionalLog(this, WARNING, + "WARNING: No nightly start time found please set in CTestConfig.cmake" + " or DartConfig.cmake" << std::endl, quiet); + cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, + quiet); return 0; } } @@ -507,8 +515,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) cmMakefile *mf = lg->GetMakefile(); if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), mf) ) { - cmCTestLog(this, DEBUG, "Cannot find custom configuration file tree" - << std::endl); + cmCTestOptionalLog(this, DEBUG, + "Cannot find custom configuration file tree" << std::endl, quiet); return 0; } @@ -583,9 +591,10 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } if (tag.empty() || (0 != command) || this->Parts[PartStart]) { - cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString() - << std::endl); - cmCTestLog(this, DEBUG, "TestModel: " << this->TestModel << std::endl); + cmCTestOptionalLog(this, DEBUG, "TestModel: " << + this->GetTestModelString() << std::endl, quiet); + cmCTestOptionalLog(this, DEBUG, "TestModel: " << + this->TestModel << std::endl, quiet); if ( this->TestModel == cmCTest::NIGHTLY ) { lctime = this->GetNightlyTime( @@ -609,8 +618,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) ofs.close(); if ( 0 == command ) { - cmCTestLog(this, OUTPUT, "Create new tag: " << tag << " - " - << this->GetTestModelString() << std::endl); + cmCTestOptionalLog(this, OUTPUT, "Create new tag: " << tag << " - " + << this->GetTestModelString() << std::endl, quiet); } } } @@ -630,8 +639,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) return 0; } - cmCTestLog(this, OUTPUT, " Use existing tag: " << tag << " - " - << this->GetTestModelString() << std::endl); + cmCTestOptionalLog(this, OUTPUT, " Use existing tag: " << tag << " - " + << this->GetTestModelString() << std::endl, quiet); } this->CurrentTag = tag; @@ -675,8 +684,8 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) if ( !fname.empty() ) { - cmCTestLog(this, OUTPUT, " Reading ctest configuration file: " - << fname << std::endl); + cmCTestOptionalLog(this, OUTPUT, " Reading ctest configuration file: " + << fname << std::endl, command->ShouldBeQuiet()); bool readit = mf->ReadListFile(mf->GetCurrentListFile(), fname.c_str() ); if(!readit) @@ -689,19 +698,20 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) } else { - cmCTestLog(this, WARNING, + cmCTestOptionalLog(this, WARNING, "Cannot locate CTest configuration: in BuildDirectory: " - << bld_dir_fname << std::endl); - cmCTestLog(this, WARNING, + << bld_dir_fname << std::endl, command->ShouldBeQuiet()); + cmCTestOptionalLog(this, WARNING, "Cannot locate CTest configuration: in SourceDirectory: " - << src_dir_fname << std::endl); + << src_dir_fname << std::endl, command->ShouldBeQuiet()); } this->SetCTestConfigurationFromCMakeVariable(mf, "NightlyStartTime", - "CTEST_NIGHTLY_START_TIME"); - this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE"); + "CTEST_NIGHTLY_START_TIME", command->ShouldBeQuiet()); + this->SetCTestConfigurationFromCMakeVariable(mf, "Site", "CTEST_SITE", + command->ShouldBeQuiet()); this->SetCTestConfigurationFromCMakeVariable(mf, "BuildName", - "CTEST_BUILD_NAME"); + "CTEST_BUILD_NAME", command->ShouldBeQuiet()); const char* dartVersion = mf->GetDefinition("CTEST_DART_SERVER_VERSION"); if ( dartVersion ) { @@ -720,8 +730,9 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) { return false; } - cmCTestLog(this, OUTPUT, " Use " << this->GetTestModelString() - << " tag: " << this->GetCurrentTag() << std::endl); + cmCTestOptionalLog(this, OUTPUT, " Use " << this->GetTestModelString() + << " tag: " << this->GetCurrentTag() << std::endl, + command->ShouldBeQuiet()); return true; } @@ -1332,16 +1343,21 @@ int cmCTest::RunTest(std::vector<const char*> argv, } *retVal = inst.Run(args, output); - *output += oss.str(); - if ( log ) + if(output) + { + *output += oss.str(); + } + if ( log && output) { *log << *output; } cmSystemTools::ChangeDirectory(oldpath); - - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "Internal cmCTest object used to run test." << std::endl - << *output << std::endl); + if(output) + { + cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, + "Internal cmCTest object used to run test." << std::endl + << *output << std::endl); + } return cmsysProcess_State_Exited; } @@ -1411,7 +1427,10 @@ int cmCTest::RunTest(std::vector<const char*> argv, *retVal = cmsysProcess_GetExitException(cp); std::string outerr = "\n*** Exception executing: "; outerr += cmsysProcess_GetExceptionString(cp); - *output += outerr; + if(output) + { + *output += outerr; + } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl << std::flush); } @@ -1419,7 +1438,10 @@ int cmCTest::RunTest(std::vector<const char*> argv, { std::string outerr = "\n*** ERROR executing: "; outerr += cmsysProcess_GetErrorString(cp); - *output += outerr; + if(output) + { + *output += outerr; + } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr.c_str() << std::endl << std::flush); } @@ -1975,11 +1997,11 @@ bool cmCTest::CheckArgument(const std::string& arg, const char* varg1, //---------------------------------------------------------------------- // Processes one command line argument (and its arguments if any) // for many simple options and then returns -void cmCTest::HandleCommandLineArguments(size_t &i, - std::vector<std::string> &args) +bool cmCTest::HandleCommandLineArguments(size_t &i, + std::vector<std::string> &args, + std::string& errormsg) { std::string arg = args[i]; - if(this->CheckArgument(arg, "-F")) { this->Failover = true; @@ -1997,6 +2019,27 @@ void cmCTest::HandleCommandLineArguments(size_t &i, this->SetParallelLevel(plevel); this->ParallelLevelSetInCli = true; } + if(this->CheckArgument(arg, "--repeat-until-fail")) + { + if( i >= args.size() - 1) + { + errormsg = "'--repeat-until-fail' requires an argument"; + return false; + } + i++; + long repeat = 1; + if(!cmSystemTools::StringToLong(args[i].c_str(), &repeat)) + { + errormsg = "'--repeat-until-fail' given non-integer value '" + + args[i] + "'"; + return false; + } + this->RepeatTests = static_cast<int>(repeat); + if(repeat > 1) + { + this->RepeatUntilFail = true; + } + } if(this->CheckArgument(arg, "--no-compress-output")) { @@ -2182,6 +2225,7 @@ void cmCTest::HandleCommandLineArguments(size_t &i, this->GetHandler("test")->SetPersistentOption("RerunFailed", "true"); this->GetHandler("memcheck")->SetPersistentOption("RerunFailed", "true"); } + return true; } //---------------------------------------------------------------------- @@ -2256,16 +2300,20 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output) bool SRArgumentSpecified = false; // copy the command line - for(size_t i=0; i < args.size(); ++i) - { - this->InitialCommandLineArguments.push_back(args[i]); - } + this->InitialCommandLineArguments.insert( + this->InitialCommandLineArguments.end(), + args.begin(), args.end()); // process the command line arguments for(size_t i=1; i < args.size(); ++i) { // handle the simple commandline arguments - this->HandleCommandLineArguments(i,args); + std::string errormsg; + if(!this->HandleCommandLineArguments(i,args, errormsg)) + { + cmSystemTools::Error(errormsg.c_str()); + return 1; + } // handle the script arguments -S -SR -SP this->HandleScriptArguments(i,args,SRArgumentSpecified); @@ -2741,10 +2789,11 @@ void cmCTest::DetermineNextDayStop() } //---------------------------------------------------------------------- -void cmCTest::SetCTestConfiguration(const char *name, const char* value) +void cmCTest::SetCTestConfiguration(const char *name, const char* value, + bool suppress) { - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:" - << name << ":" << (value ? value : "(null)") << "\n"); + cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:" + << name << ":" << (value ? value : "(null)") << "\n", suppress); if ( !name ) { @@ -2858,7 +2907,7 @@ void cmCTest::SetConfigType(const char* ct) //---------------------------------------------------------------------- bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf, - const char* dconfig, const std::string& cmake_var) + const char* dconfig, const std::string& cmake_var, bool suppress) { const char* ctvar; ctvar = mf->GetDefinition(cmake_var); @@ -2866,10 +2915,10 @@ bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf, { return false; } - cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, - "SetCTestConfigurationFromCMakeVariable:" - << dconfig << ":" << cmake_var << std::endl); - this->SetCTestConfiguration(dconfig, ctvar); + cmCTestOptionalLog(this, HANDLER_VERBOSE_OUTPUT, + "SetCTestConfigurationFromCMakeVariable:" << dconfig << ":" << + cmake_var << std::endl, suppress); + this->SetCTestConfiguration(dconfig, ctvar, suppress); return true; } @@ -3034,12 +3083,17 @@ void cmCTest::InitStreams() this->StreamErr = &std::cerr; } -void cmCTest::Log(int logType, const char* file, int line, const char* msg) +void cmCTest::Log(int logType, const char* file, int line, const char* msg, + bool suppress) { if ( !msg || !*msg ) { return; } + if ( suppress && logType != cmCTest::ERROR_MESSAGE ) + { + return; + } if ( this->OutputLogFile ) { bool display = true; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index deb8896..3f033d9 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -33,6 +33,14 @@ class cmCTestStartCommand; cmCTestLog_msg.str().c_str());\ } while ( 0 ) +#define cmCTestOptionalLog(ctSelf, logType, msg, suppress) \ + do { \ + std::ostringstream cmCTestLog_msg; \ + cmCTestLog_msg << msg; \ + (ctSelf)->Log(cmCTest::logType, __FILE__, __LINE__,\ + cmCTestLog_msg.str().c_str(), suppress);\ + } while ( 0 ) + #ifdef cerr # undef cerr #endif @@ -173,7 +181,8 @@ public: static int GetTestModelFromString(const char* str); static std::string CleanString(const std::string& str); std::string GetCTestConfiguration(const std::string& name); - void SetCTestConfiguration(const char *name, const char* value); + void SetCTestConfiguration(const char *name, const char* value, + bool suppress=false); void EmptyCTestConfiguration(); /** @@ -332,7 +341,7 @@ public: * Set the CTest variable from CMake variable */ bool SetCTestConfigurationFromCMakeVariable(cmMakefile* mf, - const char* dconfig, const std::string& cmake_var); + const char* dconfig, const std::string& cmake_var, bool suppress=false); //! Make string safe to be send as an URL static std::string MakeURLSafe(const std::string&); @@ -376,7 +385,8 @@ public: }; //! Add log to the output - void Log(int logType, const char* file, int line, const char* msg); + void Log(int logType, const char* file, int line, const char* msg, + bool suppress=false); //! Get the version of dart server int GetDartVersion() { return this->DartVersion; } @@ -419,8 +429,13 @@ public: { return this->Definitions; } - + // return the number of times a test should be run + int GetTestRepeat() { return this->RepeatTests;} + // return true if test should run until fail + bool GetRepeatUntilFail() { return this->RepeatUntilFail;} private: + int RepeatTests; + bool RepeatUntilFail; std::string ConfigType; std::string ScheduleType; std::string StopTime; @@ -525,8 +540,9 @@ private: bool AddVariableDefinition(const std::string &arg); //! parse and process most common command line arguments - void HandleCommandLineArguments(size_t &i, - std::vector<std::string> &args); + bool HandleCommandLineArguments(size_t &i, + std::vector<std::string> &args, + std::string& errormsg); //! hande the -S -SP and -SR arguments void HandleScriptArguments(size_t &i, diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index 45e92ce..0c77891 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -186,11 +186,7 @@ void cmCacheManager::CleanCMakeFiles(const std::string& path) cmsys::Glob globIt; globIt.FindFiles(glob); std::vector<std::string> files = globIt.GetFiles(); - for(std::vector<std::string>::iterator i = files.begin(); - i != files.end(); ++i) - { - cmSystemTools::RemoveFile(*i); - } + std::for_each(files.begin(), files.end(), cmSystemTools::RemoveFile); } bool cmCacheManager::LoadCache(const std::string& path, diff --git a/Source/cmCommands.h b/Source/cmCommands.h index c56673f..e902853 100644 --- a/Source/cmCommands.h +++ b/Source/cmCommands.h @@ -13,6 +13,8 @@ #define cmCommands_h #include "cmStandardIncludes.h" +#include <list> + class cmCommand; /** * Global function to return all compiled in commands. diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 32d5cd3..6005d5f 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -17,6 +17,7 @@ #include "cmMakefile.h" #include "cmTarget.h" #include "cmake.h" +#include "cmAlgorithms.h" #include <cmsys/stl/algorithm> @@ -669,7 +670,7 @@ void cmComputeLinkDepends::InferDependencies() for(++i; i != sets->end(); ++i) { DependSet intersection; - cmsys_stl::set_intersection + std::set_intersection (common.begin(), common.end(), i->begin(), i->end(), std::inserter(intersection, intersection.begin())); common = intersection; @@ -689,11 +690,10 @@ void cmComputeLinkDepends::CleanConstraintGraph() { // Sort the outgoing edges for each graph node so that the // original order will be preserved as much as possible. - cmsys_stl::sort(i->begin(), i->end()); + std::sort(i->begin(), i->end()); // Make the edge list unique. - EdgeList::iterator last = cmsys_stl::unique(i->begin(), i->end()); - i->erase(last, i->end()); + i->erase(std::unique(i->begin(), i->end()), i->end()); } } @@ -706,10 +706,7 @@ void cmComputeLinkDepends::DisplayConstraintGraph() { EdgeList const& nl = this->EntryConstraintGraph[i]; e << "item " << i << " is [" << this->EntryList[i].Item << "]\n"; - for(EdgeList::const_iterator j = nl.begin(); j != nl.end(); ++j) - { - e << " item " << *j << " must follow it\n"; - } + e << cmWrap(" item ", nl, " must follow it", "\n") << "\n"; } fprintf(stderr, "%s\n", e.str().c_str()); } diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 479da75..b0e0f36 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -19,6 +19,7 @@ #include "cmMakefile.h" #include "cmTarget.h" #include "cmake.h" +#include "cmAlgorithms.h" #include <ctype.h> diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index cf2b88e..bbffd5d 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -418,9 +418,11 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, cmTarget const* dependee, bool linking) { - if(dependee->IsImported()) + if(dependee->IsImported() || + dependee->GetType() == cmTarget::INTERFACE_LIBRARY) { - // Skip imported targets but follow their utility dependencies. + // Skip IMPORTED and INTERFACE targets but follow their utility + // dependencies. std::set<cmLinkItem> const& utils = dependee->GetUtilityItems(); for(std::set<cmLinkItem>::const_iterator i = utils.begin(); i != utils.end(); ++i) diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h index 01624f9..fcef234 100644 --- a/Source/cmConditionEvaluator.h +++ b/Source/cmConditionEvaluator.h @@ -15,6 +15,8 @@ #include "cmCommand.h" #include "cmExpandedCommandArgument.h" +#include <list> + class cmConditionEvaluator { public: diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 5b5d6b6..59efa52 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -14,6 +14,7 @@ #include "cmCacheManager.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" +#include "cmAlgorithms.h" #include "cmExportTryCompileFileGenerator.h" #include <cmsys/Directory.hxx> @@ -260,14 +261,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) err << "Unknown extension \"" << ext << "\" for file\n" << " " << *si << "\n" << "try_compile() works only for enabled languages. " - << "Currently these are:\n "; + << "Currently these are:\n "; std::vector<std::string> langs; gg->GetEnabledLanguages(langs); - for(std::vector<std::string>::iterator l = langs.begin(); - l != langs.end(); ++l) - { - err << " " << *l; - } + err << cmJoin(langs, " "); err << "\nSee project() command to enable other languages."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, err.str()); return -1; @@ -296,7 +293,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) cmVersion::GetPatchVersion(), cmVersion::GetTweakVersion()); if(def) { - fprintf(fout, "set(CMAKE_MODULE_PATH %s)\n", def); + fprintf(fout, "set(CMAKE_MODULE_PATH \"%s\")\n", def); } std::string projectLangs; @@ -373,18 +370,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv) // handle any compile flags we need to pass on if (!compileDefs.empty()) { - fprintf(fout, "add_definitions( "); - for (size_t i = 0; i < compileDefs.size(); ++i) - { - fprintf(fout,"%s ",compileDefs[i].c_str()); - } - fprintf(fout, ")\n"); + fprintf(fout, "add_definitions(%s)\n", cmJoin(compileDefs, " ").c_str()); } /* Use a random file name to avoid rapid creation and deletion of the same executable name (some filesystems fail on that). */ - sprintf(targetNameBuf, "cmTryCompileExec%u", - cmSystemTools::RandomSeed()); + sprintf(targetNameBuf, "cmTC_%05x", + cmSystemTools::RandomSeed() & 0xFFFFF); targetName = targetNameBuf; if (!targets.empty()) @@ -685,19 +677,16 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName) command += tmpOutputFile; if(cmSystemTools::FileExists(command.c_str())) { - tmpOutputFile = cmSystemTools::CollapseFullPath(command); - this->OutputFile = tmpOutputFile; + this->OutputFile = cmSystemTools::CollapseFullPath(command); return; } } std::ostringstream emsg; emsg << "Unable to find the executable at any of:\n"; - for (unsigned int i = 0; i < searchDirs.size(); ++i) - { - emsg << " " << this->BinaryDirectory << searchDirs[i] - << tmpOutputFile << "\n"; - } + emsg << cmWrap(" " + this->BinaryDirectory, + searchDirs, + tmpOutputFile, "\n") << "\n"; this->FindErrorMessage = emsg.str(); return; } diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index 6dde349..63d8fa6 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -15,6 +15,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" +#include "cmAlgorithms.h" #include <cmsys/FStream.hxx> #include <ctype.h> // isspace diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index f4e3a75..8c17536 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -14,6 +14,7 @@ #include "cmSystemTools.h" #include "cmVersion.h" #include "cmRST.h" +#include "cmAlgorithms.h" #include <cmsys/Directory.hxx> #include <cmsys/Glob.hxx> diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index a28ec48..b1203dd 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -68,16 +68,6 @@ 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(); @@ -87,6 +77,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te, cmGeneratorExpression::BuildInterface, properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_SOURCES", te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te, cmGeneratorExpression::BuildInterface, properties, missingTargets); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index af4ce8b..b4fad98 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -22,6 +22,7 @@ #include "cmTargetExport.h" #include "cmVersion.h" #include "cmComputeLinkInformation.h" +#include "cmAlgorithms.h" #include <cmsys/auto_ptr.hxx> #include <cmsys/FStream.hxx> @@ -224,7 +225,7 @@ static bool isSubDirectory(const char* a, const char* b) //---------------------------------------------------------------------------- static bool checkInterfaceDirs(const std::string &prepro, - cmTarget *target) + cmTarget *target, const std::string& prop) { const char* installDir = target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); @@ -250,20 +251,27 @@ static bool checkInterfaceDirs(const std::string &prepro, std::ostringstream e; if (genexPos != std::string::npos) { - switch (target->GetPolicyStatusCMP0041()) + if (prop == "INTERFACE_INCLUDE_DIRECTORIES") { - case cmPolicies::WARN: - messageType = cmake::WARNING; - e << target->GetMakefile()->GetPolicies() - ->GetPolicyWarning(cmPolicies::CMP0041) << "\n"; - break; - case cmPolicies::OLD: - continue; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - hadFatalError = true; - break; // Issue fatal message. + switch (target->GetPolicyStatusCMP0041()) + { + case cmPolicies::WARN: + messageType = cmake::WARNING; + e << target->GetMakefile()->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0041) << "\n"; + break; + case cmPolicies::OLD: + continue; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + hadFatalError = true; + break; // Issue fatal message. + } + } + else + { + hadFatalError = true; } } if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}")) @@ -272,8 +280,8 @@ static bool checkInterfaceDirs(const std::string &prepro, } if (!cmSystemTools::FileIsFullPath(li->c_str())) { - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n" + e << "Target \"" << target->GetName() << "\" " << prop << + " property contains relative path:\n" " \"" << *li << "\""; target->GetMakefile()->IssueMessage(messageType, e.str()); } @@ -289,32 +297,35 @@ static bool checkInterfaceDirs(const std::string &prepro, (!inBinary || isSubDirectory(installDir, topBinaryDir)) && (!inSource || isSubDirectory(installDir, topSourceDir)); - if (!shouldContinue) + if (prop == "INTERFACE_INCLUDE_DIRECTORIES") { - switch(target->GetPolicyStatusCMP0052()) + if (!shouldContinue) { - case cmPolicies::WARN: + switch(target->GetPolicyStatusCMP0052()) { - std::ostringstream s; - s << target->GetMakefile()->GetPolicies() - ->GetPolicyWarning(cmPolicies::CMP0052) << "\n"; - s << "Directory:\n \"" << *li << "\"\nin " - "INTERFACE_INCLUDE_DIRECTORIES of target \"" - << target->GetName() << "\" is a subdirectory of the install " - "directory:\n \"" << installDir << "\"\nhowever it is also " - "a subdirectory of the " << (inBinary ? "build" : "source") - << " tree:\n \"" << (inBinary ? topBinaryDir : topSourceDir) - << "\"" << std::endl; - target->GetMakefile()->IssueMessage(cmake::AUTHOR_WARNING, - s.str()); + case cmPolicies::WARN: + { + std::ostringstream s; + s << target->GetMakefile()->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0052) << "\n"; + s << "Directory:\n \"" << *li << "\"\nin " + "INTERFACE_INCLUDE_DIRECTORIES of target \"" + << target->GetName() << "\" is a subdirectory of the install " + "directory:\n \"" << installDir << "\"\nhowever it is also " + "a subdirectory of the " << (inBinary ? "build" : "source") + << " tree:\n \"" << (inBinary ? topBinaryDir : topSourceDir) + << "\"" << std::endl; + target->GetMakefile()->IssueMessage(cmake::AUTHOR_WARNING, + s.str()); + } + case cmPolicies::OLD: + shouldContinue = true; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + break; } - case cmPolicies::OLD: - shouldContinue = true; - break; - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::NEW: - break; } } if (shouldContinue) @@ -324,8 +335,8 @@ static bool checkInterfaceDirs(const std::string &prepro, } if (inBinary) { - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" + e << "Target \"" << target->GetName() << "\" " << prop << + " property contains path:\n" " \"" << *li << "\"\nwhich is prefixed in the build directory."; target->GetMakefile()->IssueMessage(messageType, e.str()); } @@ -333,8 +344,8 @@ static bool checkInterfaceDirs(const std::string &prepro, { if (inSource) { - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" + e << "Target \"" << target->GetName() << "\" " << prop << + " property contains path:\n" " \"" << *li << "\"\nwhich is prefixed in the source directory."; target->GetMakefile()->IssueMessage(messageType, e.str()); } @@ -365,6 +376,46 @@ static void prefixItems(std::string &exportDirs) } //---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateSourcesInterface( + cmTargetExport *tei, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector<std::string> &missingTargets) +{ + cmTarget *target = tei->Target; + assert(preprocessRule == cmGeneratorExpression::InstallInterface); + + const char *propName = "INTERFACE_SOURCES"; + const char *input = target->GetProperty(propName); + + if (!input) + { + return; + } + + if (!*input) + { + properties[propName] = ""; + return; + } + + std::string prepro = cmGeneratorExpression::Preprocess(input, + preprocessRule, + true); + if (!prepro.empty()) + { + this->ResolveTargetsInGeneratorExpressions(prepro, target, + missingTargets); + + if (!checkInterfaceDirs(prepro, target, propName)) + { + return; + } + properties[propName] = prepro; + } +} + +//---------------------------------------------------------------------------- void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( cmTargetExport *tei, cmGeneratorExpression::PreprocessContext preprocessRule, @@ -424,7 +475,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets); - if (!checkInterfaceDirs(prepro, target)) + if (!checkInterfaceDirs(prepro, target, propName)) { return; } diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 919924e..b6f4166 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -139,6 +139,11 @@ protected: cmGeneratorExpression::PreprocessContext preprocessRule, ImportPropertyMap &properties, std::vector<std::string> &missingTargets); + void PopulateSourcesInterface( + cmTargetExport *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector<std::string> &missingTargets); void SetImportLinkInterface(const std::string& config, std::string const& suffix, diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 98ed818..6d639c9 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -19,6 +19,7 @@ #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmTargetExport.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmExportInstallFileGenerator @@ -73,8 +74,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) // 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)) + std::string const& expDest = this->IEGen->GetDestination(); + if(cmSystemTools::FileIsFullPath(expDest)) { // The export file is being installed to an absolute path so the // package is not relocatable. Use the configured install prefix. @@ -87,7 +88,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { // Add code to compute the installation prefix relative to the // import file location. - std::string absDest = installPrefix + "/" + installDest; + std::string absDest = installPrefix + "/" + expDest; std::string absDestS = absDest + "/"; os << "# Compute the installation prefix relative to this file.\n" << "get_filename_component(_IMPORT_PREFIX" @@ -109,7 +110,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) "unset(_realOrig)\n" "unset(_realCurr)\n"; } - std::string dest = installDest; + std::string dest = expDest; while(!dest.empty()) { os << @@ -123,6 +124,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) bool require2_8_12 = false; bool require3_0_0 = false; + bool require3_1_0 = false; bool requiresConfigFiles = false; // Create all the imported targets. for(std::vector<cmTargetExport*>::const_iterator @@ -131,17 +133,6 @@ 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; @@ -152,6 +143,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateIncludeDirectoriesInterface(*tei, cmGeneratorExpression::InstallInterface, properties, missingTargets); + this->PopulateSourcesInterface(*tei, + cmGeneratorExpression::InstallInterface, + properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", te, cmGeneratorExpression::InstallInterface, @@ -190,6 +184,13 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { require3_0_0 = true; } + if(te->GetProperty("INTERFACE_SOURCES")) + { + // We can only generate INTERFACE_SOURCES in CMake 3.3, but CMake 3.1 + // can consume them. + require3_1_0 = true; + } + this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); this->PopulateCompatibleInterfaceProperties(te, properties); @@ -197,7 +198,11 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateInterfaceProperties(te, os, properties); } - if (require3_0_0) + if (require3_1_0) + { + this->GenerateRequiredCMakeVersion(os, "3.1.0"); + } + else if (require3_0_0) { this->GenerateRequiredCMakeVersion(os, "3.0.0"); } @@ -394,7 +399,7 @@ cmExportInstallFileGenerator cmTarget* target = itgen->GetTarget(); // Construct the installed location of the target. - std::string dest = itgen->GetDestination(); + std::string dest = itgen->GetDestination(config); std::string value; if(!cmSystemTools::FileIsFullPath(dest.c_str())) { diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index 14812e4..4148fb5 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -12,6 +12,7 @@ #include "cmExportSet.h" #include "cmTargetExport.h" +#include "cmAlgorithms.h" cmExportSet::~cmExportSet() { diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx index 14c4458..cf431c6 100644 --- a/Source/cmExportSetMap.cxx +++ b/Source/cmExportSetMap.cxx @@ -12,6 +12,7 @@ #include "cmExportSetMap.h" #include "cmExportSet.h" +#include "cmAlgorithms.h" cmExportSet* cmExportSetMap::operator[](const std::string &name) { diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 69857ef..554b686 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -376,11 +376,13 @@ void cmExtraCodeBlocksGenerator fout<<" </Build>\n"; - // Collect all used source files in the project - // Sort them into two containers, one for C/C++ implementation files - // which may have an acompanying header, one for all other files - std::map<std::string, cmSourceFile*> cFiles; - std::set<std::string> otherFiles; + // Collect all used source files in the project. + // Keep a list of C/C++ source files which might have an acompanying header + // that should be looked for. + typedef std::map<std::string, CbpUnit> all_files_map_t; + all_files_map_t allFiles; + std::vector<std::string> cFiles; + for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin(); lg!=lgs.end(); lg++) { @@ -429,15 +431,15 @@ void cmExtraCodeBlocksGenerator } } - // then put it accordingly into one of the two containers - if (isCFile) - { - cFiles[(*si)->GetFullPath()] = *si ; - } - else + std::string fullPath = (*si)->GetFullPath(); + + if(isCFile) { - otherFiles.insert((*si)->GetFullPath()); + cFiles.push_back(fullPath); } + + CbpUnit &cbpUnit = allFiles[fullPath]; + cbpUnit.Targets.push_back(&(ti->second)); } } default: // intended fallthrough @@ -447,19 +449,21 @@ void cmExtraCodeBlocksGenerator } // The following loop tries to add header files matching to implementation - // files to the project. It does that by iterating over all source files, + // files to the project. It does that by iterating over all + // C/C++ source files, // replacing the file name extension with ".h" and checks whether such a // file exists. If it does, it is inserted into the map of files. // A very similar version of that code exists also in the kdevelop // project generator. - for (std::map<std::string, cmSourceFile*>::const_iterator + for (std::vector<std::string>::const_iterator sit=cFiles.begin(); sit!=cFiles.end(); ++sit) { - std::string headerBasename=cmSystemTools::GetFilenamePath(sit->first); + std::string const& fileName = *sit; + std::string headerBasename=cmSystemTools::GetFilenamePath(fileName); headerBasename+="/"; - headerBasename+=cmSystemTools::GetFilenameWithoutExtension(sit->first); + headerBasename+=cmSystemTools::GetFilenameWithoutExtension(fileName); // check if there's a matching header around for(std::vector<std::string>::const_iterator @@ -471,37 +475,38 @@ void cmExtraCodeBlocksGenerator hname += "."; hname += *ext; // if it's already in the set, don't check if it exists on disk - std::set<std::string>::const_iterator headerIt=otherFiles.find(hname); - if (headerIt != otherFiles.end()) + if (allFiles.find(hname) != allFiles.end()) { break; } if(cmSystemTools::FileExists(hname.c_str())) { - otherFiles.insert(hname); + allFiles[hname].Targets = allFiles[fileName].Targets; break; } } } // insert all source files in the CodeBlocks project - // first the C/C++ implementation files, then all others - for (std::map<std::string, cmSourceFile*>::const_iterator - sit=cFiles.begin(); - sit!=cFiles.end(); + for (all_files_map_t::const_iterator + sit=allFiles.begin(); + sit!=allFiles.end(); ++sit) { - fout<<" <Unit filename=\""<< sit->first <<"\">\n" - " </Unit>\n"; - } - for (std::set<std::string>::const_iterator - sit=otherFiles.begin(); - sit!=otherFiles.end(); - ++sit) - { - fout<<" <Unit filename=\""<< *sit <<"\">\n" - " </Unit>\n"; + std::string const& unitFilename = sit->first; + CbpUnit const& unit = sit->second; + + fout<<" <Unit filename=\""<< cmXMLSafe(unitFilename) <<"\">\n"; + + for(std::vector<const cmTarget*>::const_iterator ti = unit.Targets.begin(); + ti != unit.Targets.end(); ++ti) + { + std::string const& targetName = (*ti)->GetName(); + fout<<" <Option target=\""<< cmXMLSafe(targetName) <<"\"/>\n"; + } + + fout<<" </Unit>\n"; } // Add CMakeLists.txt @@ -599,7 +604,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, // the compilerdefines for this target std::vector<std::string> cdefs; - target->GetCompileDefinitions(cdefs, buildType); + target->GetCompileDefinitions(cdefs, buildType, "C"); // Expand the list. for(std::vector<std::string>::const_iterator di = cdefs.begin(); diff --git a/Source/cmExtraCodeBlocksGenerator.h b/Source/cmExtraCodeBlocksGenerator.h index 0435ad8..97da1b8 100644 --- a/Source/cmExtraCodeBlocksGenerator.h +++ b/Source/cmExtraCodeBlocksGenerator.h @@ -39,6 +39,10 @@ public: virtual void Generate(); private: + struct CbpUnit + { + std::vector<const cmTarget*> Targets; + }; void CreateProjectFile(const std::vector<cmLocalGenerator*>& lgs); diff --git a/Source/cmExtraQbsGenerator.cxx b/Source/cmExtraQbsGenerator.cxx new file mode 100644 index 0000000..5a1f9ef --- /dev/null +++ b/Source/cmExtraQbsGenerator.cxx @@ -0,0 +1,260 @@ +#include "cmExtraQbsGenerator.h" + +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmGeneratedFileStream.h" +#include "cmSourceFile.h" + +cmExtraQbsGenerator::cmExtraQbsGenerator() +{ +#if defined(_WIN32) + this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); + this->SupportedGlobalGenerators.push_back("NMake Makefiles"); +#endif + this->SupportedGlobalGenerators.push_back("Ninja"); + this->SupportedGlobalGenerators.push_back("Unix Makefiles"); +} + +cmExtraQbsGenerator::~cmExtraQbsGenerator() {} + +void cmExtraQbsGenerator::GetDocumentation(cmDocumentationEntry &entry, + const std::string &) const +{ + entry.Name = this->GetName(); + entry.Brief = "Generates Qbs project files."; +} + +void cmExtraQbsGenerator::Generate() +{ + for (std::map<std::string, std::vector<cmLocalGenerator *> >::const_iterator + it = this->GlobalGenerator->GetProjectMap().begin(); + it != this->GlobalGenerator->GetProjectMap().end(); ++it) + { + // create a project file + this->CreateProjectFile(it->first, it->second); + } +} + +void cmExtraQbsGenerator::CreateProjectFile( + const std::string &name, + const std::vector<cmLocalGenerator *> &lgs) +{ + const cmMakefile *mf = lgs[0]->GetMakefile(); + std::string outputDir = mf->GetStartOutputDirectory(); + + const std::string filename = outputDir + "/" + name + ".qbs"; + + this->CreateNewProjectFile(name, lgs, filename); +} + +void cmExtraQbsGenerator::CreateNewProjectFile( + const std::string &projectName, const std::vector<cmLocalGenerator *> &lgs, + const std::string &filename) +{ + cmGeneratedFileStream fout(filename.c_str()); + if (!fout) + { + return; + } + + fout << "import qbs\n" + << "import qbs.File\n\n" + << "Project {\n" + << "\tname:\"" << projectName << "\"\n"; + std::vector<cmLocalGenerator *>::const_iterator itr = lgs.begin(); + for (; itr != lgs.end(); ++itr) + { + cmLocalGenerator *lg = (*itr); + this->AppendSubProject(fout, lg); + } + fout << "}\n"; +} + +void cmExtraQbsGenerator::AppendSubProject(cmGeneratedFileStream &fout, + cmLocalGenerator *lg) +{ + const cmMakefile *mk = lg->GetMakefile(); + if (!mk || mk->GetTargets().size() == 0) + { + return; + } + + const std::string &relativePath = cmSystemTools::RelativePath( + mk->GetHomeDirectory(), mk->GetCurrentDirectory()); + fout << "\tProject {\n" + << "\t\tname:\"" << relativePath << "\"\n"; + this->AppendProduct(fout, lg); + fout << "\t}\n"; +} + +void cmExtraQbsGenerator::AppendProduct(cmGeneratedFileStream &fout, + cmLocalGenerator *lg) +{ + const cmMakefile *mk = lg->GetMakefile(); + const cmTargets &ts = mk->GetTargets(); + std::string cfg = mk->GetSafeDefinition("CMAKE_BUILD_TYPE"); + cmTargets::const_iterator itr = ts.begin(); + for (; itr != ts.end(); ++itr) + { + const cmTarget &t = itr->second; + this->AppendTarget(fout, lg, t, cfg); + } +} + +void cmExtraQbsGenerator::AppendTarget(cmGeneratedFileStream &fout, + cmLocalGenerator *lg, const cmTarget &t, + const std::string &cfg) +{ + std::string type; + bool isBuildable = true; + switch (t.GetType()) + { + case cmTarget::EXECUTABLE: + type = "application"; + break; + case cmTarget::SHARED_LIBRARY: + type = "dynamiclibrary"; + break; + case cmTarget::STATIC_LIBRARY: + type = "staticlibrary"; + break; + default: + isBuildable = false; + break; + } + + if (type.empty()) + { + fout << "\t\tProject {\n"; + } + else + { + fout << "\t\tProduct {\n"; + fout << "\t\t\tdestinationDirectory: \"" << t.GetDirectory(cfg) << "\"\n"; + } + fout << "\t\t\tname:\"" << t.GetName() << "\"\n"; + + if (!type.empty()) + { + fout << "\t\t\ttype: \"" << type << "\"\n"; + fout << "\t\t\ttargetName: \"" << t.GetName() << "\"\n"; + } + + if (isBuildable) + { + fout << "\t\t\tDepends { name: \"cpp\" }\n"; + cmGeneratorTarget *gt = this->GlobalGenerator->GetGeneratorTarget(&t); + this->AppendSources(fout, gt, t, cfg); + + std::set<std::string> langs, incPaths, defs; + t.GetLanguages(langs, cfg); + for (std::set<std::string>::const_iterator lang = langs.begin(); + lang != langs.end(); + ++ lang) + { + const std::vector<std::string> &paths = + gt->GetIncludeDirectories(cfg, *lang); + std::copy(paths.begin(), paths.end(), + std::inserter(incPaths, incPaths.end())); + + lg->AddCompileDefinitions(defs, &t, cfg, *lang); + } + this->AppendIncludePaths(fout, incPaths); + this->AppendCompileDefinitions(fout, defs); + } + + fout << "\t\t}\n"; +} + +void cmExtraQbsGenerator::AppendSources(cmGeneratedFileStream &fout, + cmGeneratorTarget *gt, + const cmTarget &t, + const std::string &cfg) +{ + std::vector<cmSourceFile *> sources; + gt->GetSourceFiles(sources, cfg); + if (sources.empty()) + { + return; + } + + std::vector<cmSourceFile *> genSources; + std::vector<cmSourceFile *>::const_iterator itr = sources.begin(); + fout << "\t\t\tfiles: [\n" + << "\t\t\t\t\"" << t.GetMakefile()->GetCurrentListFile() << "\",\n"; + for (; itr != sources.end(); ++itr) + { + if (!(*itr)->GetPropertyAsBool("GENERATED")) + { + fout << "\t\t\t\t\"" << (*itr)->GetFullPath() << "\",\n"; + } + else + { + genSources.push_back(*itr); + } + } + fout << "\t\t\t]\n"; + + if (!genSources.empty()) + { + fout << "\t\t\tGroup {\n" + << "\t\t\t\tname:\"Generated\"\n" + << "\t\t\t\tfiles: [\n"; + itr = genSources.begin(); + std::string groupCondition; + bool initialCondition = true; + for (; itr != genSources.end(); ++itr) + { + const std::string &path = (*itr)->GetFullPath(); + fout << "\t\t\t\t\t\"" << path << "\",\n"; + if (initialCondition) + { + initialCondition = false; + } + else + { + groupCondition += "\t\t\t\t\t && "; + } + groupCondition += "File.exists(\"" + path + "\")\n"; + } + fout << "\t\t\t\t]\n" + << "\t\t\t\tcondition: " << groupCondition << "\t\t\t}\n"; + } +} + +void cmExtraQbsGenerator::AppendIncludePaths( + cmGeneratedFileStream &fout, + const std::set<std::string> &paths) +{ + if (paths.empty()) + { + return; + } + + std::set<std::string>::const_iterator itr = paths.begin(); + fout << "\t\t\tcpp.includePaths: [\n"; + for (; itr != paths.end(); ++ itr) + { + fout << "\t\t\t\t\"" << (*itr) << "\",\n"; + } + fout << "\t\t\t]\n"; +} + +void cmExtraQbsGenerator::AppendCompileDefinitions( + cmGeneratedFileStream &fout, + const std::set<std::string> &defs) +{ + if (defs.empty()) + { + return; + } + + std::set<std::string>::const_iterator itr = defs.begin(); + fout << "\t\t\tcpp.defines: [\n"; + for (; itr != defs.end(); ++ itr) + { + fout << "\t\t\t\t'" << (*itr) << "',\n"; + } + fout << "\t\t\t]\n"; +} diff --git a/Source/cmExtraQbsGenerator.h b/Source/cmExtraQbsGenerator.h new file mode 100644 index 0000000..531ccc9 --- /dev/null +++ b/Source/cmExtraQbsGenerator.h @@ -0,0 +1,48 @@ +#ifndef CMEXTRAQBSGENERATOR_H +#define CMEXTRAQBSGENERATOR_H + +#include "cmExternalMakefileProjectGenerator.h" + +class cmGeneratorTarget; + +class cmExtraQbsGenerator : public cmExternalMakefileProjectGenerator +{ +public: + cmExtraQbsGenerator(); + ~cmExtraQbsGenerator(); + + virtual std::string GetName() const + { return cmExtraQbsGenerator::GetActualName(); } + static std::string GetActualName() { return "Qbs"; } + static cmExternalMakefileProjectGenerator *New() + { return new cmExtraQbsGenerator; } + + /** Get the documentation entry for this generator. */ + virtual void GetDocumentation(cmDocumentationEntry &entry, + const std::string &fullName) const; + + virtual void Generate(); + +private: + void CreateProjectFile(const std::string &name, + const std::vector<cmLocalGenerator *> &lgs); + void CreateNewProjectFile(const std::string &projectName, + const std::vector<cmLocalGenerator *> &lgs, + const std::string &filename); + void AppendSubProject(cmGeneratedFileStream &fout, cmLocalGenerator *lg); + void AppendProduct(cmGeneratedFileStream &fout, cmLocalGenerator *lg); + void AppendTarget(cmGeneratedFileStream &fout, + cmLocalGenerator *lg, + const cmTarget &t, + const std::string &cfg); + void AppendSources(cmGeneratedFileStream &fout, + cmGeneratorTarget *gt, + const cmTarget &t, + const std::string &cfg); + void AppendIncludePaths(cmGeneratedFileStream &fout, + const std::set<std::string> &paths); + void AppendCompileDefinitions(cmGeneratedFileStream &fout, + const std::set<std::string> &defs); +}; + +#endif // CMEXTRAQBSGENERATOR_H diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 5fff0fb..25f9005 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -436,7 +436,7 @@ ComputeDefines(cmSourceFile *source, cmLocalGenerator* lg, cmTarget *target, } // Add preprocessor definitions for this target and configuration. - lg->AddCompileDefinitions(defines, target, config); + lg->AddCompileDefinitions(defines, target, config, language); lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS")); { std::string defPropName = "COMPILE_DEFINITIONS_"; diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx index f7d8243..488beaa 100644 --- a/Source/cmFLTKWrapUICommand.cxx +++ b/Source/cmFLTKWrapUICommand.cxx @@ -31,9 +31,6 @@ bool cmFLTKWrapUICommand // get parameter for the command this->Target = args[0]; // Target that will use the generated files - std::vector<std::string> newArgs; - this->Makefile->ExpandSourceListArguments(args,newArgs, 1); - // get the list of GUI files from which .cxx and .h will be generated std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory(); @@ -45,8 +42,8 @@ bool cmFLTKWrapUICommand this->Makefile->AddIncludeDirectories( outputDirectories ); } - for(std::vector<std::string>::iterator i = (newArgs.begin() + 1); - i != newArgs.end(); i++) + for(std::vector<std::string>::const_iterator i = (args.begin() + 1); + i != args.end(); i++) { cmSourceFile *curr = this->Makefile->GetSource(*i); // if we should use the source GUI diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index d994659..93e3ac4 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -16,6 +16,7 @@ #include "cmInstallType.h" #include "cmFileTimeComparison.h" #include "cmCryptoHash.h" +#include "cmAlgorithms.h" #include "cmTimestamp.h" @@ -71,7 +72,7 @@ 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); + std::wstring wurl = cmsys::Encoding::ToWide(url); if(!wurl.empty()) { int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, @@ -217,7 +218,6 @@ bool cmFileCommand bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, bool append) { - std::string message; std::vector<std::string>::const_iterator i = args.begin(); i++; // Get rid of subcommand @@ -231,10 +231,6 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, i++; - for(;i != args.end(); ++i) - { - message += *i; - } if ( !this->Makefile->CanIWriteThisFile(fileName.c_str()) ) { std::string e @@ -272,6 +268,7 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, this->SetError(error); return false; } + std::string message = cmJoin(cmRange(i, args.end()), std::string()); file << message; file.close(); if(mode) @@ -923,6 +920,35 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, bool first = true; for ( ; i != args.end(); ++i ) { + if( *i == "LIST_DIRECTORIES" ) + { + ++i; + if(i != args.end()) + { + if(cmSystemTools::IsOn(i->c_str())) + { + g.SetListDirs(true); + g.SetRecurseListDirs(true); + } + else if(cmSystemTools::IsOff(i->c_str())) + { + g.SetListDirs(false); + g.SetRecurseListDirs(false); + } + else + { + this->SetError("LIST_DIRECTORIES missing bool value."); + return false; + } + } + else + { + this->SetError("LIST_DIRECTORIES missing bool value."); + return false; + } + ++i; + } + if ( recurse && (*i == "FOLLOW_SYMLINKS") ) { explicitFollowSymlinks = true; @@ -953,6 +979,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, } } + cmsys::Glob::GlobMessages globMessages; if ( !cmsys::SystemTools::FileIsFullPath(i->c_str()) ) { std::string expr = this->Makefile->GetCurrentDirectory(); @@ -960,16 +987,42 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args, if (!expr.empty()) { expr += "/" + *i; - g.FindFiles(expr); + g.FindFiles(expr, &globMessages); } else { - g.FindFiles(*i); + g.FindFiles(*i, &globMessages); } } else { - g.FindFiles(*i); + g.FindFiles(*i, &globMessages); + } + + if(!globMessages.empty()) + { + bool shouldExit = false; + for(cmsys::Glob::GlobMessagesIterator it=globMessages.begin(); + it != globMessages.end(); ++it) + { + if(it->type == cmsys::Glob::cyclicRecursion) + { + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, + "Cyclic recursion detected while globbing for '" + + *i + "':\n" + it->content); + } + else + { + this->Makefile->IssueMessage(cmake::FATAL_ERROR, + "Error has occured while globbing for '" + + *i + "' - " + it->content); + shouldExit = true; + } + } + if(shouldExit) + { + return false; + } } std::vector<std::string>::size_type cc; @@ -1843,7 +1896,7 @@ bool cmFileCopier::InstallDirectory(const char* source, if(!(strcmp(dir.GetFile(fileNum), ".") == 0 || strcmp(dir.GetFile(fileNum), "..") == 0)) { - cmsys_stl::string fromPath = source; + std::string fromPath = source; fromPath += "/"; fromPath += dir.GetFile(fileNum); std::string toPath = destination; @@ -3369,6 +3422,7 @@ cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args) // enable HTTP ERROR parsing ::CURLcode res = ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + check_curl_result(res, "UPLOAD cannot set fail on error flag: "); // enable uploading res = ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1); diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx index cf8e9a9..3710eb0 100644 --- a/Source/cmFileLockPool.cxx +++ b/Source/cmFileLockPool.cxx @@ -16,6 +16,7 @@ #include "cmFileLock.h" #include "cmFileLockResult.h" +#include "cmAlgorithms.h" cmFileLockPool::cmFileLockPool() { diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h index baef310..f0614a3 100644 --- a/Source/cmFileLockPool.h +++ b/Source/cmFileLockPool.h @@ -14,6 +14,8 @@ #include "cmStandardIncludes.h" +#include <list> + class cmFileLockResult; class cmFileLock; diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx index fc18a64..36a2d72 100644 --- a/Source/cmFileLockUnix.cxx +++ b/Source/cmFileLockUnix.cxx @@ -15,6 +15,7 @@ #include <errno.h> // errno #include <stdio.h> // SEEK_SET #include <fcntl.h> +#include <unistd.h> #include "cmSystemTools.h" cmFileLock::cmFileLock(): File(-1) @@ -31,6 +32,9 @@ cmFileLockResult cmFileLock::Release() this->Filename = ""; + ::close(this->File); + this->File = -1; + if (lockResult == 0) { return cmFileLockResult::MakeOk(); diff --git a/Source/cmFileLockWin32.cxx b/Source/cmFileLockWin32.cxx index 4691689..dc65948 100644 --- a/Source/cmFileLockWin32.cxx +++ b/Source/cmFileLockWin32.cxx @@ -38,6 +38,9 @@ cmFileLockResult cmFileLock::Release() this->Filename = ""; + CloseHandle(this->File); + this->File = INVALID_HANDLE_VALUE; + if (unlockResult) { return cmFileLockResult::MakeOk(); diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 69991d5..f63df61 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmFindBase.h" +#include "cmAlgorithms.h" + cmFindBase::cmFindBase() { this->AlreadyInCache = false; @@ -166,11 +168,9 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } else { - this->VariableDocumentation += "one of the " + this->Names[0]; - for (unsigned int j = 1; j < this->Names.size() - 1; ++j) - { - this->VariableDocumentation += ", " + this->Names[j]; - } + this->VariableDocumentation += "one of the "; + this->VariableDocumentation += cmJoin(cmRange(this->Names).retreat(1), + ", "); this->VariableDocumentation += " or " + this->Names[this->Names.size() - 1] + " libraries be found"; } @@ -277,6 +277,7 @@ void cmFindBase::FillSystemEnvironmentPath() if(!this->EnvironmentPath.empty()) { paths.AddEnvPath(this->EnvironmentPath); + paths.AddEnvPrefixPath("PATH", true); } // Add PATH paths.AddEnvPath("PATH"); @@ -352,25 +353,12 @@ void cmFindBase::PrintFindStuff() std::cerr << "NoCMakeSystemPath " << this->NoCMakeSystemPath << "\n"; std::cerr << "EnvironmentPath " << this->EnvironmentPath << "\n"; std::cerr << "CMakePathName " << this->CMakePathName << "\n"; - std::cerr << "Names "; - for(unsigned int i =0; i < this->Names.size(); ++i) - { - std::cerr << this->Names[i] << " "; - } - std::cerr << "\n"; + std::cerr << "Names " << cmJoin(this->Names, " ") << "\n"; std::cerr << "\n"; std::cerr << "SearchPathSuffixes "; - for(unsigned int i =0; i < this->SearchPathSuffixes.size(); ++i) - { - std::cerr << this->SearchPathSuffixes[i] << "\n"; - } - std::cerr << "\n"; + std::cerr << cmJoin(this->SearchPathSuffixes, "\n") << "\n"; std::cerr << "SearchPaths\n"; - for(std::vector<std::string>::const_iterator i = this->SearchPaths.begin(); - i != this->SearchPaths.end(); ++i) - { - std::cerr << "[" << *i << "]\n"; - } + std::cerr << cmWrap("[", this->SearchPaths, "]", "\n") << "\n"; } bool cmFindBase::CheckForVariableInCache() diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index 78f0e9e..c499f61 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -195,12 +195,12 @@ struct cmFindLibraryHelper void RegexFromList(std::string& out, std::vector<std::string> const& in); size_type GetPrefixIndex(std::string const& prefix) { - return cmsys_stl::find(this->Prefixes.begin(), this->Prefixes.end(), + return std::find(this->Prefixes.begin(), this->Prefixes.end(), prefix) - this->Prefixes.begin(); } size_type GetSuffixIndex(std::string const& suffix) { - return cmsys_stl::find(this->Suffixes.begin(), this->Suffixes.end(), + return std::find(this->Suffixes.begin(), this->Suffixes.end(), suffix) - this->Suffixes.begin(); } bool HasValidSuffix(std::string const& name); diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 7746980..4d7fd60 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -14,6 +14,7 @@ #include <cmsys/Directory.hxx> #include <cmsys/RegularExpression.hxx> #include <cmsys/Encoding.hxx> +#include "cmAlgorithms.h" #ifdef CMAKE_BUILD_WITH_CMAKE #include "cmVariableWatch.h" @@ -329,10 +330,7 @@ bool cmFindPackageCommand { std::ostringstream e; e << "called with components that are both required and optional:\n"; - for(unsigned int i=0; i<doubledComponents.size(); ++i) - { - e << " " << doubledComponents[i] << "\n"; - } + e << cmWrap(" ", doubledComponents, "", "\n") << "\n"; this->SetError(e.str()); return false; } @@ -681,7 +679,6 @@ bool cmFindPackageCommand::HandlePackageMode() if(cmSystemTools::IsOff(def) || !fileFound) { fileFound = this->FindConfig(); - def = this->Makefile->GetDefinition(this->Variable); } // Sanity check. @@ -808,13 +805,8 @@ bool cmFindPackageCommand::HandlePackageMode() { e << "Could not find a package configuration file provided by \"" << this->Name << "\"" << requestedVersionString - << " with any of the following names:\n"; - for(std::vector<std::string>::const_iterator ci = - this->Configs.begin(); - ci != this->Configs.end(); ++ci) - { - e << " " << *ci << "\n"; - } + << " with any of the following names:\n" + << cmWrap(" ", this->Configs, "", "\n") << "\n"; } e << "Add the installation prefix of \"" << this->Name << "\" to " @@ -1064,26 +1056,11 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found) } - std::string tmp; - const char* sep =""; - for(size_t i=0; i<foundContents.size(); i++) - { - tmp += sep; - tmp += foundContents[i]; - sep = ";"; - } - + std::string tmp = cmJoin(foundContents, ";"); this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_FOUND", tmp.c_str()); - tmp = ""; - sep = ""; - for(size_t i=0; i<notFoundContents.size(); i++) - { - tmp += sep; - tmp += notFoundContents[i]; - sep = ";"; - } + tmp = cmJoin(notFoundContents, ";"); this->Makefile->GetCMakeInstance()->SetProperty("PACKAGES_NOT_FOUND", tmp.c_str()); } @@ -1620,7 +1597,6 @@ bool cmFindPackageCommand::CheckVersion(std::string const& config_file) if ((haveResult == false) && (this->Version.empty())) { result = true; - haveResult = true; } ConfigFileInfo configFileInfo; diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index c33048c..9297688 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -126,27 +126,10 @@ bool cmFunctionHelperCommand::InvokeInitialPass } // define ARGV and ARGN - std::vector<std::string>::const_iterator eit; - std::string argvDef; - std::string argnDef; - unsigned int cnt = 0; - for ( eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit ) - { - if (!argvDef.empty()) - { - argvDef += ";"; - } - argvDef += *eit; - if ( cnt >= this->Args.size()-1 ) - { - if (!argnDef.empty()) - { - argnDef += ";"; - } - argnDef += *eit; - } - cnt ++; - } + std::string argvDef = cmJoin(expandedArgs, ";"); + std::vector<std::string>::const_iterator eit + = expandedArgs.begin() + (this->Args.size()-1); + std::string argnDef = cmJoin(cmRange(eit, expandedArgs.end()), ";"); this->Makefile->AddDefinition("ARGV", argvDef.c_str()); this->Makefile->MarkVariableAsUsed("ARGV"); this->Makefile->AddDefinition("ARGN", argnDef.c_str()); @@ -192,15 +175,6 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endfunction for this function then execute if (!this->Depth) { - std::string name = this->Args[0]; - std::vector<std::string>::size_type cc; - name += "("; - for ( cc = 0; cc < this->Args.size(); cc ++ ) - { - name += " " + this->Args[cc]; - } - name += " )"; - // create a new command and add it to cmake cmFunctionHelperCommand *f = new cmFunctionHelperCommand(); f->Args = this->Args; diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index bf96951..a1c405b 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -14,6 +14,7 @@ #include "cmMakefile.h" #include "cmTarget.h" #include "assert.h" +#include "cmAlgorithms.h" #include "cmGeneratorExpressionEvaluator.h" #include "cmGeneratorExpressionLexer.h" @@ -52,14 +53,16 @@ cmGeneratorExpression::~cmGeneratorExpression() const char *cmCompiledGeneratorExpression::Evaluate( cmMakefile* mf, const std::string& config, bool quiet, cmTarget const* headTarget, - cmGeneratorExpressionDAGChecker *dagChecker) const + cmGeneratorExpressionDAGChecker *dagChecker, + std::string const& language) const { return this->Evaluate(mf, config, quiet, headTarget, headTarget, - dagChecker); + dagChecker, + language); } //---------------------------------------------------------------------------- @@ -67,7 +70,21 @@ const char *cmCompiledGeneratorExpression::Evaluate( cmMakefile* mf, const std::string& config, bool quiet, cmTarget const* headTarget, cmTarget const* currentTarget, - cmGeneratorExpressionDAGChecker *dagChecker) const + cmGeneratorExpressionDAGChecker *dagChecker, + std::string const& language) const +{ + cmGeneratorExpressionContext context(mf, config, quiet, headTarget, + currentTarget ? currentTarget : headTarget, + this->EvaluateForBuildsystem, + this->Backtrace, language); + + return this->EvaluateWithContext(context, dagChecker); +} + +//---------------------------------------------------------------------------- +const char* cmCompiledGeneratorExpression::EvaluateWithContext( + cmGeneratorExpressionContext& context, + cmGeneratorExpressionDAGChecker *dagChecker) const { if (!this->NeedsEvaluation) { @@ -81,19 +98,6 @@ const char *cmCompiledGeneratorExpression::Evaluate( const std::vector<cmGeneratorExpressionEvaluator*>::const_iterator end = this->Evaluators.end(); - cmGeneratorExpressionContext context; - context.Makefile = mf; - context.Config = config; - context.Quiet = quiet; - context.HadError = false; - context.HadContextSensitiveCondition = false; - context.HadHeadSensitiveCondition = false; - context.SourceSensitiveTargets.clear(); - context.HeadTarget = headTarget; - context.EvaluateForBuildsystem = this->EvaluateForBuildsystem; - context.CurrentTarget = currentTarget ? currentTarget : headTarget; - context.Backtrace = this->Backtrace; - for ( ; it != end; ++it) { this->Output += (*it)->Evaluate(&context, dagChecker); diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 57f78c5..11c27fd 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -24,6 +24,7 @@ class cmMakefile; class cmListFileBacktrace; struct cmGeneratorExpressionEvaluator; +struct cmGeneratorExpressionContext; struct cmGeneratorExpressionDAGChecker; class cmCompiledGeneratorExpression; @@ -80,11 +81,13 @@ public: bool quiet = false, cmTarget const* headTarget = 0, cmTarget const* currentTarget = 0, - cmGeneratorExpressionDAGChecker *dagChecker = 0) const; + cmGeneratorExpressionDAGChecker *dagChecker = 0, + std::string const& language = std::string()) const; const char* Evaluate(cmMakefile* mf, const std::string& config, bool quiet, cmTarget const* headTarget, - cmGeneratorExpressionDAGChecker *dagChecker) const; + cmGeneratorExpressionDAGChecker *dagChecker, + std::string const& language = std::string()) const; /** Get set of targets found during evaluations. */ std::set<cmTarget*> const& GetTargets() const @@ -129,6 +132,9 @@ public: std::map<std::string, std::string>& mapping); private: + const char* EvaluateWithContext(cmGeneratorExpressionContext& context, + cmGeneratorExpressionDAGChecker *dagChecker) const; + cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, const std::string& input); diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx new file mode 100644 index 0000000..947015e --- /dev/null +++ b/Source/cmGeneratorExpressionContext.cxx @@ -0,0 +1,34 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionContext.h" + +cmGeneratorExpressionContext::cmGeneratorExpressionContext( + cmMakefile* mf, std::string const& config, + bool quiet, cmTarget const* headTarget, + cmTarget const* currentTarget, + bool evaluateForBuildsystem, + cmListFileBacktrace const& backtrace, + std::string const& language) + : Backtrace(backtrace), + Makefile(mf), + Config(config), + Language(language), + HeadTarget(headTarget), + CurrentTarget(currentTarget), + Quiet(quiet), + HadError(false), + HadContextSensitiveCondition(false), + HadHeadSensitiveCondition(false), + EvaluateForBuildsystem(evaluateForBuildsystem) +{ +} diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h new file mode 100644 index 0000000..ed83509 --- /dev/null +++ b/Source/cmGeneratorExpressionContext.h @@ -0,0 +1,54 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionContext_h +#define cmGeneratorExpressionContext_h + +#include "cmListFileCache.h" + +#include <set> +#include <map> +#include <string> + +class cmTarget; + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionContext +{ + cmGeneratorExpressionContext(cmMakefile* mf, std::string const& config, + bool quiet, cmTarget const* headTarget, + cmTarget const* currentTarget, + bool evaluateForBuildsystem, + cmListFileBacktrace const& backtrace, + std::string const& language); + + + cmListFileBacktrace Backtrace; + 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; + std::string Config; + std::string Language; + cmTarget const* HeadTarget; // The target whose property is being evaluated. + cmTarget const* CurrentTarget; // The dependent of HeadTarget which appears + // directly or indirectly in the property. + bool Quiet; + bool HadError; + bool HadContextSensitiveCondition; + bool HadHeadSensitiveCondition; + bool EvaluateForBuildsystem; +}; + +#endif diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index c8b9949..ff8790c 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -13,6 +13,7 @@ #include "cmGeneratorExpressionDAGChecker.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index 4e2a868..fa00283 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -38,13 +38,15 @@ cmGeneratorExpressionEvaluationFile::cmGeneratorExpressionEvaluationFile( //---------------------------------------------------------------------------- void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, + const std::string& lang, cmCompiledGeneratorExpression* inputExpression, std::map<std::string, std::string> &outputFiles, mode_t perm) { std::string rawCondition = this->Condition->GetInput(); if (!rawCondition.empty()) { - std::string condResult = this->Condition->Evaluate(this->Makefile, config); + std::string condResult = this->Condition->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); if (condResult == "0") { return; @@ -60,9 +62,11 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, } const std::string outputFileName - = this->OutputFileExpr->Evaluate(this->Makefile, config); + = this->OutputFileExpr->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); const std::string outputContent - = inputExpression->Evaluate(this->Makefile, config); + = inputExpression->Evaluate(this->Makefile, config, + false, 0, 0, 0, lang); std::map<std::string, std::string>::iterator it = outputFiles.find(outputFileName); @@ -75,7 +79,8 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, } std::ostringstream e; e << "Evaluation file to be written multiple times for different " - "configurations with different content:\n " << outputFileName; + "configurations or languages with different content:\n " + << outputFileName; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); return; } @@ -97,14 +102,22 @@ void cmGeneratorExpressionEvaluationFile::Generate(const std::string& config, 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"); - + std::vector<std::string> enabledLanguages; cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); - gg->SetFilenameTargetDepends(sf, + gg->GetEnabledLanguages(enabledLanguages); + + for(std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) + { + std::string name = this->OutputFileExpr->Evaluate(this->Makefile, config, + false, 0, 0, 0, *le); + cmSourceFile* sf = this->Makefile->GetOrCreateSource(name); + sf->SetProperty("GENERATED", "1"); + + gg->SetFilenameTargetDepends(sf, this->OutputFileExpr->GetSourceSensitiveTargets()); + } } //---------------------------------------------------------------------------- @@ -153,13 +166,23 @@ void cmGeneratorExpressionEvaluationFile::Generate() { allConfigs.push_back(""); } - for(std::vector<std::string>::const_iterator li = allConfigs.begin(); - li != allConfigs.end(); ++li) + + std::vector<std::string> enabledLanguages; + cmGlobalGenerator *gg + = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + gg->GetEnabledLanguages(enabledLanguages); + + for(std::vector<std::string>::const_iterator le = enabledLanguages.begin(); + le != enabledLanguages.end(); ++le) { - this->Generate(*li, inputExpression.get(), outputFiles, perm); - if(cmSystemTools::GetFatalErrorOccured()) + for(std::vector<std::string>::const_iterator li = allConfigs.begin(); + li != allConfigs.end(); ++li) { - return; + this->Generate(*li, *le, inputExpression.get(), outputFiles, perm); + if(cmSystemTools::GetFatalErrorOccured()) + { + return; + } } } } diff --git a/Source/cmGeneratorExpressionEvaluationFile.h b/Source/cmGeneratorExpressionEvaluationFile.h index 3394ade..4424bec 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.h +++ b/Source/cmGeneratorExpressionEvaluationFile.h @@ -34,7 +34,7 @@ public: void CreateOutputFile(std::string const& config); private: - void Generate(const std::string& config, + void Generate(const std::string& config, const std::string& lang, cmCompiledGeneratorExpression* inputExpression, std::map<std::string, std::string> &outputFiles, mode_t perm); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 6692a92..af94bcc 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -16,1831 +16,16 @@ #include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorExpression.h" #include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" #include "cmSourceFile.h" +#include "cmAlgorithms.h" #include <cmsys/String.h> #include <assert.h> #include <errno.h> -//---------------------------------------------------------------------------- -#if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510 -static -#endif -void reportError(cmGeneratorExpressionContext *context, - const std::string &expr, const std::string &result) -{ - context->HadError = true; - if (context->Quiet) - { - return; - } - - std::ostringstream e; - e << "Error evaluating generator expression:\n" - << " " << expr << "\n" - << result; - context->Makefile->GetCMakeInstance() - ->IssueMessage(cmake::FATAL_ERROR, e.str(), - context->Backtrace); -} - -//---------------------------------------------------------------------------- -struct cmGeneratorExpressionNode -{ - enum { - DynamicParameters = 0, - OneOrMoreParameters = -1, - OneOrZeroParameters = -2 - }; - virtual ~cmGeneratorExpressionNode() {} - - virtual bool GeneratesContent() const { return true; } - - virtual bool RequiresLiteralInput() const { return false; } - - virtual bool AcceptsArbitraryContentParameter() const - { return false; } - - virtual int NumExpectedParameters() const { return 1; } - - virtual std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - 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() {} - - virtual bool GeneratesContent() const { return false; } - - virtual bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return std::string(); - } -} zeroNode; - -//---------------------------------------------------------------------------- -static const struct OneNode : public cmGeneratorExpressionNode -{ - OneNode() {} - - virtual bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return parameters.front(); - } -} oneNode; - -//---------------------------------------------------------------------------- -static const struct OneNode buildInterfaceNode; - -//---------------------------------------------------------------------------- -static const struct ZeroNode installInterfaceNode; - -//---------------------------------------------------------------------------- -#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ -static const struct OP ## Node : public cmGeneratorExpressionNode \ -{ \ - OP ## Node () {} \ - virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \ - \ - std::string Evaluate(const std::vector<std::string> ¶meters, \ - cmGeneratorExpressionContext *context, \ - const GeneratorExpressionContent *content, \ - cmGeneratorExpressionDAGChecker *) const \ - { \ - std::vector<std::string>::const_iterator it = parameters.begin(); \ - const std::vector<std::string>::const_iterator end = parameters.end(); \ - for ( ; it != end; ++it) \ - { \ - if (*it == #FAILURE_VALUE) \ - { \ - return #FAILURE_VALUE; \ - } \ - else if (*it != #SUCCESS_VALUE) \ - { \ - reportError(context, content->GetOriginalExpression(), \ - "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \ - return std::string(); \ - } \ - } \ - return #SUCCESS_VALUE; \ - } \ -} OPNAME; - -BOOLEAN_OP_NODE(andNode, AND, 1, 0) -BOOLEAN_OP_NODE(orNode, OR, 0, 1) - -#undef BOOLEAN_OP_NODE - -//---------------------------------------------------------------------------- -static const struct NotNode : public cmGeneratorExpressionNode -{ - NotNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - if (*parameters.begin() != "0" && *parameters.begin() != "1") - { - reportError(context, content->GetOriginalExpression(), - "$<NOT> parameter must resolve to exactly one '0' or '1' value."); - return std::string(); - } - return *parameters.begin() == "0" ? "1" : "0"; - } -} notNode; - -//---------------------------------------------------------------------------- -static const struct BoolNode : public cmGeneratorExpressionNode -{ - BoolNode() {} - - virtual int NumExpectedParameters() const { return 1; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0"; - } -} boolNode; - -//---------------------------------------------------------------------------- -static const struct StrEqualNode : public cmGeneratorExpressionNode -{ - StrEqualNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return *parameters.begin() == parameters[1] ? "1" : "0"; - } -} strEqualNode; - -//---------------------------------------------------------------------------- -static const struct EqualNode : public cmGeneratorExpressionNode -{ - EqualNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - char *pEnd; - - int base = 0; - bool flipSign = false; - - const char *lhs = parameters[0].c_str(); - if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B")) - { - base = 2; - lhs += 2; - } - if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B")) - { - base = 2; - lhs += 3; - flipSign = true; - } - if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B")) - { - base = 2; - lhs += 3; - } - - long lnum = strtol(lhs, &pEnd, base); - if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) - { - reportError(context, content->GetOriginalExpression(), - "$<EQUAL> parameter " + parameters[0] + " is not a valid integer."); - return std::string(); - } - - if (flipSign) - { - lnum = -lnum; - } - - base = 0; - flipSign = false; - - const char *rhs = parameters[1].c_str(); - if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B")) - { - base = 2; - rhs += 2; - } - if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B")) - { - base = 2; - rhs += 3; - flipSign = true; - } - if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B")) - { - base = 2; - rhs += 3; - } - - long rnum = strtol(rhs, &pEnd, base); - if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) - { - reportError(context, content->GetOriginalExpression(), - "$<EQUAL> parameter " + parameters[1] + " is not a valid integer."); - return std::string(); - } - - if (flipSign) - { - rnum = -rnum; - } - - return lnum == rnum ? "1" : "0"; - } -} equalNode; - -//---------------------------------------------------------------------------- -static const struct LowerCaseNode : public cmGeneratorExpressionNode -{ - LowerCaseNode() {} - - bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::LowerCase(parameters.front()); - } -} lowerCaseNode; - -//---------------------------------------------------------------------------- -static const struct UpperCaseNode : public cmGeneratorExpressionNode -{ - UpperCaseNode() {} - - bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::UpperCase(parameters.front()); - } -} upperCaseNode; - -//---------------------------------------------------------------------------- -static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode -{ - MakeCIdentifierNode() {} - - bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::MakeCidentifier(parameters.front()); - } -} makeCIdentifierNode; - -//---------------------------------------------------------------------------- -static const struct Angle_RNode : public cmGeneratorExpressionNode -{ - Angle_RNode() {} - - virtual int NumExpectedParameters() const { return 0; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return ">"; - } -} angle_rNode; - -//---------------------------------------------------------------------------- -static const struct CommaNode : public cmGeneratorExpressionNode -{ - CommaNode() {} - - virtual int NumExpectedParameters() const { return 0; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return ","; - } -} commaNode; - -//---------------------------------------------------------------------------- -static const struct SemicolonNode : public cmGeneratorExpressionNode -{ - SemicolonNode() {} - - virtual int NumExpectedParameters() const { return 0; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return ";"; - } -} semicolonNode; - -//---------------------------------------------------------------------------- -struct CompilerIdNode : public cmGeneratorExpressionNode -{ - CompilerIdNode() {} - - virtual int NumExpectedParameters() const { return OneOrZeroParameters; } - - std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *, - const std::string &lang) const - { - const char *compilerId = - context->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID"); - if (parameters.empty()) - { - return compilerId ? compilerId : ""; - } - static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$"); - if (!compilerIdValidator.find(*parameters.begin())) - { - reportError(context, content->GetOriginalExpression(), - "Expression syntax not recognized."); - return std::string(); - } - if (!compilerId) - { - return parameters.front().empty() ? "1" : "0"; - } - - if (strcmp(parameters.begin()->c_str(), compilerId) == 0) - { - return "1"; - } - - if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0) - { - switch(context->Makefile->GetPolicyStatus(cmPolicies::CMP0044)) - { - case cmPolicies::WARN: - { - std::ostringstream e; - e << context->Makefile->GetPolicies() - ->GetPolicyWarning(cmPolicies::CMP0044); - context->Makefile->GetCMakeInstance() - ->IssueMessage(cmake::AUTHOR_WARNING, - e.str(), context->Backtrace); - } - case cmPolicies::OLD: - return "1"; - case cmPolicies::NEW: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - break; - } - } - return "0"; - } -}; - -//---------------------------------------------------------------------------- -static const struct CCompilerIdNode : public CompilerIdNode -{ - CCompilerIdNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if (!context->HeadTarget) - { - reportError(context, content->GetOriginalExpression(), - "$<C_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, - dagChecker, "C"); - } -} cCompilerIdNode; - -//---------------------------------------------------------------------------- -static const struct CXXCompilerIdNode : public CompilerIdNode -{ - CXXCompilerIdNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if (!context->HeadTarget) - { - reportError(context, content->GetOriginalExpression(), - "$<CXX_COMPILER_ID> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, - dagChecker, "CXX"); - } -} cxxCompilerIdNode; - -//---------------------------------------------------------------------------- -struct CompilerVersionNode : public cmGeneratorExpressionNode -{ - CompilerVersionNode() {} - - virtual int NumExpectedParameters() const { return OneOrZeroParameters; } - - std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *, - const std::string &lang) const - { - const char *compilerVersion = context->Makefile->GetSafeDefinition( - "CMAKE_" + lang + "_COMPILER_VERSION"); - if (parameters.empty()) - { - return compilerVersion ? compilerVersion : ""; - } - - static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$"); - if (!compilerIdValidator.find(*parameters.begin())) - { - reportError(context, content->GetOriginalExpression(), - "Expression syntax not recognized."); - return std::string(); - } - if (!compilerVersion) - { - return parameters.front().empty() ? "1" : "0"; - } - - return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, - parameters.begin()->c_str(), - compilerVersion) ? "1" : "0"; - } -}; - -//---------------------------------------------------------------------------- -static const struct CCompilerVersionNode : public CompilerVersionNode -{ - CCompilerVersionNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if (!context->HeadTarget) - { - reportError(context, content->GetOriginalExpression(), - "$<C_COMPILER_VERSION> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, - dagChecker, "C"); - } -} cCompilerVersionNode; - -//---------------------------------------------------------------------------- -static const struct CxxCompilerVersionNode : public CompilerVersionNode -{ - CxxCompilerVersionNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if (!context->HeadTarget) - { - reportError(context, content->GetOriginalExpression(), - "$<CXX_COMPILER_VERSION> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - return this->EvaluateWithLanguage(parameters, context, content, - dagChecker, "CXX"); - } -} cxxCompilerVersionNode; - - -//---------------------------------------------------------------------------- -struct PlatformIdNode : public cmGeneratorExpressionNode -{ - PlatformIdNode() {} - - virtual int NumExpectedParameters() const { return OneOrZeroParameters; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - const char *platformId = - context->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - if (parameters.empty()) - { - return platformId ? platformId : ""; - } - - if (!platformId) - { - return parameters.front().empty() ? "1" : "0"; - } - - if (strcmp(parameters.begin()->c_str(), platformId) == 0) - { - return "1"; - } - return "0"; - } -} platformIdNode; - -//---------------------------------------------------------------------------- -static const struct VersionGreaterNode : public cmGeneratorExpressionNode -{ - VersionGreaterNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, - parameters.front().c_str(), - parameters[1].c_str()) ? "1" : "0"; - } -} versionGreaterNode; - -//---------------------------------------------------------------------------- -static const struct VersionLessNode : public cmGeneratorExpressionNode -{ - VersionLessNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, - parameters.front().c_str(), - parameters[1].c_str()) ? "1" : "0"; - } -} versionLessNode; - -//---------------------------------------------------------------------------- -static const struct VersionEqualNode : public cmGeneratorExpressionNode -{ - VersionEqualNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, - parameters.front().c_str(), - parameters[1].c_str()) ? "1" : "0"; - } -} versionEqualNode; - -//---------------------------------------------------------------------------- -static const struct LinkOnlyNode : public cmGeneratorExpressionNode -{ - LinkOnlyNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - if(!dagChecker->GetTransitivePropertiesOnly()) - { - return parameters.front(); - } - return ""; - } -} linkOnlyNode; - -//---------------------------------------------------------------------------- -static const struct ConfigurationNode : public cmGeneratorExpressionNode -{ - ConfigurationNode() {} - - virtual int NumExpectedParameters() const { return 0; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - context->HadContextSensitiveCondition = true; - return context->Config; - } -} configurationNode; - -//---------------------------------------------------------------------------- -static const struct ConfigurationTestNode : public cmGeneratorExpressionNode -{ - ConfigurationTestNode() {} - - virtual int NumExpectedParameters() const { return OneOrZeroParameters; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - if (parameters.empty()) - { - return configurationNode.Evaluate(parameters, context, content, 0); - } - static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$"); - if (!configValidator.find(*parameters.begin())) - { - reportError(context, content->GetOriginalExpression(), - "Expression syntax not recognized."); - return std::string(); - } - context->HadContextSensitiveCondition = true; - if (context->Config.empty()) - { - return parameters.front().empty() ? "1" : "0"; - } - - if (cmsysString_strcasecmp(parameters.begin()->c_str(), - context->Config.c_str()) == 0) - { - return "1"; - } - - if (context->CurrentTarget - && context->CurrentTarget->IsImported()) - { - const char* loc = 0; - const char* imp = 0; - std::string suffix; - if (context->CurrentTarget->GetMappedConfig(context->Config, - &loc, - &imp, - suffix)) - { - // This imported target has an appropriate location - // for this (possibly mapped) config. - // Check if there is a proper config mapping for the tested config. - std::vector<std::string> mappedConfigs; - std::string mapProp = "MAP_IMPORTED_CONFIG_"; - mapProp += cmSystemTools::UpperCase(context->Config); - if(const char* mapValue = - context->CurrentTarget->GetProperty(mapProp)) - { - cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue), - mappedConfigs); - return std::find(mappedConfigs.begin(), mappedConfigs.end(), - cmSystemTools::UpperCase(parameters.front())) - != mappedConfigs.end() ? "1" : "0"; - } - } - } - return "0"; - } -} configurationTestNode; - -static const struct JoinNode : public cmGeneratorExpressionNode -{ - JoinNode() {} - - virtual int NumExpectedParameters() const { return 2; } - - virtual bool AcceptsArbitraryContentParameter() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(parameters.front(), list); - return cmJoin(list, parameters[1]); - } -} joinNode; - -#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \ - , "INTERFACE_" #PROPERTY - -//---------------------------------------------------------------------------- -static const char* targetPropertyTransitiveWhitelist[] = { - 0 - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) -}; - -#undef TRANSITIVE_PROPERTY_NAME - -template <typename T> -std::string -getLinkedTargetsContent( - std::vector<T> const &libraries, - cmTarget const* target, - cmTarget const* headTarget, - cmGeneratorExpressionContext *context, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string &interfacePropertyName) -{ - std::string linkedTargetsContent; - std::string sep; - std::string depString; - for (typename std::vector<T>::const_iterator it = libraries.begin(); - it != libraries.end(); ++it) - { - // Broken code can have a target in its own link interface. - // Don't follow such link interface entries so as not to create a - // self-referencing loop. - if (it->Target && it->Target != target) - { - depString += - sep + "$<TARGET_PROPERTY:" + - it->Target->GetName() + "," + interfacePropertyName + ">"; - sep = ";"; - } - } - if(!depString.empty()) - { - linkedTargetsContent = - cmGeneratorExpressionNode::EvaluateDependentExpression(depString, - target->GetMakefile(), context, - headTarget, target, dagChecker); - } - linkedTargetsContent = - cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); - return linkedTargetsContent; -} - -//---------------------------------------------------------------------------- -static const struct TargetPropertyNode : public cmGeneratorExpressionNode -{ - TargetPropertyNode() {} - - // This node handles errors on parameter count itself. - virtual int NumExpectedParameters() const { return OneOrMoreParameters; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagCheckerParent - ) const - { - if (parameters.size() != 1 && parameters.size() != 2) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:...> expression requires one or two parameters"); - return std::string(); - } - static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); - - cmTarget const* target = context->HeadTarget; - std::string propertyName = *parameters.begin(); - - if (parameters.size() == 1) - { - context->HadHeadSensitiveCondition = true; - } - if (!target && parameters.size() == 1) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:prop> may only be used with binary targets. " - "It may not be used with add_custom_command or add_custom_target. " - "Specify the target to read a property from using the " - "$<TARGET_PROPERTY:tgt,prop> signature instead."); - return std::string(); - } - - if (parameters.size() == 2) - { - if (parameters.begin()->empty() && parameters[1].empty()) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " - "target name and property name."); - return std::string(); - } - if (parameters.begin()->empty()) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " - "target name."); - return std::string(); - } - - std::string targetName = parameters.front(); - propertyName = parameters[1]; - if (!cmGeneratorExpression::IsValidTargetName(targetName)) - { - if (!propertyNameValidator.find(propertyName.c_str())) - { - ::reportError(context, content->GetOriginalExpression(), - "Target name and property name not supported."); - return std::string(); - } - ::reportError(context, content->GetOriginalExpression(), - "Target name not supported."); - return std::string(); - } - if(propertyName == "ALIASED_TARGET") - { - if(context->Makefile->IsAlias(targetName)) - { - if(cmTarget* tgt = context->Makefile->FindTargetToUse(targetName)) - { - return tgt->GetName(); - } - } - return ""; - } - target = context->Makefile->FindTargetToUse(targetName); - - if (!target) - { - std::ostringstream e; - e << "Target \"" - << targetName - << "\" not found."; - reportError(context, content->GetOriginalExpression(), e.str()); - return std::string(); - } - context->AllTargets.insert(target); - } - - if (target == context->HeadTarget) - { - // Keep track of the properties seen while processing. - // The evaluation of the LINK_LIBRARIES generator expressions - // will check this to ensure that properties have one consistent - // value for all evaluations. - context->SeenTargetProperties.insert(propertyName); - } - if (propertyName == "SOURCES") - { - context->SourceSensitiveTargets.insert(target); - } - - if (propertyName.empty()) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:...> expression requires a non-empty property " - "name."); - return std::string(); - } - - if (!propertyNameValidator.find(propertyName)) - { - ::reportError(context, content->GetOriginalExpression(), - "Property name not supported."); - return std::string(); - } - - assert(target); - - if (propertyName == "LINKER_LANGUAGE") - { - if (target->LinkLanguagePropagatesToDependents() && - dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries() - || dagCheckerParent->EvaluatingSources())) - { - reportError(context, content->GetOriginalExpression(), - "LINKER_LANGUAGE target property can not be used while evaluating " - "link libraries for a static library"); - return std::string(); - } - return target->GetLinkerLanguage(context->Config); - } - - cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, - target->GetName(), - propertyName, - content, - dagCheckerParent); - - switch (dagChecker.Check()) - { - case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: - dagChecker.ReportError(context, content->GetOriginalExpression()); - return std::string(); - case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: - // No error. We just skip cyclic references. - return std::string(); - case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: - for (size_t i = 1; - i < cmArraySize(targetPropertyTransitiveWhitelist); - ++i) - { - if (targetPropertyTransitiveWhitelist[i] == propertyName) - { - // No error. We're not going to find anything new here. - return std::string(); - } - } - case cmGeneratorExpressionDAGChecker::DAG: - break; - } - - const char *prop = target->GetProperty(propertyName); - - if (dagCheckerParent) - { - if (dagCheckerParent->EvaluatingLinkLibraries()) - { -#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \ - (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) || - if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE) - false) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_PROPERTY:...> expression in link libraries " - "evaluation depends on target property which is transitive " - "over the link libraries, creating a recursion."); - return std::string(); - } -#undef TRANSITIVE_PROPERTY_COMPARE - - if(!prop) - { - return std::string(); - } - } - else - { -#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \ - dagCheckerParent->METHOD () || - - assert( - CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( - ASSERT_TRANSITIVE_PROPERTY_METHOD) - false); -#undef ASSERT_TRANSITIVE_PROPERTY_METHOD - } - } - - std::string linkedTargetsContent; - - std::string interfacePropertyName; - bool isInterfaceProperty = false; - -#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ - if (propertyName == #prop) \ - { \ - interfacePropertyName = "INTERFACE_" #prop; \ - } \ - else if (propertyName == "INTERFACE_" #prop) \ - { \ - interfacePropertyName = "INTERFACE_" #prop; \ - isInterfaceProperty = true; \ - } \ - else - - CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) - // Note that the above macro terminates with an else - /* else */ if (cmHasLiteralPrefix(propertyName.c_str(), - "COMPILE_DEFINITIONS_")) - { - cmPolicies::PolicyStatus polSt = - context->Makefile->GetPolicyStatus(cmPolicies::CMP0043); - if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) - { - interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; - } - } -#undef POPULATE_INTERFACE_PROPERTY_NAME - cmTarget const* headTarget = context->HeadTarget && isInterfaceProperty - ? context->HeadTarget : target; - - if(isInterfaceProperty) - { - if(cmTarget::LinkInterfaceLibraries const* iface = - target->GetLinkInterfaceLibraries(context->Config, headTarget, true)) - { - linkedTargetsContent = - getLinkedTargetsContent(iface->Libraries, target, - headTarget, - context, &dagChecker, - interfacePropertyName); - } - } - else if(!interfacePropertyName.empty()) - { - if(cmTarget::LinkImplementationLibraries const* impl = - target->GetLinkImplementationLibraries(context->Config)) - { - linkedTargetsContent = - getLinkedTargetsContent(impl->Libraries, target, - target, - context, &dagChecker, - interfacePropertyName); - } - } - - if (!prop) - { - if (target->IsImported() - || target->GetType() == cmTarget::INTERFACE_LIBRARY) - { - return linkedTargetsContent; - } - if (target->IsLinkInterfaceDependentBoolProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - return target->GetLinkInterfaceDependentBoolProperty( - propertyName, - context->Config) ? "1" : "0"; - } - if (target->IsLinkInterfaceDependentStringProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - const char *propContent = - target->GetLinkInterfaceDependentStringProperty( - propertyName, - context->Config); - return propContent ? propContent : ""; - } - if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - const char *propContent = - target->GetLinkInterfaceDependentNumberMinProperty( - propertyName, - context->Config); - return propContent ? propContent : ""; - } - if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - const char *propContent = - target->GetLinkInterfaceDependentNumberMaxProperty( - propertyName, - context->Config); - return propContent ? propContent : ""; - } - - return linkedTargetsContent; - } - - if (!target->IsImported() - && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries()) - { - if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - const char *propContent = - target->GetLinkInterfaceDependentNumberMinProperty( - propertyName, - context->Config); - return propContent ? propContent : ""; - } - if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, - context->Config)) - { - context->HadContextSensitiveCondition = true; - const char *propContent = - target->GetLinkInterfaceDependentNumberMaxProperty( - propertyName, - context->Config); - return propContent ? propContent : ""; - } - } - if(!interfacePropertyName.empty()) - { - std::string result = this->EvaluateDependentExpression(prop, - context->Makefile, context, - headTarget, target, &dagChecker); - if (!linkedTargetsContent.empty()) - { - result += (result.empty() ? "" : ";") + linkedTargetsContent; - } - return result; - } - return prop; - } -} targetPropertyNode; - -//---------------------------------------------------------------------------- -static const struct TargetNameNode : public cmGeneratorExpressionNode -{ - TargetNameNode() {} - - virtual bool GeneratesContent() const { return true; } - - virtual bool AcceptsArbitraryContentParameter() const { return true; } - virtual bool RequiresLiteralInput() const { return true; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *, - const GeneratorExpressionContent *, - cmGeneratorExpressionDAGChecker *) const - { - return parameters.front(); - } - - virtual int NumExpectedParameters() const { return 1; } - -} targetNameNode; - -//---------------------------------------------------------------------------- -static const struct TargetObjectsNode : public cmGeneratorExpressionNode -{ - TargetObjectsNode() {} - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - if (!context->EvaluateForBuildsystem) - { - 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."; - reportError(context, content->GetOriginalExpression(), e.str()); - return std::string(); - } - - std::string tgtName = parameters.front(); - cmGeneratorTarget* gt = - context->Makefile->FindGeneratorTargetToUse(tgtName); - if (!gt) - { - std::ostringstream e; - e << "Objects of target \"" << tgtName - << "\" referenced but no such target exists."; - reportError(context, content->GetOriginalExpression(), e.str()); - return std::string(); - } - if (gt->GetType() != cmTarget::OBJECT_LIBRARY) - { - std::ostringstream e; - e << "Objects of target \"" << tgtName - << "\" referenced but is not an OBJECT library."; - reportError(context, content->GetOriginalExpression(), e.str()); - return std::string(); - } - - std::vector<cmSourceFile const*> objectSources; - gt->GetObjectSources(objectSources, context->Config); - std::map<cmSourceFile const*, std::string> mapping; - - for(std::vector<cmSourceFile const*>::const_iterator it - = objectSources.begin(); it != objectSources.end(); ++it) - { - mapping[*it]; - } - - gt->LocalGenerator->ComputeObjectFilenames(mapping, gt); - - std::string obj_dir = gt->ObjectDirectory; - std::string result; - const char* sep = ""; - for(std::vector<cmSourceFile const*>::const_iterator it - = objectSources.begin(); it != objectSources.end(); ++it) - { - // 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 + map_it->second; - cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true); - sf->SetObjectLibrary(tgtName); - sf->SetProperty("EXTERNAL_OBJECT", "1"); - result += objFile; - sep = ";"; - } - return result; - } -} targetObjectsNode; - -//---------------------------------------------------------------------------- -static const struct CompileFeaturesNode : public cmGeneratorExpressionNode -{ - CompileFeaturesNode() {} - - virtual int NumExpectedParameters() const { return OneOrMoreParameters; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - cmTarget const* target = context->HeadTarget; - if (!target) - { - reportError(context, content->GetOriginalExpression(), - "$<COMPILE_FEATURE> may only be used with binary targets. It may " - "not be used with add_custom_command or add_custom_target."); - return std::string(); - } - context->HadHeadSensitiveCondition = true; - - typedef std::map<std::string, std::vector<std::string> > LangMap; - static LangMap availableFeatures; - - LangMap testedFeatures; - - for (std::vector<std::string>::const_iterator it = parameters.begin(); - it != parameters.end(); ++it) - { - std::string error; - std::string lang; - if (!context->Makefile->CompileFeatureKnown(context->HeadTarget, - *it, lang, &error)) - { - reportError(context, content->GetOriginalExpression(), error); - return std::string(); - } - testedFeatures[lang].push_back(*it); - - if (availableFeatures.find(lang) == availableFeatures.end()) - { - const char* featuresKnown - = context->Makefile->CompileFeaturesAvailable(lang, &error); - if (!featuresKnown) - { - reportError(context, content->GetOriginalExpression(), error); - return std::string(); - } - cmSystemTools::ExpandListArgument(featuresKnown, - availableFeatures[lang]); - } - } - - bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries(); - - std::string result; - - for (LangMap::const_iterator lit = testedFeatures.begin(); - lit != testedFeatures.end(); ++lit) - { - std::vector<std::string> const& langAvailable - = availableFeatures[lit->first]; - const char* standardDefault = context->Makefile - ->GetDefinition("CMAKE_" + lit->first + "_STANDARD_DEFAULT"); - for (std::vector<std::string>::const_iterator it = lit->second.begin(); - it != lit->second.end(); ++it) - { - if (std::find(langAvailable.begin(), langAvailable.end(), *it) - == langAvailable.end()) - { - return "0"; - } - if (standardDefault && !*standardDefault) - { - // This compiler has no notion of language standard levels. - // All features known for the language are always available. - continue; - } - if (!context->Makefile->HaveStandardAvailable(target, - lit->first, *it)) - { - if (evalLL) - { - const char* l = target->GetProperty(lit->first + "_STANDARD"); - if (!l) - { - l = standardDefault; - } - assert(l); - context->MaxLanguageStandard[target][lit->first] = l; - } - else - { - return "0"; - } - } - } - } - return "1"; - } -} compileFeaturesNode; - -//---------------------------------------------------------------------------- -static const char* targetPolicyWhitelist[] = { - 0 -#define TARGET_POLICY_STRING(POLICY) \ - , #POLICY - - CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING) - -#undef TARGET_POLICY_STRING -}; - -cmPolicies::PolicyStatus statusForTarget(cmTarget const* tgt, - const char *policy) -{ -#define RETURN_POLICY(POLICY) \ - if (strcmp(policy, #POLICY) == 0) \ - { \ - return tgt->GetPolicyStatus ## POLICY (); \ - } \ - - CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY) - -#undef RETURN_POLICY - - assert(0 && "Unreachable code. Not a valid policy"); - return cmPolicies::WARN; -} - -cmPolicies::PolicyID policyForString(const char *policy_id) -{ -#define RETURN_POLICY_ID(POLICY_ID) \ - if (strcmp(policy_id, #POLICY_ID) == 0) \ - { \ - return cmPolicies:: POLICY_ID; \ - } \ - - CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID) - -#undef RETURN_POLICY_ID - - assert(0 && "Unreachable code. Not a valid policy"); - return cmPolicies::CMP0002; -} - -//---------------------------------------------------------------------------- -static const struct TargetPolicyNode : public cmGeneratorExpressionNode -{ - TargetPolicyNode() {} - - virtual int NumExpectedParameters() const { return 1; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context , - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - if (!context->HeadTarget) - { - reportError(context, content->GetOriginalExpression(), - "$<TARGET_POLICY:prop> may only be used with binary targets. It " - "may not be used with add_custom_command or add_custom_target."); - return std::string(); - } - - context->HadContextSensitiveCondition = true; - context->HadHeadSensitiveCondition = true; - - for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i) - { - const char *policy = targetPolicyWhitelist[i]; - if (parameters.front() == policy) - { - cmMakefile *mf = context->HeadTarget->GetMakefile(); - switch(statusForTarget(context->HeadTarget, policy)) - { - case cmPolicies::WARN: - mf->IssueMessage(cmake::AUTHOR_WARNING, - mf->GetPolicies()-> - GetPolicyWarning(policyForString(policy))); - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::OLD: - return "0"; - case cmPolicies::NEW: - return "1"; - } - } - } - reportError(context, content->GetOriginalExpression(), - "$<TARGET_POLICY:prop> may only be used with a limited number of " - "policies. Currently it may be used with the following policies:\n" - -#define STRINGIFY_HELPER(X) #X -#define STRINGIFY(X) STRINGIFY_HELPER(X) - -#define TARGET_POLICY_LIST_ITEM(POLICY) \ - " * " STRINGIFY(POLICY) "\n" - - CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM) - -#undef TARGET_POLICY_LIST_ITEM - ); - return std::string(); - } - -} targetPolicyNode; - -//---------------------------------------------------------------------------- -static const struct InstallPrefixNode : public cmGeneratorExpressionNode -{ - InstallPrefixNode() {} - - virtual bool GeneratesContent() const { return true; } - virtual int NumExpectedParameters() const { return 0; } - - std::string Evaluate(const std::vector<std::string> &, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *) const - { - reportError(context, content->GetOriginalExpression(), - "INSTALL_PREFIX is a marker for install(EXPORT) only. It " - "should never be evaluated."); - return std::string(); - } - -} installPrefixNode; - -//---------------------------------------------------------------------------- -class ArtifactNameTag; -class ArtifactLinkerTag; -class ArtifactSonameTag; -class ArtifactPdbTag; - -class ArtifactPathTag; -class ArtifactDirTag; -class ArtifactNameTag; - -//---------------------------------------------------------------------------- -template<typename ArtifactT> -struct TargetFilesystemArtifactResultCreator -{ - static std::string Create(cmTarget* target, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content); -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag> -{ - static std::string Create(cmTarget* target, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content) - { - // The target soname file (.so.1). - if(target->IsDLLPlatform()) - { - ::reportError(context, content->GetOriginalExpression(), - "TARGET_SONAME_FILE is not allowed " - "for DLL target platforms."); - return std::string(); - } - if(target->GetType() != cmTarget::SHARED_LIBRARY) - { - ::reportError(context, content->GetOriginalExpression(), - "TARGET_SONAME_FILE is allowed only for " - "SHARED libraries."); - return std::string(); - } - std::string result = target->GetDirectory(context->Config); - result += "/"; - result += target->GetSOName(context->Config); - return result; - } -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag> -{ - static std::string Create(cmTarget* target, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content) - { - std::string language = target->GetLinkerLanguage(context->Config); - - std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB"; - - if(!context->Makefile->IsOn(pdbSupportVar)) - { - ::reportError(context, content->GetOriginalExpression(), - "TARGET_PDB_FILE is not supported by the target linker."); - return std::string(); - } - - cmTarget::TargetType targetType = target->GetType(); - - if(targetType != cmTarget::SHARED_LIBRARY && - targetType != cmTarget::MODULE_LIBRARY && - targetType != cmTarget::EXECUTABLE) - { - ::reportError(context, content->GetOriginalExpression(), - "TARGET_PDB_FILE is allowed only for " - "targets with linker created artifacts."); - return std::string(); - } - - std::string result = target->GetPDBDirectory(context->Config); - result += "/"; - result += target->GetPDBName(context->Config); - return result; - } -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag> -{ - static std::string Create(cmTarget* target, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content) - { - // The file used to link to the target (.so, .lib, .a). - if(!target->IsLinkable()) - { - ::reportError(context, content->GetOriginalExpression(), - "TARGET_LINKER_FILE is allowed only for libraries and " - "executables with ENABLE_EXPORTS."); - return std::string(); - } - return target->GetFullPath(context->Config, - target->HasImportLibrary()); - } -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultCreator<ArtifactNameTag> -{ - static std::string Create(cmTarget* target, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *) - { - return target->GetFullPath(context->Config, false, true); - } -}; - - -//---------------------------------------------------------------------------- -template<typename ArtifactT> -struct TargetFilesystemArtifactResultGetter -{ - static std::string Get(const std::string &result); -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultGetter<ArtifactNameTag> -{ - static std::string Get(const std::string &result) - { return cmSystemTools::GetFilenameName(result); } -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultGetter<ArtifactDirTag> -{ - static std::string Get(const std::string &result) - { return cmSystemTools::GetFilenamePath(result); } -}; - -//---------------------------------------------------------------------------- -template<> -struct TargetFilesystemArtifactResultGetter<ArtifactPathTag> -{ - static std::string Get(const std::string &result) - { return result; } -}; - -//---------------------------------------------------------------------------- -template<typename ArtifactT, typename ComponentT> -struct TargetFilesystemArtifact : public cmGeneratorExpressionNode -{ - TargetFilesystemArtifact() {} - - virtual int NumExpectedParameters() const { return 1; } - - std::string Evaluate(const std::vector<std::string> ¶meters, - cmGeneratorExpressionContext *context, - const GeneratorExpressionContent *content, - cmGeneratorExpressionDAGChecker *dagChecker) const - { - // Lookup the referenced target. - std::string name = *parameters.begin(); - - if (!cmGeneratorExpression::IsValidTargetName(name)) - { - ::reportError(context, content->GetOriginalExpression(), - "Expression syntax not recognized."); - return std::string(); - } - cmTarget* target = context->Makefile->FindTargetToUse(name); - if(!target) - { - ::reportError(context, content->GetOriginalExpression(), - "No target \"" + name + "\""); - return std::string(); - } - if(target->GetType() >= cmTarget::OBJECT_LIBRARY && - target->GetType() != cmTarget::UNKNOWN_LIBRARY) - { - ::reportError(context, content->GetOriginalExpression(), - "Target \"" + name + "\" is not an executable or library."); - return std::string(); - } - if (dagChecker && (dagChecker->EvaluatingLinkLibraries(name.c_str()) - || (dagChecker->EvaluatingSources() - && name == dagChecker->TopTarget()))) - { - ::reportError(context, content->GetOriginalExpression(), - "Expressions which require the linker language may not " - "be used while evaluating link libraries"); - return std::string(); - } - context->DependTargets.insert(target); - context->AllTargets.insert(target); - - std::string result = - TargetFilesystemArtifactResultCreator<ArtifactT>::Create( - target, - context, - content); - if (context->HadError) - { - return std::string(); - } - return - TargetFilesystemArtifactResultGetter<ComponentT>::Get(result); - } -}; - -//---------------------------------------------------------------------------- -template<typename ArtifactT> -struct TargetFilesystemArtifactNodeGroup -{ - TargetFilesystemArtifactNodeGroup() - { - } - - TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File; - TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName; - TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir; -}; - -//---------------------------------------------------------------------------- -static const -TargetFilesystemArtifactNodeGroup<ArtifactNameTag> targetNodeGroup; - -static const -TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup; - -static const -TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup; - -static const -TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup; - -//---------------------------------------------------------------------------- -static const -cmGeneratorExpressionNode* GetNode(const std::string &identifier) -{ - typedef std::map<std::string, const cmGeneratorExpressionNode*> NodeMap; - static NodeMap nodeMap; - if (nodeMap.empty()) - { - nodeMap["0"] = &zeroNode; - nodeMap["1"] = &oneNode; - nodeMap["AND"] = &andNode; - nodeMap["OR"] = &orNode; - nodeMap["NOT"] = ¬Node; - nodeMap["C_COMPILER_ID"] = &cCompilerIdNode; - nodeMap["CXX_COMPILER_ID"] = &cxxCompilerIdNode; - nodeMap["VERSION_GREATER"] = &versionGreaterNode; - nodeMap["VERSION_LESS"] = &versionLessNode; - nodeMap["VERSION_EQUAL"] = &versionEqualNode; - nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode; - nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode; - nodeMap["PLATFORM_ID"] = &platformIdNode; - nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode; - nodeMap["CONFIGURATION"] = &configurationNode; - nodeMap["CONFIG"] = &configurationTestNode; - nodeMap["TARGET_FILE"] = &targetNodeGroup.File; - nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File; - nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File; - nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File; - nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName; - nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName; - nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName; - nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName; - nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir; - nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir; - nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir; - nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir; - nodeMap["STREQUAL"] = &strEqualNode; - nodeMap["EQUAL"] = &equalNode; - nodeMap["LOWER_CASE"] = &lowerCaseNode; - nodeMap["UPPER_CASE"] = &upperCaseNode; - nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode; - nodeMap["BOOL"] = &boolNode; - nodeMap["ANGLE-R"] = &angle_rNode; - nodeMap["COMMA"] = &commaNode; - nodeMap["SEMICOLON"] = &semicolonNode; - nodeMap["TARGET_PROPERTY"] = &targetPropertyNode; - nodeMap["TARGET_NAME"] = &targetNameNode; - nodeMap["TARGET_OBJECTS"] = &targetObjectsNode; - nodeMap["TARGET_POLICY"] = &targetPolicyNode; - nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode; - nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode; - nodeMap["INSTALL_PREFIX"] = &installPrefixNode; - nodeMap["JOIN"] = &joinNode; - nodeMap["LINK_ONLY"] = &linkOnlyNode; - } - NodeMap::const_iterator i = nodeMap.find(identifier); - if (i == nodeMap.end()) - { - return 0; - } - return i->second; - -} +#include "cmGeneratorExpressionNode.h" //---------------------------------------------------------------------------- GeneratorExpressionContent::GeneratorExpressionContent( @@ -1929,7 +114,8 @@ std::string GeneratorExpressionContent::Evaluate( } } - const cmGeneratorExpressionNode *node = GetNode(identifier); + const cmGeneratorExpressionNode *node = + cmGeneratorExpressionNode::GetNode(identifier); if (!node) { diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 0bf1797..7c1bd8c 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -16,36 +16,10 @@ #include <string> #include "cmListFileCache.h" +#include "cmGeneratorExpressionContext.h" class cmTarget; -//---------------------------------------------------------------------------- -struct cmGeneratorExpressionContext -{ - cmGeneratorExpressionContext() - : Backtrace(NULL) - { - } - - cmListFileBacktrace Backtrace; - 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; - std::string Config; - cmTarget const* HeadTarget; // The target whose property is being evaluated. - cmTarget const* CurrentTarget; // The dependent of HeadTarget which appears - // directly or indirectly in the property. - bool Quiet; - bool HadError; - bool HadContextSensitiveCondition; - bool HadHeadSensitiveCondition; - bool EvaluateForBuildsystem; -}; - struct cmGeneratorExpressionDAGChecker; struct cmGeneratorExpressionNode; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx new file mode 100644 index 0000000..673dcb9 --- /dev/null +++ b/Source/cmGeneratorExpressionNode.cxx @@ -0,0 +1,1870 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmGeneratorExpressionNode.h" +#include "cmGlobalGenerator.h" +#include "cmAlgorithms.h" + +//---------------------------------------------------------------------------- +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, + context->Language); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + if (cge->GetHadHeadSensitiveCondition()) + { + context->HadHeadSensitiveCondition = true; + } + return result; +} + +//---------------------------------------------------------------------------- +static const struct ZeroNode : public cmGeneratorExpressionNode +{ + ZeroNode() {} + + virtual bool GeneratesContent() const { return false; } + + virtual bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return std::string(); + } +} zeroNode; + +//---------------------------------------------------------------------------- +static const struct OneNode : public cmGeneratorExpressionNode +{ + OneNode() {} + + virtual bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return parameters.front(); + } +} oneNode; + +//---------------------------------------------------------------------------- +static const struct OneNode buildInterfaceNode; + +//---------------------------------------------------------------------------- +static const struct ZeroNode installInterfaceNode; + +//---------------------------------------------------------------------------- +#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ +static const struct OP ## Node : public cmGeneratorExpressionNode \ +{ \ + OP ## Node () {} \ + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \ + \ + std::string Evaluate(const std::vector<std::string> ¶meters, \ + cmGeneratorExpressionContext *context, \ + const GeneratorExpressionContent *content, \ + cmGeneratorExpressionDAGChecker *) const \ + { \ + std::vector<std::string>::const_iterator it = parameters.begin(); \ + const std::vector<std::string>::const_iterator end = parameters.end(); \ + for ( ; it != end; ++it) \ + { \ + if (*it == #FAILURE_VALUE) \ + { \ + return #FAILURE_VALUE; \ + } \ + else if (*it != #SUCCESS_VALUE) \ + { \ + reportError(context, content->GetOriginalExpression(), \ + "Parameters to $<" #OP "> must resolve to either '0' or '1'."); \ + return std::string(); \ + } \ + } \ + return #SUCCESS_VALUE; \ + } \ +} OPNAME; + +BOOLEAN_OP_NODE(andNode, AND, 1, 0) +BOOLEAN_OP_NODE(orNode, OR, 0, 1) + +#undef BOOLEAN_OP_NODE + +//---------------------------------------------------------------------------- +static const struct NotNode : public cmGeneratorExpressionNode +{ + NotNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (*parameters.begin() != "0" && *parameters.begin() != "1") + { + reportError(context, content->GetOriginalExpression(), + "$<NOT> parameter must resolve to exactly one '0' or '1' value."); + return std::string(); + } + return *parameters.begin() == "0" ? "1" : "0"; + } +} notNode; + +//---------------------------------------------------------------------------- +static const struct BoolNode : public cmGeneratorExpressionNode +{ + BoolNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return !cmSystemTools::IsOff(parameters.begin()->c_str()) ? "1" : "0"; + } +} boolNode; + +//---------------------------------------------------------------------------- +static const struct StrEqualNode : public cmGeneratorExpressionNode +{ + StrEqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return *parameters.begin() == parameters[1] ? "1" : "0"; + } +} strEqualNode; + +//---------------------------------------------------------------------------- +static const struct EqualNode : public cmGeneratorExpressionNode +{ + EqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + char *pEnd; + + int base = 0; + bool flipSign = false; + + const char *lhs = parameters[0].c_str(); + if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B")) + { + base = 2; + lhs += 2; + } + if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B")) + { + base = 2; + lhs += 3; + flipSign = true; + } + if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B")) + { + base = 2; + lhs += 3; + } + + long lnum = strtol(lhs, &pEnd, base); + if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) + { + reportError(context, content->GetOriginalExpression(), + "$<EQUAL> parameter " + parameters[0] + " is not a valid integer."); + return std::string(); + } + + if (flipSign) + { + lnum = -lnum; + } + + base = 0; + flipSign = false; + + const char *rhs = parameters[1].c_str(); + if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B")) + { + base = 2; + rhs += 2; + } + if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B")) + { + base = 2; + rhs += 3; + flipSign = true; + } + if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B")) + { + base = 2; + rhs += 3; + } + + long rnum = strtol(rhs, &pEnd, base); + if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) + { + reportError(context, content->GetOriginalExpression(), + "$<EQUAL> parameter " + parameters[1] + " is not a valid integer."); + return std::string(); + } + + if (flipSign) + { + rnum = -rnum; + } + + return lnum == rnum ? "1" : "0"; + } +} equalNode; + +//---------------------------------------------------------------------------- +static const struct LowerCaseNode : public cmGeneratorExpressionNode +{ + LowerCaseNode() {} + + bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::LowerCase(parameters.front()); + } +} lowerCaseNode; + +//---------------------------------------------------------------------------- +static const struct UpperCaseNode : public cmGeneratorExpressionNode +{ + UpperCaseNode() {} + + bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::UpperCase(parameters.front()); + } +} upperCaseNode; + +//---------------------------------------------------------------------------- +static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode +{ + MakeCIdentifierNode() {} + + bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::MakeCidentifier(parameters.front()); + } +} makeCIdentifierNode; + +//---------------------------------------------------------------------------- +static const struct Angle_RNode : public cmGeneratorExpressionNode +{ + Angle_RNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ">"; + } +} angle_rNode; + +//---------------------------------------------------------------------------- +static const struct CommaNode : public cmGeneratorExpressionNode +{ + CommaNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ","; + } +} commaNode; + +//---------------------------------------------------------------------------- +static const struct SemicolonNode : public cmGeneratorExpressionNode +{ + SemicolonNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return ";"; + } +} semicolonNode; + +//---------------------------------------------------------------------------- +struct CompilerIdNode : public cmGeneratorExpressionNode +{ + CompilerIdNode() {} + + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } + + std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *, + const std::string &lang) const + { + const char *compilerId = + context->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID"); + if (parameters.empty()) + { + return compilerId ? compilerId : ""; + } + static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$"); + if (!compilerIdValidator.find(*parameters.begin())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!compilerId) + { + return parameters.front().empty() ? "1" : "0"; + } + + if (strcmp(parameters.begin()->c_str(), compilerId) == 0) + { + return "1"; + } + + if (cmsysString_strcasecmp(parameters.begin()->c_str(), compilerId) == 0) + { + switch(context->Makefile->GetPolicyStatus(cmPolicies::CMP0044)) + { + case cmPolicies::WARN: + { + std::ostringstream e; + e << context->Makefile->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0044); + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::AUTHOR_WARNING, + e.str(), context->Backtrace); + } + case cmPolicies::OLD: + return "1"; + case cmPolicies::NEW: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + break; + } + } + return "0"; + } +}; + +//---------------------------------------------------------------------------- +static const struct CCompilerIdNode : public CompilerIdNode +{ + CCompilerIdNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_ID> may only be used with binary targets. It may " + "not be used with add_custom_command or add_custom_target."); + return std::string(); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "C"); + } +} cCompilerIdNode; + +//---------------------------------------------------------------------------- +static const struct CXXCompilerIdNode : public CompilerIdNode +{ + CXXCompilerIdNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_ID> may only be used with binary targets. It may " + "not be used with add_custom_command or add_custom_target."); + return std::string(); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "CXX"); + } +} cxxCompilerIdNode; + +//---------------------------------------------------------------------------- +struct CompilerVersionNode : public cmGeneratorExpressionNode +{ + CompilerVersionNode() {} + + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } + + std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *, + const std::string &lang) const + { + const char *compilerVersion = context->Makefile->GetSafeDefinition( + "CMAKE_" + lang + "_COMPILER_VERSION"); + if (parameters.empty()) + { + return compilerVersion ? compilerVersion : ""; + } + + static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$"); + if (!compilerIdValidator.find(*parameters.begin())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + if (!compilerVersion) + { + return parameters.front().empty() ? "1" : "0"; + } + + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, + parameters.begin()->c_str(), + compilerVersion) ? "1" : "0"; + } +}; + +//---------------------------------------------------------------------------- +static const struct CCompilerVersionNode : public CompilerVersionNode +{ + CCompilerVersionNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<C_COMPILER_VERSION> may only be used with binary targets. It " + "may not be used with add_custom_command or add_custom_target."); + return std::string(); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "C"); + } +} cCompilerVersionNode; + +//---------------------------------------------------------------------------- +static const struct CxxCompilerVersionNode : public CompilerVersionNode +{ + CxxCompilerVersionNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<CXX_COMPILER_VERSION> may only be used with binary targets. It " + "may not be used with add_custom_command or add_custom_target."); + return std::string(); + } + return this->EvaluateWithLanguage(parameters, context, content, + dagChecker, "CXX"); + } +} cxxCompilerVersionNode; + + +//---------------------------------------------------------------------------- +struct PlatformIdNode : public cmGeneratorExpressionNode +{ + PlatformIdNode() {} + + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + const char *platformId = + context->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); + if (parameters.empty()) + { + return platformId ? platformId : ""; + } + + if (!platformId) + { + return parameters.front().empty() ? "1" : "0"; + } + + if (strcmp(parameters.begin()->c_str(), platformId) == 0) + { + return "1"; + } + return "0"; + } +} platformIdNode; + +//---------------------------------------------------------------------------- +static const struct VersionGreaterNode : public cmGeneratorExpressionNode +{ + VersionGreaterNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionGreaterNode; + +//---------------------------------------------------------------------------- +static const struct VersionLessNode : public cmGeneratorExpressionNode +{ + VersionLessNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionLessNode; + +//---------------------------------------------------------------------------- +static const struct VersionEqualNode : public cmGeneratorExpressionNode +{ + VersionEqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, + parameters.front().c_str(), + parameters[1].c_str()) ? "1" : "0"; + } +} versionEqualNode; + +//---------------------------------------------------------------------------- +static const struct LinkOnlyNode : public cmGeneratorExpressionNode +{ + LinkOnlyNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if(!dagChecker->GetTransitivePropertiesOnly()) + { + return parameters.front(); + } + return ""; + } +} linkOnlyNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationNode : public cmGeneratorExpressionNode +{ + ConfigurationNode() {} + + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + context->HadContextSensitiveCondition = true; + return context->Config; + } +} configurationNode; + +//---------------------------------------------------------------------------- +static const struct ConfigurationTestNode : public cmGeneratorExpressionNode +{ + ConfigurationTestNode() {} + + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (parameters.empty()) + { + return configurationNode.Evaluate(parameters, context, content, 0); + } + static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$"); + if (!configValidator.find(*parameters.begin())) + { + reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + context->HadContextSensitiveCondition = true; + if (context->Config.empty()) + { + return parameters.front().empty() ? "1" : "0"; + } + + if (cmsysString_strcasecmp(parameters.begin()->c_str(), + context->Config.c_str()) == 0) + { + return "1"; + } + + if (context->CurrentTarget + && context->CurrentTarget->IsImported()) + { + const char* loc = 0; + const char* imp = 0; + std::string suffix; + if (context->CurrentTarget->GetMappedConfig(context->Config, + &loc, + &imp, + suffix)) + { + // This imported target has an appropriate location + // for this (possibly mapped) config. + // Check if there is a proper config mapping for the tested config. + std::vector<std::string> mappedConfigs; + std::string mapProp = "MAP_IMPORTED_CONFIG_"; + mapProp += cmSystemTools::UpperCase(context->Config); + if(const char* mapValue = + context->CurrentTarget->GetProperty(mapProp)) + { + cmSystemTools::ExpandListArgument(cmSystemTools::UpperCase(mapValue), + mappedConfigs); + return std::find(mappedConfigs.begin(), mappedConfigs.end(), + cmSystemTools::UpperCase(parameters.front())) + != mappedConfigs.end() ? "1" : "0"; + } + } + } + return "0"; + } +} configurationTestNode; + +static const struct JoinNode : public cmGeneratorExpressionNode +{ + JoinNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + virtual bool AcceptsArbitraryContentParameter() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + std::vector<std::string> list; + cmSystemTools::ExpandListArgument(parameters.front(), list); + return cmJoin(list, parameters[1]); + } +} joinNode; + +static const struct CompileLanguageNode : public cmGeneratorExpressionNode +{ + CompileLanguageNode() {} + + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + if(context->Language.empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> may only be used to specify include " + "directories compile definitions, compile options and to evaluate " + "components of the file(GENERATE) command."); + return std::string(); + } + + std::vector<std::string> enabledLanguages; + cmGlobalGenerator* gg + = context->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + gg->GetEnabledLanguages(enabledLanguages); + if (!parameters.empty() && + std::find(enabledLanguages.begin(), enabledLanguages.end(), + parameters.front()) == enabledLanguages.end()) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> Unknown language."); + return std::string(); + } + std::string genName = gg->GetName(); + if (genName.find("Visual Studio") != std::string::npos) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> may not be used with Visual Studio " + "generators."); + return std::string(); + } + else if (genName.find("Xcode") != std::string::npos) + { + if (dagChecker && (dagChecker->EvaluatingCompileDefinitions() + || dagChecker->EvaluatingIncludeDirectories())) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS " + "with the Xcode generator."); + return std::string(); + } + } + else + { + if(genName.find("Makefiles") == std::string::npos && + genName.find("Ninja") == std::string::npos && + genName.find("Watcom WMake") == std::string::npos) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_LANGUAGE:...> not supported for this generator."); + return std::string(); + } + } + if (parameters.empty()) + { + return context->Language; + } + return context->Language == parameters.front() ? "1" : "0"; + } +} languageNode; + +#define TRANSITIVE_PROPERTY_NAME(PROPERTY) \ + , "INTERFACE_" #PROPERTY + +//---------------------------------------------------------------------------- +static const char* targetPropertyTransitiveWhitelist[] = { + 0 + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) +}; + +#undef TRANSITIVE_PROPERTY_NAME + +template <typename T> +std::string +getLinkedTargetsContent( + std::vector<T> const &libraries, + cmTarget const* target, + cmTarget const* headTarget, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) +{ + std::string linkedTargetsContent; + std::string sep; + std::string depString; + for (typename std::vector<T>::const_iterator it = libraries.begin(); + it != libraries.end(); ++it) + { + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + if (it->Target && it->Target != target) + { + depString += + sep + "$<TARGET_PROPERTY:" + + it->Target->GetName() + "," + interfacePropertyName + ">"; + sep = ";"; + } + } + if(!depString.empty()) + { + linkedTargetsContent = + cmGeneratorExpressionNode::EvaluateDependentExpression(depString, + target->GetMakefile(), context, + headTarget, target, dagChecker); + } + linkedTargetsContent = + cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); + return linkedTargetsContent; +} + +//---------------------------------------------------------------------------- +static const struct TargetPropertyNode : public cmGeneratorExpressionNode +{ + TargetPropertyNode() {} + + // This node handles errors on parameter count itself. + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagCheckerParent + ) const + { + if (parameters.size() != 1 && parameters.size() != 2) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression requires one or two parameters"); + return std::string(); + } + static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); + + cmTarget const* target = context->HeadTarget; + std::string propertyName = *parameters.begin(); + + if (parameters.size() == 1) + { + context->HadHeadSensitiveCondition = true; + } + if (!target && parameters.size() == 1) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:prop> may only be used with binary targets. " + "It may not be used with add_custom_command or add_custom_target. " + "Specify the target to read a property from using the " + "$<TARGET_PROPERTY:tgt,prop> signature instead."); + return std::string(); + } + + if (parameters.size() == 2) + { + if (parameters.begin()->empty() && parameters[1].empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name and property name."); + return std::string(); + } + if (parameters.begin()->empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty " + "target name."); + return std::string(); + } + + std::string targetName = parameters.front(); + propertyName = parameters[1]; + if (!cmGeneratorExpression::IsValidTargetName(targetName)) + { + if (!propertyNameValidator.find(propertyName.c_str())) + { + ::reportError(context, content->GetOriginalExpression(), + "Target name and property name not supported."); + return std::string(); + } + ::reportError(context, content->GetOriginalExpression(), + "Target name not supported."); + return std::string(); + } + if(propertyName == "ALIASED_TARGET") + { + if(context->Makefile->IsAlias(targetName)) + { + if(cmTarget* tgt = context->Makefile->FindTargetToUse(targetName)) + { + return tgt->GetName(); + } + } + return ""; + } + target = context->Makefile->FindTargetToUse(targetName); + + if (!target) + { + std::ostringstream e; + e << "Target \"" + << targetName + << "\" not found."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + context->AllTargets.insert(target); + } + + if (target == context->HeadTarget) + { + // Keep track of the properties seen while processing. + // The evaluation of the LINK_LIBRARIES generator expressions + // will check this to ensure that properties have one consistent + // value for all evaluations. + context->SeenTargetProperties.insert(propertyName); + } + if (propertyName == "SOURCES") + { + context->SourceSensitiveTargets.insert(target); + } + + if (propertyName.empty()) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression requires a non-empty property " + "name."); + return std::string(); + } + + if (!propertyNameValidator.find(propertyName)) + { + ::reportError(context, content->GetOriginalExpression(), + "Property name not supported."); + return std::string(); + } + + assert(target); + + if (propertyName == "LINKER_LANGUAGE") + { + if (target->LinkLanguagePropagatesToDependents() && + dagCheckerParent && (dagCheckerParent->EvaluatingLinkLibraries() + || dagCheckerParent->EvaluatingSources())) + { + reportError(context, content->GetOriginalExpression(), + "LINKER_LANGUAGE target property can not be used while evaluating " + "link libraries for a static library"); + return std::string(); + } + return target->GetLinkerLanguage(context->Config); + } + + cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, + target->GetName(), + propertyName, + content, + dagCheckerParent); + + switch (dagChecker.Check()) + { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: + dagChecker.ReportError(context, content->GetOriginalExpression()); + return std::string(); + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: + // No error. We just skip cyclic references. + return std::string(); + case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: + for (size_t i = 1; + i < cmArraySize(targetPropertyTransitiveWhitelist); + ++i) + { + if (targetPropertyTransitiveWhitelist[i] == propertyName) + { + // No error. We're not going to find anything new here. + return std::string(); + } + } + case cmGeneratorExpressionDAGChecker::DAG: + break; + } + + const char *prop = target->GetProperty(propertyName); + + if (dagCheckerParent) + { + if (dagCheckerParent->EvaluatingLinkLibraries()) + { +#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \ + (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) || + if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE) + false) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_PROPERTY:...> expression in link libraries " + "evaluation depends on target property which is transitive " + "over the link libraries, creating a recursion."); + return std::string(); + } +#undef TRANSITIVE_PROPERTY_COMPARE + + if(!prop) + { + return std::string(); + } + } + else + { +#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) \ + dagCheckerParent->METHOD () || + + assert( + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( + ASSERT_TRANSITIVE_PROPERTY_METHOD) + false); +#undef ASSERT_TRANSITIVE_PROPERTY_METHOD + } + } + + std::string linkedTargetsContent; + + std::string interfacePropertyName; + bool isInterfaceProperty = false; + +#define POPULATE_INTERFACE_PROPERTY_NAME(prop) \ + if (propertyName == #prop) \ + { \ + interfacePropertyName = "INTERFACE_" #prop; \ + } \ + else if (propertyName == "INTERFACE_" #prop) \ + { \ + interfacePropertyName = "INTERFACE_" #prop; \ + isInterfaceProperty = true; \ + } \ + else + + CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) + // Note that the above macro terminates with an else + /* else */ if (cmHasLiteralPrefix(propertyName.c_str(), + "COMPILE_DEFINITIONS_")) + { + cmPolicies::PolicyStatus polSt = + context->Makefile->GetPolicyStatus(cmPolicies::CMP0043); + if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) + { + interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; + } + } +#undef POPULATE_INTERFACE_PROPERTY_NAME + cmTarget const* headTarget = context->HeadTarget && isInterfaceProperty + ? context->HeadTarget : target; + + if(isInterfaceProperty) + { + if(cmTarget::LinkInterfaceLibraries const* iface = + target->GetLinkInterfaceLibraries(context->Config, headTarget, true)) + { + linkedTargetsContent = + getLinkedTargetsContent(iface->Libraries, target, + headTarget, + context, &dagChecker, + interfacePropertyName); + } + } + else if(!interfacePropertyName.empty()) + { + if(cmTarget::LinkImplementationLibraries const* impl = + target->GetLinkImplementationLibraries(context->Config)) + { + linkedTargetsContent = + getLinkedTargetsContent(impl->Libraries, target, + target, + context, &dagChecker, + interfacePropertyName); + } + } + + if (!prop) + { + if (target->IsImported() + || target->GetType() == cmTarget::INTERFACE_LIBRARY) + { + return linkedTargetsContent; + } + if (target->IsLinkInterfaceDependentBoolProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + return target->GetLinkInterfaceDependentBoolProperty( + propertyName, + context->Config) ? "1" : "0"; + } + if (target->IsLinkInterfaceDependentStringProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentStringProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + + return linkedTargetsContent; + } + + if (!target->IsImported() + && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries()) + { + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + } + if(!interfacePropertyName.empty()) + { + std::string result = this->EvaluateDependentExpression(prop, + context->Makefile, context, + headTarget, target, &dagChecker); + if (!linkedTargetsContent.empty()) + { + result += (result.empty() ? "" : ";") + linkedTargetsContent; + } + return result; + } + return prop; + } +} targetPropertyNode; + +//---------------------------------------------------------------------------- +static const struct TargetNameNode : public cmGeneratorExpressionNode +{ + TargetNameNode() {} + + virtual bool GeneratesContent() const { return true; } + + virtual bool AcceptsArbitraryContentParameter() const { return true; } + virtual bool RequiresLiteralInput() const { return true; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return parameters.front(); + } + + virtual int NumExpectedParameters() const { return 1; } + +} targetNameNode; + +//---------------------------------------------------------------------------- +static const struct TargetObjectsNode : public cmGeneratorExpressionNode +{ + TargetObjectsNode() {} + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (!context->EvaluateForBuildsystem) + { + 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."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + + std::string tgtName = parameters.front(); + cmGeneratorTarget* gt = + context->Makefile->FindGeneratorTargetToUse(tgtName); + if (!gt) + { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but no such target exists."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + if (gt->GetType() != cmTarget::OBJECT_LIBRARY) + { + std::ostringstream e; + e << "Objects of target \"" << tgtName + << "\" referenced but is not an OBJECT library."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + + std::vector<cmSourceFile const*> objectSources; + gt->GetObjectSources(objectSources, context->Config); + std::map<cmSourceFile const*, std::string> mapping; + + for(std::vector<cmSourceFile const*>::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) + { + mapping[*it]; + } + + gt->LocalGenerator->ComputeObjectFilenames(mapping, gt); + + std::string obj_dir = gt->ObjectDirectory; + std::string result; + const char* sep = ""; + for(std::vector<cmSourceFile const*>::const_iterator it + = objectSources.begin(); it != objectSources.end(); ++it) + { + // 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 + map_it->second; + cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true); + sf->SetObjectLibrary(tgtName); + sf->SetProperty("EXTERNAL_OBJECT", "1"); + result += objFile; + sep = ";"; + } + return result; + } +} targetObjectsNode; + +//---------------------------------------------------------------------------- +static const struct CompileFeaturesNode : public cmGeneratorExpressionNode +{ + CompileFeaturesNode() {} + + virtual int NumExpectedParameters() const { return OneOrMoreParameters; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + cmTarget const* target = context->HeadTarget; + if (!target) + { + reportError(context, content->GetOriginalExpression(), + "$<COMPILE_FEATURE> may only be used with binary targets. It may " + "not be used with add_custom_command or add_custom_target."); + return std::string(); + } + context->HadHeadSensitiveCondition = true; + + typedef std::map<std::string, std::vector<std::string> > LangMap; + static LangMap availableFeatures; + + LangMap testedFeatures; + + for (std::vector<std::string>::const_iterator it = parameters.begin(); + it != parameters.end(); ++it) + { + std::string error; + std::string lang; + if (!context->Makefile->CompileFeatureKnown(context->HeadTarget, + *it, lang, &error)) + { + reportError(context, content->GetOriginalExpression(), error); + return std::string(); + } + testedFeatures[lang].push_back(*it); + + if (availableFeatures.find(lang) == availableFeatures.end()) + { + const char* featuresKnown + = context->Makefile->CompileFeaturesAvailable(lang, &error); + if (!featuresKnown) + { + reportError(context, content->GetOriginalExpression(), error); + return std::string(); + } + cmSystemTools::ExpandListArgument(featuresKnown, + availableFeatures[lang]); + } + } + + bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries(); + + std::string result; + + for (LangMap::const_iterator lit = testedFeatures.begin(); + lit != testedFeatures.end(); ++lit) + { + std::vector<std::string> const& langAvailable + = availableFeatures[lit->first]; + const char* standardDefault = context->Makefile + ->GetDefinition("CMAKE_" + lit->first + "_STANDARD_DEFAULT"); + for (std::vector<std::string>::const_iterator it = lit->second.begin(); + it != lit->second.end(); ++it) + { + if (std::find(langAvailable.begin(), langAvailable.end(), *it) + == langAvailable.end()) + { + return "0"; + } + if (standardDefault && !*standardDefault) + { + // This compiler has no notion of language standard levels. + // All features known for the language are always available. + continue; + } + if (!context->Makefile->HaveStandardAvailable(target, + lit->first, *it)) + { + if (evalLL) + { + const char* l = target->GetProperty(lit->first + "_STANDARD"); + if (!l) + { + l = standardDefault; + } + assert(l); + context->MaxLanguageStandard[target][lit->first] = l; + } + else + { + return "0"; + } + } + } + } + return "1"; + } +} compileFeaturesNode; + +//---------------------------------------------------------------------------- +static const char* targetPolicyWhitelist[] = { + 0 +#define TARGET_POLICY_STRING(POLICY) \ + , #POLICY + + CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING) + +#undef TARGET_POLICY_STRING +}; + +cmPolicies::PolicyStatus statusForTarget(cmTarget const* tgt, + const char *policy) +{ +#define RETURN_POLICY(POLICY) \ + if (strcmp(policy, #POLICY) == 0) \ + { \ + return tgt->GetPolicyStatus ## POLICY (); \ + } \ + + CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY) + +#undef RETURN_POLICY + + assert(0 && "Unreachable code. Not a valid policy"); + return cmPolicies::WARN; +} + +cmPolicies::PolicyID policyForString(const char *policy_id) +{ +#define RETURN_POLICY_ID(POLICY_ID) \ + if (strcmp(policy_id, #POLICY_ID) == 0) \ + { \ + return cmPolicies:: POLICY_ID; \ + } \ + + CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID) + +#undef RETURN_POLICY_ID + + assert(0 && "Unreachable code. Not a valid policy"); + return cmPolicies::CMP0002; +} + +//---------------------------------------------------------------------------- +static const struct TargetPolicyNode : public cmGeneratorExpressionNode +{ + TargetPolicyNode() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context , + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + if (!context->HeadTarget) + { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_POLICY:prop> may only be used with binary targets. It " + "may not be used with add_custom_command or add_custom_target."); + return std::string(); + } + + context->HadContextSensitiveCondition = true; + context->HadHeadSensitiveCondition = true; + + for (size_t i = 1; i < cmArraySize(targetPolicyWhitelist); ++i) + { + const char *policy = targetPolicyWhitelist[i]; + if (parameters.front() == policy) + { + cmMakefile *mf = context->HeadTarget->GetMakefile(); + switch(statusForTarget(context->HeadTarget, policy)) + { + case cmPolicies::WARN: + mf->IssueMessage(cmake::AUTHOR_WARNING, + mf->GetPolicies()-> + GetPolicyWarning(policyForString(policy))); + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::OLD: + return "0"; + case cmPolicies::NEW: + return "1"; + } + } + } + reportError(context, content->GetOriginalExpression(), + "$<TARGET_POLICY:prop> may only be used with a limited number of " + "policies. Currently it may be used with the following policies:\n" + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +#define TARGET_POLICY_LIST_ITEM(POLICY) \ + " * " STRINGIFY(POLICY) "\n" + + CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM) + +#undef TARGET_POLICY_LIST_ITEM + ); + return std::string(); + } + +} targetPolicyNode; + +//---------------------------------------------------------------------------- +static const struct InstallPrefixNode : public cmGeneratorExpressionNode +{ + InstallPrefixNode() {} + + virtual bool GeneratesContent() const { return true; } + virtual int NumExpectedParameters() const { return 0; } + + std::string Evaluate(const std::vector<std::string> &, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + reportError(context, content->GetOriginalExpression(), + "INSTALL_PREFIX is a marker for install(EXPORT) only. It " + "should never be evaluated."); + return std::string(); + } + +} installPrefixNode; + +//---------------------------------------------------------------------------- +class ArtifactNameTag; +class ArtifactLinkerTag; +class ArtifactSonameTag; +class ArtifactPdbTag; + +class ArtifactPathTag; +class ArtifactDirTag; +class ArtifactNameTag; + +//---------------------------------------------------------------------------- +template<typename ArtifactT> +struct TargetFilesystemArtifactResultCreator +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The target soname file (.so.1). + if(target->IsDLLPlatform()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is not allowed " + "for DLL target platforms."); + return std::string(); + } + if(target->GetType() != cmTarget::SHARED_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_SONAME_FILE is allowed only for " + "SHARED libraries."); + return std::string(); + } + std::string result = target->GetDirectory(context->Config); + result += "/"; + result += target->GetSOName(context->Config); + return result; + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + std::string language = target->GetLinkerLanguage(context->Config); + + std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB"; + + if(!context->Makefile->IsOn(pdbSupportVar)) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_PDB_FILE is not supported by the target linker."); + return std::string(); + } + + cmTarget::TargetType targetType = target->GetType(); + + if(targetType != cmTarget::SHARED_LIBRARY && + targetType != cmTarget::MODULE_LIBRARY && + targetType != cmTarget::EXECUTABLE) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_PDB_FILE is allowed only for " + "targets with linker created artifacts."); + return std::string(); + } + + std::string result = target->GetPDBDirectory(context->Config); + result += "/"; + result += target->GetPDBName(context->Config); + return result; + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content) + { + // The file used to link to the target (.so, .lib, .a). + if(!target->IsLinkable()) + { + ::reportError(context, content->GetOriginalExpression(), + "TARGET_LINKER_FILE is allowed only for libraries and " + "executables with ENABLE_EXPORTS."); + return std::string(); + } + return target->GetFullPath(context->Config, + target->HasImportLibrary()); + } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultCreator<ArtifactNameTag> +{ + static std::string Create(cmTarget* target, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *) + { + return target->GetFullPath(context->Config, false, true); + } +}; + + +//---------------------------------------------------------------------------- +template<typename ArtifactT> +struct TargetFilesystemArtifactResultGetter +{ + static std::string Get(const std::string &result); +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<ArtifactNameTag> +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenameName(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<ArtifactDirTag> +{ + static std::string Get(const std::string &result) + { return cmSystemTools::GetFilenamePath(result); } +}; + +//---------------------------------------------------------------------------- +template<> +struct TargetFilesystemArtifactResultGetter<ArtifactPathTag> +{ + static std::string Get(const std::string &result) + { return result; } +}; + +//---------------------------------------------------------------------------- +template<typename ArtifactT, typename ComponentT> +struct TargetFilesystemArtifact : public cmGeneratorExpressionNode +{ + TargetFilesystemArtifact() {} + + virtual int NumExpectedParameters() const { return 1; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *dagChecker) const + { + // Lookup the referenced target. + std::string name = *parameters.begin(); + + if (!cmGeneratorExpression::IsValidTargetName(name)) + { + ::reportError(context, content->GetOriginalExpression(), + "Expression syntax not recognized."); + return std::string(); + } + cmTarget* target = context->Makefile->FindTargetToUse(name); + if(!target) + { + ::reportError(context, content->GetOriginalExpression(), + "No target \"" + name + "\""); + return std::string(); + } + if(target->GetType() >= cmTarget::OBJECT_LIBRARY && + target->GetType() != cmTarget::UNKNOWN_LIBRARY) + { + ::reportError(context, content->GetOriginalExpression(), + "Target \"" + name + "\" is not an executable or library."); + return std::string(); + } + if (dagChecker && (dagChecker->EvaluatingLinkLibraries(name.c_str()) + || (dagChecker->EvaluatingSources() + && name == dagChecker->TopTarget()))) + { + ::reportError(context, content->GetOriginalExpression(), + "Expressions which require the linker language may not " + "be used while evaluating link libraries"); + return std::string(); + } + context->DependTargets.insert(target); + context->AllTargets.insert(target); + + std::string result = + TargetFilesystemArtifactResultCreator<ArtifactT>::Create( + target, + context, + content); + if (context->HadError) + { + return std::string(); + } + return + TargetFilesystemArtifactResultGetter<ComponentT>::Get(result); + } +}; + +//---------------------------------------------------------------------------- +template<typename ArtifactT> +struct TargetFilesystemArtifactNodeGroup +{ + TargetFilesystemArtifactNodeGroup() + { + } + + TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File; + TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName; + TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir; +}; + +//---------------------------------------------------------------------------- +static const +TargetFilesystemArtifactNodeGroup<ArtifactNameTag> targetNodeGroup; + +static const +TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> targetLinkerNodeGroup; + +static const +TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup; + +static const +TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup; + +//---------------------------------------------------------------------------- +const cmGeneratorExpressionNode* +cmGeneratorExpressionNode::GetNode(const std::string &identifier) +{ + typedef std::map<std::string, const cmGeneratorExpressionNode*> NodeMap; + static NodeMap nodeMap; + if (nodeMap.empty()) + { + nodeMap["0"] = &zeroNode; + nodeMap["1"] = &oneNode; + nodeMap["AND"] = &andNode; + nodeMap["OR"] = &orNode; + nodeMap["NOT"] = ¬Node; + nodeMap["C_COMPILER_ID"] = &cCompilerIdNode; + nodeMap["CXX_COMPILER_ID"] = &cxxCompilerIdNode; + nodeMap["VERSION_GREATER"] = &versionGreaterNode; + nodeMap["VERSION_LESS"] = &versionLessNode; + nodeMap["VERSION_EQUAL"] = &versionEqualNode; + nodeMap["C_COMPILER_VERSION"] = &cCompilerVersionNode; + nodeMap["CXX_COMPILER_VERSION"] = &cxxCompilerVersionNode; + nodeMap["PLATFORM_ID"] = &platformIdNode; + nodeMap["COMPILE_FEATURES"] = &compileFeaturesNode; + nodeMap["CONFIGURATION"] = &configurationNode; + nodeMap["CONFIG"] = &configurationTestNode; + nodeMap["TARGET_FILE"] = &targetNodeGroup.File; + nodeMap["TARGET_LINKER_FILE"] = &targetLinkerNodeGroup.File; + nodeMap["TARGET_SONAME_FILE"] = &targetSoNameNodeGroup.File; + nodeMap["TARGET_PDB_FILE"] = &targetPdbNodeGroup.File; + nodeMap["TARGET_FILE_NAME"] = &targetNodeGroup.FileName; + nodeMap["TARGET_LINKER_FILE_NAME"] = &targetLinkerNodeGroup.FileName; + nodeMap["TARGET_SONAME_FILE_NAME"] = &targetSoNameNodeGroup.FileName; + nodeMap["TARGET_PDB_FILE_NAME"] = &targetPdbNodeGroup.FileName; + nodeMap["TARGET_FILE_DIR"] = &targetNodeGroup.FileDir; + nodeMap["TARGET_LINKER_FILE_DIR"] = &targetLinkerNodeGroup.FileDir; + nodeMap["TARGET_SONAME_FILE_DIR"] = &targetSoNameNodeGroup.FileDir; + nodeMap["TARGET_PDB_FILE_DIR"] = &targetPdbNodeGroup.FileDir; + nodeMap["STREQUAL"] = &strEqualNode; + nodeMap["EQUAL"] = &equalNode; + nodeMap["LOWER_CASE"] = &lowerCaseNode; + nodeMap["UPPER_CASE"] = &upperCaseNode; + nodeMap["MAKE_C_IDENTIFIER"] = &makeCIdentifierNode; + nodeMap["BOOL"] = &boolNode; + nodeMap["ANGLE-R"] = &angle_rNode; + nodeMap["COMMA"] = &commaNode; + nodeMap["SEMICOLON"] = &semicolonNode; + nodeMap["TARGET_PROPERTY"] = &targetPropertyNode; + nodeMap["TARGET_NAME"] = &targetNameNode; + nodeMap["TARGET_OBJECTS"] = &targetObjectsNode; + nodeMap["TARGET_POLICY"] = &targetPolicyNode; + nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode; + nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode; + nodeMap["INSTALL_PREFIX"] = &installPrefixNode; + nodeMap["JOIN"] = &joinNode; + nodeMap["LINK_ONLY"] = &linkOnlyNode; + nodeMap["COMPILE_LANGUAGE"] = &languageNode; + } + NodeMap::const_iterator i = nodeMap.find(identifier); + if (i == nodeMap.end()) + { + return 0; + } + return i->second; +} + +//---------------------------------------------------------------------------- +void reportError(cmGeneratorExpressionContext *context, + const std::string &expr, const std::string &result) +{ + context->HadError = true; + if (context->Quiet) + { + return; + } + + std::ostringstream e; + e << "Error evaluating generator expression:\n" + << " " << expr << "\n" + << result; + context->Makefile->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, e.str(), + context->Backtrace); +} diff --git a/Source/cmGeneratorExpressionNode.h b/Source/cmGeneratorExpressionNode.h new file mode 100644 index 0000000..847a00a --- /dev/null +++ b/Source/cmGeneratorExpressionNode.h @@ -0,0 +1,70 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly <steveire@gmail.com> + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmGeneratorExpressionNode_h +#define cmGeneratorExpressionNode_h + +#include "cmMakefile.h" + +#include "cmGeneratorExpressionEvaluator.h" +#include "cmGeneratorExpressionParser.h" +#include "cmGeneratorExpressionDAGChecker.h" +#include "cmGeneratorExpression.h" +#include "cmLocalGenerator.h" +#include "cmSourceFile.h" + +#include <cmsys/String.h> + +#include <assert.h> +#include <errno.h> + +#include "cmListFileCache.h" + +//---------------------------------------------------------------------------- +struct cmGeneratorExpressionNode +{ + enum { + DynamicParameters = 0, + OneOrMoreParameters = -1, + OneOrZeroParameters = -2 + }; + virtual ~cmGeneratorExpressionNode() {} + + virtual bool GeneratesContent() const { return true; } + + virtual bool RequiresLiteralInput() const { return false; } + + virtual bool AcceptsArbitraryContentParameter() const + { return false; } + + virtual int NumExpectedParameters() const { return 1; } + + virtual std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + 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); + + static const cmGeneratorExpressionNode* GetNode( + const std::string &identifier); +}; + +//---------------------------------------------------------------------------- +void reportError(cmGeneratorExpressionContext *context, + const std::string &expr, const std::string &result); + +#endif diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index a4f099b..e0af47a 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -20,6 +20,7 @@ #include "cmGeneratorExpressionDAGChecker.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" +#include "cmAlgorithms.h" #include <queue> @@ -528,23 +529,22 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs, std::vector<cmSourceFile const*> objectFiles; this->GetExternalObjects(objectFiles, config); std::vector<cmTarget*> objectLibraries; - std::set<cmTarget*> emitted; for(std::vector<cmSourceFile const*>::const_iterator it = objectFiles.begin(); it != objectFiles.end(); ++it) { std::string objLib = (*it)->GetObjectLibrary(); if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) { - if (emitted.insert(tgt).second) - { - objectLibraries.push_back(tgt); - } + objectLibraries.push_back(tgt); } } + std::vector<cmTarget*>::const_iterator end + = cmRemoveDuplicates(objectLibraries); + for(std::vector<cmTarget*>::const_iterator ti = objectLibraries.begin(); - ti != objectLibraries.end(); ++ti) + ti != end; ++ti) { cmTarget* objLib = *ti; cmGeneratorTarget* ogt = @@ -961,9 +961,10 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang, //---------------------------------------------------------------------------- std::vector<std::string> -cmGeneratorTarget::GetIncludeDirectories(const std::string& config) const +cmGeneratorTarget::GetIncludeDirectories(const std::string& config, + const std::string& lang) const { - return this->Target->GetIncludeDirectories(config); + return this->Target->GetIncludeDirectories(config, lang); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 2083b88..c329cf5 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -85,7 +85,7 @@ public: /** Get the include directories for this target. */ std::vector<std::string> GetIncludeDirectories( - const std::string& config) const; + const std::string& config, const std::string& lang) const; bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config) const; diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index e193cf5..85aa31f 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -14,6 +14,7 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmake.h" +#include "cmAlgorithms.h" // cmGetCMakePropertyCommand bool cmGetCMakePropertyCommand @@ -25,7 +26,6 @@ bool cmGetCMakePropertyCommand return false; } - std::vector<std::string>::size_type cc; std::string variable = args[0]; std::string output = "NOTFOUND"; @@ -35,16 +35,12 @@ bool cmGetCMakePropertyCommand std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly); if (!vars.empty()) { - output = vars[0]; - } - for ( cc = 1; cc < vars.size(); ++cc ) - { - output += ";"; - output += vars[cc]; + output = cmJoin(vars, ";"); } } else if ( args[1] == "MACROS" ) { + output.clear(); this->Makefile->GetListOfMacros(output); } else if ( args[1] == "COMPONENTS" ) @@ -52,16 +48,7 @@ bool cmGetCMakePropertyCommand const std::set<std::string>* components = this->Makefile->GetLocalGenerator()->GetGlobalGenerator() ->GetInstallComponents(); - std::set<std::string>::const_iterator compIt; - output = ""; - for (compIt = components->begin(); compIt != components->end(); ++compIt) - { - if (compIt != components->begin()) - { - output += ";"; - } - output += *compIt; - } + output = cmJoin(*components, ";"); } else { diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 120d2f8..005f0d6 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -46,6 +46,7 @@ public: cmMakefile *, bool optional); virtual bool AllowNotParallel() const { return false; } + virtual bool AllowDeleteOnError() const { return false; } }; #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 6d0fedc..8123c99 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -32,6 +32,7 @@ #include "cmGeneratorExpressionEvaluationFile.h" #include "cmExportBuildFileGenerator.h" #include "cmCPackPropertiesGenerator.h" +#include "cmAlgorithms.h" #include <cmsys/Directory.hxx> #include <cmsys/FStream.hxx> @@ -74,11 +75,7 @@ cmGlobalGenerator::cmGlobalGenerator() cmGlobalGenerator::~cmGlobalGenerator() { this->ClearGeneratorMembers(); - - if (this->ExtraGenerator) - { - delete this->ExtraGenerator; - } + delete this->ExtraGenerator; } bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p, @@ -1391,7 +1388,7 @@ void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens) cmQtAutoGenerators autogen; if(autogen.InitializeAutogenTarget(&target)) { - autogens.push_back(AutogensType::value_type(autogen, &target)); + autogens.push_back(std::make_pair(autogen, &target)); } } } @@ -1681,14 +1678,14 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir, mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); return this->Build(srcdir,bindir,projectName, newTarget, - output,"",config,false,fast, + output,"",config,false,fast,false, this->TryCompileTimeout); } void cmGlobalGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string&, const std::string&, const std::string&, const std::string&, - const std::string&, bool, + const std::string&, bool, bool, std::vector<std::string> const&) { makeCommand.push_back( @@ -1701,7 +1698,7 @@ int cmGlobalGenerator::Build( std::string& output, const std::string& makeCommandCSTR, const std::string& config, - bool clean, bool fast, + bool clean, bool fast, bool verbose, double timeout, cmSystemTools::OutputOption outputflag, std::vector<std::string> const& nativeOptions) @@ -1721,12 +1718,25 @@ int cmGlobalGenerator::Build( std::string outputBuffer; std::string* outputPtr = &outputBuffer; + std::vector<std::string> makeCommand; + this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, + bindir, target, config, fast, verbose, + nativeOptions); + + // Workaround to convince VCExpress.exe to produce output. + if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && + !makeCommand.empty() && cmSystemTools::LowerCase( + cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe") + { + outputflag = cmSystemTools::OUTPUT_NORMAL; + } + // should we do a clean first? if (clean) { std::vector<std::string> cleanCommand; this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, - bindir, "clean", config, fast); + bindir, "clean", config, fast, verbose); output += "\nRun Clean Command:"; output += cmSystemTools::PrintSingleCommand(cleanCommand); output += "\n"; @@ -1747,9 +1757,6 @@ int cmGlobalGenerator::Build( } // now build - std::vector<std::string> makeCommand; - this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, - bindir, target, config, fast, nativeOptions); std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand); output += "\nRun Build Command:"; output += makeCommandStr; @@ -2299,15 +2306,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets) std::ostringstream ostr; if (!componentsSet->empty()) { - ostr << "Available install components are:"; - std::set<std::string>::iterator it; - for ( - it = componentsSet->begin(); - it != componentsSet->end(); - ++ it ) - { - ostr << " \"" << *it << "\""; - } + ostr << "Available install components are: "; + ostr << cmWrap('"', *componentsSet, '"', " "); } else { @@ -2575,17 +2575,12 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name) "test", "RUN_TESTS", "package", "PACKAGE", "package_source", - "ZERO_CHECK", - 0 + "ZERO_CHECK" }; - for(const char** reservedTarget = reservedTargets; - *reservedTarget; ++reservedTarget) - { - if(name == *reservedTarget) return true; - } - - return false; + return std::find(cmArrayBegin(reservedTargets), + cmArrayEnd(reservedTargets), name) + != cmArrayEnd(reservedTargets); } void cmGlobalGenerator::SetExternalMakefileProjectGenerator( @@ -2941,14 +2936,11 @@ void cmGlobalGenerator::WriteSummary(cmTarget* target) { target->GetSourceFiles(sources, *ci); } - std::set<cmSourceFile*> emitted; + std::vector<cmSourceFile*>::const_iterator sourcesEnd + = cmRemoveDuplicates(sources); for(std::vector<cmSourceFile*>::const_iterator si = sources.begin(); - si != sources.end(); ++si) + si != sourcesEnd; ++si) { - if (!emitted.insert(*si).second) - { - continue; - } Json::Value& lj_source = lj_sources.append(Json::objectValue); cmSourceFile* sf = *si; std::string const& sfp = sf->GetFullPath(); @@ -3034,7 +3026,7 @@ void cmGlobalGenerator::AddEvaluationFile(const std::string &inputFile, //---------------------------------------------------------------------------- void cmGlobalGenerator::ProcessEvaluationFiles() { - std::set<std::string> generatedFiles; + std::vector<std::string> generatedFiles; for(std::vector<cmGeneratorExpressionEvaluationFile*>::const_iterator li = this->EvaluationFiles.begin(); li != this->EvaluationFiles.end(); @@ -3046,16 +3038,24 @@ void cmGlobalGenerator::ProcessEvaluationFiles() return; } std::vector<std::string> files = (*li)->GetFiles(); - for(std::vector<std::string>::const_iterator fi = files.begin(); - fi != files.end(); ++fi) + std::sort(files.begin(), files.end()); + + std::vector<std::string> intersection; + std::set_intersection(files.begin(), files.end(), + generatedFiles.begin(), generatedFiles.end(), + std::back_inserter(intersection)); + if (!intersection.empty()) { - if (!generatedFiles.insert(*fi).second) - { - cmSystemTools::Error("File to be generated by multiple different " - "commands: ", fi->c_str()); - return; - } + cmSystemTools::Error("Files to be generated by multiple different " + "commands: ", cmWrap('"', intersection, '"', " ").c_str()); + return; } + + generatedFiles.insert(generatedFiles.end(), + files.begin(), files.end()); + std::vector<std::string>::iterator newIt = + generatedFiles.end() - files.size(); + std::inplace_merge(generatedFiles.begin(), newIt, generatedFiles.end()); } } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 08f061a..5b9ddee 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -134,7 +134,7 @@ public: const std::string& projectName, const std::string& targetName, std::string& output, const std::string& makeProgram, const std::string& config, - bool clean, bool fast, + bool clean, bool fast, bool verbose, double timeout, cmSystemTools::OutputOption outputflag=cmSystemTools::OUTPUT_NONE, std::vector<std::string> const& nativeOptions = @@ -144,7 +144,8 @@ public: std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, + const std::string& targetName, const std::string& config, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 3c07be1..f74f1e0 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -17,6 +17,7 @@ #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" #include "cmVersion.h" +#include "cmAlgorithms.h" #include <algorithm> #include <assert.h> @@ -183,7 +184,10 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, i != outputs.end(); ++i) { build += " " + EncodeIdent(EncodePath(*i), os); - this->CombinedBuildOutputs.insert( EncodePath(*i) ); + if (this->ComputingUnknownDependencies) + { + this->CombinedBuildOutputs.insert( EncodePath(*i) ); + } } build += ":"; @@ -281,11 +285,14 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, orderOnly, vars); - //we need to track every dependency that comes in, since we are trying - //to find dependencies that are side effects of build commands - for(cmNinjaDeps::const_iterator i = deps.begin(); i != deps.end(); ++i) + if (this->ComputingUnknownDependencies) { - this->CombinedCustomCommandExplicitDependencies.insert( EncodePath(*i) ); + //we need to track every dependency that comes in, since we are trying + //to find dependencies that are side effects of build commands + for(cmNinjaDeps::const_iterator i = deps.begin(); i != deps.end(); ++i) + { + this->CombinedCustomCommandExplicitDependencies.insert(EncodePath(*i)); + } } } @@ -477,6 +484,8 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator() , CompileCommandsStream(0) , Rules() , AllDependencies() + , ComputingUnknownDependencies(false) + , PolicyCMP0058(cmPolicies::WARN) { // // Ninja is not ported to non-Unix OS yet. // this->ForceUnixPaths = true; @@ -510,6 +519,13 @@ void cmGlobalNinjaGenerator::Generate() this->OpenBuildFileStream(); this->OpenRulesFileStream(); + this->PolicyCMP0058 = + this->LocalGenerators[0]->GetMakefile() + ->GetPolicyStatus(cmPolicies::CMP0058); + this->ComputingUnknownDependencies = + (this->PolicyCMP0058 == cmPolicies::OLD || + this->PolicyCMP0058 == cmPolicies::WARN); + this->cmGlobalGenerator::Generate(); this->WriteAssumedSourceDependencies(); @@ -574,12 +590,18 @@ void cmGlobalNinjaGenerator const std::string& targetName, const std::string& /*config*/, bool /*fast*/, + bool verbose, std::vector<std::string> const& makeOptions) { makeCommand.push_back( this->SelectMakeProgram(makeProgram) ); + if(verbose) + { + makeCommand.push_back("-v"); + } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); if(!targetName.empty()) @@ -949,6 +971,18 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) { + if (!this->ComputingUnknownDependencies) + { + return; + } + + // We need to collect the set of known build outputs. + // Start with those generated by WriteBuild calls. + // No other method needs this so we can take ownership + // of the set locally and throw it out when we are done. + std::set<std::string> knownDependencies; + knownDependencies.swap(this->CombinedBuildOutputs); + //now write out the unknown explicit dependencies. //union the configured files, evaluations files and the CombinedBuildOutputs, @@ -965,7 +999,6 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) cmLocalNinjaGenerator *ng = static_cast<cmLocalNinjaGenerator *>(this->LocalGenerators[0]); - std::set<std::string> knownDependencies; for (std::vector<cmLocalGenerator *>::const_iterator i = this->LocalGenerators.begin(); i != this->LocalGenerators.end(); ++i) { @@ -1020,36 +1053,29 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) knownDependencies.insert( ng->ConvertToNinjaPath(i->first) ); } - //insert outputs from all WirteBuild commands - //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 - this->CombinedBuildOutputs.clear(); - //now we difference with CombinedCustomCommandExplicitDependencies to find //the list of items we know nothing about. //We have encoded all the paths in CombinedCustomCommandExplicitDependencies //and knownDependencies so no matter if unix or windows paths they //should all match now. - std::vector<std::string> unkownExplicitDepends; + std::vector<std::string> unknownExplicitDepends; this->CombinedCustomCommandExplicitDependencies.erase("all"); std::set_difference(this->CombinedCustomCommandExplicitDependencies.begin(), this->CombinedCustomCommandExplicitDependencies.end(), knownDependencies.begin(), knownDependencies.end(), - std::back_inserter(unkownExplicitDepends)); - + std::back_inserter(unknownExplicitDepends)); std::string const rootBuildDirectory = this->GetCMakeInstance()->GetHomeOutputDirectory(); + bool const inSourceBuild = + (rootBuildDirectory == this->GetCMakeInstance()->GetHomeDirectory()); + std::vector<std::string> warnExplicitDepends; for (std::vector<std::string>::const_iterator - i = unkownExplicitDepends.begin(); - i != unkownExplicitDepends.end(); + i = unknownExplicitDepends.begin(); + i != unknownExplicitDepends.end(); ++i) { //verify the file is in the build directory @@ -1063,9 +1089,35 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) this->WritePhonyBuild(os, "", deps, - deps); + cmNinjaDeps()); + if (this->PolicyCMP0058 == cmPolicies::WARN && + !inSourceBuild && warnExplicitDepends.size() < 10) + { + warnExplicitDepends.push_back(*i); + } } } + + if (!warnExplicitDepends.empty()) + { + std::ostringstream w; + w << + (this->GetCMakeInstance()->GetPolicies()-> + GetPolicyWarning(cmPolicies::CMP0058)) << "\n" + "This project specifies custom command DEPENDS on files " + "in the build tree that are not specified as the OUTPUT or " + "BYPRODUCTS of any add_custom_command or add_custom_target:\n" + " " << cmJoin(warnExplicitDepends, "\n ") << + "\n" + "For compatibility with versions of CMake that did not have " + "the BYPRODUCTS option, CMake is generating phony rules for " + "such files to convince 'ninja' to build." + "\n" + "Project authors should add the missing BYPRODUCTS or OUTPUT " + "options to the custom commands that produce these files." + ; + this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } } void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os) diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 3d443d8..6aa76f9 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -196,7 +196,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); @@ -368,6 +368,11 @@ private: /// The set of custom command outputs we have seen. std::set<std::string> CustomCommandOutputs; + /// Whether we are collecting known build outputs and needed + /// dependencies to determine unknown dependencies. + bool ComputingUnknownDependencies; + cmPolicies::PolicyStatus PolicyCMP0058; + /// The combined explicit dependencies of custom build commands std::set<std::string> CombinedCustomCommandExplicitDependencies; @@ -381,8 +386,6 @@ private: typedef std::map<std::string, cmTarget*> TargetAliasMap; TargetAliasMap TargetAliases; - static cmLocalGenerator* LocalGenerator; - static bool UsingMinGW; }; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 5f1bb83..7648813 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -18,6 +18,7 @@ #include "cmSourceFile.h" #include "cmTarget.h" #include "cmGeneratorTarget.h" +#include "cmAlgorithms.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() { @@ -554,7 +555,7 @@ void cmGlobalUnixMakefileGenerator3 const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, - bool fast, + bool fast, bool /*verbose*/, std::vector<std::string> const& makeOptions) { makeCommand.push_back( @@ -563,7 +564,7 @@ void cmGlobalUnixMakefileGenerator3 // Since we have full control over the invocation of nmake, let us // make it quiet. - if ( this->GetName() == "NMake Makefiles" ) + if (cmHasLiteralPrefix(this->GetName(), "NMake Makefiles")) { makeCommand.push_back("/NOLOGO"); } @@ -779,29 +780,24 @@ cmGlobalUnixMakefileGenerator3 localName += "/all"; depends.clear(); - std::string progressDir = - lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); + cmLocalUnixMakefileGenerator3::EchoProgress progress; + progress.Dir = lg->GetMakefile()->GetHomeOutputDirectory(); + progress.Dir += cmake::GetCMakeFilesDirectory(); + { + std::ostringstream progressArg; + const char* sep = ""; + std::vector<unsigned long>& progFiles = + this->ProgressMap[gtarget->Target].Marks; + for (std::vector<unsigned long>::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) { - std::ostringstream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; - // all target counts - progCmd << lg->Convert(progressDir, - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " "; - std::vector<unsigned long>& progFiles = - this->ProgressMap[gtarget->Target].Marks; - for (std::vector<unsigned long>::iterator i = progFiles.begin(); - i != progFiles.end(); ++i) - { - progCmd << " " << *i; - } - commands.push_back(progCmd.str()); + progressArg << sep << *i; + sep = ","; } - progressDir = "Built target "; - progressDir += name; - lg->AppendEcho(commands,progressDir.c_str()); + progress.Arg = progressArg.str(); + } + lg->AppendEcho(commands, "Built target " + name, + cmLocalUnixMakefileGenerator3::EchoNormal, &progress); this->AppendGlobalTargetDepends(depends,*gtarget->Target); lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", @@ -819,15 +815,13 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); - progressDir = lg->GetMakefile()->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); { // TODO: Convert the total progress count to a make variable. std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # in target - progCmd << lg->Convert(progressDir, + progCmd << lg->Convert(progress.Dir, cmLocalGenerator::FULL, cmLocalGenerator::SHELL); // @@ -843,7 +837,7 @@ cmGlobalUnixMakefileGenerator3 { std::ostringstream progCmd; progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0 - progCmd << lg->Convert(progressDir, + progCmd << lg->Convert(progress.Dir, cmLocalGenerator::FULL, cmLocalGenerator::SHELL); progCmd << " 0"; diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index c61c36e..a76a835 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -114,7 +114,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); @@ -128,6 +128,9 @@ public: /** Does the make tool tolerate .NOTPARALLEL? */ virtual bool AllowNotParallel() const { return true; } + /** Does the make tool tolerate .DELETE_ON_ERROR? */ + virtual bool AllowDeleteOnError() const { return true; } + virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; protected: void WriteMainMakefile2(); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 531a714..18d40e1 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -17,6 +17,7 @@ #include "cmVisualStudioSlnData.h" #include "cmVisualStudioSlnParser.h" #include "cmake.h" +#include "cmAlgorithms.h" static const char vs10generatorName[] = "Visual Studio 10 2010"; @@ -459,7 +460,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else MSBuild. @@ -507,7 +508,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( // Use devenv to build solutions containing Intel Fortran projects. cmGlobalVisualStudio7Generator::GenerateBuildCommand( makeCommand, makeProgram, projectName, projectDir, - targetName, config, fast, makeOptions); + targetName, config, fast, verbose, makeOptions); return; } diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 3b0a5cf..92202ba 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -41,7 +41,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index 3013200..ed828b6 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -12,6 +12,7 @@ #include "cmGlobalVisualStudio11Generator.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" static const char vs11generatorName[] = "Visual Studio 11 2012"; diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index 2bc9379..c2e6f47 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -12,6 +12,7 @@ #include "cmGlobalVisualStudio12Generator.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" static const char vs12generatorName[] = "Visual Studio 12 2013"; diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index fe702c0..b551c65 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -12,6 +12,7 @@ #include "cmGlobalVisualStudio14Generator.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" static const char vs14generatorName[] = "Visual Studio 14 2015"; diff --git a/Source/cmGlobalVisualStudio6Generator.cxx b/Source/cmGlobalVisualStudio6Generator.cxx index 455a7a2..62a308e 100644 --- a/Source/cmGlobalVisualStudio6Generator.cxx +++ b/Source/cmGlobalVisualStudio6Generator.cxx @@ -120,7 +120,7 @@ cmGlobalVisualStudio6Generator::GenerateBuildCommand( const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, - bool /*fast*/, + bool /*fast*/, bool /*verbose*/, std::vector<std::string> const& makeOptions ) { diff --git a/Source/cmGlobalVisualStudio6Generator.h b/Source/cmGlobalVisualStudio6Generator.h index 58efb25..a59a0b2 100644 --- a/Source/cmGlobalVisualStudio6Generator.h +++ b/Source/cmGlobalVisualStudio6Generator.h @@ -59,7 +59,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 401e475..0e0e63a 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -191,7 +191,7 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, - bool /*fast*/, + bool /*fast*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else devenv. diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 201a6a6..d641c02 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -69,7 +69,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); @@ -94,7 +94,8 @@ public: std::string& dir); ///! What is the configurations directory variable called? - virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; } + virtual const char* GetCMakeCFGIntDir() const + { return "$(ConfigurationName)"; } /** Return true if the target project file should have the option LinkLibraryDependencies and link to .sln dependencies. */ diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index 0e577b5..7bc209b 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -45,6 +45,7 @@ public: cmMakefile *, bool optional); virtual bool AllowNotParallel() const { return false; } + virtual bool AllowDeleteOnError() const { return false; } }; #endif diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index cd0dcc6..5e584a4 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -21,6 +21,7 @@ #include "cmCustomCommandGenerator.h" #include "cmGeneratorTarget.h" #include "cmGlobalGeneratorFactory.h" +#include "cmAlgorithms.h" #include <cmsys/auto_ptr.hxx> @@ -310,7 +311,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, - bool /*fast*/, + bool /*fast*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) { // now build the test @@ -804,6 +805,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext, { sourcecode = "compiled.mach-o.objfile"; } + else if(ext == "xctest") + { + sourcecode = "wrapper.cfbundle"; + } else if(ext == "xib") { keepLastKnownFileType = true; @@ -860,6 +865,10 @@ GetSourcecodeValueFromFileExtension(const std::string& _ext, { sourcecode += ".asm"; } + else if (ext == "metal") + { + sourcecode += ".metal"; + } //else // { // // Already specialized above or we leave sourcecode == "sourcecode" @@ -1743,7 +1752,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, return; } - std::string flags; std::string defFlags; bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) || (target.GetType() == cmTarget::MODULE_LIBRARY)); @@ -1752,19 +1760,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, (target.GetType() == cmTarget::EXECUTABLE) || shared); - std::string lang = target.GetLinkerLanguage(configName); - std::string cflags; - if(!lang.empty()) + // Compute the compilation flags for each language. + std::set<std::string> languages; + target.GetLanguages(languages, configName); + std::map<std::string, std::string> cflags; + for (std::set<std::string>::iterator li = languages.begin(); + li != languages.end(); ++li) { - // for c++ projects get the c flags as well - if(lang == "CXX") - { - this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName); - this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, - "C", configName); - this->CurrentLocalGenerator-> - AddCompileOptions(cflags, &target, "C", configName); - } + std::string const& lang = *li; + std::string& flags = cflags[lang]; // Add language-specific flags. this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName); @@ -1779,13 +1783,15 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->CurrentLocalGenerator-> AddCompileOptions(flags, &target, lang, configName); } - else if(binary) - { + + std::string llang = target.GetLinkerLanguage(configName); + if(binary && llang.empty()) + { cmSystemTools::Error ("CMake can not determine linker language for target: ", target.GetName().c_str()); return; - } + } // Add define flags this->CurrentLocalGenerator-> @@ -1806,7 +1812,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, } cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName); + target.GetCompileDefinitions(targetDefines, configName, "C"); this->AppendDefines(ppDefs, targetDefines); buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); @@ -2004,7 +2010,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // in many ways as an application bundle, as far as // link flags go std::string createFlags = - this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS", + this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", "-bundle"); if(!createFlags.empty()) { @@ -2032,7 +2038,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->CreateString("NO")); // Add the flags to create an executable. std::string createFlags = - this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", ""); + this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", ""); if(!createFlags.empty()) { extraLinkOptions += " "; @@ -2043,7 +2049,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { // Add the flags to create a module. std::string createFlags = - this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", lang, "_FLAGS", + this->LookupFlags("CMAKE_SHARED_MODULE_CREATE_", llang, "_FLAGS", "-bundle"); if(!createFlags.empty()) { @@ -2077,7 +2083,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { // Add the flags to create a shared library. std::string createFlags = - this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS", + this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", llang, "_FLAGS", "-dynamiclib"); if(!createFlags.empty()) { @@ -2094,7 +2100,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { // Add the flags to create an executable. std::string createFlags = - this->LookupFlags("CMAKE_", lang, "_LINK_FLAGS", ""); + this->LookupFlags("CMAKE_", llang, "_LINK_FLAGS", ""); if(!createFlags.empty()) { extraLinkOptions += " "; @@ -2178,53 +2184,58 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, buildSettings->AddAttribute("HEADER_SEARCH_PATHS", dirs.CreateList()); } - std::string oflagc = this->ExtractFlag("-O", cflags); + + bool same_gflags = true; + std::map<std::string, std::string> gflags; + std::string const* last_gflag = 0; char optLevel[2]; optLevel[0] = '0'; optLevel[1] = 0; - if(oflagc.size() == 3) - { - optLevel[0] = oflagc[2]; - } - if(oflagc.size() == 2) - { - optLevel[0] = '1'; - } - std::string oflag = this->ExtractFlag("-O", flags); - if(oflag.size() == 3) - { - optLevel[0] = oflag[2]; - } - if(oflag.size() == 2) - { - optLevel[0] = '1'; - } - std::string gflagc = this->ExtractFlag("-g", cflags); - // put back gdwarf-2 if used since there is no way - // to represent it in the gui, but we still want debug yes - if(gflagc == "-gdwarf-2") - { - cflags += " "; - cflags += gflagc; - } - std::string gflag = this->ExtractFlag("-g", flags); - if(gflag == "-gdwarf-2") + + // Minimal map of flags to build settings. + for (std::set<std::string>::iterator li = languages.begin(); + li != languages.end(); ++li) { - flags += " "; - flags += gflag; + std::string& flags = cflags[*li]; + std::string& gflag = gflags[*li]; + std::string oflag = this->ExtractFlag("-O", flags); + if(oflag.size() == 3) + { + optLevel[0] = oflag[2]; + } + if(oflag.size() == 2) + { + optLevel[0] = '1'; + } + gflag = this->ExtractFlag("-g", flags); + // put back gdwarf-2 if used since there is no way + // to represent it in the gui, but we still want debug yes + if(gflag == "-gdwarf-2") + { + flags += " "; + flags += gflag; + } + if (last_gflag && *last_gflag != gflag) + { + same_gflags = false; + } + last_gflag = &gflag; } + const char* debugStr = "YES"; - // We can't set the Xcode flag differently depending on the language, - // so put them back in this case. - if( (lang == "CXX") && gflag != gflagc ) + if (!same_gflags) { - cflags += " "; - cflags += gflagc; - flags += " "; - flags += gflag; + // We can't set the Xcode flag differently depending on the language, + // so put them back in this case. + for (std::set<std::string>::iterator li = languages.begin(); + li != languages.end(); ++li) + { + cflags[*li] += " "; + cflags[*li] += gflags[*li]; + } debugStr = "NO"; } - if( gflag == "-g0" || gflag.size() == 0 ) + else if (last_gflag && (last_gflag->empty() || *last_gflag == "-g0")) { debugStr = "NO"; } @@ -2239,24 +2250,25 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->CreateString("NO")); buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN", this->CreateString("NO")); - if(lang == "CXX") + for (std::set<std::string>::iterator li = languages.begin(); + li != languages.end(); ++li) { - flags += " "; - flags += defFlags; - buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS", - this->CreateString(flags.c_str())); - cflags += " "; - cflags += defFlags; - buildSettings->AddAttribute("OTHER_CFLAGS", - this->CreateString(cflags.c_str())); - - } - else - { - flags += " "; - flags += defFlags; - buildSettings->AddAttribute("OTHER_CFLAGS", - this->CreateString(flags.c_str())); + std::string flags = cflags[*li] + " " + defFlags; + if (*li == "CXX") + { + buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS", + this->CreateString(flags.c_str())); + } + else if (*li == "Fortran") + { + buildSettings->AddAttribute("IFORT_OTHER_FLAGS", + this->CreateString(flags.c_str())); + } + else if (*li == "C") + { + buildSettings->AddAttribute("OTHER_CFLAGS", + this->CreateString(flags.c_str())); + } } // Add Fortran source format attribute if property is set. @@ -2433,8 +2445,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if (!attribute.empty()) { + cmGeneratorExpression ge; + std::string processed = ge.Parse(i->second.GetValue()) + ->Evaluate(this->CurrentMakefile, configName); buildSettings->AddAttribute(attribute.c_str(), - this->CreateString(i->second.GetValue())); + this->CreateString(processed)); } } } @@ -2592,7 +2607,9 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget) case cmTarget::STATIC_LIBRARY: return "archive.ar"; case cmTarget::MODULE_LIBRARY: - if (cmtarget.IsCFBundleOnApple()) + if (cmtarget.IsXCTestOnApple()) + return "wrapper.cfbundle"; + else if (cmtarget.IsCFBundleOnApple()) return "wrapper.plug-in"; else return ((this->XcodeVersion >= 22)? @@ -2616,7 +2633,9 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget) case cmTarget::STATIC_LIBRARY: return "com.apple.product-type.library.static"; case cmTarget::MODULE_LIBRARY: - if (cmtarget.IsCFBundleOnApple()) + if (cmtarget.IsXCTestOnApple()) + return "com.apple.product-type.bundle.unit-test"; + else if (cmtarget.IsCFBundleOnApple()) return "com.apple.product-type.bundle"; else return ((this->XcodeVersion >= 22)? @@ -3366,53 +3385,33 @@ bool cmGlobalXCodeGenerator this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); const char* osxArch = this->CurrentMakefile->GetDefinition("CMAKE_OSX_ARCHITECTURES"); - if(!osxArch || strlen(osxArch) == 0) - { - if(this->XcodeVersion >= 32) - { - osxArch = "$(ARCHS_STANDARD_32_64_BIT)"; - } - else if(this->XcodeVersion == 31) - { - osxArch = "$(ARCHS_STANDARD_32_BIT)"; - } - else if(this->XcodeVersion <= 30) - { -#ifdef __ppc__ - osxArch = "ppc"; -#endif -#ifdef __i386 - osxArch = "i386"; -#endif - } - buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", - this->CreateString("YES")); - } - const char* sysroot = this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT"); const char* deploymentTarget = this->CurrentMakefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET"); - if(osxArch && sysroot) + std::string archs; + if(sysroot) { - // recompute this as it may have been changed since enable language - this->Architectures.clear(); - cmSystemTools::ExpandListArgument(std::string(osxArch), - this->Architectures); - buildSettings->AddAttribute("SDKROOT", - this->CreateString(sysroot)); - std::string archString; - const char* sep = ""; - for( std::vector<std::string>::iterator i = - this->Architectures.begin(); - i != this->Architectures.end(); ++i) + if(osxArch) { - archString += sep; - archString += *i; - sep = " "; + // recompute this as it may have been changed since enable language + this->Architectures.clear(); + cmSystemTools::ExpandListArgument(std::string(osxArch), + this->Architectures); + archs = cmJoin(this->Architectures, " "); } - buildSettings->AddAttribute("ARCHS", - this->CreateString(archString.c_str())); + buildSettings->AddAttribute("SDKROOT", + this->CreateString(sysroot)); + } + if (archs.empty()) + { + // Tell Xcode to use NATIVE_ARCH instead of ARCHS. + buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES")); + } + else + { + // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO). + buildSettings->AddAttribute("ARCHS", this->CreateString(archs.c_str())); } if(deploymentTarget && *deploymentTarget) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index f513e28..b272f6a 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -60,7 +60,7 @@ public: const std::string& projectDir, const std::string& targetName, const std::string& config, - bool fast, + bool fast, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>() ); diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx index 3362abb..6dea5c1 100644 --- a/Source/cmIfCommand.cxx +++ b/Source/cmIfCommand.cxx @@ -45,7 +45,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, { this->ScopeDepth++; } - if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif")) + else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endif")) { this->ScopeDepth--; // if this is the endif for this if statement, then start executing diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 8c13bab..7593380 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -44,7 +44,9 @@ cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os, { // Write code to install the directories. const char* no_rename = 0; - this->AddInstallRule(os, cmInstallType_DIRECTORY, + this->AddInstallRule(os, + this->Destination, + cmInstallType_DIRECTORY, this->Directories, this->Optional, this->FilePermissions.c_str(), diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 4480cc6..38c80df 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -185,7 +185,8 @@ cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os, files.push_back(i->second); std::string config_test = this->CreateConfigTest(i->first); os << indent << "if(" << config_test << ")\n"; - this->AddInstallRule(os, cmInstallType_FILES, files, false, + this->AddInstallRule(os, this->Destination, + cmInstallType_FILES, files, false, this->FilePermissions.c_str(), 0, 0, 0, indent.Next()); os << indent << "endif()\n"; @@ -199,7 +200,7 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, { // Remove old per-configuration export files if the main changes. std::string installedDir = "$ENV{DESTDIR}"; - installedDir += this->GetInstallDestination(); + installedDir += this->ConvertToAbsoluteDestination(this->Destination); installedDir += "/"; std::string installedFile = installedDir; installedFile += this->FileName; @@ -224,6 +225,7 @@ void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, // Install the main export file. std::vector<std::string> files; files.push_back(this->MainImportFile); - this->AddInstallRule(os, cmInstallType_FILES, files, false, + this->AddInstallRule(os, this->Destination, + cmInstallType_FILES, files, false, this->FilePermissions.c_str(), 0, 0, 0, indent); } diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index eb8c28b..3e078f2 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -41,6 +41,9 @@ public: const std::string& GetNamespace() const { return this->Namespace; } + std::string const& GetDestination() const + { return this->Destination; } + protected: virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 06a78e5..85e5345 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -15,9 +15,9 @@ // cmExecutableCommand bool cmInstallFilesCommand -::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) +::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { - if(argsIn.size() < 2) + if(args.size() < 2) { this->SetError("called with incorrect number of arguments"); return false; @@ -27,9 +27,6 @@ bool cmInstallFilesCommand this->Makefile->GetLocalGenerator() ->GetGlobalGenerator()->EnableInstallTarget(); - std::vector<std::string> args; - this->Makefile->ExpandSourceListArguments(argsIn, args, 2); - this->Destination = args[0]; if((args.size() > 1) && (args[1] == "FILES")) diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index 91b102a..28c27c2 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -57,6 +57,7 @@ void cmInstallFilesGenerator::AddFilesInstallRule( // Write code to install the files. const char* no_dir_permissions = 0; this->AddInstallRule(os, + this->Destination, (this->Programs ? cmInstallType_PROGRAMS : cmInstallType_FILES), diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index b261cbf..2e1c5f0 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -37,6 +37,7 @@ cmInstallGenerator void cmInstallGenerator ::AddInstallRule( std::ostream& os, + std::string const& dest, cmInstallType type, std::vector<std::string> const& files, bool optional /* = false */, @@ -60,7 +61,6 @@ void cmInstallGenerator case cmInstallType_FILES: stype = "FILE"; break; } os << indent; - std::string dest = this->GetInstallDestination(); if (cmSystemTools::FileIsFullPath(dest.c_str())) { os << "list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"; @@ -94,7 +94,8 @@ void cmInstallGenerator << "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"; os << indent << "endif()\n"; } - os << "file(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype; + std::string absDest = this->ConvertToAbsoluteDestination(dest); + os << "file(INSTALL DESTINATION \"" << absDest << "\" TYPE " << stype; if(optional) { os << " OPTIONAL"; @@ -179,15 +180,16 @@ bool cmInstallGenerator::InstallsForConfig(const std::string& config) } //---------------------------------------------------------------------------- -std::string cmInstallGenerator::GetInstallDestination() const +std::string +cmInstallGenerator::ConvertToAbsoluteDestination(std::string const& dest) const { std::string result; - if(!this->Destination.empty() && - !cmSystemTools::FileIsFullPath(this->Destination.c_str())) + if(!dest.empty() && + !cmSystemTools::FileIsFullPath(dest.c_str())) { result = "${CMAKE_INSTALL_PREFIX}/"; } - result += this->Destination; + result += dest; return result; } diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h index 38aac91..c4191e4 100644 --- a/Source/cmInstallGenerator.h +++ b/Source/cmInstallGenerator.h @@ -40,7 +40,9 @@ public: virtual ~cmInstallGenerator(); void AddInstallRule( - std::ostream& os, cmInstallType type, + std::ostream& os, + std::string const& dest, + cmInstallType type, std::vector<std::string> const& files, bool optional = false, const char* permissions_file = 0, @@ -50,12 +52,9 @@ public: Indent const& indent = Indent() ); - const char* GetDestination() const - { return this->Destination.c_str(); } - /** Get the install destination as it should appear in the installation script. */ - std::string GetInstallDestination() const; + std::string ConvertToAbsoluteDestination(std::string const& dest) const; /** Test if this generator installs something for a given configuration. */ bool InstallsForConfig(const std::string& config); diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 6d69f54..b035bad 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -12,6 +12,7 @@ #include "cmInstallTargetGenerator.h" #include "cmComputeLinkInformation.h" +#include "cmGeneratorExpression.h" #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -77,7 +78,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, fromDirConfig = this->Target->GetDirectory(config, this->ImportLibrary); fromDirConfig += "/"; } - std::string toDir = this->GetInstallDestination(); + std::string toDir = + this->ConvertToAbsoluteDestination(this->GetDestination(config)); toDir += "/"; // Compute the list of files to install for this target. @@ -322,8 +324,8 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, const char* no_dir_permissions = 0; const char* no_rename = 0; bool optional = this->Optional || this->ImportLibrary; - this->AddInstallRule(os, type, filesFrom, - optional, + this->AddInstallRule(os, this->GetDestination(config), + type, filesFrom, optional, this->FilePermissions.c_str(), no_dir_permissions, no_rename, literal_args.c_str(), indent); @@ -335,6 +337,15 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os, //---------------------------------------------------------------------------- std::string +cmInstallTargetGenerator::GetDestination(std::string const& config) const +{ + cmGeneratorExpression ge; + return ge.Parse(this->Destination) + ->Evaluate(this->Target->GetMakefile(), config); +} + +//---------------------------------------------------------------------------- +std::string cmInstallTargetGenerator::GetInstallFilename(const std::string& config) const { NameType nameType = this->ImportLibrary? NameImplib : NameNormal; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index 7e5cc71..075c8a4 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -60,6 +60,8 @@ public: cmTarget* GetTarget() const { return this->Target; } bool IsImportLibrary() const { return this->ImportLibrary; } + std::string GetDestination(std::string const& config) const; + protected: virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptForConfig(std::ostream& os, diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx index 4b53752..8c52b48 100644 --- a/Source/cmInstalledFile.cxx +++ b/Source/cmInstalledFile.cxx @@ -12,6 +12,7 @@ #include "cmInstalledFile.h" #include "cmSystemTools.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmInstalledFile::cmInstalledFile(): @@ -29,6 +30,16 @@ cmInstalledFile::~cmInstalledFile() } } +cmInstalledFile::Property::Property() +{ + +} + +cmInstalledFile::Property::~Property() +{ + cmDeleteAll(this->ValueExpressions); +} + //---------------------------------------------------------------------------- void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name) { diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h index 503f92c..3af90a7 100644 --- a/Source/cmInstalledFile.h +++ b/Source/cmInstalledFile.h @@ -31,15 +31,8 @@ public: struct Property { - Property() - { - - } - - ~Property() - { - cmDeleteAll(this->ValueExpressions); - } + Property(); + ~Property(); ExpressionVectorType ValueExpressions; }; diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 107dca9..d18269d 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -12,6 +12,7 @@ #include "cmListCommand.h" #include <cmsys/RegularExpression.hxx> #include <cmsys/SystemTools.hxx> +#include "cmAlgorithms.h" #include <stdlib.h> // required for atoi #include <ctype.h> @@ -104,19 +105,8 @@ bool cmListCommand::GetList(std::vector<std::string>& list, } // expand the variable into a list cmSystemTools::ExpandListArgument(listString, list, true); - // check the list for empty values - bool hasEmpty = false; - for(std::vector<std::string>::iterator i = list.begin(); - i != list.end(); ++i) - { - if(i->empty()) - { - hasEmpty = true; - break; - } - } // if no empty elements then just return - if(!hasEmpty) + if (std::find(list.begin(), list.end(), std::string()) == list.end()) { return true; } @@ -213,12 +203,12 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) std::string value; size_t cc; const char* sep = ""; + size_t nitem = varArgsExpanded.size(); for ( cc = 2; cc < args.size()-1; cc ++ ) { int item = atoi(args[cc].c_str()); value += sep; sep = ";"; - size_t nitem = varArgsExpanded.size(); if ( item < 0 ) { item = (int)nitem + item; @@ -227,8 +217,8 @@ bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args) { std::ostringstream str; str << "index: " << item << " out of range (-" - << varArgsExpanded.size() << ", " - << varArgsExpanded.size()-1 << ")"; + << nitem << ", " + << nitem - 1 << ")"; this->SetError(str.str()); return false; } @@ -254,15 +244,12 @@ bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args) // expand the variable std::string listString; this->GetListString(listString, listName); - size_t cc; - for ( cc = 2; cc < args.size(); ++ cc ) + + if(!listString.empty() && !args.empty()) { - if(!listString.empty()) - { - listString += ";"; - } - listString += args[cc]; + listString += ";"; } + listString += cmJoin(cmRange(args).advance(2), ";"); this->Makefile->AddDefinition(listName, listString.c_str()); return true; @@ -287,18 +274,14 @@ bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args) return true; } - std::vector<std::string>::iterator it; - unsigned int index = 0; - for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it ) + std::vector<std::string>::iterator it = + std::find(varArgsExpanded.begin(), varArgsExpanded.end(), args[2]); + if (it != varArgsExpanded.end()) { - if ( *it == args[2] ) - { - char indexString[32]; - sprintf(indexString, "%d", index); - this->Makefile->AddDefinition(variableName, indexString); - return true; - } - index++; + std::ostringstream indexStream; + indexStream << std::distance(varArgsExpanded.begin(), it); + this->Makefile->AddDefinition(variableName, indexStream.str().c_str()); + return true; } this->Makefile->AddDefinition(variableName, "-1"); @@ -373,25 +356,16 @@ bool cmListCommand return false; } - size_t cc; - for ( cc = 2; cc < args.size(); ++ cc ) - { - size_t kk = 0; - while ( kk < varArgsExpanded.size() ) - { - if ( varArgsExpanded[kk] == args[cc] ) - { - varArgsExpanded.erase(varArgsExpanded.begin()+kk); - } - else - { - kk ++; - } - } - } - + std::vector<std::string> remove(args.begin() + 2, args.end()); + std::sort(remove.begin(), remove.end()); + std::vector<std::string>::const_iterator remEnd = + std::unique(remove.begin(), remove.end()); + std::vector<std::string>::const_iterator remBegin = remove.begin(); - std::string value = cmJoin(varArgsExpanded, ";"); + std::vector<std::string>::const_iterator argsEnd = + cmRemoveMatching(varArgsExpanded, cmRange(remBegin, remEnd)); + std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); + std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; } @@ -417,15 +391,7 @@ bool cmListCommand return false; } - std::string value; - std::vector<std::string>::reverse_iterator it; - const char* sep = ""; - for ( it = varArgsExpanded.rbegin(); it != varArgsExpanded.rend(); ++ it ) - { - value += sep; - value += it->c_str(); - sep = ";"; - } + std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; @@ -453,24 +419,11 @@ bool cmListCommand return false; } - std::string value; - - - std::set<std::string> unique; - std::vector<std::string>::iterator it; - const char* sep = ""; - for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it ) - { - if (unique.find(*it) != unique.end()) - { - continue; - } - unique.insert(*it); - value += sep; - value += it->c_str(); - sep = ";"; - } - + std::vector<std::string>::const_iterator argsEnd = + cmRemoveDuplicates(varArgsExpanded); + std::vector<std::string>::const_iterator argsBegin = + varArgsExpanded.begin(); + std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; @@ -532,10 +485,10 @@ bool cmListCommand::HandleRemoveAtCommand( size_t cc; std::vector<size_t> removed; + size_t nitem = varArgsExpanded.size(); for ( cc = 2; cc < args.size(); ++ cc ) { int item = atoi(args[cc].c_str()); - size_t nitem = varArgsExpanded.size(); if ( item < 0 ) { item = (int)nitem + item; @@ -544,35 +497,23 @@ bool cmListCommand::HandleRemoveAtCommand( { std::ostringstream str; str << "index: " << item << " out of range (-" - << varArgsExpanded.size() << ", " - << varArgsExpanded.size()-1 << ")"; + << nitem << ", " + << nitem - 1 << ")"; this->SetError(str.str()); return false; } removed.push_back(static_cast<size_t>(item)); } - std::string value; - const char* sep = ""; - for ( cc = 0; cc < varArgsExpanded.size(); ++ cc ) - { - size_t kk; - bool found = false; - for ( kk = 0; kk < removed.size(); ++ kk ) - { - if ( cc == removed[kk] ) - { - found = true; - } - } + std::sort(removed.begin(), removed.end()); + std::vector<size_t>::const_iterator remEnd = + std::unique(removed.begin(), removed.end()); + std::vector<size_t>::const_iterator remBegin = removed.begin(); - if ( !found ) - { - value += sep; - value += varArgsExpanded[cc]; - sep = ";"; - } - } + std::vector<std::string>::const_iterator argsEnd = + cmRemoveIndices(varArgsExpanded, cmRange(remBegin, remEnd)); + std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin(); + std::string value = cmJoin(cmRange(argsBegin, argsEnd), ";"); this->Makefile->AddDefinition(listName, value.c_str()); return true; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index dd4a8f8..e1998e4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -25,6 +25,7 @@ #include "cmCustomCommandGenerator.h" #include "cmVersion.h" #include "cmake.h" +#include "cmAlgorithms.h" #if defined(CMAKE_BUILD_WITH_CMAKE) # define CM_LG_ENCODE_OBJECT_NAMES @@ -1428,11 +1429,11 @@ std::string cmLocalGenerator::GetIncludeFlags( //---------------------------------------------------------------------------- void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines, cmTarget const* target, - const std::string& config) + const std::string& config, + const std::string& lang) { std::vector<std::string> targetDefines; - target->GetCompileDefinitions(targetDefines, - config); + target->GetCompileDefinitions(targetDefines, config, lang); this->AppendDefines(defines, targetDefines); } @@ -1453,7 +1454,7 @@ void cmLocalGenerator::AddCompileOptions( { cmSystemTools::ParseWindowsCommandLine(targetFlags, opts); } - target->GetCompileOptions(opts, config); + target->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { @@ -1474,7 +1475,7 @@ void cmLocalGenerator::AddCompileOptions( this->AppendFlags(flags, targetFlags); } std::vector<std::string> opts; - target->GetCompileOptions(opts, config); + target->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { @@ -1600,7 +1601,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, // Get the target-specific include directories. std::vector<std::string> includes; - includes = target->GetIncludeDirectories(config); + includes = target->GetIncludeDirectories(config, lang); // Support putting all the in-project include directories first if // it is requested by the project. @@ -1947,14 +1948,13 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, // Write the library flags to the build rule. fout << linkLibs; - // Get the RPATH entries. - std::vector<std::string> runtimeDirs; - cli.GetRPath(runtimeDirs, relink); - // Check what kind of rpath flags to use. if(cli.GetRuntimeSep().empty()) { // Each rpath entry gets its own option ("-R a -R b -R c") + std::vector<std::string> runtimeDirs; + cli.GetRPath(runtimeDirs, relink); + std::string rpath; for(std::vector<std::string>::iterator ri = runtimeDirs.begin(); ri != runtimeDirs.end(); ++ri) @@ -2803,12 +2803,7 @@ std::string cmLocalGenerator::ConvertToOutputFormat(const std::string& source, } if(this->WindowsShell) { - std::string::size_type pos = 0; - while((pos = result.find('/', pos)) != std::string::npos) - { - result[pos] = '\\'; - pos++; - } + std::replace(result.begin(), result.end(), '/', '\\'); } result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE); } @@ -3013,14 +3008,12 @@ cmLocalGenerator::ConvertToRelativePath(const std::vector<std::string>& local, // trailing slash in the input then the last iteration of the loop // will add a slash followed by an empty string which will preserve // the trailing slash in the output. - for(unsigned int i=common; i < remote.size(); ++i) + + if(!relative.empty() && !remote.empty()) { - if(!relative.empty()) - { - relative += "/"; - } - relative += remote[i]; + relative += "/"; } + relative += cmJoin(cmRange(remote).advance(common), "/"); // Finally return the path. return relative; @@ -3206,11 +3199,7 @@ cmLocalGenerator std::string ssin = sin; // Avoid full paths by removing leading slashes. - std::string::size_type pos = 0; - for(;pos < ssin.size() && ssin[pos] == '/'; ++pos) - { - } - ssin = ssin.substr(pos); + ssin.erase(0, ssin.find_first_not_of("/")); // Avoid full paths by removing colons. cmSystemTools::ReplaceString(ssin, ":", "_"); @@ -3647,26 +3636,21 @@ bool cmLocalGenerator::NeedBackwardsCompatibility_2_4() bool cmLocalGenerator::CheckDefinition(std::string const& define) const { // Many compilers do not support -DNAME(arg)=sdf so we disable it. - bool function_style = false; - for(const char* c = define.c_str(); *c && *c != '='; ++c) + std::string::size_type pos = define.find_first_of("(="); + if (pos != std::string::npos) { - if(*c == '(') + if (define[pos] == '(') { - function_style = true; - break; + 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" + << "CMake is dropping a preprocessor definition: " << define << "\n" + << "Consider defining the macro in a (configured) header file.\n"; + cmSystemTools::Message(e.str().c_str()); + return false; } } - if(function_style) - { - 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" - << "CMake is dropping a preprocessor definition: " << define << "\n" - << "Consider defining the macro in a (configured) header file.\n"; - cmSystemTools::Message(e.str().c_str()); - return false; - } // Many compilers do not support # in the value so we disable it. if(define.find_first_of("#") != define.npos) diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index d64ae0f..6cdee42 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -239,7 +239,8 @@ public: const std::string& lang, const std::string& config); void AddCompileDefinitions(std::set<std::string>& defines, cmTarget const* target, - const std::string& config); + const std::string& config, + const std::string& lang); /** Compute the language used to compile the given source file. */ std::string GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 9213ad6..8938e67 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -20,6 +20,7 @@ #include "cmVersion.h" #include "cmFileTimeComparison.h" #include "cmCustomCommandGenerator.h" +#include "cmAlgorithms.h" // Include dependency scanners for supported languages. Only the // C/C++ scanner is needed for bootstrapping CMake. @@ -27,10 +28,10 @@ #ifdef CMAKE_BUILD_WITH_CMAKE # include "cmDependsFortran.h" # include "cmDependsJava.h" -# include <cmsys/Terminal.h> #endif #include <cmsys/auto_ptr.hxx> +#include <cmsys/Terminal.h> #include <queue> @@ -675,12 +676,7 @@ cmLocalUnixMakefileGenerator3 } // Write the list of commands. - for(std::vector<std::string>::const_iterator i = commands.begin(); - i != commands.end(); ++i) - { - replace = *i; - os << "\t" << replace << "\n"; - } + os << cmWrap("\t", commands, "", "\n") << "\n"; if(symbolic && !this->WatcomWMake) { os << ".PHONY : " << cmMakeSafe(tgt) << "\n"; @@ -1280,13 +1276,7 @@ cmLocalUnixMakefileGenerator3 this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); fout << "\n" << "# Per-language clean rules from dependency scanning.\n" - << "foreach(lang"; - for(std::set<std::string>::const_iterator l = languages.begin(); - l != languages.end(); ++l) - { - fout << " " << *l; - } - fout << ")\n" + << "foreach(lang " << cmJoin(languages, " ") << ")\n" << " include(" << this->GetTargetDirectory(target) << "/cmake_clean_${lang}.cmake OPTIONAL)\n" << "endforeach()\n"; @@ -1296,12 +1286,12 @@ cmLocalUnixMakefileGenerator3 //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, - const char* text, - EchoColor color) + std::string const& text, + EchoColor color, + EchoProgress const* progress) { // Choose the color for the text. std::string color_name; -#ifdef CMAKE_BUILD_WITH_CMAKE if(this->GlobalGenerator->GetToolSupportsColor() && this->ColorMakefile) { // See cmake::ExecuteEchoColor in cmake.cxx for these options. @@ -1317,7 +1307,7 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, color_name = "--green "; break; case EchoLink: - color_name = "--red --bold "; + color_name = "--green --bold "; break; case EchoGenerate: color_name = "--blue --bold "; @@ -1327,14 +1317,11 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, break; } } -#else - (void)color; -#endif // Echo one line at a time. std::string line; line.reserve(200); - for(const char* c = text;; ++c) + for(const char* c = text.c_str();; ++c) { if(*c == '\n' || *c == '\0') { @@ -1343,7 +1330,7 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, { // Add a command to echo this line. std::string cmd; - if(color_name.empty()) + if(color_name.empty() && !progress) { // Use the native echo command. cmd = "@echo "; @@ -1354,6 +1341,17 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, // Use cmake to echo the text in color. cmd = "@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) "; cmd += color_name; + if (progress) + { + cmd += "--progress-dir="; + cmd += this->Convert(progress->Dir, + cmLocalGenerator::FULL, + cmLocalGenerator::SHELL); + cmd += " "; + cmd += "--progress-num="; + cmd += progress->Arg; + cmd += " "; + } cmd += this->EscapeForShell(line); } commands.push_back(cmd); @@ -1362,6 +1360,9 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands, // Reset the line to emtpy. line = ""; + // Progress appears only on first line. + progress = 0; + // Terminate on end-of-string. if(*c == '\0') { @@ -1567,14 +1568,10 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo, targetName = targetName.substr(0, targetName.length()-4); std::string message = "Scanning dependencies of target "; message += targetName; -#ifdef CMAKE_BUILD_WITH_CMAKE cmSystemTools::MakefileColorEcho( cmsysTerminal_Color_ForegroundMagenta | cmsysTerminal_Color_ForegroundBold, message.c_str(), true, color); -#else - fprintf(stdout, "%s\n", message.c_str()); -#endif return this->ScanDependencies(dir.c_str(), validDependencies); } @@ -2046,23 +2043,49 @@ void cmLocalUnixMakefileGenerator3 << "set(CMAKE_" << l->first << "_COMPILER_ID \"" << cid << "\")\n"; } - } - // Build a list of preprocessor definitions for the target. - std::set<std::string> defines; - this->AddCompileDefinitions(defines, &target, - this->ConfigurationName); - if(!defines.empty()) - { + // Build a list of preprocessor definitions for the target. + std::set<std::string> defines; + this->AddCompileDefinitions(defines, &target, + this->ConfigurationName, l->first); + if(!defines.empty()) + { + cmakefileStream + << "\n" + << "# Preprocessor definitions for this target.\n" + << "set(CMAKE_TARGET_DEFINITIONS_" << l->first << "\n"; + for(std::set<std::string>::const_iterator di = defines.begin(); + di != defines.end(); ++di) + { + cmakefileStream + << " " << this->EscapeForCMake(*di) << "\n"; + } + cmakefileStream + << " )\n"; + } + + // Target-specific include directories: cmakefileStream << "\n" - << "# Preprocessor definitions for this target.\n" - << "set(CMAKE_TARGET_DEFINITIONS\n"; - for(std::set<std::string>::const_iterator di = defines.begin(); - di != defines.end(); ++di) + << "# The include file search paths:\n"; + cmakefileStream + << "set(CMAKE_" << l->first << "_TARGET_INCLUDE_PATH\n"; + std::vector<std::string> includes; + + cmGeneratorTarget* gt = this->GetGlobalGenerator() + ->GetGeneratorTarget(&target); + + const std::string& config = + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); + this->GetIncludeDirectories(includes, gt, + l->first, config); + for(std::vector<std::string>::iterator i = includes.begin(); + i != includes.end(); ++i) { cmakefileStream - << " " << this->EscapeForCMake(*di) << "\n"; + << " \"" + << this->Convert(*i, cmLocalGenerator::HOME_OUTPUT) + << "\"\n"; } cmakefileStream << " )\n"; @@ -2236,21 +2259,19 @@ cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(const char* p, // Begin the quoted result with the root component. result += components[0]; - // Now add the rest of the components separated by the proper slash - // direction for this platform. - bool first = true; - for(unsigned int i=1; i < components.size(); ++i) + if (components.size() > 1) { + // Now add the rest of the components separated by the proper slash + // direction for this platform. + std::vector<std::string>::const_iterator compEnd + = std::remove(components.begin() + 1, components.end() - 1, + std::string()); + std::vector<std::string>::const_iterator compStart + = components.begin() + 1; + result += cmJoin(cmRange(compStart, compEnd), slash); // Only the last component can be empty to avoid double slashes. - if(!components[i].empty() || (i == (components.size()-1))) - { - if(!first) - { - result += slash; - } - result += components[i]; - first = false; - } + result += slash; + result += components.back(); } } @@ -2341,14 +2362,10 @@ void cmLocalUnixMakefileGenerator3 // On UNIX we must construct a single shell command to change // directory and build because make resets the directory between // each command. - std::vector<std::string>::iterator i = commands.begin(); - for (; i != commands.end(); ++i) - { - std::string cmd = cd_cmd; - cmd += this->ConvertToOutputForExisting(tgtDir, relRetDir); - cmd += " && "; - cmd += *i; - *i = cmd; - } + std::string outputForExisting = + this->ConvertToOutputForExisting(tgtDir, relRetDir); + std::string prefix = cd_cmd + outputForExisting + " && "; + std::transform(commands.begin(), commands.end(), commands.begin(), + std::bind1st(std::plus<std::string>(), prefix)); } } diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 4f2e4a0..a2f4245 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -174,8 +174,9 @@ public: // append an echo command enum EchoColor { EchoNormal, EchoDepend, EchoBuild, EchoLink, EchoGenerate, EchoGlobal }; - void AppendEcho(std::vector<std::string>& commands, const char* text, - EchoColor color = EchoNormal); + struct EchoProgress { std::string Dir; std::string Arg; }; + void AppendEcho(std::vector<std::string>& commands, std::string const& text, + EchoColor color = EchoNormal, EchoProgress const* = 0); /** Get whether the makefile is to have color. */ bool GetColorMakefile() const { return this->ColorMakefile; } diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 1d62093..2b999eb 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1701,15 +1701,15 @@ void cmLocalVisualStudio6Generator = this->Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"); cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX", debugPostfix?debugPostfix:""); - // store flags for each configuration - std::string flags = " "; - std::string flagsRelease = " "; - std::string flagsMinSizeRel = " "; - std::string flagsDebug = " "; - std::string flagsRelWithDebInfo = " "; if(target.GetType() >= cmTarget::EXECUTABLE && target.GetType() <= cmTarget::OBJECT_LIBRARY) { + // store flags for each configuration + std::string flags = " "; + std::string flagsRelease = " "; + std::string flagsMinSizeRel = " "; + std::string flagsDebug = " "; + std::string flagsRelWithDebInfo = " "; std::vector<std::string> configs; target.GetMakefile()->GetConfigurations(configs); std::vector<std::string>::const_iterator it = configs.begin(); @@ -1760,72 +1760,77 @@ void cmLocalVisualStudio6Generator "MinSizeRel"); this->AddCompileOptions(flagsRelWithDebInfo, &target, linkLanguage, "RelWithDebInfo"); - } - // if _UNICODE and _SBCS are not found, then add -D_MBCS - std::string defs = this->Makefile->GetDefineFlags(); - if(flags.find("D_UNICODE") == flags.npos && - defs.find("D_UNICODE") == flags.npos && - flags.find("D_SBCS") == flags.npos && - defs.find("D_SBCS") == flags.npos) - { - flags += " /D \"_MBCS\""; - } + // if _UNICODE and _SBCS are not found, then add -D_MBCS + std::string defs = this->Makefile->GetDefineFlags(); + if(flags.find("D_UNICODE") == flags.npos && + defs.find("D_UNICODE") == flags.npos && + flags.find("D_SBCS") == flags.npos && + defs.find("D_SBCS") == flags.npos) + { + flags += " /D \"_MBCS\""; + } - // Add per-target and per-configuration preprocessor definitions. - std::set<std::string> definesSet; - std::set<std::string> debugDefinesSet; - std::set<std::string> releaseDefinesSet; - std::set<std::string> minsizeDefinesSet; - std::set<std::string> debugrelDefinesSet; - - this->AddCompileDefinitions(definesSet, &target, ""); - this->AddCompileDefinitions(debugDefinesSet, &target, "DEBUG"); - this->AddCompileDefinitions(releaseDefinesSet, &target, "RELEASE"); - this->AddCompileDefinitions(minsizeDefinesSet, &target, "MINSIZEREL"); - this->AddCompileDefinitions(debugrelDefinesSet, &target, "RELWITHDEBINFO"); - - std::string defines = " "; - std::string debugDefines = " "; - std::string releaseDefines = " "; - std::string minsizeDefines = " "; - std::string debugrelDefines = " "; - - this->JoinDefines(definesSet, defines, ""); - this->JoinDefines(debugDefinesSet, debugDefines, ""); - this->JoinDefines(releaseDefinesSet, releaseDefines, ""); - this->JoinDefines(minsizeDefinesSet, minsizeDefines, ""); - this->JoinDefines(debugrelDefinesSet, debugrelDefines, ""); - - flags += defines; - flagsDebug += debugDefines; - flagsRelease += releaseDefines; - flagsMinSizeRel += minsizeDefines; - flagsRelWithDebInfo += debugrelDefines; - - // The template files have CXX FLAGS in them, that need to be replaced. - // There are not separate CXX and C template files, so we use the same - // variable names. The previous code sets up flags* variables to contain - // the correct C or CXX flags - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", - flagsMinSizeRel.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", - flagsDebug.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO", - flagsRelWithDebInfo.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", - flagsRelease.c_str()); - cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str()); - - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL", - minsizeDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG", - debugDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO", - debugrelDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE", - releaseDefines.c_str()); - cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS", defines.c_str()); + // Add per-target and per-configuration preprocessor definitions. + std::set<std::string> definesSet; + std::set<std::string> debugDefinesSet; + std::set<std::string> releaseDefinesSet; + std::set<std::string> minsizeDefinesSet; + std::set<std::string> debugrelDefinesSet; + + this->AddCompileDefinitions(definesSet, &target, "", linkLanguage); + this->AddCompileDefinitions(debugDefinesSet, &target, + "DEBUG", linkLanguage); + this->AddCompileDefinitions(releaseDefinesSet, &target, + "RELEASE", linkLanguage); + this->AddCompileDefinitions(minsizeDefinesSet, &target, + "MINSIZEREL", linkLanguage); + this->AddCompileDefinitions(debugrelDefinesSet, &target, + "RELWITHDEBINFO", linkLanguage); + + std::string defines = " "; + std::string debugDefines = " "; + std::string releaseDefines = " "; + std::string minsizeDefines = " "; + std::string debugrelDefines = " "; + + this->JoinDefines(definesSet, defines, ""); + this->JoinDefines(debugDefinesSet, debugDefines, ""); + this->JoinDefines(releaseDefinesSet, releaseDefines, ""); + this->JoinDefines(minsizeDefinesSet, minsizeDefines, ""); + this->JoinDefines(debugrelDefinesSet, debugrelDefines, ""); + + flags += defines; + flagsDebug += debugDefines; + flagsRelease += releaseDefines; + flagsMinSizeRel += minsizeDefines; + flagsRelWithDebInfo += debugrelDefines; + + // The template files have CXX FLAGS in them, that need to be replaced. + // There are not separate CXX and C template files, so we use the same + // variable names. The previous code sets up flags* variables to + // contain the correct C or CXX flags + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_MINSIZEREL", + flagsMinSizeRel.c_str()); + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_DEBUG", + flagsDebug.c_str()); + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELWITHDEBINFO", + flagsRelWithDebInfo.c_str()); + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS_RELEASE", + flagsRelease.c_str()); + cmSystemTools::ReplaceString(line, "CMAKE_CXX_FLAGS", flags.c_str()); + + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_MINSIZEREL", + minsizeDefines.c_str()); + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_DEBUG", + debugDefines.c_str()); + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELWITHDEBINFO", + debugrelDefines.c_str()); + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS_RELEASE", + releaseDefines.c_str()); + cmSystemTools::ReplaceString(line, "COMPILE_DEFINITIONS", + defines.c_str()); + } fout << line.c_str() << std::endl; } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 914df5f..c4abeb2 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -391,6 +391,13 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranFlagTable[] = {"OptimizeForProcessor", "QxT", "", "codeExclusivelyCore2Duo", 0}, {"OptimizeForProcessor", "QxO", "", "codeExclusivelyCore2StreamingSIMD", 0}, {"OptimizeForProcessor", "QxS", "", "codeExclusivelyCore2StreamingSIMD4", 0}, + {"OpenMP", "Qopenmp", "", "OpenMPParallelCode", 0}, + {"OpenMP", "Qopenmp-stubs", "", "OpenMPSequentialCode", 0}, + {"Traceback", "traceback", "", "true", 0}, + {"Traceback", "notraceback", "", "false", 0}, + {"FloatingPointExceptionHandling", "fpe:0", "", "fpe0", 0}, + {"FloatingPointExceptionHandling", "fpe:1", "", "fpe1", 0}, + {"FloatingPointExceptionHandling", "fpe:3", "", "fpe3", 0}, {"ModulePath", "module:", "", "", cmVS7FlagTable::UserValueRequired}, @@ -669,8 +676,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator); fout << "\t\t<Configuration\n" << "\t\t\tName=\"" << configName - << "|" << gg->GetPlatformName() << "\"\n" - << "\t\t\tOutputDirectory=\"" << configName << "\"\n"; + << "|" << gg->GetPlatformName() << "\"\n"; // This is an internal type to Visual Studio, it seems that: // 4 == static library // 2 == dll @@ -776,7 +782,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(&target); std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName); + target.GetCompileDefinitions(targetDefines, configName, "CXX"); targetOptions.AddDefines(targetDefines); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); @@ -798,6 +804,16 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, std::string intermediateDir = this->GetTargetDirectory(target); intermediateDir += "/"; intermediateDir += configName; + + if (target.GetType() < cmTarget::UTILITY) + { + std::string const& outDir = + target.GetType() == cmTarget::OBJECT_LIBRARY? + intermediateDir : target.GetDirectory(configName); + fout << "\t\t\tOutputDirectory=\"" + << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n"; + } + fout << "\t\t\tIntermediateDirectory=\"" << this->ConvertToXMLOutputPath(intermediateDir.c_str()) << "\"\n" @@ -1441,7 +1457,8 @@ cmLocalVisualStudio7Generator // First search a configuration-specific subdirectory and then the // original directory. - fout << comma << this->ConvertToXMLOutputPath((dir+"/$(OutDir)").c_str()) + fout << comma + << this->ConvertToXMLOutputPath((dir+"/$(ConfigurationName)").c_str()) << "," << this->ConvertToXMLOutputPath(dir.c_str()); comma = ","; } diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index 69fcca7..b7cbae6 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -12,6 +12,7 @@ #include "cmMacroCommand.h" #include "cmake.h" +#include "cmAlgorithms.h" // define the class for macro commands class cmMacroHelperCommand : public cmCommand @@ -84,10 +85,6 @@ bool cmMacroHelperCommand::InvokeInitialPass std::vector<std::string> expandedArgs; this->Makefile->ExpandArguments(args, expandedArgs); - std::string tmps; - cmListFileArgument arg; - std::string variable; - // make sure the number of arguments passed is at least the number // required by the signature if (expandedArgs.size() < this->Args.size() - 1) @@ -111,11 +108,24 @@ bool cmMacroHelperCommand::InvokeInitialPass argcDefStream << expandedArgs.size(); std::string argcDef = argcDefStream.str(); - // declare varuiables for ARGV ARGN but do not compute until needed - std::string argvDef; - std::string argnDef; - bool argnDefInitialized = false; - bool argvDefInitialized = false; + std::vector<std::string>::const_iterator eit + = expandedArgs.begin() + (this->Args.size() - 1); + std::string expandedArgn = cmJoin(cmRange(eit, expandedArgs.end()), ";"); + std::string expandedArgv = cmJoin(expandedArgs, ";"); + std::vector<std::string> variables; + variables.reserve(this->Args.size() - 1); + for (unsigned int j = 1; j < this->Args.size(); ++j) + { + variables.push_back("${" + this->Args[j] + "}"); + } + std::vector<std::string> argVs; + argVs.reserve(expandedArgs.size()); + char argvName[60]; + for (unsigned int j = 0; j < expandedArgs.size(); ++j) + { + sprintf(argvName,"${ARGV%i}",j); + argVs.push_back(argvName); + } if(!this->Functions.empty()) { this->FilePath = this->Functions[0].FilePath; @@ -140,81 +150,35 @@ bool cmMacroHelperCommand::InvokeInitialPass // Set the FilePath on the arguments to match the function since it is // not stored and the original values may be freed k->FilePath = this->FilePath.c_str(); - if(k->Delim == cmListFileArgument::Bracket) - { - arg.Value = k->Value; - } - else + + cmListFileArgument arg; + arg.Value = k->Value; + if(k->Delim != cmListFileArgument::Bracket) { - tmps = k->Value; // replace formal arguments - for (unsigned int j = 1; j < this->Args.size(); ++j) + for (unsigned int j = 0; j < variables.size(); ++j) { - variable = "${"; - variable += this->Args[j]; - variable += "}"; - cmSystemTools::ReplaceString(tmps, variable.c_str(), - expandedArgs[j-1].c_str()); + cmSystemTools::ReplaceString(arg.Value, variables[j].c_str(), + expandedArgs[j].c_str()); } // replace argc - cmSystemTools::ReplaceString(tmps, "${ARGC}",argcDef.c_str()); + cmSystemTools::ReplaceString(arg.Value, "${ARGC}",argcDef.c_str()); - // repleace ARGN - if (tmps.find("${ARGN}") != std::string::npos) - { - if (!argnDefInitialized) - { - std::vector<std::string>::const_iterator eit; - std::vector<std::string>::size_type cnt = 0; - for(eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit) - { - if ( cnt >= this->Args.size()-1 ) - { - if (!argnDef.empty()) - { - argnDef += ";"; - } - argnDef += *eit; - } - cnt ++; - } - argnDefInitialized = true; - } - cmSystemTools::ReplaceString(tmps, "${ARGN}", argnDef.c_str()); - } + cmSystemTools::ReplaceString(arg.Value, "${ARGN}", + expandedArgn.c_str()); + cmSystemTools::ReplaceString(arg.Value, "${ARGV}", + expandedArgv.c_str()); // if the current argument of the current function has ${ARGV in it // then try replacing ARGV values - if (tmps.find("${ARGV") != std::string::npos) + if (arg.Value.find("${ARGV") != std::string::npos) { - char argvName[60]; - - // repleace ARGV, compute it only once - if (!argvDefInitialized) - { - std::vector<std::string>::const_iterator eit; - for(eit = expandedArgs.begin(); eit != expandedArgs.end(); ++eit) - { - if (!argvDef.empty()) - { - argvDef += ";"; - } - argvDef += *eit; - } - argvDefInitialized = true; - } - cmSystemTools::ReplaceString(tmps, "${ARGV}", argvDef.c_str()); - - // also replace the ARGV1 ARGV2 ... etc for (unsigned int t = 0; t < expandedArgs.size(); ++t) { - sprintf(argvName,"${ARGV%i}",t); - cmSystemTools::ReplaceString(tmps, argvName, + cmSystemTools::ReplaceString(arg.Value, argVs[t].c_str(), expandedArgs[t].c_str()); } } - - arg.Value = tmps; } arg.Delim = k->Delim; arg.FilePath = k->FilePath; @@ -261,15 +225,7 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf, // if this is the endmacro for this macro then execute if (!this->Depth) { - std::string name = this->Args[0]; - std::vector<std::string>::size_type cc; - name += "("; - for ( cc = 0; cc < this->Args.size(); cc ++ ) - { - name += " " + this->Args[cc]; - } - name += " )"; - mf.AddMacro(this->Args[0].c_str(), name.c_str()); + mf.AddMacro(this->Args[0].c_str()); // create a new command and add it to cmake cmMacroHelperCommand *f = new cmMacroHelperCommand(); f->Args = this->Args; diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index 31bbb73..a6d4e58 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -12,6 +12,7 @@ #include "cmMakeDepend.h" #include "cmSystemTools.h" #include "cmGeneratorExpression.h" +#include "cmAlgorithms.h" #include <cmsys/RegularExpression.hxx> #include <cmsys/FStream.hxx> diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index ba914e1..ec1d814 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -30,6 +30,7 @@ #include "cmInstallGenerator.h" #include "cmTestGenerator.h" #include "cmDefinitions.h" +#include "cmAlgorithms.h" #include "cmake.h" #include <stdlib.h> // required for atoi @@ -38,6 +39,7 @@ #include <cmsys/auto_ptr.hxx> #include <stack> +#include <list> #include <ctype.h> // for isspace #include <assert.h> @@ -99,7 +101,6 @@ cmMakefile::cmMakefile(): Internal(new Internals) this->AddDefaultDefinitions(); this->Initialize(); - this->PreOrder = false; this->GeneratingBuildSystem = false; this->SuppressWatches = false; @@ -111,8 +112,6 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->Internal->VarInitStack.push(mf.Internal->VarInitStack.top()); this->Internal->VarUsageStack.push(mf.Internal->VarUsageStack.top()); - this->Prefix = mf.Prefix; - this->AuxSourceDirectories = mf.AuxSourceDirectories; this->cmStartDirectory = mf.cmStartDirectory; this->StartOutputDirectory = mf.StartOutputDirectory; this->cmHomeDirectory = mf.cmHomeDirectory; @@ -142,10 +141,8 @@ cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals) this->LocalGenerator = mf.LocalGenerator; this->FunctionBlockers = mf.FunctionBlockers; - this->MacrosMap = mf.MacrosMap; - this->SubDirectoryOrder = mf.SubDirectoryOrder; + this->MacrosList = mf.MacrosList; this->Properties = mf.Properties; - this->PreOrder = mf.PreOrder; this->WarnUnused = mf.WarnUnused; this->Initialize(); this->CheckSystemVars = mf.CheckSystemVars; @@ -212,13 +209,7 @@ cmMakefile::~cmMakefile() void cmMakefile::PrintStringVector(const char* s, const std::vector<std::string>& v) const { - std::cout << s << ": ( \n"; - for(std::vector<std::string>::const_iterator i = v.begin(); - i != v.end(); ++i) - { - std::cout << *i << " "; - } - std::cout << " )\n"; + std::cout << s << ": ( \n" << cmWrap('"', v, '"', " ") << ")\n"; } void cmMakefile @@ -990,6 +981,33 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs, } else { + std::ostringstream e; + cmake::MessageType messageType = cmake::AUTHOR_WARNING; + bool issueMessage = false; + + switch(this->GetPolicyStatus(cmPolicies::CMP0057)) + { + case cmPolicies::WARN: + e << (this->GetPolicies()-> + GetPolicyWarning(cmPolicies::CMP0057)) << "\n"; + issueMessage = true; + case cmPolicies::OLD: + break; + case cmPolicies::NEW: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + issueMessage = true; + messageType = cmake::FATAL_ERROR; + break; + } + + if(issueMessage) + { + e << "\"" << main_dependency << "\" can only be specified as a " + "custom command MAIN_DEPENDENCY once."; + IssueMessage(messageType, e.str()); + } + // The existing custom command is different. We need to // generate a rule file for this new command. file = 0; @@ -1339,22 +1357,11 @@ void cmMakefile::AddDefineFlag(const char* flag) void cmMakefile::AddDefineFlag(const char* flag, std::string& dflags) { // remove any \n\r - std::string ret = flag; - std::string::size_type pos = 0; - while((pos = ret.find('\n', pos)) != std::string::npos) - { - ret[pos] = ' '; - pos++; - } - pos = 0; - while((pos = ret.find('\r', pos)) != std::string::npos) - { - ret[pos] = ' '; - pos++; - } - - dflags += " "; - dflags += ret; + std::string::size_type initSize = dflags.size(); + dflags += std::string(" ") + flag; + std::string::iterator flagStart = dflags.begin() + initSize + 1; + std::replace(flagStart, dflags.end(), '\n', ' '); + std::replace(flagStart, dflags.end(), '\r', ' '); } @@ -1471,18 +1478,11 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove) cmSystemTools::ExpandListArgument(cdefs, defs); // Recompose the list without the definition. - std::string ndefs; - const char* sep = ""; - for(std::vector<std::string>::const_iterator di = defs.begin(); - di != defs.end(); ++di) - { - if(*di != define) - { - ndefs += sep; - sep = ";"; - ndefs += *di; - } - } + std::vector<std::string>::const_iterator defEnd = + std::remove(defs.begin(), defs.end(), define); + std::vector<std::string>::const_iterator defBegin = + defs.begin(); + std::string ndefs = cmJoin(cmRange(defBegin, defEnd), ";"); // Store the new list. this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str()); @@ -1692,7 +1692,7 @@ void cmMakefile::ConfigureSubDirectory(cmLocalGenerator *lg2) } void cmMakefile::AddSubDirectory(const std::string& sub, - bool excludeFromAll, bool preorder) + bool excludeFromAll) { // the source path must be made full if it isn't already std::string srcPath = sub; @@ -1714,13 +1714,13 @@ void cmMakefile::AddSubDirectory(const std::string& sub, this->AddSubDirectory(srcPath, binPath, - excludeFromAll, preorder, false); + excludeFromAll, false); } void cmMakefile::AddSubDirectory(const std::string& srcPath, const std::string& binPath, - bool excludeFromAll, bool preorder, + bool excludeFromAll, bool immediate) { // Make sure the binary directory is unique. @@ -1742,7 +1742,6 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, { lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - lg2->GetMakefile()->SetPreOrder(preorder); if (immediate) { @@ -2203,7 +2202,7 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, if(i==lastElement) { // group already exists, replace its regular expression - if ( regex ) + if ( regex && sg) { // We only want to set the regular expression. If there are already // source files in the group, we don't want to remove them. @@ -2219,7 +2218,11 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, sg = this->GetSourceGroup(currentName); i = 0; // last component found } - + if(!sg) + { + cmSystemTools::Error("Could not create source group "); + return; + } // build the whole source group path const char* fullname = sg->GetFullName(); cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator(); @@ -2247,11 +2250,6 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name, #endif -void cmMakefile::AddExtraDirectory(const char* dir) -{ - this->AuxSourceDirectories.push_back(dir); -} - static bool mightExpandVariablesCMP0019(const char* s) { return s && *s && strstr(s,"${") && strchr(s,'}'); @@ -3576,19 +3574,6 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const & lang, optional); } -void cmMakefile::ExpandSourceListArguments( - std::vector<std::string> const& arguments, - std::vector<std::string>& newargs, unsigned int /* start */) const -{ - // now expand the args - unsigned int i; - for(i = 0; i < arguments.size(); ++i) - { - // List expansion will have been done already. - newargs.push_back(arguments[i]); - } -} - int cmMakefile::TryCompile(const std::string& srcdir, const std::string& bindir, const std::string& projectName, @@ -3751,29 +3736,16 @@ cmVariableWatch *cmMakefile::GetVariableWatch() const } #endif -void cmMakefile::AddMacro(const char* name, const char* signature) +void cmMakefile::AddMacro(const char* name) { - if ( !name || !signature ) - { - return; - } - this->MacrosMap[name] = signature; + assert(name); + this->MacrosList.push_back(name); } void cmMakefile::GetListOfMacros(std::string& macros) const { - StringStringMap::const_iterator it; - macros = ""; - int cc = 0; - for ( it = this->MacrosMap.begin(); it != this->MacrosMap.end(); ++it ) - { - if ( cc > 0 ) - { - macros += ";"; - } - macros += it->first; - cc ++; - } + assert(macros.empty()); + macros = cmJoin(this->MacrosList, ";"); } cmCacheManager *cmMakefile::GetCacheManager() const @@ -4217,16 +4189,7 @@ const char *cmMakefile::GetProperty(const std::string& prop, } else if (prop == "LISTFILE_STACK") { - for (std::deque<std::string>::const_iterator - i = this->ListFileStack.begin(); - i != this->ListFileStack.end(); ++i) - { - if (i != this->ListFileStack.begin()) - { - output += ";"; - } - output += *i; - } + output = cmJoin(this->ListFileStack, ";"); return output.c_str(); } else if (prop == "VARIABLES" || prop == "CACHE_VARIABLES") @@ -4236,15 +4199,7 @@ const char *cmMakefile::GetProperty(const std::string& prop, { cacheonly = 1; } - std::vector<std::string> vars = this->GetDefinitions(cacheonly); - for (unsigned int cc = 0; cc < vars.size(); cc ++ ) - { - if ( cc > 0 ) - { - output += ";"; - } - output += vars[cc]; - } + output = cmJoin(this->GetDefinitions(cacheonly), ";"); return output.c_str(); } else if (prop == "MACROS") @@ -4254,24 +4209,23 @@ const char *cmMakefile::GetProperty(const std::string& prop, } else if (prop == "DEFINITIONS") { - output += this->DefineFlagsOrig; - return output.c_str(); + switch(this->GetPolicyStatus(cmPolicies::CMP0059)) + { + case cmPolicies::WARN: + this->IssueMessage(cmake::AUTHOR_WARNING, this->GetPolicies()-> + GetPolicyWarning(cmPolicies::CMP0059)); + case cmPolicies::OLD: + output += this->DefineFlagsOrig; + return output.c_str(); + case cmPolicies::NEW: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + break; + } } else if (prop == "LINK_DIRECTORIES") { - std::ostringstream str; - for (std::vector<std::string>::const_iterator - it = this->GetLinkDirectories().begin(); - it != this->GetLinkDirectories().end(); - ++ it ) - { - if ( it != this->GetLinkDirectories().begin()) - { - str << ";"; - } - str << it->c_str(); - } - output = str.str(); + output = cmJoin(this->GetLinkDirectories(), ";"); return output.c_str(); } else if (prop == "INCLUDE_DIRECTORIES") diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index bff8c12..ebfe508 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -35,6 +35,7 @@ #endif #include <stack> +#include <deque> class cmFunctionBlocker; class cmCommand; @@ -291,11 +292,10 @@ public: /** * Add a subdirectory to the build. */ - void AddSubDirectory(const std::string&, bool excludeFromAll=false, - bool preorder = false); + void AddSubDirectory(const std::string&, bool excludeFromAll=false); void AddSubDirectory(const std::string& fullSrcDir, const std::string& fullBinDir, - bool excludeFromAll, bool preorder, + bool excludeFromAll, bool immediate); /** @@ -432,15 +432,6 @@ public: bool HasCMP0054AlreadyBeenReported( cmListFileContext context) const; - /** - * Add an auxiliary directory to the build. - */ - void AddExtraDirectory(const char* dir); - - - /** - * Add an auxiliary directory to the build. - */ void MakeStartDirectoriesCurrent() { this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", @@ -599,17 +590,6 @@ public: */ void AddSystemIncludeDirectories(const std::set<std::string> &incs); - /** Expand out any arguements in the vector that have ; separated - * strings into multiple arguements. A new vector is created - * containing the expanded versions of all arguments in argsIn. - * This method differes from the one in cmSystemTools in that if - * the CmakeLists file is version 1.2 or earlier it will check for - * source lists being used without ${} around them - */ - void ExpandSourceListArguments(std::vector<std::string> const& argsIn, - std::vector<std::string>& argsOut, - unsigned int startArgumentIndex) const; - /** Get a cmSourceFile pointer for a given source name, if the name is * not found, then a null pointer is returned. */ @@ -630,12 +610,6 @@ public: cmSourceFile* GetOrCreateSource(const std::string& sourceName, bool generated = false); - /** - * Obtain a list of auxiliary source directories. - */ - const std::vector<std::string>& GetAuxSourceDirectories() const - {return this->AuxSourceDirectories;} - //@{ /** * Return a list of extensions associated with source and header @@ -851,7 +825,7 @@ public: * Add a macro to the list of macros. The arguments should be name of the * macro and a documentation signature of it */ - void AddMacro(const char* name, const char* signature); + void AddMacro(const char* name); ///! Add a new cmTest to the list of tests for this makefile. cmTest* CreateTest(const std::string& testName); @@ -889,10 +863,6 @@ public: ///! Initialize a makefile from its parent void InitializeFromParent(); - ///! Set/Get the preorder flag - void SetPreOrder(bool p) { this->PreOrder = p; } - bool GetPreOrder() const { return this->PreOrder; } - void AddInstallGenerator(cmInstallGenerator* g) { if(g) this->InstallGenerators.push_back(g); } std::vector<cmInstallGenerator*>& GetInstallGenerators() @@ -986,9 +956,6 @@ protected: // Check for a an unused variable void CheckForUnused(const char* reason, const std::string& name) const; - std::string Prefix; - std::vector<std::string> AuxSourceDirectories; // - std::string cmStartDirectory; std::string StartOutputDirectory; std::string cmHomeDirectory; @@ -1075,10 +1042,7 @@ private: std::stack<int> LoopBlockCounter; - typedef std::map<std::string, std::string> StringStringMap; - StringStringMap MacrosMap; - - std::map<std::string, bool> SubDirectoryOrder; + std::vector<std::string> MacrosList; mutable cmsys::RegularExpression cmDefineRegex; mutable cmsys::RegularExpression cmDefine01Regex; @@ -1087,9 +1051,6 @@ private: cmPropertyMap Properties; - // should this makefile be processed before or after processing the parent - bool PreOrder; - // Unused variable flags bool WarnUnused; bool CheckSystemVars; diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index d4036d2..ab58cbd 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -171,15 +171,19 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) return; } + this->NumberOfProgressActions++; if(!this->NoRuleMessages) { + cmLocalUnixMakefileGenerator3::EchoProgress progress; + this->MakeEchoProgress(progress); // Add the link message. std::string buildEcho = "Linking "; buildEcho += linkLanguage; buildEcho += " executable "; buildEcho += targetOutPath; this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoLink); + cmLocalUnixMakefileGenerator3::EchoLink, + &progress); } // Build a list of compiler flags and linker flags. diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index e55f651..fcb76c3 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -341,8 +341,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules this->Convert(targetFullPathImport,cmLocalGenerator::START_OUTPUT, cmLocalGenerator::SHELL); + this->NumberOfProgressActions++; if(!this->NoRuleMessages) { + cmLocalUnixMakefileGenerator3::EchoProgress progress; + this->MakeEchoProgress(progress); // Add the link message. std::string buildEcho = "Linking "; buildEcho += linkLanguage; @@ -365,7 +368,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } buildEcho += targetOutPath.c_str(); this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(), - cmLocalUnixMakefileGenerator3::EchoLink); + cmLocalUnixMakefileGenerator3::EchoLink, + &progress); } const char* forbiddenFlagVar = 0; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 4ece016..2cd2d3e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -122,6 +122,14 @@ void cmMakefileTargetGenerator::CreateRuleFile() return; } this->LocalGenerator->WriteDisclaimer(*this->BuildFileStream); + if (this->GlobalGenerator->AllowDeleteOnError()) + { + std::vector<std::string> no_depends; + std::vector<std::string> no_commands; + this->LocalGenerator->WriteMakeRule( + *this->BuildFileStream, "Delete rule output on recipe failure.", + ".DELETE_ON_ERROR", no_depends, no_commands, false); + } this->LocalGenerator->WriteSpecialTargetsTop(*this->BuildFileStream); } @@ -329,7 +337,7 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->LocalGenerator->ConfigurationName); + this->LocalGenerator->ConfigurationName, l); std::string definesString; this->LocalGenerator->JoinDefines(defines, definesString, lang); @@ -618,16 +626,19 @@ cmMakefileTargetGenerator std::vector<std::string> commands; // add in a progress call if needed - this->AppendProgress(commands); + this->NumberOfProgressActions++; if(!this->NoRuleMessages) { + cmLocalUnixMakefileGenerator3::EchoProgress progress; + this->MakeEchoProgress(progress); std::string buildEcho = "Building "; buildEcho += lang; buildEcho += " object "; buildEcho += relativeObj; this->LocalGenerator->AppendEcho - (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild); + (commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild, + &progress); } std::string targetOutPathReal; @@ -1123,40 +1134,6 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "set(CMAKE_Fortran_TARGET_MODULE_DIR \"" << mdir << "\")\n"; } - // Target-specific include directories: - *this->InfoFileStream - << "\n" - << "# The include file search paths:\n"; - *this->InfoFileStream - << "set(CMAKE_C_TARGET_INCLUDE_PATH\n"; - std::vector<std::string> includes; - - const std::string& config = - this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->LocalGenerator->GetIncludeDirectories(includes, - this->GeneratorTarget, - "C", config); - for(std::vector<std::string>::iterator i = includes.begin(); - i != includes.end(); ++i) - { - *this->InfoFileStream - << " \"" - << this->LocalGenerator->Convert(*i, - cmLocalGenerator::HOME_OUTPUT) - << "\"\n"; - } - *this->InfoFileStream - << " )\n"; - *this->InfoFileStream - << "set(CMAKE_CXX_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - *this->InfoFileStream - << "set(CMAKE_Fortran_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - *this->InfoFileStream - << "set(CMAKE_ASM_TARGET_INCLUDE_PATH " - << "${CMAKE_C_TARGET_INCLUDE_PATH})\n"; - // and now write the rule to use it std::vector<std::string> depends; std::vector<std::string> commands; @@ -1270,12 +1247,15 @@ void cmMakefileTargetGenerator if(!comment.empty()) { // add in a progress call if needed - this->AppendProgress(commands); + this->NumberOfProgressActions++; if(!this->NoRuleMessages) { + cmLocalUnixMakefileGenerator3::EchoProgress progress; + this->MakeEchoProgress(progress); this->LocalGenerator ->AppendEcho(commands, comment.c_str(), - cmLocalUnixMakefileGenerator3::EchoGenerate); + cmLocalUnixMakefileGenerator3::EchoGenerate, + &progress); } } @@ -1332,22 +1312,14 @@ void cmMakefileTargetGenerator //---------------------------------------------------------------------------- void -cmMakefileTargetGenerator::AppendProgress(std::vector<std::string>& commands) +cmMakefileTargetGenerator +::MakeEchoProgress(cmLocalUnixMakefileGenerator3::EchoProgress& progress) const { - this->NumberOfProgressActions++; - if(this->NoRuleMessages) - { - return; - } - std::string progressDir = this->Makefile->GetHomeOutputDirectory(); - progressDir += cmake::GetCMakeFilesDirectory(); - std::ostringstream progCmd; - progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; - progCmd << this->LocalGenerator->Convert(progressDir, - cmLocalGenerator::FULL, - cmLocalGenerator::SHELL); - progCmd << " $(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")"; - commands.push_back(progCmd.str()); + progress.Dir = this->Makefile->GetHomeOutputDirectory(); + progress.Dir += cmake::GetCMakeFilesDirectory(); + std::ostringstream progressArg; + progressArg << "$(CMAKE_PROGRESS_" << this->NumberOfProgressActions << ")"; + progress.Arg = progressArg.str(); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index f62c51d..98017be 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -109,7 +109,7 @@ protected: void GenerateExtraOutput(const char* out, const char* in, bool symbolic = false); - void AppendProgress(std::vector<std::string>& commands); + void MakeEchoProgress(cmLocalUnixMakefileGenerator3::EchoProgress&) const; // write out the variable that lists the objects for this target void WriteObjectsVariable(std::string& variableName, diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx index 88d6a77..0449c50 100644 --- a/Source/cmMessageCommand.cxx +++ b/Source/cmMessageCommand.cxx @@ -20,7 +20,6 @@ bool cmMessageCommand this->SetError("called with incorrect number of arguments"); return false; } - std::string message; std::vector<std::string>::const_iterator i = args.begin(); cmake::MessageType type = cmake::MESSAGE; @@ -70,10 +69,7 @@ bool cmMessageCommand ++i; } - for(;i != args.end(); ++i) - { - message += *i; - } + std::string message = cmJoin(cmRange(i, args.end()), std::string()); if (type != cmake::MESSAGE) { diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index c352c1a..155a30e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -19,6 +19,7 @@ #include "cmOSXBundleGenerator.h" #include "cmGeneratorTarget.h" #include "cmCustomCommandGenerator.h" +#include "cmAlgorithms.h" #include <assert.h> #include <algorithm> diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index cfd8937..92fccd3 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -231,7 +231,7 @@ ComputeDefines(cmSourceFile const* source, const std::string& language) // Add preprocessor definitions for this target and configuration. this->LocalGenerator->AddCompileDefinitions(defines, this->Target, - this->GetConfigName()); + this->GetConfigName(), language); this->LocalGenerator->AppendDefines (defines, source->GetProperty("COMPILE_DEFINITIONS")); diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 55e20ab..a8eef82 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -181,8 +181,9 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName, std::string plist = root + "/" + this->GT->Target->GetCFBundleDirectory(this->ConfigName, true); plist += "/Info.plist"; + std::string name = cmSystemTools::GetFilenameName(targetName); this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target, - targetName, + name, plist.c_str()); this->Makefile->AddCMakeOutputFile(plist); } diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx index e505440..60728ea 100644 --- a/Source/cmOptionCommand.cxx +++ b/Source/cmOptionCommand.cxx @@ -34,11 +34,7 @@ bool cmOptionCommand if(argError) { std::string m = "called with incorrect number of arguments: "; - for(size_t i =0; i < args.size(); ++i) - { - m += args[i]; - m += " "; - } + m += cmJoin(args, " "); this->SetError(m); return false; } diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index 23f8526..a612437 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -14,6 +14,7 @@ #include "cmGlobalGenerator.h" #include "cmSystemTools.h" #include "cmake.h" +#include "cmAlgorithms.h" #include <assert.h> diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 5016493..df531e7 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmOutputRequiredFilesCommand.h" #include "cmMakeDepend.h" +#include "cmAlgorithms.h" #include <cmsys/FStream.hxx> class cmLBDepend : public cmMakeDepend diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 3a48101..0a61bca 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -4,6 +4,7 @@ #include "cmSourceFile.h" #include "cmVersion.h" #include "cmVersionMacros.h" +#include "cmAlgorithms.h" #include <map> #include <set> #include <queue> @@ -374,6 +375,21 @@ cmPolicies::cmPolicies() CMP0056, "CMP0056", "Honor link flags in try_compile() source-file signature.", 3,2,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0057, "CMP0057", + "Disallow multiple MAIN_DEPENDENCY specifications for the same file.", + 3,3,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0058, "CMP0058", + "Ninja requires custom command byproducts to be explicit.", + 3,3,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0059, "CMP0059", + "Do no treat DEFINITIONS as a built-in directory property.", + 3,3,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index c393c2f..ced9d8c 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -113,6 +113,11 @@ public: /// or keywords when unquoted. CMP0055, ///< Strict checking for break() command. CMP0056, ///< Honor link flags in try_compile() source-file signature. + CMP0057, ///< Disallow multiple MAIN_DEPENDENCY specifications + /// for the same file. + CMP0058, ///< Ninja requires custom command byproducts to be explicit + CMP0059, ///< Do not treat ``DEFINITIONS`` as a built-in directory + /// property. /** \brief Always the last entry. * diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx index a984260..878562c 100644 --- a/Source/cmQTWrapCPPCommand.cxx +++ b/Source/cmQTWrapCPPCommand.cxx @@ -12,19 +12,15 @@ #include "cmQTWrapCPPCommand.h" // cmQTWrapCPPCommand -bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn, +bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { - if(argsIn.size() < 3 ) + if(args.size() < 3 ) { this->SetError("called with incorrect number of arguments"); return false; } - // This command supports source list inputs for compatibility. - std::vector<std::string> args; - this->Makefile->ExpandSourceListArguments(argsIn, args, 2); - // Get the moc executable to run in the custom command. const char* moc_exe = this->Makefile->GetRequiredDefinition("QT_MOC_EXECUTABLE"); @@ -35,7 +31,7 @@ bool cmQTWrapCPPCommand::InitialPass(std::vector<std::string> const& argsIn, this->Makefile->GetSafeDefinition(sourceList); // Create a rule for all sources listed. - for(std::vector<std::string>::iterator j = (args.begin() + 2); + for(std::vector<std::string>::const_iterator j = (args.begin() + 2); j != args.end(); ++j) { cmSourceFile *curr = this->Makefile->GetSource(*j); diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx index dce59ef..9b92b1e 100644 --- a/Source/cmQTWrapUICommand.cxx +++ b/Source/cmQTWrapUICommand.cxx @@ -12,19 +12,15 @@ #include "cmQTWrapUICommand.h" // cmQTWrapUICommand -bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn, +bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { - if(argsIn.size() < 4 ) + if(args.size() < 4 ) { this->SetError("called with incorrect number of arguments"); return false; } - // This command supports source list inputs for compatibility. - std::vector<std::string> args; - this->Makefile->ExpandSourceListArguments(argsIn, args, 3); - // Get the uic and moc executables to run in the custom commands. const char* uic_exe = this->Makefile->GetRequiredDefinition("QT_UIC_EXECUTABLE"); @@ -40,7 +36,7 @@ bool cmQTWrapUICommand::InitialPass(std::vector<std::string> const& argsIn, this->Makefile->GetSafeDefinition(sourceList); // Create rules for all sources listed. - for(std::vector<std::string>::iterator j = (args.begin() + 3); + for(std::vector<std::string>::const_iterator j = (args.begin() + 3); j != args.end(); ++j) { cmSourceFile *curr = this->Makefile->GetSource(*j); diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e18e757..4cb49c8 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -16,11 +16,14 @@ #include "cmMakefile.h" #include "cmSourceFile.h" #include "cmSystemTools.h" +#include "cmAlgorithms.h" #if defined(_WIN32) && !defined(__CYGWIN__) # include "cmLocalVisualStudioGenerator.h" #endif +#include <sys/stat.h> + #include <cmsys/Terminal.h> #include <cmsys/ios/sstream> #include <cmsys/FStream.hxx> @@ -371,7 +374,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) #endif std::vector<std::string> rcc_output; - if(makefile->GetLocalGenerator()->GetGlobalGenerator()->GetName() == "Ninja" + bool const isNinja = + makefile->GetLocalGenerator()->GetGlobalGenerator()->GetName() == "Ninja"; + if(isNinja #if defined(_WIN32) && !defined(__CYGWIN__) || usePRE_BUILD #endif @@ -441,7 +446,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) #endif { cmTarget* autogenTarget = 0; - if (!rcc_output.empty()) + if (!rcc_output.empty() && !isNinja) { std::vector<std::string> no_byproducts; makefile->AddCustomCommandToOutput(rcc_output, no_byproducts, @@ -461,7 +466,8 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target) { autogenTarget = makefile->AddUtilityCommand( autogenTargetName, true, - workingDirectory.c_str(), depends, + workingDirectory.c_str(), + /*byproducts=*/rcc_output, depends, commandLines, false, autogenComment.c_str()); } @@ -507,7 +513,7 @@ static void GetCompileDefinitionsAndDirectories(cmTarget const* target, incs = cmJoin(includeDirs, ";"); std::set<std::string> defines; - localGen->AddCompileDefinitions(defines, target, config); + localGen->AddCompileDefinitions(defines, target, config, "CXX"); defs += cmJoin(defines, ";"); } @@ -581,6 +587,18 @@ void cmQtAutoGenerators::SetupAutoGenerateTarget(cmTarget const* target) makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, false); + // Ensure we have write permission in case .in was read-only. + mode_t perm = 0; +#if defined(WIN32) && !defined(__CYGWIN__) + mode_t mode_write = S_IWRITE; +#else + mode_t mode_write = S_IWUSR; +#endif + cmSystemTools::GetPermissions(outputFile, perm); + if (!(perm & mode_write)) + { + cmSystemTools::SetPermissions(outputFile, perm | mode_write); + } if (!configDefines.empty() || !configIncludes.empty() || !configUicOptions.empty()) diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 79fa5df..f74e3c5 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -14,6 +14,8 @@ #ifndef cmQtAutoGenerators_h #define cmQtAutoGenerators_h +#include <list> + class cmGlobalGenerator; class cmMakefile; diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index f4607c6..cb61ed9 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -12,6 +12,7 @@ #include "cmRST.h" #include "cmSystemTools.h" +#include "cmAlgorithms.h" #include "cmVersion.h" #include <cmsys/FStream.hxx> #include <ctype.h> @@ -462,10 +463,7 @@ void cmRST::UnindentLines(std::vector<std::string>& lines) } // Truncate indentation to match that on this line. - if(line.size() < indentEnd) - { - indentEnd = line.size(); - } + indentEnd = std::min(indentEnd, line.size()); for(std::string::size_type j = 0; j != indentEnd; ++j) { if(line[j] != indentText[j]) @@ -486,19 +484,16 @@ void cmRST::UnindentLines(std::vector<std::string>& lines) } } - // Drop leading blank lines. - size_t leadingEmpty = 0; - for(size_t i = 0; i < lines.size() && lines[i].empty(); ++i) - { - ++leadingEmpty; - } - lines.erase(lines.begin(), lines.begin()+leadingEmpty); + std::vector<std::string>::const_iterator it = lines.begin(); + size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string())); - // Drop trailing blank lines. - size_t trailingEmpty = 0; - for(size_t i = lines.size(); i > 0 && lines[i-1].empty(); --i) - { - ++trailingEmpty; - } - lines.erase(lines.end()-trailingEmpty, lines.end()); + std::vector<std::string>::const_reverse_iterator rit = lines.rbegin(); + size_t trailingEmpty = std::distance(rit, + cmFindNot(cmReverseRange(lines), std::string())); + + std::vector<std::string>::iterator contentEnd + = cmRotate(lines.begin(), + lines.begin() + leadingEmpty, + lines.end() - trailingEmpty); + lines.erase(contentEnd, lines.end()); } diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx index 861dbf1..045c82e 100644 --- a/Source/cmSearchPath.cxx +++ b/Source/cmSearchPath.cxx @@ -12,6 +12,7 @@ #include "cmSearchPath.h" #include "cmFindCommon.h" +#include "cmAlgorithms.h" //---------------------------------------------------------------------------- cmSearchPath::cmSearchPath(cmFindCommon* findCmd) @@ -136,10 +137,30 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable) } //---------------------------------------------------------------------------- -void cmSearchPath::AddEnvPrefixPath(const std::string& variable) +static std::string cmSearchPathStripBin(std::string const& s) +{ + // If the path is a PREFIX/bin case then add its parent instead. + if((cmHasLiteralSuffix(s, "/bin")) || + (cmHasLiteralSuffix(s, "/sbin"))) + { + return cmSystemTools::GetFilenamePath(s); + } + else + { + return s; + } +} + +//---------------------------------------------------------------------------- +void cmSearchPath::AddEnvPrefixPath(const std::string& variable, bool stripBin) { std::vector<std::string> expanded; cmSystemTools::GetPath(expanded, variable.c_str()); + if (stripBin) + { + std::transform(expanded.begin(), expanded.end(), expanded.begin(), + cmSearchPathStripBin); + } this->AddPrefixPaths(expanded); } diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h index 51a6149..41c680d 100644 --- a/Source/cmSearchPath.h +++ b/Source/cmSearchPath.h @@ -42,7 +42,7 @@ public: 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 AddEnvPrefixPath(const std::string& variable, bool stripBin = false); void AddSuffixes(const std::vector<std::string>& suffixes); protected: diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index 90d7b03..204d95b 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -108,17 +108,7 @@ bool cmSetCommand } // collect any values into a single semi-colon separated value list - if(static_cast<unsigned short>(args.size()) > - static_cast<unsigned short>(1 + ignoreLastArgs)) - { - value = args[1]; - size_t endPos = args.size() - ignoreLastArgs; - for(size_t i = 2; i < endPos; ++i) - { - value += ";"; - value += args[i]; - } - } + value = cmJoin(cmRange(args).advance(1).retreat(ignoreLastArgs), ";"); if (parentScope) { diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx index aeb8077..06217bb 100644 --- a/Source/cmSetTargetPropertiesCommand.cxx +++ b/Source/cmSetTargetPropertiesCommand.cxx @@ -25,40 +25,25 @@ bool cmSetTargetPropertiesCommand // first collect up the list of files std::vector<std::string> propertyPairs; - bool doingFiles = true; int numFiles = 0; std::vector<std::string>::const_iterator j; for(j= args.begin(); j != args.end();++j) { if(*j == "PROPERTIES") { - doingFiles = false; // now loop through the rest of the arguments, new style ++j; - while (j != args.end()) + if (std::distance(j, args.end()) % 2 != 0) { - propertyPairs.push_back(*j); - ++j; - if(j == args.end()) - { - this->SetError("called with incorrect number of arguments."); - return false; - } - propertyPairs.push_back(*j); - ++j; + this->SetError("called with incorrect number of arguments."); + return false; } - // break out of the loop because j is already == end + propertyPairs.insert(propertyPairs.end(), j, args.end()); break; } - else if (doingFiles) - { - numFiles++; - } else { - this->SetError("called with illegal arguments, maybe missing " - "a PROPERTIES specifier?"); - return false; + numFiles++; } } if(propertyPairs.empty()) diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx index e66d13d..e9cfacc 100644 --- a/Source/cmSetTestsPropertiesCommand.cxx +++ b/Source/cmSetTestsPropertiesCommand.cxx @@ -26,40 +26,25 @@ bool cmSetTestsPropertiesCommand // first collect up the list of files std::vector<std::string> propertyPairs; - bool doingFiles = true; int numFiles = 0; std::vector<std::string>::const_iterator j; for(j= args.begin(); j != args.end();++j) { if(*j == "PROPERTIES") { - doingFiles = false; // now loop through the rest of the arguments, new style ++j; - while (j != args.end()) + if (std::distance(j, args.end()) % 2 != 0) { - propertyPairs.push_back(*j); - ++j; - if(j == args.end()) - { - this->SetError("called with incorrect number of arguments."); - return false; - } - propertyPairs.push_back(*j); - ++j; + this->SetError("called with incorrect number of arguments."); + return false; } - // break out of the loop because j is already == end + propertyPairs.insert(propertyPairs.end(), j, args.end()); break; } - else if (doingFiles) - { - numFiles++; - } else { - this->SetError("called with illegal arguments, maybe " - "missing a PROPERTIES specifier?"); - return false; + numFiles++; } } if(propertyPairs.empty()) @@ -69,7 +54,6 @@ bool cmSetTestsPropertiesCommand return false; } - // now loop over all the targets int i; for(i = 0; i < numFiles; ++i) diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx index b81951d..9d67c1e 100644 --- a/Source/cmSourceFileLocation.cxx +++ b/Source/cmSourceFileLocation.cxx @@ -15,6 +15,7 @@ #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" #include "cmSystemTools.h" +#include "cmAlgorithms.h" #include "assert.h" diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 646300d..a9796b9 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -22,7 +22,6 @@ #ifdef _MSC_VER #pragma warning ( disable : 4786 ) #pragma warning ( disable : 4503 ) -#pragma warning ( disable : 4512 ) /* operator=() could not be generated */ #endif @@ -42,11 +41,6 @@ # include <cmsys/IOStream.hxx> #endif -// Avoid warnings in system headers. -#if defined(_MSC_VER) -# pragma warning (push,1) -#endif - #include <fstream> #include <iostream> #include <iomanip> @@ -59,13 +53,7 @@ #include <algorithm> #include <functional> #include <map> -#include <list> #include <set> -#include <deque> - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif // include the "c" string header #include <string.h> @@ -143,138 +131,4 @@ 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) -{ - return strncmp(str1.c_str(), str2, N) == 0; -} - -inline bool cmHasLiteralPrefixImpl(const char* str1, - const char *str2, - size_t N) -{ - return strncmp(str1, str2, N) == 0; -} - -inline bool cmHasLiteralSuffixImpl(const std::string &str1, - const char *str2, - size_t N) -{ - size_t len = str1.size(); - return len >= N && strcmp(str1.c_str() + len - N, str2) == 0; -} - -inline bool cmHasLiteralSuffixImpl(const char* str1, - const char* str2, - size_t N) -{ - size_t len = strlen(str1); - return len >= N && strcmp(str1 + len - N, str2) == 0; -} - -template<typename T, size_t N> -const T* cmArrayBegin(const T (&a)[N]) { return a; } -template<typename T, size_t N> -const T* cmArrayEnd(const T (&a)[N]) { return a + N; } -template<typename T, size_t N> -size_t cmArraySize(const T (&)[N]) { return N; } - -template<typename T, size_t N> -bool cmHasLiteralPrefix(T str1, const char (&str2)[N]) -{ - return cmHasLiteralPrefixImpl(str1, str2, N - 1); -} - -template<typename T, size_t N> -bool cmHasLiteralSuffix(T str1, const char (&str2)[N]) -{ - return cmHasLiteralSuffixImpl(str1, str2, N - 1); -} - -struct cmStrCmp { - cmStrCmp(const char *test) : m_test(test) {} - cmStrCmp(const std::string &test) : m_test(test) {} - - bool operator()(const std::string& input) const - { - return m_test == input; - } - - bool operator()(const char * input) const - { - return strcmp(input, m_test.c_str()) == 0; - } - -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/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 3e606d7..edc6afc 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -303,13 +303,6 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) std::string regex = args[2]; std::string outvar = args[3]; - // Concatenate all the last arguments together. - std::string input = args[4]; - for(unsigned int i=5; i < args.size(); ++i) - { - input += args[i]; - } - this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; @@ -321,6 +314,9 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) return false; } + // Concatenate all the last arguments together. + std::string input = cmJoin(cmRange(args).advance(4), std::string()); + // Scan through the input for all matches. std::string output; if(re.find(input.c_str())) @@ -352,13 +348,6 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) std::string regex = args[2]; std::string outvar = args[3]; - // Concatenate all the last arguments together. - std::string input = args[4]; - for(unsigned int i=5; i < args.size(); ++i) - { - input += args[i]; - } - this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; @@ -371,6 +360,9 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) return false; } + // Concatenate all the last arguments together. + std::string input = cmJoin(cmRange(args).advance(4), std::string()); + // Scan through the input for all matches. std::string output; const char* p = input.c_str(); @@ -456,13 +448,6 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) l = r; } - // Concatenate all the last arguments together. - std::string input = args[5]; - for(unsigned int i=6; i < args.size(); ++i) - { - input += args[i]; - } - this->Makefile->ClearMatches(); // Compile the regular expression. cmsys::RegularExpression re; @@ -475,6 +460,9 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) return false; } + // Concatenate all the last arguments together. + std::string input = cmJoin(cmRange(args).advance(5), std::string()); + // Scan through the input for all matches. std::string output; std::string::size_type base = 0; @@ -673,11 +661,7 @@ bool cmStringCommand::HandleReplaceCommand(std::vector<std::string> const& const std::string& replaceExpression = args[2]; const std::string& variableName = args[3]; - std::string input = args[4]; - for(unsigned int i=5; i < args.size(); ++i) - { - input += args[i]; - } + std::string input = cmJoin(cmRange(args).advance(4), std::string()); cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(), replaceExpression.c_str()); @@ -756,11 +740,7 @@ bool cmStringCommand } std::string const& variableName = args[1]; - std::string value; - for(unsigned int i = 2; i < args.size(); ++i) - { - value += args[i]; - } + std::string value = cmJoin(cmRange(args).advance(2), std::string()); this->Makefile->AddDefinition(variableName, value.c_str()); return true; diff --git a/Source/cmSubdirCommand.cxx b/Source/cmSubdirCommand.cxx index 93ad4f3..7cb2edc 100644 --- a/Source/cmSubdirCommand.cxx +++ b/Source/cmSubdirCommand.cxx @@ -22,7 +22,6 @@ bool cmSubdirCommand } bool res = true; bool excludeFromAll = false; - bool preorder = false; for(std::vector<std::string>::const_iterator i = args.begin(); i != args.end(); ++i) @@ -34,7 +33,7 @@ bool cmSubdirCommand } if(*i == "PREORDER") { - preorder = true; + // Ignored continue; } @@ -48,7 +47,7 @@ bool cmSubdirCommand std::string(this->Makefile->GetCurrentOutputDirectory()) + "/" + i->c_str(); this->Makefile->AddSubDirectory(srcPath, binPath, - excludeFromAll, preorder, false); + excludeFromAll, false); } // otherwise it is a full path else if ( cmSystemTools::FileIsDirectory(*i) ) @@ -59,7 +58,7 @@ bool cmSubdirCommand std::string(this->Makefile->GetCurrentOutputDirectory()) + "/" + cmSystemTools::GetFilenameName(*i); this->Makefile->AddSubDirectory(*i, binPath, - excludeFromAll, preorder, false); + excludeFromAll, false); } else { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 6a7467f..5264123 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmSystemTools.h" +#include "cmAlgorithms.h" #include <ctype.h> #include <errno.h> #include <time.h> @@ -28,10 +29,10 @@ # include "cmArchiveWrite.h" # include "cmLocale.h" # include <cm_libarchive.h> -# include <cmsys/Terminal.h> #endif #include <cmsys/stl/algorithm> #include <cmsys/FStream.hxx> +#include <cmsys/Terminal.h> #if defined(_WIN32) # include <windows.h> @@ -367,13 +368,17 @@ bool cmSystemTools::IsInternallyOn(const char* val) return false; } std::basic_string<char> v = val; + if (v.size() > 4) + { + return false; + } for(std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } - return (v == "I_ON" || v == "i_on"); + return v == "I_ON"; } bool cmSystemTools::IsOn(const char* val) @@ -830,7 +835,7 @@ cmSystemTools::PrintSingleCommand(std::vector<std::string> const& command) return std::string(); } - return "\"" + cmJoin(command, "\" \"") + "\""; + return cmWrap('"', command, '"', " "); } bool cmSystemTools::DoesFileExistWithExtensions( @@ -2287,7 +2292,6 @@ std::string const& cmSystemTools::GetCMakeRoot() } //---------------------------------------------------------------------------- -#if defined(CMAKE_BUILD_WITH_CMAKE) void cmSystemTools::MakefileColorEcho(int color, const char* message, bool newline, bool enabled) { @@ -2308,16 +2312,21 @@ void cmSystemTools::MakefileColorEcho(int color, const char* message, if(enabled) { - cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s%s", - message, newline? "\n" : ""); + // Print with color. Delay the newline until later so that + // all color restore sequences appear before it. + cmsysTerminal_cfprintf(color | assumeTTY, stdout, "%s", message); } else { // Color is disabled. Print without color. - fprintf(stdout, "%s%s", message, newline? "\n" : ""); + fprintf(stdout, "%s", message); + } + + if(newline) + { + fprintf(stdout, "\n"); } } -#endif //---------------------------------------------------------------------------- bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath, @@ -2698,7 +2707,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg, } if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection) { - cmsys_stl::swap(se[0], se[1]); + std::swap(se[0], se[1]); } // Get the size of the dynamic section header. diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 361f42e..c59ae96 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -428,11 +428,9 @@ public: static std::string const& GetCMakeCursesCommand(); static std::string const& GetCMakeRoot(); -#if defined(CMAKE_BUILD_WITH_CMAKE) /** Echo a message in color using KWSys's Terminal cprintf. */ static void MakefileColorEcho(int color, const char* message, bool newLine, bool enabled); -#endif /** Try to guess the soname of a shared library. */ static bool GuessLibrarySOName(std::string const& fullPath, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 98cb75c..b3d1155 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -19,6 +19,7 @@ #include "cmListFileCache.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionDAGChecker.h" +#include "cmAlgorithms.h" #include <cmsys/RegularExpression.hxx> #include <map> #include <set> @@ -615,6 +616,13 @@ bool cmTarget::IsCFBundleOnApple() const } //---------------------------------------------------------------------------- +bool cmTarget::IsXCTestOnApple() const +{ + return (this->IsCFBundleOnApple() && + this->GetPropertyAsBool("XCTEST")); +} + +//---------------------------------------------------------------------------- bool cmTarget::IsBundleOnApple() const { return this->IsFrameworkOnApple() || this->IsAppBundleOnApple() || @@ -1153,15 +1161,11 @@ cmTarget::LinkLibraryType cmTarget::ComputeLinkType( // Check if any entry in the list matches this configuration. std::string configUpper = cmSystemTools::UpperCase(config); - for(std::vector<std::string>::const_iterator i = debugConfigs.begin(); - i != debugConfigs.end(); ++i) + if (std::find(debugConfigs.begin(), debugConfigs.end(), configUpper) != + debugConfigs.end()) { - if(*i == configUpper) - { - return cmTarget::DEBUG; - } + return cmTarget::DEBUG; } - // The current configuration is not a debug configuration. return cmTarget::OPTIMIZED; } @@ -1546,12 +1550,9 @@ void cmTarget::DeleteDependencyForVS6( DependencyMap& depMap, if( map_itr != depMap.end() ) { DependencyList& depList = map_itr->second; - DependencyList::iterator itr; - while( (itr = std::find(depList.begin(), depList.end(), dep)) != - depList.end() ) - { - depList.erase( itr ); - } + DependencyList::iterator begin = + std::remove(depList.begin(), depList.end(), dep); + depList.erase(begin, depList.end()); } } @@ -1986,7 +1987,8 @@ static void processIncludeDirectories(cmTarget const* tgt, std::vector<std::string> &includes, UNORDERED_SET<std::string> &uniqueIncludes, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugIncludes) + const std::string& config, bool debugIncludes, + const std::string& language) { cmMakefile *mf = tgt->GetMakefile(); @@ -2002,7 +2004,7 @@ static void processIncludeDirectories(cmTarget const* tgt, config, false, tgt, - dagChecker), + dagChecker, language), entryIncludes); std::string usedIncludes; @@ -2113,7 +2115,8 @@ static void processIncludeDirectories(cmTarget const* tgt, //---------------------------------------------------------------------------- std::vector<std::string> -cmTarget::GetIncludeDirectories(const std::string& config) const +cmTarget::GetIncludeDirectories(const std::string& config, + const std::string& language) const { std::vector<std::string> includes; UNORDERED_SET<std::string> uniqueIncludes; @@ -2146,7 +2149,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceIncludeDirectoriesEntries; @@ -2186,7 +2190,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); deleteAndClear(linkInterfaceIncludeDirectoriesEntries); @@ -2199,7 +2204,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions, const char *logName) + const std::string& config, bool debugOptions, const char *logName, + std::string const& language) { cmMakefile *mf = tgt->GetMakefile(); @@ -2211,7 +2217,8 @@ static void processCompileOptionsInternal(cmTarget const* tgt, config, false, tgt, - dagChecker), + dagChecker, + language), entryOptions); std::string usedOptions; for(std::vector<std::string>::iterator @@ -2245,10 +2252,12 @@ static void processCompileOptions(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions) + const std::string& config, bool debugOptions, + std::string const& language) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "options"); + dagChecker, config, debugOptions, "options", + language); } //---------------------------------------------------------------------------- @@ -2278,7 +2287,8 @@ void cmTarget::GetAutoUicOptions(std::vector<std::string> &result, //---------------------------------------------------------------------------- void cmTarget::GetCompileOptions(std::vector<std::string> &result, - const std::string& config) const + const std::string& config, + const std::string& language) const { UNORDERED_SET<std::string> uniqueOptions; @@ -2310,7 +2320,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileOptionsEntries; @@ -2325,7 +2336,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); deleteAndClear(linkInterfaceCompileOptionsEntries); } @@ -2336,16 +2348,18 @@ static void processCompileDefinitions(cmTarget const* tgt, std::vector<std::string> &options, UNORDERED_SET<std::string> &uniqueOptions, cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions) + const std::string& config, bool debugOptions, + std::string const& language) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, config, debugOptions, - "definitions"); + "definitions", language); } //---------------------------------------------------------------------------- void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, - const std::string& config) const + const std::string& config, + const std::string& language) const { UNORDERED_SET<std::string> uniqueOptions; @@ -2377,7 +2391,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileDefinitionsEntries; @@ -2424,7 +2439,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); deleteAndClear(linkInterfaceCompileDefinitionsEntries); } @@ -2438,7 +2454,8 @@ static void processCompileFeatures(cmTarget const* tgt, const std::string& config, bool debugOptions) { processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "features"); + dagChecker, config, debugOptions, "features", + std::string()); } //---------------------------------------------------------------------------- @@ -4715,13 +4732,11 @@ bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const //---------------------------------------------------------------------------- template<typename PropertyType> -PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop, - PropertyType *); +PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop); //---------------------------------------------------------------------------- template<> -bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop, - bool *) +bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop) { return tgt->GetPropertyAsBool(prop); } @@ -4729,8 +4744,7 @@ bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop, //---------------------------------------------------------------------------- template<> const char *getTypedProperty<const char *>(cmTarget const* tgt, - const std::string& prop, - const char **) + const std::string& prop) { return tgt->GetProperty(prop); } @@ -4941,8 +4955,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, CompatibleType t, PropertyType *) { - PropertyType propContent = getTypedProperty<PropertyType>(tgt, p, - 0); + PropertyType propContent = getTypedProperty<PropertyType>(tgt, p); const bool explicitlySet = tgt->GetProperties() .find(p) != tgt->GetProperties().end(); @@ -4995,7 +5008,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, != theTarget->GetProperties().end(); PropertyType ifacePropContent = getTypedProperty<PropertyType>(theTarget, - interfaceProperty, 0); + interfaceProperty); std::string reportEntry; if (ifaceIsSet) @@ -5919,8 +5932,7 @@ cmTarget::GetCompatibleInterfaces(std::string const& config) const { \ std::vector<std::string> props; \ cmSystemTools::ExpandListArgument(prop, props); \ - std::copy(props.begin(), props.end(), \ - std::inserter(compat.Props##x, compat.Props##x.begin())); \ + compat.Props##x.insert(props.begin(), props.end()); \ } CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool) CM_READ_COMPATIBLE_INTERFACE(STRING, String) @@ -6692,40 +6704,33 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, if (!prop.empty()) { - // Use a std::set to keep the error message sorted. - std::set<std::string> props; + // Use a sorted std::vector to keep the error message sorted. + std::vector<std::string> props; std::set<std::string>::const_iterator i = emittedBools.find(prop); if (i != emittedBools.end()) { - props.insert(strBool); + props.push_back(strBool); } i = emittedStrings.find(prop); if (i != emittedStrings.end()) { - props.insert(strString); + props.push_back(strString); } i = emittedMinNumbers.find(prop); if (i != emittedMinNumbers.end()) { - props.insert(strNumMin); + props.push_back(strNumMin); } i = emittedMaxNumbers.find(prop); if (i != emittedMaxNumbers.end()) { - props.insert(strNumMax); + props.push_back(strNumMax); } + std::sort(props.begin(), props.end()); + + std::string propsString = cmJoin(cmRange(props).retreat(1), ", "); + propsString += " and the " + props.back(); - std::string propsString = *props.begin(); - props.erase(props.begin()); - while (props.size() > 1) - { - propsString += ", " + *props.begin(); - props.erase(props.begin()); - } - if (props.size() == 1) - { - propsString += " and the " + *props.begin(); - } std::ostringstream e; e << "Property \"" << prop << "\" appears in both the " << propsString << @@ -6793,7 +6798,14 @@ std::string cmTarget::GetCFBundleDirectory(const std::string& config, const char *ext = this->GetProperty("BUNDLE_EXTENSION"); if (!ext) { - ext = "bundle"; + if (this->IsXCTestOnApple()) + { + ext = "xctest"; + } + else + { + ext = "bundle"; + } } fpath += ext; fpath += "/Contents"; @@ -6891,11 +6903,11 @@ cmTargetInternalPointer //---------------------------------------------------------------------------- cmTargetInternalPointer::~cmTargetInternalPointer() { - deleteAndClear(this->Pointer->IncludeDirectoriesEntries); - deleteAndClear(this->Pointer->CompileOptionsEntries); - deleteAndClear(this->Pointer->CompileFeaturesEntries); - deleteAndClear(this->Pointer->CompileDefinitionsEntries); - deleteAndClear(this->Pointer->SourceEntries); + cmDeleteAll(this->Pointer->IncludeDirectoriesEntries); + cmDeleteAll(this->Pointer->CompileOptionsEntries); + cmDeleteAll(this->Pointer->CompileFeaturesEntries); + cmDeleteAll(this->Pointer->CompileDefinitionsEntries); + cmDeleteAll(this->Pointer->SourceEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index ddd9859..a4ef977 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -496,7 +496,8 @@ public: const char* GetExportMacro() const; void GetCompileDefinitions(std::vector<std::string> &result, - const std::string& config) const; + const std::string& config, + const std::string& language) const; // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change @@ -526,6 +527,9 @@ public: /** Return whether this target is a CFBundle (plugin) on Apple. */ bool IsCFBundleOnApple() const; + /** Return whether this target is a XCTest on Apple. */ + bool IsXCTestOnApple() const; + /** Return whether this target is an executable Bundle on Apple. */ bool IsAppBundleOnApple() const; @@ -567,7 +571,8 @@ public: bool contentOnly) const; std::vector<std::string> GetIncludeDirectories( - const std::string& config) const; + const std::string& config, + const std::string& language) const; void InsertInclude(const cmValueWithOrigin &entry, bool before = false); void InsertCompileOption(const cmValueWithOrigin &entry, @@ -577,7 +582,8 @@ public: void AppendBuildInterfaceIncludes(); void GetCompileOptions(std::vector<std::string> &result, - const std::string& config) const; + const std::string& config, + const std::string& language) const; void GetAutoUicOptions(std::vector<std::string> &result, const std::string& config) const; void GetCompileFeatures(std::vector<std::string> &features, diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index dc19720..394a166 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmTargetCompileDefinitionsCommand.h" +#include "cmAlgorithms.h" + bool cmTargetCompileDefinitionsCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx index 6ebc31e..823afa1 100644 --- a/Source/cmTargetCompileFeaturesCommand.cxx +++ b/Source/cmTargetCompileFeaturesCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmTargetCompileFeaturesCommand.h" +#include "cmAlgorithms.h" + bool cmTargetCompileFeaturesCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus &) diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index 8c6fc06..a85153d 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmTargetCompileOptionsCommand.h" +#include "cmAlgorithms.h" + bool cmTargetCompileOptionsCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx index b8a6df2..57dde31 100644 --- a/Source/cmVariableWatch.cxx +++ b/Source/cmVariableWatch.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmVariableWatch.h" +#include "cmAlgorithms.h" + static const char* const cmVariableWatchAccessStrings[] = { "READ_ACCESS", diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index a286049..19444ed 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1876,7 +1876,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); std::vector<std::string> targetDefines; - this->Target->GetCompileDefinitions(targetDefines, configName.c_str()); + this->Target->GetCompileDefinitions(targetDefines, + configName.c_str(), "CXX"); clOptions.AddDefines(targetDefines); if(this->MSTools) { @@ -2522,7 +2523,8 @@ WriteMidlOptions(std::string const& /*config*/, } this->WriteString("%(AdditionalIncludeDirectories)" "</AdditionalIncludeDirectories>\n", 0); - this->WriteString("<OutputDirectory>$(IntDir)</OutputDirectory>\n", 3); + this->WriteString("<OutputDirectory>$(ProjectDir)/$(IntDir)" + "</OutputDirectory>\n", 3); this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3); this->WriteString( "<TypeLibraryName>%(Filename).tlb</TypeLibraryName>\n", 3); diff --git a/Source/cmXMLSafe.cxx b/Source/cmXMLSafe.cxx index 72fdc34..99f5625 100644 --- a/Source/cmXMLSafe.cxx +++ b/Source/cmXMLSafe.cxx @@ -28,7 +28,7 @@ cmXMLSafe::cmXMLSafe(const char* s): } //---------------------------------------------------------------------------- -cmXMLSafe::cmXMLSafe(cmsys_stl::string const& s): +cmXMLSafe::cmXMLSafe(std::string const& s): Data(s.c_str()), Size(static_cast<unsigned long>(s.length())), DoQuotes(true) @@ -43,7 +43,7 @@ cmXMLSafe& cmXMLSafe::Quotes(bool b) } //---------------------------------------------------------------------------- -cmsys_stl::string cmXMLSafe::str() +std::string cmXMLSafe::str() { cmsys_ios::ostringstream ss; ss << *this; diff --git a/Source/cmXMLSafe.h b/Source/cmXMLSafe.h index cba9f39..c23a90c 100644 --- a/Source/cmXMLSafe.h +++ b/Source/cmXMLSafe.h @@ -24,7 +24,7 @@ public: /** Construct with the data to be written. This assumes the data will exist for the duration of this object's life. */ cmXMLSafe(const char* s); - cmXMLSafe(cmsys_stl::string const& s); + cmXMLSafe(std::string const& s); /** Specify whether to escape quotes too. This is needed when writing the content of an attribute value. By default quotes @@ -32,7 +32,7 @@ public: cmXMLSafe& Quotes(bool b = true); /** Get the escaped data as a string. */ - cmsys_stl::string str(); + std::string str(); private: char const* Data; unsigned long Size; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 652e451..51df7f2 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -20,6 +20,7 @@ #include "cmSourceFile.h" #include "cmTest.h" #include "cmDocumentationFormatter.h" +#include "cmAlgorithms.h" #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmGraphVizWriter.h" @@ -85,6 +86,8 @@ # include "cmGlobalKdevelopGenerator.h" #endif +#include "cmExtraQbsGenerator.h" + #ifdef CMAKE_USE_ECLIPSE # include "cmExtraEclipseCDT4Generator.h" #endif @@ -103,6 +106,8 @@ #include <sys/stat.h> // struct stat +#include <list> + static bool cmakeCheckStampFile(const char* stampName); static bool cmakeCheckStampList(const char* stampName); @@ -1026,6 +1031,8 @@ void cmake::AddDefaultExtraGenerators() &cmExtraSublimeTextGenerator::New); this->AddExtraGenerator(cmExtraKateGenerator::GetActualName(), &cmExtraKateGenerator::New); + this->AddExtraGenerator(cmExtraQbsGenerator::GetActualName(), + &cmExtraQbsGenerator::New); #ifdef CMAKE_USE_ECLIPSE this->AddExtraGenerator(cmExtraEclipseCDT4Generator::GetActualName(), @@ -2731,11 +2738,10 @@ std::vector<std::string> const& cmake::GetDebugConfigs() { // Expand the specified list and convert to upper-case. cmSystemTools::ExpandListArgument(config_list, this->DebugConfigs); - for(std::vector<std::string>::iterator i = this->DebugConfigs.begin(); - i != this->DebugConfigs.end(); ++i) - { - *i = cmSystemTools::UpperCase(*i); - } + std::transform(this->DebugConfigs.begin(), + this->DebugConfigs.end(), + this->DebugConfigs.begin(), + cmSystemTools::UpperCase); } // If no configurations were specified, use a default list. if(this->DebugConfigs.empty()) @@ -2788,11 +2794,16 @@ int cmake::Build(const std::string& dir, return 1; } projName = it.GetValue(); + bool verbose = false; + if(it.Find("CMAKE_VERBOSE_MAKEFILE")) + { + verbose = it.GetValueAsBool(); + } return gen->Build("", dir, projName, target, output, "", - config, clean, false, 0, + config, clean, false, verbose, 0, cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index e0bd55b..ac73ad0 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -24,6 +24,7 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmAlgorithms.h" #include <cmsys/Encoding.hxx> #ifdef CMAKE_BUILD_WITH_CMAKE diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 28fcd27..9f2ea46 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -15,15 +15,16 @@ #include "cmGlobalGenerator.h" #include "cmQtAutoGenerators.h" #include "cmVersion.h" +#include "cmAlgorithms.h" #if defined(CMAKE_BUILD_WITH_CMAKE) # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. -# include <cmsys/Terminal.h> #endif #include <cmsys/Directory.hxx> #include <cmsys/Process.h> #include <cmsys/FStream.hxx> +#include <cmsys/Terminal.h> #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" @@ -213,27 +214,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Echo string else if (args[1] == "echo" ) { - unsigned int cc; - const char* space = ""; - for ( cc = 2; cc < args.size(); cc ++ ) - { - std::cout << space << args[cc]; - space = " "; - } - std::cout << std::endl; + std::cout << cmJoin(cmRange(args).advance(2), " ") << std::endl; return 0; } // Echo string no new line else if (args[1] == "echo_append" ) { - unsigned int cc; - const char* space = ""; - for ( cc = 2; cc < args.size(); cc ++ ) - { - std::cout << space << args[cc]; - space = " "; - } + std::cout << cmJoin(cmRange(args).advance(2), " "); return 0; } @@ -287,8 +275,6 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) } #if defined(CMAKE_BUILD_WITH_CMAKE) - // Command to create a symbolic link. Fails on platforms not - // supporting them. else if (args[1] == "environment" ) { std::vector<std::string> env = cmSystemTools::GetEnvironmentVariables(); @@ -352,8 +338,6 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) { for (std::string::size_type cc = 2; cc < args.size(); cc ++) { - // Complain if the file could not be removed, still exists, - // and the -f option was not given. if(!cmSystemTools::Touch(args[cc], true)) { return 1; @@ -406,12 +390,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Clock command else if (args[1] == "time" && args.size() > 2) { - std::string command = args[2]; - for (std::string::size_type cc = 3; cc < args.size(); cc ++) - { - command += " "; - command += args[cc]; - } + std::string command = cmJoin(cmRange(args).advance(2), " "); clock_t clock_start, clock_finish; time_t time_start, time_finish; @@ -472,15 +451,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) return 1; } - std::string command = "\""; - command += args[3]; - command += "\""; - for (std::string::size_type cc = 4; cc < args.size(); cc ++) - { - command += " \""; - command += args[cc]; - command += "\""; - } + std::string command = cmWrap('"', cmRange(args).advance(3), '"', " "); int retval = 0; int timeout = 0; if ( cmSystemTools::RunSingleCommand(command.c_str(), 0, &retval, @@ -534,48 +505,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Command to report progress for a build else if (args[1] == "cmake_progress_report" && args.size() >= 3) { - std::string dirName = args[2]; - dirName += "/Progress"; - std::string fName; - FILE *progFile; - - // read the count - fName = dirName; - fName += "/count.txt"; - progFile = cmsys::SystemTools::Fopen(fName,"r"); - int count = 0; - if (!progFile) - { - return 0; - } - else - { - if (1!=fscanf(progFile,"%i",&count)) - { - cmSystemTools::Message("Could not read from progress file."); - } - fclose(progFile); - } - unsigned int i; - for (i = 3; i < args.size(); ++i) - { - fName = dirName; - fName += "/"; - fName += args[i]; - progFile = cmsys::SystemTools::Fopen(fName,"w"); - if (progFile) - { - fprintf(progFile,"empty"); - fclose(progFile); - } - } - int fileNum = static_cast<int> - (cmsys::Directory::GetNumberOfFilesInDirectory(dirName)); - if (count > 0) - { - // print the progress - fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count); - } + // This has been superseded by cmake_echo_color --progress-* + // options. We leave it here to avoid errors if somehow this + // is invoked by an existing makefile without regenerating. return 0; } @@ -753,12 +685,12 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) { return cmcmd::VisualStudioLink(args, 2); } -#ifdef CMAKE_BUILD_WITH_CMAKE // Internal CMake color makefile support. else if (args[1] == "cmake_echo_color") { return cmcmd::ExecuteEchoColor(args); } +#ifdef CMAKE_BUILD_WITH_CMAKE else if (args[1] == "cmake_autogen" && args.size() >= 4) { cmQtAutoGenerators autogen; @@ -987,7 +919,65 @@ bool cmcmd::SymlinkInternal(std::string const& file, std::string const& link) } //---------------------------------------------------------------------------- -#ifdef CMAKE_BUILD_WITH_CMAKE +static void cmcmdProgressReport(std::string const& dir, + std::string const& num) +{ + std::string dirName = dir; + dirName += "/Progress"; + std::string fName; + FILE *progFile; + + // read the count + fName = dirName; + fName += "/count.txt"; + progFile = cmsys::SystemTools::Fopen(fName,"r"); + int count = 0; + if (!progFile) + { + return; + } + else + { + if (1!=fscanf(progFile,"%i",&count)) + { + cmSystemTools::Message("Could not read from progress file."); + } + fclose(progFile); + } + const char* last = num.c_str(); + for(const char* c = last;; ++c) + { + if (*c == ',' || *c == '\0') + { + if (c != last) + { + fName = dirName; + fName += "/"; + fName.append(last, c-last); + progFile = cmsys::SystemTools::Fopen(fName,"w"); + if (progFile) + { + fprintf(progFile,"empty"); + fclose(progFile); + } + } + if(*c == '\0') + { + break; + } + last = c + 1; + } + } + int fileNum = static_cast<int> + (cmsys::Directory::GetNumberOfFilesInDirectory(dirName)); + if (count > 0) + { + // print the progress + fprintf(stdout,"[%3i%%] ",((fileNum-3)*100)/count); + } +} + +//---------------------------------------------------------------------------- int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) { // The arguments are @@ -997,6 +987,7 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) bool enabled = true; int color = cmsysTerminal_Color_Normal; bool newline = true; + std::string progressDir; for(unsigned int i=2; i < args.size(); ++i) { if(args[i].find("--switch=") == 0) @@ -1015,6 +1006,18 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) } } } + else if(cmHasLiteralPrefix(args[i], "--progress-dir=")) + { + progressDir = args[i].substr(15); + } + else if(cmHasLiteralPrefix(args[i], "--progress-num=")) + { + if (!progressDir.empty()) + { + std::string const& progressNum = args[i].substr(15); + cmcmdProgressReport(progressDir, progressNum); + } + } else if(args[i] == "--normal") { color = cmsysTerminal_Color_Normal; @@ -1073,12 +1076,6 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string>& args) return 0; } -#else -int cmcmd::ExecuteEchoColor(std::vector<std::string>&) -{ - return 1; -} -#endif //---------------------------------------------------------------------------- int cmcmd::ExecuteLinkScript(std::vector<std::string>& args) @@ -1318,12 +1315,7 @@ bool cmcmd::RunCommand(const char* comment, if(verbose) { std::cout << comment << ":\n"; - for(std::vector<std::string>::iterator i = command.begin(); - i != command.end(); ++i) - { - std::cout << *i << " "; - } - std::cout << "\n"; + std::cout << cmJoin(command, " ") << "\n"; } std::string output; int retCode =0; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index c0eb8ac..0fc47b7 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -75,6 +75,8 @@ static const char * cmDocumentationOptions[][2] = "Run a specific number of tests by number."}, {"-U, --union", "Take the Union of -I and -R"}, {"--rerun-failed", "Run only the tests that failed previously"}, + {"--repeat-until-fail <n>", "Require each test to run <n> " + "times without failing in order to pass"}, {"--max-width <width>", "Set the max width for a test name to output"}, {"--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1."}, {"--no-label-summary", "Disable timing summary information for labels."}, diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 5a96aed..11bfd16 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -19,6 +19,7 @@ #include KWSYS_HEADER(Directory.hxx) #include KWSYS_HEADER(stl/string) #include KWSYS_HEADER(stl/vector) +#include KWSYS_HEADER(stl/algorithm) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. @@ -30,6 +31,8 @@ # include "SystemTools.hxx.in" # include "kwsys_stl.hxx.in" # include "kwsys_stl_string.hxx.in" +# include "kwsys_stl_vector.hxx.in" +# include "kwsys_stl_algorithm.hxx.in" #endif #include <ctype.h> @@ -66,6 +69,10 @@ Glob::Glob() // RecurseThroughSymlinks is true by default for backwards compatibility, // not because it's a good idea... this->FollowedSymlinkCount = 0; + + // Keep separate variables for directory listing for back compatibility + this->ListDirs = true; + this->RecurseListDirs = false; } //---------------------------------------------------------------------------- @@ -214,16 +221,15 @@ kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern, } //---------------------------------------------------------------------------- -void Glob::RecurseDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir) +bool Glob::RecurseDirectory(kwsys_stl::string::size_type start, + const kwsys_stl::string& dir, GlobMessages* messages) { kwsys::Directory d; if ( !d.Load(dir) ) { - return; + return true; } unsigned long cc; - kwsys_stl::string fullname; kwsys_stl::string realname; kwsys_stl::string fname; for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ ) @@ -248,15 +254,6 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start, fname = kwsys::SystemTools::LowerCase(fname); #endif - if ( start == 0 ) - { - fullname = dir + fname; - } - else - { - fullname = dir + "/" + fname; - } - bool isDir = kwsys::SystemTools::FileIsDirectory(realname); bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname); @@ -265,8 +262,67 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start, if (isSymLink) { ++this->FollowedSymlinkCount; + kwsys_stl::string realPathErrorMessage; + kwsys_stl::string canonicalPath(SystemTools::GetRealPath(dir, + &realPathErrorMessage)); + + if(!realPathErrorMessage.empty()) + { + if(messages) + { + messages->push_back(Message( + Glob::error, "Canonical path generation from path '" + + dir + "' failed! Reason: '" + realPathErrorMessage + "'")); + } + return false; + } + + if(kwsys_stl::find(this->VisitedSymlinks.begin(), + this->VisitedSymlinks.end(), + canonicalPath) == this->VisitedSymlinks.end()) + { + if(this->RecurseListDirs) + { + // symlinks are treated as directories + this->AddFile(this->Internals->Files, realname); + } + + this->VisitedSymlinks.push_back(canonicalPath); + if(!this->RecurseDirectory(start+1, realname, messages)) + { + this->VisitedSymlinks.pop_back(); + + return false; + } + this->VisitedSymlinks.pop_back(); + } + // else we have already visited this symlink - prevent cyclic recursion + else if(messages) + { + kwsys_stl::string message; + for(kwsys_stl::vector<kwsys_stl::string>::const_iterator + pathIt = kwsys_stl::find(this->VisitedSymlinks.begin(), + this->VisitedSymlinks.end(), + canonicalPath); + pathIt != this->VisitedSymlinks.end(); ++pathIt) + { + message += *pathIt + "\n"; + } + message += canonicalPath + "/" + fname; + messages->push_back(Message(Glob::cyclicRecursion, message)); + } + } + else + { + if(this->RecurseListDirs) + { + this->AddFile(this->Internals->Files, realname); + } + if(!this->RecurseDirectory(start+1, realname, messages)) + { + return false; + } } - this->RecurseDirectory(start+1, realname); } else { @@ -277,17 +333,19 @@ void Glob::RecurseDirectory(kwsys_stl::string::size_type start, } } } + + return true; } //---------------------------------------------------------------------------- void Glob::ProcessDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir) + const kwsys_stl::string& dir, GlobMessages* messages) { //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl; bool last = ( start == this->Internals->Expressions.size()-1 ); if ( last && this->Recurse ) { - this->RecurseDirectory(start, dir); + this->RecurseDirectory(start, dir, messages); return; } @@ -302,7 +360,6 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start, return; } unsigned long cc; - kwsys_stl::string fullname; kwsys_stl::string realname; kwsys_stl::string fname; for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ ) @@ -327,22 +384,14 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start, fname = kwsys::SystemTools::LowerCase(fname); #endif - if ( start == 0 ) - { - fullname = dir + fname; - } - else - { - fullname = dir + "/" + fname; - } - //kwsys_ios::cout << "Look at file: " << fname << kwsys_ios::endl; //kwsys_ios::cout << "Match: " // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl; - //kwsys_ios::cout << "Full name: " << fullname << kwsys_ios::endl; + //kwsys_ios::cout << "Real name: " << realname << kwsys_ios::endl; - if ( !last && - !kwsys::SystemTools::FileIsDirectory(realname) ) + if( (!last && !kwsys::SystemTools::FileIsDirectory(realname)) + || (!this->ListDirs && last && + kwsys::SystemTools::FileIsDirectory(realname)) ) { continue; } @@ -355,14 +404,14 @@ void Glob::ProcessDirectory(kwsys_stl::string::size_type start, } else { - this->ProcessDirectory(start+1, realname + "/"); + this->ProcessDirectory(start+1, realname, messages); } } } } //---------------------------------------------------------------------------- -bool Glob::FindFiles(const kwsys_stl::string& inexpr) +bool Glob::FindFiles(const kwsys_stl::string& inexpr, GlobMessages* messages) { kwsys_stl::string cexpr; kwsys_stl::string::size_type cc; @@ -458,11 +507,11 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr) // Handle network paths if ( skip > 0 ) { - this->ProcessDirectory(0, fexpr.substr(0, skip) + "/"); + this->ProcessDirectory(0, fexpr.substr(0, skip) + "/", messages); } else { - this->ProcessDirectory(0, "/"); + this->ProcessDirectory(0, "/", messages); } return true; } diff --git a/Source/kwsys/Glob.hxx.in b/Source/kwsys/Glob.hxx.in index d8b8491..39b7ce7 100644 --- a/Source/kwsys/Glob.hxx.in +++ b/Source/kwsys/Glob.hxx.in @@ -40,11 +40,36 @@ class GlobInternals; class @KWSYS_NAMESPACE@_EXPORT Glob { public: + enum MessageType + { + error, + cyclicRecursion + }; + + struct Message + { + MessageType type; + kwsys_stl::string content; + + Message(MessageType t, const kwsys_stl::string& c) : + type(t), + content(c) + {} + Message(const Message& msg) : + type(msg.type), + content(msg.content) + {} + }; + + typedef kwsys_stl::vector<Message> GlobMessages; + typedef kwsys_stl::vector<Message>::iterator GlobMessagesIterator; +public: Glob(); ~Glob(); //! Find all files that match the pattern. - bool FindFiles(const kwsys_stl::string& inexpr); + bool FindFiles(const kwsys_stl::string& inexpr, + GlobMessages* messages = 0); //! Return the list of files that matched. kwsys_stl::vector<kwsys_stl::string>& GetFiles(); @@ -80,15 +105,26 @@ public: bool require_whole_string = true, bool preserve_case = false); + /** Getters and setters for enabling and disabling directory + listing in recursive and non recursive globbing mode. + If listing is enabled in recursive mode it also lists + directory symbolic links even if follow symlinks is enabled. */ + void SetListDirs(bool list) { this->ListDirs=list; } + bool GetListDirs() const { return this->ListDirs; } + void SetRecurseListDirs(bool list) { this->RecurseListDirs=list; } + bool GetRecurseListDirs() const { return this->RecurseListDirs; } + protected: //! Process directory void ProcessDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir); + const kwsys_stl::string& dir, + GlobMessages* messages); //! Process last directory, but only when recurse flags is on. That is // effectively like saying: /path/to/file/**/file - void RecurseDirectory(kwsys_stl::string::size_type start, - const kwsys_stl::string& dir); + bool RecurseDirectory(kwsys_stl::string::size_type start, + const kwsys_stl::string& dir, + GlobMessages* messages); //! Add regular expression void AddExpression(const kwsys_stl::string& expr); @@ -101,6 +137,9 @@ protected: kwsys_stl::string Relative; bool RecurseThroughSymlinks; unsigned int FollowedSymlinkCount; + kwsys_stl::vector<kwsys_stl::string> VisitedSymlinks; + bool ListDirs; + bool RecurseListDirs; private: Glob(const Glob&); // Not implemented. diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 9c7ceee..b0434f4 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -1234,6 +1234,7 @@ void StacktraceSignalHandler( case ILL_ILLTRP: oss << "illegal trap"; + break; case ILL_PRVOPC: oss << "privileged opcode"; @@ -1823,6 +1824,7 @@ const char * SystemInformationImplementation::GetVendorID() return "Motorola"; case HP: return "Hewlett-Packard"; + case UnknownManufacturer: default: return "Unknown Manufacturer"; } @@ -3064,6 +3066,12 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity() case NSC: this->ChipID.ProcessorName = "Cx486SLC \\ DLC \\ Cx486S A-Step"; break; + + case Sun: + case IBM: + case Motorola: + case HP: + case UnknownManufacturer: default: this->ChipID.ProcessorName = "Unknown family"; // We cannot identify the processor. return false; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index b03e7b0..8a481d6 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -250,17 +250,46 @@ inline int Chdir(const kwsys_stl::string& dir) return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str()); #endif } -inline void Realpath(const kwsys_stl::string& path, kwsys_stl::string & resolved_path) +inline void Realpath(const kwsys_stl::string& path, + kwsys_stl::string& resolved_path, + kwsys_stl::string* errorMessage = 0) { kwsys_stl::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path); wchar_t *ptemp; wchar_t fullpath[MAX_PATH]; - if( GetFullPathNameW(tmp.c_str(), sizeof(fullpath)/sizeof(fullpath[0]), - fullpath, &ptemp) ) + DWORD bufferLen = GetFullPathNameW(tmp.c_str(), + sizeof(fullpath) / sizeof(fullpath[0]), + fullpath, &ptemp); + if( bufferLen < sizeof(fullpath)/sizeof(fullpath[0]) ) { resolved_path = KWSYS_NAMESPACE::Encoding::ToNarrow(fullpath); KWSYS_NAMESPACE::SystemTools::ConvertToUnixSlashes(resolved_path); } + else if(errorMessage) + { + if(bufferLen) + { + *errorMessage = "Destination path buffer size too small."; + } + else if(unsigned int errorId = GetLastError()) + { + LPSTR message = NULL; + DWORD size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorId, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&message, 0, NULL); + *errorMessage = std::string(message, size); + LocalFree(message); + } + else + { + *errorMessage = "Unknown error."; + } + + resolved_path = ""; + } else { resolved_path = path; @@ -287,15 +316,31 @@ inline int Chdir(const kwsys_stl::string& dir) { return chdir(dir.c_str()); } -inline void Realpath(const kwsys_stl::string& path, kwsys_stl::string & resolved_path) +inline void Realpath(const kwsys_stl::string& path, + kwsys_stl::string& resolved_path, + kwsys_stl::string* errorMessage = 0) { char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH]; + errno = 0; char *ret = realpath(path.c_str(), resolved_name); if(ret) { resolved_path = ret; } + else if(errorMessage) + { + if(errno) + { + *errorMessage = strerror(errno); + } + else + { + *errorMessage = "Unknown error."; + } + + resolved_path = ""; + } else { // if path resolution fails, return what was passed in @@ -3050,10 +3095,11 @@ kwsys_stl::string SystemTools return ""; } -kwsys_stl::string SystemTools::GetRealPath(const kwsys_stl::string& path) +kwsys_stl::string SystemTools::GetRealPath(const kwsys_stl::string& path, + kwsys_stl::string* errorMessage) { kwsys_stl::string ret; - Realpath(path, ret); + Realpath(path, ret, errorMessage); return ret; } diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index beb2a7e..93cde02 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -385,9 +385,12 @@ public: /** * Get the real path for a given path, removing all symlinks. In * the event of an error (non-existent path, permissions issue, - * etc.) the original path is returned. + * etc.) the original path is returned if errorMessage pointer is + * NULL. Otherwise empty string is returned and errorMessage + * contains error description. */ - static kwsys_stl::string GetRealPath(const kwsys_stl::string& path); + static kwsys_stl::string GetRealPath(const kwsys_stl::string& path, + kwsys_stl::string* errorMessage = 0); /** * Split a path name into its root component and the rest of the diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in index 307f6bc..7e7dc42 100644 --- a/Source/kwsys/hashtable.hxx.in +++ b/Source/kwsys/hashtable.hxx.in @@ -423,7 +423,7 @@ static const unsigned long _stl_prime_list[_stl_num_primes] = return &_stl_prime_list[0]; } -inline size_t _stl_next_prime(size_t __n) +static inline size_t _stl_next_prime(size_t __n) { const unsigned long* __first = get_stl_prime_list(); const unsigned long* __last = get_stl_prime_list() + (int)_stl_num_primes; diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx index b861a5b..ac5cf74 100644 --- a/Source/kwsys/testHashSTL.cxx +++ b/Source/kwsys/testHashSTL.cxx @@ -34,7 +34,7 @@ template class kwsys::hash_map<const char*, int>; template class kwsys::hash_set<int>; -bool test_hash_map() +static bool test_hash_map() { typedef kwsys::hash_map<const char*, int> mtype; mtype m; @@ -51,7 +51,7 @@ bool test_hash_map() return sum == 3; } -bool test_hash_set() +static bool test_hash_set() { typedef kwsys::hash_set<int> stype; stype s; diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt index 14d40aa..f96283d 100644 --- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -26,6 +26,21 @@ target_compile_definitions(consumer PRIVATE ) +if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_compile_definitions(consumer + PRIVATE + CONSUMER_LANG_$<COMPILE_LANGUAGE> + LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX> + LANG_IS_C=$<COMPILE_LANGUAGE:C> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + add_definitions(-DSOME_DEF) add_library(imp UNKNOWN IMPORTED) get_target_property(_res imp COMPILE_DEFINITIONS) diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.c b/Tests/CMakeCommands/target_compile_definitions/consumer.c new file mode 100644 index 0000000..5796d96 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.c @@ -0,0 +1,23 @@ + +#ifdef TEST_LANG_DEFINES + #ifdef CONSUMER_LANG_CXX + #error Unexpected CONSUMER_LANG_CXX + #endif + + #ifndef CONSUMER_LANG_C + #error Expected CONSUMER_LANG_C + #endif + + #if !LANG_IS_C + #error Expected LANG_IS_C + #endif + + #if LANG_IS_CXX + #error Unexpected LANG_IS_CXX + #endif +#endif + +void consumer_c() +{ + +} diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp index a391114..778f57e 100644 --- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp @@ -15,4 +15,22 @@ #error Expected DASH_D_DEFINE #endif +#ifdef TEST_LANG_DEFINES + #ifndef CONSUMER_LANG_CXX + #error Expected CONSUMER_LANG_CXX + #endif + + #ifdef CONSUMER_LANG_C + #error Unexpected CONSUMER_LANG_C + #endif + + #if !LANG_IS_CXX + #error Expected LANG_IS_CXX + #endif + + #if LANG_IS_C + #error Unexpected LANG_IS_C + #endif +#endif + int main() { return 0; } diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt index 1d04639..35dd276 100644 --- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt @@ -23,6 +23,21 @@ add_executable(consumer "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" ) +if (NOT CMAKE_GENERATOR MATCHES "Visual Studio") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_compile_options(consumer + PRIVATE + -DCONSUMER_LANG_$<COMPILE_LANGUAGE> + -DLANG_IS_CXX=$<COMPILE_LANGUAGE:CXX> + -DLANG_IS_C=$<COMPILE_LANGUAGE:C> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + target_compile_options(consumer PRIVATE $<$<CXX_COMPILER_ID:GNU>:$<TARGET_PROPERTY:target_compile_options,INTERFACE_COMPILE_OPTIONS>> ) diff --git a/Tests/CMakeCommands/target_compile_options/consumer.c b/Tests/CMakeCommands/target_compile_options/consumer.c new file mode 100644 index 0000000..5796d96 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_options/consumer.c @@ -0,0 +1,23 @@ + +#ifdef TEST_LANG_DEFINES + #ifdef CONSUMER_LANG_CXX + #error Unexpected CONSUMER_LANG_CXX + #endif + + #ifndef CONSUMER_LANG_C + #error Expected CONSUMER_LANG_C + #endif + + #if !LANG_IS_C + #error Expected LANG_IS_C + #endif + + #if LANG_IS_CXX + #error Unexpected LANG_IS_CXX + #endif +#endif + +void consumer_c() +{ + +} diff --git a/Tests/CMakeCommands/target_compile_options/consumer.cpp b/Tests/CMakeCommands/target_compile_options/consumer.cpp index 1299606..c5882a5 100644 --- a/Tests/CMakeCommands/target_compile_options/consumer.cpp +++ b/Tests/CMakeCommands/target_compile_options/consumer.cpp @@ -15,4 +15,22 @@ #endif +#ifdef TEST_LANG_DEFINES + #ifndef CONSUMER_LANG_CXX + #error Expected CONSUMER_LANG_CXX + #endif + + #ifdef CONSUMER_LANG_C + #error Unexpected CONSUMER_LANG_C + #endif + + #if !LANG_IS_CXX + #error Expected LANG_IS_CXX + #endif + + #if LANG_IS_C + #error Unexpected LANG_IS_C + #endif +#endif + int main() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt index 661bbaa..d57556a 100644 --- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -42,6 +42,20 @@ add_executable(consumer "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" ) +if (CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja") + target_sources(consumer PRIVATE + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.c" + ) + target_include_directories(consumer + PRIVATE + $<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_only> + $<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}/c_only> + ) + target_compile_definitions(consumer + PRIVATE -DTEST_LANG_DEFINES + ) +endif() + target_include_directories(consumer PRIVATE $<TARGET_PROPERTY:target_include_directories,INTERFACE_INCLUDE_DIRECTORIES> diff --git a/Tests/CMakeCommands/target_include_directories/c_only/c_only.h b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h new file mode 100644 index 0000000..29f68ee --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/c_only/c_only.h @@ -0,0 +1,2 @@ + +#define C_ONLY_DEFINE diff --git a/Tests/CMakeCommands/target_include_directories/consumer.c b/Tests/CMakeCommands/target_include_directories/consumer.c new file mode 100644 index 0000000..8821f5b --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/consumer.c @@ -0,0 +1,10 @@ + +#ifdef TEST_LANG_DEFINES + #include "c_only.h" + + #ifndef C_ONLY_DEFINE + #error Expected C_ONLY_DEFINE + #endif +#endif + +int consumer_c() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp index 7e3443e..649510c 100644 --- a/Tests/CMakeCommands/target_include_directories/consumer.cpp +++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp @@ -4,6 +4,9 @@ #include "interfaceinclude.h" #include "relative_dir.h" #include "consumer.h" +#ifdef TEST_LANG_DEFINES + #include "cxx_only.h" +#endif #ifdef PRIVATEINCLUDE_DEFINE #error Unexpected PRIVATEINCLUDE_DEFINE @@ -29,4 +32,10 @@ #error Expected CONSUMER_DEFINE #endif +#ifdef TEST_LANG_DEFINES + #ifndef CXX_ONLY_DEFINE + #error Expected CXX_ONLY_DEFINE + #endif +#endif + int main() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h new file mode 100644 index 0000000..67289a4 --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/cxx_only/cxx_only.h @@ -0,0 +1,2 @@ + +#define CXX_ONLY_DEFINE diff --git a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt index 818b8c9..741c73e 100644 --- a/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/cmp0022/CMakeLists.txt @@ -22,8 +22,18 @@ generate_export_header(staticlib1) add_library(staticlib2 STATIC staticlib2.cpp) generate_export_header(staticlib2) target_link_libraries(staticlib1 LINK_PUBLIC staticlib2) + +# Try adding a private link item to be propagated out of a static lib. +set(private_link "") if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang) - target_link_libraries(staticlib1 LINK_PRIVATE "-Wl,-v") + if (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(private_link "-Wl,-V") + else() + set(private_link "-Wl,-v") + endif() +endif() +if(private_link) + target_link_libraries(staticlib1 LINK_PRIVATE "${private_link}") endif() add_executable(staticlib_exe staticlib_exe.cpp) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7e7aa2e..5944d08 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -102,6 +102,17 @@ if(BUILD_TESTING) list(APPEND build_options -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}) endif() + # Look for rpmbuild to use for tests. + # The tool does not work with spaces in the path. + if(NOT CMAKE_CURRENT_BINARY_DIR MATCHES " ") + find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild) + else() + set(RPMBUILD_EXECUTABLE "RPMBUILD_EXECUTABLE-NOTFOUND") + endif() + + #--------------------------------------------------------------------------- + # Add tests below here. + if(NOT CMake_TEST_EXTERNAL_CMAKE) add_subdirectory(CMakeLib) endif() @@ -161,6 +172,7 @@ if(BUILD_TESTING) ON) mark_as_advanced(CTEST_TEST_CPACK) set(CTEST_TEST_OSX_ARCH 0) + set(CMake_TEST_XCODE_VERSION 0) if(APPLE) execute_process( COMMAND sw_vers -productVersion @@ -174,6 +186,17 @@ if(BUILD_TESTING) else() set(CTEST_TEST_OSX_ARCH 1) endif() + if(XCODE_VERSION) + set(CMake_TEST_XCODE_VERSION "${XCODE_VERSION}") + else() + execute_process( + COMMAND xcodebuild -version + OUTPUT_VARIABLE _version ERROR_VARIABLE _version + ) + if(_version MATCHES "^Xcode ([0-9]+(\\.[0-9]+)*)") + set(CMake_TEST_XCODE_VERSION "${CMAKE_MATCH_1}") + endif() + endif() endif() # Use 1500 or CTEST_TEST_TIMEOUT for long test timeout value, @@ -549,7 +572,21 @@ if(BUILD_TESTING) --test-command Simple) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_KDevelop3Generator") endif () - + # check for the Qbs generator + if ("${cmakeOutput}" MATCHES Qbs) + add_test(Simple_QbsGenerator ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Simple" + "${CMake_BINARY_DIR}/Tests/Simple_QbsGenerator" + --build-two-config + --build-generator "Qbs - Unix Makefiles" + --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}" + --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}" + --build-project Simple + --build-options ${build_options} + --test-command Simple) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_QbsGenerator") + endif () endif() # test for correct sub-project generation @@ -825,12 +862,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set(CTEST_RUN_CPackComponents ${CTEST_TEST_CPACK}) set(CTEST_package_X11_TEST ${CTEST_TEST_CPACK}) set(CTEST_RUN_CPackComponentsForAll ${CTEST_TEST_CPACK}) + set(CTEST_RUN_CPackComponentsPrefix ${CTEST_TEST_CPACK}) - if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT CMAKE_CURRENT_BINARY_DIR MATCHES " ") - find_program(RPMBUILD NAMES rpmbuild) - endif() # Do not try to build RPM - if (NOT RPMBUILD) + if (NOT RPMBUILD_EXECUTABLE) set(CPACK_BINARY_RPM OFF) endif() @@ -912,7 +947,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release if(CTEST_RUN_CPackComponentsForAll) # Check whether if rpmbuild command is found # before adding RPM tests - find_program(RPMBUILD_EXECUTABLE NAMES rpmbuild) if(RPMBUILD_EXECUTABLE) list(APPEND ACTIVE_CPACK_GENERATORS RPM) endif() @@ -931,11 +965,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release if(APPLE) list(APPEND GENLST "DragNDrop") endif() - if (NOT CMAKE_CURRENT_BINARY_DIR MATCHES " ") - list(FIND ACTIVE_CPACK_GENERATORS "RPM" RPM_ACTIVE) - if (NOT ${RPM_ACTIVE} EQUAL -1) - list(APPEND GENLST "RPM") - endif() + list(FIND ACTIVE_CPACK_GENERATORS "RPM" RPM_ACTIVE) + if (NOT ${RPM_ACTIVE} EQUAL -1) + list(APPEND GENLST "RPM") endif() list(FIND ACTIVE_CPACK_GENERATORS "DEB" DEB_ACTIVE) if (NOT ${DEB_ACTIVE} EQUAL -1) @@ -959,6 +991,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ${build_generator_args} --build-project CPackComponentsForAll --build-options ${build_options} + -DCPACK_GENERATOR:STRING=${CPackGen} -DCPACK_BINARY_${CPackGen}:BOOL=ON ${CPackRun_CPackComponentWay} ${CPackComponentsForAll_BUILD_OPTIONS} @@ -1004,6 +1037,33 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators") endif() + if(CTEST_RUN_CPackComponentsPrefix) + set(CPackComponents_BUILD_OPTIONS) + if(APPLE) + set(CPackComponents_BUILD_OPTIONS -DCPACK_BINARY_DRAGNDROP:BOOL=ON) + endif() + if(NOT NSIS_MAKENSIS_EXECUTABLE) + set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS} + -DCPACK_BINARY_NSIS:BOOL=OFF) + endif() + + add_test(CPackComponentsPrefix ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CPackComponentsPrefix" + "${CMake_BINARY_DIR}/Tests/CPackComponentsPrefix" + ${build_generator_args} + --build-project CPackComponentsPrefix + --build-two-config + --build-target package + --build-options ${build_options} + -DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB} + -DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM} + -DCPACK_BINARY_ZIP:BOOL=ON + ${CPackComponents_BUILD_OPTIONS} + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackComponentsPrefix") + endif() + if(CTEST_package_X11_TEST) set(X11_build_target_arg --build-target package) else() @@ -1251,6 +1311,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindJsonCpp) endif() + # Matlab module + if(CMake_TEST_FindMatlab) + ADD_TEST_MACRO(FindMatlab.basic_checks ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>) + ADD_TEST_MACRO(FindMatlab.versions_checks ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>) + endif() + find_package(GTK2 QUIET) if(GTK2_FOUND) add_subdirectory(FindGTK2) @@ -1482,6 +1548,12 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ) endif() + if(CMake_TEST_XCODE_VERSION AND NOT CMake_TEST_XCODE_VERSION VERSION_LESS 5 + AND OSX_VERSION MATCHES "^([0-9]+\\.[0-9]+)") + set(XCTest_BUILD_OPTIONS -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_MATCH_1}) + ADD_TEST_MACRO(XCTest ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> -V) + endif() + add_test(linkorder1 ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/LinkLineOrder" @@ -2404,6 +2476,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release "${CMake_BINARY_DIR}/Testing/JacocoCoverage/DartConfiguration.tcl") file(COPY "${CMake_SOURCE_DIR}/Tests/JacocoCoverage/Coverage" DESTINATION "${CMake_BINARY_DIR}/Testing/JacocoCoverage") + configure_file("${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml.in" + "${CMake_BINARY_DIR}/Testing/JacocoCoverage/Coverage/target/site/jacoco.xml") add_test(NAME CTestJacocoCoverage COMMAND cmake -E chdir ${CMake_BINARY_DIR}/Testing/JacocoCoverage @@ -2554,6 +2628,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release --output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log" ) + configure_file("${CMake_SOURCE_DIR}/Tests/CTestTestVerboseOutput/test.cmake.in" + "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/test.cmake" @ONLY ESCAPE_QUOTES) + add_test(CTestTestVerboseOutput ${CMAKE_CTEST_COMMAND} + -S "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/test.cmake" -VV + --output-log "${CMake_BINARY_DIR}/Tests/CTestTestVerboseOutput/testOutput.log" + -C "\${CTestTest_CONFIG}" + ) + set_property(TEST CTestTestVerboseOutput PROPERTY PASS_REGULAR_EXPRESSION + "Environment variables:.*foo=bar.*this=that" + ) + configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestSkipReturnCode/test.cmake.in" "${CMake_BINARY_DIR}/Tests/CTestTestSkipReturnCode/test.cmake" @@ -2738,48 +2823,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release --output-log "${CMake_BINARY_DIR}/Tests/CTestTestFdSetSize/testOutput.log" ) - function(add_failed_submit_test name source build in out log regex) - configure_file("${in}" "${out}" @ONLY) - add_test(${name} ${CMAKE_CTEST_COMMAND} -S "${out}" -V --output-log "${log}") - set_tests_properties(${name} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}") - endfunction() - - set(regex "(Problems when submitting via S*CP") - set(regex "${regex}|Error message was: ") - set(regex "${regex}([Cc]ould *n.t resolve host") - set(regex "${regex}|[Cc]ould *n.t connect to host") - set(regex "${regex}|Failed *t*o* connect to") - set(regex "${regex}|Connection timed out after [0-9]+ milliseconds") - set(regex "${regex}|Empty reply from server") - set(regex "${regex}|The requested URL returned error") - set(regex "${regex}|libcurl was built with SSL disabled. https: not supported)") - set(regex "${regex}|Submission method .xmlrpc. not compiled into CTest") - set(regex "${regex}|Submission problem") - set(regex "${regex}|Submission successful)") - - set(ctest_coverage_labels_args "") - - foreach(drop_method cp ftp http https scp xmlrpc) - # Cycle through these values each time through the loop: - if(ctest_coverage_labels_args STREQUAL "") - set(ctest_coverage_labels_args "LABELS Everything") - elseif(ctest_coverage_labels_args STREQUAL "LABELS Everything") - set(ctest_coverage_labels_args "LABELS 0ArgTest") - else() - set(ctest_coverage_labels_args "") - endif() - - add_failed_submit_test(CTestTestFailedSubmit-${drop_method} - "${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast" - "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/${drop_method}" - "${CMake_SOURCE_DIR}/Tests/CTestTestFailedSubmits/test.cmake.in" - "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/test-${drop_method}.cmake" - "${CMake_BINARY_DIR}/Tests/CTestTestFailedSubmits/test-${drop_method}.log" - "${regex}" - ) - endforeach() - - if (CMAKE_TESTS_CDASH_SERVER) set(regex "^([^:]+)://([^/]+)(.*)$") diff --git a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt index 3a2bdeb..02e4668 100644 --- a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt +++ b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt @@ -4,19 +4,11 @@ project(CompilerIdFortran Fortran) foreach(v CMAKE_Fortran_COMPILER CMAKE_Fortran_COMPILER_ID - ) - if(${v}) - message(STATUS "${v}=[${${v}}]") - else() - message(SEND_ERROR "${v} not set!") - endif() -endforeach() -foreach(v CMAKE_Fortran_COMPILER_VERSION ) if(${v}) message(STATUS "${v}=[${${v}}]") else() - message(WARNING "${v} not set!") + message(SEND_ERROR "${v} not set!") endif() endforeach() diff --git a/Tests/CMakeTests/ELFTest.cmake.in b/Tests/CMakeTests/ELFTest.cmake.in index 0271abb..4635778 100644 --- a/Tests/CMakeTests/ELFTest.cmake.in +++ b/Tests/CMakeTests/ELFTest.cmake.in @@ -11,7 +11,7 @@ set(out "@CMAKE_CURRENT_BINARY_DIR@/ELF-Out") file(REMOVE_RECURSE "${out}") file(MAKE_DIRECTORY "${out}") foreach(f ${names}) - file(COPY ${in}/${f} DESTINATION ${out}) + file(COPY ${in}/${f} DESTINATION ${out} NO_SOURCE_PERMISSIONS) list(APPEND files "${out}/${f}") endforeach() diff --git a/Tests/CPackComponentsForAll/CMakeLists.txt b/Tests/CPackComponentsForAll/CMakeLists.txt index b55594e..1cc34b0 100644 --- a/Tests/CPackComponentsForAll/CMakeLists.txt +++ b/Tests/CPackComponentsForAll/CMakeLists.txt @@ -43,12 +43,50 @@ install(TARGETS mylibapp # CPACK_MONOLITHIC_INSTALL=1 is set (at cmake time). install(TARGETS mylibapp2 RUNTIME - DESTINATION bin) + DESTINATION bin/@in@_@path@@with\\@and\\@/\@in_path\@) # test @ char in path install(FILES mylib.h DESTINATION include COMPONENT headers) +if("${CPACK_GENERATOR}" MATCHES "RPM") + # Package symbolic links + install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries) + install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable/bar COMPONENT libraries) + install(DIRECTORY DESTINATION other_relocatable/depth_two COMPONENT libraries) + install(DIRECTORY DESTINATION non_relocatable/depth_two COMPONENT libraries) + # test symbolic links to same dir + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink depth_three symlink_samedir_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) + # test symbolic links to same dir with current dir ./ prefix + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./depth_three symlink_samedir_path_current_dir) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_current_dir DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) + # test symbolic links to same dir with longer relative path + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../${CMAKE_INSTALL_LIBDIR}/.././${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two/depth_three symlink_samedir_path_longer) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_longer DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) + # test symbolic links to sub dir + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three symlink_subdir_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_subdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one COMPONENT libraries) + # test symbolic links to parent dir + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two symlink_parentdir_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_parentdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries) + # test symbolic link to another relocatable path + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././.././../other_relocatable/./depth_two symlink_other_relocatable_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_other_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries) + # test symbolic link to non relocatable path + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../non_relocatable/./depth_two symlink_to_non_relocatable_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_to_non_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries) + # test symbolic link from non relocatable path + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two symlink_from_non_relocatable_path) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_from_non_relocatable_path DESTINATION non_relocatable/depth_two COMPONENT libraries) + # test symbolic link relocatable path to its relocatable subpath + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../inside_relocatable_two/depth_two/different_relocatable/bar symlink_relocatable_subpath) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_relocatable_subpath DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) + # test symbolic link to location outside package + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./outside_package symlink_outside_package) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_outside_package DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) +endif() + # CPack boilerplate for this project set(CPACK_PACKAGE_NAME "MyLib") set(CPACK_PACKAGE_CONTACT "None") @@ -114,7 +152,8 @@ set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full) # can not be used in CPack scripts due to CMAKE_SIZEOF_VOID_P # variable not being set set(CPACK_RPM_RELOCATION_PATHS "${CMAKE_INSTALL_INCLUDEDIR}" - "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_BINDIR}") + "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_BINDIR}" "other_relocatable" + "${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable") # We may use the CPack specific config file in order # to tailor CPack behavior on a CPack generator specific way diff --git a/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in index e20f11a..ac9b552 100644 --- a/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in +++ b/Tests/CPackComponentsForAll/MyLibCPackConfig-IgnoreGroup.cmake.in @@ -16,12 +16,22 @@ if(CPACK_GENERATOR MATCHES "RPM") # test requires set(CPACK_RPM_applications_PACKAGE_REQUIRES "mylib-libraries") - # test package summary override + # test a "noarch" rpm + set(CPACK_RPM_headers_PACKAGE_ARCHITECTURE "noarch") + + # test cross-built rpm + set(CPACK_RPM_applications_PACKAGE_ARCHITECTURE "armv7hf") + + # test package summary override - headers rpm is generated in the middle set(CPACK_RPM_PACKAGE_SUMMARY "default summary") - set(CPACK_RPM_libraries_PACKAGE_SUMMARY "libraries summary") + set(CPACK_RPM_headers_PACKAGE_SUMMARY "headers summary") + + # test package description override - headers rpm is generated in the middle + set(CPACK_RPM_headers_PACKAGE_DESCRIPTION "headers description") - # test package description override - set(CPACK_RPM_libraries_PACKAGE_DESCRIPTION "libraries description") + # test package do not use CPACK_PACKAGING_INSTALL_PREFIX + # as relocation path + set(CPACK_RPM_NO_libraries_INSTALL_PREFIX_RELOCATION true) endif() if(CPACK_GENERATOR MATCHES "DEB") diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index 69af374..e747052 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -1,3 +1,7 @@ +# prevent older policies from interfearing with this script +cmake_policy(PUSH) +cmake_policy(VERSION ${CMAKE_VERSION}) + message(STATUS "=============================================================================") message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") message(STATUS "") @@ -132,13 +136,15 @@ if(CPackGen MATCHES "RPM") endif() set(CPACK_RPM_PACKAGE_SUMMARY "default summary") - set(CPACK_RPM_libraries_PACKAGE_SUMMARY "libraries summary") - set(CPACK_RPM_libraries_PACKAGE_DESCRIPTION "libraries description") + set(CPACK_RPM_headers_PACKAGE_SUMMARY "headers summary") + set(CPACK_RPM_headers_PACKAGE_DESCRIPTION "headers description") set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION "An extremely useful application that makes use of MyLib") - set(CPACK_COMPONENT_HEADERS_DESCRIPTION - "C/C\\+\\+ header files for use with MyLib") + set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION + "Static libraries used to build programs with MyLib") + set(LIB_SUFFIX "6?4?") + # test package info if(${CPackComponentWay} STREQUAL "IgnoreGroup") # set gnu install prefixes to what they are set during rpm creation # CMAKE_SIZEOF_VOID_P is not set here but lib is prefix of lib64 so @@ -157,37 +163,77 @@ if(CPackGen MATCHES "RPM") ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${RPM_EXECUTABLE} -pqa ${check_file} + RESULT_VARIABLE check_package_architecture_result + OUTPUT_VARIABLE check_package_architecture + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${RPM_EXECUTABLE} -pql ${check_file} OUTPUT_VARIABLE check_package_content ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + set(whitespaces "[\\t\\n\\r ]*") + if(check_file_libraries_match) - set(check_file_match_expected_summary ".*${CPACK_RPM_libraries_PACKAGE_SUMMARY}.*") - set(check_file_match_expected_description ".*${CPACK_RPM_libraries_PACKAGE_DESCRIPTION}.*") - set(check_file_match_expected_relocation_path "Relocations : ${CPACK_PACKAGING_INSTALL_PREFIX} ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") + set(check_file_match_expected_description ".*${CPACK_COMPONENT_LIBRARIES_DESCRIPTION}.*") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/other_relocatable${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable") + set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it set(spec_regex "*libraries*") - set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/lib.*\n/usr/foo/bar/lib.*/libmylib.a$") + set(check_content_list "^/usr/foo/bar/lib${LIB_SUFFIX} +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three/symlink_parentdir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_outside_package +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_relocatable_subpath +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_current_dir +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_longer +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/symlink_subdir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable/bar +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_other_relocatable_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_to_non_relocatable_path +/usr/foo/bar/lib${LIB_SUFFIX}/libmylib.a +/usr/foo/bar/non_relocatable +/usr/foo/bar/non_relocatable/depth_two +/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path +/usr/foo/bar/other_relocatable +/usr/foo/bar/other_relocatable/depth_two$") elseif(check_file_headers_match) - set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") - set(check_file_match_expected_description ".*${CPACK_COMPONENT_HEADERS_DESCRIPTION}.*") - set(check_file_match_expected_relocation_path "Relocations : ${CPACK_PACKAGING_INSTALL_PREFIX} ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") + set(check_file_match_expected_summary ".*${CPACK_RPM_headers_PACKAGE_SUMMARY}.*") + set(check_file_match_expected_description ".*${CPACK_RPM_headers_PACKAGE_DESCRIPTION}.*") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") + set(check_file_match_expected_architecture "noarch") set(spec_regex "*headers*") set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/include\n/usr/foo/bar/include/mylib.h$") elseif(check_file_applications_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_COMPONENT_APPLICATIONS_DESCRIPTION}.*") - set(check_file_match_expected_relocation_path "Relocations : ${CPACK_PACKAGING_INSTALL_PREFIX} ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") + set(check_file_match_expected_architecture "armv7hf") set(spec_regex "*applications*") - set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/bin\n/usr/foo/bar/bin/mylibapp$") + set(check_content_list "^/usr/foo/bar +/usr/foo/bar/bin +/usr/foo/bar/bin/mylibapp$") elseif(check_file_Unspecified_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*DESCRIPTION.*") - set(check_file_match_expected_relocation_path "Relocations : ${CPACK_PACKAGING_INSTALL_PREFIX} ${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") + set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it set(spec_regex "*Unspecified*") set(check_content_list "^/usr/foo/bar /usr/foo/bar/bin -/usr/foo/bar/bin/mylibapp2$") +/usr/foo/bar/bin/@in@_@path@@with +/usr/foo/bar/bin/@in@_@path@@with/@and +/usr/foo/bar/bin/@in@_@path@@with/@and/@ +/usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@ +/usr/foo/bar/bin/@in@_@path@@with/@and/@/@in_path@/mylibapp2$") else() message(FATAL_ERROR "error: unexpected rpm package '${check_file}'") endif() @@ -220,6 +266,24 @@ if(CPackGen MATCHES "RPM") endif() ####################### + # test package architecture + ####################### + string(REGEX MATCH "Architecture${whitespaces}:" check_info_contains_arch ${check_file_content}) + if(check_info_contains_arch) # test for rpm versions that contain architecture in package info (e.g. 4.11.x) + string(REGEX MATCH "Architecture${whitespaces}:${whitespaces}${check_file_match_expected_architecture}" check_file_match_architecture ${check_file_content}) + if(NOT check_file_match_architecture) + message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_file_content}'; generated spec file: '${spec_file_content}'") + endif() + elseif(NOT check_package_architecture_result) # test result only on platforms that support -pqa rpm query + # test for rpm versions that do not contain architecture in package info (e.g. 4.8.x) + string(REGEX MATCH ".*${check_file_match_expected_architecture}" check_file_match_architecture "${check_package_architecture}") + if(NOT check_file_match_architecture) + message(FATAL_ERROR "error: '${check_file}' Architecture does not match expected value - '${check_file_match_expected_architecture}'; RPM output: '${check_package_architecture}'; generated spec file: '${spec_file_content}'") + endif() + # else rpm version too old (e.g. 4.4.x) - skip test + endif() + + ####################### # test package content ####################### string(REGEX MATCH "${check_content_list}" expected_content_list "${check_package_content}") @@ -234,6 +298,59 @@ if(CPackGen MATCHES "RPM") message(FATAL_ERROR "error: '${check_file}' rpm package content does not match expected value - regex '${check_content_list}'; RPM output: '${check_package_content}'; generated spec file: '${spec_file_content}'") endif() endforeach() - elseif(${CPackComponentWay} STREQUAL "IgnoreGroup") + + ####################### + # verify generated symbolic links + ####################### + file(GLOB_RECURSE symlink_files RELATIVE "${CPackComponentsForAll_BINARY_DIR}" "${CPackComponentsForAll_BINARY_DIR}/*/symlink_*") + + foreach(check_symlink IN LISTS symlink_files) + get_filename_component(symlink_name "${check_symlink}" NAME) + execute_process(COMMAND ls -la "${check_symlink}" + WORKING_DIRECTORY "${CPackComponentsForAll_BINARY_DIR}" + OUTPUT_VARIABLE SYMLINK_POINT_ + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if("${symlink_name}" STREQUAL "symlink_samedir_path" + OR "${symlink_name}" STREQUAL "symlink_samedir_path_current_dir" + OR "${symlink_name}" STREQUAL "symlink_samedir_path_longer") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_three$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_subdir_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_two/depth_three$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_parentdir_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}../$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_to_non_relocatable_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/non_relocatable/depth_two$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_outside_package") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}outside_package$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_other_relocatable_path" + OR "${symlink_name}" STREQUAL "symlink_from_non_relocatable_path" + OR "${symlink_name}" STREQUAL "symlink_relocatable_subpath") + # these links were not canged - post install script only - ignore them + else() + message(FATAL_ERROR "error: unexpected rpm symbolic link '${check_symlink}'") + endif() + + if(NOT check_symlink) + message(FATAL_ERROR "symlink points to unexpected location '${SYMLINK_POINT_}'") + endif() + endforeach() + + # verify post install symlink relocation script + file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/*libraries*.spec") + file(READ ${spec_file} spec_file_content) + file(READ "${CMAKE_CURRENT_LIST_DIR}/symlink_postinstall_expected.txt" symlink_postinstall_expected) + # prepare regex + string(STRIP "${symlink_postinstall_expected}" symlink_postinstall_expected) + string(REPLACE "[" "\\[" symlink_postinstall_expected "${symlink_postinstall_expected}") + string(REPLACE "$" "\\$" symlink_postinstall_expected "${symlink_postinstall_expected}") + string(REPLACE "lib" "lib${LIB_SUFFIX}" symlink_postinstall_expected "${symlink_postinstall_expected}") + # compare + string(REGEX MATCH ".*${symlink_postinstall_expected}.*" symlink_postinstall_expected_matches "${spec_file_content}") + if(NOT symlink_postinstall_expected_matches) + message(FATAL_ERROR "error: unexpected rpm symbolic link postinstall script! generated spec file: '${spec_file_content}'") + endif() endif() endif() + +cmake_policy(POP) diff --git a/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt new file mode 100644 index 0000000..ba46792 --- /dev/null +++ b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt @@ -0,0 +1,57 @@ +if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then + if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "$RPM_INSTALL_PREFIX1/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi + fi + if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX2/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "/usr/foo/bar/other_relocatable/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi +fi +if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "$RPM_INSTALL_PREFIX1/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi +fi +if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX2/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi +fi +if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_2=true + fi +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "/usr/foo/bar/other_relocatable/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path" +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path" +fi diff --git a/Tests/CPackComponentsPrefix/CMakeLists.txt b/Tests/CPackComponentsPrefix/CMakeLists.txt new file mode 100644 index 0000000..207dae8 --- /dev/null +++ b/Tests/CPackComponentsPrefix/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.2) +project(CPackComponentsPrefix NONE) + +install(FILES file-runtime.txt + DESTINATION bin COMPONENT Runtime) +install(FILES file-development.txt + DESTINATION lib COMPONENT Development) + +set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 1) +set(CPACK_COMPONENTS_ALL Development) +set(CPACK_ARCHIVE_COMPONENT_INSTALL 1) +set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/My-1.0") +include(CPack) diff --git a/Tests/CPackComponentsPrefix/file-development.txt b/Tests/CPackComponentsPrefix/file-development.txt new file mode 100644 index 0000000..df22d2f --- /dev/null +++ b/Tests/CPackComponentsPrefix/file-development.txt @@ -0,0 +1 @@ +This file is installed with the Development component. diff --git a/Tests/CPackComponentsPrefix/file-runtime.txt b/Tests/CPackComponentsPrefix/file-runtime.txt new file mode 100644 index 0000000..135c13d --- /dev/null +++ b/Tests/CPackComponentsPrefix/file-runtime.txt @@ -0,0 +1 @@ +This file is installed with the Runtime component. diff --git a/Tests/CTestTestFailedSubmits/test.cmake.in b/Tests/CTestTestFailedSubmits/test.cmake.in deleted file mode 100644 index 5ff836f..0000000 --- a/Tests/CTestTestFailedSubmits/test.cmake.in +++ /dev/null @@ -1,49 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -# CTestConfig.cmake settings: -set(CTEST_PROJECT_NAME "SmallAndFast") - -# Intentionally leave out other upload-related CTestConfig.cmake settings -# so that the ctest_submit call below fails with an error message... -# -set(CTEST_DROP_METHOD "@drop_method@") - -# Settings: -set(CTEST_USE_LAUNCHERS 1) - -# Emit these compiler warnings: -set(ENV{CXXFLAGS} "$ENV{CXXFLAGS} -Wall") - -set(CTEST_SITE "@SITE@") -set(CTEST_BUILD_NAME "CTestTestLaunchers-@drop_method@") - -set(CTEST_SOURCE_DIRECTORY "@source@") -set(CTEST_BINARY_DIRECTORY "@build@") -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_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}") -set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@") -set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") - -CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY}) - -CTEST_START(Experimental) - -# explicitly do not use CTEST_UPDATE - avoid network activity - -CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" - OPTIONS "-DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS};-DSAF_INTENTIONAL_COMPILE_ERROR:BOOL=ON;-DSAF_INTENTIONAL_COMPILE_WARNING:BOOL=ON" - RETURN_VALUE res) -CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) -CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) -CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" @ctest_coverage_labels_args@ RETURN_VALUE res) - -# ok to call ctest_submit - still avoids network activity because there is -# not a valid drop location given above... -CTEST_SUBMIT(RETURN_VALUE res) - -# Add coverage for the new APPEND arg to ctest_start: -# -CTEST_START(Experimental APPEND) diff --git a/Tests/CTestTestVerboseOutput/CMakeLists.txt b/Tests/CTestTestVerboseOutput/CMakeLists.txt new file mode 100644 index 0000000..4cdd29c --- /dev/null +++ b/Tests/CTestTestVerboseOutput/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required (VERSION 2.6) +project(CTestTestVerboseOutput) +include(CTest) + +add_executable(nop nop.c) + +add_test(NAME TestWithProperties COMMAND nop) +set_property(TEST TestWithProperties PROPERTY ENVIRONMENT + "foo=bar" + "this=that" +) diff --git a/Tests/CTestTestVerboseOutput/CTestConfig.cmake b/Tests/CTestTestVerboseOutput/CTestConfig.cmake new file mode 100644 index 0000000..4f96c79 --- /dev/null +++ b/Tests/CTestTestVerboseOutput/CTestConfig.cmake @@ -0,0 +1,7 @@ +set(CTEST_PROJECT_NAME "CTestTestVerboseOutput") +set(CTEST_NIGHTLY_START_TIME "21:00:00 EDT") +set(CTEST_DART_SERVER_VERSION "2") +set(CTEST_DROP_METHOD "http") +set(CTEST_DROP_SITE "open.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=PublicDashboard") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/Tests/CTestTestVerboseOutput/nop.c b/Tests/CTestTestVerboseOutput/nop.c new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/CTestTestVerboseOutput/nop.c @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/CTestTestVerboseOutput/test.cmake.in b/Tests/CTestTestVerboseOutput/test.cmake.in new file mode 100644 index 0000000..7f49548 --- /dev/null +++ b/Tests/CTestTestVerboseOutput/test.cmake.in @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.4) + +# Settings: +set(CTEST_DASHBOARD_ROOT "@CMake_BINARY_DIR@/Tests/CTestTest") +set(CTEST_SITE "@SITE@") +set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-VerboseOutput") + +set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTestVerboseOutput") +set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestTestVerboseOutput") +set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") +set(CTEST_CMAKE_GENERATOR_PLATFORM "@CMAKE_GENERATOR_PLATFORM@") +set(CTEST_CMAKE_GENERATOR_TOOLSET "@CMAKE_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}") + +CTEST_START(Experimental) +CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}") +CTEST_BUILD(BUILD "${CTEST_BINARY_DIRECTORY}") +CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}") diff --git a/Tests/CTestUpdateCommon.cmake b/Tests/CTestUpdateCommon.cmake index 97153f0..77b3398 100644 --- a/Tests/CTestUpdateCommon.cmake +++ b/Tests/CTestUpdateCommon.cmake @@ -13,6 +13,9 @@ function(run_child) message(FATAL_ERROR "Child failed (${FAILED}), output is\n ${OUTPUT}\n" "Command = [${ARGN}]\n") endif() + + # Pass output back up to the parent scope for possible further inspection. + set(OUTPUT "${OUTPUT}" PARENT_SCOPE) endfunction() #----------------------------------------------------------------------------- @@ -269,6 +272,9 @@ function(run_dashboard_script bin_dir) Updated{subdir/bar.txt} ) endif() + + # Pass console output up to the parent, in case they'd like to inspect it. + set(OUTPUT "${OUTPUT}" PARENT_SCOPE) endfunction() #----------------------------------------------------------------------------- diff --git a/Tests/CTestUpdateGIT.cmake.in b/Tests/CTestUpdateGIT.cmake.in index 41b732b..5987a30 100644 --- a/Tests/CTestUpdateGIT.cmake.in +++ b/Tests/CTestUpdateGIT.cmake.in @@ -334,3 +334,36 @@ set(CTEST_UPDATE_VERSION_ONLY TRUE) # Run the dashboard script with CTest. set(NO_UPDATE 1) run_dashboard_script(dash-binary-no-update) + +rewind_source(dash-source) + +#----------------------------------------------------------------------------- +# Test ctest_update(QUIET) +set(NO_UPDATE 0) +message("Running CTest Dashboard Script (update quietly)...") + +create_dashboard_script(dash-binary-quiet + "# git command configuration +set(CTEST_GIT_COMMAND \"${GIT}\") +set(CTEST_GIT_UPDATE_OPTIONS) +set(CTEST_GIT_UPDATE_CUSTOM \${CTEST_GIT_COMMAND} pull origin master) +") + +# We need to modify the created dashboard script to include our "QUIET" +# option. +set(filename "${TOP}/dash-binary-quiet.cmake") +file(READ "${filename}" contents) +string(REPLACE + [=[ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY})]=] + [=[ctest_update(SOURCE ${CTEST_SOURCE_DIRECTORY} QUIET)]=] + contents + "${contents}") +file(WRITE "${filename}" "${contents}") + +# Run the dashboard script with CTest. +run_dashboard_script(dash-binary-quiet) + +# Make sure the output seems quiet. +if("${OUTPUT}" MATCHES "Updating the repository") + message(FATAL_ERROR "Found 'Updating the repository' in quiet output") +endif() diff --git a/Tests/CustomCommandByproducts/CMakeLists.txt b/Tests/CustomCommandByproducts/CMakeLists.txt index 884f8c2..3289e8f 100644 --- a/Tests/CustomCommandByproducts/CMakeLists.txt +++ b/Tests/CustomCommandByproducts/CMakeLists.txt @@ -102,6 +102,27 @@ add_library(ExternalLibrary STATIC IMPORTED) set_property(TARGET ExternalLibrary PROPERTY IMPORTED_LOCATION ${ExternalLibrary_LIBRARY}) add_dependencies(ExternalLibrary ExternalTarget) +# Generate the library file of an imported target as a byproduct +# of an external project. The byproduct uses <BINARY_DIR> that is substituted +# by the real binary path +if(CMAKE_CONFIGURATION_TYPES) + set(cfg /${CMAKE_CFG_INTDIR}) +else() + set(cfg) +endif() +include(ExternalProject) +ExternalProject_Add(ExtTargetSubst + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/External" + DOWNLOAD_COMMAND "" + INSTALL_COMMAND "" + BUILD_BYPRODUCTS "<BINARY_DIR>${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}" + ) +ExternalProject_Get_Property(ExtTargetSubst binary_dir) +add_library(ExternalLibraryWithSubstitution STATIC IMPORTED) +set_property(TARGET ExternalLibraryWithSubstitution PROPERTY IMPORTED_LOCATION + ${binary_dir}${cfg}/${CMAKE_STATIC_LIBRARY_PREFIX}ExternalLibrary${CMAKE_STATIC_LIBRARY_SUFFIX}) +add_dependencies(ExternalLibraryWithSubstitution ExtTargetSubst) + # Add an executable consuming all the byproducts. add_executable(CustomCommandByproducts CustomCommandByproducts.c diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index e130eca..0df42d9 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -68,6 +68,11 @@ add_library(testLib5 SHARED testLib5.c) add_library(testLib6 STATIC testLib6.cxx testLib6c.c) +add_library(testLibPerConfigDest STATIC testLibPerConfigDest.c) +install(TARGETS testLibPerConfigDest EXPORT exp + DESTINATION lib/$<$<BOOL:$<CONFIG>>:$<CONFIG>>$<$<NOT:$<BOOL:$<CONFIG>>>:NoConfig> + ) + # Work-around: Visual Studio 6 does not support per-target object files. set(VS6) if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6") @@ -446,9 +451,9 @@ install( cmp0022NEW cmp0022OLD systemlib EXPORT exp - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib NAMELINK_SKIP - ARCHIVE DESTINATION lib + RUNTIME DESTINATION $<1:bin> + LIBRARY DESTINATION $<1:lib> NAMELINK_SKIP + ARCHIVE DESTINATION $<1:lib> FRAMEWORK DESTINATION Frameworks BUNDLE DESTINATION Applications ) @@ -503,6 +508,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3 export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib testLib4lib testLib4libdbg testLib4libopt testLibCycleA testLibCycleB + testLibPerConfigDest NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake ) diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt index 523fc29..00a5375 100644 --- a/Tests/ExportImport/Export/Interface/CMakeLists.txt +++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt @@ -29,7 +29,17 @@ target_compile_features(use_auto_type INTERFACE cxx_auto_type) add_library(use_c_restrict INTERFACE) target_compile_features(use_c_restrict INTERFACE c_restrict) -install(TARGETS headeronly sharediface use_auto_type use_c_restrict +add_library(source_target INTERFACE) +target_sources(source_target INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/source_target.cpp> + $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/src/source_target_for_install.cpp> +) +install(FILES + source_target_for_install.cpp + DESTINATION src +) + +install(TARGETS headeronly sharediface use_auto_type use_c_restrict source_target EXPORT expInterface ) install(TARGETS sharedlib diff --git a/Tests/ExportImport/Export/Interface/source_target.cpp b/Tests/ExportImport/Export/Interface/source_target.cpp new file mode 100644 index 0000000..037191c --- /dev/null +++ b/Tests/ExportImport/Export/Interface/source_target.cpp @@ -0,0 +1,13 @@ + +#ifndef USE_FROM_BUILD_DIR +#error Expected define USE_FROM_BUILD_DIR +#endif + +#ifdef USE_FROM_INSTALL_DIR +#error Unexpected define USE_FROM_INSTALL_DIR +#endif + +int source_symbol() +{ + return 42; +} diff --git a/Tests/ExportImport/Export/Interface/source_target_for_install.cpp b/Tests/ExportImport/Export/Interface/source_target_for_install.cpp new file mode 100644 index 0000000..64514ed --- /dev/null +++ b/Tests/ExportImport/Export/Interface/source_target_for_install.cpp @@ -0,0 +1,13 @@ + +#ifdef USE_FROM_BUILD_DIR +#error Unexpected define USE_FROM_BUILD_DIR +#endif + +#ifndef USE_FROM_INSTALL_DIR +#error Expected define USE_FROM_INSTALL_DIR +#endif + +int source_symbol() +{ + return 42; +} diff --git a/Tests/ExportImport/Export/testLibPerConfigDest.c b/Tests/ExportImport/Export/testLibPerConfigDest.c new file mode 100644 index 0000000..c7113fc --- /dev/null +++ b/Tests/ExportImport/Export/testLibPerConfigDest.c @@ -0,0 +1 @@ +int testLibPerConfigDest(void) { return 0; } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 358776b..ced7b03 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -34,6 +34,7 @@ target_link_libraries(imp_testExe1 exp_testLib5 exp_testLib6 exp_testLibCycleA + exp_testLibPerConfigDest ) # Try building a plugin to an executable imported from the install tree. @@ -66,6 +67,7 @@ target_link_libraries(imp_testExe1b bld_testLib5 bld_testLib6 bld_testLibCycleA + bld_testLibPerConfigDest ) add_custom_target(check_testLib1_genex ALL diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c index 451998a..150fcef 100644 --- a/Tests/ExportImport/Import/A/imp_testExe1.c +++ b/Tests/ExportImport/Import/A/imp_testExe1.c @@ -7,6 +7,7 @@ extern int testLib4lib(); extern int testLib5(); extern int testLib6(); extern int testLibCycleA1(); +extern int testLibPerConfigDest(); /* Switch a symbol between debug and optimized builds to make sure the proper library is found from the testLib4 link interface. */ @@ -21,5 +22,6 @@ int main() { return (testLib2() + generated_by_testExe1() + testLib3() + testLib4() + testLib5() + testLib6() + testLibCycleA1() + + testLibPerConfigDest() + generated_by_testExe3() + testLib4lib() + testLib4libcfg()); } diff --git a/Tests/ExportImport/Import/Interface/CMakeLists.txt b/Tests/ExportImport/Import/Interface/CMakeLists.txt index 4028405..51d518e 100644 --- a/Tests/ExportImport/Import/Interface/CMakeLists.txt +++ b/Tests/ExportImport/Import/Interface/CMakeLists.txt @@ -82,6 +82,14 @@ endmacro() do_try_compile(bld) +add_executable(source_target_test_bld source_target_test.cpp) +target_link_libraries(source_target_test_bld bld::source_target) +target_compile_definitions(source_target_test_bld PRIVATE USE_FROM_BUILD_DIR) + +add_executable(source_target_test_exp source_target_test.cpp) +target_link_libraries(source_target_test_exp exp::source_target) +target_compile_definitions(source_target_test_exp PRIVATE USE_FROM_INSTALL_DIR) + add_executable(headeronlytest_exp headeronlytest.cpp) target_link_libraries(headeronlytest_exp exp::headeronly) diff --git a/Tests/ExportImport/Import/Interface/source_target_test.cpp b/Tests/ExportImport/Import/Interface/source_target_test.cpp new file mode 100644 index 0000000..0e8ec5f --- /dev/null +++ b/Tests/ExportImport/Import/Interface/source_target_test.cpp @@ -0,0 +1,7 @@ + +extern int source_symbol(); + +int main() +{ + return source_symbol() - 42; +} diff --git a/Tests/FindMatlab/basic_checks/CMakeLists.txt b/Tests/FindMatlab/basic_checks/CMakeLists.txt new file mode 100644 index 0000000..acf71ea --- /dev/null +++ b/Tests/FindMatlab/basic_checks/CMakeLists.txt @@ -0,0 +1,57 @@ + +cmake_minimum_required (VERSION 2.8.12) +enable_testing() +project(basic_checks) + +set(MATLAB_FIND_DEBUG TRUE) + +# the success of the following command is dependent on the current configuration: +# - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab +# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab +find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY MAIN_PROGRAM) + + + +matlab_add_mex( + # target name + NAME cmake_matlab_test_wrapper1 + # output name + OUTPUT_NAME cmake_matlab_mex1 + SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp + DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt + ) + + +matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-1 + TIMEOUT 30 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests1.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + +matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-2 + TIMEOUT 15 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests_timeout.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) +set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE) + + +# testing the test without the unittest framework of Matlab +matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-3 + TIMEOUT 30 + NO_UNITTEST_FRAMEWORK + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests2.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + +matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-4 + TIMEOUT 30 + NO_UNITTEST_FRAMEWORK + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests3.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) +set_tests_properties(${PROJECT_NAME}_matlabtest-4 PROPERTIES WILL_FAIL TRUE) diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests1.m b/Tests/FindMatlab/cmake_matlab_unit_tests1.m new file mode 100644 index 0000000..2371c3a --- /dev/null +++ b/Tests/FindMatlab/cmake_matlab_unit_tests1.m @@ -0,0 +1,33 @@ + +classdef cmake_matlab_unit_tests1 < matlab.unittest.TestCase + % some simple unit test for CMake Matlab wrapper + properties + end + + methods (Test) + function testDummyCall(testCase) + % very simple call test + cmake_matlab_mex1(rand(3,3)); + end + + function testDummyCall2(testCase) + % very simple call test 2 + ret = cmake_matlab_mex1(rand(3,3)); + testCase.verifyEqual(size(ret), size(rand(3,3))); + + testCase.verifyEqual(size(cmake_matlab_mex1(rand(4,3))), [4,3] ); + end + + function testFailTest(testCase) + testCase.verifyError(@() cmake_matlab_mex1(10), 'cmake_matlab:configuration'); + testCase.verifyError(@() cmake_matlab_mex1([10]), 'cmake_matlab:configuration'); + end + + function testHelpContent(testCase) + % testing the help feature + testCase.verifySubstring(evalc('help cmake_matlab_mex1'), 'Dummy matlab extension in cmake'); + end + + + end +end diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests2.m b/Tests/FindMatlab/cmake_matlab_unit_tests2.m new file mode 100644 index 0000000..7a8a342 --- /dev/null +++ b/Tests/FindMatlab/cmake_matlab_unit_tests2.m @@ -0,0 +1,6 @@ + +ret = cmake_matlab_mex1(rand(3,3)); + +if(size(ret) ~= size(rand(3,3))) + error('Dimension mismatch!'); +end diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests3.m b/Tests/FindMatlab/cmake_matlab_unit_tests3.m new file mode 100644 index 0000000..2639325 --- /dev/null +++ b/Tests/FindMatlab/cmake_matlab_unit_tests3.m @@ -0,0 +1,5 @@ + +cmake_matlab_mex1(10); + +% should not reach this point +exit(0); diff --git a/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m b/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m new file mode 100644 index 0000000..11d5e9e --- /dev/null +++ b/Tests/FindMatlab/cmake_matlab_unit_tests_timeout.m @@ -0,0 +1,16 @@ + +classdef cmake_matlab_unit_tests_timeout < matlab.unittest.TestCase + % timeout tests + + properties + end + + methods (Test) + function testCallHangsShouldBeTimedOut(testCase) + cmake_matlab_mex1(rand(3,3)); + disp('Will now wait.'); + disp('Testing the cmake Matlab package timeout - do not kill'); + pause(20); % supposed to be killed after 15s + end + end +end diff --git a/Tests/FindMatlab/help_text1.m.txt b/Tests/FindMatlab/help_text1.m.txt new file mode 100644 index 0000000..a924355 --- /dev/null +++ b/Tests/FindMatlab/help_text1.m.txt @@ -0,0 +1,2 @@ +% Dummy matlab extension in cmake +function ret = cmake_matlab_mex1(X) diff --git a/Tests/FindMatlab/matlab_wrapper1.cpp b/Tests/FindMatlab/matlab_wrapper1.cpp new file mode 100644 index 0000000..4149bb9 --- /dev/null +++ b/Tests/FindMatlab/matlab_wrapper1.cpp @@ -0,0 +1,26 @@ + +// simple workaround to some compiler specific problems +// see http://stackoverflow.com/questions/22367516/mex-compile-error-unknown-type-name-char16-t/23281916#23281916 +#include <algorithm> + +#include "mex.h" + +// this test should return a matrix of 10 x 10 and should check some of the arguments + +void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) +{ + if(nrhs != 1) + { + mexErrMsgTxt("Incorrect arguments"); + } + + size_t dim1 = mxGetM(prhs[0]); + size_t dim2 = mxGetN(prhs[0]); + + if(dim1 == 1 || dim2 == 1) + { + mexErrMsgIdAndTxt("cmake_matlab:configuration", "Incorrect arguments"); + } + + plhs[0] = mxCreateNumericMatrix(dim1, dim2, mxGetClassID(prhs[0]), mxREAL); +} diff --git a/Tests/FindMatlab/versions_checks/CMakeLists.txt b/Tests/FindMatlab/versions_checks/CMakeLists.txt new file mode 100644 index 0000000..5d20685 --- /dev/null +++ b/Tests/FindMatlab/versions_checks/CMakeLists.txt @@ -0,0 +1,52 @@ + +cmake_minimum_required (VERSION 2.8.12) +enable_testing() +project(versions_checks) + +set(MATLAB_FIND_DEBUG TRUE) +set(MATLAB_ADDITIONAL_VERSIONS + "dummy=14.9") + +# the success of the following command is dependent on the current configuration +# in this case, we are only interested in the version macros +find_package(Matlab) + + + +if(NOT COMMAND matlab_get_version_from_release_name) + message(FATAL_ERROR "The macro matlab_get_version_from_release_name should be defined") +endif() + +if(NOT COMMAND matlab_get_release_name_from_version) + message(FATAL_ERROR "The macro matlab_get_release_name_from_version should be defined") +endif() + + +# matlab_get_release_name_from_version +matlab_get_release_name_from_version("7.13" release_name) +if(NOT release_name STREQUAL "R2011b") + message(FATAL_ERROR "version 7.13 does not give release R2011b : '${release_name}' != R2011b") +endif() + +matlab_get_release_name_from_version("14.9" release_name) +if(NOT release_name STREQUAL "dummy") + message(FATAL_ERROR "version 14.9 does not give release dummy : '${release_name}' != dummy") +endif() + +matlab_get_release_name_from_version("14.10" release_name) +if(NOT release_name STREQUAL "") + message(FATAL_ERROR "version 14.10 does not give empty release: '${release_name}' != ''") +endif() + + +# matlab_get_version_from_release_name +matlab_get_version_from_release_name("R2011a" version) +if(NOT version STREQUAL "7.12") + message(FATAL_ERROR "Release R2011a does not give version 7.12 : '${version}' != 7.12") +endif() + +matlab_get_version_from_release_name("dummy" version) +#message(FATAL_ERROR "versionversion = ${version}") +if(NOT version STREQUAL "14.9") + message(FATAL_ERROR "Release dummy does not give version 14.9 : '${version}' != 14.9") +endif() diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt index 1b2651d..9bf0303 100644 --- a/Tests/FortranOnly/CMakeLists.txt +++ b/Tests/FortranOnly/CMakeLists.txt @@ -65,6 +65,13 @@ if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL) message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n" "${err}") endif() + + unset(Fortran_BOGUS_FLAG CACHE) + include(CheckFortranCompilerFlag) + CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG) + if (Fortran_BOGUS_FLAG) + message (SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed") + endif () endif() # Test generation of preprocessed sources. diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt index 98f521e..826a9ed 100644 --- a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt +++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt @@ -3,6 +3,11 @@ set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) add_library(headeriface INTERFACE) -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h" - "#define IFACE_HEADER_BUILDDIR\n" -) +add_custom_target(headeriface_gen + COMMENT "Generating iface_header_builddir.h" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/iface_header_builddir.h.in + ${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h + VERBATIM + ) +add_dependencies(headeriface headeriface_gen) diff --git a/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in b/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in new file mode 100644 index 0000000..42dd6df --- /dev/null +++ b/Tests/InterfaceLibrary/headerdir/iface_header_builddir.h.in @@ -0,0 +1 @@ +#define IFACE_HEADER_BUILDDIR diff --git a/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in index 49c3e87..49c3e87 100644 --- a/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml +++ b/Tests/JacocoCoverage/Coverage/target/site/jacoco.xml.in diff --git a/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3 b/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3 new file mode 100644 index 0000000..fa0cb1a --- /dev/null +++ b/Tests/Module/ExternalData/Alt/MyAlgoMap1-md5/dded55e43cd6529ee35d24113dfc87a3 @@ -0,0 +1 @@ +DataAlgoMap
\ No newline at end of file diff --git a/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93 b/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93 new file mode 100644 index 0000000..fa0cb1a --- /dev/null +++ b/Tests/Module/ExternalData/Alt/SHA1/85158f0c1996837976e858c42a9a7634bfe91b93 @@ -0,0 +1 @@ +DataAlgoMap
\ No newline at end of file diff --git a/Tests/Module/ExternalData/CMakeLists.txt b/Tests/Module/ExternalData/CMakeLists.txt index f99f6af..b6e24d2 100644 --- a/Tests/Module/ExternalData/CMakeLists.txt +++ b/Tests/Module/ExternalData/CMakeLists.txt @@ -10,8 +10,10 @@ if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" MATCHES "^/") endif() set(ExternalData_URL_TEMPLATES "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/%(algo)/%(hash)" + "file://${slash}${CMAKE_CURRENT_SOURCE_DIR}/Alt/%(algo:MyAlgoMap1)/%(hash)" "ExternalDataCustomScript://MyScript1/%(algo)/%(hash)" ) +set(ExternalData_URL_ALGO_MD5_MyAlgoMap1 MyAlgoMap1-md5) 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 @@ -26,6 +28,8 @@ ExternalData_Add_Test(Data1 -D Data=DATA{Data.dat} ${Data1CheckSpaces} -D DataScript=DATA{DataScript.dat} + -D DataAlgoMapA=DATA{DataAlgoMapA.dat} + -D DataAlgoMapB=DATA{DataAlgoMapB.dat} -D DataMissing=DATA{DataMissing.dat} -D DataMissingWithAssociated=DATA{DataMissing.dat,Data.dat} -D SeriesA=DATA{SeriesA.dat,:} @@ -40,6 +44,7 @@ ExternalData_Add_Test(Data1 -D Paired=DATA{PairedA.dat,PairedB.dat} -D Meta=DATA{MetaTop.dat,REGEX:Meta[ABC].dat} -D Directory=DATA{Directory/,A.dat,REGEX:[BC].dat} + -D DirRecurse=DATA{DirRecurse/,RECURSE:,A.dat,REGEX:[BC].dat} -D "Semicolons=DATA{Data.dat}\\;DATA{Data.dat}" -P ${CMAKE_CURRENT_SOURCE_DIR}/Data1Check.cmake ) diff --git a/Tests/Module/ExternalData/Data1Check.cmake b/Tests/Module/ExternalData/Data1Check.cmake index a7aa4ae..f60c209 100644 --- a/Tests/Module/ExternalData/Data1Check.cmake +++ b/Tests/Module/ExternalData/Data1Check.cmake @@ -12,6 +12,14 @@ 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() +file(STRINGS "${DataAlgoMapA}" lines LIMIT_INPUT 1024) +if(NOT "x${lines}" STREQUAL "xDataAlgoMap") + message(SEND_ERROR "Input file:\n ${DataAlgoMapA}\ndoes not have expected content, but [[${lines}]]") +endif() +file(STRINGS "${DataAlgoMapB}" lines LIMIT_INPUT 1024) +if(NOT "x${lines}" STREQUAL "xDataAlgoMap") + message(SEND_ERROR "Input file:\n ${DataAlgoMapB}\ndoes not have expected content, but [[${lines}]]") +endif() if(DataMissing) if(EXISTS "${DataMissing}") message(SEND_ERROR @@ -82,6 +90,12 @@ foreach(n A B C) message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!") endif() endforeach() +foreach(n A Sub1/A Sub2/Dir/A B Sub1/B Sub2/Dir/B C Sub1/C Sub2/Dir/C) + set(file "${DirRecurse}/${n}.dat") + if(NOT EXISTS "${file}") + message(SEND_ERROR "Input file:\n ${file}\ndoes not exist!") + endif() +endforeach() list(LENGTH Semicolons len) if("${len}" EQUAL 2) foreach(file ${Semicolons}) diff --git a/Tests/Module/ExternalData/DataAlgoMapA.dat.md5 b/Tests/Module/ExternalData/DataAlgoMapA.dat.md5 new file mode 100644 index 0000000..7281481 --- /dev/null +++ b/Tests/Module/ExternalData/DataAlgoMapA.dat.md5 @@ -0,0 +1 @@ +dded55e43cd6529ee35d24113dfc87a3 diff --git a/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1 b/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1 new file mode 100644 index 0000000..4fd7c06 --- /dev/null +++ b/Tests/Module/ExternalData/DataAlgoMapB.dat.sha1 @@ -0,0 +1 @@ +85158f0c1996837976e858c42a9a7634bfe91b93 diff --git a/Tests/Module/ExternalData/DirRecurse/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/A.dat.md5 new file mode 100644 index 0000000..4a78fc7 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/A.dat.md5 @@ -0,0 +1 @@ +9d980b06c2f0fec3d4872d68175b9822 diff --git a/Tests/Module/ExternalData/DirRecurse/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/B.dat.md5 new file mode 100644 index 0000000..4557a21 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/B.dat.md5 @@ -0,0 +1 @@ +8f4add4581551facf27237e6577fd662 diff --git a/Tests/Module/ExternalData/DirRecurse/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/C.dat.md5 new file mode 100644 index 0000000..a7f23dd --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/C.dat.md5 @@ -0,0 +1 @@ +c1030719c95f3435d8abc39c0d442946 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5 new file mode 100644 index 0000000..4a78fc7 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub1/A.dat.md5 @@ -0,0 +1 @@ +9d980b06c2f0fec3d4872d68175b9822 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5 new file mode 100644 index 0000000..4557a21 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub1/B.dat.md5 @@ -0,0 +1 @@ +8f4add4581551facf27237e6577fd662 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5 new file mode 100644 index 0000000..a7f23dd --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub1/C.dat.md5 @@ -0,0 +1 @@ +c1030719c95f3435d8abc39c0d442946 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5 new file mode 100644 index 0000000..4a78fc7 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/A.dat.md5 @@ -0,0 +1 @@ +9d980b06c2f0fec3d4872d68175b9822 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5 new file mode 100644 index 0000000..4557a21 --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/B.dat.md5 @@ -0,0 +1 @@ +8f4add4581551facf27237e6577fd662 diff --git a/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5 b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5 new file mode 100644 index 0000000..a7f23dd --- /dev/null +++ b/Tests/Module/ExternalData/DirRecurse/Sub2/Dir/C.dat.md5 @@ -0,0 +1 @@ +c1030719c95f3435d8abc39c0d442946 diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-exe-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-shared-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-NEW-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-link_libraries-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-NOWARN-static-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt b/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0022/CMP0022-export-exe-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0026/CMP0026-CONFIG-LOCATION-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0026/CMP0026-LOCATION-CONFIG-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0028/CMP0028-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0037/CMP0037-OLD-reserved-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0037/CMP0037-OLD-space-stderr.txt b/Tests/RunCMake/CMP0037/CMP0037-OLD-space-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0037/CMP0037-OLD-space-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0038/CMP0038-OLD-stderr.txt b/Tests/RunCMake/CMP0038/CMP0038-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0038/CMP0038-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0039/CMP0039-OLD-stderr.txt b/Tests/RunCMake/CMP0039/CMP0039-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0039/CMP0039-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0041/CMP0041-OLD-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0041/CMP0041-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-stderr.txt b/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0041/CMP0041-tid-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0042/CMP0042-NEW-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt b/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0042/CMP0042-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0043/CMP0043-NEW-stderr.txt b/Tests/RunCMake/CMP0043/CMP0043-NEW-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0043/CMP0043-NEW-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0043/CMP0043-OLD-stderr.txt b/Tests/RunCMake/CMP0043/CMP0043-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0043/CMP0043-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0045/CMP0045-OLD-stderr.txt b/Tests/RunCMake/CMP0045/CMP0045-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0045/CMP0045-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0046/CMP0046-NEW-existing-dependency-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0046/CMP0046-OLD-existing-dependency-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency-stderr.txt b/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0046/CMP0046-OLD-missing-dependency-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0049/CMP0049-OLD-stderr.txt b/Tests/RunCMake/CMP0049/CMP0049-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0049/CMP0049-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0050/CMP0050-OLD-stderr.txt b/Tests/RunCMake/CMP0050/CMP0050-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0050/CMP0050-OLD-stderr.txt +++ /dev/null @@ -1 +0,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 deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0055/CMP0055-OLD-Out-of-Scope-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt b/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CMP0055/CMP0055-OLD-Reject-Arguments-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/interface_library/add_dependencies-result.txt b/Tests/RunCMake/CMP0057/CMP0057-NEW-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/interface_library/add_dependencies-result.txt +++ b/Tests/RunCMake/CMP0057/CMP0057-NEW-result.txt diff --git a/Tests/RunCMake/CMP0057/CMP0057-NEW-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-NEW-stderr.txt new file mode 100644 index 0000000..9607d54 --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-NEW-stderr.txt @@ -0,0 +1,4 @@ +CMake Error at CMP0057-NEW.cmake:8 \(add_custom_command\): + "input.txt" can only be specified as a custom command MAIN_DEPENDENCY once. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake b/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake new file mode 100644 index 0000000..22dbfb3 --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-NEW.cmake @@ -0,0 +1,13 @@ +cmake_policy(SET CMP0057 NEW) + +add_custom_command(OUTPUT out1 + COMMAND ${CMAKE_COMMAND} -E echo out1 + MAIN_DEPENDENCY input.txt +) + +add_custom_command(OUTPUT out2 + COMMAND ${CMAKE_COMMAND} -E echo out2 + MAIN_DEPENDENCY input.txt +) + +add_custom_target(mytarget1 ALL DEPENDS out1 out2) diff --git a/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake b/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake new file mode 100644 index 0000000..ccf4fcb --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-OLD.cmake @@ -0,0 +1,13 @@ +cmake_policy(SET CMP0057 OLD) + +add_custom_command(OUTPUT out1 + COMMAND ${CMAKE_COMMAND} -E echo out1 + MAIN_DEPENDENCY input.txt +) + +add_custom_command(OUTPUT out2 + COMMAND ${CMAKE_COMMAND} -E echo out2 + MAIN_DEPENDENCY input.txt +) + +add_custom_target(mytarget1 ALL DEPENDS out1 out2) diff --git a/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt b/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt new file mode 100644 index 0000000..da3a1cb --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-WARN-stderr.txt @@ -0,0 +1,9 @@ +CMake Warning \(dev\) at CMP0057-WARN.cmake:6 \(add_custom_command\): + Policy CMP0057 is not set: Disallow multiple MAIN_DEPENDENCY specifications + for the same file. Run "cmake --help-policy CMP0057" for policy details. + Use the cmake_policy command to set the policy and suppress this warning. + + "input.txt" can only be specified as a custom command MAIN_DEPENDENCY once. +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/CMP0057/CMP0057-WARN.cmake b/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake new file mode 100644 index 0000000..1837968 --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-WARN.cmake @@ -0,0 +1,11 @@ +add_custom_command(OUTPUT out1 + COMMAND ${CMAKE_COMMAND} -E echo out1 + MAIN_DEPENDENCY input.txt +) + +add_custom_command(OUTPUT out2 + COMMAND ${CMAKE_COMMAND} -E echo out2 + MAIN_DEPENDENCY input.txt +) + +add_custom_target(mytarget1 ALL DEPENDS out1 out2) diff --git a/Tests/RunCMake/CMP0057/CMP0057-once_is_ok.cmake b/Tests/RunCMake/CMP0057/CMP0057-once_is_ok.cmake new file mode 100644 index 0000000..8ce02f9 --- /dev/null +++ b/Tests/RunCMake/CMP0057/CMP0057-once_is_ok.cmake @@ -0,0 +1,8 @@ +cmake_policy(SET CMP0057 NEW) + +add_custom_command(OUTPUT out1 + COMMAND ${CMAKE_COMMAND} -E echo out1 + MAIN_DEPENDENCY input.txt +) + +add_custom_target(mytarget1 ALL DEPENDS out1) diff --git a/Tests/RunCMake/CMP0057/CMakeLists.txt b/Tests/RunCMake/CMP0057/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/CMP0057/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/CMP0057/RunCMakeTest.cmake b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake new file mode 100644 index 0000000..f79235f --- /dev/null +++ b/Tests/RunCMake/CMP0057/RunCMakeTest.cmake @@ -0,0 +1,7 @@ +include(RunCMake) + +run_cmake(CMP0057-OLD) +run_cmake(CMP0057-NEW) +run_cmake(CMP0057-WARN) + +run_cmake(CMP0057-once_is_ok) diff --git a/Tests/RunCMake/CMP0057/input.txt b/Tests/RunCMake/CMP0057/input.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CMP0057/input.txt diff --git a/Tests/RunCMake/include_directories/export-NOWARN-result.txt b/Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/export-NOWARN-result.txt +++ b/Tests/RunCMake/CMP0059/CMP0059-NEW-result.txt diff --git a/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt new file mode 100644 index 0000000..76992d8 --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-NEW-stderr.txt @@ -0,0 +1,2 @@ +DEFS: +CUSTOM CONTENT:CUSTOM_CONTENT diff --git a/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake b/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake new file mode 100644 index 0000000..f7b9303 --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-NEW.cmake @@ -0,0 +1,17 @@ + +cmake_policy(SET CMP0059 NEW) + +add_definitions(-DSOME_DEF) + +get_property(defs DIRECTORY . + PROPERTY DEFINITIONS +) +message("DEFS:${defs}") + +set_property(DIRECTORY . + PROPERTY DEFINITIONS CUSTOM_CONTENT +) +get_property(content DIRECTORY . + PROPERTY DEFINITIONS +) +message("CUSTOM CONTENT:${content}") diff --git a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-result.txt b/Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-result.txt +++ b/Tests/RunCMake/CMP0059/CMP0059-OLD-result.txt diff --git a/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt new file mode 100644 index 0000000..e35e8c5 --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-OLD-stderr.txt @@ -0,0 +1,2 @@ +DEFS: -DSOME_DEF +CUSTOM CONTENT: -DSOME_DEF diff --git a/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake b/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake new file mode 100644 index 0000000..2555774 --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-OLD.cmake @@ -0,0 +1,17 @@ + +cmake_policy(SET CMP0059 OLD) + +add_definitions(-DSOME_DEF) + +get_property(defs DIRECTORY . + PROPERTY DEFINITIONS +) +message("DEFS:${defs}") + +set_property(DIRECTORY . + PROPERTY DEFINITIONS CUSTOM_CONTENT +) +get_property(content DIRECTORY . + PROPERTY DEFINITIONS +) +message("CUSTOM CONTENT:${content}") diff --git a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-result.txt b/Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-result.txt +++ b/Tests/RunCMake/CMP0059/CMP0059-WARN-result.txt diff --git a/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt b/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt new file mode 100644 index 0000000..4e04d15 --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-WARN-stderr.txt @@ -0,0 +1,18 @@ +CMake Warning \(dev\) at CMP0059-WARN.cmake:6 \(get_property\): + Policy CMP0059 is not set: Do no treat DEFINITIONS as a built-in directory + property. Run "cmake --help-policy CMP0059" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +DEFS: -DSOME_DEF +CMake Warning \(dev\) at CMP0059-WARN.cmake:14 \(get_property\): + Policy CMP0059 is not set: Do no treat DEFINITIONS as a built-in directory + property. Run "cmake --help-policy CMP0059" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. + +CUSTOM CONTENT: -DSOME_DEF diff --git a/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake b/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake new file mode 100644 index 0000000..9d0b49c --- /dev/null +++ b/Tests/RunCMake/CMP0059/CMP0059-WARN.cmake @@ -0,0 +1,17 @@ + + + +add_definitions(-DSOME_DEF) + +get_property(defs DIRECTORY . + PROPERTY DEFINITIONS +) +message("DEFS:${defs}") + +set_property(DIRECTORY . + PROPERTY DEFINITIONS CUSTOM_CONTENT +) +get_property(content DIRECTORY . + PROPERTY DEFINITIONS +) +message("CUSTOM CONTENT:${content}") diff --git a/Tests/RunCMake/CMP0059/CMakeLists.txt b/Tests/RunCMake/CMP0059/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/CMP0059/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/CMP0059/RunCMakeTest.cmake b/Tests/RunCMake/CMP0059/RunCMakeTest.cmake new file mode 100644 index 0000000..9b57579 --- /dev/null +++ b/Tests/RunCMake/CMP0059/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0059-OLD) +run_cmake(CMP0059-NEW) +run_cmake(CMP0059-WARN) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 801655f..6daf27a 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -1,17 +1,28 @@ # See adjacent README.rst for documentation of this test infrastructure. macro(add_RunCMake_test test) + set(TEST_ARGS ${ARGN}) + if ("${ARGV1}" STREQUAL "TEST_DIR") + if ("${ARGV2}" STREQUAL "") + message(FATAL_ERROR "Invalid args") + endif() + set(Test_Dir ${ARGV2}) + list(REMOVE_AT TEST_ARGS 0) + list(REMOVE_AT TEST_ARGS 0) + else() + set(Test_Dir ${test}) + endif() 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} -DRunCMake_GENERATOR_TOOLSET=${CMAKE_GENERATOR_TOOLSET} -DRunCMake_MAKE_PROGRAM=${CMake_TEST_EXPLICIT_MAKE_PROGRAM} - -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${test} + -DRunCMake_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/${Test_Dir} -DRunCMake_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}/${test} ${${test}_ARGS} - ${ARGN} - -P "${CMAKE_CURRENT_SOURCE_DIR}/${test}/RunCMakeTest.cmake" + ${TEST_ARGS} + -P "${CMAKE_CURRENT_SOURCE_DIR}/${Test_Dir}/RunCMakeTest.cmake" ) endmacro() @@ -52,11 +63,15 @@ add_RunCMake_test(CMP0051) add_RunCMake_test(CMP0053) add_RunCMake_test(CMP0054) add_RunCMake_test(CMP0055) +add_RunCMake_test(CMP0057) +add_RunCMake_test(CMP0059) +if(CMAKE_GENERATOR STREQUAL "Ninja") + add_RunCMake_test(Ninja) +endif() add_RunCMake_test(CTest) -add_RunCMake_test(CTestSubmit) if(NOT CMake_TEST_EXTERNAL_CMAKE) - add_RunCMake_test(CTestMemcheck + add_RunCMake_test(ctest_memcheck -DPSEUDO_BC=$<TARGET_FILE:pseudo_BC> -DPSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify> -DPSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind> @@ -119,9 +134,20 @@ add_RunCMake_test(build_command) add_RunCMake_test(export) add_RunCMake_test(cmake_minimum_required) add_RunCMake_test(continue) +add_RunCMake_test(ctest_build) +add_RunCMake_test(ctest_configure) +if(COVERAGE_COMMAND) + add_RunCMake_test(ctest_coverage -DCOVERAGE_COMMAND=${COVERAGE_COMMAND}) +endif() +add_RunCMake_test(ctest_start) +add_RunCMake_test(ctest_submit) +add_RunCMake_test(ctest_test) +add_RunCMake_test(ctest_upload) add_RunCMake_test(file) +add_RunCMake_test(find_file) add_RunCMake_test(find_library) add_RunCMake_test(find_package) +add_RunCMake_test(find_path) add_RunCMake_test(get_filename_component) add_RunCMake_test(get_property) add_RunCMake_test(if) @@ -163,7 +189,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio [^6]") endif() if(XCODE_VERSION AND NOT "${XCODE_VERSION}" VERSION_LESS 3) - add_RunCMake_test(XcodeProject) + add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION}) endif() add_RunCMake_test(File_Generate) @@ -177,7 +203,21 @@ add_RunCMake_test(CommandLine) add_RunCMake_test(install) add_RunCMake_test(CPackInstallProperties) add_RunCMake_test(ExternalProject) +add_RunCMake_test(CTestCommandLine) + +set(IfacePaths_INCLUDE_DIRECTORIES_ARGS -DTEST_PROP=INCLUDE_DIRECTORIES) +add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths) -if(RPMBUILD) +set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES) +add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths) + +if(RPMBUILD_EXECUTABLE) add_RunCMake_test(CPackRPM) endif() + +add_RunCMake_test(COMPILE_LANGUAGE-genex) + +# Matlab module related tests +if(CMake_TEST_FindMatlab) + add_RunCMake_test(FindMatlab) +endif() diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/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/include_directories/SrcInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-result.txt +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-result.txt diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt new file mode 100644 index 0000000..73b66ac --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt new file mode 100644 index 0000000..a1ed633 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions-stderr-Xcode.txt @@ -0,0 +1,9 @@ +CMake Error at CompileDefinitions.cmake:5 \(target_compile_definitions\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the + Xcode generator. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake new file mode 100644 index 0000000..7935d88 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileDefinitions.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_compile_definitions(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>) diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-result.txt diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt new file mode 100644 index 0000000..e9e8e9f --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at CompileOptions.cmake:5 \(target_compile_options\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake new file mode 100644 index 0000000..6c92abc --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/CompileOptions.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_compile_options(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-DANYTHING>) diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-result.txt diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt new file mode 100644 index 0000000..ec15068 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-VS.txt @@ -0,0 +1,8 @@ +CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may not be used with Visual Studio generators. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt new file mode 100644 index 0000000..fdf92b2 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories-stderr-Xcode.txt @@ -0,0 +1,9 @@ +CMake Error at IncludeDirectories.cmake:5 \(target_include_directories\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> may only be used with COMPILE_OPTIONS with the + Xcode generator. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake new file mode 100644 index 0000000..31771f6 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/IncludeDirectories.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_executable(main main.cpp) +target_include_directories(main PRIVATE $<$<COMPILE_LANGUAGE:CXX>:anydir>) diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake new file mode 100644 index 0000000..5e0a5f5 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/RunCMakeTest.cmake @@ -0,0 +1,20 @@ +include(RunCMake) + +if (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file CompileOptions-stderr-VS.txt) + run_cmake(CompileOptions) +endif() +if (RunCMake_GENERATOR STREQUAL "Xcode") + set(RunCMake-stderr-file CompileDefinitions-stderr-Xcode.txt) + run_cmake(CompileDefinitions) +elseif (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file CompileDefinitions-stderr-VS.txt) + run_cmake(CompileDefinitions) +endif() +if (RunCMake_GENERATOR STREQUAL "Xcode") + set(RunCMake-stderr-file IncludeDirectories-stderr-Xcode.txt) + run_cmake(IncludeDirectories) +elseif (RunCMake_GENERATOR MATCHES "Visual Studio") + set(RunCMake-stderr-file IncludeDirectories-stderr-VS.txt) + run_cmake(IncludeDirectories) +endif() diff --git a/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp new file mode 100644 index 0000000..31a1337 --- /dev/null +++ b/Tests/RunCMake/COMPILE_LANGUAGE-genex/main.cpp @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/CTestCommandLine/CMakeLists.txt b/Tests/RunCMake/CTestCommandLine/CMakeLists.txt new file mode 100644 index 0000000..2897109 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/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/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake new file mode 100644 index 0000000..2e5156c --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake @@ -0,0 +1,25 @@ +include(RunCMake) + +run_cmake_command(repeat-until-fail-bad1 + ${CMAKE_CTEST_COMMAND} --repeat-until-fail + ) +run_cmake_command(repeat-until-fail-bad2 + ${CMAKE_CTEST_COMMAND} --repeat-until-fail foo + ) +run_cmake_command(repeat-until-fail-good + ${CMAKE_CTEST_COMMAND} --repeat-until-fail 2 + ) + +function(run_repeat_until_fail_tests) + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(repeat-until-fail-cmake) + run_cmake_command(repeat-until-fail-ctest + ${CMAKE_CTEST_COMMAND} -C Debug --repeat-until-fail 3 + ) +endfunction() +run_repeat_until_fail_tests() diff --git a/Tests/RunCMake/CTestCommandLine/init.cmake b/Tests/RunCMake/CTestCommandLine/init.cmake new file mode 100644 index 0000000..a900f67 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/init.cmake @@ -0,0 +1,3 @@ +# This is run by test initialization in repeat-until-fail-cmake.cmake +# with cmake -P. It creates TEST_OUTPUT_FILE with a 0 in it. +file(WRITE "${TEST_OUTPUT_FILE}" "0") diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/RelativePathInGenex-result.txt +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-result.txt diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt new file mode 100644 index 0000000..5ea8816 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad1-stderr.txt @@ -0,0 +1 @@ +^CMake Error: '--repeat-until-fail' requires an argument$ diff --git a/Tests/RunCMake/include_directories/InstallInSrcDir-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/InstallInSrcDir-result.txt +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-result.txt diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt new file mode 100644 index 0000000..a79faae --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-bad2-stderr.txt @@ -0,0 +1 @@ +^CMake Error: '--repeat-until-fail' given non-integer value 'foo'$ diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake new file mode 100644 index 0000000..4654416 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-cmake.cmake @@ -0,0 +1,15 @@ +enable_testing() + +set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt") +add_test(NAME initialization + COMMAND ${CMAKE_COMMAND} + "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake") +add_test(NAME test1 + COMMAND ${CMAKE_COMMAND} + "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/test1.cmake") +set_tests_properties(test1 PROPERTIES DEPENDS "initialization") + +add_test(hello ${CMAKE_COMMAND} -E echo hello) +add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye) diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-result.txt @@ -0,0 +1 @@ +8 diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt new file mode 100644 index 0000000..7593783 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stderr.txt @@ -0,0 +1 @@ +^Errors while running CTest$ diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt new file mode 100644 index 0000000..6e133cd --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-ctest-stdout.txt @@ -0,0 +1,30 @@ +^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-fail-build + Start 1: initialization + Test #1: initialization ................... Passed +[0-9.]+ sec + Start 1: initialization + Test #1: initialization ................... Passed +[0-9.]+ sec + Start 1: initialization +1/4 Test #1: initialization ................... Passed +[0-9.]+ sec + Start 2: test1 + Test #2: test1 ............................ Passed +[0-9.]+ sec + Start 2: test1 + Test #2: test1 ............................\*\*\*Failed +[0-9.]+ sec + Start 3: hello + Test #3: hello ............................ Passed +[0-9.]+ sec + Start 3: hello + Test #3: hello ............................ Passed +[0-9.]+ sec + Start 3: hello +3/4 Test #3: hello ............................ Passed +[0-9.]+ sec + Start 4: goodbye + Test #4: goodbye .......................... Passed +[0-9.]+ sec + Start 4: goodbye + Test #4: goodbye .......................... Passed +[0-9.]+ sec + Start 4: goodbye +4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec ++ +75% tests passed, 1 tests failed out of 4 ++ +Total Test time \(real\) = +[0-9.]+ sec ++ +The following tests FAILED: +[ ]+2 - test1 \(Failed\)$ diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt new file mode 100644 index 0000000..a7c4b11 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/repeat-until-fail-good-stderr.txt @@ -0,0 +1 @@ +^No tests were found!!!$ diff --git a/Tests/RunCMake/CTestCommandLine/test1.cmake b/Tests/RunCMake/CTestCommandLine/test1.cmake new file mode 100644 index 0000000..eeae7a2 --- /dev/null +++ b/Tests/RunCMake/CTestCommandLine/test1.cmake @@ -0,0 +1,13 @@ +# This is run by test test1 in repeat-until-fail-cmake.cmake with cmake -P. +# It reads the file TEST_OUTPUT_FILE and increments the number +# found in the file by 1. When the number is 2, then the +# code sends out a cmake error causing the test to fail +# the second time it is run. +message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}") +file(READ "${TEST_OUTPUT_FILE}" COUNT) +message("COUNT= ${COUNT}") +math(EXPR COUNT "${COUNT} + 1") +file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}") +if(${COUNT} EQUAL 2) + message(FATAL_ERROR "this test fails on the 2nd run") +endif() diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt deleted file mode 100644 index 725270c..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyBCNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stderr.txt deleted file mode 100644 index 634e331..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -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/DummyLeakSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stderr.txt deleted file mode 100644 index 520222f..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyMemorySanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stderr.txt deleted file mode 100644 index 29c6ec7..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyPurify-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyPurify-stderr.txt deleted file mode 100644 index 14bc228..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyPurify-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -^((^| -)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ -]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt deleted file mode 100644 index 2506f35..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyThreadSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stderr.txt deleted file mode 100644 index ca23692..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyUndefinedBehaviorSanitizer-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stderr.txt deleted file mode 100644 index fd684da..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyValgrind-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrind-stderr.txt deleted file mode 100644 index 14bc228..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrind-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -^((^| -)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ -]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt deleted file mode 100644 index 1a2ee5c..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyValgrindFailPre-stdout.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stdout.txt deleted file mode 100644 index 9a6a1d6..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stdout.txt +++ /dev/null @@ -1 +0,0 @@ -Memory check project .*/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-build diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt deleted file mode 100644 index 14bc228..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -^((^| -)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ -]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt deleted file mode 100644 index d8d1ff0..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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 deleted file mode 100644 index d46912e..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-stdout.txt +++ /dev/null @@ -1 +0,0 @@ -Memory check project .*/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-build$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt deleted file mode 100644 index 321a2a5..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/DummyValgrindPrePost-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stderr.txt deleted file mode 100644 index 14bc228..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -^((^| -)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ -]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt b/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt deleted file mode 100644 index 14bc228..0000000 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -^((^| -)(BullseyeCoverage|==|ctest\([0-9]+\) malloc:)[^ -]*)*$ diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt b/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt deleted file mode 100644 index 9e92266..0000000 --- a/Tests/RunCMake/CTestMemcheck/NotExist-stdout.txt +++ /dev/null @@ -1 +0,0 @@ -Memory check project .*/Tests/RunCMake/CTestMemcheck/NotExist-build$ diff --git a/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt b/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt deleted file mode 100644 index 2beea2d..0000000 --- a/Tests/RunCMake/CTestMemcheck/Unknown-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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 deleted file mode 100644 index 7ea1af0..0000000 --- a/Tests/RunCMake/CTestMemcheck/Unknown-stdout.txt +++ /dev/null @@ -1 +0,0 @@ -Memory check project .*/Tests/RunCMake/CTestMemcheck/Unknown-build$ diff --git a/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt b/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt deleted file mode 100644 index 68812ab..0000000 --- a/Tests/RunCMake/CTestSubmit/BadArg-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/BadFILES-stderr.txt deleted file mode 100644 index 703224b..0000000 --- a/Tests/RunCMake/CTestSubmit/BadFILES-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/BadPARTS-stderr.txt deleted file mode 100644 index 4e491a9..0000000 --- a/Tests/RunCMake/CTestSubmit/BadPARTS-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt deleted file mode 100644 index 48177e2..0000000 --- a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/CDashUploadPARTS-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt deleted file mode 100644 index 497ead2..0000000 --- a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt deleted file mode 100644 index 8c4e6b1..0000000 --- a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt deleted file mode 100644 index 6c56399..0000000 --- a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/FailDrop-ftp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt deleted file mode 100644 index a622fac..0000000 --- a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -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-http-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt deleted file mode 100644 index 6870d2e..0000000 --- a/Tests/RunCMake/CTestSubmit/FailDrop-http-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -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-https-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt deleted file mode 100644 index a3c0cd5..0000000 --- a/Tests/RunCMake/CTestSubmit/FailDrop-https-stderr.txt +++ /dev/null @@ -1,3 +0,0 @@ -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-scp-stderr.txt b/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt deleted file mode 100644 index 42b8f50..0000000 --- a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ - Problems when submitting via SCP -Error in read script: .*/Tests/RunCMake/CTestSubmit/FailDrop-scp/test.cmake diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt deleted file mode 100644 index dfa7e33..0000000 --- a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt deleted file mode 100644 index 42becaf..0000000 --- a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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-stderr.txt b/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-stderr.txt deleted file mode 100644 index d56793e..0000000 --- a/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-stderr.txt +++ /dev/null @@ -1,2 +0,0 @@ -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/CommandLine/Build-ninja-v-stdout.txt b/Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt new file mode 100644 index 0000000..83c62ec --- /dev/null +++ b/Tests/RunCMake/CommandLine/Build-ninja-v-stdout.txt @@ -0,0 +1 @@ +-E echo CustomCommand diff --git a/Tests/RunCMake/CommandLine/Build.cmake b/Tests/RunCMake/CommandLine/Build.cmake new file mode 100644 index 0000000..20df108 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Build.cmake @@ -0,0 +1,5 @@ +add_custom_command( + OUTPUT output.txt + COMMAND ${CMAKE_COMMAND} -E echo CustomCommand > output.txt + ) +add_custom_target(CustomTarget ALL DEPENDS output.txt) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 2be6651..a9c49e7 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -18,6 +18,22 @@ run_cmake_command(build-no-generator run_cmake_command(build-bad-generator ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator) +if(RunCMake_GENERATOR STREQUAL "Ninja") + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + set(RunCMake_TEST_OPTIONS -DCMAKE_VERBOSE_MAKEFILE=1) + run_cmake(Build) + unset(RunCMake_TEST_OPTIONS) + run_cmake_command(Build-ninja-v ${CMAKE_COMMAND} --build .) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) +endif() + if(UNIX) run_cmake_command(E_create_symlink-missing-dir ${CMAKE_COMMAND} -E create_symlink T missing-dir/L diff --git a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-stderr.txt b/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/CompileFeatures/LinkImplementationFeatureCycleSolved-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/DisallowedCommands/CMP0029-OLD-stderr.txt b/Tests/RunCMake/DisallowedCommands/CMP0029-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/DisallowedCommands/CMP0029-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/InstallInBinDir-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/InstallInBinDir-result.txt +++ b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt b/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt new file mode 100644 index 0000000..c3708a9 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap1-stderr.txt @@ -0,0 +1,9 @@ +CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Bad %\(algo:\) in URL template: + + file:///path/to/%\(algo:\)/%\(hash\) + + The transform name must be a valid C identifier. +Call Stack \(most recent call first\): + BadAlgoMap1.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake b/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake new file mode 100644 index 0000000..542ec1d --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap1.cmake @@ -0,0 +1,5 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "file:///path/to/%(algo:)/%(hash)" + ) +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt +++ b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt b/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt new file mode 100644 index 0000000..1f10644 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap2-stderr.txt @@ -0,0 +1,9 @@ +CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Bad %\(algo:0BadMap\(\) in URL template: + + file:///path/to/%\(algo:0BadMap\(\)/%\(hash\) + + The transform name must be a valid C identifier. +Call Stack \(most recent call first\): + BadAlgoMap2.cmake:[0-9]+ \(ExternalData_Add_Target\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake b/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake new file mode 100644 index 0000000..0537a7b --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap2.cmake @@ -0,0 +1,5 @@ +include(ExternalData) +set(ExternalData_URL_TEMPLATES + "file:///path/to/%(algo:0BadMap()/%(hash)" + ) +ExternalData_Add_Target(Data) diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt +++ b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt diff --git a/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt new file mode 100644 index 0000000..aedc330 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse1-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Recurse option "RECURSE:" allowed only with directories. +Call Stack \(most recent call first\): + .* + BadRecurse1.cmake:2 \(ExternalData_Expand_Arguments\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExternalData/BadRecurse1.cmake b/Tests/RunCMake/ExternalData/BadRecurse1.cmake new file mode 100644 index 0000000..f70b9f9 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse1.cmake @@ -0,0 +1,2 @@ +include(ExternalData) +ExternalData_Expand_Arguments(Data args DATA{Series.txt,:,RECURSE:}) diff --git a/Tests/RunCMake/TargetSources/ExportInstall-result.txt b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/TargetSources/ExportInstall-result.txt +++ b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt diff --git a/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt new file mode 100644 index 0000000..3f809ca --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse2-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Recurse option "RECURSE:" allowed only with directories. +Call Stack \(most recent call first\): + .* + BadRecurse2.cmake:2 \(ExternalData_Expand_Arguments\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExternalData/BadRecurse2.cmake b/Tests/RunCMake/ExternalData/BadRecurse2.cmake new file mode 100644 index 0000000..c4dc35d --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse2.cmake @@ -0,0 +1,2 @@ +include(ExternalData) +ExternalData_Expand_Arguments(Data args DATA{Data.txt,RECURSE:}) diff --git a/Tests/RunCMake/ExternalData/BadRecurse3-result.txt b/Tests/RunCMake/ExternalData/BadRecurse3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt b/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt new file mode 100644 index 0000000..37740e0 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse3-stderr.txt @@ -0,0 +1,9 @@ +CMake Error at .*/Modules/ExternalData.cmake:[0-9]+ \(message\): + Unknown option "RECURSE:x" in argument + + DATA{Directory1/,RECURSE:x,Data.dat} + +Call Stack \(most recent call first\): + .* + BadRecurse3.cmake:2 \(ExternalData_Expand_Arguments\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/ExternalData/BadRecurse3.cmake b/Tests/RunCMake/ExternalData/BadRecurse3.cmake new file mode 100644 index 0000000..9a22f62 --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse3.cmake @@ -0,0 +1,2 @@ +include(ExternalData) +ExternalData_Expand_Arguments(Data args DATA{Directory1/,RECURSE:x,Data.dat}) diff --git a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake index 7afd289..b5ab22d 100644 --- a/Tests/RunCMake/ExternalData/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalData/RunCMakeTest.cmake @@ -1,5 +1,7 @@ include(RunCMake) +run_cmake(BadAlgoMap1) +run_cmake(BadAlgoMap2) run_cmake(BadCustom1) run_cmake(BadCustom2) run_cmake(BadCustom3) @@ -7,6 +9,9 @@ run_cmake(BadCustom4) run_cmake(BadHashAlgo1) run_cmake(BadOption1) run_cmake(BadOption2) +run_cmake(BadRecurse1) +run_cmake(BadRecurse2) +run_cmake(BadRecurse3) run_cmake(BadSeries1) run_cmake(BadSeries2) run_cmake(BadSeries3) diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt new file mode 100644 index 0000000..39be105 --- /dev/null +++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce-stdout.txt @@ -0,0 +1,4 @@ +--( ) + \* Foo , Foo decscription\. ++ +-- diff --git a/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake new file mode 100644 index 0000000..545fb92 --- /dev/null +++ b/Tests/RunCMake/FeatureSummary/FeatureSummaryWhatOnce.cmake @@ -0,0 +1,8 @@ +include(FeatureSummary) + +set(WITH_FOO 1) + +add_feature_info(Foo WITH_FOO "Foo decscription.") +add_feature_info(Foo WITH_FOO "Foo decscription.") + +feature_summary(WHAT ENABLED_FEATURES) diff --git a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake index 1417338..6a5fc28 100644 --- a/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake +++ b/Tests/RunCMake/FeatureSummary/RunCMakeTest.cmake @@ -6,3 +6,4 @@ run_cmake(FeatureSummaryWhatSingleUnknown) run_cmake(FeatureSummaryWhatList) run_cmake(FeatureSummaryWhatListUnknown) run_cmake(FeatureSummaryWhatListAll) +run_cmake(FeatureSummaryWhatOnce) diff --git a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-result.txt b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-result.txt +++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex-result.txt diff --git a/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake new file mode 100644 index 0000000..e2b081d --- /dev/null +++ b/Tests/RunCMake/File_Generate/COMPILE_LANGUAGE-genex.cmake @@ -0,0 +1,12 @@ + +enable_language(CXX C) + +add_library(empty empty.cpp empty.c) +target_compile_options(empty + PRIVATE LANG_IS_$<COMPILE_LANGUAGE> +) + +file(GENERATE + OUTPUT opts-$<COMPILE_LANGUAGE>.txt + CONTENT "$<TARGET_PROPERTY:empty,COMPILE_OPTIONS>\n" +) diff --git a/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt b/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/File_Generate/CarryPermissions-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt index da97ba4..4fa3f20 100644 --- a/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt +++ b/Tests/RunCMake/File_Generate/CommandConflict-stderr.txt @@ -1 +1 @@ -CMake Error: File to be generated by multiple different commands: .*CommandConflict-build/output_.*.txt +CMake Error: Files to be generated by multiple different commands: ".*CommandConflict-build/output_.*.txt" diff --git a/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt b/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/File_Generate/GenerateSource-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt index dbd39de..0abb7df 100644 --- a/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt +++ b/Tests/RunCMake/File_Generate/OutputConflict-stderr.txt @@ -1,5 +1,5 @@ CMake Error in CMakeLists.txt: Evaluation file to be written multiple times for different configurations - with different content: + or languages with different content: .*output.txt diff --git a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt b/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/File_Generate/OutputNameMatchesOtherSources-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt b/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/File_Generate/ReRunCMake-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index 97f93d5..db344ef 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -17,6 +17,16 @@ if (NOT file_contents MATCHES "generated.cpp.rule") message(SEND_ERROR "Rule file not in target sources! ${file_contents}") endif() +if (NOT RunCMake_GENERATOR MATCHES "Visual Studio") + run_cmake(COMPILE_LANGUAGE-genex) + foreach(l CXX C) + file(READ "${RunCMake_BINARY_DIR}/COMPILE_LANGUAGE-genex-build/opts-${l}.txt" l_defs) + if (NOT l_defs STREQUAL "LANG_IS_${l}\n") + message(FATAL_ERROR "File content does not match: ${l_defs}") + endif() + endforeach() +endif() + set(timeformat "%Y%j%H%M%S") file(REMOVE "${RunCMake_BINARY_DIR}/WriteIfDifferent-build/output_file.txt") diff --git a/Tests/RunCMake/File_Generate/WriteIfDifferent-stderr.txt b/Tests/RunCMake/File_Generate/WriteIfDifferent-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/File_Generate/WriteIfDifferent-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/File_Generate/empty.c b/Tests/RunCMake/File_Generate/empty.c new file mode 100644 index 0000000..563eef0 --- /dev/null +++ b/Tests/RunCMake/File_Generate/empty.c @@ -0,0 +1,8 @@ + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty_c() +{ + return 0; +} diff --git a/Tests/RunCMake/FindMatlab/CMakeLists.txt b/Tests/RunCMake/FindMatlab/CMakeLists.txt new file mode 100644 index 0000000..1b9a957 --- /dev/null +++ b/Tests/RunCMake/FindMatlab/CMakeLists.txt @@ -0,0 +1,3 @@ + +cmake_minimum_required(VERSION 2.8.12) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt b/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/FindMatlab/MatlabTest1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt b/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt new file mode 100644 index 0000000..95a787f --- /dev/null +++ b/Tests/RunCMake/FindMatlab/MatlabTest1-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*FindMatlab.cmake:[0-9]+ \(message\): + \[MATLAB\] This functionality needs the MAIN_PROGRAM component \(not default\) diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1.cmake b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake new file mode 100644 index 0000000..1cbc1c2 --- /dev/null +++ b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake @@ -0,0 +1,22 @@ + +cmake_minimum_required (VERSION 2.8.12) +enable_testing() +project(test_should_fail) + +find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY) + +matlab_add_mex( + # target name + NAME cmake_matlab_test_wrapper1 + # output name + OUTPUT_NAME cmake_matlab_mex1 + SRC ${CMAKE_CURRENT_SOURCE_DIR}/matlab_wrapper1.cpp + ) + +# this command should raise a FATAL_ERROR, component MAIN_PROGRAM is missing +matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-1 + TIMEOUT 1 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake_matlab_unit_tests2.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) diff --git a/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake new file mode 100644 index 0000000..33dbb77 --- /dev/null +++ b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake @@ -0,0 +1,3 @@ + +include(RunCMake) +run_cmake(MatlabTest1) diff --git a/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m b/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m new file mode 100644 index 0000000..7a8a342 --- /dev/null +++ b/Tests/RunCMake/FindMatlab/cmake_matlab_unit_tests2.m @@ -0,0 +1,6 @@ + +ret = cmake_matlab_mex1(rand(3,3)); + +if(size(ret) ~= size(rand(3,3))) + error('Dimension mismatch!'); +end diff --git a/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp b/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp new file mode 100644 index 0000000..4149bb9 --- /dev/null +++ b/Tests/RunCMake/FindMatlab/matlab_wrapper1.cpp @@ -0,0 +1,26 @@ + +// simple workaround to some compiler specific problems +// see http://stackoverflow.com/questions/22367516/mex-compile-error-unknown-type-name-char16-t/23281916#23281916 +#include <algorithm> + +#include "mex.h" + +// this test should return a matrix of 10 x 10 and should check some of the arguments + +void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) +{ + if(nrhs != 1) + { + mexErrMsgTxt("Incorrect arguments"); + } + + size_t dim1 = mxGetM(prhs[0]); + size_t dim2 = mxGetN(prhs[0]); + + if(dim1 == 1 || dim2 == 1) + { + mexErrMsgIdAndTxt("cmake_matlab:configuration", "Incorrect arguments"); + } + + plhs[0] = mxCreateNumericMatrix(dim1, dim2, mxGetClassID(prhs[0]), mxREAL); +} diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt new file mode 100644 index 0000000..789b4d0 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-add_custom_command.cmake:6 \(add_custom_command\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake new file mode 100644 index 0000000..f4ba261 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_command.cmake @@ -0,0 +1,8 @@ + +enable_language(C) + +add_library(empty empty.c) + +add_custom_command(TARGET empty PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE> +) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt new file mode 100644 index 0000000..400fbc0 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-add_custom_target.cmake:4 \(add_custom_target\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake new file mode 100644 index 0000000..4102623 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_custom_target.cmake @@ -0,0 +1,6 @@ + +enable_language(C) + +add_custom_target(empty + COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE> +) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt new file mode 100644 index 0000000..e45bb02 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-add_executable.cmake:4 \(add_executable\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake new file mode 100644 index 0000000..5c2ff35 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_executable.cmake @@ -0,0 +1,4 @@ + +enable_language(C) + +add_executable(empty empty.$<COMPILE_LANGUAGE>) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt new file mode 100644 index 0000000..c9ee6fe --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-add_library.cmake:4 \(add_library\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake new file mode 100644 index 0000000..dd9f824 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_library.cmake @@ -0,0 +1,4 @@ + +enable_language(C) + +add_library(empty empty.$<COMPILE_LANGUAGE>) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt new file mode 100644 index 0000000..9955f5d --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-add_test.cmake:5 \(add_test\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake new file mode 100644 index 0000000..deedf65 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-add_test.cmake @@ -0,0 +1,5 @@ + +include(CTest) +enable_testing() + +add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANGUAGE>) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt new file mode 100644 index 0000000..eca700f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install-stderr.txt @@ -0,0 +1,8 @@ +CMake Error: + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake new file mode 100644 index 0000000..92c20e3 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-install.cmake @@ -0,0 +1,5 @@ + +install(FILES + empty.$<COMPILE_LANGUAGE> + DESTINATION src +) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt new file mode 100644 index 0000000..2d324e2 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources-stderr.txt @@ -0,0 +1,10 @@ +CMake Error at COMPILE_LANGUAGE-target_sources.cmake:5 \(target_sources\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE> + + \$<COMPILE_LANGUAGE:...> may only be used to specify include directories + compile definitions, compile options and to evaluate components of the + file\(GENERATE\) command. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake new file mode 100644 index 0000000..0c78acd --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-target_sources.cmake @@ -0,0 +1,5 @@ + +enable_language(C) + +add_library(empty empty.c) +target_sources(empty PRIVATE empty.$<COMPILE_LANGUAGE>) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt new file mode 100644 index 0000000..444da45 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at COMPILE_LANGUAGE-unknown-lang.cmake:4 \(target_compile_options\): + Error evaluating generator expression: + + \$<COMPILE_LANGUAGE:CXX> + + \$<COMPILE_LANGUAGE:...> Unknown language. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake new file mode 100644 index 0000000..cec12a3 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/COMPILE_LANGUAGE-unknown-lang.cmake @@ -0,0 +1,4 @@ + +enable_language(C) +add_executable(empty empty.c) +target_compile_options(empty PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall>) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 6c32393..542b7fc 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -16,6 +16,14 @@ run_cmake(NonValidTarget-C_COMPILER_VERSION) run_cmake(NonValidTarget-CXX_COMPILER_VERSION) run_cmake(NonValidTarget-TARGET_PROPERTY) run_cmake(NonValidTarget-TARGET_POLICY) +run_cmake(COMPILE_LANGUAGE-add_custom_target) +run_cmake(COMPILE_LANGUAGE-add_custom_command) +run_cmake(COMPILE_LANGUAGE-install) +run_cmake(COMPILE_LANGUAGE-target_sources) +run_cmake(COMPILE_LANGUAGE-add_executable) +run_cmake(COMPILE_LANGUAGE-add_library) +run_cmake(COMPILE_LANGUAGE-add_test) +run_cmake(COMPILE_LANGUAGE-unknown-lang) if(LINKER_SUPPORTS_PDB) run_cmake(NonValidTarget-TARGET_PDB_FILE) diff --git a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-stderr.txt b/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/GeneratorExpression/ValidTarget-TARGET_PDB_FILE-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-stderr.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt index f0adc9f..f2d749b 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-stderr.txt +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-NEW-build/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-NEW-build/foo" which is prefixed in the build directory. diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-result.txt +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-OLD-result.txt diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-result.txt +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-result.txt diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-stderr.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt index 054bff5..3d83892 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-stderr.txt +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt @@ -6,15 +6,15 @@ CMake Warning \(dev\) in CMakeLists.txt: Directory: - ".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-WARN-build/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-WARN-build/foo" in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory of the install directory: - ".*Tests/RunCMake/include_directories/prefix" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix" however it is also a subdirectory of the build tree: - ".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-WARN-build" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/BinInInstallPrefix-CMP0052-WARN-build" This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt new file mode 100644 index 0000000..239c069 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinInInstallPrefix-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths_SOURCES/prefix/BinInInstallPrefix-build/empty.cpp" + + which is prefixed in the build directory. diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt index 0d4379e..ed7cd58 100644 --- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt +++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*RunCMake/include_directories/BinaryDirectoryInInterface-build/foo" + ".*RunCMake/IfacePaths_INCLUDE_DIRECTORIES/BinaryDirectoryInInterface-build/foo" which is prefixed in the build directory. diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt new file mode 100644 index 0000000..e931a01 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths_SOURCES/BinaryDirectoryInInterface-build/empty.cpp" + + which is prefixed in the build directory. diff --git a/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake new file mode 100644 index 0000000..7001f3f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/BinaryDirectoryInInterface.cmake @@ -0,0 +1,15 @@ + +enable_language(CXX) + +add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") +if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foo") +else() + set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/empty.cpp") +endif() + +install(TARGETS testTarget EXPORT testTargets + DESTINATION lib +) + +install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/IfacePaths/CMakeLists.txt b/Tests/RunCMake/IfacePaths/CMakeLists.txt new file mode 100644 index 0000000..5cd4825 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.0) +project(${RunCMake_TEST} NONE) +if(NOT TEST_FILE) + set(TEST_FILE ${RunCMake_TEST}.cmake) +endif() +include(${TEST_FILE}) diff --git a/Tests/RunCMake/include_directories/DirInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/DirInInstallPrefix-result.txt +++ b/Tests/RunCMake/IfacePaths/DirInInstallPrefix-result.txt diff --git a/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake b/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake new file mode 100644 index 0000000..f5f3005 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/DirInInstallPrefix.cmake @@ -0,0 +1,14 @@ +enable_language(CXX) +add_library(testTarget empty.cpp) + +if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/dir") +else() + set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_INSTALL_PREFIX}/empty.cpp") +endif() + +install(TARGETS testTarget EXPORT testTargets + DESTINATION lib +) + +install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/InstallInBinDir-stderr.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt index 254fae1..3d60831 100644 --- a/Tests/RunCMake/include_directories/InstallInBinDir-stderr.txt +++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*Tests/RunCMake/include_directories/InstallInBinDir-build/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/InstallInBinDir-build/foo" which is prefixed in the build directory. diff --git a/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt new file mode 100644 index 0000000..c79d598 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/InstallInBinDir-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths_SOURCES/InstallInBinDir-build/empty.cpp" + + which is prefixed in the build directory. diff --git a/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/InstallInSrcDir-stderr.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt index 7be3044..11994dd 100644 --- a/Tests/RunCMake/include_directories/InstallInSrcDir-stderr.txt +++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*Tests/RunCMake/include_directories/copy/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/copy/foo" which is prefixed in the source directory. diff --git a/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt new file mode 100644 index 0000000..e71921e --- /dev/null +++ b/Tests/RunCMake/IfacePaths/InstallInSrcDir-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths_SOURCES/copy/empty.cpp" + + which is prefixed in the source directory. diff --git a/Tests/RunCMake/include_directories/InstallPrefixInInterface-result.txt b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/InstallPrefixInInterface-result.txt +++ b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface-result.txt diff --git a/Tests/RunCMake/include_directories/InstallPrefixInInterface.cmake b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake index 8d777f5..8d777f5 100644 --- a/Tests/RunCMake/include_directories/InstallPrefixInInterface.cmake +++ b/Tests/RunCMake/IfacePaths/InstallPrefixInInterface.cmake diff --git a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-result.txt b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-result.txt +++ b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirInSource-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-result.txt b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/NotExist-result.txt +++ b/Tests/RunCMake/IfacePaths/InstallToPrefixInSrcDirOutOfSource-result.txt diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_INCLUDE_DIRECTORIES.txt index 490c700..490c700 100644 --- a/Tests/RunCMake/include_directories/RelativePathInGenex-stderr.txt +++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_INCLUDE_DIRECTORIES.txt diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt new file mode 100644 index 0000000..2311af9 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex-stderr_SOURCES.txt @@ -0,0 +1,4 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" contains relative path in its INTERFACE_SOURCES: + + "empty.cpp" diff --git a/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake b/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake new file mode 100644 index 0000000..489c3a1 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInGenex.cmake @@ -0,0 +1,13 @@ + +enable_language(CXX) + +add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") + +if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>") +else() + set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "$<1:empty.cpp>") +endif() + +add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") +target_link_libraries(userTarget testTarget) diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_INCLUDE_DIRECTORIES.txt index f6cdb53..f6cdb53 100644 --- a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt +++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_INCLUDE_DIRECTORIES.txt diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt new file mode 100644 index 0000000..f0f002c --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface-stderr_SOURCES.txt @@ -0,0 +1,4 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains relative path: + + "empty.cpp" diff --git a/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake b/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake new file mode 100644 index 0000000..e974aac --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RelativePathInInterface.cmake @@ -0,0 +1,14 @@ + +enable_language(CXX) + +add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") +if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo") +else() + set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "empty.cpp") +endif() +install(TARGETS testTarget EXPORT testTargets + DESTINATION lib +) + +install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake new file mode 100644 index 0000000..489e3df --- /dev/null +++ b/Tests/RunCMake/IfacePaths/RunCMakeTest.cmake @@ -0,0 +1,156 @@ +include(RunCMake) + +macro(run_cmake test) + list(APPEND RunCMake_TEST_OPTIONS -DTEST_PROP=${TEST_PROP}) + set(RunCMake-stderr-file ${test}-stderr_${TEST_PROP}.txt) + _run_cmake(${test}) +endmacro() + +run_cmake(RelativePathInInterface) +run_cmake(RelativePathInGenex) +run_cmake(export-NOWARN) +run_cmake(SourceDirectoryInInterface) +run_cmake(BinaryDirectoryInInterface) + +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/DirInInstallPrefix/prefix") +run_cmake(DirInInstallPrefix) + +configure_file( + "${RunCMake_SOURCE_DIR}/CMakeLists.txt" + "${RunCMake_BINARY_DIR}/copy/CMakeLists.txt" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/empty.cpp" + "${RunCMake_BINARY_DIR}/copy/empty.cpp" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake" + "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake" + COPYONLY +) +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix" + "-DTEST_FILE=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake" + ) +set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy") +run_cmake(InstallInSrcDir) +unset(RunCMake_TEST_SOURCE_DIR) + +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix") +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix" + "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" + ) +set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/InstallInBinDir-build") +run_cmake(InstallInBinDir) +unset(RunCMake_TEST_BINARY_DIR) + +configure_file( + "${RunCMake_SOURCE_DIR}/CMakeLists.txt" + "${RunCMake_BINARY_DIR}/prefix/src/CMakeLists.txt" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/empty.cpp" + "${RunCMake_BINARY_DIR}/prefix/src/empty.cpp" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake" + "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake" + COPYONLY +) + +foreach(policyStatus NEW OLD "") + if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + if (NOT "${policyStatus}" STREQUAL "") + set(policyOption -DCMAKE_POLICY_DEFAULT_CMP0052=${policyStatus}) + else() + unset(policyOption) + set(policyStatus WARN) + endif() + set(policySuffix -CMP0052-${policyStatus}) + endif() + set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption} + "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" + ) + # Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run + # the test suite in-source properly. Otherwise the install directory would be + # a subdirectory or the source directory, which is allowed and tested separately + # below. + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/prefix/src") + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/prefix/BinInInstallPrefix${policySuffix}-build") + run_cmake(BinInInstallPrefix${policySuffix}) + unset(RunCMake_TEST_BINARY_DIR) + + set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption} + "-DTEST_FILE=${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake" + ) + run_cmake(SrcInInstallPrefix${policySuffix}) + unset(RunCMake_TEST_SOURCE_DIR) + + if (NOT TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + break() + endif() +endforeach() + +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallPrefixInInterface-build/prefix") +run_cmake(InstallPrefixInInterface) + +configure_file( + "${RunCMake_SOURCE_DIR}/CMakeLists.txt" + "${RunCMake_BINARY_DIR}/installToSrc/CMakeLists.txt" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/empty.cpp" + "${RunCMake_BINARY_DIR}/installToSrc/empty.cpp" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake" + "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake" + COPYONLY +) +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface/prefix" + "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake" + ) +set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrc") +run_cmake(InstallToPrefixInSrcDirOutOfSource) +unset(RunCMake_TEST_SOURCE_DIR) + + +file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/installToSrcInSrc") +set(RunCMake_TEST_NO_CLEAN ON) + +configure_file( + "${RunCMake_SOURCE_DIR}/CMakeLists.txt" + "${RunCMake_BINARY_DIR}/installToSrcInSrc/CMakeLists.txt" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/empty.cpp" + "${RunCMake_BINARY_DIR}/installToSrcInSrc/empty.cpp" + COPYONLY +) +configure_file( + "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake" + "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake" + COPYONLY +) + +set(RunCMake_TEST_OPTIONS + "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface/prefix" + "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake" + ) +set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc") +set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc") +run_cmake(InstallToPrefixInSrcDirInSource) +unset(RunCMake_TEST_SOURCE_DIR) +unset(RunCMake_TEST_BINARY_DIR) +unset(RunCMake_TEST_NO_CLEAN) diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt index 9346b99..97a94b1 100644 --- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt +++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*RunCMake/include_directories/foo" + ".*RunCMake/IfacePaths/foo" which is prefixed in the source directory. diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt new file mode 100644 index 0000000..c5157ad --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths/empty.cpp" + + which is prefixed in the source directory. diff --git a/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake new file mode 100644 index 0000000..d80cbec --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SourceDirectoryInInterface.cmake @@ -0,0 +1,15 @@ + +enable_language(CXX) + +add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") +if (TEST_PROP STREQUAL INCLUDE_DIRECTORIES) + set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/foo") +else() + set_property(TARGET testTarget PROPERTY INTERFACE_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") +endif() + +install(TARGETS testTarget EXPORT testTargets + DESTINATION lib +) + +install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-stderr.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt index afa43e0..ed5df34 100644 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-stderr.txt +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-NEW-stderr_INCLUDE_DIRECTORIES.txt @@ -1,6 +1,6 @@ CMake Error in CMakeLists.txt: Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path: - ".*Tests/RunCMake/include_directories/prefix/src/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src/foo" which is prefixed in the source directory. diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-result.txt +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-OLD-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-result.txt +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-result.txt diff --git a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-stderr.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt index 0b13fd8..cb5a51c 100644 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-stderr.txt +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-CMP0052-WARN-stderr_INCLUDE_DIRECTORIES.txt @@ -6,15 +6,15 @@ CMake Warning \(dev\) in CMakeLists.txt: Directory: - ".*Tests/RunCMake/include_directories/prefix/src/foo" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src/foo" in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory of the install directory: - ".*Tests/RunCMake/include_directories/prefix" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix" however it is also a subdirectory of the source tree: - ".*Tests/RunCMake/include_directories/prefix/src" + ".*Tests/RunCMake/IfacePaths_INCLUDE_DIRECTORIES/prefix/src" This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt new file mode 100644 index 0000000..48f2485 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/SrcInInstallPrefix-stderr_SOURCES.txt @@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Target "testTarget" INTERFACE_SOURCES property contains path: + + ".*Tests/RunCMake/IfacePaths_SOURCES/prefix/src/empty.cpp" + + which is prefixed in the source directory. diff --git a/Tests/RunCMake/IfacePaths/empty.cpp b/Tests/RunCMake/IfacePaths/empty.cpp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/IfacePaths/empty.cpp diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-result.txt b/Tests/RunCMake/IfacePaths/export-NOWARN-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-result.txt +++ b/Tests/RunCMake/IfacePaths/export-NOWARN-result.txt diff --git a/Tests/RunCMake/include_directories/export-NOWARN.cmake b/Tests/RunCMake/IfacePaths/export-NOWARN.cmake index 50720a0..592572c 100644 --- a/Tests/RunCMake/include_directories/export-NOWARN.cmake +++ b/Tests/RunCMake/IfacePaths/export-NOWARN.cmake @@ -1,19 +1,34 @@ enable_language(CXX) add_library(foo empty.cpp) + set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<0:>/include/subdir) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_PREFIX>/include/subdir) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<0:>/include/subdir/empty.cpp) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_PREFIX>/include/subdir/empty.cpp) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/subdir>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:include/$<0:>>) set_property(TARGET foo APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $<INSTALL_INTERFACE:$<0:>/include>) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/subdir/empty.cpp>) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp>) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>) +set_property(TARGET foo APPEND PROPERTY INTERFACE_SOURCES $<INSTALL_INTERFACE:$<0:>/include/subdir/empty.cpp>) # target_include_directories(foo INTERFACE include/subdir) # Does and should warn. INSTALL_INTERFACE must not list src dir paths. target_include_directories(foo INTERFACE $<0:>/include/subdir) # Does not and should not should warn, because it starts with a genex. target_include_directories(foo INTERFACE $<INSTALL_PREFIX>/include/subdir) +target_sources(foo INTERFACE $<0:>/include/subdir/empty.cpp) +target_sources(foo INTERFACE $<INSTALL_PREFIX>/include/subdir/empty.cpp) target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/subdir>) target_include_directories(foo INTERFACE $<INSTALL_INTERFACE:include/$<0:>>) +target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp>) +target_sources(foo INTERFACE $<INSTALL_INTERFACE:include/subdir/empty.cpp$<0:>>) + +install(FILES include/subdir/empty.cpp + DESTINATION include/subdir +) install(TARGETS foo EXPORT FooTargets DESTINATION lib) install(EXPORT FooTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt new file mode 100644 index 0000000..8646a13 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-NEW-by-build-stdout.txt @@ -0,0 +1,4 @@ +^[^ +]* Generating output1 +[^ +]* Generating output2$ diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake b/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake new file mode 100644 index 0000000..0f77930 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-NEW-by.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0058 NEW) +set(byproducts BYPRODUCTS byproduct1a byproduct1b) +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt new file mode 100644 index 0000000..fa10109 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no-build-stderr.txt @@ -0,0 +1 @@ +ninja: error: 'byproduct1a', needed by 'output2', missing and no known rule to make it diff --git a/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake b/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake new file mode 100644 index 0000000..582e3d5 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-NEW-no.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0058 NEW) +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt new file mode 100644 index 0000000..8646a13 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-OLD-by-build-stdout.txt @@ -0,0 +1,4 @@ +^[^ +]* Generating output1 +[^ +]* Generating output2$ diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake b/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake new file mode 100644 index 0000000..92a3a0f --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-OLD-by.cmake @@ -0,0 +1,3 @@ +cmake_policy(SET CMP0058 OLD) +set(byproducts BYPRODUCTS byproduct1a byproduct1b) +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt new file mode 100644 index 0000000..8646a13 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-OLD-no-build-stdout.txt @@ -0,0 +1,4 @@ +^[^ +]* Generating output1 +[^ +]* Generating output2$ diff --git a/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake b/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake new file mode 100644 index 0000000..0326e07 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-OLD-no.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0058 OLD) +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt new file mode 100644 index 0000000..8646a13 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-WARN-by-build-stdout.txt @@ -0,0 +1,4 @@ +^[^ +]* Generating output1 +[^ +]* Generating output2$ diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake b/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake new file mode 100644 index 0000000..6128167 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-WARN-by.cmake @@ -0,0 +1,2 @@ +set(byproducts BYPRODUCTS byproduct1a byproduct1b) +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt new file mode 100644 index 0000000..8646a13 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no-build-stdout.txt @@ -0,0 +1,4 @@ +^[^ +]* Generating output1 +[^ +]* Generating output2$ diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt b/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt new file mode 100644 index 0000000..439a2d9 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no-stderr.txt @@ -0,0 +1,19 @@ +^CMake Warning \(dev\): + Policy CMP0058 is not set: Ninja requires custom command byproducts to be + explicit. Run "cmake --help-policy CMP0058" for policy details. Use the + cmake_policy command to set the policy and suppress this warning. + + This project specifies custom command DEPENDS on files in the build tree + that are not specified as the OUTPUT or BYPRODUCTS of any + add_custom_command or add_custom_target: + + byproduct1a + byproduct1b + + For compatibility with versions of CMake that did not have the BYPRODUCTS + option, CMake is generating phony rules for such files to convince 'ninja' + to build. + + Project authors should add the missing BYPRODUCTS or OUTPUT options to the + custom commands that produce these files. +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake b/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake new file mode 100644 index 0000000..7bc66ef --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-WARN-no.cmake @@ -0,0 +1 @@ +include(CMP0058-common.cmake) diff --git a/Tests/RunCMake/Ninja/CMP0058-common.cmake b/Tests/RunCMake/Ninja/CMP0058-common.cmake new file mode 100644 index 0000000..9274d58 --- /dev/null +++ b/Tests/RunCMake/Ninja/CMP0058-common.cmake @@ -0,0 +1,17 @@ +add_custom_command( + OUTPUT output1 + ${byproducts} + COMMAND ${CMAKE_COMMAND} -E touch output1 + COMMAND ${CMAKE_COMMAND} -E touch byproduct1a + COMMAND ${CMAKE_COMMAND} -E touch byproduct1b + ) +add_custom_target(Drive1 ALL DEPENDS output1) +add_custom_command( + OUTPUT output2 + COMMAND ${CMAKE_COMMAND} -E copy output1 output2 + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/output1 + ${CMAKE_CURRENT_BINARY_DIR}/byproduct1a + ${CMAKE_CURRENT_BINARY_DIR}/byproduct1b + ) +add_custom_target(Drive2 ALL DEPENDS output2) +add_dependencies(Drive2 Drive1) diff --git a/Tests/RunCMake/Ninja/CMakeLists.txt b/Tests/RunCMake/Ninja/CMakeLists.txt new file mode 100644 index 0000000..2a0591e --- /dev/null +++ b/Tests/RunCMake/Ninja/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.2) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake new file mode 100644 index 0000000..64f97bc --- /dev/null +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -0,0 +1,18 @@ +include(RunCMake) + +function(run_CMP0058 case) + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0058-${case}-build) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + run_cmake(CMP0058-${case}) + run_cmake_command(CMP0058-${case}-build ${CMAKE_COMMAND} --build .) +endfunction() + +run_CMP0058(OLD-no) +run_CMP0058(OLD-by) +run_CMP0058(WARN-no) +run_CMP0058(WARN-by) +run_CMP0058(NEW-no) +run_CMP0058(NEW-by) diff --git a/Tests/RunCMake/README.rst b/Tests/RunCMake/README.rst index e801a86..4aae4ae 100644 --- a/Tests/RunCMake/README.rst +++ b/Tests/RunCMake/README.rst @@ -22,6 +22,16 @@ but do not actually build anything. To add a test: to fully customize the test case command-line. + Alternatively, if the test is to cover running ``ctest -S`` then use:: + + include(RunCTest) + run_ctest(SubTest1) + ... + run_ctest(SubTestN) + + and create ``test.cmake.in``, ``CTestConfig.cmake.in``, and + ``CMakeLists.txt.in`` files to be configured for each case. + 4. Create file ``<Test>/CMakeLists.txt`` in the directory containing:: cmake_minimum_required(...) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 33b745d..abac66e 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -18,7 +18,10 @@ function(run_cmake test) set(expect_result 0) endif() foreach(o out err) - if(EXISTS ${top_src}/${test}-std${o}.txt) + if(RunCMake-std${o}-file AND EXISTS ${top_src}/${RunCMake-std${o}-file}) + file(READ ${top_src}/${RunCMake-std${o}-file} expect_std${o}) + string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") + elseif(EXISTS ${top_src}/${test}-std${o}.txt) file(READ ${top_src}/${test}-std${o}.txt expect_std${o}) string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") else() @@ -80,7 +83,7 @@ function(run_cmake test) endif() foreach(o out err) string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}") - string(REGEX REPLACE "(^|\n)(==[0-9]+==[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}") + string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}") string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}") set(expect_${o} "") if(DEFINED expect_std${o}) diff --git a/Tests/RunCMake/RunCTest.cmake b/Tests/RunCMake/RunCTest.cmake new file mode 100644 index 0000000..e94432b --- /dev/null +++ b/Tests/RunCMake/RunCTest.cmake @@ -0,0 +1,17 @@ +include(RunCMake) + +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() diff --git a/Tests/RunCMake/Syntax/ParenNoSpace2-stderr.txt b/Tests/RunCMake/Syntax/ParenNoSpace2-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/Syntax/ParenNoSpace2-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/TargetSources/ExportBuild-result.txt b/Tests/RunCMake/TargetSources/ExportBuild-result.txt index d00491f..573541a 100644 --- a/Tests/RunCMake/TargetSources/ExportBuild-result.txt +++ b/Tests/RunCMake/TargetSources/ExportBuild-result.txt @@ -1 +1 @@ -1 +0 diff --git a/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt b/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt deleted file mode 100644 index 0d65a55..0000000 --- a/Tests/RunCMake/TargetSources/ExportBuild-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -CMake Error: Target "iface" has a populated INTERFACE_SOURCES property. This is not currently supported. diff --git a/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt b/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt deleted file mode 100644 index 0d65a55..0000000 --- a/Tests/RunCMake/TargetSources/ExportInstall-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 8e7c9f9..0000000 --- a/Tests/RunCMake/TargetSources/ExportInstall.cmake +++ /dev/null @@ -1,6 +0,0 @@ - -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/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake index 1b4ef0b..4416ef9 100644 --- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake +++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake @@ -10,4 +10,3 @@ endif() run_cmake(CMP0026-LOCATION) run_cmake(RelativePathInInterface) run_cmake(ExportBuild) -run_cmake(ExportInstall) diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index 8e4026b..03d3cd3 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -1,3 +1,8 @@ include(RunCMake) run_cmake(XcodeFileType) +run_cmake(XcodeAttributeGenex) +run_cmake(XcodeAttributeGenexError) +if (NOT XCODE_VERSION VERSION_LESS 6) + run_cmake(XcodePlatformFrameworks) +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake new file mode 100644 index 0000000..637df0f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex-check.cmake @@ -0,0 +1,7 @@ +set(expect "TEST_HOST = \"[^;\"]*Tests/RunCMake/XcodeProject/XcodeAttributeGenex-build/[^;\"/]*/some\"") +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeAttributeGenex.xcodeproj/project.pbxproj actual + REGEX "TEST_HOST = .*;" LIMIT_COUNT 1) +if(NOT "${actual}" MATCHES "${expect}") + message(SEND_ERROR "The actual project contains the line:\n ${actual}\n" + "which does not match expected regex:\n ${expect}\n") +endif() diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake new file mode 100644 index 0000000..760b882 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenex.cmake @@ -0,0 +1,4 @@ +enable_language(C) +add_executable(some main.c) +add_executable(another main.c) +set_property(TARGET another PROPERTY XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:some>") diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt new file mode 100644 index 0000000..9844158 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$<NOTAGENEX> + + Expression did not evaluate to a known generator expression diff --git a/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake new file mode 100644 index 0000000..98ad6c5 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeAttributeGenexError.cmake @@ -0,0 +1,4 @@ +enable_language(C) +add_executable(some main.c) +add_executable(another main.c) +set_property(TARGET another PROPERTY XCODE_ATTRIBUTE_TEST_HOST "$<NOTAGENEX>") diff --git a/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake b/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake new file mode 100644 index 0000000..74dc978 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodePlatformFrameworks.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +find_library(XCTEST_LIBRARY XCTest) +if(NOT XCTEST_LIBRARY) + message(FATAL_ERROR "XCTest Framework not found.") +endif() diff --git a/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt new file mode 100644 index 0000000..2e59d99 --- /dev/null +++ b/Tests/RunCMake/ctest_build/BuildQuiet-stdout.txt @@ -0,0 +1,12 @@ +Run dashboard with model Experimental + Source directory: .*/Tests/RunCMake/ctest_build/BuildQuiet + Build directory: .*/Tests/RunCMake/ctest_build/BuildQuiet-build + Reading ctest configuration file: .*/Tests/RunCMake/ctest_build/BuildQuiet/CTestConfig.cmake + Site: test-site + Build name: test-build-name + Use Experimental tag: [0-9-]+ +Configure project + Each . represents 1024 bytes of output + . Size of output: 0K + 0 Compiler errors + 0 Compiler warnings diff --git a/Tests/RunCMake/ctest_build/CMakeLists.txt.in b/Tests/RunCMake/ctest_build/CMakeLists.txt.in new file mode 100644 index 0000000..9ba08e9 --- /dev/null +++ b/Tests/RunCMake/ctest_build/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestBuild@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_build/CTestConfig.cmake.in b/Tests/RunCMake/ctest_build/CTestConfig.cmake.in new file mode 100644 index 0000000..097f82c --- /dev/null +++ b/Tests/RunCMake/ctest_build/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestBuild@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_build/RunCMakeTest.cmake b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake new file mode 100644 index 0000000..5826fe4 --- /dev/null +++ b/Tests/RunCMake/ctest_build/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_BUILD_ARGS "") + +function(run_ctest_build CASE_NAME) + set(CASE_CTEST_BUILD_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_build(BuildQuiet QUIET) diff --git a/Tests/RunCMake/ctest_build/test.cmake.in b/Tests/RunCMake/ctest_build/test.cmake.in new file mode 100644 index 0000000..38c8ea1 --- /dev/null +++ b/Tests/RunCMake/ctest_build/test.cmake.in @@ -0,0 +1,15 @@ +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}") + +set(ctest_build_args "@CASE_CTEST_BUILD_ARGS@") +ctest_start(Experimental) +ctest_configure() +ctest_build(${ctest_build_args}) diff --git a/Tests/RunCMake/ctest_configure/CMakeLists.txt.in b/Tests/RunCMake/ctest_configure/CMakeLists.txt.in new file mode 100644 index 0000000..2fb21d4 --- /dev/null +++ b/Tests/RunCMake/ctest_configure/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestConfigure@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in b/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in new file mode 100644 index 0000000..7e30ab9 --- /dev/null +++ b/Tests/RunCMake/ctest_configure/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestConfigure@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt new file mode 100644 index 0000000..015644d --- /dev/null +++ b/Tests/RunCMake/ctest_configure/ConfigureQuiet-stdout.txt @@ -0,0 +1,9 @@ +Run dashboard with model Experimental + Source directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet + Build directory: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet-build + Reading ctest configuration file: .*/Tests/RunCMake/ctest_configure/ConfigureQuiet/CTestConfig.cmake + Site: test-site + Build name: test-build-name + Use Experimental tag: [0-9-]+ + Each . represents 1024 bytes of output + . Size of output: 0K diff --git a/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake b/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake new file mode 100644 index 0000000..fc1b02c --- /dev/null +++ b/Tests/RunCMake/ctest_configure/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_CONFIGURE_ARGS "") + +function(run_ctest_configure CASE_NAME) + set(CASE_CTEST_CONFIGURE_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_configure(ConfigureQuiet QUIET) diff --git a/Tests/RunCMake/ctest_configure/test.cmake.in b/Tests/RunCMake/ctest_configure/test.cmake.in new file mode 100644 index 0000000..72d199a --- /dev/null +++ b/Tests/RunCMake/ctest_configure/test.cmake.in @@ -0,0 +1,14 @@ +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}") + +set(ctest_configure_args "@CASE_CTEST_CONFIGURE_ARGS@") +ctest_start(Experimental) +ctest_configure(${ctest_configure_args}) diff --git a/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in b/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in new file mode 100644 index 0000000..1babd72 --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestCoverage@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in b/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in new file mode 100644 index 0000000..1f679d5 --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestCoverage@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt b/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt new file mode 100644 index 0000000..3b09eac --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/CoverageQuiet-stdout.txt @@ -0,0 +1 @@ +sec$ diff --git a/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake new file mode 100644 index 0000000..dd443fc --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_COVERAGE_ARGS "") + +function(run_ctest_coverage CASE_NAME) + set(CASE_CTEST_COVERAGE_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_coverage(CoverageQuiet QUIET) diff --git a/Tests/RunCMake/ctest_coverage/test.cmake.in b/Tests/RunCMake/ctest_coverage/test.cmake.in new file mode 100644 index 0000000..1788e66 --- /dev/null +++ b/Tests/RunCMake/ctest_coverage/test.cmake.in @@ -0,0 +1,18 @@ +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}") +set(CTEST_COVERAGE_COMMAND "@COVERAGE_COMMAND@") + +set(ctest_coverage_args "@CASE_CTEST_COVERAGE_ARGS@") +ctest_start(Experimental) +ctest_configure() +ctest_build() +ctest_test() +ctest_coverage(${ctest_coverage_args}) diff --git a/Tests/RunCMake/CTestMemcheck/CMakeLists.txt.in b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in index d15d148..3b8edf4 100644 --- a/Tests/RunCMake/CTestMemcheck/CMakeLists.txt.in +++ b/Tests/RunCMake/ctest_memcheck/CMakeLists.txt.in @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.8.9) -project(CTestTestMemcheck@SUBTEST_NAME@ NONE) +project(CTestTestMemcheck@CASE_NAME@ NONE) include(CTest) add_test(NAME RunCMake COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/CTestMemcheck/CTestConfig.cmake.in b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in index 19c76c2..6d4a718 100644 --- a/Tests/RunCMake/CTestMemcheck/CTestConfig.cmake.in +++ b/Tests/RunCMake/ctest_memcheck/CTestConfig.cmake.in @@ -1,4 +1,4 @@ -set (CTEST_PROJECT_NAME "CTestTestMemcheck@SUBTEST_NAME@") +set (CTEST_PROJECT_NAME "CTestTestMemcheck@CASE_NAME@") set (CTEST_NIGHTLY_START_TIME "21:00:00 EDT") set (CTEST_DART_SERVER_VERSION "2") set(CTEST_DROP_METHOD "http") diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt new file mode 100644 index 0000000..8fa3f1b --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* diff --git a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt index 1d255d0..1d255d0 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyAddressSanitizer-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyAddressSanitizer-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-result.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyBC-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyBC-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt index 24f536a..24f536a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyBC-stderr.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyBC-stderr.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyBC-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt index 5829613..5829613 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyBC-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyBC-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt new file mode 100644 index 0000000..adc744b --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stderr.txt @@ -0,0 +1,2 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-build/Testing/Temporary/MemoryChecker.1.log +.*Error parsing XML in stream at line 1: no element found diff --git a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt index 5829613..5829613 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyBCNoLogFile-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyBCNoLogFile-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt new file mode 100644 index 0000000..3551043 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* diff --git a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt index 97a8a9b..97a8a9b 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyLeakSanitizer-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizer-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt new file mode 100644 index 0000000..02d5626 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* diff --git a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt index 64390c7..64390c7 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyMemorySanitizer-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyMemorySanitizer-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurify-result.txt b/Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyPurify-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyPurify-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurify-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt index dabb004..dabb004 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyPurify-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyPurify-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt new file mode 100644 index 0000000..653c136 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-build/Testing/Temporary/MemoryChecker.1.log diff --git a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt index 5829613..5829613 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyPurifyNoLogFile-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyPurifyNoLogFile-stdout.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt new file mode 100644 index 0000000..58f55a5 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyQuiet-stdout.txt @@ -0,0 +1 @@ +0 tests failed out of 1$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt new file mode 100644 index 0000000..5f6c6c1 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* diff --git a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt index c3af1f9..c3af1f9 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyThreadSanitizer-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyThreadSanitizer-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-result.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt new file mode 100644 index 0000000..423b7f7 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\* diff --git a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt index b3473bf..b3473bf 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyUndefinedBehaviorSanitizer-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyUndefinedBehaviorSanitizer-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrind-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt index 573541a..573541a 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrind-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrind-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrind-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt index dabb004..dabb004 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrind-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrind-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt new file mode 100644 index 0000000..032b5b4 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-build/Testing/Temporary/MemoryChecker.1.log diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt index dabb004..dabb004 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindCustomOptions-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindCustomOptions-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt index 2d078ef..6f52318 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stderr.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stderr.txt @@ -1,3 +1,2 @@ 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/ctest_memcheck/DummyValgrindFailPost-stdout.txt index dabb004..dabb004 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPost-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPost-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-result.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt index 43ccb2e..973c014 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindFailPre-stderr.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stderr.txt @@ -1,3 +1,2 @@ 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/ctest_memcheck/DummyValgrindFailPre-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt new file mode 100644 index 0000000..8d8b7e9 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/ctest_memcheck/DummyValgrindFailPre-build diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt index 5a5675c..5a5675c 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindIgnoreMemcheck-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindIgnoreMemcheck-stdout.txt diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindInvalidSupFile-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt new file mode 100644 index 0000000..42cd5e8 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stderr.txt @@ -0,0 +1 @@ +Cannot find memory checker suppression file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-build/does-not-exist diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt new file mode 100644 index 0000000..4c58df4 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/ctest_memcheck/DummyValgrindInvalidSupFile-build$ diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-result.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt new file mode 100644 index 0000000..18d9f03 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stderr.txt @@ -0,0 +1 @@ +Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-build/Testing/Temporary/MemoryChecker.1.log diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt index 5829613..5829613 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindNoLogFile-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoLogFile-stdout.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt index dabb004..dabb004 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindPrePost-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindPrePost-stdout.txt diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt index 3e0fdb2..3e0fdb2 100644 --- a/Tests/RunCMake/CTestMemcheck/DummyValgrindTwoTargets-stdout.txt +++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindTwoTargets-stdout.txt diff --git a/Tests/RunCMake/ctest_memcheck/NotExist-result.txt b/Tests/RunCMake/ctest_memcheck/NotExist-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/NotExist-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CTestMemcheck/NotExist-stderr.txt b/Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt index 0af5b7a..0af5b7a 100644 --- a/Tests/RunCMake/CTestMemcheck/NotExist-stderr.txt +++ b/Tests/RunCMake/ctest_memcheck/NotExist-stderr.txt diff --git a/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt b/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt new file mode 100644 index 0000000..0e58936 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/NotExist-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/ctest_memcheck/NotExist-build$ diff --git a/Tests/RunCMake/CTestMemcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake index 6485de8..6c96a26 100644 --- a/Tests/RunCMake/CTestMemcheck/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake @@ -1,23 +1,11 @@ -include(RunCMake) +include(RunCTest) 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} - ) +function(run_mc_test CASE_NAME CHECKER_COMMAND) + run_ctest(${CASE_NAME} ${ARGN}) endfunction() unset(CTEST_EXTRA_CONFIG) @@ -142,3 +130,4 @@ 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}") +run_mc_test(DummyQuiet "${PSEUDO_VALGRIND}" -DMEMCHECK_ARGS=QUIET) diff --git a/Tests/RunCMake/CTestMemcheck/Unknown-result.txt b/Tests/RunCMake/ctest_memcheck/Unknown-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestMemcheck/Unknown-result.txt +++ b/Tests/RunCMake/ctest_memcheck/Unknown-result.txt diff --git a/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt b/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt new file mode 100644 index 0000000..8868e0c --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/Unknown-stderr.txt @@ -0,0 +1 @@ +Do not understand memory checker: .*/cmake.* diff --git a/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt b/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt new file mode 100644 index 0000000..0208e80 --- /dev/null +++ b/Tests/RunCMake/ctest_memcheck/Unknown-stdout.txt @@ -0,0 +1 @@ +Memory check project .*/Tests/RunCMake/ctest_memcheck/Unknown-build$ diff --git a/Tests/RunCMake/CTestMemcheck/test.cmake.in b/Tests/RunCMake/ctest_memcheck/test.cmake.in index 622d709..8431fa6 100644 --- a/Tests/RunCMake/CTestMemcheck/test.cmake.in +++ b/Tests/RunCMake/ctest_memcheck/test.cmake.in @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 2.8.9) # Settings: set(CTEST_SITE "@SITE@") -set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Memcheck@SUBTEST_NAME@") +set(CTEST_BUILD_NAME "CTestTest-@BUILDNAME@-Memcheck@CASE_NAME@") -set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@SUBTEST_NAME@") -set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@SUBTEST_NAME@-build") +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@") @@ -21,4 +21,4 @@ set(CTEST_MEMORYCHECK_TYPE "${MEMCHECK_TYPE}") CTEST_START(Experimental) CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) -CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) +CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res ${MEMCHECK_ARGS}) diff --git a/Tests/RunCMake/CTestMemcheck/testAddressSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake index 3082e4b..3082e4b 100644 --- a/Tests/RunCMake/CTestMemcheck/testAddressSanitizer.cmake +++ b/Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake diff --git a/Tests/RunCMake/CTestMemcheck/testLeakSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake index 02030be..02030be 100644 --- a/Tests/RunCMake/CTestMemcheck/testLeakSanitizer.cmake +++ b/Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake diff --git a/Tests/RunCMake/CTestMemcheck/testMemorySanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake index c87af9a..c87af9a 100644 --- a/Tests/RunCMake/CTestMemcheck/testMemorySanitizer.cmake +++ b/Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake diff --git a/Tests/RunCMake/CTestMemcheck/testThreadSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake index d591931..d591931 100644 --- a/Tests/RunCMake/CTestMemcheck/testThreadSanitizer.cmake +++ b/Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake diff --git a/Tests/RunCMake/CTestMemcheck/testUndefinedBehaviorSanitizer.cmake b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake index 8ef3c0a..8ef3c0a 100644 --- a/Tests/RunCMake/CTestMemcheck/testUndefinedBehaviorSanitizer.cmake +++ b/Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake diff --git a/Tests/RunCMake/ctest_start/CMakeLists.txt.in b/Tests/RunCMake/ctest_start/CMakeLists.txt.in new file mode 100644 index 0000000..913239c --- /dev/null +++ b/Tests/RunCMake/ctest_start/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestStart@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_start/CTestConfig.cmake.in b/Tests/RunCMake/ctest_start/CTestConfig.cmake.in new file mode 100644 index 0000000..e75d14f --- /dev/null +++ b/Tests/RunCMake/ctest_start/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestStart@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_start/RunCMakeTest.cmake b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake new file mode 100644 index 0000000..f765a0f --- /dev/null +++ b/Tests/RunCMake/ctest_start/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_START_ARGS "") + +function(run_ctest_start CASE_NAME) + set(CASE_CTEST_START_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_start(StartQuiet Experimental QUIET) diff --git a/Tests/RunCMake/project/CMP0048-NEW-stderr.txt b/Tests/RunCMake/ctest_start/StartQuiet-stdout.txt index 10f3293..10f3293 100644 --- a/Tests/RunCMake/project/CMP0048-NEW-stderr.txt +++ b/Tests/RunCMake/ctest_start/StartQuiet-stdout.txt diff --git a/Tests/RunCMake/ctest_start/test.cmake.in b/Tests/RunCMake/ctest_start/test.cmake.in new file mode 100644 index 0000000..21e3fad --- /dev/null +++ b/Tests/RunCMake/ctest_start/test.cmake.in @@ -0,0 +1,13 @@ +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}") + +set(ctest_start_args "@CASE_CTEST_START_ARGS@") +ctest_start(${ctest_start_args}) diff --git a/Tests/RunCMake/CTestSubmit/BadArg-result.txt b/Tests/RunCMake/ctest_submit/BadArg-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/BadArg-result.txt +++ b/Tests/RunCMake/ctest_submit/BadArg-result.txt diff --git a/Tests/RunCMake/ctest_submit/BadArg-stderr.txt b/Tests/RunCMake/ctest_submit/BadArg-stderr.txt new file mode 100644 index 0000000..7eeef0a --- /dev/null +++ b/Tests/RunCMake/ctest_submit/BadArg-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/BadFILES-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/BadFILES-result.txt +++ b/Tests/RunCMake/ctest_submit/BadFILES-result.txt diff --git a/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt b/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt new file mode 100644 index 0000000..ab84ab9 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/BadFILES-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/BadPARTS-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/BadPARTS-result.txt +++ b/Tests/RunCMake/ctest_submit/BadPARTS-result.txt diff --git a/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt b/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt new file mode 100644 index 0000000..3db54f3 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/BadPARTS-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/BadPARTS/test.cmake:[0-9]+ \(ctest_submit\): + Part name "bad-part" is invalid. diff --git a/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-result.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/RepeatRETURN_VALUE-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt new file mode 100644 index 0000000..adf334b --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stderr.txt @@ -0,0 +1,3 @@ + *Error when uploading file: .*/Configure.xml + *Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?|The requested URL returned error:.*) + *Problems when submitting via HTTP diff --git a/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt new file mode 100644 index 0000000..cd42c9a --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashSubmitQuiet-stdout.txt @@ -0,0 +1,3 @@ +Configure project + Each . represents 1024 bytes of output + . Size of output: 0K$ diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadFILES-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadFILES-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt new file mode 100644 index 0000000..0106fee --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadFILES-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/CDashUploadFTP-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadFTP-result.txt diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt index 77df44f..77df44f 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadFTP-stderr.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadFTP-stderr.txt diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadNone-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadNone-result.txt diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt index af95b5c..af95b5c 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadNone-stderr.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadNone-stderr.txt diff --git a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadPARTS-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt new file mode 100644 index 0000000..fe94cb7 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadPARTS-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/CDashUploadRETRY_COUNT-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_COUNT-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt new file mode 100644 index 0000000..21621d4 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_COUNT-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/CDashUploadRETRY_DELAY-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/CDashUploadRETRY_DELAY-result.txt +++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-result.txt diff --git a/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt new file mode 100644 index 0000000..f726674 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/CDashUploadRETRY_DELAY-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/CMakeLists.txt.in index 96e6c13..96e6c13 100644 --- a/Tests/RunCMake/CTestSubmit/CMakeLists.txt.in +++ b/Tests/RunCMake/ctest_submit/CMakeLists.txt.in diff --git a/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in index 378a85a..378a85a 100644 --- a/Tests/RunCMake/CTestSubmit/CTestConfig.cmake.in +++ b/Tests/RunCMake/ctest_submit/CTestConfig.cmake.in diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-cp-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-result.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt index b451315..00a60ac 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stderr.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-stderr.txt @@ -1,4 +1,3 @@ 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/ctest_submit/FailDrop-cp-stdout.txt index fa6e004..fa6e004 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-cp-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-cp-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-result.txt diff --git a/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt new file mode 100644 index 0000000..64c3011 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stderr.txt @@ -0,0 +1,2 @@ +Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?|The requested URL returned error:.*) + Problems when submitting via FTP diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt index 345bb62..345bb62 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-ftp-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-ftp-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-http-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-http-result.txt diff --git a/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt new file mode 100644 index 0000000..73f0138 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stderr.txt @@ -0,0 +1,2 @@ +Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?|The requested URL returned error:.*) + Problems when submitting via HTTP diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt index c7f35c5..c7f35c5 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-http-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-http-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-https-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-https-result.txt diff --git a/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt new file mode 100644 index 0000000..a1ba4f6 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stderr.txt @@ -0,0 +1,2 @@ +Error message was: ([Cc]ould *n.t resolve host:? '?-no-site-'?|The requested URL returned error:.*|Protocol "https" not supported or disabled in .*|.* was built with SSL disabled.*) + Problems when submitting via HTTP diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt index 19f8234..19f8234 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-https-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-https-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-scp-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-result.txt diff --git a/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt new file mode 100644 index 0000000..ef67149 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-stderr.txt @@ -0,0 +1 @@ + Problems when submitting via SCP diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt b/Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt index ec2ce92..ec2ce92 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-scp-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-scp-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-result.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-result.txt diff --git a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt index 020b615..c0f718e 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stderr.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stderr.txt @@ -1,2 +1 @@ (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/ctest_submit/FailDrop-xmlrpc-stdout.txt index ed2acb5..ed2acb5 100644 --- a/Tests/RunCMake/CTestSubmit/FailDrop-xmlrpc-stdout.txt +++ b/Tests/RunCMake/ctest_submit/FailDrop-xmlrpc-stdout.txt diff --git a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/PARTSCDashUpload-result.txt +++ b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-result.txt diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt new file mode 100644 index 0000000..ad4c8cb --- /dev/null +++ b/Tests/RunCMake/ctest_submit/PARTSCDashUpload-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/PARTSCDashUploadType-result.txt index b57e2de..b57e2de 100644 --- a/Tests/RunCMake/CTestSubmit/PARTSCDashUploadType-result.txt +++ b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-result.txt diff --git a/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt new file mode 100644 index 0000000..8d8a852 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/PARTSCDashUploadType-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/PARTSCDashUploadType/test.cmake:[0-9]+ \(ctest_submit\): + Part name "CDASH_UPLOAD_TYPE" is invalid. diff --git a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt new file mode 100644 index 0000000..b57e2de --- /dev/null +++ b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-result.txt @@ -0,0 +1 @@ +(-1|255) diff --git a/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt new file mode 100644 index 0000000..6e17c75 --- /dev/null +++ b/Tests/RunCMake/ctest_submit/RepeatRETURN_VALUE-stderr.txt @@ -0,0 +1,2 @@ +CMake Error at .*/Tests/RunCMake/ctest_submit/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/ctest_submit/RunCMakeTest.cmake index 797365d..a81bc96 100644 --- a/Tests/RunCMake/CTestSubmit/RunCMakeTest.cmake +++ b/Tests/RunCMake/ctest_submit/RunCMakeTest.cmake @@ -1,26 +1,10 @@ -include(RunCMake) +include(RunCTest) # 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. @@ -40,6 +24,7 @@ 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) +run_ctest_submit(CDashSubmitQuiet QUIET) function(run_ctest_CDashUploadFTP) set(CASE_DROP_METHOD ftp) diff --git a/Tests/RunCMake/CTestSubmit/test.cmake.in b/Tests/RunCMake/ctest_submit/test.cmake.in index ba826f1..ba826f1 100644 --- a/Tests/RunCMake/CTestSubmit/test.cmake.in +++ b/Tests/RunCMake/ctest_submit/test.cmake.in diff --git a/Tests/RunCMake/ctest_test/CMakeLists.txt.in b/Tests/RunCMake/ctest_test/CMakeLists.txt.in new file mode 100644 index 0000000..cedf379 --- /dev/null +++ b/Tests/RunCMake/ctest_test/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestTest@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_test/CTestConfig.cmake.in b/Tests/RunCMake/ctest_test/CTestConfig.cmake.in new file mode 100644 index 0000000..9004419 --- /dev/null +++ b/Tests/RunCMake/ctest_test/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestTest@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake new file mode 100644 index 0000000..d906290 --- /dev/null +++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_TEST_ARGS "") + +function(run_ctest_test CASE_NAME) + set(CASE_CTEST_TEST_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_test(TestQuiet QUIET) diff --git a/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt b/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt new file mode 100644 index 0000000..14613c5 --- /dev/null +++ b/Tests/RunCMake/ctest_test/TestQuiet-stdout.txt @@ -0,0 +1,2 @@ + 0 Compiler warnings + Start 1: RunCMakeVersion diff --git a/Tests/RunCMake/ctest_test/test.cmake.in b/Tests/RunCMake/ctest_test/test.cmake.in new file mode 100644 index 0000000..1350abe --- /dev/null +++ b/Tests/RunCMake/ctest_test/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}") + +set(ctest_test_args "@CASE_CTEST_TEST_ARGS@") +ctest_start(Experimental) +ctest_configure() +ctest_build() +ctest_test(${ctest_test_args}) diff --git a/Tests/RunCMake/ctest_upload/CMakeLists.txt.in b/Tests/RunCMake/ctest_upload/CMakeLists.txt.in new file mode 100644 index 0000000..1fab71b --- /dev/null +++ b/Tests/RunCMake/ctest_upload/CMakeLists.txt.in @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.1) +project(CTestUpload@CASE_NAME@ NONE) +include(CTest) +add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version) diff --git a/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in b/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in new file mode 100644 index 0000000..52665a8 --- /dev/null +++ b/Tests/RunCMake/ctest_upload/CTestConfig.cmake.in @@ -0,0 +1 @@ +set(CTEST_PROJECT_NAME "CTestUpload@CASE_NAME@") diff --git a/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake b/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake new file mode 100644 index 0000000..b33d278 --- /dev/null +++ b/Tests/RunCMake/ctest_upload/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCTest) + +set(CASE_CTEST_UPLOAD_ARGS "") + +function(run_ctest_upload CASE_NAME) + set(CASE_CTEST_UPLOAD_ARGS "${ARGN}") + run_ctest(${CASE_NAME}) +endfunction() + +run_ctest_upload(UploadQuiet QUIET) diff --git a/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt b/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt new file mode 100644 index 0000000..20e13b8 --- /dev/null +++ b/Tests/RunCMake/ctest_upload/UploadQuiet-stdout.txt @@ -0,0 +1 @@ +Use Experimental tag: [0-9-]+$ diff --git a/Tests/RunCMake/ctest_upload/test.cmake.in b/Tests/RunCMake/ctest_upload/test.cmake.in new file mode 100644 index 0000000..f13bdd1 --- /dev/null +++ b/Tests/RunCMake/ctest_upload/test.cmake.in @@ -0,0 +1,14 @@ +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}") + +set(ctest_upload_args "@CASE_CTEST_UPLOAD_ARGS@") +ctest_start(Experimental) +ctest_upload(FILES "${CTEST_SOURCE_DIRECTORY}/CMakeLists.txt" ${ctest_upload_args}) diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt new file mode 100644 index 0000000..9629cfd --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg-stderr.txt @@ -0,0 +1 @@ +.*file LIST_DIRECTORIES missing bool value\. diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake new file mode 100644 index 0000000..a8e15f2 --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-no-arg.cmake @@ -0,0 +1 @@ +file(GLOB CONTENT_LIST LIST_DIRECTORIES) diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt new file mode 100644 index 0000000..9629cfd --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean-stderr.txt @@ -0,0 +1 @@ +.*file LIST_DIRECTORIES missing bool value\. diff --git a/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake new file mode 100644 index 0000000..f735433 --- /dev/null +++ b/Tests/RunCMake/file/GLOB-error-LIST_DIRECTORIES-not-boolean.cmake @@ -0,0 +1 @@ +file(GLOB CONTENT_LIST LIST_DIRECTORIES 13) diff --git a/Tests/RunCMake/file/GLOB-stderr.txt b/Tests/RunCMake/file/GLOB-stderr.txt new file mode 100644 index 0000000..c47dc40 --- /dev/null +++ b/Tests/RunCMake/file/GLOB-stderr.txt @@ -0,0 +1,6 @@ +content: 6[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir +content: 6[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir +content: 2[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 2/dir 2 file diff --git a/Tests/RunCMake/file/GLOB.cmake b/Tests/RunCMake/file/GLOB.cmake new file mode 100644 index 0000000..3d577e3 --- /dev/null +++ b/Tests/RunCMake/file/GLOB.cmake @@ -0,0 +1,28 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/dir 1 file" "test file") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir/dir 1 subdir file" "test file") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/dir 2 file" "test file") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir/dir 2 subdir file" "test file") + +file(GLOB CONTENT_LIST "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB CONTENT_LIST LIST_DIRECTORIES true "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB CONTENT_LIST LIST_DIRECTORIES false "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") diff --git a/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt new file mode 100644 index 0000000..f73aa83 --- /dev/null +++ b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion-stderr.txt @@ -0,0 +1,15 @@ +.*Cyclic recursion detected while globbing for.* +.*/test/depth1/depth2/depth3.* +.*/test/depth1/depth2/depth3/recursion.* +content: 4[ ] +.*/test/abc;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink +.*Cyclic recursion detected while globbing for.* +.*/test/depth1/depth2/depth3.* +.*/test/depth1/depth2/depth3/recursion.* +content: 4[ ] +.*/test/abc;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink +.*Cyclic recursion detected while globbing for.* +.*/test/depth1/depth2/depth3.* +.*/test/depth1/depth2/depth3/recursion.* +content: 11[ ] +.*/test/abc;.*/test/depth1;.*/test/depth1/depth2;.*/test/depth1/depth2/depth3;.*/test/depth1/depth2/depth3/file_symlink;.*/test/depth1/depth2/depth3/recursion;.*/test/depth1/depth2/depth3/recursion/abc;.*/test/depth1/depth2/depth3/recursion/depth1;.*/test/depth1/depth2/depth3/recursion/depth1/depth2;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3;.*/test/depth1/depth2/depth3/recursion/depth1/depth2/depth3/file_symlink diff --git a/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake new file mode 100644 index 0000000..a8c6784 --- /dev/null +++ b/Tests/RunCMake/file/GLOB_RECURSE-cyclic-recursion.cmake @@ -0,0 +1,23 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3") +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/test" "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3/recursion") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/abc" "message to write") +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_CURRENT_BINARY_DIR}/test/abc" "${CMAKE_CURRENT_BINARY_DIR}/test/depth1/depth2/depth3/file_symlink") + +file(GLOB_RECURSE CONTENT_LIST FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES false FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES true FOLLOW_SYMLINKS "${CMAKE_CURRENT_BINARY_DIR}/test/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") diff --git a/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt b/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt new file mode 100644 index 0000000..5d48e47 --- /dev/null +++ b/Tests/RunCMake/file/GLOB_RECURSE-stderr.txt @@ -0,0 +1,6 @@ +content: 4[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/non_empty_dir/dir 2 subdir file +content: 4[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/non_empty_dir/dir 2 subdir file +content: 8[ ] +.*/test/dir 1/dir 1 file;.*/test/dir 1/empty_dir;.*/test/dir 1/non_empty_dir;.*/test/dir 1/non_empty_dir/dir 1 subdir file;.*/test/dir 2/dir 2 file;.*/test/dir 2/empty_dir;.*/test/dir 2/non_empty_dir;.*/test/dir 2/non_empty_dir/dir 2 subdir file diff --git a/Tests/RunCMake/file/GLOB_RECURSE.cmake b/Tests/RunCMake/file/GLOB_RECURSE.cmake new file mode 100644 index 0000000..6db377b --- /dev/null +++ b/Tests/RunCMake/file/GLOB_RECURSE.cmake @@ -0,0 +1,28 @@ +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/empty_dir") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/dir 1 file" "test file") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 1/non_empty_dir/dir 1 subdir file" "test file") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/dir 2 file" "test file") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test/dir 2/non_empty_dir/dir 2 subdir file" "test file") + +file(GLOB_RECURSE CONTENT_LIST "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES false "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") + +file(GLOB_RECURSE CONTENT_LIST LIST_DIRECTORIES true "${CMAKE_CURRENT_BINARY_DIR}/test/*/*") +list(LENGTH CONTENT_LIST CONTENT_COUNT) +message("content: ${CONTENT_COUNT} ") +list(SORT CONTENT_LIST) +message("${CONTENT_LIST}") diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake index 14819e7..d3dfb1b 100644 --- a/Tests/RunCMake/file/RunCMakeTest.cmake +++ b/Tests/RunCMake/file/RunCMakeTest.cmake @@ -17,3 +17,13 @@ run_cmake(LOCK-error-no-result-variable) run_cmake(LOCK-error-no-timeout) run_cmake(LOCK-error-timeout) run_cmake(LOCK-error-unknown-option) +run_cmake(GLOB) +run_cmake(GLOB_RECURSE) +# test is valid both for GLOB and GLOB_RECURSE +run_cmake(GLOB-error-LIST_DIRECTORIES-not-boolean) +# test is valid both for GLOB and GLOB_RECURSE +run_cmake(GLOB-error-LIST_DIRECTORIES-no-arg) + +if(NOT WIN32 OR CYGWIN) + run_cmake(GLOB_RECURSE-cyclic-recursion) +endif() diff --git a/Tests/RunCMake/find_file/CMakeLists.txt b/Tests/RunCMake/find_file/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/find_file/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_file/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_file/PrefixInPATH-stdout.txt new file mode 100644 index 0000000..d73bc1d --- /dev/null +++ b/Tests/RunCMake/find_file/PrefixInPATH-stdout.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_file/include/PrefixInPATH.h' diff --git a/Tests/RunCMake/find_file/PrefixInPATH.cmake b/Tests/RunCMake/find_file/PrefixInPATH.cmake new file mode 100644 index 0000000..1e33c08 --- /dev/null +++ b/Tests/RunCMake/find_file/PrefixInPATH.cmake @@ -0,0 +1,8 @@ +set(ENV_PATH "$ENV{PATH}") +foreach(path "/does_not_exist" "" "/bin" "/sbin") + unset(PrefixInPATH_INCLUDE_DIR CACHE) + set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}") + find_file(PrefixInPATH_INCLUDE_DIR NAMES PrefixInPATH.h) + message(STATUS "PrefixInPATH_INCLUDE_DIR='${PrefixInPATH_INCLUDE_DIR}'") +endforeach() +set(ENV{PATH} "${ENV_PATH}") diff --git a/Tests/RunCMake/find_file/RunCMakeTest.cmake b/Tests/RunCMake/find_file/RunCMakeTest.cmake new file mode 100644 index 0000000..014f397 --- /dev/null +++ b/Tests/RunCMake/find_file/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(PrefixInPATH) diff --git a/Tests/RunCMake/find_file/include/PrefixInPATH.h b/Tests/RunCMake/find_file/include/PrefixInPATH.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_file/include/PrefixInPATH.h diff --git a/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt new file mode 100644 index 0000000..1ab884c --- /dev/null +++ b/Tests/RunCMake/find_library/PrefixInPATH-stdout.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_LIBRARY='PrefixInPATH_LIBRARY-NOTFOUND' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' +-- PrefixInPATH_LIBRARY='.*/Tests/RunCMake/find_library/lib/libPrefixInPATH.a' diff --git a/Tests/RunCMake/find_library/PrefixInPATH.cmake b/Tests/RunCMake/find_library/PrefixInPATH.cmake new file mode 100644 index 0000000..f1b8b18 --- /dev/null +++ b/Tests/RunCMake/find_library/PrefixInPATH.cmake @@ -0,0 +1,11 @@ +list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib) +list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a) + +set(ENV_PATH "$ENV{PATH}") +foreach(path "/does_not_exist" "" "/bin" "/sbin") + unset(PrefixInPATH_LIBRARY CACHE) + set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}") + find_library(PrefixInPATH_LIBRARY NAMES PrefixInPATH) + message(STATUS "PrefixInPATH_LIBRARY='${PrefixInPATH_LIBRARY}'") +endforeach() +set(ENV{PATH} "${ENV_PATH}") diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake index 4000679..136031c 100644 --- a/Tests/RunCMake/find_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake @@ -1,3 +1,4 @@ include(RunCMake) run_cmake(Created) +run_cmake(PrefixInPATH) diff --git a/Tests/RunCMake/find_library/lib/libPrefixInPATH.a b/Tests/RunCMake/find_library/lib/libPrefixInPATH.a new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_library/lib/libPrefixInPATH.a diff --git a/Tests/RunCMake/find_path/CMakeLists.txt b/Tests/RunCMake/find_path/CMakeLists.txt new file mode 100644 index 0000000..ef2163c --- /dev/null +++ b/Tests/RunCMake/find_path/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_path/PrefixInPATH-stdout.txt b/Tests/RunCMake/find_path/PrefixInPATH-stdout.txt new file mode 100644 index 0000000..bb2ceb7 --- /dev/null +++ b/Tests/RunCMake/find_path/PrefixInPATH-stdout.txt @@ -0,0 +1,4 @@ +-- PrefixInPATH_INCLUDE_DIR='PrefixInPATH_INCLUDE_DIR-NOTFOUND' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' +-- PrefixInPATH_INCLUDE_DIR='.*/Tests/RunCMake/find_path/include' diff --git a/Tests/RunCMake/find_path/PrefixInPATH.cmake b/Tests/RunCMake/find_path/PrefixInPATH.cmake new file mode 100644 index 0000000..614d64f --- /dev/null +++ b/Tests/RunCMake/find_path/PrefixInPATH.cmake @@ -0,0 +1,8 @@ +set(ENV_PATH "$ENV{PATH}") +foreach(path "/does_not_exist" "" "/bin" "/sbin") + unset(PrefixInPATH_INCLUDE_DIR CACHE) + set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}") + find_path(PrefixInPATH_INCLUDE_DIR NAMES PrefixInPATH.h) + message(STATUS "PrefixInPATH_INCLUDE_DIR='${PrefixInPATH_INCLUDE_DIR}'") +endforeach() +set(ENV{PATH} "${ENV_PATH}") diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake new file mode 100644 index 0000000..014f397 --- /dev/null +++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake @@ -0,0 +1,3 @@ +include(RunCMake) + +run_cmake(PrefixInPATH) diff --git a/Tests/RunCMake/find_path/include/PrefixInPATH.h b/Tests/RunCMake/find_path/include/PrefixInPATH.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/find_path/include/PrefixInPATH.h diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-stderr.txt b/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake deleted file mode 100644 index 67ee7de..0000000 --- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake +++ /dev/null @@ -1,11 +0,0 @@ - -enable_language(CXX) - -add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") -target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/foo") - -install(TARGETS testTarget EXPORT testTargets - DESTINATION lib -) - -install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/include_directories/CMakeLists.txt b/Tests/RunCMake/include_directories/CMakeLists.txt index 5cd4825..2897109 100644 --- a/Tests/RunCMake/include_directories/CMakeLists.txt +++ b/Tests/RunCMake/include_directories/CMakeLists.txt @@ -1,6 +1,3 @@ cmake_minimum_required(VERSION 3.0) project(${RunCMake_TEST} NONE) -if(NOT TEST_FILE) - set(TEST_FILE ${RunCMake_TEST}.cmake) -endif() -include(${TEST_FILE}) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/include_directories/DirInInstallPrefix-stderr.txt b/Tests/RunCMake/include_directories/DirInInstallPrefix-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/DirInInstallPrefix-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/DirInInstallPrefix.cmake b/Tests/RunCMake/include_directories/DirInInstallPrefix.cmake deleted file mode 100644 index fab7717..0000000 --- a/Tests/RunCMake/include_directories/DirInInstallPrefix.cmake +++ /dev/null @@ -1,9 +0,0 @@ -enable_language(CXX) -add_library(testTarget empty.cpp) -target_include_directories(testTarget INTERFACE "${CMAKE_INSTALL_PREFIX}/dir") - -install(TARGETS testTarget EXPORT testTargets - DESTINATION lib -) - -install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/include_directories/InstallPrefixInInterface-stderr.txt b/Tests/RunCMake/include_directories/InstallPrefixInInterface-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/InstallPrefixInInterface-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-stderr.txt b/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-stderr.txt b/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/RelativePathInGenex.cmake b/Tests/RunCMake/include_directories/RelativePathInGenex.cmake deleted file mode 100644 index 070a381..0000000 --- a/Tests/RunCMake/include_directories/RelativePathInGenex.cmake +++ /dev/null @@ -1,8 +0,0 @@ - -enable_language(CXX) - -add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") -set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<1:foo>") - -add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") -target_link_libraries(userTarget testTarget) diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake b/Tests/RunCMake/include_directories/RelativePathInInterface.cmake deleted file mode 100644 index 4c4727d..0000000 --- a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake +++ /dev/null @@ -1,11 +0,0 @@ - -enable_language(CXX) - -add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") -set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo") - -install(TARGETS testTarget EXPORT testTargets - DESTINATION lib -) - -install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake index fa76f24..3f624f8 100644 --- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake +++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake @@ -3,148 +3,7 @@ include(RunCMake) run_cmake(NotFoundContent) run_cmake(DebugIncludes) run_cmake(TID-bad-target) -run_cmake(SourceDirectoryInInterface) -run_cmake(BinaryDirectoryInInterface) -run_cmake(RelativePathInInterface) run_cmake(ImportedTarget) -run_cmake(RelativePathInGenex) run_cmake(CMP0021) run_cmake(install_config) run_cmake(incomplete-genex) -run_cmake(export-NOWARN) - -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/DirInInstallPrefix/prefix") -run_cmake(DirInInstallPrefix) - -configure_file( - "${RunCMake_SOURCE_DIR}/CMakeLists.txt" - "${RunCMake_BINARY_DIR}/copy/CMakeLists.txt" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/empty.cpp" - "${RunCMake_BINARY_DIR}/copy/empty.cpp" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake" - "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake" - COPYONLY -) -set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix" - "-DTEST_FILE=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake" - ) -set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy") -run_cmake(InstallInSrcDir) -unset(RunCMake_TEST_SOURCE_DIR) - -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix") -set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix" - "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" - ) -set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/InstallInBinDir-build") -run_cmake(InstallInBinDir) -unset(RunCMake_TEST_BINARY_DIR) - -configure_file( - "${RunCMake_SOURCE_DIR}/CMakeLists.txt" - "${RunCMake_BINARY_DIR}/prefix/src/CMakeLists.txt" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/empty.cpp" - "${RunCMake_BINARY_DIR}/prefix/src/empty.cpp" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake" - "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake" - COPYONLY -) - -foreach(policyStatus "" NEW OLD) - if (NOT "${policyStatus}" STREQUAL "") - set(policyOption -DCMAKE_POLICY_DEFAULT_CMP0052=${policyStatus}) - else() - unset(policyOption) - set(policyStatus WARN) - endif() - set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption} - "-DTEST_FILE=${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface.cmake" - ) - # Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run - # the test suite in-source properly. Otherwise the install directory would be - # a subdirectory or the source directory, which is allowed and tested separately - # below. - set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/prefix/src") - set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/prefix/BinInInstallPrefix-CMP0052-${policyStatus}-build") - run_cmake(BinInInstallPrefix-CMP0052-${policyStatus}) - unset(RunCMake_TEST_BINARY_DIR) - - set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption} - "-DTEST_FILE=${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake" - ) - run_cmake(SrcInInstallPrefix-CMP0052-${policyStatus}) - unset(RunCMake_TEST_SOURCE_DIR) -endforeach() - -set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallPrefixInInterface-build/prefix") -run_cmake(InstallPrefixInInterface) - -configure_file( - "${RunCMake_SOURCE_DIR}/CMakeLists.txt" - "${RunCMake_BINARY_DIR}/installToSrc/CMakeLists.txt" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/empty.cpp" - "${RunCMake_BINARY_DIR}/installToSrc/empty.cpp" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake" - "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake" - COPYONLY -) -set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface/prefix" - "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake" - ) -set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrc") -run_cmake(InstallToPrefixInSrcDirOutOfSource) -unset(RunCMake_TEST_SOURCE_DIR) - - -file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/installToSrcInSrc") -set(RunCMake_TEST_NO_CLEAN ON) - -configure_file( - "${RunCMake_SOURCE_DIR}/CMakeLists.txt" - "${RunCMake_BINARY_DIR}/installToSrcInSrc/CMakeLists.txt" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/empty.cpp" - "${RunCMake_BINARY_DIR}/installToSrcInSrc/empty.cpp" - COPYONLY -) -configure_file( - "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake" - "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake" - COPYONLY -) - -set(RunCMake_TEST_OPTIONS - "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface/prefix" - "-DTEST_FILE=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake" - ) -set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc") -set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc") -run_cmake(InstallToPrefixInSrcDirInSource) -unset(RunCMake_TEST_SOURCE_DIR) -unset(RunCMake_TEST_BINARY_DIR) -unset(RunCMake_TEST_NO_CLEAN) diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake deleted file mode 100644 index f814a3c..0000000 --- a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake +++ /dev/null @@ -1,11 +0,0 @@ - -enable_language(CXX) - -add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp") -target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/foo") - -install(TARGETS testTarget EXPORT testTargets - DESTINATION lib -) - -install(EXPORT testTargets DESTINATION lib/cmake) diff --git a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-stderr.txt b/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/include_directories/export-NOWARN-stderr.txt b/Tests/RunCMake/include_directories/export-NOWARN-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/include_directories/export-NOWARN-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index 53b91f3..7149603 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -6,3 +6,4 @@ run_cmake(DIRECTORY-message-lazy) run_cmake(SkipInstallRulesWarning) run_cmake(SkipInstallRulesNoWarning1) run_cmake(SkipInstallRulesNoWarning2) +run_cmake(TARGETS-DESTINATION-bad) diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning1-stderr.txt b/Tests/RunCMake/install/SkipInstallRulesNoWarning1-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/install/SkipInstallRulesNoWarning1-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/install/SkipInstallRulesNoWarning2-stderr.txt b/Tests/RunCMake/install/SkipInstallRulesNoWarning2-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/install/SkipInstallRulesNoWarning2-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt new file mode 100644 index 0000000..9844158 --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$<NOTAGENEX> + + Expression did not evaluate to a known generator expression diff --git a/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake b/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake new file mode 100644 index 0000000..feff52df --- /dev/null +++ b/Tests/RunCMake/install/TARGETS-DESTINATION-bad.cmake @@ -0,0 +1,3 @@ +enable_language(C) +add_library(empty empty.c) +install(TARGETS empty DESTINATION $<NOTAGENEX>) diff --git a/Tests/RunCMake/install/empty.c b/Tests/RunCMake/install/empty.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/install/empty.c diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake index 08e81c6..201daa7 100644 --- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/interface_library/RunCMakeTest.cmake @@ -7,5 +7,4 @@ run_cmake(whitelist) run_cmake(invalid_signature) run_cmake(global-interface) run_cmake(genex_link) -run_cmake(add_dependencies) run_cmake(add_custom_command-TARGET) diff --git a/Tests/RunCMake/interface_library/add_dependencies-stderr.txt b/Tests/RunCMake/interface_library/add_dependencies-stderr.txt deleted file mode 100644 index c550b68..0000000 --- a/Tests/RunCMake/interface_library/add_dependencies-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Error at add_dependencies.cmake:4 \(add_dependencies\): - add_dependencies Cannot add target-level dependencies to INTERFACE library - target "iface". - -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/interface_library/add_dependencies.cmake b/Tests/RunCMake/interface_library/add_dependencies.cmake deleted file mode 100644 index 12cdfb4..0000000 --- a/Tests/RunCMake/interface_library/add_dependencies.cmake +++ /dev/null @@ -1,4 +0,0 @@ - -add_library(foo empty.cpp) -add_library(iface INTERFACE) -add_dependencies(iface foo) diff --git a/Tests/RunCMake/interface_library/genex_link-stderr.txt b/Tests/RunCMake/interface_library/genex_link-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/interface_library/genex_link-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/interface_library/no_shared_libs-stderr.txt b/Tests/RunCMake/interface_library/no_shared_libs-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/interface_library/no_shared_libs-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/message/nomessage-stderr.txt b/Tests/RunCMake/message/nomessage-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/message/nomessage-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/RunCMake/no_install_prefix/with_install_prefix-stderr.txt b/Tests/RunCMake/no_install_prefix/with_install_prefix-stderr.txt deleted file mode 100644 index 10f3293..0000000 --- a/Tests/RunCMake/no_install_prefix/with_install_prefix-stderr.txt +++ /dev/null @@ -1 +0,0 @@ -^$ diff --git a/Tests/XCTest/CMakeLists.txt b/Tests/XCTest/CMakeLists.txt new file mode 100644 index 0000000..e866623 --- /dev/null +++ b/Tests/XCTest/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.1) +project(XCTest) +enable_testing() + +find_package(XCTest REQUIRED) + +# Framework + +add_library(FrameworkExample SHARED + FrameworkExample/FrameworkExample.c + FrameworkExample/FrameworkExample.h + FrameworkExample/Info.plist) + +target_include_directories(FrameworkExample PUBLIC .) + +set_target_properties(FrameworkExample PROPERTIES + FRAMEWORK TRUE + VERSION "1.0.0" + SOVERSION "1.0.0" + FRAMEWORK_VERSION "A" + MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/FrameworkExample/Info.plist + PUBLIC_HEADER FrameworkExample/FrameworkExample.h) + +# XCTest for Framework + +xctest_add_bundle(FrameworkExampleTests FrameworkExample + FrameworkExampleTests/FrameworkExampleTests.m + FrameworkExampleTests/Info.plist) + +set_target_properties(FrameworkExampleTests PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/FrameworkExampleTests/Info.plist + ) + +xctest_add_test(XCTest.FrameworkExample FrameworkExampleTests) + +# Cocoa App Bundle + +add_executable(CocoaExample MACOSX_BUNDLE + CocoaExample/main.m + CocoaExample/AppDelegate.m + CocoaExample/AppDelegate.h + CocoaExample/MainMenu.xib +) + +target_link_libraries(CocoaExample PRIVATE "-framework Foundation") +target_link_libraries(CocoaExample PRIVATE "-framework AppKit") + +set_target_properties(CocoaExample PROPERTIES + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/CocoaExample/Info.plist + RESOURCE "CocoaExample/MainMenu.xib") + +# XCTest for Cocoa App Bundle + +xctest_add_bundle(CocoaExampleTests CocoaExample + CocoaExampleTests/CocoaExampleTests.m) + +xctest_add_test(XCTest.CocoaExample CocoaExampleTests) diff --git a/Tests/XCTest/CocoaExample/AppDelegate.h b/Tests/XCTest/CocoaExample/AppDelegate.h new file mode 100644 index 0000000..4bf4101 --- /dev/null +++ b/Tests/XCTest/CocoaExample/AppDelegate.h @@ -0,0 +1,6 @@ +#import <Cocoa/Cocoa.h> + +@interface AppDelegate : NSObject <NSApplicationDelegate> + + +@end diff --git a/Tests/XCTest/CocoaExample/AppDelegate.m b/Tests/XCTest/CocoaExample/AppDelegate.m new file mode 100644 index 0000000..07af62f --- /dev/null +++ b/Tests/XCTest/CocoaExample/AppDelegate.m @@ -0,0 +1,18 @@ +#import "AppDelegate.h" + +@interface AppDelegate () + +@property (assign) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/Tests/XCTest/CocoaExample/Info.plist b/Tests/XCTest/CocoaExample/Info.plist new file mode 100644 index 0000000..5267c63 --- /dev/null +++ b/Tests/XCTest/CocoaExample/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>CocoaExample</string> + <key>CFBundleIconFile</key> + <string></string> + <key>CFBundleIdentifier</key> + <string>org.cmake.CocoaExample</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>CocoaExample</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> + <key>NSMainNibFile</key> + <string>MainMenu</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/Tests/XCTest/CocoaExample/MainMenu.xib b/Tests/XCTest/CocoaExample/MainMenu.xib new file mode 100644 index 0000000..9498a0a --- /dev/null +++ b/Tests/XCTest/CocoaExample/MainMenu.xib @@ -0,0 +1,680 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6233" systemVersion="14A329f" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> + <dependencies> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6233"/> + </dependencies> + <objects> + <customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> + <connections> + <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/> + </connections> + </customObject> + <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/> + <customObject id="-3" userLabel="Application" customClass="NSObject"/> + <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider=""> + <connections> + <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/> + </connections> + </customObject> + <customObject id="YLy-65-1bz" customClass="NSFontManager"/> + <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> + <items> + <menuItem title="CocoaExample" id="1Xt-HY-uBw"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="CocoaExample" systemMenu="apple" id="uQy-DD-JDr"> + <items> + <menuItem title="About CocoaExample" id="5kV-Vb-QxS"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/> + <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/> + <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/> + <menuItem title="Services" id="NMo-om-nkz"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/> + </menuItem> + <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/> + <menuItem title="Hide CocoaExample" keyEquivalent="h" id="Olw-nP-bQN"> + <connections> + <action selector="hide:" target="-1" id="PnN-Uc-m68"/> + </connections> + </menuItem> + <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/> + </connections> + </menuItem> + <menuItem title="Show All" id="Kd2-mp-pUS"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/> + <menuItem title="Quit CocoaExample" keyEquivalent="q" id="4sb-4s-VLi"> + <connections> + <action selector="terminate:" target="-1" id="Te7-pn-YzF"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="File" id="dMs-cI-mzQ"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="File" id="bib-Uj-vzu"> + <items> + <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl"> + <connections> + <action selector="newDocument:" target="-1" id="4Si-XN-c54"/> + </connections> + </menuItem> + <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9"> + <connections> + <action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/> + </connections> + </menuItem> + <menuItem title="Open Recent" id="tXI-mr-wws"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ"> + <items> + <menuItem title="Clear Menu" id="vNY-rz-j42"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/> + <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG"> + <connections> + <action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/> + </connections> + </menuItem> + <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV"> + <connections> + <action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/> + </connections> + </menuItem> + <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A"> + <connections> + <action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/> + </connections> + </menuItem> + <menuItem title="Revert to Saved" id="KaW-ft-85H"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/> + <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK"> + <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/> + <connections> + <action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/> + </connections> + </menuItem> + <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS"> + <connections> + <action selector="print:" target="-1" id="qaZ-4w-aoO"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Edit" id="5QF-Oa-p0T"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Edit" id="W48-6f-4Dl"> + <items> + <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg"> + <connections> + <action selector="undo:" target="-1" id="M6e-cu-g7V"/> + </connections> + </menuItem> + <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam"> + <connections> + <action selector="redo:" target="-1" id="oIA-Rs-6OD"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/> + <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG"> + <connections> + <action selector="cut:" target="-1" id="YJe-68-I9s"/> + </connections> + </menuItem> + <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU"> + <connections> + <action selector="copy:" target="-1" id="G1f-GL-Joy"/> + </connections> + </menuItem> + <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL"> + <connections> + <action selector="paste:" target="-1" id="UvS-8e-Qdg"/> + </connections> + </menuItem> + <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/> + </connections> + </menuItem> + <menuItem title="Delete" id="pa3-QI-u2k"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/> + </connections> + </menuItem> + <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m"> + <connections> + <action selector="selectAll:" target="-1" id="VNm-Mi-diN"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/> + <menuItem title="Find" id="4EN-yA-p0u"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Find" id="1b7-l0-nxx"> + <items> + <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W"> + <connections> + <action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/> + </connections> + </menuItem> + <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/> + </connections> + </menuItem> + <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye"> + <connections> + <action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/> + </connections> + </menuItem> + <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV"> + <connections> + <action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/> + </connections> + </menuItem> + <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt"> + <connections> + <action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/> + </connections> + </menuItem> + <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd"> + <connections> + <action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Spelling" id="3IN-sU-3Bg"> + <items> + <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI"> + <connections> + <action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/> + </connections> + </menuItem> + <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7"> + <connections> + <action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/> + <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/> + </connections> + </menuItem> + <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/> + </connections> + </menuItem> + <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Substitutions" id="9ic-FL-obx"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Substitutions" id="FeM-D8-WVr"> + <items> + <menuItem title="Show Substitutions" id="z6F-FW-3nz"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/> + <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/> + </connections> + </menuItem> + <menuItem title="Smart Quotes" id="hQb-2v-fYv"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/> + </connections> + </menuItem> + <menuItem title="Smart Dashes" id="rgM-f4-ycn"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/> + </connections> + </menuItem> + <menuItem title="Smart Links" id="cwL-P1-jid"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/> + </connections> + </menuItem> + <menuItem title="Data Detectors" id="tRr-pd-1PS"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/> + </connections> + </menuItem> + <menuItem title="Text Replacement" id="HFQ-gK-NFA"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Transformations" id="2oI-Rn-ZJC"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Transformations" id="c8a-y6-VQd"> + <items> + <menuItem title="Make Upper Case" id="vmV-6d-7jI"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/> + </connections> + </menuItem> + <menuItem title="Make Lower Case" id="d9M-CD-aMd"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/> + </connections> + </menuItem> + <menuItem title="Capitalize" id="UEZ-Bs-lqG"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Speech" id="xrE-MZ-jX0"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Speech" id="3rS-ZA-NoH"> + <items> + <menuItem title="Start Speaking" id="Ynk-f8-cLZ"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/> + </connections> + </menuItem> + <menuItem title="Stop Speaking" id="Oyz-dy-DGm"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Format" id="jxT-CU-nIS"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Format" id="GEO-Iw-cKr"> + <items> + <menuItem title="Font" id="Gi5-1S-RQB"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq"> + <items> + <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq"> + <connections> + <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/> + </connections> + </menuItem> + <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27"> + <connections> + <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/> + </connections> + </menuItem> + <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq"> + <connections> + <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/> + </connections> + </menuItem> + <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S"> + <connections> + <action selector="underline:" target="-1" id="FYS-2b-JAY"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/> + <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL"> + <connections> + <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/> + </connections> + </menuItem> + <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST"> + <connections> + <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/> + <menuItem title="Kern" id="jBQ-r6-VK2"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Kern" id="tlD-Oa-oAM"> + <items> + <menuItem title="Use Default" id="GUa-eO-cwY"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/> + </connections> + </menuItem> + <menuItem title="Use None" id="cDB-IK-hbR"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/> + </connections> + </menuItem> + <menuItem title="Tighten" id="46P-cB-AYj"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/> + </connections> + </menuItem> + <menuItem title="Loosen" id="ogc-rX-tC1"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Ligatures" id="o6e-r0-MWq"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Ligatures" id="w0m-vy-SC9"> + <items> + <menuItem title="Use Default" id="agt-UL-0e3"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/> + </connections> + </menuItem> + <menuItem title="Use None" id="J7y-lM-qPV"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/> + </connections> + </menuItem> + <menuItem title="Use All" id="xQD-1f-W4t"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Baseline" id="OaQ-X3-Vso"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Baseline" id="ijk-EB-dga"> + <items> + <menuItem title="Use Default" id="3Om-Ey-2VK"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="unscript:" target="-1" id="0vZ-95-Ywn"/> + </connections> + </menuItem> + <menuItem title="Superscript" id="Rqc-34-cIF"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="superscript:" target="-1" id="3qV-fo-wpU"/> + </connections> + </menuItem> + <menuItem title="Subscript" id="I0S-gh-46l"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="subscript:" target="-1" id="Q6W-4W-IGz"/> + </connections> + </menuItem> + <menuItem title="Raise" id="2h7-ER-AoG"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/> + </connections> + </menuItem> + <menuItem title="Lower" id="1tx-W0-xDw"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/> + <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk"> + <connections> + <action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/> + <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="copyFont:" target="-1" id="GJO-xA-L4q"/> + </connections> + </menuItem> + <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="pasteFont:" target="-1" id="JfD-CL-leO"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Text" id="Fal-I4-PZk"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Text" id="d9c-me-L2H"> + <items> + <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1"> + <connections> + <action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/> + </connections> + </menuItem> + <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb"> + <connections> + <action selector="alignCenter:" target="-1" id="spX-mk-kcS"/> + </connections> + </menuItem> + <menuItem title="Justify" id="J5U-5w-g23"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="alignJustified:" target="-1" id="ljL-7U-jND"/> + </connections> + </menuItem> + <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4"> + <connections> + <action selector="alignRight:" target="-1" id="r48-bG-YeY"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/> + <menuItem title="Writing Direction" id="H1b-Si-o9J"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd"> + <items> + <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> + <menuItem id="YGs-j5-SAR"> + <string key="title"> Default</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/> + </connections> + </menuItem> + <menuItem id="Lbh-J2-qVU"> + <string key="title"> Left to Right</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/> + </connections> + </menuItem> + <menuItem id="jFq-tB-4Kx"> + <string key="title"> Right to Left</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="swp-gr-a21"/> + <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA"> + <modifierMask key="keyEquivalentModifierMask"/> + </menuItem> + <menuItem id="Nop-cj-93Q"> + <string key="title"> Default</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/> + </connections> + </menuItem> + <menuItem id="BgM-ve-c93"> + <string key="title"> Left to Right</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/> + </connections> + </menuItem> + <menuItem id="RB4-Sm-HuC"> + <string key="title"> Right to Left</string> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/> + <menuItem title="Show Ruler" id="vLm-3I-IUL"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/> + </connections> + </menuItem> + <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5"> + <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> + <connections> + <action selector="copyRuler:" target="-1" id="71i-fW-3W2"/> + </connections> + </menuItem> + <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI"> + <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> + <connections> + <action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="View" id="H8h-7b-M4v"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="View" id="HyV-fh-RgO"> + <items> + <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5"> + <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> + <connections> + <action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/> + </connections> + </menuItem> + <menuItem title="Customize Toolbar…" id="1UK-8n-QPP"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Window" id="aUF-d1-5bR"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo"> + <items> + <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV"> + <connections> + <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/> + </connections> + </menuItem> + <menuItem title="Zoom" id="R4o-n2-Eq4"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="performZoom:" target="-1" id="DIl-cC-cCs"/> + </connections> + </menuItem> + <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/> + <menuItem title="Bring All to Front" id="LE2-aR-0XJ"> + <modifierMask key="keyEquivalentModifierMask"/> + <connections> + <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + <menuItem title="Help" id="wpr-3q-Mcd"> + <modifierMask key="keyEquivalentModifierMask"/> + <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ"> + <items> + <menuItem title="CocoaExample Help" keyEquivalent="?" id="FKE-Sm-Kum"> + <connections> + <action selector="showHelp:" target="-1" id="y7X-2Q-9no"/> + </connections> + </menuItem> + </items> + </menu> + </menuItem> + </items> + </menu> + <window title="CocoaExample" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g"> + <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> + <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> + <rect key="contentRect" x="335" y="390" width="480" height="360"/> + <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1177"/> + <view key="contentView" id="EiT-Mj-1SZ"> + <rect key="frame" x="0.0" y="0.0" width="480" height="360"/> + <autoresizingMask key="autoresizingMask"/> + </view> + </window> + </objects> +</document> diff --git a/Tests/XCTest/CocoaExample/main.m b/Tests/XCTest/CocoaExample/main.m new file mode 100644 index 0000000..8a6799b --- /dev/null +++ b/Tests/XCTest/CocoaExample/main.m @@ -0,0 +1,5 @@ +#import <Cocoa/Cocoa.h> + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m b/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m new file mode 100644 index 0000000..70d61d6 --- /dev/null +++ b/Tests/XCTest/CocoaExampleTests/CocoaExampleTests.m @@ -0,0 +1,13 @@ +#import <XCTest/XCTest.h> + +@interface CocoaExampleTests : XCTestCase + +@end + +@implementation CocoaExampleTests + +- (void)testExample { + XCTAssert(YES, @"Pass"); +} + +@end diff --git a/Tests/XCTest/FrameworkExample/FrameworkExample.c b/Tests/XCTest/FrameworkExample/FrameworkExample.c new file mode 100644 index 0000000..2da78da --- /dev/null +++ b/Tests/XCTest/FrameworkExample/FrameworkExample.c @@ -0,0 +1,6 @@ +#include "FrameworkExample.h" + +int FourtyTwo() +{ + return 42; +} diff --git a/Tests/XCTest/FrameworkExample/FrameworkExample.h b/Tests/XCTest/FrameworkExample/FrameworkExample.h new file mode 100644 index 0000000..2e0b499 --- /dev/null +++ b/Tests/XCTest/FrameworkExample/FrameworkExample.h @@ -0,0 +1 @@ +int FourtyTwo(); diff --git a/Tests/XCTest/FrameworkExample/Info.plist b/Tests/XCTest/FrameworkExample/Info.plist new file mode 100644 index 0000000..a22acea --- /dev/null +++ b/Tests/XCTest/FrameworkExample/Info.plist @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>FrameworkExample</string> + <key>CFBundleIdentifier</key> + <string>org.cmake.FrameworkExample</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>FrameworkExample</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string></string> + <key>NSHumanReadableCopyright</key> + <string></string> + <key>NSPrincipalClass</key> + <string></string> +</dict> +</plist> diff --git a/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m b/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m new file mode 100644 index 0000000..7cba23e --- /dev/null +++ b/Tests/XCTest/FrameworkExampleTests/FrameworkExampleTests.m @@ -0,0 +1,16 @@ +#import <XCTest/XCTest.h> + +#import "FrameworkExample/FrameworkExample.h" + +@interface FrameworkExampleTests : XCTestCase + +@end + +@implementation FrameworkExampleTests + +- (void)testFourtyTwo { + // This is an example of a functional test case. + XCTAssertEqual(42, FourtyTwo()); +} + +@end diff --git a/Tests/XCTest/FrameworkExampleTests/Info.plist b/Tests/XCTest/FrameworkExampleTests/Info.plist new file mode 100644 index 0000000..293921b --- /dev/null +++ b/Tests/XCTest/FrameworkExampleTests/Info.plist @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>en</string> + <key>CFBundleExecutable</key> + <string>FrameworkExampleTests</string> + <key>CFBundleIdentifier</key> + <string>org.cmake.FrameworkExampleTests</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>FrameworkExampleTests</string> + <key>CFBundlePackageType</key> + <string>BNDL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1</string> +</dict> +</plist> diff --git a/Utilities/KWIML/ABI.h.in b/Utilities/KWIML/ABI.h.in index 21c9139..6300ada 100644 --- a/Utilities/KWIML/ABI.h.in +++ b/Utilities/KWIML/ABI.h.in @@ -432,6 +432,12 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. # define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG # endif +/* Xtensa */ +#elif defined(__XTENSA_EB__) +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG +#elif defined(__XTENSA_EL__) +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE + /* Unknown CPU */ #elif !defined(@KWIML@_ABI_NO_ERROR_ENDIAN) # error "Byte order of target CPU unknown." diff --git a/Utilities/Release/cpack_wix_ui_banner.jpg b/Utilities/Release/cpack_wix_ui_banner.jpg Binary files differnew file mode 100644 index 0000000..8d950a6 --- /dev/null +++ b/Utilities/Release/cpack_wix_ui_banner.jpg diff --git a/Utilities/Release/cpack_wix_ui_dialog.jpg b/Utilities/Release/cpack_wix_ui_dialog.jpg Binary files differnew file mode 100644 index 0000000..bb6fa5b --- /dev/null +++ b/Utilities/Release/cpack_wix_ui_dialog.jpg diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index a58604e..da81752 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -159,7 +159,6 @@ if(SPHINX_HTML) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION ${CMAKE_DOC_DIR} PATTERN .buildinfo EXCLUDE - PATTERN objects.inv EXCLUDE ) endif() @@ -167,7 +166,6 @@ if(SPHINX_SINGLEHTML) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/singlehtml DESTINATION ${CMAKE_DOC_DIR} PATTERN .buildinfo EXCLUDE - PATTERN objects.inv EXCLUDE ) endif() diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 08bdff5..32e4561 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -524,12 +524,18 @@ check_include_file("features.h" HAVE_FEATURES_H) if(NOT UNIX) check_include_file_concat("ws2tcpip.h" HAVE_WS2TCPIP_H) check_include_file_concat("winsock2.h" HAVE_WINSOCK2_H) -endif(NOT UNIX) +else() + set(HAVE_WS2TCPIP_H 0) + set(HAVE_WINSOCK2_H 0) +endif() check_include_file_concat("stdio.h" HAVE_STDIO_H) if(NOT UNIX) check_include_file_concat("windows.h" HAVE_WINDOWS_H) check_include_file_concat("winsock.h" HAVE_WINSOCK_H) -endif(NOT UNIX) +else() + set(HAVE_WINDOWS_H 0) + set(HAVE_WINSOCK_H 0) +endif() check_include_file_concat("inttypes.h" HAVE_INTTYPES_H) check_include_file_concat("sys/filio.h" HAVE_SYS_FILIO_H) diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp index 7f8e6f1..15222d6 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp @@ -27,6 +27,20 @@ # define isfinite finite #endif +// AIX +#if defined(_AIX) +# if !defined(isfinite) +# define isfinite finite +# endif +#endif + +// HP-UX +#if defined(__hpux) +# if !defined(isfinite) +# define isfinite finite +# endif +#endif + // Ancient glibc #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2 # if !defined(isfinite) @@ -267,9 +267,11 @@ CMAKE_CXX_SOURCES="\ cmInstallDirectoryGenerator \ cmGeneratedFileStream \ cmGeneratorTarget \ + cmGeneratorExpressionContext \ cmGeneratorExpressionDAGChecker \ cmGeneratorExpressionEvaluator \ cmGeneratorExpressionLexer \ + cmGeneratorExpressionNode \ cmGeneratorExpressionParser \ cmGeneratorExpression \ cmGlobalGenerator \ @@ -334,13 +336,15 @@ if ${cmake_system_mingw}; then EncodingC \ ProcessWin32 \ String \ - System" + System \ + Terminal" else KWSYS_C_SOURCES="\ EncodingC \ ProcessUNIX \ String \ - System" + System \ + Terminal" fi KWSYS_CXX_SOURCES="\ @@ -363,7 +367,8 @@ KWSYS_FILES="\ String.h \ String.hxx \ System.h \ - SystemTools.hxx" + SystemTools.hxx \ + Terminal.h" KWSYS_IOS_FILES=" fstream \ |