diff options
42 files changed, 835 insertions, 167 deletions
diff --git a/Help/dev/source.rst b/Help/dev/source.rst index 0f7488b..5371353 100644 --- a/Help/dev/source.rst +++ b/Help/dev/source.rst @@ -23,12 +23,142 @@ format only a subset of files, such as those that are locally modified. C++ Subset Permitted ==================== -CMake requires compiling as C++11 or above. However, in order to support -building on older toolchains some constructs need to be handled with care: +CMake requires compiling as C++11 in order to support building on older +toolchains. However, to facilitate development, some standard library +features from more recent C++ standards are supported through a compatibility +layer. These features are defined under the namespace ``cm`` and headers +are accessible under the ``cm/`` directory. The headers under ``cm/`` can +be used in place of the standard ones when extended features are needed. +For example ``<cm/memory>`` can be used in place of ``<memory>``. -* Do not use ``std::auto_ptr``. +Available features are: - The ``std::auto_ptr`` template is deprecated in C++11. Use ``std::unique_ptr``. +* From ``C++14``: + + * ``<cm/iterator>``: + ``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``, + ``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend`` + + * ``<cm/memory>``: + ``cm::make_unique`` + + * ``<cm/shared_mutex>``: + ``cm::shared_lock`` + + * ``<cm/type_traits>``: + ``cm::enable_if_t`` + +* From ``C++17``: + + * ``<cm/algorithm>``: + ``cm::clamp`` + + * ``<cm/iterator>``: + ``cm::size``, ``cm::empty``, ``cm::data`` + + * ``<cm/optional>``: + ``cm::nullopt_t``, ``cm::nullopt``, ``cm::optional``, + ``cm::make_optional``, ``cm::bad_optional_access`` + + * ``<cm/shared_mutex>``: + ``cm::shared_mutex`` + + * ``<cm/string_view>``: + ``cm::string_view`` + + * ``<cm/type_traits>``: + ``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``, + ``cm::void_t`` + + * ``<cm/utility>``: + ``cm::in_place_t``, ``cm::in_place`` + +* From ``C++20``: + + * ``<cm/deque>``: + ``cm::erase``, ``cm::erase_if`` + + * ``<cm/list>``: + ``cm::erase``, ``cm::erase_if`` + + * ``<cm/map>`` : + ``cm::erase_if`` + + * ``<cm/set>`` : + ``cm::erase_if`` + + * ``<cm/string>``: + ``cm::erase``, ``cm::erase_if`` + + * ``<cm/unordered_map>``: + ``cm::erase_if`` + + * ``<cm/unordered_set>``: + ``cm::erase_if`` + + * ``<cm/vector>``: + ``cm::erase``, ``cm::erase_if`` + +Additionally, some useful non-standard extensions to the C++ standard library +are available in headers under the directory ``cmext/`` in namespace ``cm``. +These are: + +* ``<cmext/algorithm>``: + + * ``cm::append``: + Append elements to a sequential container. + +* ``<cmext/iterator>``: + + * ``cm::is_terator``: + Checks if a type is an iterator type. + + * ``cm::is_input_iterator``: + Checks if a type is an input iterator type. + + * ``cm::is_range``: + Checks if a type is a range type: must have methods ``begin()`` and + ``end()`` returning an iterator. + + * ``cm::is_input_range``: + Checks if a type is an input range type: must have methods ``begin()`` and + ``end()`` returning an input iterator. + +* ``<cmext/memory>``: + + * ``cm::static_reference_cast``: + Apply a ``static_cast`` to a smart pointer. + + * ``cm::dynamic_reference_cast``: + Apply a ``dynamic_cast`` to a smart pointer. + +* ``<cmext/type_traits>``: + + * ``cm::is_container``: + Checks if a type is a container type. + + * ``cm::is_associative_container``: + Checks if a type is an associative container type. + + * ``cm::is_unordered_associative_container``: + Checks if a type is an unordered associative container type. + + * ``cm::is_sequence_container``: + Checks if a type is a sequence container type. + + * ``cm::is_unique_ptr``: + Checks if a type is a ``std::unique_ptr`` type. + +Dynamic Memory Management +========================= + +To ensure efficient memory management, i.e. no memory leaks, it is required +to use smart pointers. Any dynamic memory allocation must be handled by a +smart pointer such as ``std::unique_ptr`` or ``std::shared_ptr``. + +It is allowed to pass raw pointers between objects to enable objects sharing. +A raw pointer **must** not be deleted. Only the object(s) owning the smart +pointer are allowed to delete dynamically allocated memory. Source Tree Layout ================== @@ -69,6 +199,12 @@ The CMake source tree is organized as follows. * ``Utilities/``: Scripts, third-party source code. + * ``Utilities/std/cm``: + Support files for various C++ standards. + + * ``Utilities/std/cmext``: + Extensions to the C++ STL. + * ``Utilities/Sphinx/``: Sphinx configuration to build CMake user documentation. diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 44b1f2f..429cba4 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -356,6 +356,20 @@ Options in :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`. This flag tells CMake to warn about other files as well. +``--profiling-output=<path>`` + Used in conjuction with ``--profiling-format`` to output to a given path. + +``--profiling-format=<file>`` + Enable the output of profiling data of CMake script in the given format. + + This can aid performance analysis of CMake scripts executed. Third party + applications should be used to process the output into human readable format. + + Currently supported values are: + ``google-trace`` Outputs in Google Trace Format, which can be parsed by the + about:tracing tab of Google Chrome or using a plugin for a tool like Trace + Compass. + .. _`Build Tool Mode`: Build a Project diff --git a/Help/release/dev/FindRuby-variable-case.rst b/Help/release/dev/FindRuby-variable-case.rst new file mode 100644 index 0000000..bd4a2f1 --- /dev/null +++ b/Help/release/dev/FindRuby-variable-case.rst @@ -0,0 +1,7 @@ +FindRuby-variable-case +---------------------- + +* The :module:`FindRuby` module input and output variables were all renamed + from ``RUBY_`` to ``Ruby_`` for consistency with other find modules. + Input variables of the old case will be honored if provided, and output + variables of the old case are always provided. diff --git a/Help/release/dev/profiling.rst b/Help/release/dev/profiling.rst new file mode 100644 index 0000000..ab180f0 --- /dev/null +++ b/Help/release/dev/profiling.rst @@ -0,0 +1,9 @@ +cmake-profiling +--------------- + +* Add support for profiling of CMake scripts through the parameters + ``--profiling-output`` and ``--profiling-format``. These options can + be used by users to gain insight into the performance of their scripts. + + The first supported output format is ``google-trace`` which is a format + supported by Google Chrome's ``about:tracing`` tab. diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in index b8e09fe..858c053 100644 --- a/Modules/CMakeASMCompiler.cmake.in +++ b/Modules/CMakeASMCompiler.cmake.in @@ -10,6 +10,7 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1) set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@") set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@") set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@") +@_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH@ @_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID@ set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index e47f3a4..86fb057 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -211,6 +211,13 @@ foreach(_var set(_CMAKE_ASM_${_var} "${CMAKE_ASM${ASM_DIALECT}_${_var}}") endforeach() +if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH) + set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH + "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}]==])") +else() + set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH "") +endif() + if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID) set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID})") diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index d125791..812f032 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -868,6 +868,14 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}) endif() + # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables + # and set them to "C" so we get the expected output to match. + set(_orig_lc_all $ENV{LC_ALL}) + set(_orig_lc_messages $ENV{LC_MESSAGES}) + set(_orig_lang $ENV{LANG}) + set(ENV{LC_ALL} C) + set(ENV{LC_MESSAGES} C) + set(ENV{LANG} C) foreach(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS}) set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}}) @@ -889,6 +897,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) "matched \"${regex}\":\n${output}") set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE) + set(CMAKE_${lang}_COMPILER_ID_VENDOR_MATCH "${CMAKE_MATCH_1}" PARENT_SCOPE) break() else() if("${result}" MATCHES "timeout") @@ -902,6 +911,11 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags) endif() endif() endforeach() + + # Restore original LC_ALL, LC_MESSAGES, and LANG + set(ENV{LC_ALL} ${_orig_lc_all}) + set(ENV{LC_MESSAGES} ${_orig_lc_messages}) + set(ENV{LANG} ${_orig_lang}) endfunction() function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags) diff --git a/Modules/Compiler/GNU-ASM.cmake b/Modules/Compiler/GNU-ASM.cmake index e07401d..4aa680f 100644 --- a/Modules/Compiler/GNU-ASM.cmake +++ b/Modules/Compiler/GNU-ASM.cmake @@ -4,3 +4,9 @@ include(Compiler/GNU) set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm) __compiler_gnu(ASM) + +if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH STREQUAL "GNU assembler") + set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEPFILE>") + set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE + "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") +endif() diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index 7e01fbc..5df242b 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -17,279 +17,323 @@ standard syntax, e.g. find_package(Ruby 1.8) It also determines what the name of the library is. This code sets the following variables: -``RUBY_EXECUTABLE`` +``Ruby_EXECUTABLE`` full path to the ruby binary -``RUBY_INCLUDE_DIRS`` +``Ruby_INCLUDE_DIRS`` include dirs to be used when using the ruby library -``RUBY_LIBRARY`` +``Ruby_LIBRARY`` full path to the ruby library -``RUBY_VERSION`` +``Ruby_VERSION`` the version of ruby which was found, e.g. "1.8.7" -``RUBY_FOUND`` +``Ruby_FOUND`` set to true if ruby ws found successfully Also: -``RUBY_INCLUDE_PATH`` - same as RUBY_INCLUDE_DIRS, only provided for compatibility reasons, don't use it +``Ruby_INCLUDE_PATH`` + same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it #]=======================================================================] -# RUBY_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'` -# RUBY_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'` -# RUBY_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'` -# RUBY_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'` -# RUBY_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'` +# Backwards compatibility +# Define camel case versions of input variables +foreach(UPPER + RUBY_EXECUTABLE + RUBY_LIBRARY + RUBY_INCLUDE_DIR + RUBY_CONFIG_INCLUDE_DIR + ) + if (DEFINED ${UPPER}) + string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER}) + if (NOT DEFINED ${Camel}) + set(${Camel} ${${UPPER}}) + endif() + endif() +endforeach() + +# Ruby_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'` +# Ruby_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'` +# Ruby_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'` +# Ruby_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'` +# Ruby_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'` # uncomment the following line to get debug output for this file -# set(_RUBY_DEBUG_OUTPUT TRUE) +# set(_Ruby_DEBUG_OUTPUT TRUE) # Determine the list of possible names of the ruby executable depending # on which version of ruby is required -set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby) +set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby) # if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8 if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR) - set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}") + set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}") # we can't construct that if only major version is given - set(_RUBY_POSSIBLE_EXECUTABLE_NAMES + set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${Ruby_FIND_VERSION_MAJOR}.${Ruby_FIND_VERSION_MINOR} ruby${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR} - ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}) + ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}) else() set(Ruby_FIND_VERSION_SHORT_NODOT "18") endif() if(NOT Ruby_FIND_VERSION_EXACT) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.4 ruby24) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.3 ruby23) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.2 ruby22) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20) - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.4 ruby24) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.3 ruby23) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.2 ruby22) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19) # if we want a version below 1.9, also look for ruby 1.8 if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19") - list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18) + list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18) endif() - list(REMOVE_DUPLICATES _RUBY_POSSIBLE_EXECUTABLE_NAMES) + list(REMOVE_DUPLICATES _Ruby_POSSIBLE_EXECUTABLE_NAMES) endif() -find_program(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}) +find_program(Ruby_EXECUTABLE NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}) -if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR) +if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) function(_RUBY_CONFIG_VAR RBVAR OUTVAR) - execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']" - RESULT_VARIABLE _RUBY_SUCCESS - OUTPUT_VARIABLE _RUBY_OUTPUT + execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']" + RESULT_VARIABLE _Ruby_SUCCESS + OUTPUT_VARIABLE _Ruby_OUTPUT ERROR_QUIET) - if(_RUBY_SUCCESS OR _RUBY_OUTPUT STREQUAL "") - execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']" - RESULT_VARIABLE _RUBY_SUCCESS - OUTPUT_VARIABLE _RUBY_OUTPUT + if(_Ruby_SUCCESS OR _Ruby_OUTPUT STREQUAL "") + execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']" + RESULT_VARIABLE _Ruby_SUCCESS + OUTPUT_VARIABLE _Ruby_OUTPUT ERROR_QUIET) endif() - set(${OUTVAR} "${_RUBY_OUTPUT}" PARENT_SCOPE) + set(${OUTVAR} "${_Ruby_OUTPUT}" PARENT_SCOPE) endfunction() # query the ruby version - _RUBY_CONFIG_VAR("MAJOR" RUBY_VERSION_MAJOR) - _RUBY_CONFIG_VAR("MINOR" RUBY_VERSION_MINOR) - _RUBY_CONFIG_VAR("TEENY" RUBY_VERSION_PATCH) + _RUBY_CONFIG_VAR("MAJOR" Ruby_VERSION_MAJOR) + _RUBY_CONFIG_VAR("MINOR" Ruby_VERSION_MINOR) + _RUBY_CONFIG_VAR("TEENY" Ruby_VERSION_PATCH) # query the different directories - _RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR) - _RUBY_CONFIG_VAR("arch" RUBY_ARCH) - _RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR) - _RUBY_CONFIG_VAR("rubyarchhdrdir" RUBY_ARCHHDR_DIR) - _RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR) - _RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR) + _RUBY_CONFIG_VAR("archdir" Ruby_ARCH_DIR) + _RUBY_CONFIG_VAR("arch" Ruby_ARCH) + _RUBY_CONFIG_VAR("rubyhdrdir" Ruby_HDR_DIR) + _RUBY_CONFIG_VAR("rubyarchhdrdir" Ruby_ARCHHDR_DIR) + _RUBY_CONFIG_VAR("libdir" Ruby_POSSIBLE_LIB_DIR) + _RUBY_CONFIG_VAR("rubylibdir" Ruby_RUBY_LIB_DIR) # site_ruby - _RUBY_CONFIG_VAR("sitearchdir" RUBY_SITEARCH_DIR) - _RUBY_CONFIG_VAR("sitelibdir" RUBY_SITELIB_DIR) + _RUBY_CONFIG_VAR("sitearchdir" Ruby_SITEARCH_DIR) + _RUBY_CONFIG_VAR("sitelibdir" Ruby_SITELIB_DIR) # vendor_ruby available ? - execute_process(COMMAND ${RUBY_EXECUTABLE} -r vendor-specific -e "print 'true'" - OUTPUT_VARIABLE RUBY_HAS_VENDOR_RUBY ERROR_QUIET) + execute_process(COMMAND ${Ruby_EXECUTABLE} -r vendor-specific -e "print 'true'" + OUTPUT_VARIABLE Ruby_HAS_VENDOR_RUBY ERROR_QUIET) - if(RUBY_HAS_VENDOR_RUBY) - _RUBY_CONFIG_VAR("vendorlibdir" RUBY_VENDORLIB_DIR) - _RUBY_CONFIG_VAR("vendorarchdir" RUBY_VENDORARCH_DIR) + if(Ruby_HAS_VENDOR_RUBY) + _RUBY_CONFIG_VAR("vendorlibdir" Ruby_VENDORLIB_DIR) + _RUBY_CONFIG_VAR("vendorarchdir" Ruby_VENDORARCH_DIR) endif() # save the results in the cache so we don't have to run ruby the next time again - set(RUBY_VERSION_MAJOR ${RUBY_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE) - set(RUBY_VERSION_MINOR ${RUBY_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE) - set(RUBY_VERSION_PATCH ${RUBY_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE) - set(RUBY_ARCH_DIR ${RUBY_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE) - set(RUBY_HDR_DIR ${RUBY_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE) - set(RUBY_ARCHHDR_DIR ${RUBY_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE) - set(RUBY_POSSIBLE_LIB_DIR ${RUBY_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE) - set(RUBY_RUBY_LIB_DIR ${RUBY_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE) - set(RUBY_SITEARCH_DIR ${RUBY_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE) - set(RUBY_SITELIB_DIR ${RUBY_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE) - set(RUBY_HAS_VENDOR_RUBY ${RUBY_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE) - set(RUBY_VENDORARCH_DIR ${RUBY_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE) - set(RUBY_VENDORLIB_DIR ${RUBY_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE) + set(Ruby_VERSION_MAJOR ${Ruby_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE) + set(Ruby_VERSION_MINOR ${Ruby_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE) + set(Ruby_VERSION_PATCH ${Ruby_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE) + set(Ruby_ARCH_DIR ${Ruby_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE) + set(Ruby_HDR_DIR ${Ruby_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE) + set(Ruby_ARCHHDR_DIR ${Ruby_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE) + set(Ruby_POSSIBLE_LIB_DIR ${Ruby_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE) + set(Ruby_RUBY_LIB_DIR ${Ruby_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE) + set(Ruby_SITEARCH_DIR ${Ruby_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE) + set(Ruby_SITELIB_DIR ${Ruby_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE) + set(Ruby_HAS_VENDOR_RUBY ${Ruby_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE) + set(Ruby_VENDORARCH_DIR ${Ruby_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE) + set(Ruby_VENDORLIB_DIR ${Ruby_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE) mark_as_advanced( - RUBY_ARCH_DIR - RUBY_ARCH - RUBY_HDR_DIR - RUBY_ARCHHDR_DIR - RUBY_POSSIBLE_LIB_DIR - RUBY_RUBY_LIB_DIR - RUBY_SITEARCH_DIR - RUBY_SITELIB_DIR - RUBY_HAS_VENDOR_RUBY - RUBY_VENDORARCH_DIR - RUBY_VENDORLIB_DIR - RUBY_VERSION_MAJOR - RUBY_VERSION_MINOR - RUBY_VERSION_PATCH + Ruby_ARCH_DIR + Ruby_ARCH + Ruby_HDR_DIR + Ruby_ARCHHDR_DIR + Ruby_POSSIBLE_LIB_DIR + Ruby_RUBY_LIB_DIR + Ruby_SITEARCH_DIR + Ruby_SITELIB_DIR + Ruby_HAS_VENDOR_RUBY + Ruby_VENDORARCH_DIR + Ruby_VENDORLIB_DIR + Ruby_VERSION_MAJOR + Ruby_VERSION_MINOR + Ruby_VERSION_PATCH ) endif() -# In case RUBY_EXECUTABLE could not be executed (e.g. cross compiling) +# In case Ruby_EXECUTABLE could not be executed (e.g. cross compiling) # try to detect which version we found. This is not too good. -if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR) +if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) # by default assume 1.8.0 - set(RUBY_VERSION_MAJOR 1) - set(RUBY_VERSION_MINOR 8) - set(RUBY_VERSION_PATCH 0) + set(Ruby_VERSION_MAJOR 1) + set(Ruby_VERSION_MINOR 8) + set(Ruby_VERSION_PATCH 0) # check whether we found 1.9.x - if(${RUBY_EXECUTABLE} MATCHES "ruby1\\.?9") - set(RUBY_VERSION_MAJOR 1) - set(RUBY_VERSION_MINOR 9) + if(${Ruby_EXECUTABLE} MATCHES "ruby1\\.?9") + set(Ruby_VERSION_MAJOR 1) + set(Ruby_VERSION_MINOR 9) endif() # check whether we found 2.0.x - if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?0") - set(RUBY_VERSION_MAJOR 2) - set(RUBY_VERSION_MINOR 0) + if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0") + set(Ruby_VERSION_MAJOR 2) + set(Ruby_VERSION_MINOR 0) endif() # check whether we found 2.1.x - if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?1") - set(RUBY_VERSION_MAJOR 2) - set(RUBY_VERSION_MINOR 1) + if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1") + set(Ruby_VERSION_MAJOR 2) + set(Ruby_VERSION_MINOR 1) endif() # check whether we found 2.2.x - if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?2") - set(RUBY_VERSION_MAJOR 2) - set(RUBY_VERSION_MINOR 2) + if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2") + set(Ruby_VERSION_MAJOR 2) + set(Ruby_VERSION_MINOR 2) endif() # check whether we found 2.3.x - if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?3") - set(RUBY_VERSION_MAJOR 2) - set(RUBY_VERSION_MINOR 3) + if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3") + set(Ruby_VERSION_MAJOR 2) + set(Ruby_VERSION_MINOR 3) endif() # check whether we found 2.4.x - if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?4") - set(RUBY_VERSION_MAJOR 2) - set(RUBY_VERSION_MINOR 4) + if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4") + set(Ruby_VERSION_MAJOR 2) + set(Ruby_VERSION_MINOR 4) endif() endif() -if(RUBY_VERSION_MAJOR) - set(RUBY_VERSION "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}") - set(_RUBY_VERSION_SHORT "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}") - set(_RUBY_VERSION_SHORT_NODOT "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}") - set(_RUBY_NODOT_VERSION "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}") +if(Ruby_VERSION_MAJOR) + set(Ruby_VERSION "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}.${Ruby_VERSION_PATCH}") + set(_Ruby_VERSION_SHORT "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}") + set(_Ruby_VERSION_SHORT_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}") + set(_Ruby_NODOT_VERSION "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}${Ruby_VERSION_PATCH}") endif() -find_path(RUBY_INCLUDE_DIR +find_path(Ruby_INCLUDE_DIR NAMES ruby.h HINTS - ${RUBY_HDR_DIR} - ${RUBY_ARCH_DIR} - /usr/lib/ruby/${_RUBY_VERSION_SHORT}/i586-linux-gnu/ + ${Ruby_HDR_DIR} + ${Ruby_ARCH_DIR} + /usr/lib/ruby/${_Ruby_VERSION_SHORT}/i586-linux-gnu/ ) -set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIR} ) +set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR} ) # if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir -if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_RUBY_VERSION_SHORT_NODOT}" GREATER 18 OR RUBY_HDR_DIR) - find_path(RUBY_CONFIG_INCLUDE_DIR +if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_Ruby_VERSION_SHORT_NODOT}" GREATER 18 OR Ruby_HDR_DIR) + find_path(Ruby_CONFIG_INCLUDE_DIR NAMES ruby/config.h config.h HINTS - ${RUBY_HDR_DIR}/${RUBY_ARCH} - ${RUBY_ARCH_DIR} - ${RUBY_ARCHHDR_DIR} + ${Ruby_HDR_DIR}/${Ruby_ARCH} + ${Ruby_ARCH_DIR} + ${Ruby_ARCHHDR_DIR} ) - set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIRS} ${RUBY_CONFIG_INCLUDE_DIR} ) + set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIRS} ${Ruby_CONFIG_INCLUDE_DIR} ) endif() # Determine the list of possible names for the ruby library -set(_RUBY_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_RUBY_VERSION_SHORT} ruby${_RUBY_VERSION_SHORT_NODOT} ruby-${_RUBY_VERSION_SHORT} ruby-${RUBY_VERSION}) +set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION}) if(WIN32) - set( _RUBY_MSVC_RUNTIME "" ) + set( _Ruby_MSVC_RUNTIME "" ) if( MSVC_VERSION EQUAL 1200 ) - set( _RUBY_MSVC_RUNTIME "60" ) + set( _Ruby_MSVC_RUNTIME "60" ) endif() if( MSVC_VERSION EQUAL 1300 ) - set( _RUBY_MSVC_RUNTIME "70" ) + set( _Ruby_MSVC_RUNTIME "70" ) endif() if( MSVC_VERSION EQUAL 1310 ) - set( _RUBY_MSVC_RUNTIME "71" ) + set( _Ruby_MSVC_RUNTIME "71" ) endif() if( MSVC_VERSION EQUAL 1400 ) - set( _RUBY_MSVC_RUNTIME "80" ) + set( _Ruby_MSVC_RUNTIME "80" ) endif() if( MSVC_VERSION EQUAL 1500 ) - set( _RUBY_MSVC_RUNTIME "90" ) + set( _Ruby_MSVC_RUNTIME "90" ) endif() - set(_RUBY_ARCH_PREFIX "") + set(_Ruby_ARCH_PREFIX "") if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_RUBY_ARCH_PREFIX "x64-") + set(_Ruby_ARCH_PREFIX "x64-") endif() - list(APPEND _RUBY_POSSIBLE_LIB_NAMES - "${_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" ) + list(APPEND _Ruby_POSSIBLE_LIB_NAMES + "${_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} ) +find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} ) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) -set(_RUBY_REQUIRED_VARS RUBY_EXECUTABLE RUBY_INCLUDE_DIR RUBY_LIBRARY) -if(_RUBY_VERSION_SHORT_NODOT GREATER 18) - list(APPEND _RUBY_REQUIRED_VARS RUBY_CONFIG_INCLUDE_DIR) +set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY) +if(_Ruby_VERSION_SHORT_NODOT GREATER 18) + list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR) endif() -if(_RUBY_DEBUG_OUTPUT) +if(_Ruby_DEBUG_OUTPUT) message(STATUS "--------FindRuby.cmake debug------------") - message(STATUS "_RUBY_POSSIBLE_EXECUTABLE_NAMES: ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}") - message(STATUS "_RUBY_POSSIBLE_LIB_NAMES: ${_RUBY_POSSIBLE_LIB_NAMES}") - message(STATUS "RUBY_ARCH_DIR: ${RUBY_ARCH_DIR}") - message(STATUS "RUBY_HDR_DIR: ${RUBY_HDR_DIR}") - message(STATUS "RUBY_POSSIBLE_LIB_DIR: ${RUBY_POSSIBLE_LIB_DIR}") - message(STATUS "Found RUBY_VERSION: \"${RUBY_VERSION}\" , short: \"${_RUBY_VERSION_SHORT}\", nodot: \"${_RUBY_VERSION_SHORT_NODOT}\"") - message(STATUS "_RUBY_REQUIRED_VARS: ${_RUBY_REQUIRED_VARS}") - message(STATUS "RUBY_EXECUTABLE: ${RUBY_EXECUTABLE}") - message(STATUS "RUBY_LIBRARY: ${RUBY_LIBRARY}") - message(STATUS "RUBY_INCLUDE_DIR: ${RUBY_INCLUDE_DIR}") - message(STATUS "RUBY_CONFIG_INCLUDE_DIR: ${RUBY_CONFIG_INCLUDE_DIR}") + message(STATUS "_Ruby_POSSIBLE_EXECUTABLE_NAMES: ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}") + message(STATUS "_Ruby_POSSIBLE_LIB_NAMES: ${_Ruby_POSSIBLE_LIB_NAMES}") + message(STATUS "Ruby_ARCH_DIR: ${Ruby_ARCH_DIR}") + message(STATUS "Ruby_HDR_DIR: ${Ruby_HDR_DIR}") + message(STATUS "Ruby_POSSIBLE_LIB_DIR: ${Ruby_POSSIBLE_LIB_DIR}") + message(STATUS "Found Ruby_VERSION: \"${Ruby_VERSION}\" , short: \"${_Ruby_VERSION_SHORT}\", nodot: \"${_Ruby_VERSION_SHORT_NODOT}\"") + message(STATUS "_Ruby_REQUIRED_VARS: ${_Ruby_REQUIRED_VARS}") + message(STATUS "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}") + message(STATUS "Ruby_LIBRARY: ${Ruby_LIBRARY}") + message(STATUS "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}") + message(STATUS "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}") message(STATUS "--------------------") endif() -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_RUBY_REQUIRED_VARS} - VERSION_VAR RUBY_VERSION ) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_Ruby_REQUIRED_VARS} + VERSION_VAR Ruby_VERSION ) mark_as_advanced( - RUBY_EXECUTABLE - RUBY_LIBRARY - RUBY_INCLUDE_DIR - RUBY_CONFIG_INCLUDE_DIR + Ruby_EXECUTABLE + Ruby_LIBRARY + Ruby_INCLUDE_DIR + Ruby_CONFIG_INCLUDE_DIR ) -# Set some variables for compatibility with previous version of this file -set(RUBY_POSSIBLE_LIB_PATH ${RUBY_POSSIBLE_LIB_DIR}) -set(RUBY_RUBY_LIB_PATH ${RUBY_RUBY_LIB_DIR}) -set(RUBY_INCLUDE_PATH ${RUBY_INCLUDE_DIRS}) +# Set some variables for compatibility with previous version of this file (no need to provide a CamelCase version of that...) +set(RUBY_POSSIBLE_LIB_PATH ${Ruby_POSSIBLE_LIB_DIR}) +set(RUBY_RUBY_LIB_PATH ${Ruby_RUBY_LIB_DIR}) +set(RUBY_INCLUDE_PATH ${Ruby_INCLUDE_DIRS}) + +# Backwards compatibility +# Define upper case versions of output variables +foreach(Camel + Ruby_EXECUTABLE + Ruby_INCLUDE_DIRS + Ruby_LIBRARY + Ruby_VERSION + Ruby_VERSION_MAJOR + Ruby_VERSION_MINOR + Ruby_VERSION_PATCH + Ruby_INCLUDE_PATH + + Ruby_ARCH_DIR + Ruby_ARCH + Ruby_HDR_DIR + Ruby_ARCHHDR_DIR + Ruby_POSSIBLE_LIB_DIR + Ruby_RUBY_LIB_DIR + Ruby_SITEARCH_DIR + Ruby_SITELIB_DIR + Ruby_HAS_VENDOR_RUBY + Ruby_VENDORARCH_DIR + + ) + string(TOUPPER ${Camel} UPPER) + set(${UPPER} ${${Camel}}) +endforeach() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 24370aa..467abe9 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -354,6 +354,7 @@ set(SRCS cmMakefileTargetGenerator.cxx cmMakefileExecutableTargetGenerator.cxx cmMakefileLibraryTargetGenerator.cxx + cmMakefileProfilingData.cxx cmMakefileUtilityTargetGenerator.cxx cmMessageType.h cmMessenger.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1b452f8..edbac48 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 17) -set(CMake_VERSION_PATCH 20200313) +set(CMake_VERSION_PATCH 20200316) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 6441e6f..bbae86c 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -1116,7 +1116,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode( return; } /* clang-format off */ - os << "# Make sure the targets which have been exported in some other \n" + os << "# Make sure the targets which have been exported in some other\n" "# export set exist.\n" "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" "foreach(_target "; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index ad142d7..cb80fe6 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1282,6 +1282,86 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( } namespace { +std::string AddSwiftInterfaceIncludeDirectories( + const cmGeneratorTarget* root, const cmGeneratorTarget* target, + const std::string& config, cmGeneratorExpressionDAGChecker* context) +{ + cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target, + "Swift_MODULE_DIRECTORY", nullptr, + context }; + switch (dag.Check()) { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: + dag.ReportError(nullptr, + "$<TARGET_PROPERTY:" + target->GetName() + + ",Swift_MODULE_DIRECTORY>"); + return ""; + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: + // No error. We just skip cyclic references. + return ""; + case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: + // No error. We have already seen this transitive property. + return ""; + case cmGeneratorExpressionDAGChecker::DAG: + break; + } + + std::string directories; + if (const auto* interface = + target->GetLinkInterfaceLibraries(config, root, true)) { + for (const cmLinkItem& library : interface->Libraries) { + if (const cmGeneratorTarget* dependency = library.Target) { + if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) { + std::string value = + dependency->GetSafeProperty("Swift_MODULE_DIRECTORY"); + if (value.empty()) { + value = + dependency->GetLocalGenerator()->GetCurrentBinaryDirectory(); + } + + if (!directories.empty()) { + directories += ";"; + } + directories += value; + } + } + } + } + return directories; +} + +void AddSwiftImplicitIncludeDirectories( + const cmGeneratorTarget* target, const std::string& config, + std::vector<EvaluatedTargetPropertyEntry>& entries) +{ + if (const auto* libraries = target->GetLinkImplementationLibraries(config)) { + cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target, + "Swift_MODULE_DIRECTORY", nullptr, + nullptr }; + + for (const cmLinkImplItem& library : libraries->Libraries) { + if (const cmGeneratorTarget* dependency = library.Target) { + if (cmContains(dependency->GetAllConfigCompileLanguages(), "Swift")) { + EvaluatedTargetPropertyEntry entry{ library, library.Backtrace }; + + if (const char* val = + dependency->GetProperty("Swift_MODULE_DIRECTORY")) { + entry.Values.emplace_back(val); + } else { + entry.Values.emplace_back( + dependency->GetLocalGenerator()->GetCurrentBinaryDirectory()); + } + + cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency, + config, &dag), + entry.Values); + + entries.emplace_back(std::move(entry)); + } + } + } + } +} + void AddInterfaceEntries(cmGeneratorTarget const* headTarget, std::string const& config, std::string const& prop, std::string const& lang, @@ -3177,6 +3257,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( EvaluateTargetPropertyEntries(this, config, lang, &dagChecker, this->IncludeDirectoriesEntries); + if (lang == "Swift") { + AddSwiftImplicitIncludeDirectories(this, config, entries); + } + AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang, &dagChecker, entries); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 94d99b7..76c559f 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -60,6 +60,7 @@ #include "cmake.h" #ifndef CMAKE_BOOTSTRAP +# include "cmMakefileProfilingData.h" # include "cmVariableWatch.h" #endif @@ -372,19 +373,30 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const class cmMakefileCall { public: - cmMakefileCall(cmMakefile* mf, cmCommandContext const& cc, + cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff, cmExecutionStatus& status) : Makefile(mf) { cmListFileContext const& lfc = cmListFileContext::FromCommandContext( - cc, this->Makefile->StateSnapshot.GetExecutionListFile()); + lff, this->Makefile->StateSnapshot.GetExecutionListFile()); this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc); ++this->Makefile->RecursionDepth; this->Makefile->ExecutionStatusStack.push_back(&status); +#if !defined(CMAKE_BOOTSTRAP) + if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) { + this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff, + lfc); + } +#endif } ~cmMakefileCall() { +#if !defined(CMAKE_BOOTSTRAP) + if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) { + this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry(); + } +#endif this->Makefile->ExecutionStatusStack.pop_back(); --this->Makefile->RecursionDepth; this->Makefile->Backtrace = this->Makefile->Backtrace.Pop(); diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx new file mode 100644 index 0000000..ea64132 --- /dev/null +++ b/Source/cmMakefileProfilingData.cxx @@ -0,0 +1,113 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmMakefileProfilingData.h" + +#include <chrono> +#include <cstdint> +#include <stdexcept> +#include <vector> + +#include "cmsys/FStream.hxx" +#include "cmsys/SystemInformation.hxx" + +#include "cm_jsoncpp_value.h" +#include "cm_jsoncpp_writer.h" + +#include "cmListFileCache.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +cmMakefileProfilingData::cmMakefileProfilingData( + const std::string& profileStream) +{ + std::ios::openmode omode = std::ios::out | std::ios::trunc; + this->ProfileStream.open(profileStream.c_str(), omode); + Json::StreamWriterBuilder wbuilder; + this->JsonWriter = + std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter()); + if (!this->ProfileStream.good()) { + throw std::runtime_error(std::string("Unable to open: ") + profileStream); + } + + this->ProfileStream << "["; +}; + +cmMakefileProfilingData::~cmMakefileProfilingData() noexcept +{ + if (this->ProfileStream.good()) { + try { + this->ProfileStream << "]"; + this->ProfileStream.close(); + } catch (...) { + cmSystemTools::Error("Error writing profiling output!"); + } + } +} + +void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff, + cmListFileContext const& lfc) +{ + /* Do not try again if we previously failed to write to output. */ + if (!this->ProfileStream.good()) { + return; + } + + try { + if (this->ProfileStream.tellp() > 1) { + this->ProfileStream << ","; + } + cmsys::SystemInformation info; + Json::Value v; + v["ph"] = "B"; + v["name"] = lff.Name.Original; + v["cat"] = "cmake"; + v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::steady_clock::now().time_since_epoch()) + .count()); + v["pid"] = static_cast<int>(info.GetProcessId()); + v["tid"] = 0; + Json::Value argsValue; + if (!lff.Arguments.empty()) { + std::string args; + for (const auto& a : lff.Arguments) { + args += (args.empty() ? "" : " ") + a.Value; + } + argsValue["functionArgs"] = args; + } + argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line); + v["args"] = argsValue; + + this->JsonWriter->write(v, &this->ProfileStream); + } catch (std::ios_base::failure& fail) { + cmSystemTools::Error( + cmStrCat("Failed to write to profiling output: ", fail.what())); + } catch (...) { + cmSystemTools::Error("Error writing profiling output!"); + } +} + +void cmMakefileProfilingData::StopEntry() +{ + /* Do not try again if we previously failed to write to output. */ + if (!this->ProfileStream.good()) { + return; + } + + try { + this->ProfileStream << ","; + cmsys::SystemInformation info; + Json::Value v; + v["ph"] = "E"; + v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>( + std::chrono::steady_clock::now().time_since_epoch()) + .count()); + v["pid"] = static_cast<int>(info.GetProcessId()); + v["tid"] = 0; + this->JsonWriter->write(v, &this->ProfileStream); + } catch (std::ios_base::failure& fail) { + cmSystemTools::Error( + cmStrCat("Failed to write to profiling output:", fail.what())); + } catch (...) { + cmSystemTools::Error("Error writing profiling output!"); + } +} diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h new file mode 100644 index 0000000..1babd97 --- /dev/null +++ b/Source/cmMakefileProfilingData.h @@ -0,0 +1,29 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmMakefileProfilingData_h +#define cmMakefileProfilingData_h +#include <memory> +#include <string> + +#include "cmsys/FStream.hxx" + +namespace Json { +class StreamWriter; +} + +class cmListFileContext; +struct cmListFileFunction; + +class cmMakefileProfilingData +{ +public: + cmMakefileProfilingData(const std::string&); + ~cmMakefileProfilingData() noexcept; + void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc); + void StopEntry(); + +private: + cmsys::ofstream ProfileStream; + std::unique_ptr<Json::StreamWriter> JsonWriter; +}; +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index f4b9f16..29ed61d 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -9,6 +9,7 @@ #include <initializer_list> #include <iostream> #include <sstream> +#include <stdexcept> #include <utility> #include <cm/memory> @@ -39,6 +40,9 @@ #include "cmLinkLineComputer.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#if !defined(CMAKE_BOOTSTRAP) +# include "cmMakefileProfilingData.h" +#endif #include "cmMessenger.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -613,6 +617,10 @@ void cmake::SetArgs(const std::vector<std::string>& args) { bool haveToolset = false; bool havePlatform = false; +#if !defined(CMAKE_BOOTSTRAP) + std::string profilingFormat; + std::string profilingOutput; +#endif for (unsigned int i = 1; i < args.size(); ++i) { std::string const& arg = args[i]; if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) { @@ -839,6 +847,20 @@ void cmake::SetArgs(const std::vector<std::string>& args) return; } this->SetGlobalGenerator(std::move(gen)); +#if !defined(CMAKE_BOOTSTRAP) + } else if (arg.find("--profiling-format", 0) == 0) { + profilingFormat = arg.substr(strlen("--profiling-format=")); + if (profilingFormat.empty()) { + cmSystemTools::Error("No format specified for --profiling-format"); + } + } else if (arg.find("--profiling-output", 0) == 0) { + profilingOutput = arg.substr(strlen("--profiling-output=")); + profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput); + cmSystemTools::ConvertToUnixSlashes(profilingOutput); + if (profilingOutput.empty()) { + cmSystemTools::Error("No path specified for --profiling-output"); + } +#endif } // no option assume it is the path to the source or an existing build else { @@ -856,6 +878,29 @@ void cmake::SetArgs(const std::vector<std::string>& args) } } +#if !defined(CMAKE_BOOTSTRAP) + if (!profilingOutput.empty() || !profilingFormat.empty()) { + if (profilingOutput.empty()) { + cmSystemTools::Error( + "--profiling-format specified but no --profiling-output!"); + return; + } + if (profilingFormat == "google-trace") { + try { + this->ProfilingOutput = + cm::make_unique<cmMakefileProfilingData>(profilingOutput); + } catch (std::runtime_error& e) { + cmSystemTools::Error( + cmStrCat("Could not start profiling: ", e.what())); + return; + } + } else { + cmSystemTools::Error("Invalid format specified for --profiling-format"); + return; + } + } +#endif + const bool haveSourceDir = !this->GetHomeDirectory().empty(); const bool haveBinaryDir = !this->GetHomeOutputDirectory().empty(); @@ -2952,3 +2997,15 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b) " and functions.", cmStateEnums::INTERNAL); } + +#if !defined(CMAKE_BOOTSTRAP) +cmMakefileProfilingData& cmake::GetProfilingOutput() +{ + return *(this->ProfilingOutput); +} + +bool cmake::IsProfilingEnabled() const +{ + return static_cast<bool>(this->ProfilingOutput); +} +#endif diff --git a/Source/cmake.h b/Source/cmake.h index 35425ec..58769fd 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -34,6 +34,9 @@ class cmFileTimeCache; class cmGlobalGenerator; class cmGlobalGeneratorFactory; class cmMakefile; +#if !defined(CMAKE_BOOTSTRAP) +class cmMakefileProfilingData; +#endif class cmMessenger; class cmVariableWatch; struct cmDocumentationEntry; @@ -549,6 +552,11 @@ public: bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; } +#if !defined(CMAKE_BOOTSTRAP) + cmMakefileProfilingData& GetProfilingOutput(); + bool IsProfilingEnabled() const; +#endif + protected: void RunCheckForUnusedVariables(); int HandleDeleteCacheVariables(const std::string& var); @@ -657,6 +665,10 @@ private: void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&); void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&); + +#if !defined(CMAKE_BOOTSTRAP) + std::unique_ptr<cmMakefileProfilingData> ProfilingOutput; +#endif }; #define CMAKE_STANDARD_OPTIONS_TABLE \ diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 494d5d9..90d8ea6 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -93,6 +93,12 @@ const char* cmDocumentationOptions[][2] = { { "--check-system-vars", "Find problems with variable usage in system " "files." }, +# if !defined(CMAKE_BOOTSTRAP) + { "--profiling-format=<fmt>", "Output data for profiling CMake scripts." }, + { "--profiling-output=<file>", + "Select an output path for the profiling data enabled through " + "--profiling-format." }, +# endif { nullptr, nullptr } }; diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt index a53e441..49a4041 100644 --- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt +++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt @@ -86,7 +86,7 @@ foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG endforeach() foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2 - HDF5 JPEG LibArchive OPENSCENEGRAPH RUBY SWIG Protobuf) + HDF5 JPEG LibArchive OPENSCENEGRAPH Ruby RUBY SWIG Protobuf) check_version_string(${VTEST} ${VTEST}_VERSION) endforeach() diff --git a/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt new file mode 100644 index 0000000..c4326ae --- /dev/null +++ b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt @@ -0,0 +1,4 @@ +-- The ASM compiler identification is GNU +-- Found assembler: [^ +]*/as(\.exe)? +-- CMAKE_ASM_COMPILER_ID_VENDOR_MATCH='GNU assembler' diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.cmake new file mode 100644 index 0000000..21921ef --- /dev/null +++ b/Tests/RunCMake/BuildDepends/GNU-AS.cmake @@ -0,0 +1,13 @@ +enable_language(ASM) + +# Validate undocumented implementation detail. +message(STATUS "CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH='${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}'") + +add_library(gnu_as STATIC gnu_as.s) +target_include_directories(gnu_as PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"$<TARGET_FILE:gnu_as>|${CMAKE_CURRENT_BINARY_DIR}/gnu_as.inc\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake new file mode 100644 index 0000000..15a5e96 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake @@ -0,0 +1 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "") diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake new file mode 100644 index 0000000..15a5e96 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake @@ -0,0 +1 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "") diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 14ae243..753417d 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -103,3 +103,8 @@ endfunction() if(RunCMake_GENERATOR STREQUAL "Xcode") run_ReGeneration(regenerate-project) endif() + +if(CMake_TEST_BuildDepends_GNU_AS) + set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}") + run_BuildDepends(GNU-AS) +endif() diff --git a/Tests/RunCMake/BuildDepends/gnu_as.s b/Tests/RunCMake/BuildDepends/gnu_as.s new file mode 100644 index 0000000..a2e7dfb --- /dev/null +++ b/Tests/RunCMake/BuildDepends/gnu_as.s @@ -0,0 +1 @@ +.include "gnu_as.inc" diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 4b5475e..f99f704 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -169,7 +169,20 @@ if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND) set(autogen_with_qt5 TRUE) endif () add_RunCMake_test(Autogen -Dwith_qt5=${autogen_with_qt5}) -add_RunCMake_test(BuildDepends) +if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS + AND CMAKE_C_COMPILER_ID STREQUAL "GNU" + AND CMAKE_GENERATOR MATCHES "^Ninja" + ) + execute_process(COMMAND "${CMAKE_C_COMPILER}" -print-prog-name=as + RESULT_VARIABLE _gnu_res + OUTPUT_VARIABLE _gnu_as OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + if(_gnu_res EQUAL 0 AND _gnu_as) + set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}") + endif() +endif() +add_RunCMake_test(BuildDepends + -DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS} + ) if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja") add_RunCMake_test(Byproducts) endif() diff --git a/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake new file mode 100644 index 0000000..19ece86 --- /dev/null +++ b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake @@ -0,0 +1,18 @@ +if (NOT EXISTS ${ProfilingTestOutput}) + set(RunCMake_TEST_FAILED "Expected ${ProfilingTestOutput} to exists") +endif() + +file(READ "${ProfilingTestOutput}" JSON_HEADER LIMIT 2) +if (NOT JSON_HEADER MATCHES "^\\[{") + set(RunCMake_TEST_FAILED "Expected valid JSON start") + return() +endif() + +file(SIZE "${ProfilingTestOutput}" OUTPUT_SIZE) +math(EXPR END_OFFSET "${OUTPUT_SIZE} -2 ") + +file(READ "${ProfilingTestOutput}" JSON_TRAILER OFFSET ${END_OFFSET}) +if (NOT JSON_TRAILER MATCHES "^}]$") + set(RunCMake_TEST_FAILED "Expected valid JSON end") + return() +endif() diff --git a/Tests/RunCMake/CommandLine/ProfilingTest.cmake b/Tests/RunCMake/CommandLine/ProfilingTest.cmake new file mode 100644 index 0000000..837f4bf --- /dev/null +++ b/Tests/RunCMake/CommandLine/ProfilingTest.cmake @@ -0,0 +1 @@ +# This file is intentionally left blank diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 087ef21..41f13db 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -697,3 +697,25 @@ function(run_llvm_rc) unset(LLVMRC_RESULT) endfunction() run_llvm_rc() + +set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=google-trace) +run_cmake(profiling-all-params) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=invalid-format) +run_cmake(profiling-invalid-format) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt) +run_cmake(profiling-missing-format) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_OPTIONS --profiling-format=google-trace) +run_cmake(profiling-missing-output) +unset(RunCMake_TEST_OPTIONS) + +set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/profiling-test") +set(ProfilingTestOutput ${RunCMake_TEST_BINARY_DIR}/output.json) +set(RunCMake_TEST_OPTIONS --profiling-format=google-trace --profiling-output=${ProfilingTestOutput}) +run_cmake(ProfilingTest) +unset(RunCMake_TEST_OPTIONS) diff --git a/Tests/RunCMake/CommandLine/profiling-all-params-result.txt b/Tests/RunCMake/CommandLine/profiling-all-params-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-all-params-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt new file mode 100644 index 0000000..6b5c373 --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt @@ -0,0 +1 @@ +^.*Could not start profiling: Unable to open: /no/such/file.txt$ diff --git a/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt new file mode 100644 index 0000000..459bc3a --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt @@ -0,0 +1 @@ +^.*Invalid format specified for --profiling-format$ diff --git a/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt new file mode 100644 index 0000000..459bc3a --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt @@ -0,0 +1 @@ +^.*Invalid format specified for --profiling-format$ diff --git a/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt new file mode 100644 index 0000000..9ab0c8f --- /dev/null +++ b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt @@ -0,0 +1 @@ +^.*--profiling-format specified but no --profiling-output!$ diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt index f4cbac2..e24279b 100644 --- a/Tests/SwiftOnly/CMakeLists.txt +++ b/Tests/SwiftOnly/CMakeLists.txt @@ -1,4 +1,16 @@ cmake_minimum_required(VERSION 3.3) + +# NOTE: Force the Release mode configuration as there are some issues with the +# debug information handling on macOS on certain Xcode builds. +if(NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build" FORCE) +endif() + +# NOTE: enable shared libraries by default. Older Xcode releases do not play +# well with static libraries, and Windows does not currently support static +# libraries in Swift. +set(BUILD_SHARED_LIBS YES) + project(SwiftOnly Swift) if(NOT XCODE_VERSION VERSION_LESS 10.2) @@ -7,7 +19,19 @@ elseif(NOT XCODE_VERSION VERSION_LESS 8.0) set(CMAKE_Swift_LANGUAGE_VERSION 3.0) endif() +set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift) + add_executable(SwiftOnly main.swift) +add_library(L L.swift) + +add_library(M M.swift) +target_link_libraries(M PUBLIC + L) + +add_library(N N.swift) +target_link_libraries(N PUBLIC + M) + # Dummy to make sure generation works with such targets. add_library(SwiftIface INTERFACE) diff --git a/Tests/SwiftOnly/L.swift b/Tests/SwiftOnly/L.swift new file mode 100644 index 0000000..79ff87e --- /dev/null +++ b/Tests/SwiftOnly/L.swift @@ -0,0 +1 @@ +public let ThirtyTwo: Int = 32 diff --git a/Tests/SwiftOnly/M.swift b/Tests/SwiftOnly/M.swift new file mode 100644 index 0000000..dd333fe --- /dev/null +++ b/Tests/SwiftOnly/M.swift @@ -0,0 +1,2 @@ +import L +public let SixtyFour: Int = ThirtyTwo * 2 diff --git a/Tests/SwiftOnly/N.swift b/Tests/SwiftOnly/N.swift new file mode 100644 index 0000000..990ddf9 --- /dev/null +++ b/Tests/SwiftOnly/N.swift @@ -0,0 +1,2 @@ +import M +public let OneTwentyEight = SixtyFour * 2 |