diff options
1134 files changed, 16563 insertions, 7063 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..e979d4f 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() @@ -543,10 +543,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE) "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}") set(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}") # make sure CMAKE_INSTALL_PREFIX ends in / - string(LENGTH "${CMAKE_INSTALL_PREFIX}" LEN) - math(EXPR LEN "${LEN} -1" ) - string(SUBSTRING "${CMAKE_INSTALL_PREFIX}" ${LEN} 1 ENDCH) - if(NOT "${ENDCH}" STREQUAL "/") + if(NOT CMAKE_INSTALL_PREFIX MATCHES "/$") set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/") endif() set(CMAKE_INSTALL_PREFIX diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index f499be1..8a345b0 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -53,6 +53,9 @@ 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 .*/libgcc.a archive's cputype" + "ld: warning: ignoring file .*/libgcc.a, file was built for archive which is not the architecture being linked" + "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 +65,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/set_directory_properties.rst b/Help/command/set_directory_properties.rst index 834013a..e485fce 100644 --- a/Help/command/set_directory_properties.rst +++ b/Help/command/set_directory_properties.rst @@ -7,9 +7,6 @@ Set a property of the directory. set_directory_properties(PROPERTIES prop1 value1 prop2 value2) -Set a property for the current directory and subdirectories. If the -property is not found, CMake will report an error. The properties -include: INCLUDE_DIRECTORIES, LINK_DIRECTORIES, -INCLUDE_REGULAR_EXPRESSION, and ADDITIONAL_MAKE_CLEAN_FILES. -ADDITIONAL_MAKE_CLEAN_FILES is a list of files that will be cleaned as -a part of "make clean" stage. +Set a property for the current directory and subdirectories. See +:ref:`Directory Properties` for the list of properties known +to CMake. diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst index 8ea02a3..b4904e8 100644 --- a/Help/command/set_source_files_properties.rst +++ b/Help/command/set_source_files_properties.rst @@ -10,6 +10,6 @@ Source files can have properties that affect how they are built. [prop2 value2 [...]]) Set properties associated with source files using a key/value paired -list. See properties documentation for those known to CMake. -Unrecognized properties are ignored. Source file properties are -visible only to targets added in the same directory (CMakeLists.txt). +list. See :ref:`Source File Properties` for the list of properties known +to CMake. Source file properties are visible only to targets added +in the same directory (CMakeLists.txt). diff --git a/Help/command/set_tests_properties.rst b/Help/command/set_tests_properties.rst index afac847..3efb165 100644 --- a/Help/command/set_tests_properties.rst +++ b/Help/command/set_tests_properties.rst @@ -8,29 +8,7 @@ Set a property of the tests. set_tests_properties(test1 [test2...] PROPERTIES prop1 value1 prop2 value2) Set a property for the tests. If the test is not found, CMake -will report an error. Generator expressions will be expanded the same -as supported by the test's add_test call. The properties include: - -WILL_FAIL: If set to true, this will invert the pass/fail flag of the -test. - -PASS_REGULAR_EXPRESSION: If set, the test output will be checked -against the specified regular expressions and at least one of the -regular expressions has to match, otherwise the test will fail. - -:: - - Example: PASS_REGULAR_EXPRESSION "TestPassed;All ok" - -FAIL_REGULAR_EXPRESSION: If set, if the output will match to one of -specified regular expressions, the test will fail. - -:: - - Example: FAIL_REGULAR_EXPRESSION "[^a-z]Error;ERROR;Failed" - -Both PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION expect a list -of regular expressions. - -TIMEOUT: Setting this will limit the test runtime to the number of -seconds specified. +will report an error. +:manual:`Generator expressions <cmake-generator-expressions(7)>` will be +expanded the same as supported by the test's :command:`add_test` call. See +:ref:`Test Properties` for the list of properties known to CMake. 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_features.rst b/Help/command/target_compile_features.rst index 29a8b41..b66a4ec 100644 --- a/Help/command/target_compile_features.rst +++ b/Help/command/target_compile_features.rst @@ -29,4 +29,4 @@ Arguments to ``target_compile_features`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-compile-features(7)` manual for -information on compile features. +information on compile features and a list of supported compilers. 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_include_directories.rst b/Help/command/target_include_directories.rst index 1d236ce..30ec2cb 100644 --- a/Help/command/target_include_directories.rst +++ b/Help/command/target_include_directories.rst @@ -55,5 +55,8 @@ installation prefix. For example: $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib ) +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` .. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index e6a82b6..d903d05 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -1,38 +1,113 @@ target_link_libraries --------------------- -Link a target to given libraries. +.. only:: html + + .. contents:: + +Specify libraries or flags to use when linking a given target and/or +its dependents. :ref:`Usage requirements <Target Usage Requirements>` +from linked library targets will be propagated. Usage requirements +of a target's dependencies affect compilation of its own sources. + +Overview +^^^^^^^^ + +This command has several signatures as detailed in subsections below. +All of them have the general form:: + + target_link_libraries(<target> ... <item>... ...) + +The named ``<target>`` must have been created in the current directory by +a command such as :command:`add_executable` or :command:`add_library`. +Repeated calls for the same ``<target>`` append items in the order called. +Each ``<item>`` may be: + +* **A library target name**: The generated link line will have the + full path to the linkable library file associated with the target. + The buildsystem will have a dependency to re-link ``<target>`` if + the library file changes. + + The named target must be created by :command:`add_library` within + the project or as an :ref:`IMPORTED library <Imported Targets>`. + If it is created within the project an ordering dependency will + automatically be added in the build system to make sure the named + library target is up-to-date before the ``<target>`` links. + + If an imported library has the :prop_tgt:`IMPORTED_NO_SONAME` + target property set, CMake may ask the linker to search for + the library instead of using the full path + (e.g. ``/usr/lib/libfoo.so`` becomes ``-lfoo``). + +* **A full path to a library file**: The generated link line will + normally preserve the full path to the file. The buildsystem will + have a dependency to re-link ``<target>`` if the library file changes. + + There are some cases where CMake may ask the linker to search for + the library (e.g. ``/usr/lib/libfoo.so`` becomes ``-lfoo``), such + as when a shared library is detected to have no ``SONAME`` field. + See policy :policy:`CMP0060` for discussion of another case. + + If the library file is in a Mac OSX framework, the ``Headers`` directory + of the framework will also be processed as a + :ref:`usage requirement <Target Usage Requirements>`. This has the same + effect as passing the framework directory as an include directory. + +* **A plain library name**: The generated link line will ask the linker + to search for the library (e.g. ``foo`` becomes ``-lfoo`` or ``foo.lib``). + +* **A link flag**: Item names starting with ``-``, but not ``-l`` or + ``-framework``, are treated as linker flags. Note that such flags will + be treated like any other library link item for purposes of transitive + dependencies, so they are generally safe to specify only as private link + items that will not propagate to dependents. + +* A ``debug``, ``optimized``, or ``general`` keyword immediately followed + by another ``<item>``. The item following such a keyword will be used + only for the corresponding build configuration. The ``debug`` keyword + corresponds to the ``Debug`` configuration (or to configurations named + in the :prop_gbl:`DEBUG_CONFIGURATIONS` global property if it is set). + The ``optimized`` keyword corresponds to all other configurations. The + ``general`` keyword corresponds to all configurations, and is purely + optional. Higher granularity may be achieved for per-configuration + rules by creating and linking to + :ref:`IMPORTED library targets <Imported Targets>`. + +Items containing ``::``, such as ``Foo::Bar``, are assumed to be +:ref:`IMPORTED <Imported Targets>` or :ref:`ALIAS <Alias Targets>` library +target names and will cause an error if no such target exists. +See policy :policy:`CMP0028`. + +Arguments to ``target_link_libraries`` may use "generator expressions" +with the syntax ``$<...>``. Note however, that generator expressions +will not be used in OLD handling of :policy:`CMP0003` or :policy:`CMP0004`. +See the :manual:`cmake-generator-expressions(7)` manual for available +expressions. See the :manual:`cmake-buildsystem(7)` manual for more on +defining buildsystem properties. + +Libraries for a Target and/or its Dependents +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:: + + target_link_libraries(<target> + <PRIVATE|PUBLIC|INTERFACE> <item>... + [<PRIVATE|PUBLIC|INTERFACE> <item>...]...) + +The ``PUBLIC``, ``PRIVATE`` and ``INTERFACE`` keywords can be used to +specify both the link dependencies and the link interface in one command. +Libraries and targets following ``PUBLIC`` are linked to, and are made +part of the link interface. Libraries and targets following ``PRIVATE`` +are linked to, but are not made part of the link interface. Libraries +following ``INTERFACE`` are appended to the link interface and are not +used for linking ``<target>``. + +Libraries for both a Target and its Dependents +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - target_link_libraries(<target> [item1 [item2 [...]]] - [[debug|optimized|general] <item>] ...) - -Specify libraries or flags to use when linking a given target. The -named ``<target>`` must have been created in the current directory by a -command such as :command:`add_executable` or :command:`add_library`. The -remaining arguments specify library names or flags. Repeated calls for -the same ``<target>`` append items in the order called. - -If a library name matches that of another target in the project a -dependency will automatically be added in the build system to make sure -the library being linked is up-to-date before the target links. Item names -starting with ``-``, but not ``-l`` or ``-framework``, are treated as -linker flags. Note that such flags will be treated like any other library -link item for purposes of transitive dependencies, so they are generally -safe to specify only as private link items that will not propagate to -dependents of ``<target>``. - -A ``debug``, ``optimized``, or ``general`` keyword indicates that the -library immediately following it is to be used only for the -corresponding build configuration. The ``debug`` keyword corresponds to -the Debug configuration (or to configurations named in the -:prop_gbl:`DEBUG_CONFIGURATIONS` global property if it is set). The -``optimized`` keyword corresponds to all other configurations. The -``general`` keyword corresponds to all configurations, and is purely -optional (assumed if omitted). Higher granularity may be achieved for -per-configuration rules by creating and linking to -:ref:`IMPORTED library targets <Imported Targets>`. + target_link_libraries(<target> <item>...) Library dependencies are transitive by default with this signature. When this target is linked into another target then the libraries @@ -45,40 +120,34 @@ by setting the property directly. When :policy:`CMP0022` is not set to of this command may set the property making any libraries linked exclusively by this signature private. -CMake will also propagate :ref:`usage requirements <Target Usage Requirements>` -from linked library targets. Usage requirements of dependencies affect -compilation of sources in the ``<target>``. - -.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES` -.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt - -If an ``<item>`` is a library in a Mac OX framework, the ``Headers`` -directory of the framework will also be processed as a -:ref:`usage requirement <Target Usage Requirements>`. This has the same -effect as passing the framework directory as an include directory. - --------------------------------------------------------------------------- +Libraries for a Target and/or its Dependents (Legacy) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: target_link_libraries(<target> - <PRIVATE|PUBLIC|INTERFACE> <lib> ... - [<PRIVATE|PUBLIC|INTERFACE> <lib> ... ] ...]) + <LINK_PRIVATE|LINK_PUBLIC> <lib>... + [<LINK_PRIVATE|LINK_PUBLIC> <lib>...]...) -The ``PUBLIC``, ``PRIVATE`` and ``INTERFACE`` keywords can be used to -specify both the link dependencies and the link interface in one command. -Libraries and targets following ``PUBLIC`` are linked to, and are made -part of the link interface. Libraries and targets following ``PRIVATE`` -are linked to, but are not made part of the link interface. Libraries -following ``INTERFACE`` are appended to the link interface and are not -used for linking ``<target>``. +The ``LINK_PUBLIC`` and ``LINK_PRIVATE`` modes can be used to specify both +the link dependencies and the link interface in one command. + +This signature is for compatibility only. Prefer the ``PUBLIC`` or +``PRIVATE`` keywords instead. + +Libraries and targets following ``LINK_PUBLIC`` are linked to, and are +made part of the :prop_tgt:`INTERFACE_LINK_LIBRARIES`. If policy +:policy:`CMP0022` is not ``NEW``, they are also made part of the +:prop_tgt:`LINK_INTERFACE_LIBRARIES`. Libraries and targets following +``LINK_PRIVATE`` are linked to, but are not made part of the +:prop_tgt:`INTERFACE_LINK_LIBRARIES` (or :prop_tgt:`LINK_INTERFACE_LIBRARIES`). --------------------------------------------------------------------------- +Libraries for Dependents Only (Legacy) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: - target_link_libraries(<target> LINK_INTERFACE_LIBRARIES - [[debug|optimized|general] <lib>] ...) + target_link_libraries(<target> LINK_INTERFACE_LIBRARIES <item>...) The ``LINK_INTERFACE_LIBRARIES`` mode appends the libraries to the :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property instead of using them @@ -102,28 +171,8 @@ is not ``NEW``, they are also appended to the ``general`` (or without any keyword) are treated as if specified for both ``debug`` and ``optimized``. --------------------------------------------------------------------------- - -:: - - target_link_libraries(<target> - <LINK_PRIVATE|LINK_PUBLIC> - [[debug|optimized|general] <lib>] ... - [<LINK_PRIVATE|LINK_PUBLIC> - [[debug|optimized|general] <lib>] ...]) - -The ``LINK_PUBLIC`` and ``LINK_PRIVATE`` modes can be used to specify both -the link dependencies and the link interface in one command. - -This signature is for compatibility only. Prefer the ``PUBLIC`` or -``PRIVATE`` keywords instead. - -Libraries and targets following ``LINK_PUBLIC`` are linked to, and are -made part of the :prop_tgt:`INTERFACE_LINK_LIBRARIES`. If policy -:policy:`CMP0022` is not ``NEW``, they are also made part of the -:prop_tgt:`LINK_INTERFACE_LIBRARIES`. Libraries and targets following -``LINK_PRIVATE`` are linked to, but are not made part of the -:prop_tgt:`INTERFACE_LINK_LIBRARIES` (or :prop_tgt:`LINK_INTERFACE_LIBRARIES`). +Cyclic Dependencies of Static Libraries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The library dependency graph is normally acyclic (a DAG), but in the case of mutually-dependent ``STATIC`` libraries CMake allows the graph to @@ -142,14 +191,14 @@ For example, the code links ``main`` to ``A B A B``. While one repetition is usually sufficient, pathological object file and symbol arrangements can require -more. One may handle such cases by manually repeating the component in -the last ``target_link_libraries`` call. However, if two archives are -really so interdependent they should probably be combined into a single -archive. +more. One may handle such cases by using the +:prop_tgt:`LINK_INTERFACE_MULTIPLICITY` target property or by manually +repeating the component in the last ``target_link_libraries`` call. +However, if two archives are really so interdependent they should probably +be combined into a single archive, perhaps by using :ref:`Object Libraries`. -Arguments to target_link_libraries may use "generator expressions" -with the syntax ``$<...>``. Note however, that generator expressions -will not be used in OLD handling of :policy:`CMP0003` or :policy:`CMP0004`. -See the :manual:`cmake-generator-expressions(7)` manual for available -expressions. See the :manual:`cmake-buildsystem(7)` manual for more on -defining buildsystem properties. +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES` +.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt 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/command/try_run.rst b/Help/command/try_run.rst index 43ee219..e3bd57d 100644 --- a/Help/command/try_run.rst +++ b/Help/command/try_run.rst @@ -73,7 +73,8 @@ When cross compiling, the executable compiled in the first step usually cannot be run on the build host. The ``try_run`` command checks the :variable:`CMAKE_CROSSCOMPILING` variable to detect whether CMake is in cross-compiling mode. If that is the case, it will still try to compile -the executable, but it will not try to run the executable. Instead it +the executable, but it will not try to run the executable unless the +:variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable is set. Instead it will create cache variables which must be filled by the user or by presetting them in some CMake script file to the values the executable would have produced if it had been run on its actual target platform. 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/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt index 33f7183..a54d728 100644 --- a/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt +++ b/Help/include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt @@ -1,30 +1,18 @@ Note that it is not advisable to populate the ``INSTALL_INTERFACE`` of the -|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies. -That would hard-code into installed packages the include directory paths -for dependencies **as found on the machine the package was made on**. +|INTERFACE_PROPERTY_LINK| of a target with absolute paths to the include +directories of dependencies. That would hard-code into installed packages +the include directory paths for dependencies +**as found on the machine the package was made on**. The ``INSTALL_INTERFACE`` of the |INTERFACE_PROPERTY_LINK| is only -suitable for specifying the required include directories of the target itself, -not its dependencies. +suitable for specifying the required include directories for headers +provided with the target itself, not those provided by the transitive +dependencies listed in its :prop_tgt:`INTERFACE_LINK_LIBRARIES` target +property. Those dependencies should themselves be targets that specify +their own header locations in |INTERFACE_PROPERTY_LINK|. -That is, code like this is incorrect for targets which will be used to -generate :manual:`cmake-packages(7)`: - -.. code-block:: cmake - - target_include_directories(mylib INTERFACE - $<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}> - ) - -Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` -which have their own |INTERFACE_PROPERTY_LINK| populated -appropriately. Those :ref:`IMPORTED targets <Imported Targets>` may then be -used with the :command:`target_link_libraries` command for ``mylib``. - -That way, when a consumer uses the installed package, the -consumer will run the appropriate :command:`find_package` command to find -the dependencies on their own machine and populate the -:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See -:ref:`Creating Packages` for more. Note that many modules currently shipped -with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`. +See the :ref:`Creating Relocatable Packages` section of the +:manual:`cmake-packages(7)` manual for discussion of additional care +that must be taken when specifying usage requirements while creating +packages for redistribution. diff --git a/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt index ceefa4d..46e84ac 100644 --- a/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt +++ b/Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt @@ -1,23 +1,10 @@ Note that it is not advisable to populate the -|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies. -That would hard-code into installed packages the include directory paths +|INTERFACE_PROPERTY_LINK| of a target with absolute paths to dependencies. +That would hard-code into installed packages the library file paths for dependencies **as found on the machine the package was made on**. -That is, code like this is incorrect for targets which will be used to -generate :manual:`cmake-packages(7)`: - -.. code-block:: cmake - - target_link_libraries(mylib INTERFACE - ${Boost_LIBRARIES};${OtherDep_LIBRARIES} - ) - -Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` -which have their own :prop_tgt:`IMPORTED_LOCATION` populated -appropriately. That way, when a consumer uses the installed package, the -consumer will run the appropriate :command:`find_package` command to find -the dependencies on their own machine and populate the -:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See -:ref:`Creating Packages` for more. Note that many modules currently shipped -with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`. +See the :ref:`Creating Relocatable Packages` section of the +:manual:`cmake-packages(7)` manual for discussion of additional care +that must be taken when specifying usage requirements while creating +packages for redistribution. diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt index 363d0aa..e4c5873 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. @@ -35,7 +43,7 @@ CMake may support multiple native build systems on certain platforms. A generator is responsible for generating a particular build system. Possible generator names are specified in the - Generators section. + :manual:`cmake-generators(7)` manual. ``-T <toolset-name>`` Specify toolset name if supported by generator. diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst index 002f2c2..ae5e58e 100644 --- a/Help/manual/cmake-buildsystem.7.rst +++ b/Help/manual/cmake-buildsystem.7.rst @@ -143,6 +143,11 @@ use particular :prop_tgt:`COMPILE_OPTIONS` or the properties must be **requirements**, not merely recommendations or convenience. +See the :ref:`Creating Relocatable Packages` section of the +:manual:`cmake-packages(7)` manual for discussion of additional care +that must be taken when specifying usage requirements while creating +packages for redistribution. + Target Properties ----------------- diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst index 7a6c249..46a5afb 100644 --- a/Help/manual/cmake-compile-features.7.rst +++ b/Help/manual/cmake-compile-features.7.rst @@ -295,3 +295,17 @@ the feature-appropriate include directory add_executable(consumer_no consumer_no.cpp) target_link_libraries(consumer_no foo) + +Supported Compilers +=================== + +CMake is currently aware of the :prop_tgt:`language standards <CXX_STANDARD>` +and :prop_gbl:`compile features <CMAKE_CXX_KNOWN_FEATURES>` available from +the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the +versions specified for each: + +* ``AppleClang``: Apple Clang for Xcode versions 4.4 though 6.2. +* ``Clang``: Clang compiler versions 2.9 through 3.4. +* ``GNU``: GNU compiler versions 4.4 through 5.0. +* ``MSVC``: Microsoft Visual Studio versions 2010 through 2015. +* ``SunPro``: Oracle SolarisStudio version 12.4. diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index e18250c..ab74140 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 ------ @@ -633,6 +605,7 @@ have a .cmake file in this directory NOT show up in the modules documentation, simply leave out the ``Help/module/<module-name>.rst`` file and the ``Help/manual/cmake-modules.7.rst`` toctree entry. +.. _`Find Modules`: Find Modules ------------ diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c47a7c4..189c3ef 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:?[,?]...>`` @@ -92,7 +88,47 @@ Available logical expressions are: increases the required :prop_tgt:`C_STANDARD` or :prop_tgt:`CXX_STANDARD` for the 'head' target, an error is reported. See the :manual:`cmake-compile-features(7)` manual for information on - compile features. + compile features and a list of supported compilers. +``$<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..6f76fb1 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -34,6 +34,11 @@ These generators support command-line build tools. In order to use them, one must launch CMake from a command-line prompt whose environment is already configured for the chosen compiler and build tool. +.. _`Makefile Generators`: + +Makefile Generators +^^^^^^^^^^^^^^^^^^^ + .. toctree:: :maxdepth: 1 @@ -42,10 +47,17 @@ already configured for the chosen compiler and build tool. /generator/MinGW Makefiles /generator/NMake Makefiles /generator/NMake Makefiles JOM - /generator/Ninja /generator/Unix Makefiles /generator/Watcom WMake +Ninja Generator +^^^^^^^^^^^^^^^ + +.. toctree:: + :maxdepth: 1 + + /generator/Ninja + IDE Build Tool Generators ------------------------- @@ -53,6 +65,11 @@ These generators support Integrated Development Environment (IDE) project files. Since the IDEs configure their own environment one may launch CMake from any environment. +.. _`Visual Studio Generators`: + +Visual Studio Generators +^^^^^^^^^^^^^^^^^^^^^^^^ + .. toctree:: :maxdepth: 1 @@ -65,6 +82,13 @@ one may launch CMake from any environment. /generator/Visual Studio 11 2012 /generator/Visual Studio 12 2013 /generator/Visual Studio 14 2015 + +Xcode Generator +^^^^^^^^^^^^^^^ + +.. toctree:: + :maxdepth: 1 + /generator/Xcode Extra Generators @@ -85,3 +109,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-packages.7.rst b/Help/manual/cmake-packages.7.rst index 3367ba4..b9073a5 100644 --- a/Help/manual/cmake-packages.7.rst +++ b/Help/manual/cmake-packages.7.rst @@ -373,38 +373,6 @@ attempt to use version 3 together with version 4. Packages can choose to employ such a pattern if different major versions of the package are designed to be incompatible. -Note that it is not advisable to populate any properties which may contain -paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and -:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevnt to dependencies. -That would hard-code into installed packages the include directory or library -paths for dependencies **as found on the machine the package was made on**. - -That is, code like this is incorrect for targets which will be used to -generate config file packages: - -.. code-block:: cmake - - target_link_libraries(ClimbingStats INTERFACE - ${Boost_LIBRARIES};${OtherDep_LIBRARIES}> - ) - target_include_directories(ClimbingStats INTERFACE - $<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}> - ) - -Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>` -which have their own :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and -:prop_tgt:`IMPORTED_LOCATION` populated appropriately. Those -:ref:`IMPORTED targets <Imported Targets>` may then be -used with the :command:`target_link_libraries` command for ``ClimbingStats``. - -That way, when a consumer uses the installed package, the -consumer will run the appropriate :command:`find_package` command (via the -find_dependency macro described below) to find -the dependencies on their own machine and populate the -:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. Note that -many modules currently shipped with CMake do not currently provide -:ref:`IMPORTED targets <Imported Targets>`. - A ``NAMESPACE`` with double-colons is specified when exporting the targets for installation. This convention of double-colons gives CMake a hint that the name is an :prop_tgt:`IMPORTED` target when it is used by downstreams @@ -418,6 +386,9 @@ directory in the :variable:`CMAKE_INSTALL_PREFIX`. When the ``IMPORTED`` target is used by downsteam, it automatically consumes the entries from that property. +Creating a Package Configuration File +------------------------------------- + In this case, the ``ClimbingStatsConfig.cmake`` file could be as simple as: .. code-block:: cmake @@ -429,44 +400,6 @@ should be provided by the ``ClimbingStats`` package, they should be in a separate file which is installed to the same location as the ``ClimbingStatsConfig.cmake`` file, and included from there. -Packages created by :command:`install(EXPORT)` are designed to be relocatable, -using paths relative to the location of the package itself. When defining -the interface of a target for ``EXPORT``, keep in mind that the include -directories should be specified as relative paths which are relative to the -:variable:`CMAKE_INSTALL_PREFIX`: - -.. code-block:: cmake - - target_include_directories(tgt INTERFACE - # Wrong, not relocatable: - $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName> - ) - - target_include_directories(tgt INTERFACE - # Ok, relocatable: - $<INSTALL_INTERFACE:include/TgtName> - ) - -The ``$<INSTALL_PREFIX>`` -:manual:`generator expression <cmake-generator-expressions(7)>` may be used as -a placeholder for the install prefix without resulting in a non-relocatable -package. This is necessary if complex generator expressions are used: - -.. code-block:: cmake - - target_include_directories(tgt INTERFACE - # Ok, relocatable: - $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>> - ) - -The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets -definition file which is specific to the build-tree, and is not relocatable. -This can similiarly be used with a suitable package configuration file and -package version file to define a package for the build tree which may be used -without installation. Consumers of the build tree can simply ensure that the -:variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the -``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache. - This can also be extended to cover dependencies: .. code-block:: cmake @@ -526,6 +459,111 @@ could not be found because an invalid component was specified. This message variable can be set for any case where the ``_FOUND`` variable is set to ``False``, and will be displayed to the user. +Creating a Package Configuration File for the Build Tree +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets +definition file which is specific to the build-tree, and is not relocatable. +This can similiarly be used with a suitable package configuration file and +package version file to define a package for the build tree which may be used +without installation. Consumers of the build tree can simply ensure that the +:variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the +``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache. + +.. _`Creating Relocatable Packages`: + +Creating Relocatable Packages +----------------------------- + +A relocatable package must not reference absolute paths of files on +the machine where the package is built that will not exist on the +machines where the package may be installed. + +Packages created by :command:`install(EXPORT)` are designed to be relocatable, +using paths relative to the location of the package itself. When defining +the interface of a target for ``EXPORT``, keep in mind that the include +directories should be specified as relative paths which are relative to the +:variable:`CMAKE_INSTALL_PREFIX`: + +.. code-block:: cmake + + target_include_directories(tgt INTERFACE + # Wrong, not relocatable: + $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName> + ) + + target_include_directories(tgt INTERFACE + # Ok, relocatable: + $<INSTALL_INTERFACE:include/TgtName> + ) + +The ``$<INSTALL_PREFIX>`` +:manual:`generator expression <cmake-generator-expressions(7)>` may be used as +a placeholder for the install prefix without resulting in a non-relocatable +package. This is necessary if complex generator expressions are used: + +.. code-block:: cmake + + target_include_directories(tgt INTERFACE + # Ok, relocatable: + $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>> + ) + +This also applies to paths referencing external dependencies. +It is not advisable to populate any properties which may contain +paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and +:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevant to dependencies. +For example, this code may not work well for a relocatable package: + +.. code-block:: cmake + + target_link_libraries(ClimbingStats INTERFACE + ${Foo_LIBRARIES} ${Bar_LIBRARIES} + ) + target_include_directories(ClimbingStats INTERFACE + "$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>" + ) + +The referenced variables may contain the absolute paths to libraries +and include directories **as found on the machine the package was made on**. +This would create a package with hard-coded paths to dependencies and not +suitable for relocation. + +Ideally such dependencies should be used through their own +:ref:`IMPORTED targets <Imported Targets>` that have their own +:prop_tgt:`IMPORTED_LOCATION` and usage requirement properties +such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated +appropriately. Those imported targets may then be used with +the :command:`target_link_libraries` command for ``ClimbingStats``: + +.. code-block:: cmake + + target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar) + +With this approach the package references its external dependencies +only through the names of :ref:`IMPORTED targets <Imported Targets>`. +When a consumer uses the installed package, the consumer will run the +appropriate :command:`find_package` commands (via the ``find_dependency`` +macro described above) to find the dependencies and populate the +imported targets with appropriate paths on their own machine. + +Unfortunately many :manual:`modules <cmake-modules(7)>` shipped with +CMake do not yet provide :ref:`IMPORTED targets <Imported Targets>` +because their development pre-dated this approach. This may improve +incrementally over time. Workarounds to create relocatable packages +using such modules include: + +* When building the package, specify each ``Foo_LIBRARY`` cache + entry as just a library name, e.g. ``-DFoo_LIBRARY=foo``. This + tells the corresponding find module to populate the ``Foo_LIBRARIES`` + with just ``foo`` to ask the linker to search for the library + instead of hard-coding a path. + +* Or, after installing the package content but before creating the + package installation binary for redistribution, manually replace + the absolute paths with placeholders for substitution by the + installation tool when the package is installed. + .. _`Package Registry`: Package Registry diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 96f39e6..aff696d 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -114,3 +114,7 @@ All Policies /policy/CMP0054 /policy/CMP0055 /policy/CMP0056 + /policy/CMP0057 + /policy/CMP0058 + /policy/CMP0059 + /policy/CMP0060 diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 25f989f..02d164b 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -7,6 +7,8 @@ cmake-properties(7) .. contents:: +.. _`Global Properties`: + Properties of Global Scope ========================== @@ -41,6 +43,8 @@ Properties of Global Scope /prop_gbl/TARGET_SUPPORTS_SHARED_LIBS /prop_gbl/USE_FOLDERS +.. _`Directory Properties`: + Properties on Directories ========================= @@ -72,6 +76,8 @@ Properties on Directories /prop_dir/VS_GLOBAL_SECTION_POST_section /prop_dir/VS_GLOBAL_SECTION_PRE_section +.. _`Target Properties`: + Properties on Targets ===================== @@ -113,6 +119,7 @@ Properties on Targets /prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG /prop_tgt/CONFIG_OUTPUT_NAME /prop_tgt/CONFIG_POSTFIX + /prop_tgt/CROSSCOMPILING_EMULATOR /prop_tgt/CXX_EXTENSIONS /prop_tgt/CXX_STANDARD /prop_tgt/CXX_STANDARD_REQUIRED @@ -243,6 +250,9 @@ Properties on Targets /prop_tgt/VS_WINRT_REFERENCES /prop_tgt/WIN32_EXECUTABLE /prop_tgt/XCODE_ATTRIBUTE_an-attribute + /prop_tgt/XCTEST + +.. _`Test Properties`: Properties on Tests =================== @@ -268,6 +278,8 @@ Properties on Tests /prop_test/WILL_FAIL /prop_test/WORKING_DIRECTORY +.. _`Source File Properties`: + Properties on Source Files ========================== @@ -297,10 +309,13 @@ Properties on Source Files /prop_sf/VS_SHADER_FLAGS /prop_sf/VS_SHADER_MODEL /prop_sf/VS_SHADER_TYPE + /prop_sf/VS_XAML_TYPE /prop_sf/WRAP_EXCLUDE /prop_sf/XCODE_EXPLICIT_FILE_TYPE /prop_sf/XCODE_LAST_KNOWN_FILE_TYPE +.. _`Cache Entry Properties`: + Properties on Cache Entries =========================== @@ -314,19 +329,24 @@ Properties on Cache Entries /prop_cache/TYPE /prop_cache/VALUE +.. _`Installed File Properties`: + 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 Deprecated Properties on Directories -===================================== +==================================== .. toctree:: :maxdepth: 1 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index c342dbe..63f704d 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -25,6 +25,7 @@ Variables that Provide Information /variable/CMAKE_CFG_INTDIR /variable/CMAKE_COMMAND /variable/CMAKE_CROSSCOMPILING + /variable/CMAKE_CROSSCOMPILING_EMULATOR /variable/CMAKE_CTEST_COMMAND /variable/CMAKE_CURRENT_BINARY_DIR /variable/CMAKE_CURRENT_LIST_DIR diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index da41bbb..b2f7e9d 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -215,6 +215,10 @@ Available commands are: names start in ``-``. ``--mtime=<date>`` Specify modification time recorded in tarball entries. + ``--format=<format>`` + Specify the format of the archive to be created. + Supported formats are: ``7zip``, ``gnutar``, ``pax``, + ``paxr`` (restricted pax, default), and ``zip``. ``time <command> [<args>...]`` Run command and return elapsed time. 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/policy/CMP0060.rst b/Help/policy/CMP0060.rst new file mode 100644 index 0000000..cc37b1b --- /dev/null +++ b/Help/policy/CMP0060.rst @@ -0,0 +1,63 @@ +CMP0060 +------- + +Link libraries by full path even in implicit directories. + +Policy :policy:`CMP0003` was introduced with the intention of always +linking library files by full path when a full path is given to the +:command:`target_link_libraries` command. However, on some platforms +(e.g. HP-UX) the compiler front-end adds alternative library search paths +for the current architecture (e.g. ``/usr/lib/<arch>`` has alternatives +to libraries in ``/usr/lib`` for the current architecture). +On such platforms the :command:`find_library` may find a library such as +``/usr/lib/libfoo.so`` that does not belong to the current architecture. + +Prior to policy :policy:`CMP0003` projects would still build in such +cases because the incorrect library path would be converted to ``-lfoo`` +on the link line and the linker would find the proper library in the +arch-specific search path provided by the compiler front-end implicitly. +At the time we chose to remain compatible with such projects by always +converting library files found in implicit link directories to ``-lfoo`` +flags to ask the linker to search for them. This approach allowed existing +projects to continue to build while still linking to libraries outside +implicit link directories via full path (such as those in the build tree). + +CMake does allow projects to override this behavior by using an +:ref:`IMPORTED library target <Imported Targets>` with its +:prop_tgt:`IMPORTED_LOCATION` property set to the desired full path to +a library file. In fact, many :ref:`Find Modules` are learning to provide +:ref:`Imported Targets` instead of just the traditional ``Foo_LIBRARIES`` +variable listing library files. However, this makes the link line +generated for a library found by a Find Module depend on whether it +is linked through an imported target or not, which is inconsistent. +Furthermore, this behavior has been a source of confusion because the +generated link line for a library file depends on its location. It is +also problematic for projects trying to link statically because flags +like ``-Wl,-Bstatic -lfoo -Wl,-Bdynamic`` may be used to help the linker +select ``libfoo.a`` instead of ``libfoo.so`` but then leak dynamic linking +to following libraries. (See the :prop_tgt:`LINK_SEARCH_END_STATIC` +target property for a solution typically used for that problem.) + +When the special case for libraries in implicit link directories was first +introduced the list of implicit link directories was simply hard-coded +(e.g. ``/lib``, ``/usr/lib``, and a few others). Since that time, CMake +has learned to detect the implicit link directories used by the compiler +front-end. If necessary, the :command:`find_library` command could be +taught to use this information to help find libraries of the proper +architecture. + +For these reasons, CMake 3.3 and above prefer to drop the special case +and link libraries by full path even when they are in implicit link +directories. Policy ``CMP0060`` provides compatibility for existing +projects. + +The OLD behavior for this policy is to ask the linker to search for +libraries whose full paths are known to be in implicit link directories. +The NEW behavior for this policy is to link libraries by full path even +if they are in implicit link directories. + +This policy was introduced in CMake version 3.3. Unlike most policies, +CMake version |release| does *not* warn by default when this policy +is not set and simply uses OLD behavior. See documentation of the +:variable:`CMAKE_POLICY_WARNING_CMP0060 <CMAKE_POLICY_WARNING_CMP<NNNN>>` +variable to control the warning. diff --git a/Help/prop_dir/COMPILE_OPTIONS.rst b/Help/prop_dir/COMPILE_OPTIONS.rst index 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_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst index 163ae34..3db4f18 100644 --- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst @@ -9,7 +9,7 @@ be listed in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable. The features listed here may be used with the :command:`target_compile_features` command. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. The features known to this version of CMake are: diff --git a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst index 18cd030..a08af00 100644 --- a/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst +++ b/Help/prop_gbl/CMAKE_C_KNOWN_FEATURES.rst @@ -9,7 +9,7 @@ be listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable. The features listed here may be used with the :command:`target_compile_features` command. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. The features known to this version of CMake are: 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_sf/VS_XAML_TYPE.rst b/Help/prop_sf/VS_XAML_TYPE.rst new file mode 100644 index 0000000..e92191d --- /dev/null +++ b/Help/prop_sf/VS_XAML_TYPE.rst @@ -0,0 +1,6 @@ +VS_XAML_TYPE +------------ + +Mark a XAML source file as a different type than the default ``Page``. +The most common usage would be to set the default App.xaml file as +ApplicationDefinition. diff --git a/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst b/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst index b02d17d..facf902 100644 --- a/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst +++ b/Help/prop_test/FAIL_REGULAR_EXPRESSION.rst @@ -4,5 +4,12 @@ FAIL_REGULAR_EXPRESSION If the output matches this regular expression the test will fail. If set, if the output matches one of specified regular expressions, -the test will fail.For example: FAIL_REGULAR_EXPRESSION -"[^a-z]Error;ERROR;Failed" +the test will fail. Example: + +.. code-block:: cmake + + set_tests_properties(mytest PROPERTIES + FAIL_REGULAR_EXPRESSION "[^a-z]Error;ERROR;Failed" + ) + +``FAIL_REGULAR_EXPRESSION`` expects a list of regular expressions. diff --git a/Help/prop_test/PASS_REGULAR_EXPRESSION.rst b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst index bb35f77..0cd6215 100644 --- a/Help/prop_test/PASS_REGULAR_EXPRESSION.rst +++ b/Help/prop_test/PASS_REGULAR_EXPRESSION.rst @@ -5,4 +5,12 @@ The output must match this regular expression for the test to pass. If set, the test output will be checked against the specified regular expressions and at least one of the regular expressions has to match, -otherwise the test will fail. +otherwise the test will fail. Example: + +.. code-block:: cmake + + set_tests_properties(mytest PROPERTIES + PASS_REGULAR_EXPRESSION "TestPassed;All ok" + ) + +``PASS_REGULAR_EXPRESSION`` expects a list of regular expressions. diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst index 225ffee..195215e 100644 --- a/Help/prop_tgt/COMPILE_FEATURES.rst +++ b/Help/prop_tgt/COMPILE_FEATURES.rst @@ -9,4 +9,4 @@ in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable. Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-compile-features(7)` manual -for information on compile features. +for information on compile features and a list of supported compilers. 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/CROSSCOMPILING_EMULATOR.rst b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst new file mode 100644 index 0000000..3ef8e03 --- /dev/null +++ b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst @@ -0,0 +1,6 @@ +CROSSCOMPILING_EMULATOR +----------------------- + +Use the given emulator to run executables created when crosscompiling. This +command will be added as a prefix to :command:`add_test` test commands for +built target system executables. diff --git a/Help/prop_tgt/CXX_EXTENSIONS.rst b/Help/prop_tgt/CXX_EXTENSIONS.rst index 67c5cb0..0f547e2 100644 --- a/Help/prop_tgt/CXX_EXTENSIONS.rst +++ b/Help/prop_tgt/CXX_EXTENSIONS.rst @@ -9,7 +9,7 @@ as ``-std=gnu++11`` instead of ``-std=c++11`` to the compile line. This property is ``ON`` by default. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_CXX_EXTENSIONS` variable if it is set when a target diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst index 65b30ec..edc9ba5 100644 --- a/Help/prop_tgt/CXX_STANDARD.rst +++ b/Help/prop_tgt/CXX_STANDARD.rst @@ -24,7 +24,7 @@ flag will not result in an error or warning, but will instead add the with the :prop_tgt:`CXX_STANDARD_REQUIRED` target property. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_CXX_STANDARD` variable if it is set when a target diff --git a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst index 4e24e5e..697d7f6 100644 --- a/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst +++ b/Help/prop_tgt/CXX_STANDARD_REQUIRED.rst @@ -11,7 +11,7 @@ not available. For compilers that have no notion of a standard level, such as MSVC, this has no effect. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_CXX_STANDARD_REQUIRED` variable if it is set when a diff --git a/Help/prop_tgt/C_EXTENSIONS.rst b/Help/prop_tgt/C_EXTENSIONS.rst index dc48cc6..fce67f4 100644 --- a/Help/prop_tgt/C_EXTENSIONS.rst +++ b/Help/prop_tgt/C_EXTENSIONS.rst @@ -9,7 +9,7 @@ as ``-std=gnu11`` instead of ``-std=c11`` to the compile line. This property is ``ON`` by default. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_C_EXTENSIONS` variable if it is set when a target diff --git a/Help/prop_tgt/C_STANDARD.rst b/Help/prop_tgt/C_STANDARD.rst index 3aa74af..5e36821 100644 --- a/Help/prop_tgt/C_STANDARD.rst +++ b/Help/prop_tgt/C_STANDARD.rst @@ -24,7 +24,7 @@ flag will not result in an error or warning, but will instead add the be controlled with the :prop_tgt:`C_STANDARD_REQUIRED` target property. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_C_STANDARD` variable if it is set when a target diff --git a/Help/prop_tgt/C_STANDARD_REQUIRED.rst b/Help/prop_tgt/C_STANDARD_REQUIRED.rst index 743d568..acfad98 100644 --- a/Help/prop_tgt/C_STANDARD_REQUIRED.rst +++ b/Help/prop_tgt/C_STANDARD_REQUIRED.rst @@ -11,7 +11,7 @@ not available. For compilers that have no notion of a standard level, such as MSVC, this has no effect. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. This property is initialized by the value of the :variable:`CMAKE_C_STANDARD_REQUIRED` variable if it is set when a diff --git a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst index 8dfec5f..31b594f 100644 --- a/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst +++ b/Help/prop_tgt/INTERFACE_COMPILE_FEATURES.rst @@ -9,4 +9,4 @@ INTERFACE_COMPILE_FEATURES .. include:: INTERFACE_BUILD_PROPERTY.txt See the :manual:`cmake-compile-features(7)` manual for information on compile -features. +features and a list of supported compilers. diff --git a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst index 1cfd7a8..b1c40b2 100644 --- a/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst +++ b/Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst @@ -22,5 +22,8 @@ installation prefix. For example: $<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib ) +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_INCLUDE_DIRECTORIES`` .. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt diff --git a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst index 55b7b8d..832d12b 100644 --- a/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst +++ b/Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst @@ -17,5 +17,8 @@ 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. +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_LINK_LIBRARIES`` .. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt diff --git a/Help/prop_tgt/INTERFACE_SOURCES.rst b/Help/prop_tgt/INTERFACE_SOURCES.rst index 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/LINK_INTERFACE_LIBRARIES.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst index 2e859eb..2dcf45c 100644 --- a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst @@ -24,5 +24,8 @@ property if policy :policy:`CMP0022` is ``NEW``. This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES` instead. +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES`` .. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt diff --git a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst index 7f2b5dd..22ee5a6 100644 --- a/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst +++ b/Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst @@ -13,5 +13,8 @@ property if policy :policy:`CMP0022` is ``NEW``. This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES` instead. +Creating Relocatable Packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + .. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES_<CONFIG>`` .. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt 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/FindCUDA-StaticRuntime.rst b/Help/release/dev/FindCUDA-StaticRuntime.rst new file mode 100644 index 0000000..112596c --- /dev/null +++ b/Help/release/dev/FindCUDA-StaticRuntime.rst @@ -0,0 +1,7 @@ +FindCUDA-StaticRuntime +---------------------- + +* The :module:`FindCUDA` module now defaults to using the static + CUDA runtime library if it is available. A new + ``CUDA_USE_STATIC_CUDA_RUNTIME`` option is offered to control + this behavior. 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/emulator-property.rst b/Help/release/dev/emulator-property.rst new file mode 100644 index 0000000..1bc2f2d --- /dev/null +++ b/Help/release/dev/emulator-property.rst @@ -0,0 +1,7 @@ +emulator-property +----------------- + +* A :prop_tgt:`CROSSCOMPILING_EMULATOR` target property and supporting + :variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable were introduced + to allow target platform binaries to run on the host during cross + compiling. 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/gcov-module-coverage-exclude.rst b/Help/release/dev/gcov-module-coverage-exclude.rst new file mode 100644 index 0000000..ee4ebae --- /dev/null +++ b/Help/release/dev/gcov-module-coverage-exclude.rst @@ -0,0 +1,6 @@ +gcov-module-coverage-exclude +---------------------------- + +* The :module:`CTestCoverageCollectGCOV` module learned to support + the same ``CTEST_CUSTOM_COVERAGE_EXCLUDE`` option as the + :command:`ctest_coverage` command. 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/link-implicit-libs-full-path.rst b/Help/release/dev/link-implicit-libs-full-path.rst new file mode 100644 index 0000000..7ed7245 --- /dev/null +++ b/Help/release/dev/link-implicit-libs-full-path.rst @@ -0,0 +1,6 @@ +link-implicit-libs-full-path +---------------------------- + +* Linking to library files by a full path in an implicit linker search + directory (e.g. ``/usr/lib/libfoo.a``) no longer asks the linker to + search for the library (e.g. ``-lfoo``). See policy :policy:`CMP0060`. 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/tar-write-format.rst b/Help/release/dev/tar-write-format.rst new file mode 100644 index 0000000..004df21 --- /dev/null +++ b/Help/release/dev/tar-write-format.rst @@ -0,0 +1,6 @@ +tar-write-format +---------------- + +* The :manual:`cmake(1)` ``-E tar`` command learned a new + ``--format<format>`` option to specify the archive format to + be written. 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/vs-xaml.rst b/Help/release/dev/vs-xaml.rst new file mode 100644 index 0000000..575899f --- /dev/null +++ b/Help/release/dev/vs-xaml.rst @@ -0,0 +1,6 @@ +vs-xaml +------- + +* The :ref:`Visual Studio Generators` learned to support ``.xaml`` + source files and automatically associate them with corresponding + ``.h`` and ``.cpp`` sources. 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/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst new file mode 100644 index 0000000..95d2c7f --- /dev/null +++ b/Help/variable/CMAKE_CROSSCOMPILING_EMULATOR.rst @@ -0,0 +1,12 @@ +CMAKE_CROSSCOMPILING_EMULATOR +----------------------------- + +This variable is only used when :variable:`CMAKE_CROSSCOMPILING` is on. It +should point to a command on the host system that can run executable built +for the target system. + +The command will be used to run :command:`try_run` generated executables, +which avoids manual population of the TryRunResults.cmake file. + +It is also used as the default value for the +:prop_tgt:`CROSSCOMPILING_EMULATOR` target property of executables. diff --git a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst index 460c78c..f003227 100644 --- a/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst +++ b/Help/variable/CMAKE_CXX_COMPILE_FEATURES.rst @@ -8,4 +8,4 @@ list is a subset of the features listed in the :prop_gbl:`CMAKE_CXX_KNOWN_FEATUR global property. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_CXX_EXTENSIONS.rst b/Help/variable/CMAKE_CXX_EXTENSIONS.rst index 6448371..b14d753 100644 --- a/Help/variable/CMAKE_CXX_EXTENSIONS.rst +++ b/Help/variable/CMAKE_CXX_EXTENSIONS.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_CXX_STANDARD.rst b/Help/variable/CMAKE_CXX_STANDARD.rst index 963a42a..2bc4525 100644 --- a/Help/variable/CMAKE_CXX_STANDARD.rst +++ b/Help/variable/CMAKE_CXX_STANDARD.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst index f7750fa..14ffcd1 100644 --- a/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst +++ b/Help/variable/CMAKE_CXX_STANDARD_REQUIRED.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst index 1106246..df66eae 100644 --- a/Help/variable/CMAKE_C_COMPILE_FEATURES.rst +++ b/Help/variable/CMAKE_C_COMPILE_FEATURES.rst @@ -8,4 +8,4 @@ list is a subset of the features listed in the :prop_gbl:`CMAKE_C_KNOWN_FEATURES global property. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_C_EXTENSIONS.rst b/Help/variable/CMAKE_C_EXTENSIONS.rst index 5e935fc..25bec12 100644 --- a/Help/variable/CMAKE_C_EXTENSIONS.rst +++ b/Help/variable/CMAKE_C_EXTENSIONS.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_C_STANDARD.rst b/Help/variable/CMAKE_C_STANDARD.rst index 3098ce5..2eb4e43 100644 --- a/Help/variable/CMAKE_C_STANDARD.rst +++ b/Help/variable/CMAKE_C_STANDARD.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst index c24eea4..5e415da 100644 --- a/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst +++ b/Help/variable/CMAKE_C_STANDARD_REQUIRED.rst @@ -8,4 +8,4 @@ property on all targets. See that target property for additional information. See the :manual:`cmake-compile-features(7)` manual for information on -compile features. +compile features and a list of supported compilers. diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst index a83c807..092fe3e 100644 --- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst +++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst @@ -11,6 +11,8 @@ warn by default: policy :policy:`CMP0047`. * ``CMAKE_POLICY_WARNING_CMP0056`` controls the warning for policy :policy:`CMP0056`. +* ``CMAKE_POLICY_WARNING_CMP0060`` controls the warning for + policy :policy:`CMP0060`. This variable should not be set by a project in CMake code. Project developers running CMake may set this variable in their cache to diff --git a/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..6c74cf3 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 @@ -139,8 +147,37 @@ function(ctest_coverage_collect_gcov) \"Binary\": \"${binary_dir}\" }") # collect the gcov files + set(unfiltered_gcov_files) + file(GLOB_RECURSE unfiltered_gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov") + set(gcov_files) - file(GLOB_RECURSE gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov") + foreach(gcov_file ${unfiltered_gcov_files}) + file(STRINGS ${binary_dir}/${gcov_file} first_line LIMIT_COUNT 1 ENCODING UTF-8) + + set(is_excluded false) + if(first_line MATCHES "^ -: 0:Source:(.*)$") + set(source_file ${CMAKE_MATCH_1}) + elseif(NOT GCOV_QUIET) + message(STATUS "Could not determine source file corresponding to: ${gcov_file}") + endif() + + foreach(exclude_entry ${CTEST_CUSTOM_COVERAGE_EXCLUDE}) + if(source_file MATCHES "${exclude_entry}") + set(is_excluded true) + + if(NOT GCOV_QUIET) + message("Excluding coverage for: ${source_file} which matches ${exclude_entry}") + endif() + + break() + endif() + endforeach() + + if(NOT is_excluded) + list(APPEND gcov_files ${gcov_file}) + endif() + endforeach() + # tar up the coverage info with the same date so that the md5 # sum will be the same for the tar file independent of file time # stamps @@ -151,9 +188,17 @@ 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" + "--format=gnutar" --files-from=${coverage_dir}/coverage_file_list.txt WORKING_DIRECTORY ${binary_dir}) endfunction() 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/MSVC-CXX-FeatureTests.cmake b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake index c770211..fcedf3c 100644 --- a/Modules/Compiler/MSVC-CXX-FeatureTests.cmake +++ b/Modules/Compiler/MSVC-CXX-FeatureTests.cmake @@ -16,12 +16,6 @@ set(_cmake_feature_test_cxx_decltype_auto "${MSVC_2015}") # says they will be available in the RTM. set(_cmake_feature_test_cxx_digit_separators "${MSVC_2015}") set(_cmake_feature_test_cxx_func_identifier "${MSVC_2015}") -# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx -# Note 1. While previous version of VisualStudio said they supported these -# they silently produced bad code, and are now marked as having partial -# support in previous versions. The footnote says the support will be complete -# in MSVC 2015, so support the feature for that version, assuming that is true. -set(_cmake_feature_test_cxx_generalized_initializers "${MSVC_2015}") set(_cmake_feature_test_cxx_nonstatic_member_init "${MSVC_2015}") # Microsoft calls this 'rvalue references v3' set(_cmake_feature_test_cxx_defaulted_move_initializers "${MSVC_2015}") @@ -44,6 +38,16 @@ set(_cmake_feature_test_cxx_reference_qualified_functions "${MSVC_2015}") # lists this as 'partial' in 2013 set(_cmake_feature_test_cxx_deleted_functions "${MSVC_2015}") +set(MSVC_2013_v30723 "_MSC_FULL_VER >= 180030723") +# http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx +# Note 1. While previous version of VisualStudio said they supported these +# they silently produced bad code, and are now marked as having partial +# support in previous versions. The footnote says the support will be complete +# in MSVC 2015, so support the feature for that version, assuming that is true. +# The blog post also says that VS 2013 Update 3 generates an error in cases +# that previously produced bad code. +set(_cmake_feature_test_cxx_generalized_initializers "${MSVC_2013_v30723}") + set(MSVC_2013 "_MSC_VER >= 1800") set(_cmake_feature_test_cxx_alias_templates "${MSVC_2013}") # Microsoft now states they support contextual conversions in 2013 and above. @@ -101,6 +105,7 @@ set(_cmake_feature_test_cxx_variadic_macros "${MSVC_2010}") # Unset all the variables that we don't need exposed. # _cmake_oldestSupported is required by WriteCompilerDetectionHeader set(MSVC_2015) +set(MSVC_2013_v30723) set(MSVC_2013) set(MSVC_2012) set(MSVC_2010) 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/FindCUDA.cmake b/Modules/FindCUDA.cmake index 81e1cad..1802e61 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -106,6 +106,18 @@ # CUDA_COMPUTE_SEPARABLE_COMPILATION_OBJECT_FILE_NAME and # CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS should be called. # +# CUDA_SOURCE_PROPERTY_FORMAT +# -- If this source file property is set, it can override the format specified +# to CUDA_WRAP_SRCS (OBJ, PTX, CUBIN, or FATBIN). If an input source file +# is not a .cu file, setting this file will cause it to be treated as a .cu +# file. See documentation for set_source_files_properties on how to set +# this property. +# +# CUDA_USE_STATIC_CUDA_RUNTIME (Default ON) +# -- When enabled the static version of the CUDA runtime library will be used +# in CUDA_LIBRARIES. If the version of CUDA configured doesn't support +# this option, then it will be silently disabled. +# # CUDA_VERBOSE_BUILD (Default OFF) # -- Set to ON to see all the commands used when building the CUDA file. When # using a Makefile generator the value defaults to VERBOSE (run make @@ -272,6 +284,8 @@ # CUDA_CUBLAS_LIBRARIES -- Device or emulation library for the Cuda BLAS # implementation (alterative to: # CUDA_ADD_CUBLAS_TO_TARGET macro). +# CUDA_cudart_static_LIBRARY -- Statically linkable cuda runtime library. +# Only available for CUDA version 5.5+ # CUDA_cupti_LIBRARY -- CUDA Profiling Tools Interface library. # Only available for CUDA version 4.0+. # CUDA_curand_LIBRARY -- CUDA Random Number Generation library. @@ -518,11 +532,12 @@ macro(cuda_unset_include_and_libraries) # This only existed in the 3.0 version of the CUDA toolkit unset(CUDA_CUDARTEMU_LIBRARY CACHE) endif() - unset(CUDA_cupti_LIBRARY CACHE) + unset(CUDA_cudart_static_LIBRARY CACHE) unset(CUDA_cublas_LIBRARY CACHE) unset(CUDA_cublasemu_LIBRARY CACHE) unset(CUDA_cufft_LIBRARY CACHE) unset(CUDA_cufftemu_LIBRARY CACHE) + unset(CUDA_cupti_LIBRARY CACHE) unset(CUDA_curand_LIBRARY CACHE) unset(CUDA_cusolver_LIBRARY CACHE) unset(CUDA_cusparse_LIBRARY CACHE) @@ -532,6 +547,8 @@ macro(cuda_unset_include_and_libraries) unset(CUDA_npps_LIBRARY CACHE) unset(CUDA_nvcuvenc_LIBRARY CACHE) unset(CUDA_nvcuvid_LIBRARY CACHE) + + unset(CUDA_USE_STATIC_CUDA_RUNTIME CACHE) endmacro() # Check to see if the CUDA_TOOLKIT_ROOT_DIR and CUDA_SDK_ROOT_DIR have changed, @@ -539,8 +556,8 @@ endmacro() if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}") unset(CUDA_TOOLKIT_TARGET_DIR CACHE) unset(CUDA_NVCC_EXECUTABLE CACHE) - unset(CUDA_VERSION CACHE) cuda_unset_include_and_libraries() + unset(CUDA_VERSION CACHE) endif() if(NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}") @@ -696,6 +713,53 @@ if(CUDA_VERSION VERSION_EQUAL "3.0") CUDA_CUDARTEMU_LIBRARY ) endif() +if(NOT CUDA_VERSION VERSION_LESS "5.5") + cuda_find_library_local_first(CUDA_cudart_static_LIBRARY cudart_static "static CUDA runtime library") + mark_as_advanced(CUDA_cudart_static_LIBRARY) +endif() +if(CUDA_cudart_static_LIBRARY) + # Set whether to use the static cuda runtime. + option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" ON) +else() + option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" OFF) +endif() + +if(CUDA_USE_STATIC_CUDA_RUNTIME) + if(UNIX) + # Check for the dependent libraries. Here we look for pthreads. + if (DEFINED CMAKE_THREAD_PREFER_PTHREAD) + set(_cuda_cmake_thread_prefer_pthread ${CMAKE_THREAD_PREFER_PTHREAD}) + endif() + set(CMAKE_THREAD_PREFER_PTHREAD 1) + + # Many of the FindXYZ CMake comes with makes use of try_compile with int main(){return 0;} + # as the source file. Unfortunately this causes a warning with -Wstrict-prototypes and + # -Werror causes the try_compile to fail. We will just temporarily disable other flags + # when doing the find_package command here. + set(_cuda_cmake_c_flags ${CMAKE_C_FLAGS}) + set(CMAKE_C_FLAGS "-fPIC") + find_package(Threads REQUIRED) + set(CMAKE_C_FLAGS ${_cuda_cmake_c_flags}) + + if (DEFINED _cuda_cmake_thread_prefer_pthread) + set(CMAKE_THREAD_PREFER_PTHREAD ${_cuda_cmake_thread_prefer_pthread}) + unset(_cuda_cmake_thread_prefer_pthread) + else() + unset(CMAKE_THREAD_PREFER_PTHREAD) + endif() + if (NOT APPLE) + # Here is librt that has things such as, clock_gettime, shm_open, and shm_unlink. + find_library(CUDA_rt_LIBRARY rt) + find_library(CUDA_dl_LIBRARY dl) + if (NOT CUDA_rt_LIBRARY) + message(WARNING "Expecting to find librt for libcudart_static, but didn't find it.") + endif() + if (NOT CUDA_dl_LIBRARY) + message(WARNING "Expecting to find libdl for libcudart_static, but didn't find it.") + endif() + endif() + endif() +endif() # CUPTI library showed up in cuda toolkit 4.0 if(NOT CUDA_VERSION VERSION_LESS "4.0") @@ -703,12 +767,32 @@ if(NOT CUDA_VERSION VERSION_LESS "4.0") mark_as_advanced(CUDA_cupti_LIBRARY) endif() +# Set the CUDA_LIBRARIES variable. This is the set of stuff to link against if you are +# using the CUDA runtime. For the dynamic version of the runtime, most of the +# dependencies are brough in, but for the static version there are additional libraries +# and linker commands needed. +# Initialize to empty +set(CUDA_LIBRARIES) + # If we are using emulation mode and we found the cudartemu library then use # that one instead of cudart. if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY) - set(CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY}) + list(APPEND CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY}) +elseif(CUDA_USE_STATIC_CUDA_RUNTIME AND CUDA_cudart_static_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) + if (CUDA_rt_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_rt_LIBRARY}) + endif() + if (CUDA_dl_LIBRARY) + list(APPEND CUDA_LIBRARIES ${CUDA_dl_LIBRARY}) + endif() + if(APPLE) + # We need to add the default path to the driver (libcuda.dylib) as an rpath, so that + # the static cuda runtime can find it at runtime. + list(APPEND CUDA_LIBRARIES -Wl,-rpath,/usr/local/cuda/lib) + endif() else() - set(CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY}) + list(APPEND CUDA_LIBRARIES ${CUDA_CUDART_LIBRARY}) endif() # 1.1 toolkit on linux doesn't appear to have a separate library on @@ -1184,6 +1268,19 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) set(_cuda_nvcc_flags_config "${_cuda_nvcc_flags_config}\nset(CUDA_NVCC_FLAGS_${config_upper} ${CUDA_NVCC_FLAGS_${config_upper}} ;; ${CUDA_WRAP_OPTION_NVCC_FLAGS_${config_upper}})") endforeach() + # Process the C++11 flag. If the host sets the flag, we need to add it to nvcc and + # remove it from the host. This is because -Xcompile -std=c++ will choke nvcc (it uses + # the C preprocessor). In order to get this to work correctly, we need to use nvcc's + # specific c++11 flag. + if( "${_cuda_host_flags}" MATCHES "-std=c\\+\\+11") + # Add the c++11 flag to nvcc if it isn't already present. Note that we only look at + # the main flag instead of the configuration specific flags. + if( NOT "${CUDA_NVCC_FLAGS}" MATCHES "-std;c\\+\\+11" ) + list(APPEND nvcc_flags --std c++11) + endif() + string(REGEX REPLACE "[-]+std=c\\+\\+11" "" _cuda_host_flags "${_cuda_host_flags}") + endif() + # Get the list of definitions from the directory property get_directory_property(CUDA_NVCC_DEFINITIONS COMPILE_DEFINITIONS) if(CUDA_NVCC_DEFINITIONS) @@ -1204,13 +1301,19 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) foreach(file ${ARGN}) # Ignore any file marked as a HEADER_FILE_ONLY get_source_file_property(_is_header ${file} HEADER_FILE_ONLY) - if(${file} MATCHES "\\.cu$" AND NOT _is_header) + # Allow per source file overrides of the format. Also allows compiling non-.cu files. + get_source_file_property(_cuda_source_format ${file} CUDA_SOURCE_PROPERTY_FORMAT) + if((${file} MATCHES "\\.cu$" OR _cuda_source_format) AND NOT _is_header) - # Allow per source file overrides of the format. - get_source_file_property(_cuda_source_format ${file} CUDA_SOURCE_PROPERTY_FORMAT) if(NOT _cuda_source_format) set(_cuda_source_format ${format}) endif() + # If file isn't a .cu file, we need to tell nvcc to treat it as such. + if(NOT ${file} MATCHES "\\.cu$") + set(cuda_language_flag -x=cu) + else() + set(cuda_language_flag) + endif() if( ${_cuda_source_format} MATCHES "OBJ") set( cuda_compile_to_external_module OFF ) @@ -1223,7 +1326,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files) elseif( ${_cuda_source_format} MATCHES "FATBIN") set( cuda_compile_to_external_module_type "fatbin" ) else() - message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS for file '${file}': '${_cuda_source_format}'. Use OBJ, PTX, CUBIN or FATBIN.") + message( FATAL_ERROR "Invalid format flag passed to CUDA_WRAP_SRCS or set with CUDA_SOURCE_PROPERTY_FORMAT file property for file '${file}': '${_cuda_source_format}'. Use OBJ, PTX, CUBIN or FATBIN.") endif() endif() @@ -1382,10 +1485,10 @@ endmacro() function(_cuda_get_important_host_flags important_flags flag_string) if(CMAKE_GENERATOR MATCHES "Visual Studio") - string(REGEX MATCHALL "/M[DT][d]?" flags ${flag_string}) + string(REGEX MATCHALL "/M[DT][d]?" flags "${flag_string}") list(APPEND ${important_flags} ${flags}) else() - string(REGEX MATCHALL "-fPIC" flags ${flag_string}) + string(REGEX MATCHALL "-fPIC" flags "${flag_string}") list(APPEND ${important_flags} ${flags}) endif() set(${important_flags} ${${important_flags}} PARENT_SCOPE) @@ -1445,14 +1548,14 @@ function(CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS output_file cuda_target options list(APPEND config_specific_flags $<$<CONFIG:${config}>:${f}>) endforeach() set(important_host_flags) - _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}) + _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS_${config_upper}}") foreach(f ${important_host_flags}) list(APPEND flags $<$<CONFIG:${config}>:-Xcompiler> $<$<CONFIG:${config}>:${f}>) endforeach() endforeach() # Add CMAKE_${CUDA_C_OR_CXX}_FLAGS set(important_host_flags) - _cuda_get_important_host_flags(important_host_flags ${CMAKE_${CUDA_C_OR_CXX}_FLAGS}) + _cuda_get_important_host_flags(important_host_flags "${CMAKE_${CUDA_C_OR_CXX}_FLAGS}") foreach(f ${important_host_flags}) list(APPEND flags -Xcompiler ${f}) endforeach() diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake index abdd307..8032309 100644 --- a/Modules/FindCUDA/run_nvcc.cmake +++ b/Modules/FindCUDA/run_nvcc.cmake @@ -75,6 +75,7 @@ set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list set(nvcc_flags @nvcc_flags@) # list set(CUDA_NVCC_INCLUDE_ARGS "@CUDA_NVCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly). set(format_flag "@format_flag@") # string +set(cuda_language_flag @cuda_language_flag@) # list if(build_cubin AND NOT generated_cubin_file) message(FATAL_ERROR "You must specify generated_cubin_file on the command line") @@ -238,6 +239,7 @@ cuda_execute_process( "Generating ${generated_file}" COMMAND "${CUDA_NVCC_EXECUTABLE}" "${source_file}" + ${cuda_language_flag} ${format_flag} -o "${generated_file}" ${CCBIN} ${nvcc_flags} 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..b4beec3 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,1249 @@ # (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 + "R2015a=8.5" + "R2014b=8.4" + "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..7af6da3 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -159,6 +159,8 @@ set(SRCS cmCacheManager.cxx cmCacheManager.h "${CMAKE_CURRENT_BINARY_DIR}/cmCommands.cxx" + cmCLocaleEnvironmentScope.h + cmCLocaleEnvironmentScope.cxx cmCommands.h cmCommandArgumentLexer.cxx cmCommandArgumentParser.cxx @@ -229,6 +231,8 @@ set(SRCS cmExtraKateGenerator.h cmExtraSublimeTextGenerator.cxx cmExtraSublimeTextGenerator.h + cmExtraQbsGenerator.cxx + cmExtraQbsGenerator.h cmFileLock.cxx cmFileLock.h cmFileLockPool.cxx @@ -238,12 +242,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 +528,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 +646,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..f91acbe 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 20150413) +#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/cmCPack7zGenerator.cxx b/Source/CPack/cmCPack7zGenerator.cxx index ce31ad4..2809e56 100644 --- a/Source/CPack/cmCPack7zGenerator.cxx +++ b/Source/CPack/cmCPack7zGenerator.cxx @@ -15,7 +15,7 @@ //---------------------------------------------------------------------- cmCPack7zGenerator::cmCPack7zGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, - cmArchiveWrite::Type7Zip) + "7zip") { } diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index e2437b5..58bd947 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -27,10 +27,10 @@ //---------------------------------------------------------------------- cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t, - cmArchiveWrite::Type at) + std::string const& format) { this->Compress = t; - this->Archive = at; + this->ArchiveFormat = format; } //---------------------------------------------------------------------- @@ -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 ) @@ -100,7 +108,7 @@ if (!GenerateHeader(&gf)) \ << ">." << std::endl); \ return 0; \ } \ -cmArchiveWrite archive(gf,this->Compress, this->Archive); \ +cmArchiveWrite archive(gf,this->Compress, this->ArchiveFormat); \ if (!archive) \ { \ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " \ diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index 6411b1e..16e7632 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -31,7 +31,7 @@ public: /** * Construct generator */ - cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type); + cmCPackArchiveGenerator(cmArchiveWrite::Compress, std::string const& format); virtual ~cmCPackArchiveGenerator(); // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); @@ -68,7 +68,7 @@ protected: int PackageComponentsAllInOne(); virtual const char* GetOutputExtension() = 0; cmArchiveWrite::Compress Compress; - cmArchiveWrite::Type Archive; + std::string ArchiveFormat; }; #endif 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..995eb0d 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); @@ -1505,7 +1499,10 @@ bool cmCPackGenerator::SupportsComponentInstallation() const //---------------------------------------------------------------------- bool cmCPackGenerator::WantsComponentInstallation() const { - return (!IsOn("CPACK_MONOLITHIC_INSTALL") & SupportsComponentInstallation()); + return (!IsOn("CPACK_MONOLITHIC_INSTALL") + && SupportsComponentInstallation() + // check that package at least has components + && !(this->ComponentGroups.empty() || this->Components.empty())); } //---------------------------------------------------------------------- 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/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx index 509c7f8..3fa2b64 100644 --- a/Source/CPack/cmCPackTGZGenerator.cxx +++ b/Source/CPack/cmCPackTGZGenerator.cxx @@ -15,7 +15,7 @@ //---------------------------------------------------------------------- cmCPackTGZGenerator::cmCPackTGZGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, - cmArchiveWrite::TypeTAR) + "paxr") { } diff --git a/Source/CPack/cmCPackTXZGenerator.cxx b/Source/CPack/cmCPackTXZGenerator.cxx index ecfc177..6d4ede1 100644 --- a/Source/CPack/cmCPackTXZGenerator.cxx +++ b/Source/CPack/cmCPackTXZGenerator.cxx @@ -15,7 +15,7 @@ //---------------------------------------------------------------------- cmCPackTXZGenerator::cmCPackTXZGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressXZ, - cmArchiveWrite::TypeTAR) + "paxr") { } diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx index ae73c37..9ff588b 100644 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ b/Source/CPack/cmCPackTarBZip2Generator.cxx @@ -14,7 +14,7 @@ //---------------------------------------------------------------------- cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, - cmArchiveWrite::TypeTAR) + "paxr") { } diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx index df29408..1c8311b 100644 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ b/Source/CPack/cmCPackTarCompressGenerator.cxx @@ -15,7 +15,7 @@ //---------------------------------------------------------------------- cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, - cmArchiveWrite::TypeTAR) + "paxr") { } diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx index e6e4e77..7ef7729 100644 --- a/Source/CPack/cmCPackZIPGenerator.cxx +++ b/Source/CPack/cmCPackZIPGenerator.cxx @@ -15,7 +15,7 @@ //---------------------------------------------------------------------- cmCPackZIPGenerator::cmCPackZIPGenerator() :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, - cmArchiveWrite::TypeZIP) + "zip") { } diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 6106472..00b23cd 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -203,6 +203,9 @@ int main (int argc, char const* const* argv) cmgg.SetCMakeInstance(&cminst); cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator()); cmMakefile* globalMF = cmlg->GetMakefile(); +#if defined(__CYGWIN__) + globalMF->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0"); +#endif bool cpackConfigFileSpecified = true; if ( cpackConfigFile.empty() ) diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index d90aeb7..586070b 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -18,7 +18,6 @@ #include "cmGlobalGenerator.h" #include <cmsys/Process.h> #include "cmCTestTestHandler.h" -#include "cmCacheManager.h" //---------------------------------------------------------------------- cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() @@ -32,8 +31,7 @@ cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler() //---------------------------------------------------------------------- void cmCTestBuildAndTestHandler::Initialize() { - this->BuildTargets.erase( - this->BuildTargets.begin(), this->BuildTargets.end()); + this->BuildTargets.clear(); this->Superclass::Initialize(); } @@ -256,7 +254,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) cm.SetGeneratorToolset(this->BuildGeneratorToolset); // Load the cache to make CMAKE_MAKE_PROGRAM available. - cm.GetCacheManager()->LoadCache(this->BinaryDir); + cm.LoadCache(this->BinaryDir); } else { @@ -311,7 +309,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..10927e7 100644 --- a/Source/CTest/cmCTestUpdateHandler.cxx +++ b/Source/CTest/cmCTestUpdateHandler.cxx @@ -21,6 +21,7 @@ #include "cmGeneratedFileStream.h" #include "cmXMLParser.h" #include "cmXMLSafe.h" +#include "cmCLocaleEnvironmentScope.h" #include "cmCTestVC.h" #include "cmCTestCVS.h" @@ -66,46 +67,6 @@ static const char* cmCTestUpdateHandlerUpdateToString(int type) return cmCTestUpdateHandlerUpdateStrings[type]; } -class cmCTestUpdateHandlerLocale -{ -public: - cmCTestUpdateHandlerLocale(); - ~cmCTestUpdateHandlerLocale(); -private: - std::string saveLCMessages; -}; - -cmCTestUpdateHandlerLocale::cmCTestUpdateHandlerLocale() -{ - const char* lcmess = cmSystemTools::GetEnv("LC_MESSAGES"); - if(lcmess) - { - saveLCMessages = lcmess; - } - // if LC_MESSAGES is not set to C, then - // set it, so that svn/cvs info will be in english ascii - if(! (lcmess && strcmp(lcmess, "C") == 0)) - { - cmSystemTools::PutEnv("LC_MESSAGES=C"); - } -} - -cmCTestUpdateHandlerLocale::~cmCTestUpdateHandlerLocale() -{ - // restore the value of LC_MESSAGES after running the version control - // commands - if(!saveLCMessages.empty()) - { - std::string put = "LC_MESSAGES="; - put += saveLCMessages; - cmSystemTools::PutEnv(put); - } - else - { - cmSystemTools::UnsetEnv("LC_MESSAGES"); - } -} - //---------------------------------------------------------------------- cmCTestUpdateHandler::cmCTestUpdateHandler() { @@ -122,11 +83,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 +118,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 ) { @@ -192,7 +155,7 @@ int cmCTestUpdateHandler::DetermineType(const char* cmd, const char* type) int cmCTestUpdateHandler::ProcessHandler() { // Make sure VCS tool messages are in English so we can parse them. - cmCTestUpdateHandlerLocale fixLocale; + cmCLocaleEnvironmentScope fixLocale; static_cast<void>(fixLocale); // Get source dir @@ -211,18 +174,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 +247,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 +295,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/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx index 682f95f..4f028c4 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx @@ -18,6 +18,9 @@ #include "cmCursesFilePathWidget.h" #include "cmCursesDummyWidget.h" #include "../cmSystemTools.h" +#include "../cmake.h" + +#include <assert.h> cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( const std::string& key, @@ -32,7 +35,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( } cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( - const std::string& key, const cmCacheManager::CacheIterator& it, bool isNew, + const std::string& key, cmake *cm, bool isNew, int labelwidth, int entrywidth) : Key(key), LabelWidth(labelwidth), EntryWidth(entrywidth) { @@ -47,11 +50,13 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( } this->Entry = 0; - switch ( it.GetType() ) + const char* value = cm->GetCacheManager()->GetCacheEntryValue(key); + assert(value); + switch (cm->GetCacheManager()->GetCacheEntryType(key)) { - case cmCacheManager::BOOL: + case cmCacheManager::BOOL: this->Entry = new cmCursesBoolWidget(this->EntryWidth, 1, 1, 1); - if (cmSystemTools::IsOn(it.GetValue().c_str())) + if (cmSystemTools::IsOn(value)) { static_cast<cmCursesBoolWidget*>(this->Entry)->SetValueAsBool(true); } @@ -62,40 +67,40 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite( break; case cmCacheManager::PATH: this->Entry = new cmCursesPathWidget(this->EntryWidth, 1, 1, 1); - static_cast<cmCursesPathWidget*>(this->Entry)->SetString( - it.GetValue()); + static_cast<cmCursesPathWidget*>(this->Entry)->SetString(value); break; case cmCacheManager::FILEPATH: this->Entry = new cmCursesFilePathWidget(this->EntryWidth, 1, 1, 1); - static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString( - it.GetValue()); + static_cast<cmCursesFilePathWidget*>(this->Entry)->SetString(value); break; case cmCacheManager::STRING: - if(it.PropertyExists("STRINGS")) + { + const char* stringsProp = cm->GetCacheManager() + ->GetCacheEntryProperty(key, "STRINGS"); + if(stringsProp) { cmCursesOptionsWidget* ow = new cmCursesOptionsWidget(this->EntryWidth, 1, 1, 1); this->Entry = ow; std::vector<std::string> options; - cmSystemTools::ExpandListArgument( - std::string(it.GetProperty("STRINGS")), options); + cmSystemTools::ExpandListArgument(stringsProp, options); for(std::vector<std::string>::iterator si = options.begin(); si != options.end(); ++si) { ow->AddOption(*si); } - ow->SetOption(it.GetValue()); + ow->SetOption(value); } else { this->Entry = new cmCursesStringWidget(this->EntryWidth, 1, 1, 1); - static_cast<cmCursesStringWidget*>(this->Entry)->SetString( - it.GetValue()); + static_cast<cmCursesStringWidget*>(this->Entry)->SetString(value); } break; + } case cmCacheManager::UNINITIALIZED: cmSystemTools::Error("Found an undefined variable: ", - it.GetName().c_str()); + key.c_str()); break; default: // TODO : put warning message here diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h index 7cdf13b..dc4ee4af 100644 --- a/Source/CursesDialog/cmCursesCacheEntryComposite.h +++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h @@ -21,7 +21,7 @@ public: cmCursesCacheEntryComposite(const std::string& key, int labelwidth, int entrywidth); cmCursesCacheEntryComposite(const std::string& key, - const cmCacheManager::CacheIterator& it, + cmake *cm, bool isNew, int labelwidth, int entrywidth); ~cmCursesCacheEntryComposite(); const char* GetValue(); diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx index dcd0b6c..833d540 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) @@ -110,13 +111,17 @@ void cmCursesMainForm::InitializeUI() // Count non-internal and non-static entries int count=0; - for(cmCacheManager::CacheIterator i = - this->CMakeInstance->GetCacheManager()->NewIterator(); - !i.IsAtEnd(); i.Next()) + std::vector<std::string> cacheKeys = + this->CMakeInstance->GetCacheManager()->GetCacheEntryKeys(); + + for(std::vector<std::string>::const_iterator it = cacheKeys.begin(); + it != cacheKeys.end(); ++it) { - if ( i.GetType() != cmCacheManager::INTERNAL && - i.GetType() != cmCacheManager::STATIC && - i.GetType() != cmCacheManager::UNINITIALIZED) + cmCacheManager::CacheEntryType t = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryType(*it); + if (t != cmCacheManager::INTERNAL && + t != cmCacheManager::STATIC && + t != cmCacheManager::UNINITIALIZED) { ++count; } @@ -138,45 +143,49 @@ void cmCursesMainForm::InitializeUI() // Create the composites. // First add entries which are new - for(cmCacheManager::CacheIterator i = - this->CMakeInstance->GetCacheManager()->NewIterator(); - !i.IsAtEnd(); i.Next()) + for(std::vector<std::string>::const_iterator it = cacheKeys.begin(); + it != cacheKeys.end(); ++it) { - std::string key = i.GetName(); - if ( i.GetType() == cmCacheManager::INTERNAL || - i.GetType() == cmCacheManager::STATIC || - i.GetType() == cmCacheManager::UNINITIALIZED ) + std::string key = *it; + cmCacheManager::CacheEntryType t = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryType(*it); + if (t == cmCacheManager::INTERNAL || + t == cmCacheManager::STATIC || + t == cmCacheManager::UNINITIALIZED ) { continue; } if (!this->LookForCacheEntry(key)) { - newEntries->push_back(new cmCursesCacheEntryComposite(key, i, - true, 30, - entrywidth)); + newEntries->push_back(new cmCursesCacheEntryComposite(key, + this->CMakeInstance, + true, 30, + entrywidth)); this->OkToGenerate = false; } } // then add entries which are old - for(cmCacheManager::CacheIterator i = - this->CMakeInstance->GetCacheManager()->NewIterator(); - !i.IsAtEnd(); i.Next()) + for(std::vector<std::string>::const_iterator it = cacheKeys.begin(); + it != cacheKeys.end(); ++it) { - std::string key = i.GetName(); - if ( i.GetType() == cmCacheManager::INTERNAL || - i.GetType() == cmCacheManager::STATIC || - i.GetType() == cmCacheManager::UNINITIALIZED ) + std::string key = *it; + cmCacheManager::CacheEntryType t = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryType(*it); + if (t == cmCacheManager::INTERNAL || + t == cmCacheManager::STATIC || + t == cmCacheManager::UNINITIALIZED ) { continue; } if (this->LookForCacheEntry(key)) { - newEntries->push_back(new cmCursesCacheEntryComposite(key, i, - false, 30, - entrywidth)); + newEntries->push_back(new cmCursesCacheEntryComposite(key, + this->CMakeInstance, + false, 30, + entrywidth)); } } } @@ -215,10 +224,13 @@ void cmCursesMainForm::RePost() std::vector<cmCursesCacheEntryComposite*>::iterator it; for (it = this->Entries->begin(); it != this->Entries->end(); ++it) { - cmCacheManager::CacheIterator mit = - this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue()); - if (mit.IsAtEnd() || - (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED"))) + const char* existingValue = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue((*it)->GetValue()); + bool advanced = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED"); + if (!existingValue || (!this->AdvancedMode && advanced)) { continue; } @@ -244,10 +256,13 @@ void cmCursesMainForm::RePost() std::vector<cmCursesCacheEntryComposite*>::iterator it; for (it = this->Entries->begin(); it != this->Entries->end(); ++it) { - cmCacheManager::CacheIterator mit = - this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue()); - if (mit.IsAtEnd() || - (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED"))) + const char* existingValue = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue((*it)->GetValue()); + bool advanced = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED"); + if (!existingValue || (!this->AdvancedMode && advanced)) { continue; } @@ -313,10 +328,13 @@ void cmCursesMainForm::Render(int left, int top, int width, int height) std::vector<cmCursesCacheEntryComposite*>::iterator it; for (it = this->Entries->begin(); it != this->Entries->end(); ++it) { - cmCacheManager::CacheIterator mit = - this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue()); - if (mit.IsAtEnd() || - (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED"))) + const char* existingValue = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue((*it)->GetValue()); + bool advanced = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED"); + if (!existingValue || (!this->AdvancedMode && advanced)) { continue; } @@ -333,10 +351,13 @@ void cmCursesMainForm::Render(int left, int top, int width, int height) std::vector<cmCursesCacheEntryComposite*>::iterator it; for (it = this->Entries->begin(); it != this->Entries->end(); ++it) { - cmCacheManager::CacheIterator mit = - this->CMakeInstance->GetCacheManager()->GetCacheIterator((*it)->GetValue()); - if (mit.IsAtEnd() || - (!this->AdvancedMode && mit.GetPropertyAsBool("ADVANCED"))) + const char* existingValue = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue((*it)->GetValue()); + bool advanced = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryPropertyAsBool((*it)->GetValue(), "ADVANCED"); + if (!existingValue || (!this->AdvancedMode && advanced)) { continue; } @@ -494,11 +515,12 @@ void cmCursesMainForm::UpdateStatusBar(const char* message) // Get the help string of the current entry // and add it to the help string - cmCacheManager::CacheIterator it = - this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField); - if (!it.IsAtEnd()) + const char* existingValue = + this->CMakeInstance->GetCacheManager()->GetCacheEntryValue(curField); + if (existingValue) { - const char* hs = it.GetProperty("HELPSTRING"); + const char* hs = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryProperty(curField, "HELPSTRING"); if ( hs ) { strncpy(help, hs, 127); @@ -638,7 +660,7 @@ int cmCursesMainForm::Configure(int noconfigure) // always save the current gui values to disk this->FillCacheManagerFromUI(); - this->CMakeInstance->GetCacheManager()->SaveCache( + this->CMakeInstance->SaveCache( this->CMakeInstance->GetHomeOutputDirectory()); this->LoadCache(0); @@ -791,23 +813,28 @@ void cmCursesMainForm::FillCacheManagerFromUI() size_t size = this->Entries->size(); for(size_t i=0; i < size; i++) { - cmCacheManager::CacheIterator it = - this->CMakeInstance->GetCacheManager()->GetCacheIterator( - (*this->Entries)[i]->Key.c_str()); - if (!it.IsAtEnd()) + std::string cacheKey = (*this->Entries)[i]->Key; + const char* existingValue = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue(cacheKey); + if (existingValue) { - std::string oldValue = it.GetValue(); + std::string oldValue = existingValue; std::string newValue = (*this->Entries)[i]->Entry->GetValue(); std::string fixedOldValue; std::string fixedNewValue; - this->FixValue(it.GetType(), oldValue, fixedOldValue); - this->FixValue(it.GetType(), newValue, fixedNewValue); + cmCacheManager::CacheEntryType t = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryType(cacheKey); + this->FixValue(t, oldValue, fixedOldValue); + this->FixValue(t, newValue, fixedNewValue); if(!(fixedOldValue == fixedNewValue)) { // The user has changed the value. Mark it as modified. - it.SetProperty("MODIFIED", true); - it.SetValue(fixedNewValue.c_str()); + this->CMakeInstance->GetCacheManager() + ->SetCacheEntryBoolProperty(cacheKey, "MODIFIED", true); + this->CMakeInstance->GetCacheManager() + ->SetCacheEntryValue(cacheKey, fixedNewValue); } } } @@ -1016,12 +1043,15 @@ void cmCursesMainForm::HandleInput() cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr( this->Fields[findex-2])); const char* curField = lbl->GetValue(); - const char* helpString=0; - cmCacheManager::CacheIterator it = - this->CMakeInstance->GetCacheManager()->GetCacheIterator(curField); - if (!it.IsAtEnd()) + const char* helpString = 0; + + const char* existingValue = + this->CMakeInstance->GetCacheManager() + ->GetCacheEntryValue(curField); + if (existingValue) { - helpString = it.GetProperty("HELPSTRING"); + helpString = this->CMakeInstance->GetCacheManager() + ->GetCacheEntryProperty(curField, "HELPSTRING"); } if (helpString) { 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/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 996aa75..08d53ce 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -96,7 +96,7 @@ void QCMake::setBinaryDirectory(const QString& _dir) emit this->binaryDirChanged(this->BinaryDirectory); cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); this->setGenerator(QString()); - if(!this->CMakeInstance->GetCacheManager()->LoadCache( + if(!this->CMakeInstance->LoadCache( this->BinaryDirectory.toLocal8Bit().data())) { QDir testDir(this->BinaryDirectory); @@ -110,16 +110,18 @@ void QCMake::setBinaryDirectory(const QString& _dir) QCMakePropertyList props = this->properties(); emit this->propertiesChanged(props); - cmCacheManager::CacheIterator itm = cachem->NewIterator(); - if ( itm.Find("CMAKE_HOME_DIRECTORY")) + const char* homeDir = cachem->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"); + if (homeDir) { - setSourceDirectory(QString::fromLocal8Bit(itm.GetValue().c_str())); + setSourceDirectory(QString::fromLocal8Bit(homeDir)); } - if ( itm.Find("CMAKE_GENERATOR")) + const char* gen = cachem->GetCacheEntryValue("CMAKE_GENERATOR"); + if (gen) { - const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR"); + const char* extraGen = cachem + ->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); std::string curGen = cmExternalMakefileProjectGenerator:: - CreateFullGeneratorName(itm.GetValue(), extraGen? extraGen : ""); + CreateFullGeneratorName(gen, extraGen? extraGen : ""); this->setGenerator(QString::fromLocal8Bit(curGen.c_str())); } } @@ -194,33 +196,35 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) // set the value of properties cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); - for(cmCacheManager::CacheIterator i = cachem->NewIterator(); - !i.IsAtEnd(); i.Next()) + std::vector<std::string> cacheKeys = cachem->GetCacheEntryKeys(); + for(std::vector<std::string>::const_iterator it = cacheKeys.begin(); + it != cacheKeys.end(); ++it) { - - if(i.GetType() == cmCacheManager::INTERNAL || - i.GetType() == cmCacheManager::STATIC) + cmCacheManager::CacheEntryType t = cachem->GetCacheEntryType(*it); + if(t == cmCacheManager::INTERNAL || + t == cmCacheManager::STATIC) { continue; } QCMakeProperty prop; - prop.Key = QString::fromLocal8Bit(i.GetName().c_str()); + prop.Key = QString::fromLocal8Bit(it->c_str()); int idx = props.indexOf(prop); if(idx == -1) { - toremove.append(QString::fromLocal8Bit(i.GetName().c_str())); + toremove.append(QString::fromLocal8Bit(it->c_str())); } else { prop = props[idx]; if(prop.Value.type() == QVariant::Bool) { - i.SetValue(prop.Value.toBool() ? "ON" : "OFF"); + cachem->SetCacheEntryValue(*it, prop.Value.toBool() ? "ON" : "OFF"); } else { - i.SetValue(prop.Value.toString().toLocal8Bit().data()); + cachem->SetCacheEntryValue(*it, + prop.Value.toString().toLocal8Bit().data()); } props.removeAt(idx); } @@ -270,7 +274,7 @@ void QCMake::setProperties(const QCMakePropertyList& newProps) } } - cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->SaveCache(this->BinaryDirectory.toLocal8Bit().data()); } QCMakePropertyList QCMake::properties() const @@ -278,42 +282,47 @@ QCMakePropertyList QCMake::properties() const QCMakePropertyList ret; cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); - for(cmCacheManager::CacheIterator i = cachem->NewIterator(); - !i.IsAtEnd(); i.Next()) + std::vector<std::string> cacheKeys = cachem->GetCacheEntryKeys(); + for (std::vector<std::string>::const_iterator i = cacheKeys.begin(); + i != cacheKeys.end(); ++i) { - - if(i.GetType() == cmCacheManager::INTERNAL || - i.GetType() == cmCacheManager::STATIC || - i.GetType() == cmCacheManager::UNINITIALIZED) + cmCacheManager::CacheEntryType t = cachem->GetCacheEntryType(*i); + if(t == cmCacheManager::INTERNAL || + t == cmCacheManager::STATIC || + t == cmCacheManager::UNINITIALIZED) { continue; } - QCMakeProperty prop; - prop.Key = QString::fromLocal8Bit(i.GetName().c_str()); - prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING")); - prop.Value = QString::fromLocal8Bit(i.GetValue().c_str()); - prop.Advanced = i.GetPropertyAsBool("ADVANCED"); + const char* cachedValue = cachem->GetCacheEntryValue(*i); - if(i.GetType() == cmCacheManager::BOOL) + QCMakeProperty prop; + prop.Key = QString::fromLocal8Bit(i->c_str()); + prop.Help = QString::fromLocal8Bit( + cachem->GetCacheEntryProperty(*i, "HELPSTRING")); + prop.Value = QString::fromLocal8Bit(cachedValue); + prop.Advanced = cachem->GetCacheEntryPropertyAsBool(*i, "ADVANCED"); + if(t == cmCacheManager::BOOL) { prop.Type = QCMakeProperty::BOOL; - prop.Value = cmSystemTools::IsOn(i.GetValue().c_str()); + prop.Value = cmSystemTools::IsOn(cachedValue); } - else if(i.GetType() == cmCacheManager::PATH) + else if(t == cmCacheManager::PATH) { prop.Type = QCMakeProperty::PATH; } - else if(i.GetType() == cmCacheManager::FILEPATH) + else if(t == cmCacheManager::FILEPATH) { prop.Type = QCMakeProperty::FILEPATH; } - else if(i.GetType() == cmCacheManager::STRING) + else if(t == cmCacheManager::STRING) { prop.Type = QCMakeProperty::STRING; - if (i.PropertyExists("STRINGS")) + const char* stringsProperty = + cachem->GetCacheEntryProperty(*i, "STRINGS"); + if (stringsProperty) { - prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";"); + prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";"); } } @@ -397,9 +406,9 @@ QStringList QCMake::availableGenerators() const void QCMake::deleteCache() { // delete cache - this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->DeleteCache(this->BinaryDirectory.toLocal8Bit().data()); // reload to make our cache empty - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit no generator and no properties this->setGenerator(QString()); QCMakePropertyList props = this->properties(); @@ -412,7 +421,7 @@ void QCMake::reloadCache() QCMakePropertyList props; emit this->propertiesChanged(props); // reload - this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); + this->CMakeInstance->LoadCache(this->BinaryDirectory.toLocal8Bit().data()); // emit new cache properties props = this->properties(); emit this->propertiesChanged(props); 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/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx index cf2fe82..72818f5 100644 --- a/Source/cmArchiveWrite.cxx +++ b/Source/cmArchiveWrite.cxx @@ -79,11 +79,12 @@ struct cmArchiveWrite::Callback }; //---------------------------------------------------------------------------- -cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t): - Stream(os), - Archive(archive_write_new()), - Disk(archive_read_disk_new()), - Verbose(false) +cmArchiveWrite::cmArchiveWrite( + std::ostream& os, Compress c, std::string const& format): + Stream(os), + Archive(archive_write_new()), + Disk(archive_read_disk_new()), + Verbose(false) { switch (c) { @@ -141,35 +142,16 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c, Type t): { this->Error = "archive_read_disk_set_standard_lookup: "; this->Error += cm_archive_error_string(this->Archive); - return;; + return; } #endif - switch (t) + + if(archive_write_set_format_by_name(this->Archive, format.c_str()) + != ARCHIVE_OK) { - case TypeZIP: - if(archive_write_set_format_zip(this->Archive) != ARCHIVE_OK) - { - this->Error = "archive_write_set_format_zip: "; - this->Error += cm_archive_error_string(this->Archive); - return; - } - break; - case TypeTAR: - if(archive_write_set_format_pax_restricted(this->Archive) != ARCHIVE_OK) - { - this->Error = "archive_write_set_format_pax_restricted: "; - this->Error += cm_archive_error_string(this->Archive); - return; - } - break; - case Type7Zip: - if(archive_write_set_format_7zip(this->Archive) != ARCHIVE_OK) - { - this->Error = "archive_write_set_format_7zip: "; - this->Error += cm_archive_error_string(this->Archive); - return; - } - break; + this->Error = "archive_write_set_format_by_name: "; + this->Error += cm_archive_error_string(this->Archive); + return; } // do not pad the last block!! diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 17357b4..794cb28 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -38,16 +38,10 @@ public: CompressXZ }; - /** Archive Type */ - enum Type - { - TypeTAR, - TypeZIP, - Type7Zip - }; - /** Construct with output stream to which to write archive. */ - cmArchiveWrite(std::ostream& os, Compress c = CompressNone, Type = TypeTAR); + cmArchiveWrite(std::ostream& os, Compress c = CompressNone, + std::string const& format = "paxr"); + ~cmArchiveWrite(); /** 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/cmCLocaleEnvironmentScope.cxx b/Source/cmCLocaleEnvironmentScope.cxx new file mode 100644 index 0000000..5792302 --- /dev/null +++ b/Source/cmCLocaleEnvironmentScope.cxx @@ -0,0 +1,67 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmCLocaleEnvironmentScope.h" + +#include "cmSystemTools.h" + +#include <sstream> + +cmCLocaleEnvironmentScope::cmCLocaleEnvironmentScope() +{ + this->SetEnv("LANGUAGE", ""); + this->SetEnv("LC_MESSAGES", "C"); + + std::string lcAll = this->GetEnv("LC_ALL"); + + if(!lcAll.empty()) + { + this->SetEnv("LC_ALL", ""); + this->SetEnv("LC_CTYPE", lcAll); + } +} + +std::string cmCLocaleEnvironmentScope::GetEnv(std::string const& key) +{ + const char* value = cmSystemTools::GetEnv(key); + return value ? value : std::string(); +} + +void cmCLocaleEnvironmentScope::SetEnv( + std::string const& key, std::string const& value) +{ + std::string oldValue = this->GetEnv(key); + + this->EnvironmentBackup.insert(std::make_pair(key, oldValue)); + + if(value.empty()) + { + cmSystemTools::UnsetEnv(key.c_str()); + } + else + { + std::stringstream tmp; + tmp << key << "=" << value; + cmSystemTools::PutEnv(tmp.str()); + } +} + +cmCLocaleEnvironmentScope::~cmCLocaleEnvironmentScope() +{ + for(backup_map_t::const_iterator i = this->EnvironmentBackup.begin(); + i != this->EnvironmentBackup.end(); ++i) + { + std::stringstream tmp; + tmp << i->first << "=" << i->second; + cmSystemTools::PutEnv(tmp.str()); + } +} diff --git a/Source/cmCLocaleEnvironmentScope.h b/Source/cmCLocaleEnvironmentScope.h new file mode 100644 index 0000000..b011741 --- /dev/null +++ b/Source/cmCLocaleEnvironmentScope.h @@ -0,0 +1,32 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2015 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmCLocaleEnvironmentScope_h +#define cmCLocaleEnvironmentScope_h + +#include "cmStandardIncludes.h" + +class cmCLocaleEnvironmentScope +{ +public: + cmCLocaleEnvironmentScope(); + ~cmCLocaleEnvironmentScope(); + +private: + std::string GetEnv(std::string const& key); + void SetEnv(std::string const& key, std::string const& value); + + typedef std::map<std::string, std::string> backup_map_t; + backup_map_t EnvironmentBackup; +}; + +#endif diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx index d0dc30a..987a7b1 100644 --- a/Source/cmCPluginAPI.cxx +++ b/Source/cmCPluginAPI.cxx @@ -51,12 +51,14 @@ void CCONV cmSetError(void *info, const char *err) unsigned int CCONV cmGetCacheMajorVersion(void *arg) { cmMakefile *mf = static_cast<cmMakefile *>(arg); - return mf->GetCacheMajorVersion(); + cmCacheManager *manager = mf->GetCMakeInstance()->GetCacheManager(); + return manager->GetCacheMajorVersion(); } unsigned int CCONV cmGetCacheMinorVersion(void *arg) { cmMakefile *mf = static_cast<cmMakefile *>(arg); - return mf->GetCacheMinorVersion(); + cmCacheManager *manager = mf->GetCMakeInstance()->GetCacheManager(); + return manager->GetCacheMinorVersion(); } unsigned int CCONV cmGetMajorVersion(void *) @@ -438,15 +440,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..1db057b 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; } //---------------------------------------------------------------------- @@ -2237,7 +2281,7 @@ bool cmCTest::AddVariableDefinition(const std::string &arg) std::string value; cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; - if (cmCacheManager::ParseEntry(arg, name, value, type)) + if (cmake::ParseCacheEntry(arg, name, value, type)) { this->Definitions[name] = value; 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..5387d0c 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -12,7 +12,6 @@ #include "cmCacheManager.h" #include "cmSystemTools.h" -#include "cmCacheManager.h" #include "cmGeneratedFileStream.h" #include "cmMakefile.h" #include "cmake.h" @@ -76,22 +75,10 @@ bool cmCacheManager::IsType(const char* s) return false; } -bool cmCacheManager::LoadCache(cmMakefile* mf) -{ - return this->LoadCache(mf->GetHomeOutputDirectory()); -} - - bool cmCacheManager::LoadCache(const std::string& path) { - return this->LoadCache(path,true); -} - -bool cmCacheManager::LoadCache(const std::string& path, - bool internal) -{ std::set<std::string> emptySet; - return this->LoadCache(path, internal, emptySet, emptySet); + return this->LoadCache(path, true, emptySet, emptySet); } static bool ParseEntryWithoutType(const std::string& entry, @@ -186,11 +173,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, @@ -300,14 +283,16 @@ bool cmCacheManager::LoadCache(const std::string& path, } this->CacheMajorVersion = 0; this->CacheMinorVersion = 0; - if(const char* cmajor = this->GetCacheValue("CMAKE_CACHE_MAJOR_VERSION")) + if(const char* cmajor = + this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) { unsigned int v=0; if(sscanf(cmajor, "%u", &v) == 1) { this->CacheMajorVersion = v; } - if(const char* cminor = this->GetCacheValue("CMAKE_CACHE_MINOR_VERSION")) + if(const char* cminor = + this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) { if(sscanf(cminor, "%u", &v) == 1) { @@ -329,10 +314,11 @@ bool cmCacheManager::LoadCache(const std::string& path, } // check to make sure the cache directory has not // been moved - if ( internal && this->GetCacheValue("CMAKE_CACHEFILE_DIR") ) + const char* oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR"); + if (internal && oldDir) { std::string currentcwd = path; - std::string oldcwd = this->GetCacheValue("CMAKE_CACHEFILE_DIR"); + std::string oldcwd = oldDir; cmSystemTools::ConvertToUnixSlashes(currentcwd); currentcwd += "/CMakeCache.txt"; oldcwd += "/CMakeCache.txt"; @@ -341,7 +327,7 @@ bool cmCacheManager::LoadCache(const std::string& path, std::string message = std::string("The current CMakeCache.txt directory ") + currentcwd + std::string(" is different than the directory ") + - std::string(this->GetCacheValue("CMAKE_CACHEFILE_DIR")) + + std::string(this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR")) + std::string(" where CMakeCache.txt was created. This may result " "in binaries being created in the wrong place. If you " "are not sure, reedit the CMakeCache.txt"); @@ -422,12 +408,6 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, } } -bool cmCacheManager::SaveCache(cmMakefile* mf) -{ - return this->SaveCache(mf->GetHomeOutputDirectory()); -} - - bool cmCacheManager::SaveCache(const std::string& path) { std::string cacheFile = path; @@ -677,7 +657,8 @@ cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator( return CacheIterator(*this, key); } -const char* cmCacheManager::GetCacheValue(const std::string& key) const +const char* +cmCacheManager::GetInitializedCacheValue(const std::string& key) const { CacheEntryMap::const_iterator i = this->Cache.find(key); if(i != this->Cache.end() && @@ -918,21 +899,3 @@ bool cmCacheManager::CacheIterator::PropertyExists( { return this->GetProperty(prop)? true:false; } - -//---------------------------------------------------------------------------- -bool cmCacheManager::NeedCacheCompatibility(int major, int minor) -{ - // Compatibility is not needed if the cache version is zero because - // the cache was created or modified by the user. - if(this->CacheMajorVersion == 0) - { - return false; - } - - // Compatibility is needed if the cache version is equal to or lower - // than the given version. - cmIML_INT_uint64_t actual_compat = - CMake_VERSION_ENCODE(this->CacheMajorVersion, this->CacheMinorVersion, 0); - return (actual_compat && - actual_compat <= CMake_VERSION_ENCODE(major, minor, 0)); -} diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index d9a9112..3b02fa6 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -65,7 +65,7 @@ public: void AppendProperty(const std::string& property, const char* value, bool asString=false); void SetProperty(const std::string& property, bool value); - std::string GetValue() const { return this->GetEntry().Value; } + const char* GetValue() const { return this->GetEntry().Value.c_str(); } bool GetValueAsBool() const; void SetValue(const char*); CacheEntryType GetType() const { return this->GetEntry().Type; } @@ -105,17 +105,12 @@ public: static const char* TypeToString(CacheEntryType); static bool IsType(const char*); - ///! Load a cache for given makefile. Loads from ouput home. - bool LoadCache(cmMakefile*); ///! Load a cache for given makefile. Loads from path/CMakeCache.txt. bool LoadCache(const std::string& path); - bool LoadCache(const std::string& path, bool internal); bool LoadCache(const std::string& path, bool internal, std::set<std::string>& excludes, std::set<std::string>& includes); - ///! Save cache for given makefile. Saves to ouput home CMakeCache.txt. - bool SaveCache(cmMakefile*) ; ///! Save cache for given makefile. Saves to ouput path/CMakeCache.txt bool SaveCache(const std::string& path) ; @@ -142,14 +137,88 @@ public: CacheEntryType& type); ///! Get a value from the cache given a key - const char* GetCacheValue(const std::string& key) const; + const char* GetInitializedCacheValue(const std::string& key) const; + + const char* GetCacheEntryValue(const std::string& key) + { + cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str()); + if (it.IsAtEnd()) + { + return 0; + } + return it.GetValue(); + } + + const char* GetCacheEntryProperty(std::string const& key, + std::string const& propName) + { + return this->GetCacheIterator(key.c_str()).GetProperty(propName); + } + + CacheEntryType GetCacheEntryType(std::string const& key) + { + return this->GetCacheIterator(key.c_str()).GetType(); + } + + bool GetCacheEntryPropertyAsBool(std::string const& key, + std::string const& propName) + { + return this->GetCacheIterator(key.c_str()).GetPropertyAsBool(propName); + } + + void SetCacheEntryProperty(std::string const& key, + std::string const& propName, + std::string const& value) + { + this->GetCacheIterator(key.c_str()).SetProperty(propName, value.c_str()); + } + + void SetCacheEntryBoolProperty(std::string const& key, + std::string const& propName, + bool value) + { + this->GetCacheIterator(key.c_str()).SetProperty(propName, value); + } + + void SetCacheEntryValue(std::string const& key, + std::string const& value) + { + this->GetCacheIterator(key.c_str()).SetValue(value.c_str()); + } + + void RemoveCacheEntryProperty(std::string const& key, + std::string const& propName) + { + this->GetCacheIterator(key.c_str()).SetProperty(propName, (void*)0); + } + + void AppendCacheEntryProperty(std::string const& key, + std::string const& propName, + std::string const& value, + bool asString = false) + { + this->GetCacheIterator(key.c_str()).AppendProperty(propName, + value.c_str(), + asString); + } + + std::vector<std::string> GetCacheEntryKeys() + { + std::vector<std::string> definitions; + definitions.reserve(this->GetSize()); + cmCacheManager::CacheIterator cit = this->GetCacheIterator(); + for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() ) + { + definitions.push_back(cit.GetName()); + } + return definitions; + } /** Get the version of CMake that wrote the cache. */ unsigned int GetCacheMajorVersion() const { return this->CacheMajorVersion; } unsigned int GetCacheMinorVersion() const { return this->CacheMinorVersion; } - bool NeedCacheCompatibility(int major, int minor); protected: ///! Add an entry into the cache diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index 747b7e4..99bf5f5 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -90,7 +90,8 @@ char* cmCommandArgumentParserHelper::ExpandSpecialVariable(const char* key, } if ( strcmp(key, "CACHE") == 0 ) { - if(const char* c = this->Makefile->GetCacheManager()->GetCacheValue(var)) + if(const char* c = this->Makefile->GetCacheManager() + ->GetInitializedCacheValue(var)) { if(this->EscapeQuotes) { 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..8880667 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> @@ -410,6 +411,10 @@ cmComputeLinkInformation std::vector<std::string> const& dirs = this->Target->GetLinkDirectories(); this->OldLinkDirMask.insert(dirs.begin(), dirs.end()); } + + this->CMP0060Warn = + this->Makefile->PolicyOptionalWarningEnabled( + "CMAKE_POLICY_WARNING_CMP0060"); } //---------------------------------------------------------------------------- @@ -547,6 +552,22 @@ bool cmComputeLinkInformation::Compute() // Add implicit language runtime libraries and directories. this->AddImplicitLinkInfo(); + if (!this->CMP0060WarnItems.empty()) + { + std::ostringstream w; + w << (this->Makefile->GetCMakeInstance()->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0060)) << "\n" + "Some library files are in directories implicitly searched by " + "the linker when invoked for " << this->LinkLanguage << ":\n" + " " << cmJoin(this->CMP0060WarnItems, "\n ") << "\n" + "For compatibility with older versions of CMake, the generated " + "link line will ask the linker to search for these by library " + "name." + ; + this->CMakeInstance->IssueMessage(cmake::AUTHOR_WARNING, w.str(), + this->Target->GetBacktrace()); + } + return true; } @@ -1189,6 +1210,28 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item) return false; } + // Check the policy for whether we should use the approach below. + switch (this->Target->GetPolicyStatusCMP0060()) + { + case cmPolicies::WARN: + if (this->CMP0060Warn) + { + // Print the warning at most once for this item. + std::string const& wid = "CMP0060-WARNING-GIVEN-" + item; + if (!this->CMakeInstance->GetPropertyAsBool(wid)) + { + this->CMakeInstance->SetProperty(wid, "1"); + this->CMP0060WarnItems.insert(item); + } + } + case cmPolicies::OLD: + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + return false; + } + // Many system linkers support multiple architectures by // automatically selecting the implicit linker search path for the // current architecture. If the library appears in an implicit link diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index e5d674a..8847141 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -175,6 +175,10 @@ private: std::vector<std::string> OldUserFlagItems; bool OldLinkDirMode; + // CMP0060 warnings. + bool CMP0060Warn; + std::set<std::string> CMP0060WarnItems; + // Runtime path computation. cmOrderDirectories* OrderRuntimeSearchPath; void AddLibraryRuntimeInfo(std::string const& fullPath, 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..6cdd4c1 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 @@ -241,13 +242,22 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, cmsys::ifstream fin(fullName.c_str()); if(fin) { - // Add this file as a dependency. - dependencies.insert(fullName); + cmsys::FStream::BOM bom = cmsys::FStream::ReadBOM(fin); + if(bom == cmsys::FStream::BOM_None || + bom == cmsys::FStream::BOM_UTF8) + { + // Add this file as a dependency. + dependencies.insert(fullName); - // Scan this file for new dependencies. Pass the directory - // containing the file to handle double-quote includes. - std::string dir = cmSystemTools::GetFilenamePath(fullName); - this->Scan(fin, dir.c_str(), fullName); + // Scan this file for new dependencies. Pass the directory + // containing the file to handle double-quote includes. + std::string dir = cmSystemTools::GetFilenamePath(fullName); + this->Scan(fin, dir.c_str(), fullName); + } + else + { + // Skip file with encoding we do not implement. + } } } } diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index f4e3a75..4f34755 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> @@ -137,6 +138,8 @@ bool cmDocumentation::PrintDocumentation(Type ht, std::ostream& os) return this->PrintHelpListVariables(os); case cmDocumentation::ListPolicies: return this->PrintHelpListPolicies(os); + case cmDocumentation::ListGenerators: + return this->PrintHelpListGenerators(os); case cmDocumentation::Version: return this->PrintVersion(os); case cmDocumentation::OldCustomModules: @@ -816,6 +819,19 @@ bool cmDocumentation::PrintHelpListPolicies(std::ostream& os) } //---------------------------------------------------------------------------- +bool cmDocumentation::PrintHelpListGenerators(std::ostream& os) +{ + std::map<std::string,cmDocumentationSection*>::iterator si; + si = this->AllSections.find("Generators"); + if(si != this->AllSections.end()) + { + this->Formatter.SetIndent(" "); + this->Formatter.PrintSection(os, *si->second); + } + return true; +} + +//---------------------------------------------------------------------------- bool cmDocumentation::PrintHelpOneVariable(std::ostream& os) { std::string vname = cmSystemTools::HelpFileName(this->CurrentArgument); diff --git a/Source/cmDocumentation.h b/Source/cmDocumentation.h index b72b5fe..8854c36 100644 --- a/Source/cmDocumentation.h +++ b/Source/cmDocumentation.h @@ -117,6 +117,7 @@ private: bool PrintHelpListProperties(std::ostream& os); bool PrintHelpListVariables(std::ostream& os); bool PrintHelpListPolicies(std::ostream& os); + bool PrintHelpListGenerators(std::ostream& os); bool PrintOldCustomModules(std::ostream& os); const char* GetNameString() const; diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx index 4de59c0..6869e2f 100644 --- a/Source/cmDocumentationFormatter.cxx +++ b/Source/cmDocumentationFormatter.cxx @@ -204,7 +204,7 @@ void cmDocumentationFormatter if(!op->Name.empty()) { os << " " << op->Name; - this->TextIndent = " "; + this->TextIndent = " "; int align = static_cast<int>(strlen(this->TextIndent))-4; for(int i = static_cast<int>(op->Name.size()); i < align; ++i) { diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h index 59513cc..6e19b7d 100644 --- a/Source/cmDocumentationFormatter.h +++ b/Source/cmDocumentationFormatter.h @@ -26,8 +26,8 @@ public: /** Types of help provided. */ enum Type { - None, Version, Usage, Help, Full, ListManuals, - ListCommands, ListModules, ListProperties, ListVariables, ListPolicies, + None, Version, Usage, Help, Full, ListManuals, ListCommands, + ListModules, ListProperties, ListVariables, ListPolicies, ListGenerators, OneManual, OneCommand, OneModule, OneProperty, OneVariable, OnePolicy, OldCustomModules }; 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/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index d64b0d7..0d32e4b 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -205,7 +205,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout, std::string cacheEntryName = "CMAKE_ECLIPSE_ENVVAR_"; cacheEntryName += envVar; - const char* cacheValue = mf->GetCacheManager()->GetCacheValue( + const char* cacheValue = mf->GetCacheManager()->GetInitializedCacheValue( cacheEntryName); // now we have both, decide which one to use @@ -223,7 +223,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout, mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(), cacheEntryName.c_str(), cmCacheManager::STRING, true); - mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory()); + mf->GetCMakeInstance()->SaveCache(mf->GetHomeOutputDirectory()); } else if (envVarValue==0 && cacheValue!=0) { @@ -244,7 +244,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(cmGeneratedFileStream& fout, mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(), cacheEntryName.c_str(), cmCacheManager::STRING, true); - mf->GetCacheManager()->SaveCache(mf->GetHomeOutputDirectory()); + mf->GetCMakeInstance()->SaveCache(mf->GetHomeOutputDirectory()); } } 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..cc08052 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() @@ -378,18 +366,18 @@ bool cmFindBase::CheckForVariableInCache() if(const char* cacheValue = this->Makefile->GetDefinition(this->VariableName)) { - cmCacheManager::CacheIterator it = - this->Makefile->GetCacheManager()-> - GetCacheIterator(this->VariableName.c_str()); + cmCacheManager* manager = this->Makefile->GetCacheManager(); + const char* cacheEntry = manager->GetCacheEntryValue(this->VariableName); bool found = !cmSystemTools::IsNOTFOUND(cacheValue); - bool cached = !it.IsAtEnd(); + bool cached = cacheEntry ? true : false; if(found) { // If the user specifies the entry on the command line without a // type we should add the type and docstring but keep the // original value. Tell the subclass implementations to do // this. - if(cached && it.GetType() == cmCacheManager::UNINITIALIZED) + if(cached && manager->GetCacheEntryType(this->VariableName) + == cmCacheManager::UNINITIALIZED) { this->AlreadyInCacheWithoutMetaInfo = true; } @@ -397,7 +385,8 @@ bool cmFindBase::CheckForVariableInCache() } else if(cached) { - const char* hs = it.GetProperty("HELPSTRING"); + const char* hs = manager->GetCacheEntryProperty(this->VariableName, + "HELPSTRING"); this->VariableDocumentation = hs?hs:"(none)"; } } 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..2654851 --- /dev/null +++ b/Source/cmGeneratorExpressionNode.cxx @@ -0,0 +1,1869 @@ +/*============================================================================ + 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; + +//---------------------------------------------------------------------------- +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..41d12d7 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> @@ -55,6 +56,7 @@ struct ResxTag {}; struct ModuleDefinitionFileTag {}; struct AppManifestTag{}; struct CertificatesTag{}; +struct XamlTag{}; template<typename Tag, typename OtherTag> struct IsSameTag @@ -97,6 +99,20 @@ struct DoAccept<true> data.ExpectedResxHeaders.insert(hFileName); data.ResxSources.push_back(f); } + static void Do(cmGeneratorTarget::XamlData& data, cmSourceFile* f) + { + // Build and save the name of the corresponding .h and .cpp file + // This relationship will be used later when building the project files. + // Both names would have been auto generated from Visual Studio + // where the user supplied the file name and Visual Studio + // appended the suffix. + std::string xaml = f->GetFullPath(); + std::string hFileName = xaml + ".h"; + std::string cppFileName = xaml + ".cpp"; + data.ExpectedXamlHeaders.insert(hFileName); + data.ExpectedXamlSources.insert(cppFileName); + data.XamlSources.push_back(f); + } static void Do(std::string& data, cmSourceFile* f) { data = f->GetFullPath(); @@ -185,6 +201,10 @@ struct TagVisitor { DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf); } + else if (ext == "xaml") + { + DoAccept<IsSameTag<Tag, XamlTag>::Result>::Do(this->Data, sf); + } else if(this->Header.find(sf->GetFullPath().c_str())) { DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf); @@ -437,6 +457,36 @@ cmGeneratorTarget } //---------------------------------------------------------------------------- +void +cmGeneratorTarget::GetExpectedXamlHeaders(std::set<std::string>& headers, + const std::string& config) const +{ + XamlData data; + IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData) + headers = data.ExpectedXamlHeaders; +} + +//---------------------------------------------------------------------------- +void +cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs, + const std::string& config) const +{ + XamlData data; + IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData) + srcs = data.ExpectedXamlSources; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget +::GetXamlSources(std::vector<cmSourceFile const*>& srcs, + const std::string& config) const +{ + XamlData data; + IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData) + srcs = data.XamlSources; +} + +//---------------------------------------------------------------------------- bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir, const std::string& config) const { @@ -528,23 +578,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 +1010,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..c79aa72 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -58,6 +58,12 @@ public: const std::string& config) const; void GetCertificates(std::vector<cmSourceFile const*>&, const std::string& config) const; + void GetXamlSources(std::vector<cmSourceFile const*>&, + const std::string& config) const; + void GetExpectedXamlHeaders(std::set<std::string>&, + const std::string& config) const; + void GetExpectedXamlSources(std::set<std::string>&, + const std::string& config) const; void ComputeObjectMapping(); @@ -85,7 +91,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; @@ -132,6 +138,13 @@ public: mutable std::set<std::string> ExpectedResxHeaders; mutable std::vector<cmSourceFile const*> ResxSources; }; + + struct XamlData { + std::set<std::string> ExpectedXamlHeaders; + std::set<std::string> ExpectedXamlSources; + std::vector<cmSourceFile const*> XamlSources; + }; + private: friend class cmTargetTraceDependencies; struct SourceEntry { std::vector<cmSourceFile*> Depends; }; 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/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index f0b2686..0e6e0c2 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -391,11 +391,10 @@ bool cmGetPropertyCommand::HandleCacheMode() } const char* value = 0; - cmCacheManager::CacheIterator it = - this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str()); - if(!it.IsAtEnd()) + if(this->Makefile->GetCacheManager()->GetCacheEntryValue(this->Name)) { - value = it.GetProperty(this->PropertyName); + value = this->Makefile->GetCacheManager() + ->GetCacheEntryProperty(this->Name, this->PropertyName); } this->StoreResult(value); return true; 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..35394b8 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, @@ -182,7 +179,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, return; } const char* cname = this->GetCMakeInstance()-> - GetCacheManager()->GetCacheValue(langComp); + GetCacheManager()->GetInitializedCacheValue(langComp); std::string changeVars; if(cname && !optional) { @@ -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)); } } } @@ -1540,10 +1537,9 @@ void cmGlobalGenerator::CheckLocalGenerators() std::map<std::string, std::string> notFoundMap; // std::set<std::string> notFoundMap; // after it is all done do a ConfigureFinalPass - cmCacheManager* manager = 0; + cmCacheManager* manager = this->GetCMakeInstance()->GetCacheManager(); for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { - manager = this->LocalGenerators[i]->GetMakefile()->GetCacheManager(); this->LocalGenerators[i]->ConfigureFinalPass(); cmTargets &targets = this->LocalGenerators[i]->GetMakefile()->GetTargets(); @@ -1563,9 +1559,7 @@ void cmGlobalGenerator::CheckLocalGenerators() cmSystemTools::IsNOTFOUND(lib->first.c_str())) { std::string varName = lib->first.substr(0, lib->first.size()-9); - cmCacheManager::CacheIterator it = - manager->GetCacheIterator(varName.c_str()); - if(it.GetPropertyAsBool("ADVANCED")) + if(manager->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) { varName += " (ADVANCED)"; } @@ -1596,9 +1590,7 @@ void cmGlobalGenerator::CheckLocalGenerators() cmSystemTools::IsNOTFOUND(incDir->c_str())) { std::string varName = incDir->substr(0, incDir->size()-9); - cmCacheManager::CacheIterator it = - manager->GetCacheIterator(varName.c_str()); - if(it.GetPropertyAsBool("ADVANCED")) + if(manager->GetCacheEntryPropertyAsBool(varName, "ADVANCED")) { varName += " (ADVANCED)"; } @@ -1645,7 +1637,7 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir, // and there is a good chance that the try compile stuff will // take the bulk of the time, so try and guess some progress // by getting closer and closer to 100 without actually getting there. - if (!this->CMakeInstance->GetCacheManager()->GetCacheValue + if (!this->CMakeInstance->GetCacheManager()->GetInitializedCacheValue ("CMAKE_NUMBER_OF_LOCAL_GENERATORS")) { // If CMAKE_NUMBER_OF_LOCAL_GENERATORS is not set @@ -1681,14 +1673,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 +1693,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 +1713,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 +1752,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; @@ -1833,7 +1835,7 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg) // update progress // estimate how many lg there will be const char *numGenC = - this->CMakeInstance->GetCacheManager()->GetCacheValue + this->CMakeInstance->GetCacheManager()->GetInitializedCacheValue ("CMAKE_NUMBER_OF_LOCAL_GENERATORS"); if (!numGenC) @@ -2299,15 +2301,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 +2570,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 +2931,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 +3021,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 +3033,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..1c6ac88 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"; @@ -70,8 +71,11 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs10generatorName; - entry.Brief = "Generates Visual Studio 10 (VS 2010) project files."; + entry.Name = std::string(vs10generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2010 project files. " + "Optional [arch] can be \"Win64\" or \"IA64\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const @@ -459,7 +463,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 +511,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..5d3ae16 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"; @@ -77,8 +78,11 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs11generatorName; - entry.Brief = "Generates Visual Studio 11 (VS 2012) project files."; + entry.Name = std::string(vs11generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2012 project files. " + "Optional [arch] can be \"Win64\" or \"ARM\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index 2bc9379..e70e082 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"; @@ -65,8 +66,11 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs12generatorName; - entry.Brief = "Generates Visual Studio 12 (VS 2013) project files."; + entry.Name = std::string(vs12generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2013 project files. " + "Optional [arch] can be \"Win64\" or \"ARM\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index fe702c0..7b1dd24 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"; @@ -65,8 +66,11 @@ public: virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs14generatorName; - entry.Brief = "Generates Visual Studio 14 (VS 2015) project files."; + entry.Name = std::string(vs14generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2015 project files. " + "Optional [arch] can be \"Win64\" or \"ARM\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const 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/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index e6ce45d..726db0f 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -66,8 +66,11 @@ public: } virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs8generatorName; - entry.Brief = "Generates Visual Studio 8 2005 project files."; + entry.Name = std::string(vs8generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2005 project files. " + "Optional [arch] can be \"Win64\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const { diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 1d73b5c..1bc627f 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -70,8 +70,11 @@ public: } virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = vs9generatorName; - entry.Brief = "Generates Visual Studio 9 2008 project files."; + entry.Name = std::string(vs9generatorName) + " [arch]"; + entry.Brief = + "Generates Visual Studio 2008 project files. " + "Optional [arch] can be \"Win64\" or \"IA64\"." + ; } virtual void GetGenerators(std::vector<std::string>& names) const { 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..0561a05 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) { @@ -3704,7 +3703,7 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root, // Since this call may have created new cache entries, save the cache: // - root->GetMakefile()->GetCacheManager()->SaveCache( + root->GetMakefile()->GetCMakeInstance()->SaveCache( root->GetMakefile()->GetHomeOutputDirectory()); } 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/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 3e26349..ddcea9b 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -146,18 +146,12 @@ bool cmListFile::ParseFile(const char* filename, } bool parseError = false; - this->ModifiedTime = cmSystemTools::ModifiedTime(filename); { cmListFileParser parser(this, mf, filename); parseError = !parser.ParseFile(); } - if(parseError) - { - this->ModifiedTime = 0; - } - // do we need a cmake_policy(VERSION call? if(topLevel) { diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 2ca9b8e..544ff1b 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -85,15 +85,10 @@ class cmListFileBacktrace: public std::vector<cmListFileContext> struct cmListFile { - cmListFile() - :ModifiedTime(0) - { - } bool ParseFile(const char* path, bool topLevel, cmMakefile *mf); - long int ModifiedTime; std::vector<cmListFileFunction> Functions; }; diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx index 93aec32..e2ae901 100644 --- a/Source/cmLoadCacheCommand.cxx +++ b/Source/cmLoadCacheCommand.cxx @@ -81,8 +81,8 @@ bool cmLoadCacheCommand { break; } - this->Makefile->GetCacheManager()->LoadCache(args[i], false, - excludes, includes); + this->Makefile->GetCMakeInstance()->LoadCache(args[i], false, + excludes, includes); } @@ -173,7 +173,7 @@ void cmLoadCacheCommand::CheckLine(const char* line) std::string var; std::string value; cmCacheManager::CacheEntryType type = cmCacheManager::UNINITIALIZED; - if(cmCacheManager::ParseEntry(line, var, value, type)) + if(cmake::ParseCacheEntry(line, var, value, type)) { // Found a real entry. See if this one was requested. if(this->VariablesToRead.find(var) != this->VariablesToRead.end()) 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..6844fee 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -14,7 +14,6 @@ #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmSourceFile.h" -#include "cmCacheManager.h" #include "cmGeneratorTarget.h" #include "cmCustomCommandGenerator.h" #include "cmake.h" @@ -1701,15 +1700,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 +1759,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..34b4621 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; @@ -177,21 +174,6 @@ void cmMakefile::Initialize() this->CheckCMP0000 = false; } -unsigned int cmMakefile::GetCacheMajorVersion() const -{ - return this->GetCacheManager()->GetCacheMajorVersion(); -} - -unsigned int cmMakefile::GetCacheMinorVersion() const -{ - return this->GetCacheManager()->GetCacheMinorVersion(); -} - -bool cmMakefile::NeedCacheCompatibility(int major, int minor) const -{ - return this->GetCacheManager()->NeedCacheCompatibility(major, minor); -} - cmMakefile::~cmMakefile() { cmDeleteAll(this->InstallGenerators); @@ -212,13 +194,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 +966,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 +1342,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 +1463,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 +1677,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 +1699,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 +1727,6 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, { lg2->GetMakefile()->SetProperty("EXCLUDE_FROM_ALL", "TRUE"); } - lg2->GetMakefile()->SetPreOrder(preorder); if (immediate) { @@ -1826,16 +1810,17 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, { bool haveVal = value ? true : false; std::string val = haveVal ? value : ""; - cmCacheManager::CacheIterator it = - this->GetCacheManager()->GetCacheIterator(name.c_str()); - if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) && - it.Initialized()) + const char* existingValue = + this->GetCacheManager()->GetInitializedCacheValue(name); + if(existingValue + && (this->GetCacheManager()->GetCacheEntryType(name) + == cmCacheManager::UNINITIALIZED)) { // if this is not a force, then use the value from the cache // if it is a force, then use the value being passed in if(!force) { - val = it.GetValue(); + val = existingValue; haveVal = true; } if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH ) @@ -1858,13 +1843,13 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value, } this->GetCacheManager()->AddCacheEntry(name, nvalue.c_str(), doc, type); - val = it.GetValue(); + val = this->GetCacheManager()->GetInitializedCacheValue(name); haveVal = true; } } - this->GetCacheManager()->AddCacheEntry(name, haveVal ? val.c_str() : 0, doc, - type); + this->GetCacheManager()->AddCacheEntry(name, haveVal ? val.c_str() : 0, + doc, type); // if there was a definition then remove it this->Internal->VarStack.top().Set(name, 0); } @@ -2203,7 +2188,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 +2204,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 +2236,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,'}'); @@ -2449,7 +2433,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const this->Internal->VarUsageStack.top().insert(name); if(!def) { - def = this->GetCacheManager()->GetCacheValue(name); + def = this->GetCacheManager()->GetInitializedCacheValue(name); } #ifdef CMAKE_BUILD_WITH_CMAKE if(cmVariableWatch* vv = this->GetVariableWatch()) @@ -2474,7 +2458,7 @@ const char* cmMakefile::GetDefinition(const std::string& name) const const char* def = this->Internal->VarStack.top().Get(name); if(!def) { - def = this->GetCacheManager()->GetCacheValue(name); + def = this->GetCacheManager()->GetInitializedCacheValue(name); } #ifdef CMAKE_BUILD_WITH_CMAKE cmVariableWatch* vv = this->GetVariableWatch(); @@ -2508,20 +2492,18 @@ const char* cmMakefile::GetSafeDefinition(const std::string& def) const std::vector<std::string> cmMakefile ::GetDefinitions(int cacheonly /* = 0 */) const { - std::set<std::string> definitions; + std::vector<std::string> res; if ( !cacheonly ) { - definitions = this->Internal->VarStack.top().ClosureKeys(); - } - cmCacheManager::CacheIterator cit = - this->GetCacheManager()->GetCacheIterator(); - for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() ) - { - definitions.insert(cit.GetName()); + std::set<std::string> definitions = + this->Internal->VarStack.top().ClosureKeys(); + res.insert(res.end(), definitions.begin(), definitions.end()); } + std::vector<std::string> cacheKeys = + this->GetCacheManager()->GetCacheEntryKeys(); + res.insert(res.end(), cacheKeys.begin(), cacheKeys.end()); - std::vector<std::string> res; - res.insert(res.end(), definitions.begin(), definitions.end()); + std::sort(res.begin(), res.end()); return res; } @@ -2852,7 +2834,8 @@ cmake::MessageType cmMakefile::ExpandVariablesInStringNew( value = cmSystemTools::GetEnv(lookup.c_str()); break; case CACHE: - value = this->GetCacheManager()->GetCacheValue(lookup); + value = this->GetCacheManager() + ->GetInitializedCacheValue(lookup); break; } // Get the string we're meant to append to. @@ -3576,19 +3559,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 +3721,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 +4174,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 +4184,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 +4194,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") @@ -4964,7 +4903,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id, (status == cmPolicies::WARN || status == cmPolicies::OLD)) { if(!(this->GetCacheManager() - ->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))) + ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY"))) { // Set it to 2.4 because that is the last version where the // variable had meaning. diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index bff8c12..5209891 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -35,6 +35,7 @@ #endif #include <stack> +#include <deque> class cmFunctionBlocker; class cmCommand; @@ -61,14 +62,6 @@ class cmMakefile class Internals; cmsys::auto_ptr<Internals> Internal; public: - /** - * Return the major and minor version of the cmake that - * was used to write the currently loaded cache, note - * this method will not work before the cache is loaded. - */ - unsigned int GetCacheMajorVersion() const; - unsigned int GetCacheMinorVersion() const; - /* Check for unused variables in this scope */ void CheckForUnusedVariables() const; /* Mark a variable as used */ @@ -77,9 +70,6 @@ public: bool VariableInitialized(const std::string& ) const; /* return true if a variable has been used */ bool VariableUsed(const std::string& ) const; - /** Return whether compatibility features needed for a version of - the cache or lower should be enabled. */ - bool NeedCacheCompatibility(int major, int minor) const; /** * Construct an empty makefile. @@ -291,11 +281,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 +421,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 +579,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 +599,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 @@ -802,10 +765,6 @@ public: ///enabled. void EnableLanguage(std::vector<std::string>const& languages, bool optional); - /** - * Set/Get the name of the parent directories CMakeLists file - * given a current CMakeLists file name - */ cmCacheManager *GetCacheManager() const; /** @@ -851,7 +810,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 +848,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 +941,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; @@ -1018,9 +970,8 @@ protected: // directories. std::set<std::string> SystemIncludeDirectories; - std::vector<std::string> ListFiles; // list of command files loaded - std::vector<std::string> OutputFiles; // list of command files loaded - + std::vector<std::string> ListFiles; + std::vector<std::string> OutputFiles; cmTarget::LinkLibraryVectorType LinkLibraries; @@ -1075,10 +1026,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 +1035,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 ea11c79..bd9c579 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; @@ -1147,40 +1158,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; @@ -1294,12 +1271,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); } } @@ -1342,22 +1322,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 42c4f58..58044e8 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/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index f6a2c26..cc094b1 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -37,24 +37,19 @@ bool cmMarkAsAdvancedCommand { std::string variable = args[i]; cmCacheManager* manager = this->Makefile->GetCacheManager(); - cmCacheManager::CacheIterator it = - manager->GetCacheIterator(variable.c_str()); - if ( it.IsAtEnd() ) + if (!manager->GetCacheEntryValue(variable)) { - this->Makefile->GetCacheManager() - ->AddCacheEntry(variable, 0, 0, - cmCacheManager::UNINITIALIZED); + manager->AddCacheEntry(variable, 0, 0, cmCacheManager::UNINITIALIZED); overwrite = true; } - it.Find(variable); - if ( it.IsAtEnd() ) + if (!manager->GetCacheEntryValue(variable)) { cmSystemTools::Error("This should never happen..."); return false; } - if ( !it.PropertyExists("ADVANCED") || overwrite ) + if (!manager->GetCacheEntryProperty(variable, "ADVANCED") || overwrite) { - it.SetProperty("ADVANCED", value); + manager->SetCacheEntryProperty(variable, "ADVANCED", value); } } return true; 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..baf5b1e 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; } @@ -46,16 +42,16 @@ bool cmOptionCommand std::string initialValue = "Off"; // Now check and see if the value has been stored in the cache // already, if so use that value and don't look for the program - cmCacheManager::CacheIterator it = - this->Makefile->GetCacheManager()->GetCacheIterator(args[0].c_str()); - if(!it.IsAtEnd()) + cmCacheManager* manager = this->Makefile->GetCacheManager(); + const char* existingValue = manager->GetCacheEntryValue(args[0]); + if(existingValue) { - if ( it.GetType() != cmCacheManager::UNINITIALIZED ) + if (manager->GetCacheEntryType(args[0]) != cmCacheManager::UNINITIALIZED) { - it.SetProperty("HELPSTRING", args[1].c_str()); + manager->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]); return true; } - initialValue = it.GetValue(); + initialValue = existingValue; } if(args.size() == 3) { 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..e7678cb 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,26 @@ 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); + + this->DefinePolicy( + CMP0060, "CMP0060", + "Link libraries by full path even in implicit directories.", + 3,3,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index c393c2f..1d108c1 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -113,6 +113,12 @@ 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. + CMP0060, ///< Link libraries by full path even in implicit directories. /** \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..e17474b 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) { @@ -146,9 +136,10 @@ bool cmSetCommand } // see if this is already in the cache - cmCacheManager::CacheIterator it = - this->Makefile->GetCacheManager()->GetCacheIterator(variable); - if(!it.IsAtEnd() && (it.GetType() != cmCacheManager::UNINITIALIZED)) + cmCacheManager* manager = this->Makefile->GetCacheManager(); + const char* existingValue = manager->GetCacheEntryValue(variable); + if(existingValue && + (manager->GetCacheEntryType(variable) != cmCacheManager::UNINITIALIZED)) { // if the set is trying to CACHE the value but the value // is already in the cache and the type is not internal diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 1150bc7..77f9fb9 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -452,11 +452,11 @@ bool cmSetPropertyCommand::HandleCacheMode() // Get the source file. cmMakefile* mf = this->GetMakefile(); cmake* cm = mf->GetCMakeInstance(); - cmCacheManager::CacheIterator it = - cm->GetCacheManager()->GetCacheIterator(ni->c_str()); - if(!it.IsAtEnd()) + const char* existingValue + = cm->GetCacheManager()->GetCacheEntryValue(*ni); + if(existingValue) { - if(!this->HandleCacheEntry(it)) + if(!this->HandleCacheEntry(*ni)) { return false; } @@ -474,22 +474,25 @@ bool cmSetPropertyCommand::HandleCacheMode() } //---------------------------------------------------------------------------- -bool cmSetPropertyCommand::HandleCacheEntry(cmCacheManager::CacheIterator& it) +bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey) { // Set or append the property. const char* name = this->PropertyName.c_str(); const char* value = this->PropertyValue.c_str(); + cmCacheManager* manager = this->Makefile->GetCacheManager(); if (this->Remove) { - value = 0; + manager->RemoveCacheEntryProperty(cacheKey, name); + return true; } if(this->AppendMode) { - it.AppendProperty(name, value, this->AppendAsString); + manager->AppendCacheEntryProperty(cacheKey, name, value, + this->AppendAsString); } else { - it.SetProperty(name, value); + manager->SetCacheEntryProperty(cacheKey, name, value); } return true; diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h index b06cb68..3285e60 100644 --- a/Source/cmSetPropertyCommand.h +++ b/Source/cmSetPropertyCommand.h @@ -61,7 +61,7 @@ private: bool HandleTestMode(); bool HandleTest(cmTest* test); bool HandleCacheMode(); - bool HandleCacheEntry(cmCacheManager::CacheIterator&); + bool HandleCacheEntry(std::string const&); bool HandleInstallMode(); bool HandleInstall(cmInstalledFile* file); }; 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..95d05a6 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( @@ -1470,7 +1475,8 @@ bool cmSystemTools::IsPathToFramework(const char* path) bool cmSystemTools::CreateTar(const char* outFileName, const std::vector<std::string>& files, cmTarCompression compressType, - bool verbose, std::string const& mtime) + bool verbose, std::string const& mtime, + std::string const& format) { #if defined(CMAKE_BUILD_WITH_CMAKE) std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); @@ -1500,8 +1506,10 @@ bool cmSystemTools::CreateTar(const char* outFileName, compress = cmArchiveWrite::CompressNone; break; } + cmArchiveWrite a(fout, compress, - cmArchiveWrite::TypeTAR); + format.empty() ? "paxr" : format); + a.SetMTime(mtime); a.SetVerbose(verbose); for(std::vector<std::string>::const_iterator i = files.begin(); @@ -2287,7 +2295,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 +2315,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 +2710,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..433ef46 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -395,7 +395,8 @@ public: static bool CreateTar(const char* outFileName, const std::vector<std::string>& files, cmTarCompression compressType, bool verbose, - std::string const& mtime = std::string()); + std::string const& mtime = std::string(), + std::string const& format = std::string()); static bool ExtractTar(const char* inFileName, bool verbose); // This should be called first thing in main // it will keep child processes from inheriting the @@ -428,11 +429,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..85e5165 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> @@ -441,6 +442,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) if(this->TargetTypeValue == cmTarget::EXECUTABLE) { this->SetPropertyDefault("ANDROID_GUI", 0); + this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", 0); } if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY || this->TargetTypeValue == cmTarget::MODULE_LIBRARY) @@ -615,6 +617,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 +1162,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 +1551,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 +1988,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 +2005,7 @@ static void processIncludeDirectories(cmTarget const* tgt, config, false, tgt, - dagChecker), + dagChecker, language), entryIncludes); std::string usedIncludes; @@ -2113,7 +2116,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 +2150,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceIncludeDirectoriesEntries; @@ -2186,7 +2191,8 @@ cmTarget::GetIncludeDirectories(const std::string& config) const uniqueIncludes, &dagChecker, config, - debugIncludes); + debugIncludes, + language); deleteAndClear(linkInterfaceIncludeDirectoriesEntries); @@ -2199,7 +2205,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 +2218,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 +2253,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 +2288,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 +2321,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileOptionsEntries; @@ -2325,7 +2337,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, uniqueOptions, &dagChecker, config, - debugOptions); + debugOptions, + language); deleteAndClear(linkInterfaceCompileOptionsEntries); } @@ -2336,16 +2349,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 +2392,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); std::vector<cmTargetInternals::TargetPropertyEntry*> linkInterfaceCompileDefinitionsEntries; @@ -2424,7 +2440,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, uniqueOptions, &dagChecker, config, - debugDefines); + debugDefines, + language); deleteAndClear(linkInterfaceCompileDefinitionsEntries); } @@ -2438,7 +2455,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 +4733,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 +4745,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 +4956,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 +5009,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, != theTarget->GetProperties().end(); PropertyType ifacePropContent = getTypedProperty<PropertyType>(theTarget, - interfaceProperty, 0); + interfaceProperty); std::string reportEntry; if (ifaceIsSet) @@ -5919,8 +5933,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 +6705,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 +6799,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 +6904,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..55bf234 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -34,7 +34,8 @@ F(CMP0041) \ F(CMP0042) \ F(CMP0046) \ - F(CMP0052) + F(CMP0052) \ + F(CMP0060) class cmake; class cmMakefile; @@ -496,7 +497,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 +528,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 +572,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 +583,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/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index f87a535..add80fa 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -82,11 +82,31 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // be translated. std::string exe = command[0]; cmMakefile* mf = this->Test->GetMakefile(); + cmLocalGenerator* lg = mf->GetLocalGenerator(); cmTarget* target = mf->FindTargetToUse(exe); if(target && target->GetType() == cmTarget::EXECUTABLE) { // Use the target file on disk. exe = target->GetFullPath(config); + + // Prepend with the emulator when cross compiling if required. + const char * emulator = + target->GetProperty("CROSSCOMPILING_EMULATOR"); + if (emulator != 0) + { + std::vector<std::string> emulatorWithArgs; + cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); + std::string emulatorExe(emulatorWithArgs[0]); + cmSystemTools::ConvertToUnixSlashes(emulatorExe); + os << lg->EscapeForCMake(emulatorExe) << " "; + for(std::vector<std::string>::const_iterator ei = + emulatorWithArgs.begin()+1; + ei != emulatorWithArgs.end(); + ++ei) + { + os << lg->EscapeForCMake(*ei) << " "; + } + } } else { @@ -96,7 +116,6 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, } // Generate the command line with full escapes. - cmLocalGenerator* lg = mf->GetLocalGenerator(); os << lg->EscapeForCMake(exe); for(std::vector<std::string>::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index b5280cf..63109e0 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -149,7 +149,8 @@ bool cmTryRunCommand { // "run" it and capture the output std::string runOutputContents; - if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING")) + if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING") && + !this->Makefile->IsDefinitionSet("CMAKE_CROSSCOMPILING_EMULATOR")) { this->DoNotRunExecutable(runArgs, argv[3], @@ -195,7 +196,28 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs, std::string* out) { int retVal = -1; - std::string finalCommand = cmSystemTools::ConvertToRunCommandPath( + + std::string finalCommand; + const std::string emulator = + this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR"); + if (!emulator.empty()) + { + std::vector<std::string> emulatorWithArgs; + cmSystemTools::ExpandListArgument(emulator, emulatorWithArgs); + finalCommand += cmSystemTools::ConvertToRunCommandPath( + emulatorWithArgs[0].c_str()); + finalCommand += " "; + for (std::vector<std::string>::const_iterator ei = + emulatorWithArgs.begin()+1; + ei != emulatorWithArgs.end(); ++ei) + { + finalCommand += "\""; + finalCommand += *ei; + finalCommand += "\""; + finalCommand += " "; + } + } + finalCommand += cmSystemTools::ConvertToRunCommandPath( this->OutputFile.c_str()); if (!runArgs.empty()) { @@ -264,11 +286,12 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, comment.c_str(), cmCacheManager::STRING); - cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()-> - GetCacheIterator(this->RunResultVariable.c_str()); - if ( !it.IsAtEnd() ) + cmCacheManager* manager = this->Makefile->GetCacheManager(); + const char* existingValue + = manager->GetCacheEntryValue(this->RunResultVariable); + if (existingValue) { - it.SetProperty("ADVANCED", "1"); + manager->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1"); } error = true; @@ -290,11 +313,13 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(), cmCacheManager::STRING); - cmCacheManager::CacheIterator it = this->Makefile->GetCacheManager()-> - GetCacheIterator(internalRunOutputName.c_str()); - if ( !it.IsAtEnd() ) + cmCacheManager* manager = this->Makefile->GetCacheManager(); + const char* existing = + manager->GetCacheEntryValue(internalRunOutputName); + if (existing) { - it.SetProperty("ADVANCED", "1"); + manager->SetCacheEntryProperty(internalRunOutputName, + "ADVANCED", "1"); } error = true; diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index ee1ff29..2799a9b 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -52,11 +52,13 @@ bool cmUtilitySourceCommand } else { + cmCacheManager *manager = + this->Makefile->GetCMakeInstance()->GetCacheManager(); haveCacheValue = (cacheValue && (strstr(cacheValue, "(IntDir)") == 0 || (intDir && strcmp(intDir, "$(IntDir)") == 0)) && - (this->Makefile->GetCacheMajorVersion() != 0 && - this->Makefile->GetCacheMinorVersion() != 0 )); + (manager->GetCacheMajorVersion() != 0 && + manager->GetCacheMinorVersion() != 0 )); } if(haveCacheValue) diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 80c1286..dd2a682 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -41,9 +41,9 @@ bool cmVariableRequiresCommand requirementsMet = false; notSet += args[i]; notSet += "\n"; - cmCacheManager::CacheIterator it = - this->Makefile->GetCacheManager()->GetCacheIterator(args[i].c_str()); - if(!it.IsAtEnd() && it.GetPropertyAsBool("ADVANCED")) + cmCacheManager* manager = this->Makefile->GetCacheManager(); + if(manager->GetCacheEntryValue(args[i]) && + manager->GetCacheEntryPropertyAsBool(args[i], "ADVANCED")) { hasAdvanced = true; } 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..dad6f93 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -461,6 +461,7 @@ void cmVisualStudio10TargetGenerator::Generate() this->WriteAllSources(); this->WriteDotNetReferences(); this->WriteEmbeddedResourceGroup(); + this->WriteXamlFilesGroup(); this->WriteWinRTReferences(); this->WriteProjectReferences(); this->WriteString( @@ -522,8 +523,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() this->WriteString("<DependentUpon>", 3); std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; - (*this->BuildFileStream ) << hFileName; - this->WriteString("</DependentUpon>\n", 3); + (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; std::vector<std::string> const * configs = this->GlobalGenerator->GetConfigurations(); @@ -546,6 +546,38 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() } } +void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() +{ + std::vector<cmSourceFile const*> xamlObjs; + this->GeneratorTarget->GetXamlSources(xamlObjs, ""); + if (!xamlObjs.empty()) + { + this->WriteString("<ItemGroup>\n", 1); + for (std::vector<cmSourceFile const*>::const_iterator + oi = xamlObjs.begin(); oi != xamlObjs.end(); ++oi) + { + std::string obj = (*oi)->GetFullPath(); + std::string xamlType; + const char * xamlTypeProperty = (*oi)->GetProperty("VS_XAML_TYPE"); + if (xamlTypeProperty) + { + xamlType = xamlTypeProperty; + } + else + { + xamlType = "Page"; + } + + this->WriteSource(xamlType, *oi, ">\n"); + this->WriteString("<SubType>Designer</SubType>\n", 3); + this->WriteString("</", 2); + (*this->BuildFileStream) << xamlType << ">\n"; + + } + this->WriteString("</ItemGroup>\n", 1); + } +} + void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences() { if(this->MSTools) @@ -1192,12 +1224,21 @@ WriteGroupSources(const char* name, void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf) { - if(this->IsResxHeader(sf->GetFullPath())) + std::string const& fileName = sf->GetFullPath(); + if (this->IsResxHeader(fileName)) { this->WriteSource("ClInclude", sf, ">\n"); this->WriteString("<FileType>CppForm</FileType>\n", 3); this->WriteString("</ClInclude>\n", 2); } + else if (this->IsXamlHeader(fileName)) + { + this->WriteSource("ClInclude", sf, ">\n"); + this->WriteString("<DependentUpon>", 3); + std::string xamlFileName = fileName.substr(0, fileName.find_last_of(".")); + (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n"; + this->WriteString("</ClInclude>\n", 2); + } else { this->WriteSource("ClInclude", sf); @@ -1669,6 +1710,17 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( " ", "\n", lang); } } + if (this->IsXamlSource(source->GetFullPath())) + { + (*this->BuildFileStream) << firstString; + firstString = ""; // only do firstString once + hasFlags = true; + this->WriteString("<DependentUpon>", 3); + const std::string& fileName = source->GetFullPath(); + std::string xamlFileName = fileName.substr(0, fileName.find_last_of(".")); + (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n"; + } + return hasFlags; } @@ -1876,7 +1928,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 +2575,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); @@ -2747,6 +2801,28 @@ bool cmVisualStudio10TargetGenerator:: return it != expectedResxHeaders.end(); } +bool cmVisualStudio10TargetGenerator:: +IsXamlHeader(const std::string& headerFile) +{ + std::set<std::string> expectedXamlHeaders; + this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, ""); + + std::set<std::string>::const_iterator it = + expectedXamlHeaders.find(headerFile); + return it != expectedXamlHeaders.end(); +} + +bool cmVisualStudio10TargetGenerator:: +IsXamlSource(const std::string& sourceFile) +{ + std::set<std::string> expectedXamlSources; + this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, ""); + + std::set<std::string>::const_iterator it = + expectedXamlSources.find(sourceFile); + return it != expectedXamlSources.end(); +} + void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings() { bool isAppContainer = false; diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index a02dfa8..a2776de 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -69,6 +69,7 @@ private: void WriteEmbeddedResourceGroup(); void WriteWinRTReferences(); void WriteWinRTPackageCertificateKeyFile(); + void WriteXamlFilesGroup(); void WritePathAndIncrementalLinkOptions(); void WriteItemDefinitionGroups(); void VerifyNecessaryFiles(); @@ -119,6 +120,8 @@ private: void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed, const std::vector<cmSourceGroup>& allGroups); bool IsResxHeader(const std::string& headerFile); + bool IsXamlHeader(const std::string& headerFile); + bool IsXamlSource(const std::string& headerFile); cmIDEFlagTable const* GetClFlagTable() const; cmIDEFlagTable const* GetRcFlagTable() const; diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index 3302a8d..5a90fd9 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -242,6 +242,7 @@ void cmXCodeObject::PrintString(std::ostream& os,std::string String) // considered special by the Xcode project file parser. bool needQuote = (String.empty() || + String.find("//") != String.npos || String.find_first_of(" <>.+-=@$[],") != String.npos); const char* quote = needQuote? "\"" : ""; 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..3654aa7 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); @@ -183,7 +188,6 @@ void cmake::InitializeProperties() { this->Properties.clear(); this->Properties.SetCMakeInstance(this); - this->AccessedProperties.clear(); this->PropertyDefinitions.clear(); // initialize properties @@ -208,7 +212,7 @@ void cmake::CleanupCommandsAndMacros() delete j->second; } } - this->Commands.erase(this->Commands.begin(), this->Commands.end()); + this->Commands.clear(); std::vector<cmCommand*>::iterator it; for ( it = commands.begin(); it != commands.end(); ++ it ) @@ -340,7 +344,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) std::string cachedValue; if(this->WarnUnusedCli) { - if(const char *v = this->CacheManager->GetCacheValue(var)) + if(const char *v = this->CacheManager + ->GetInitializedCacheValue(var)) { haveValue = true; cachedValue = v; @@ -353,7 +358,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) if(this->WarnUnusedCli) { if (!haveValue || - cachedValue != this->CacheManager->GetCacheValue(var)) + cachedValue != this->CacheManager + ->GetInitializedCacheValue(var)) { this->WatchUnusedCli(var); } @@ -397,17 +403,18 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) cmsys::Glob::PatternToRegex(entryPattern, true, true).c_str()); //go through all cache entries and collect the vars which will be removed std::vector<std::string> entriesToDelete; - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(); - for ( it.Begin(); !it.IsAtEnd(); it.Next() ) + std::vector<std::string> cacheKeys = + this->CacheManager->GetCacheEntryKeys(); + for (std::vector<std::string>::const_iterator it = cacheKeys.begin(); + it != cacheKeys.end(); ++it) { - cmCacheManager::CacheEntryType t = it.GetType(); + cmCacheManager::CacheEntryType t = + this->CacheManager->GetCacheEntryType(*it); if(t != cmCacheManager::STATIC) { - std::string entryName = it.GetName(); - if (regex.find(entryName.c_str())) + if (regex.find(it->c_str())) { - entriesToDelete.push_back(entryName); + entriesToDelete.push_back(*it); } } } @@ -811,6 +818,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, if(i >= args.size()) { cmSystemTools::Error("No generator specified for -G"); + this->PrintGeneratorList(); return; } value = args[i]; @@ -821,6 +829,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, { cmSystemTools::Error("Could not create named generator ", value.c_str()); + this->PrintGeneratorList(); } else { @@ -911,16 +920,18 @@ void cmake::SetDirectoriesFromFile(const char* arg) // If there is a CMakeCache.txt file, use its settings. if(!cachePath.empty()) { - cmCacheManager* cachem = this->GetCacheManager(); - cmCacheManager::CacheIterator it = cachem->NewIterator(); - if(cachem->LoadCache(cachePath) && - it.Find("CMAKE_HOME_DIRECTORY")) + if(this->LoadCache(cachePath)) { - this->SetHomeOutputDirectory(cachePath); - this->SetStartOutputDirectory(cachePath); - this->SetHomeDirectory(it.GetValue()); - this->SetStartDirectory(it.GetValue()); - return; + const char* existingValue = + this->CacheManager->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"); + if (existingValue) + { + this->SetHomeOutputDirectory(cachePath); + this->SetStartOutputDirectory(cachePath); + this->SetHomeDirectory(existingValue); + this->SetStartDirectory(existingValue); + return; + } } } @@ -1026,6 +1037,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(), @@ -1197,10 +1210,10 @@ int cmake::DoPreConfigureChecks() } // do a sanity check on some values - if(this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY")) + if(this->CacheManager->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY")) { std::string cacheStart = - this->CacheManager->GetCacheValue("CMAKE_HOME_DIRECTORY"); + this->CacheManager->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY"); cacheStart += "/CMakeLists.txt"; std::string currentStart = this->GetHomeDirectory(); currentStart += "/CMakeLists.txt"; @@ -1349,9 +1362,9 @@ int cmake::ActualConfigure() if(!this->GlobalGenerator) { const char* genName = - this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); + this->CacheManager->GetInitializedCacheValue("CMAKE_GENERATOR"); const char* extraGenName = - this->CacheManager->GetCacheValue("CMAKE_EXTRA_GENERATOR"); + this->CacheManager->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); if(genName) { std::string fullName = cmExternalMakefileProjectGenerator:: @@ -1429,7 +1442,8 @@ int cmake::ActualConfigure() } } - const char* genName = this->CacheManager->GetCacheValue("CMAKE_GENERATOR"); + const char* genName = this->CacheManager + ->GetInitializedCacheValue("CMAKE_GENERATOR"); if(genName) { if(!this->GlobalGenerator->MatchesGeneratorName(genName)) @@ -1445,7 +1459,7 @@ int cmake::ActualConfigure() return -2; } } - if(!this->CacheManager->GetCacheValue("CMAKE_GENERATOR")) + if(!this->CacheManager->GetInitializedCacheValue("CMAKE_GENERATOR")) { this->CacheManager->AddCacheEntry("CMAKE_GENERATOR", this->GlobalGenerator->GetName().c_str(), @@ -1458,7 +1472,7 @@ int cmake::ActualConfigure() } if(const char* platformName = - this->CacheManager->GetCacheValue("CMAKE_GENERATOR_PLATFORM")) + this->CacheManager->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if(this->GeneratorPlatform.empty()) { @@ -1486,7 +1500,7 @@ int cmake::ActualConfigure() } if(const char* tsName = - this->CacheManager->GetCacheValue("CMAKE_GENERATOR_TOOLSET")) + this->CacheManager->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) { if(this->GeneratorToolset.empty()) { @@ -1540,16 +1554,18 @@ int cmake::ActualConfigure() // project requires compatibility with CMake 2.4. We detect this // here by looking for the old CMAKE_BACKWARDS_COMPATIBILITY // variable created when CMP0001 is not set to NEW. - if(this->GetCacheManager()->GetCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")) + if(this->GetCacheManager() + ->GetInitializedCacheValue("CMAKE_BACKWARDS_COMPATIBILITY")) { - if(!this->CacheManager->GetCacheValue("LIBRARY_OUTPUT_PATH")) + if(!this->CacheManager->GetInitializedCacheValue("LIBRARY_OUTPUT_PATH")) { this->CacheManager->AddCacheEntry ("LIBRARY_OUTPUT_PATH", "", "Single output directory for building all libraries.", cmCacheManager::PATH); } - if(!this->CacheManager->GetCacheValue("EXECUTABLE_OUTPUT_PATH")) + if(!this->CacheManager + ->GetInitializedCacheValue("EXECUTABLE_OUTPUT_PATH")) { this->CacheManager->AddCacheEntry ("EXECUTABLE_OUTPUT_PATH", "", @@ -1557,24 +1573,25 @@ int cmake::ActualConfigure() cmCacheManager::PATH); } } - if(!this->CacheManager->GetCacheValue("CMAKE_USE_RELATIVE_PATHS")) + if(!this->CacheManager + ->GetInitializedCacheValue("CMAKE_USE_RELATIVE_PATHS")) { this->CacheManager->AddCacheEntry ("CMAKE_USE_RELATIVE_PATHS", "OFF", "If true, cmake will use relative paths in makefiles and projects.", cmCacheManager::BOOL); - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator("CMAKE_USE_RELATIVE_PATHS"); - if ( !it.PropertyExists("ADVANCED") ) + if (!this->CacheManager->GetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", + "ADVANCED")) { - it.SetProperty("ADVANCED", "1"); + this->CacheManager->SetCacheEntryProperty("CMAKE_USE_RELATIVE_PATHS", + "ADVANCED", "1"); } } if(cmSystemTools::GetFatalErrorOccured() && - (!this->CacheManager->GetCacheValue("CMAKE_MAKE_PROGRAM") || + (!this->CacheManager->GetInitializedCacheValue("CMAKE_MAKE_PROGRAM") || cmSystemTools::IsOff(this->CacheManager-> - GetCacheValue("CMAKE_MAKE_PROGRAM")))) + GetInitializedCacheValue("CMAKE_MAKE_PROGRAM")))) { // We must have a bad generator selection. Wipe the cache entry so the // user can select another. @@ -1790,7 +1807,7 @@ void cmake::AddCacheEntry(const std::string& key, const char* value, const char* cmake::GetCacheDefinition(const std::string& name) const { - return this->CacheManager->GetCacheValue(name); + return this->CacheManager->GetInitializedCacheValue(name); } void cmake::AddDefaultCommands() @@ -1811,23 +1828,23 @@ void cmake::AddDefaultGenerators() #if defined(_WIN32) && !defined(__CYGWIN__) # if !defined(CMAKE_BOOT_MINGW) this->Generators.push_back( - cmGlobalVisualStudio6Generator::NewFactory()); - this->Generators.push_back( - cmGlobalVisualStudio7Generator::NewFactory()); + cmGlobalVisualStudio14Generator::NewFactory()); this->Generators.push_back( - cmGlobalVisualStudio10Generator::NewFactory()); + cmGlobalVisualStudio12Generator::NewFactory()); this->Generators.push_back( cmGlobalVisualStudio11Generator::NewFactory()); this->Generators.push_back( - cmGlobalVisualStudio12Generator::NewFactory()); + cmGlobalVisualStudio10Generator::NewFactory()); this->Generators.push_back( - cmGlobalVisualStudio14Generator::NewFactory()); + cmGlobalVisualStudio9Generator::NewFactory()); + this->Generators.push_back( + cmGlobalVisualStudio8Generator::NewFactory()); this->Generators.push_back( cmGlobalVisualStudio71Generator::NewFactory()); this->Generators.push_back( - cmGlobalVisualStudio8Generator::NewFactory()); + cmGlobalVisualStudio7Generator::NewFactory()); this->Generators.push_back( - cmGlobalVisualStudio9Generator::NewFactory()); + cmGlobalVisualStudio6Generator::NewFactory()); this->Generators.push_back( cmGlobalBorlandMakefileGenerator::NewFactory()); this->Generators.push_back( @@ -1854,10 +1871,18 @@ void cmake::AddDefaultGenerators() #endif } +bool cmake::ParseCacheEntry(const std::string& entry, + std::string& var, + std::string& value, + cmCacheManager::CacheEntryType& type) +{ + return cmCacheManager::ParseEntry(entry, var, value, type); +} + int cmake::LoadCache() { // could we not read the cache - if (!this->CacheManager->LoadCache(this->GetHomeOutputDirectory())) + if (!this->LoadCache(this->GetHomeOutputDirectory())) { // if it does exist, but isn't readable then warn the user std::string cacheFile = this->GetHomeOutputDirectory(); @@ -1880,6 +1905,28 @@ int cmake::LoadCache() return 0; } +bool cmake::LoadCache(const std::string& path) +{ + return this->CacheManager->LoadCache(path); +} + +bool cmake::LoadCache(const std::string& path, bool internal, + std::set<std::string>& excludes, + std::set<std::string>& includes) +{ + return this->CacheManager->LoadCache(path, internal, excludes, includes); +} + +bool cmake::SaveCache(const std::string& path) +{ + return this->CacheManager->SaveCache(path); +} + +bool cmake::DeleteCache(const std::string& path) +{ + return this->CacheManager->DeleteCache(path); +} + void cmake::SetProgressCallback(ProgressCallbackType f, void *cd) { this->ProgressCallback = f; @@ -1916,11 +1963,24 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) } } +void cmake::PrintGeneratorList() +{ +#ifdef CMAKE_BUILD_WITH_CMAKE + cmDocumentation doc; + std::vector<cmDocumentationEntry> generators; + this->GetGeneratorDocumentation(generators); + doc.AppendSection("Generators",generators); + std::cerr << "\n"; + doc.PrintDocumentation(cmDocumentation::ListGenerators, std::cerr); +#endif +} + void cmake::UpdateConversionPathTable() { // Update the path conversion table with any specified file: const char* tablepath = - this->CacheManager->GetCacheValue("CMAKE_PATH_TRANSLATION_FILE"); + this->CacheManager + ->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE"); if(tablepath) { @@ -2154,7 +2214,7 @@ void cmake::TruncateOutputLog(const char* fname) { return; } - if ( !this->CacheManager->GetCacheValue("CMAKE_CACHEFILE_DIR") ) + if ( !this->CacheManager->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR") ) { cmSystemTools::RemoveFile(fullPath); return; @@ -2267,23 +2327,13 @@ const char *cmake::GetProperty(const std::string& prop) const char *cmake::GetProperty(const std::string& prop, cmProperty::ScopeType scope) { - bool chain = false; - // watch for special properties std::string output = ""; if ( prop == "CACHE_VARIABLES" ) { - cmCacheManager::CacheIterator cit = - this->GetCacheManager()->GetCacheIterator(); - for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() ) - { - if (!output.empty()) - { - output += ";"; - } - output += cit.GetName(); - } - this->SetProperty("CACHE_VARIABLES", output.c_str()); + std::vector<std::string> cacheKeys = + this->CacheManager->GetCacheEntryKeys(); + this->SetProperty("CACHE_VARIABLES", cmJoin(cacheKeys, ";").c_str()); } else if ( prop == "COMMANDS" ) { @@ -2326,7 +2376,8 @@ const char *cmake::GetProperty(const std::string& prop, return FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT) + 1; } #undef STRING_LIST_ELEMENT - return this->Properties.GetPropertyValue(prop, scope, chain); + bool dummy = false; + return this->Properties.GetPropertyValue(prop, scope, dummy); } bool cmake::GetPropertyAsBool(const std::string& prop) @@ -2401,6 +2452,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) if(i >= args.size()) { cmSystemTools::Error("No generator specified for -G"); + this->PrintGeneratorList(); return -1; } value = args[i]; @@ -2411,6 +2463,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) { cmSystemTools::Error("Could not create named generator ", value.c_str()); + this->PrintGeneratorList(); } else { @@ -2434,7 +2487,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // we have to find the module directory, so we can copy the files this->AddCMakePaths(); std::string modulesPath = - this->CacheManager->GetCacheValue("CMAKE_ROOT"); + this->CacheManager->GetInitializedCacheValue("CMAKE_ROOT"); modulesPath += "/Modules"; std::string inFile = modulesPath; inFile += "/SystemInformation.cmake"; @@ -2644,9 +2697,9 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text, if(t == cmake::AUTHOR_WARNING) { // Allow suppression of these warnings. - cmCacheManager::CacheIterator it = this->CacheManager - ->GetCacheIterator("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); - if(!it.IsAtEnd() && it.GetValueAsBool()) + const char* suppress = this->CacheManager->GetCacheEntryValue( + "CMAKE_SUPPRESS_DEVELOPER_WARNINGS"); + if(suppress && cmSystemTools::IsOn(suppress)) { return; } @@ -2731,11 +2784,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()) @@ -2760,39 +2812,48 @@ int cmake::Build(const std::string& dir, } std::string cachePath = dir; cmSystemTools::ConvertToUnixSlashes(cachePath); - cmCacheManager* cachem = this->GetCacheManager(); - cmCacheManager::CacheIterator it = cachem->NewIterator(); - if(!cachem->LoadCache(cachePath)) + if(!this->LoadCache(cachePath)) { std::cerr << "Error: could not load cache\n"; return 1; } - if(!it.Find("CMAKE_GENERATOR")) + const char* cachedGenerator = + this->CacheManager->GetCacheEntryValue("CMAKE_GENERATOR"); + if(!cachedGenerator) { std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; return 1; } cmsys::auto_ptr<cmGlobalGenerator> gen( - this->CreateGlobalGenerator(it.GetValue())); + this->CreateGlobalGenerator(cachedGenerator)); if(!gen.get()) { std::cerr << "Error: could create CMAKE_GENERATOR \"" - << it.GetValue() << "\"\n"; + << cachedGenerator << "\"\n"; return 1; } std::string output; std::string projName; - if(!it.Find("CMAKE_PROJECT_NAME")) + const char* cachedProjectName = + this->CacheManager->GetCacheEntryValue("CMAKE_PROJECT_NAME"); + if(!cachedProjectName) { std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; return 1; } - projName = it.GetValue(); + projName = cachedProjectName; + bool verbose = false; + const char* cachedVerbose = + this->CacheManager->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE"); + if(cachedVerbose) + { + verbose = cmSystemTools::IsOn(cachedVerbose); + } return gen->Build("", dir, projName, target, output, "", - config, clean, false, 0, + config, clean, false, verbose, 0, cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmake.h b/Source/cmake.h index 60ffcd4..0715d74 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -18,11 +18,11 @@ #include "cmPropertyDefinitionMap.h" #include "cmPropertyMap.h" #include "cmInstalledFile.h" +#include "cmCacheManager.h" class cmGlobalGeneratorFactory; class cmGlobalGenerator; class cmLocalGenerator; -class cmCacheManager; class cmMakefile; class cmCommand; class cmVariableWatch; @@ -173,7 +173,19 @@ class cmake int Configure(); int ActualConfigure(); + ///! Break up a line like VAR:type="value" into var, type and value + static bool ParseCacheEntry(const std::string& entry, + std::string& var, + std::string& value, + cmCacheManager::CacheEntryType& type); + int LoadCache(); + bool LoadCache(const std::string& path); + bool LoadCache(const std::string& path, bool internal, + std::set<std::string>& excludes, + std::set<std::string>& includes); + bool SaveCache(const std::string& path); + bool DeleteCache(const std::string& path); void PreLoadCMakeFiles(); ///! Create a GlobalGenerator @@ -287,9 +299,6 @@ class cmake cmProperty::ScopeType scope); bool GetPropertyAsBool(const std::string& prop); - // Get the properties - cmPropertyMap &GetProperties() { return this->Properties; } - ///! Get or create an cmInstalledFile instance and return a pointer to it cmInstalledFile *GetOrCreateInstalledFile( cmMakefile* mf, const std::string& name); @@ -383,7 +392,6 @@ protected: void InitializeProperties(); int HandleDeleteCacheVariables(const std::string& var); cmPropertyMap Properties; - std::set<std::pair<std::string,cmProperty::ScopeType> > AccessedProperties; std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions; @@ -468,6 +476,9 @@ private: InstalledFilesMap InstalledFiles; void UpdateConversionPathTable(); + + // Print a list of valid generators to stderr. + void PrintGeneratorList(); }; #define CMAKE_STANDARD_OPTIONS_TABLE \ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index e0bd55b..3b518be 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 @@ -327,25 +328,31 @@ int do_cmake(int ac, char const* const* av) int res = cm.Run(args, view_only); if ( list_cached || list_all_cached ) { - cmCacheManager::CacheIterator it = - cm.GetCacheManager()->GetCacheIterator(); std::cout << "-- Cache values" << std::endl; - for ( it.Begin(); !it.IsAtEnd(); it.Next() ) + std::vector<std::string> keys = + cm.GetCacheManager()->GetCacheEntryKeys(); + for (std::vector<std::string>::const_iterator it = keys.begin(); + it != keys.end(); ++it) { - cmCacheManager::CacheEntryType t = it.GetType(); + cmCacheManager::CacheEntryType t = + cm.GetCacheManager()->GetCacheEntryType(*it); if ( t != cmCacheManager::INTERNAL && t != cmCacheManager::STATIC && t != cmCacheManager::UNINITIALIZED ) { - bool advanced = it.PropertyExists("ADVANCED"); - if ( list_all_cached || !advanced) + const char* advancedProp = + cm.GetCacheManager()->GetCacheEntryProperty(*it, "ADVANCED"); + if ( list_all_cached || !advancedProp) { if ( list_help ) { - std::cout << "// " << it.GetProperty("HELPSTRING") << std::endl; + std::cout << "// " + << cm.GetCacheManager()->GetCacheEntryProperty(*it, + "HELPSTRING") << std::endl; } - std::cout << it.GetName() << ":" << - cmCacheManager::TypeToString(it.GetType()) - << "=" << it.GetValue() << std::endl; + std::cout << *it << ":" << + cmCacheManager::TypeToString(t) + << "=" << cm.GetCacheManager()->GetCacheEntryValue(*it) + << std::endl; if ( list_help ) { std::cout << std::endl; diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 28fcd27..2ef04ef 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; @@ -771,10 +703,20 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Tar files else if (args[1] == "tar" && args.size() > 3) { + const char* knownFormats[] = + { + "7zip", + "gnutar", + "pax", + "paxr", + "zip" + }; + std::string flags = args[2]; std::string outFile = args[3]; std::vector<std::string> files; std::string mtime; + std::string format; bool doing_options = true; for (std::string::size_type cc = 4; cc < args.size(); cc ++) { @@ -797,6 +739,19 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) return 1; } } + else if (cmHasLiteralPrefix(arg, "--format=")) + { + format = arg.substr(9); + bool isKnown = std::find(cmArrayBegin(knownFormats), + cmArrayEnd(knownFormats), format) != cmArrayEnd(knownFormats); + + if(!isKnown) + { + cmSystemTools::Error("Unknown -E tar --format= argument: ", + format.c_str()); + return 1; + } + } else { cmSystemTools::Error("Unknown option to -E tar: ", arg.c_str()); @@ -827,7 +782,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) compress = cmSystemTools::TarCompressGZip; ++nCompress; } - if ( nCompress > 1 ) + if ( (format == "7zip" || format == "zip") && nCompress > 0 ) + { + cmSystemTools::Error("Can not use compression flags with format: ", + format.c_str()); + return 1; + } + else if ( nCompress > 1 ) { cmSystemTools::Error("Can only compress a tar file one way; " "at most one flag of z, j, or J may be used"); @@ -849,7 +810,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) else if ( flags.find_first_of('c') != flags.npos ) { if ( !cmSystemTools::CreateTar( - outFile.c_str(), files, compress, verbose, mtime) ) + outFile.c_str(), files, compress, verbose, mtime, format) ) { cmSystemTools::Error("Problem creating tar: ", outFile.c_str()); return 1; @@ -987,7 +948,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 +1016,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 +1035,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 +1105,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 +1344,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 b9b65a0..6c4a7a6 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 @@ -3057,10 +3102,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..1e60abe 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, @@ -195,7 +218,6 @@ if(BUILD_TESTING) ADD_TEST_MACRO(FindModulesExecuteAll FindModulesExecuteAll) ADD_TEST_MACRO(StringFileTest StringFileTest) ADD_TEST_MACRO(TryCompile TryCompile) - ADD_TEST_MACRO(TarTest TarTest) ADD_TEST_MACRO(SystemInformation SystemInformation) ADD_TEST_MACRO(MathTest MathTest) ADD_TEST_MACRO(CompileFeatures CompileFeatures) @@ -549,7 +571,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 +861,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 +946,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 +964,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 +990,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 +1036,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() @@ -1036,21 +1095,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release "${CMake_BINARY_DIR}/Tests/CMakeTestAllGenerators") endif() - if(NOT DEFINED CTEST_RUN_CMakeTestBadCommandLines) - set(CTEST_RUN_CMakeTestBadCommandLines ON) - endif() - - if(CTEST_RUN_CMakeTestBadCommandLines) - add_test(CMakeTestBadCommandLines ${CMAKE_CMAKE_COMMAND} - -D dir=${CMake_BINARY_DIR}/Tests/CMakeTestBadCommandLines - -D gen=${CMAKE_GENERATOR} - -D CMake_SOURCE_DIR=${CMake_SOURCE_DIR} - -P ${CMake_SOURCE_DIR}/Tests/CMakeTestBadCommandLines/RunCMake.cmake - ) - list(APPEND TEST_BUILD_DIRS - "${CMake_BINARY_DIR}/Tests/CMakeTestBadCommandLines") - endif() - if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures) set(CTEST_RUN_CMakeTestMultipleConfigures ON) endif() @@ -1251,6 +1295,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 +1532,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" @@ -1855,6 +1911,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_test_VSWinStorePhone(vs12-store81-X86 "Visual Studio 12 2013" WindowsStore 8.1) add_test_VSWinStorePhone(vs12-store81-ARM "Visual Studio 12 2013 ARM" WindowsStore 8.1) add_test_VSWinStorePhone(vs12-store81-X64 "Visual Studio 12 2013 Win64" WindowsStore 8.1) + + add_test(NAME VSXaml COMMAND ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/VSXaml" + "${CMake_BINARY_DIR}/Tests/VSXaml" + --build-generator "Visual Studio 12 2013" + --build-project VSXaml + --build-config $<CONFIGURATION> + --build-options -DCMAKE_SYSTEM_NAME=WindowsStore + -DCMAKE_SYSTEM_VERSION=8.1 + ) endif() if(vs11 AND wp80) add_test_VSWinStorePhone(vs11-phone80-X86 "Visual Studio 11 2012" WindowsPhone 8.0) @@ -2273,12 +2340,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" @ONLY ESCAPE_QUOTES) add_test(CTestCoverageCollectGCOV ${CMAKE_CTEST_COMMAND} + -C \${CTEST_CONFIGURATION_TYPE} -S "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" -VV --output-log "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/testOut.log" ) set_tests_properties(CTestCoverageCollectGCOV PROPERTIES PASS_REGULAR_EXPRESSION - "PASSED with correct output.*Testing/CoverageInfo/echoargs.gcov") + "PASSED with correct output.*Testing/CoverageInfo/main.cpp.gcov") configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in" @@ -2404,6 +2472,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 +2624,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 +2819,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/CMakeTestBadCommandLines/RunCMake.cmake b/Tests/CMakeTestBadCommandLines/RunCMake.cmake deleted file mode 100644 index 08549cc..0000000 --- a/Tests/CMakeTestBadCommandLines/RunCMake.cmake +++ /dev/null @@ -1,79 +0,0 @@ -if(NOT DEFINED CMake_SOURCE_DIR) - message(FATAL_ERROR "CMake_SOURCE_DIR not defined") -endif() - -if(NOT DEFINED dir) - message(FATAL_ERROR "dir not defined") -endif() - -if(NOT DEFINED gen) - message(FATAL_ERROR "gen not defined") -endif() - -message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") - -# First setup a source tree to run CMake on. -# -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast - ${dir}/Source -) - -execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory - ${dir}/Build - ) - -function(RunCMakeWithArgs) - message(STATUS "info: running cmake with ARGN='${ARGN}'") - - execute_process(COMMAND ${CMAKE_COMMAND} ${ARGN} - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr - WORKING_DIRECTORY ${dir}/Build - ) - - message(STATUS "result='${result}'") - message(STATUS "stdout='${stdout}'") - message(STATUS "stderr='${stderr}'") - message(STATUS "") -endfunction() - -# Run cmake once with no errors to get a good build tree: -# -RunCMakeWithArgs(-G ${gen} ../Source) - -# Run cmake with args that produce some sort of problem to cover the error -# cases in cmake.cxx... -# -# (These are not good examples of cmake command lines. Do not copy and -# paste them elsewhere and expect them to work... See the cmake -# documentation or other real examples of usage instead.) -# -RunCMakeWithArgs() -RunCMakeWithArgs(-C) -RunCMakeWithArgs(-C nosuchcachefile.txt) -RunCMakeWithArgs(--check-stamp-file nostampfile) -RunCMakeWithArgs(--check-stamp-list nostamplist) -RunCMakeWithArgs(nosuchsubdir/CMakeCache.txt) -RunCMakeWithArgs(nosuchsubdir/CMakeLists.txt) -RunCMakeWithArgs(-D) -RunCMakeWithArgs(--debug-output .) -RunCMakeWithArgs(--debug-trycompile .) -RunCMakeWithArgs(-E) -RunCMakeWithArgs(-E create_symlink) -RunCMakeWithArgs(-E echo_append) -RunCMakeWithArgs(-E rename) -RunCMakeWithArgs(-E touch_nocreate) -RunCMakeWithArgs(-G) -RunCMakeWithArgs(--graphviz= ../Source) -RunCMakeWithArgs(--graphviz=g.dot .) -RunCMakeWithArgs(-P) -RunCMakeWithArgs(-P nosuchscriptfile.cmake) -RunCMakeWithArgs(--trace .) -RunCMakeWithArgs(-U) -RunCMakeWithArgs(-U nosuchvariable .) -RunCMakeWithArgs(-V) -RunCMakeWithArgs(-V .) -RunCMakeWithArgs(-Wno-dev .) -RunCMakeWithArgs(-Wdev .) 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/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp new file mode 100644 index 0000000..85e6cd8 --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/3rdparty/foo.cpp @@ -0,0 +1 @@ +void foo() {} diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt b/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt new file mode 100644 index 0000000..ce6fac4 --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.2) + +project(TestProject CXX) + +include(CTest) + +set(SOURCES + main.cpp + 3rdparty/foo.cpp + extra/extra.cpp +) + +add_executable(myexecutable ${SOURCES}) + +set_property(SOURCE main.cpp APPEND PROPERTY LABELS SourceLabel) +set_property(TARGET myexecutable APPEND PROPERTY LABELS TargetLabel) + +set(MYEXECUTABLE_INFO_FILE "${CMAKE_CURRENT_BINARY_DIR}/myexecutable_info.cmake") + +file(WRITE "${MYEXECUTABLE_INFO_FILE}" " + set(TARGET myexecutable) + set(SOURCE_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\") + set(SOURCES \"${SOURCES}\") +") + +add_custom_command(TARGET myexecutable + POST_BUILD + COMMAND ${CMAKE_COMMAND} + "-DINFO_FILE=${MYEXECUTABLE_INFO_FILE}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/fake_compile_time_gcno.cmake" + VERBATIM +) + +add_test(NAME mytest + COMMAND ${CMAKE_COMMAND} + "-DMYEXECUTABLE=$<TARGET_FILE:myexecutable>" + "-DTARGETDIR=${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/myexecutable.dir" + -P "${CMAKE_CURRENT_SOURCE_DIR}/fake_run_time_gcda.cmake" +) + +set_property(TEST mytest APPEND PROPERTY LABELS TestLabel) diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp new file mode 100644 index 0000000..c3a2c12 --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/extra/extra.cpp @@ -0,0 +1 @@ +void extra() {} diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake b/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake new file mode 100644 index 0000000..881460b --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/fake_compile_time_gcno.cmake @@ -0,0 +1,7 @@ +include("${INFO_FILE}") + +foreach(source ${SOURCES}) + file(WRITE "CMakeFiles/${TARGET}.dir/${source}.gcno" + "${SOURCE_DIR}/${source}" + ) +endforeach() diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake b/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake new file mode 100644 index 0000000..26ce2bd --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/fake_run_time_gcda.cmake @@ -0,0 +1,12 @@ +execute_process(COMMAND ${MYEXECUTABLE} RESULT_VARIABLE RESULT) + +if(NOT RESULT_VARIABLE STREQUAL "0") + message("Test failure") +endif() + +file(GLOB_RECURSE gcno_files "${TARGETDIR}/*.gcno") + +foreach(gcno_file ${gcno_files}) + string(REPLACE ".gcno" ".gcda" gcda_file "${gcno_file}") + configure_file(${gcno_file} ${gcda_file} COPYONLY) +endforeach() diff --git a/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp b/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp new file mode 100644 index 0000000..237c8ce --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/TestProject/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake index e704f14..b0c3a9b 100644 --- a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake +++ b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake @@ -3,6 +3,12 @@ foreach(I RANGE 0 ${CMAKE_ARGC}) set(gcda_file "${CMAKE_ARGV${I}}") endif() endforeach() -get_filename_component(gcda_file ${gcda_file} NAME_WE) -file(WRITE "${CMAKE_SOURCE_DIR}/${gcda_file}.gcov" -"fake gcov file") + +get_filename_component(gcda_name ${gcda_file} NAME) +string(REPLACE ".gcda" ".gcov" gcov_name "${gcda_name}") + +file(STRINGS "${gcda_file}" source_file LIMIT_COUNT 1 ENCODING UTF-8) + +file(WRITE "${CMAKE_SOURCE_DIR}/${gcov_name}" + " -: 0:Source:${source_file}" +) diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in index 4bdcb10..29f7e7f 100644 --- a/Tests/CTestCoverageCollectGCOV/test.cmake.in +++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in @@ -1,16 +1,21 @@ cmake_minimum_required(VERSION 2.8.12) -set(CTEST_PROJECT_NAME "SmallAndFast") -set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTest/SmallAndFast") -set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV") +set(CTEST_PROJECT_NAME "TestProject") +set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/TestProject") +set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV/TestProject") set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") + +ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) + ctest_start(Experimental) ctest_configure() ctest_build() ctest_test() -file(WRITE ${CTEST_BINARY_DIRECTORY}/CMakeFiles/echoargs.dir/echoargs.gcda -"dummy -") +list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE + "/foo/something" + "/3rdparty/" + "/bar/somethingelse" +) include(CTestCoverageCollectGCOV) set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar) @@ -22,15 +27,21 @@ ctest_coverage_collect_gcov( GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake") execute_process(COMMAND - ${CMAKE_COMMAND} -E tar tf ${tar_file} - OUTPUT_VARIABLE out - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + ${CMAKE_COMMAND} -E tar tf ${tar_file} + OUTPUT_VARIABLE out + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +string(REPLACE "\n" ";" out "${out}") +list(SORT out) set(expected_out -"Testing/CoverageInfo/echoargs.gcov -Testing/CoverageInfo/data.json -CMakeFiles/echoargs.dir/Labels.json -") + CMakeFiles/myexecutable.dir/Labels.json + Testing/CoverageInfo/data.json + Testing/CoverageInfo/extra.cpp.gcov + Testing/CoverageInfo/main.cpp.gcov +) if("${out}" STREQUAL "${expected_out}") message("PASSED with correct output: ${out}") 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/TarTest/TestTarExec.cxx b/Tests/CTestTestVerboseOutput/nop.c index 86f2cd1..f8b643a 100644 --- a/Tests/TarTest/TestTarExec.cxx +++ b/Tests/CTestTestVerboseOutput/nop.c @@ -2,4 +2,3 @@ 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/CompileFeatures/cxx_generalized_initializers.cpp b/Tests/CompileFeatures/cxx_generalized_initializers.cpp index 7bf356b..ad05f12 100644 --- a/Tests/CompileFeatures/cxx_generalized_initializers.cpp +++ b/Tests/CompileFeatures/cxx_generalized_initializers.cpp @@ -1,3 +1,6 @@ +#if defined(_MSC_VER) && _MSC_VER == 1800 && _MSC_FULL_VER < 180030723 +# error "VS 2013 safely supports this only with Update 3 or greater" +#endif // Dummy implementation. Test only the compiler feature. namespace std { @@ -7,8 +10,9 @@ namespace std { { const _E* __begin_; size_t __size_; - - initializer_list(const int*, long unsigned int) {} + public: + template <typename T1, typename T2> + initializer_list(T1, T2) {} }; } 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/CMP0060/CMP0060-Common.cmake b/Tests/RunCMake/CMP0060/CMP0060-Common.cmake new file mode 100644 index 0000000..e0a56e6 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-Common.cmake @@ -0,0 +1,35 @@ +# Always build in a predictable configuration. For multi-config +# generators we depend on RunCMakeTest.cmake to do this for us. +if(NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Debug) +endif() + +# Convince CMake that it can instruct the linker to search for the +# library of the proper linkage type, but do not really pass flags. +set(CMAKE_EXE_LINK_STATIC_C_FLAGS " ") +set(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS " ") + +# Make a link line asking for the linker to search for the library +# look like a missing object file so we will get predictable content +# in the error message. This also ensures that cases expected to use +# the full path can be verified by confirming that they link. +set(CMAKE_LINK_LIBRARY_FLAG LINKFLAG_) +set(CMAKE_LINK_LIBRARY_SUFFIX _LINKSUFFIX${CMAKE_C_OUTPUT_EXTENSION}) + +# Convince CMake that our library is in an implicit linker search directory. +list(APPEND CMAKE_C_IMPLICIT_LINK_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/lib) + +# Create a simple library file. Place it in our library directory. +add_library(CMP0060 STATIC cmp0060.c) +set_property(TARGET CMP0060 PROPERTY + ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib) + +# Add a target to link the library file by full path. +add_executable(main1 main.c) +target_link_libraries(main1 $<TARGET_FILE:CMP0060>) +add_dependencies(main1 CMP0060) + +# Add a second target to verify the warning only appears once. +add_executable(main2 main.c) +target_link_libraries(main2 $<TARGET_FILE:CMP0060>) +add_dependencies(main2 CMP0060) diff --git a/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake b/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake new file mode 100644 index 0000000..0414e4b --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0060 NEW) +include(CMP0060-Common.cmake) diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt new file mode 100644 index 0000000..240764c --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-OLD-Build-stdout.txt @@ -0,0 +1 @@ +LINKFLAG_CMP0060_LINKSUFFIX diff --git a/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake b/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake new file mode 100644 index 0000000..a9cffef --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0060 OLD) +include(CMP0060-Common.cmake) diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt new file mode 100644 index 0000000..240764c --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF-Build-stdout.txt @@ -0,0 +1 @@ +LINKFLAG_CMP0060_LINKSUFFIX diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake new file mode 100644 index 0000000..6b84565 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-OFF.cmake @@ -0,0 +1 @@ +include(CMP0060-Common.cmake) diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt new file mode 100644 index 0000000..240764c --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-Build-stdout.txt @@ -0,0 +1 @@ +LINKFLAG_CMP0060_LINKSUFFIX diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt new file mode 100644 index 0000000..f6cc978 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-stderr.txt @@ -0,0 +1,16 @@ +^CMake Warning \(dev\) at CMP0060-Common.cmake:[0-9]+ \(add_executable\): + Policy CMP0060 is not set: Link libraries by full path even in implicit + directories. Run "cmake --help-policy CMP0060" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + Some library files are in directories implicitly searched by the linker + when invoked for C: + + .*/Tests/RunCMake/CMP0060/CMP0060-WARN-ON-build/lib/(lib)?CMP0060.(a|lib) + + For compatibility with older versions of CMake, the generated link line + will ask the linker to search for these by library name. +Call Stack \(most recent call first\): + CMP0060-WARN-ON.cmake:[0-9]+ \(include\) + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake new file mode 100644 index 0000000..a0a7950 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMP0060-WARN-ON.cmake @@ -0,0 +1,2 @@ +set(CMAKE_POLICY_WARNING_CMP0060 1) +include(CMP0060-Common.cmake) diff --git a/Tests/RunCMake/CMP0060/CMakeLists.txt b/Tests/RunCMake/CMP0060/CMakeLists.txt new file mode 100644 index 0000000..db6b701 --- /dev/null +++ b/Tests/RunCMake/CMP0060/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.2) +project(${RunCMake_TEST} C) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0060/RunCMakeTest.cmake b/Tests/RunCMake/CMP0060/RunCMakeTest.cmake new file mode 100644 index 0000000..445156f --- /dev/null +++ b/Tests/RunCMake/CMP0060/RunCMakeTest.cmake @@ -0,0 +1,19 @@ +include(RunCMake) + +function(run_cmake_CMP0060 CASE) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0060-${CASE}-build) + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(CMP0060-${CASE}) + set(RunCMake_TEST_OUTPUT_MERGE 1) + run_cmake_command(CMP0060-${CASE}-Build + ${CMAKE_COMMAND} --build . --config Debug + ) +endfunction() + +run_cmake_CMP0060(OLD) +run_cmake_CMP0060(WARN-OFF) +run_cmake_CMP0060(WARN-ON) +run_cmake_CMP0060(NEW) diff --git a/Tests/RunCMake/CMP0060/cmp0060.c b/Tests/RunCMake/CMP0060/cmp0060.c new file mode 100644 index 0000000..a2da227 --- /dev/null +++ b/Tests/RunCMake/CMP0060/cmp0060.c @@ -0,0 +1,4 @@ +int libCMP0060(void) +{ + return 0; +} diff --git a/Tests/RunCMake/CMP0060/main.c b/Tests/RunCMake/CMP0060/main.c new file mode 100644 index 0000000..91848c2 --- /dev/null +++ b/Tests/RunCMake/CMP0060/main.c @@ -0,0 +1,5 @@ +extern int libCMP0060(void); +int main(void) +{ + return libCMP0060(); +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 801655f..d5f1d22 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,16 @@ add_RunCMake_test(CMP0051) add_RunCMake_test(CMP0053) add_RunCMake_test(CMP0054) add_RunCMake_test(CMP0055) +add_RunCMake_test(CMP0057) +add_RunCMake_test(CMP0059) +add_RunCMake_test(CMP0060) +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 +135,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 +190,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) @@ -173,11 +200,43 @@ add_RunCMake_test(target_link_libraries) add_RunCMake_test(target_compile_features) add_RunCMake_test(CheckModules) add_RunCMake_test(CommandLine) +add_RunCMake_test(CommandLineTar) add_RunCMake_test(install) add_RunCMake_test(CPackInstallProperties) add_RunCMake_test(ExternalProject) +add_RunCMake_test(CTestCommandLine) +# Only run this test on unix platforms that support +# symbolic links +if(UNIX) + add_RunCMake_test(CPackSymlinks) +endif() + +set(IfacePaths_INCLUDE_DIRECTORIES_ARGS -DTEST_PROP=INCLUDE_DIRECTORIES) +add_RunCMake_test(IfacePaths_INCLUDE_DIRECTORIES TEST_DIR IfacePaths) + +set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES) +add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths) -if(RPMBUILD) +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() + +add_executable(pseudo_emulator pseudo_emulator.c) +add_RunCMake_test(CrosscompilingEmulator + -DPSEUDO_EMULATOR=$<TARGET_FILE:pseudo_emulator>) +# Xcode 2.x forgets to create the output directory before linking +# the individual architectures. +if(CMAKE_OSX_ARCHITECTURES AND XCODE AND NOT "${XCODE_VERSION}" MATCHES "^[^12]") + add_custom_command( + TARGET pseudo_emulator + PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CFG_INTDIR}" + ) +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/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake b/Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake index 3ace6a8..31e729b 100644 --- a/Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake +++ b/Tests/RunCMake/CPackRPM/CPackRPM_PARTIALLY_RELOCATABLE_WARNING.cmake @@ -1,5 +1,4 @@ install(FILES CMakeLists.txt DESTINATION /not_relocatable COMPONENT static) -install(FILES CMakeLists.txt DESTINATION relocatable COMPONENT relocatable) set(CPACK_PACKAGE_RELOCATABLE TRUE) set(CPACK_PACKAGING_INSTALL_PREFIX "/opt") diff --git a/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake new file mode 100644 index 0000000..439d95e --- /dev/null +++ b/Tests/RunCMake/CPackSymlinks/RunCMakeTest.cmake @@ -0,0 +1,20 @@ +include(RunCMake) + +function(run_cpack_symlink_test) + set(RunCMake_TEST_NO_CLEAN TRUE) + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/SrcSymlinks-build") + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/SrcSymlinks") + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + run_cmake_command(SrcSymlinksTar + ${CMAKE_COMMAND} -E chdir ${RunCMake_TEST_SOURCE_DIR} + ${CMAKE_COMMAND} -E tar xvf ${RunCMake_SOURCE_DIR}/testcpacksym.tar + ) + run_cmake(SrcSymlinksCMake) + run_cmake_command(SrcSymlinksCPack + ${CMAKE_CPACK_COMMAND} --config CPackSourceConfig.cmake + ) +endfunction() + +run_cpack_symlink_test() diff --git a/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt new file mode 100644 index 0000000..24ad124 --- /dev/null +++ b/Tests/RunCMake/CPackSymlinks/SrcSymlinksTar-stdout.txt @@ -0,0 +1,10 @@ +^x CMakeLists.txt +x cygwin/ +x cygwin/build.sh +x cygwin/setup.patch +x include/ +x include/src.h +x link.h +x real.h +x src/ +x src/src.h$ diff --git a/Tests/RunCMake/CPackSymlinks/testcpacksym.tar b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar Binary files differnew file mode 100644 index 0000000..a44c656 --- /dev/null +++ b/Tests/RunCMake/CPackSymlinks/testcpacksym.tar 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/include_directories/InstallInBinDir-result.txt b/Tests/RunCMake/CommandLine/C-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/InstallInBinDir-result.txt +++ b/Tests/RunCMake/CommandLine/C-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt new file mode 100644 index 0000000..0570d8f --- /dev/null +++ b/Tests/RunCMake/CommandLine/C-no-arg-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: -C must be followed by a file name. +CMake Error: Problem processing arguments. Aborting.$ diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/CommandLine/C-no-file-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt +++ b/Tests/RunCMake/CommandLine/C-no-file-result.txt diff --git a/Tests/RunCMake/CommandLine/C-no-file-stderr.txt b/Tests/RunCMake/CommandLine/C-no-file-stderr.txt new file mode 100644 index 0000000..5315f59 --- /dev/null +++ b/Tests/RunCMake/CommandLine/C-no-file-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: Error processing file: nosuchcachefile.txt +CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/C-no-file-build/nosuchcachefile.txt" does not exist. +Specify --help for usage, or press the help button on the CMake GUI.$ diff --git a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt b/Tests/RunCMake/CommandLine/D-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt +++ b/Tests/RunCMake/CommandLine/D-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt new file mode 100644 index 0000000..5e43bca --- /dev/null +++ b/Tests/RunCMake/CommandLine/D-no-arg-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: -D must be followed with VAR=VALUE. +CMake Error: Problem processing arguments. Aborting.$ diff --git a/Tests/RunCMake/TargetSources/ExportInstall-result.txt b/Tests/RunCMake/CommandLine/E-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/TargetSources/ExportInstall-result.txt +++ b/Tests/RunCMake/CommandLine/E-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt new file mode 100644 index 0000000..056ce05 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E-no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: cmake version .* +Usage: .* -E \[command\] \[arguments ...\] +Available commands: diff --git a/Tests/RunCMake/CommandLine/E_tar-end-opt1-result.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-end-opt1-result.txt +++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt new file mode 100644 index 0000000..056ce05 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_create_symlink-no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: cmake version .* +Usage: .* -E \[command\] \[arguments ...\] +Available commands: diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-result.txt b/Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-result.txt +++ b/Tests/RunCMake/CommandLine/E_rename-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt new file mode 100644 index 0000000..056ce05 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_rename-no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: cmake version .* +Usage: .* -E \[command\] \[arguments ...\] +Available commands: diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-result.txt b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-result.txt +++ b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt new file mode 100644 index 0000000..056ce05 --- /dev/null +++ b/Tests/RunCMake/CommandLine/E_touch_nocreate-no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: cmake version .* +Usage: .* -E \[command\] \[arguments ...\] +Available commands: diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt b/Tests/RunCMake/CommandLine/G_bad-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from5-result.txt +++ b/Tests/RunCMake/CommandLine/G_bad-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt b/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt new file mode 100644 index 0000000..07f2b52 --- /dev/null +++ b/Tests/RunCMake/CommandLine/G_bad-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: Could not create named generator NoSuchGenerator + +Generators diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt b/Tests/RunCMake/CommandLine/G_no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from4-result.txt +++ b/Tests/RunCMake/CommandLine/G_no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt b/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt new file mode 100644 index 0000000..2f491a2 --- /dev/null +++ b/Tests/RunCMake/CommandLine/G_no-arg-stderr.txt @@ -0,0 +1,3 @@ +^CMake Error: No generator specified for -G + +Generators diff --git a/Tests/RunCMake/CommandLine/NoArgs-stdout.txt b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt new file mode 100644 index 0000000..1cd3469 --- /dev/null +++ b/Tests/RunCMake/CommandLine/NoArgs-stdout.txt @@ -0,0 +1,10 @@ +^Usage + + cmake \[options\] <path-to-source> + cmake \[options\] <path-to-existing-build> + +Specify a source directory to \(re-\)generate a build system for it in the +current working directory. Specify an existing build directory to +re-generate its build system. + +Run 'cmake --help' for more information.$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt b/Tests/RunCMake/CommandLine/P_no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from3-result.txt +++ b/Tests/RunCMake/CommandLine/P_no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt b/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt new file mode 100644 index 0000000..8af3a53 --- /dev/null +++ b/Tests/RunCMake/CommandLine/P_no-arg-stderr.txt @@ -0,0 +1 @@ +^CMake Error: No script specified for argument -P$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt b/Tests/RunCMake/CommandLine/P_no-file-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from2-result.txt +++ b/Tests/RunCMake/CommandLine/P_no-file-result.txt diff --git a/Tests/RunCMake/CommandLine/P_no-file-stderr.txt b/Tests/RunCMake/CommandLine/P_no-file-stderr.txt new file mode 100644 index 0000000..2e12399 --- /dev/null +++ b/Tests/RunCMake/CommandLine/P_no-file-stderr.txt @@ -0,0 +1 @@ +^CMake Error: Error processing file: nosuchscriptfile.cmake$ diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 2be6651..f047baf 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -1,15 +1,21 @@ include(RunCMake) -run_cmake_command(E_tar-bad-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar --bad) -run_cmake_command(E_tar-bad-mtime1 ${CMAKE_COMMAND} -E tar cvf bad.tar --mtime=bad .) -run_cmake_command(E_tar-bad-from1 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=bad) -run_cmake_command(E_tar-bad-from2 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=.) -run_cmake_command(E_tar-bad-from3 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from3.txt) -run_cmake_command(E_tar-bad-from4 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from4.txt) -run_cmake_command(E_tar-bad-from5 ${CMAKE_COMMAND} -E tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/E_tar-bad-from5.txt) -run_cmake_command(E_tar-end-opt1 ${CMAKE_COMMAND} -E tar cvf bad.tar -- --bad) -run_cmake_command(E_tar-end-opt2 ${CMAKE_COMMAND} -E tar cvf bad.tar --) -run_cmake_command(E_tar-mtime ${CMAKE_COMMAND} -E tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC") +run_cmake_command(NoArgs ${CMAKE_COMMAND}) +run_cmake_command(C-no-arg ${CMAKE_COMMAND} -C) +run_cmake_command(C-no-file ${CMAKE_COMMAND} -C nosuchcachefile.txt) +run_cmake_command(cache-no-file ${CMAKE_COMMAND} nosuchsubdir/CMakeCache.txt) +run_cmake_command(lists-no-file ${CMAKE_COMMAND} nosuchsubdir/CMakeLists.txt) +run_cmake_command(D-no-arg ${CMAKE_COMMAND} -D) +run_cmake_command(U-no-arg ${CMAKE_COMMAND} -U) +run_cmake_command(E-no-arg ${CMAKE_COMMAND} -E) +run_cmake_command(E_echo_append ${CMAKE_COMMAND} -E echo_append) +run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename) +run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate) + +run_cmake_command(G_no-arg ${CMAKE_COMMAND} -G) +run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -G NoSuchGenerator) +run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P) +run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake) run_cmake_command(build-no-cache ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}) @@ -18,7 +24,26 @@ 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-no-arg + ${CMAKE_COMMAND} -E create_symlink + ) run_cmake_command(E_create_symlink-missing-dir ${CMAKE_COMMAND} -E create_symlink T missing-dir/L ) @@ -64,3 +89,49 @@ run_cmake(D_nested_cache) set(RunCMake_TEST_OPTIONS "-DFOO:STRING=-DBAR:BOOL=BAZ") run_cmake(D_typed_nested_cache) + +set(RunCMake_TEST_OPTIONS -Wno-dev) +run_cmake(Wno-dev) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS -Wno-dev -Wdev) +run_cmake(Wdev) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --debug-output) +run_cmake(debug-output) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --trace) +run_cmake(trace) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --debug-trycompile) +run_cmake(debug-trycompile) +unset(RunCMake_TEST_OPTIONS) + +function(run_cmake_depends) + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_SOURCE_DIR}/cmake_depends") + set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/cmake_depends-build") + set(RunCMake_TEST_NO_CLEAN 1) + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake" " +set(CMAKE_DEPENDS_LANGUAGES \"C\") +set(CMAKE_DEPENDS_CHECK_C + \"${RunCMake_TEST_SOURCE_DIR}/test.c\" + \"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/test.c.o\" + ) +") + file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/CMakeDirectoryInformation.cmake" " +set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"${RunCMake_TEST_SOURCE_DIR}\") +set(CMAKE_RELATIVE_PATH_TOP_BINARY \"${RunCMake_TEST_BINARY_DIR}\") +") + run_cmake_command(cmake_depends ${CMAKE_COMMAND} -E cmake_depends + "Unix Makefiles" + ${RunCMake_TEST_SOURCE_DIR} ${RunCMake_TEST_SOURCE_DIR} + ${RunCMake_TEST_BINARY_DIR} ${RunCMake_TEST_BINARY_DIR} + ${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake + ) +endfunction() +run_cmake_depends() diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt b/Tests/RunCMake/CommandLine/U-no-arg-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from1-result.txt +++ b/Tests/RunCMake/CommandLine/U-no-arg-result.txt diff --git a/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt b/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt new file mode 100644 index 0000000..c34ef94 --- /dev/null +++ b/Tests/RunCMake/CommandLine/U-no-arg-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: -U must be followed with VAR. +CMake Error: Problem processing arguments. Aborting.$ diff --git a/Tests/RunCMake/CommandLine/Wdev-stderr.txt b/Tests/RunCMake/CommandLine/Wdev-stderr.txt new file mode 100644 index 0000000..f427303 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Wdev-stderr.txt @@ -0,0 +1,5 @@ +^CMake Warning \(dev\) at Wdev.cmake:1 \(message\): + Some Author Warning +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/CommandLine/Wdev.cmake b/Tests/RunCMake/CommandLine/Wdev.cmake new file mode 100644 index 0000000..0242086 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Wdev.cmake @@ -0,0 +1 @@ +message(AUTHOR_WARNING "Some Author Warning") diff --git a/Tests/RunCMake/CommandLine/Wno-dev.cmake b/Tests/RunCMake/CommandLine/Wno-dev.cmake new file mode 100644 index 0000000..0242086 --- /dev/null +++ b/Tests/RunCMake/CommandLine/Wno-dev.cmake @@ -0,0 +1 @@ +message(AUTHOR_WARNING "Some Author Warning") diff --git a/Tests/RunCMake/CommandLine/cache-no-file-result.txt b/Tests/RunCMake/CommandLine/cache-no-file-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-no-file-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt b/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt new file mode 100644 index 0000000..da3a0c3 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cache-no-file-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/cache-no-file-build/nosuchsubdir" does not exist. +Specify --help for usage, or press the help button on the CMake GUI.$ diff --git a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake new file mode 100644 index 0000000..031478b --- /dev/null +++ b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake @@ -0,0 +1,13 @@ +set(depend_make "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/depend.make") +if(EXISTS "${depend_make}") + file(READ "${depend_make}" depend_make_content) + string(REGEX REPLACE "\n+$" "" depend_make_content "${depend_make_content}") + if(NOT depend_make_content MATCHES " +CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.c +CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.h$") + string(REPLACE "\n" "\n " depend_make_content " ${depend_make_content}") + set(RunCMake_TEST_FAILED "depend.make does not have expected content:\n${depend_make_content}") + endif() +else() + set(RunCMake_TEST_FAILED "depend.make missing:\n ${depend_make}") +endif() diff --git a/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt new file mode 100644 index 0000000..8fe092b --- /dev/null +++ b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt @@ -0,0 +1 @@ +^Scanning dependencies of target DepTarget$ diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test.c b/Tests/RunCMake/CommandLine/cmake_depends/test.c new file mode 100644 index 0000000..92c056f --- /dev/null +++ b/Tests/RunCMake/CommandLine/cmake_depends/test.c @@ -0,0 +1,2 @@ +#include "test.h" +#include "test_UTF-16LE.h" diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test.h b/Tests/RunCMake/CommandLine/cmake_depends/test.h new file mode 100644 index 0000000..fd87388 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cmake_depends/test.h @@ -0,0 +1 @@ +void test(void) {} diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h Binary files differnew file mode 100644 index 0000000..bf56ec6 --- /dev/null +++ b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h diff --git a/Tests/RunCMake/CommandLine/debug-output-stdout.txt b/Tests/RunCMake/CommandLine/debug-output-stdout.txt new file mode 100644 index 0000000..96f2aae --- /dev/null +++ b/Tests/RunCMake/CommandLine/debug-output-stdout.txt @@ -0,0 +1 @@ +Running with debug output on. diff --git a/Tests/RunCMake/CommandLine/debug-output.cmake b/Tests/RunCMake/CommandLine/debug-output.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CommandLine/debug-output.cmake diff --git a/Tests/RunCMake/CommandLine/debug-trycompile.cmake b/Tests/RunCMake/CommandLine/debug-trycompile.cmake new file mode 100644 index 0000000..a3835a7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/debug-trycompile.cmake @@ -0,0 +1,5 @@ +enable_language(C) +# Look for a source tree left by enable_language internal checks. +if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/CMakeLists.txt) + message(FATAL_ERROR "--debug-trycompile should leave the source behind") +endif() diff --git a/Tests/RunCMake/CommandLine/lists-no-file-result.txt b/Tests/RunCMake/CommandLine/lists-no-file-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/lists-no-file-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt b/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt new file mode 100644 index 0000000..3465e89 --- /dev/null +++ b/Tests/RunCMake/CommandLine/lists-no-file-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/lists-no-file-build/nosuchsubdir" does not exist. +Specify --help for usage, or press the help button on the CMake GUI.$ diff --git a/Tests/RunCMake/CommandLine/trace-stderr.txt b/Tests/RunCMake/CommandLine/trace-stderr.txt new file mode 100644 index 0000000..8e8ddfa --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace-stderr.txt @@ -0,0 +1,2 @@ +^.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(1\): cmake_minimum_required\(VERSION 3.0 \) +.*/Tests/RunCMake/CommandLine/CMakeLists.txt\(2\): project\(\${RunCMake_TEST} NONE \) diff --git a/Tests/RunCMake/CommandLine/trace.cmake b/Tests/RunCMake/CommandLine/trace.cmake new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CommandLine/trace.cmake diff --git a/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt b/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/7zip-gz-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt b/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt new file mode 100644 index 0000000..2fad326 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/7zip-gz-stderr.txt @@ -0,0 +1 @@ +CMake Error: Can not use compression flags with format: 7zip diff --git a/Tests/RunCMake/CommandLineTar/7zip.cmake b/Tests/RunCMake/CommandLineTar/7zip.cmake new file mode 100644 index 0000000..4bc6548 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/7zip.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.7z") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=7zip) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("377abcaf271c" LIMIT 6 HEX) diff --git a/Tests/RunCMake/CommandLineTar/CMakeLists.txt b/Tests/RunCMake/CommandLineTar/CMakeLists.txt new file mode 100644 index 0000000..2897109 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/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/CommandLineTar/RunCMakeTest.cmake b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake new file mode 100644 index 0000000..12635db --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/RunCMakeTest.cmake @@ -0,0 +1,28 @@ +include(RunCMake) + +function(external_command_test NAME) + run_cmake_command(${NAME} ${CMAKE_COMMAND} -E ${ARGN}) +endfunction() + +external_command_test(bad-opt1 tar cvf bad.tar --bad) +external_command_test(bad-mtime1 tar cvf bad.tar --mtime=bad .) +external_command_test(bad-from1 tar cvf bad.tar --files-from=bad) +external_command_test(bad-from2 tar cvf bad.tar --files-from=.) +external_command_test(bad-from3 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from3.txt) +external_command_test(bad-from4 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from4.txt) +external_command_test(bad-from5 tar cvf bad.tar --files-from=${CMAKE_CURRENT_LIST_DIR}/bad-from5.txt) +external_command_test(end-opt1 tar cvf bad.tar -- --bad) +external_command_test(end-opt2 tar cvf bad.tar --) +external_command_test(mtime tar cvf bad.tar "--mtime=1970-01-01 00:00:00 UTC") +external_command_test(bad-format tar cvf bad.tar "--format=bad-format") +external_command_test(zip-bz2 tar cvjf bad.tar "--format=zip") +external_command_test(7zip-gz tar cvzf bad.tar "--format=7zip") + +run_cmake(7zip) +run_cmake(gnutar) +run_cmake(gnutar-gz) +run_cmake(pax) +run_cmake(pax-xz) +run_cmake(paxr) +run_cmake(paxr-bz2) +run_cmake(zip) diff --git a/Tests/RunCMake/CommandLineTar/bad-format-result.txt b/Tests/RunCMake/CommandLineTar/bad-format-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-format-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt new file mode 100644 index 0000000..fe9e2dc --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-format-stderr.txt @@ -0,0 +1 @@ +CMake Error: Unknown -E tar --format= argument: bad-format diff --git a/Tests/RunCMake/CommandLineTar/bad-from1-result.txt b/Tests/RunCMake/CommandLineTar/bad-from1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-from1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt index d67431d..d67431d 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from1-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from1-stderr.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-from2-result.txt b/Tests/RunCMake/CommandLineTar/bad-from2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-from2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt index d1d278c..d1d278c 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from2-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from2-stderr.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-from3-result.txt b/Tests/RunCMake/CommandLineTar/bad-from3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-from3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt index 147bd80..da32ad9 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from3-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from3-stderr.txt @@ -1,2 +1,2 @@ -^CMake Error: -E tar --files-from='.*/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt' file invalid line: +^CMake Error: -E tar --files-from='.*/Tests/RunCMake/CommandLineTar/bad-from3.txt' file invalid line: -add-file=option-typo$ diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt b/Tests/RunCMake/CommandLineTar/bad-from3.txt index 5bad1c3..5bad1c3 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from3.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from3.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-from4-result.txt b/Tests/RunCMake/CommandLineTar/bad-from4-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-from4-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt index 1417d4d..1417d4d 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from5-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from4-stderr.txt diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4.txt b/Tests/RunCMake/CommandLineTar/bad-from4.txt index 4b97f79..4b97f79 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from4.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from4.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-from5-result.txt b/Tests/RunCMake/CommandLineTar/bad-from5-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-from5-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt index 1417d4d..1417d4d 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from4-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from5-stderr.txt diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-from5.txt b/Tests/RunCMake/CommandLineTar/bad-from5.txt index 9ea755b..9ea755b 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-from5.txt +++ b/Tests/RunCMake/CommandLineTar/bad-from5.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt b/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-mtime1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt index ca925f1..ca925f1 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-mtime1-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-mtime1-stderr.txt diff --git a/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt b/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/bad-opt1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-stderr.txt b/Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt index 35133c8..35133c8 100644 --- a/Tests/RunCMake/CommandLine/E_tar-bad-opt1-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/bad-opt1-stderr.txt diff --git a/Tests/RunCMake/CommandLineTar/end-opt1-result.txt b/Tests/RunCMake/CommandLineTar/end-opt1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/end-opt1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/E_tar-end-opt1-stderr.txt b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt index 1fddf6d..1fddf6d 100644 --- a/Tests/RunCMake/CommandLine/E_tar-end-opt1-stderr.txt +++ b/Tests/RunCMake/CommandLineTar/end-opt1-stderr.txt diff --git a/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake new file mode 100644 index 0000000..5f2674a --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/gnutar-gz.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar.gz") + +set(COMPRESSION_FLAGS cvzf) +set(COMPRESSION_OPTIONS --format=gnutar) + +set(DECOMPRESSION_FLAGS xvzf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("1f8b" LIMIT 2 HEX) diff --git a/Tests/RunCMake/CommandLineTar/gnutar.cmake b/Tests/RunCMake/CommandLineTar/gnutar.cmake new file mode 100644 index 0000000..aaca596 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/gnutar.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=gnutar) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/pax-xz.cmake b/Tests/RunCMake/CommandLineTar/pax-xz.cmake new file mode 100644 index 0000000..baf63d5 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/pax-xz.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar.xz") + +set(COMPRESSION_FLAGS cvJf) +set(COMPRESSION_OPTIONS --format=pax) + +set(DECOMPRESSION_FLAGS xvJf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("fd377a585a00" LIMIT 6 HEX) diff --git a/Tests/RunCMake/CommandLineTar/pax.cmake b/Tests/RunCMake/CommandLineTar/pax.cmake new file mode 100644 index 0000000..60ed238 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/pax.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=pax) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake b/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake new file mode 100644 index 0000000..881a0af --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/paxr-bz2.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar.bz2") + +set(COMPRESSION_FLAGS cvjf) +set(COMPRESSION_OPTIONS --format=paxr) + +set(DECOMPRESSION_FLAGS xvjf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("425a68" LIMIT 3 HEX) diff --git a/Tests/RunCMake/CommandLineTar/paxr.cmake b/Tests/RunCMake/CommandLineTar/paxr.cmake new file mode 100644 index 0000000..968a103 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/paxr.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.tar") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=paxr) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX) diff --git a/Tests/RunCMake/CommandLineTar/roundtrip.cmake b/Tests/RunCMake/CommandLineTar/roundtrip.cmake new file mode 100644 index 0000000..dc1c885 --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/roundtrip.cmake @@ -0,0 +1,81 @@ +foreach(parameter OUTPUT_NAME COMPRESSION_FLAGS DECOMPRESSION_FLAGS) + if(NOT DEFINED ${parameter}) + message(FATAL_ERROR "missing required parameter ${parameter}") + endif() +endforeach() + +function(run_tar WORKING_DIRECTORY) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar ${ARGN} + WORKING_DIRECTORY ${WORKING_DIRECTORY} + RESULT_VARIABLE result + ) + + if(NOT result STREQUAL "0") + message(FATAL_ERROR "tar failed with arguments [${ARGN}] result [${result}]") + endif() +endfunction() + +set(COMPRESS_DIR compress_dir) +set(FULL_COMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${COMPRESS_DIR}) + +set(DECOMPRESS_DIR decompress_dir) +set(FULL_DECOMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DECOMPRESS_DIR}) + +set(FULL_OUTPUT_NAME ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME}) + +set(CHECK_FILES + "f1.txt" + "d1/f1.txt" + "d 2/f1.txt" + "d + 3/f1.txt" + "d_4/f1.txt" + "d-4/f1.txt" + "My Special Directory/f1.txt" +) + +foreach(file ${CHECK_FILES}) + configure_file(${CMAKE_CURRENT_LIST_FILE} ${FULL_COMPRESS_DIR}/${file} COPYONLY) +endforeach() + +if(UNIX) + execute_process(COMMAND ln -sf f1.txt ${FULL_COMPRESS_DIR}/d1/f2.txt) + list(APPEND CHECK_FILES "d1/f2.txt") +endif() + +file(REMOVE ${FULL_OUTPUT_NAME}) +file(REMOVE_RECURSE ${FULL_DECOMPRESS_DIR}) +file(MAKE_DIRECTORY ${FULL_DECOMPRESS_DIR}) + +run_tar(${CMAKE_CURRENT_BINARY_DIR} ${COMPRESSION_FLAGS} ${FULL_OUTPUT_NAME} ${COMPRESSION_OPTIONS} ${COMPRESS_DIR}) +run_tar(${FULL_DECOMPRESS_DIR} ${DECOMPRESSION_FLAGS} ${FULL_OUTPUT_NAME} ${DECOMPRESSION_OPTIONS}) + +foreach(file ${CHECK_FILES}) + set(input ${FULL_COMPRESS_DIR}/${file}) + set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file}) + + if(NOT EXISTS ${input}) + message(SEND_ERROR "Cannot find input file ${output}") + endif() + + if(NOT EXISTS ${output}) + message(SEND_ERROR "Cannot find output file ${output}") + endif() + + file(MD5 ${input} input_md5) + file(MD5 ${output} output_md5) + + if(NOT input_md5 STREQUAL output_md5) + message(SEND_ERROR "Files \"${input}\" and \"${output}\" are different") + endif() +endforeach() + +function(check_magic EXPECTED) + file(READ ${FULL_OUTPUT_NAME} ACTUAL + ${ARGN} + ) + + if(NOT ACTUAL STREQUAL EXPECTED) + message(FATAL_ERROR + "Actual [${ACTUAL}] does not match expected [${EXPECTED}]") + endif() +endfunction() diff --git a/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt b/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/zip-bz2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt b/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt new file mode 100644 index 0000000..1134b4f --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/zip-bz2-stderr.txt @@ -0,0 +1 @@ +CMake Error: Can not use compression flags with format: zip diff --git a/Tests/RunCMake/CommandLineTar/zip.cmake b/Tests/RunCMake/CommandLineTar/zip.cmake new file mode 100644 index 0000000..08e2fdb --- /dev/null +++ b/Tests/RunCMake/CommandLineTar/zip.cmake @@ -0,0 +1,10 @@ +set(OUTPUT_NAME "test.zip") + +set(COMPRESSION_FLAGS cvf) +set(COMPRESSION_OPTIONS --format=zip) + +set(DECOMPRESSION_FLAGS xvf) + +include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake) + +check_magic("504b0304" LIMIT 4 HEX) 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/CrosscompilingEmulator/AddTest-check.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake new file mode 100644 index 0000000..0aae06c --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest-check.cmake @@ -0,0 +1,12 @@ +set(testfile "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake") +if(EXISTS "${testfile}") + file(READ "${testfile}" testfile_contents) +else() + message(FATAL_ERROR "Could not find expected CTestTestfile.cmake.") +endif() +if(testfile_contents MATCHES "add_test[(]DoesNotUseEmulator ^(pseudo_emulator)+$") + message(SEND_ERROR "Used emulator when it should not be used.") +endif() +if(NOT testfile_contents MATCHES "add_test[(]UsesEmulator .+pseudo_emulator.+$") + message(SEND_ERROR "Did not use emulator when it should be used.") +endif() diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake new file mode 100644 index 0000000..41850f2 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/AddTest.cmake @@ -0,0 +1,8 @@ +set(CMAKE_CROSSCOMPILING 1) +enable_testing() +add_test(NAME DoesNotUseEmulator + COMMAND ${CMAKE_COMMAND} -E echo "Hi") + +add_executable(generated_exe simple_src.cxx) +add_test(NAME UsesEmulator + COMMAND generated_exe) diff --git a/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt b/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt new file mode 100644 index 0000000..2d75985 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.1) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake new file mode 100644 index 0000000..22d537c --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/CrosscompilingEmulatorProperty.cmake @@ -0,0 +1,28 @@ +# This tests setting the CROSSCOMPILING_EMULATOR target property from the +# CMAKE_CROSSCOMPILING_EMULATOR variable. + +# -DCMAKE_CROSSCOMPILING_EMULATOR=/path/to/pseudo_emulator is passed to this +# test +add_executable(target_with_emulator simple_src.cxx) +get_property(emulator TARGET target_with_emulator + PROPERTY CROSSCOMPILING_EMULATOR) +if(NOT "${emulator}" MATCHES "pseudo_emulator") + message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set") +endif() + +set_property(TARGET target_with_emulator + PROPERTY CROSSCOMPILING_EMULATOR "another_emulator") +get_property(emulator TARGET target_with_emulator + PROPERTY CROSSCOMPILING_EMULATOR) +if(NOT "${emulator}" MATCHES "another_emulator") + message(SEND_ERROR + "set_property/get_property CROSSCOMPILING_EMULATOR is not consistent") +endif() + +unset(CMAKE_CROSSCOMPILING_EMULATOR CACHE) +add_executable(target_without_emulator simple_src.cxx) +get_property(emulator TARGET target_without_emulator + PROPERTY CROSSCOMPILING_EMULATOR) +if(NOT "${emulator}" STREQUAL "") + message(SEND_ERROR "Default CROSSCOMPILING_EMULATOR property not set to null") +endif() diff --git a/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in b/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in new file mode 100644 index 0000000..c95fd8b --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/InitialCache.txt.in @@ -0,0 +1 @@ +CMAKE_EMULATOR:STRING=@PSEUDO_EMULATOR@ diff --git a/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake new file mode 100644 index 0000000..2581cfc --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/RunCMakeTest.cmake @@ -0,0 +1,8 @@ +include(RunCMake) + +set(RunCMake_TEST_OPTIONS + "-DCMAKE_CROSSCOMPILING_EMULATOR=${PSEUDO_EMULATOR}") + +run_cmake(CrosscompilingEmulatorProperty) +run_cmake(TryRun) +run_cmake(AddTest) diff --git a/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt b/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt new file mode 100644 index 0000000..d012974 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/TryRun-stdout.txt @@ -0,0 +1 @@ +run_result: 42 diff --git a/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake b/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake new file mode 100644 index 0000000..4851cc7 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/TryRun.cmake @@ -0,0 +1,18 @@ +set(CMAKE_CROSSCOMPILING 1) + +try_run(run_result compile_result + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx + RUN_OUTPUT_VARIABLE run_output) + +message(STATUS "run_output: ${run_output}") +message(STATUS "run_result: ${run_result}") + +set(CMAKE_CROSSCOMPILING_EMULATOR ${CMAKE_CROSSCOMPILING_EMULATOR} + --flag + "multi arg") +try_run(run_result compile_result + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/simple_src.cxx + RUN_OUTPUT_VARIABLE run_output) +message(STATUS "Emulator with arguments run_output: ${run_output}") diff --git a/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx b/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx new file mode 100644 index 0000000..e5e94f2 --- /dev/null +++ b/Tests/RunCMake/CrosscompilingEmulator/simple_src.cxx @@ -0,0 +1,4 @@ +int main(int, char **) +{ + return 13; +} 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/ExternalData/BadAlgoMap1-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap1-result.txt @@ -0,0 +1 @@ +1 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/ExternalData/BadAlgoMap2-result.txt b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadAlgoMap2-result.txt @@ -0,0 +1 @@ +1 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/ExternalData/BadRecurse1-result.txt b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse1-result.txt @@ -0,0 +1 @@ +1 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/ExternalData/BadRecurse2-result.txt b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/ExternalData/BadRecurse2-result.txt @@ -0,0 +1 @@ +1 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..6333703 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() @@ -51,12 +54,18 @@ function(run_cmake test) if(RunCMake_MAKE_PROGRAM) list(APPEND RunCMake_TEST_OPTIONS "-DCMAKE_MAKE_PROGRAM=${RunCMake_MAKE_PROGRAM}") endif() + if(RunCMake_TEST_OUTPUT_MERGE) + set(actual_stderr_var actual_stdout) + set(actual_stderr "") + else() + set(actual_stderr_var actual_stderr) + endif() if(RunCMake_TEST_COMMAND) execute_process( COMMAND ${RunCMake_TEST_COMMAND} WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}" OUTPUT_VARIABLE actual_stdout - ERROR_VARIABLE actual_stderr + ERROR_VARIABLE ${actual_stderr_var} RESULT_VARIABLE actual_result ) else() @@ -70,7 +79,7 @@ function(run_cmake test) ${RunCMake_TEST_OPTIONS} WORKING_DIRECTORY "${RunCMake_TEST_BINARY_DIR}" OUTPUT_VARIABLE actual_stdout - ERROR_VARIABLE actual_stderr + ERROR_VARIABLE ${actual_stderr_var} RESULT_VARIABLE actual_result ) endif() @@ -80,7 +89,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/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt index f4b744b..1da1623 100644 --- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt +++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt @@ -17,6 +17,7 @@ \* CMP0042 \* CMP0046 \* CMP0052 + \* CMP0060 Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) 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..b7de614 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -1,3 +1,9 @@ include(RunCMake) run_cmake(XcodeFileType) +run_cmake(XcodeAttributeGenex) +run_cmake(XcodeAttributeGenexError) +run_cmake(XcodeObjectNeedsQuote) +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/XcodeObjectNeedsQuote-check.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake new file mode 100644 index 0000000..be7d96a --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote-check.cmake @@ -0,0 +1,7 @@ +set(expect "path = \"") +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/XcodeObjectNeedsQuote.xcodeproj/project.pbxproj actual + REGEX "path = [^;]*someFileWithoutSpecialChars[^;]*;" 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/XcodeObjectNeedsQuote.cmake b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake new file mode 100644 index 0000000..ecc56ab --- /dev/null +++ b/Tests/RunCMake/XcodeProject/XcodeObjectNeedsQuote.cmake @@ -0,0 +1,3 @@ +enable_language(C) +add_library(some /${CMAKE_CURRENT_SOURCE_DIR}/someFileWithoutSpecialChars) +set_property(SOURCE /${CMAKE_CURRENT_SOURCE_DIR}/someFileWithoutSpecialChars PROPERTY LANGUAGE C) 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/XcodeProject/someFileWithoutSpecialChars b/Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/someFileWithoutSpecialChars 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/RunCMake/pseudo_emulator.c b/Tests/RunCMake/pseudo_emulator.c new file mode 100644 index 0000000..9308f75 --- /dev/null +++ b/Tests/RunCMake/pseudo_emulator.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main(int argc, char * argv[] ) +{ + int ii; + + printf("Command:"); + for(ii = 1; ii < argc; ++ii) + { + printf(" \"%s\"", argv[ii]); + } + printf("\n"); + + return 42; +} diff --git a/Tests/TarTest/CMakeLists.txt b/Tests/TarTest/CMakeLists.txt deleted file mode 100644 index bcc340b..0000000 --- a/Tests/TarTest/CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project(TarTest) - -# this is macro that we will be running -macro(EXEC_TAR_COMMAND DIR ARGS) - exec_program("${CMAKE_COMMAND}" "${DIR}" ARGS "-E tar ${ARGS}" RETURN_VALUE RET) - if(${RET}) - message(FATAL_ERROR "CMake tar command failed with arguments \"${ARGS}\"") - endif() -endmacro() - -# Create a directory structure -set(CHECK_FILES) -macro(COPY F1 F2) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${F1}" "${CMAKE_CURRENT_BINARY_DIR}/tar_dir/${F2}" COPYONLY) - set(CHECK_FILES ${CHECK_FILES} "${F2}") -endmacro() -COPY("CMakeLists.txt" "f1.txt") -COPY("CMakeLists.txt" "d1/f1.txt") -COPY("CMakeLists.txt" "d 2/f1.txt") -COPY("CMakeLists.txt" "d + 3/f1.txt") -COPY("CMakeLists.txt" "d_4/f1.txt") -COPY("CMakeLists.txt" "d-4/f1.txt") -COPY("CMakeLists.txt" "My Special Directory/f1.txt") - -if(UNIX) - exec_program("ln" ARGS "-sf f1.txt \"${CMAKE_CURRENT_BINARY_DIR}/tar_dir/d1/f2.txt\"") - set(CHECK_FILES ${CHECK_FILES} "d1/f2.txt") -endif() - -# cleanup first in case there are files left from previous runs -# if the umask is odd on the machine it might create files that -# are not automatically over written. These tests are run -# each time the configure step is run. -file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar") -file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz") -file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/test_output_tar") -file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz") - -make_directory("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar") -make_directory("${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz") - - -# Run tests -EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}" "cvf \"${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar\" tar_dir") -EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}" "cvfz \"${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz\" tar_dir") - -EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar" "xvf \"${CMAKE_CURRENT_BINARY_DIR}/test_tar.tar\"") -EXEC_TAR_COMMAND("${CMAKE_CURRENT_BINARY_DIR}/test_output_tgz" "xvfz \"${CMAKE_CURRENT_BINARY_DIR}/test_tgz.tgz\"") - -macro(CHECK_DIR_STRUCTURE DIR) - foreach(file ${CHECK_FILES}) - set(sfile "${DIR}/${file}") - set(rfile "${CMAKE_CURRENT_BINARY_DIR}/tar_dir/${file}") - if(NOT EXISTS "${sfile}") - message(SEND_ERROR "Cannot find file ${sfile}") - else() - exec_program("${CMAKE_COMMAND}" ARGS "-E compare_files \"${sfile}\" \"${rfile}\"" RETURN_VALUE ret) - if(${ret}) - message(SEND_ERROR "Files \"${sfile}\" \"${rfile}\" are different") - endif() - endif() - endforeach() -endmacro() - -CHECK_DIR_STRUCTURE("${CMAKE_CURRENT_BINARY_DIR}/test_output_tar/tar_dir") - -add_executable(TarTest TestTarExec.cxx) - diff --git a/Tests/VSWindowsFormsResx/CMakeLists.txt b/Tests/VSWindowsFormsResx/CMakeLists.txt index 4373810..43c4833 100644 --- a/Tests/VSWindowsFormsResx/CMakeLists.txt +++ b/Tests/VSWindowsFormsResx/CMakeLists.txt @@ -14,7 +14,7 @@ include(CheckCXXSourceCompiles) include(CheckIncludeFile) # Note: The designable form is assumed to have a .h extension as is default in Visual Studio. -# Node: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio +# Note: The designable form is assumed to have a .resx file with the same name and path (save extension) as is default in Visual Studio set(TARGET_H WindowsFormsResx/MyForm.h diff --git a/Tests/VSXaml/App.xaml b/Tests/VSXaml/App.xaml new file mode 100644 index 0000000..eecf2c1 --- /dev/null +++ b/Tests/VSXaml/App.xaml @@ -0,0 +1,7 @@ +<Application + x:Class="VSXaml.App" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="using:VSXaml"> + +</Application> diff --git a/Tests/VSXaml/App.xaml.cpp b/Tests/VSXaml/App.xaml.cpp new file mode 100644 index 0000000..334dc1f --- /dev/null +++ b/Tests/VSXaml/App.xaml.cpp @@ -0,0 +1,125 @@ +// +// App.xaml.cpp +// Implementation of the App class. +// + +#include "pch.h" +#include "MainPage.xaml.h" + +using namespace VSXaml; + +using namespace Platform; +using namespace Windows::ApplicationModel; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Interop; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 + +/// <summary> +/// Initializes the singleton application object. This is the first line of authored code +/// executed, and as such is the logical equivalent of main() or WinMain(). +/// </summary> +App::App() +{ + InitializeComponent(); + Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending); +} + +/// <summary> +/// Invoked when the application is launched normally by the end user. Other entry points +/// will be used such as when the application is launched to open a specific file. +/// </summary> +/// <param name="e">Details about the launch request and process.</param> +void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) +{ + +#if _DEBUG + // Show graphics profiling information while debugging. + if (IsDebuggerPresent()) + { + // Display the current frame rate counters + DebugSettings->EnableFrameRateCounter = true; + } +#endif + + auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content); + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == nullptr) + { + // Create a Frame to act as the navigation context and associate it with + // a SuspensionManager key + rootFrame = ref new Frame(); + + // Set the default language + rootFrame->Language = Windows::Globalization::ApplicationLanguages::Languages->GetAt(0); + + rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed); + + if (e->PreviousExecutionState == ApplicationExecutionState::Terminated) + { + // TODO: Restore the saved session state only when appropriate, scheduling the + // final launch steps after the restore is complete + + } + + if (rootFrame->Content == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); + } + // Place the frame in the current Window + Window::Current->Content = rootFrame; + // Ensure the current window is active + Window::Current->Activate(); + } + else + { + if (rootFrame->Content == nullptr) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments); + } + // Ensure the current window is active + Window::Current->Activate(); + } +} + +/// <summary> +/// Invoked when application execution is being suspended. Application state is saved +/// without knowing whether the application will be terminated or resumed with the contents +/// of memory still intact. +/// </summary> +/// <param name="sender">The source of the suspend request.</param> +/// <param name="e">Details about the suspend request.</param> +void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e) +{ + (void) sender; // Unused parameter + (void) e; // Unused parameter + + //TODO: Save application state and stop any background activity +} + +/// <summary> +/// Invoked when Navigation to a certain page fails +/// </summary> +/// <param name="sender">The Frame which failed navigation</param> +/// <param name="e">Details about the navigation failure</param> +void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e) +{ + throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name); +}
\ No newline at end of file diff --git a/Tests/VSXaml/App.xaml.h b/Tests/VSXaml/App.xaml.h new file mode 100644 index 0000000..1f65bda --- /dev/null +++ b/Tests/VSXaml/App.xaml.h @@ -0,0 +1,27 @@ +// +// App.xaml.h +// Declaration of the App class. +// + +#pragma once + +#include "App.g.h" + +namespace VSXaml +{ + /// <summary> + /// Provides application-specific behavior to supplement the default Application class. + /// </summary> + ref class App sealed + { + protected: + virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override; + + internal: + App(); + + private: + void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); + void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e); + }; +} diff --git a/Tests/VSXaml/Assets/Logo.scale-100.png b/Tests/VSXaml/Assets/Logo.scale-100.png Binary files differnew file mode 100644 index 0000000..e26771c --- /dev/null +++ b/Tests/VSXaml/Assets/Logo.scale-100.png diff --git a/Tests/VSXaml/Assets/SmallLogo.scale-100.png b/Tests/VSXaml/Assets/SmallLogo.scale-100.png Binary files differnew file mode 100644 index 0000000..1eb0d9d --- /dev/null +++ b/Tests/VSXaml/Assets/SmallLogo.scale-100.png diff --git a/Tests/VSXaml/Assets/SplashScreen.scale-100.png b/Tests/VSXaml/Assets/SplashScreen.scale-100.png Binary files differnew file mode 100644 index 0000000..c951e03 --- /dev/null +++ b/Tests/VSXaml/Assets/SplashScreen.scale-100.png diff --git a/Tests/VSXaml/Assets/StoreLogo.scale-100.png b/Tests/VSXaml/Assets/StoreLogo.scale-100.png Binary files differnew file mode 100644 index 0000000..dcb6727 --- /dev/null +++ b/Tests/VSXaml/Assets/StoreLogo.scale-100.png diff --git a/Tests/VSXaml/CMakeLists.txt b/Tests/VSXaml/CMakeLists.txt new file mode 100644 index 0000000..f384c82 --- /dev/null +++ b/Tests/VSXaml/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.2) +project(VSXaml) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(SOURCE_FILES + App.xaml.cpp + MainPage.xaml.cpp + pch.cpp + ) + +set(HEADER_FILES + App.xaml.h + MainPage.xaml.h + pch.h + ) + +set(XAML_FILES + App.xaml + MainPage.xaml + ) + +set(ASSET_FILES + Assets/Logo.scale-100.png + Assets/SmallLogo.scale-100.png + Assets/SplashScreen.scale-100.png + Assets/StoreLogo.scale-100.png + ) + +set(CONTENT_FILES + Package.appxmanifest + ) + +set(RESOURCE_FILES + ${CONTENT_FILES} ${ASSET_FILES} + VSXaml_TemporaryKey.pfx) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +set_property(SOURCE ${CONTENT_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1) +set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_CONTENT 1) +set_property(SOURCE ${ASSET_FILES} PROPERTY VS_DEPLOYMENT_LOCATION "Assets") + +set_property(SOURCE "App.xaml" PROPERTY VS_XAML_TYPE "ApplicationDefinition") + +source_group("Source Files" FILES ${SOURCE_FILES}) +source_group("Header Files" FILES ${HEADER_FILES}) +source_group("Resource Files" FILES ${RESOURCE_FILES}) +source_group("Xaml Files" FILES ${XAML_FILES}) + +add_executable(VSXaml WIN32 ${SOURCE_FILES} ${HEADER_FILES} ${RESOURCE_FILES} ${XAML_FILES}) +set_property(TARGET VSXaml PROPERTY VS_WINRT_COMPONENT TRUE) diff --git a/Tests/VSXaml/MainPage.xaml b/Tests/VSXaml/MainPage.xaml new file mode 100644 index 0000000..62139ca --- /dev/null +++ b/Tests/VSXaml/MainPage.xaml @@ -0,0 +1,14 @@ +<Page + x:Class="VSXaml.MainPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:local="using:VSXaml" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + mc:Ignorable="d"> + + <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> + <TextBlock Text="I'm a CMake XAML App" HorizontalAlignment="Center" VerticalAlignment="Center" + Style="{StaticResource HeaderTextBlockStyle}"/> + </Grid> +</Page> diff --git a/Tests/VSXaml/MainPage.xaml.cpp b/Tests/VSXaml/MainPage.xaml.cpp new file mode 100644 index 0000000..d0a64e8 --- /dev/null +++ b/Tests/VSXaml/MainPage.xaml.cpp @@ -0,0 +1,27 @@ +// +// MainPage.xaml.cpp +// Implementation of the MainPage class. +// + +#include "pch.h" +#include "MainPage.xaml.h" + +using namespace VSXaml; + +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::UI::Xaml; +using namespace Windows::UI::Xaml::Controls; +using namespace Windows::UI::Xaml::Controls::Primitives; +using namespace Windows::UI::Xaml::Data; +using namespace Windows::UI::Xaml::Input; +using namespace Windows::UI::Xaml::Media; +using namespace Windows::UI::Xaml::Navigation; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +MainPage::MainPage() +{ + InitializeComponent(); +} diff --git a/Tests/VSXaml/MainPage.xaml.h b/Tests/VSXaml/MainPage.xaml.h new file mode 100644 index 0000000..ccc781b --- /dev/null +++ b/Tests/VSXaml/MainPage.xaml.h @@ -0,0 +1,21 @@ +// +// MainPage.xaml.h +// Declaration of the MainPage class. +// + +#pragma once + +#include "MainPage.g.h" + +namespace VSXaml +{ + /// <summary> + /// An empty page that can be used on its own or navigated to within a Frame. + /// </summary> + public ref class MainPage sealed + { + public: + MainPage(); + + }; +} diff --git a/Tests/VSXaml/Package.appxmanifest b/Tests/VSXaml/Package.appxmanifest new file mode 100644 index 0000000..873a64a --- /dev/null +++ b/Tests/VSXaml/Package.appxmanifest @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest"> + + <Identity Name="19ff96f1-8379-4e14-8b9d-04648b3b36a9" + Publisher="CN=Microsoft" + Version="1.0.0.0" /> + + <Properties> + <DisplayName>VSXaml</DisplayName> + <PublisherDisplayName>Microsoft</PublisherDisplayName> + <Logo>Assets\StoreLogo.png</Logo> + </Properties> + + <Prerequisites> + <OSMinVersion>6.3.0</OSMinVersion> + <OSMaxVersionTested>6.3.0</OSMaxVersionTested> + </Prerequisites> + + <Resources> + <Resource Language="x-generate"/> + </Resources> + + <Applications> + <Application Id="App" + Executable="$targetnametoken$.exe" + EntryPoint="VSXaml.App"> + <m2:VisualElements + DisplayName="VSXaml" + Square150x150Logo="Assets\Logo.png" + Square30x30Logo="Assets\SmallLogo.png" + Description="VSXaml" + ForegroundText="light" + BackgroundColor="#464646"> + <m2:SplashScreen Image="Assets\SplashScreen.png" /> + </m2:VisualElements> + </Application> + </Applications> + <Capabilities> + <Capability Name="internetClient" /> + </Capabilities> +</Package>
\ No newline at end of file diff --git a/Tests/VSXaml/VSXaml_TemporaryKey.pfx b/Tests/VSXaml/VSXaml_TemporaryKey.pfx Binary files differnew file mode 100644 index 0000000..1cad999 --- /dev/null +++ b/Tests/VSXaml/VSXaml_TemporaryKey.pfx diff --git a/Tests/VSXaml/pch.cpp b/Tests/VSXaml/pch.cpp new file mode 100644 index 0000000..01484ff --- /dev/null +++ b/Tests/VSXaml/pch.cpp @@ -0,0 +1,6 @@ +// +// pch.cpp +// Include the standard header and generate the precompiled header. +// + +#include "pch.h" diff --git a/Tests/VSXaml/pch.h b/Tests/VSXaml/pch.h new file mode 100644 index 0000000..2c4354d --- /dev/null +++ b/Tests/VSXaml/pch.h @@ -0,0 +1,11 @@ +// +// pch.h +// Header for standard system include files. +// + +#pragma once + +#include <collection.h> +#include <ppltasks.h> + +#include "App.xaml.h" 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) diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c index 96b88d8..d136498 100644 --- a/Utilities/cmlibarchive/libarchive/archive_util.c +++ b/Utilities/cmlibarchive/libarchive/archive_util.c @@ -249,6 +249,8 @@ __archive_errx(int retvalue, const char *msg) int __archive_mktemp(const char *tmpdir) { + static const wchar_t *prefix = L"libarchive_"; + static const wchar_t *suffix = L"XXXXXXXXXX"; static const wchar_t num[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F', @@ -323,10 +325,10 @@ __archive_mktemp(const char *tmpdir) /* * Create a temporary file. */ - archive_wstrcat(&temp_name, L"libarchive_"); - xp = temp_name.s + archive_strlen(&temp_name); - archive_wstrcat(&temp_name, L"XXXXXXXXXX"); + archive_wstrcat(&temp_name, prefix); + archive_wstrcat(&temp_name, suffix); ep = temp_name.s + archive_strlen(&temp_name); + xp = ep - wcslen(suffix); if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c index 13942c1..647079d 100644 --- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c +++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c @@ -644,18 +644,18 @@ archive_format_gnutar_header(struct archive_write *a, char h[512], format_octal(archive_entry_mode(entry) & 07777, h + GNUTAR_mode_offset, GNUTAR_mode_size); - /* TODO: How does GNU tar handle large UIDs? */ - if (format_octal(archive_entry_uid(entry), - h + GNUTAR_uid_offset, GNUTAR_uid_size)) { + /* GNU tar supports base-256 here, so should never overflow. */ + if (format_number(archive_entry_uid(entry), h + GNUTAR_uid_offset, + GNUTAR_uid_size, GNUTAR_uid_max_size)) { archive_set_error(&a->archive, ERANGE, "Numeric user ID %jd too large", (intmax_t)archive_entry_uid(entry)); ret = ARCHIVE_FAILED; } - /* TODO: How does GNU tar handle large GIDs? */ - if (format_octal(archive_entry_gid(entry), - h + GNUTAR_gid_offset, GNUTAR_gid_size)) { + /* GNU tar supports base-256 here, so should never overflow. */ + if (format_number(archive_entry_gid(entry), h + GNUTAR_gid_offset, + GNUTAR_gid_size, GNUTAR_gid_max_size)) { archive_set_error(&a->archive, ERANGE, "Numeric group ID %jd too large", (intmax_t)archive_entry_gid(entry)); diff --git a/Utilities/cmliblzma/CMakeLists.txt b/Utilities/cmliblzma/CMakeLists.txt index d991438..8920536 100644 --- a/Utilities/cmliblzma/CMakeLists.txt +++ b/Utilities/cmliblzma/CMakeLists.txt @@ -211,4 +211,14 @@ ENDIF() ADD_LIBRARY(cmliblzma ${LZMA_SRCS}) +IF(CMAKE_C_COMPILER_ID STREQUAL "XL") + # Disable the XL compiler optimizer because it causes crashes + # and other bad behavior in liblzma code. + SET_PROPERTY(TARGET cmliblzma PROPERTY COMPILE_FLAGS "-qnooptimize") +ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND + CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4) + # Disable the old GNU compiler optimizer. + SET_PROPERTY(TARGET cmliblzma PROPERTY COMPILE_FLAGS "-O0") +ENDIF() + INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmliblzma) diff --git a/Utilities/cmliblzma/config.h.in b/Utilities/cmliblzma/config.h.in index 017c435..9c53150 100644 --- a/Utilities/cmliblzma/config.h.in +++ b/Utilities/cmliblzma/config.h.in @@ -280,4 +280,10 @@ typedef uint64_t uintmax_t; /* Define to 1 if the system supports fast unaligned access to 16-bit and 32-bit integers. */ -#define TUKLIB_FAST_UNALIGNED_ACCESS 1 +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) \ + || defined(__amd64) || defined(__amd64__) \ + || defined(__powerpc) || defined(__powerpc__) \ + || defined(__ppc) || defined(__ppc__) || defined(__POWERPC__) +# define TUKLIB_FAST_UNALIGNED_ACCESS 1 +#endif @@ -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 \ |