diff options
78 files changed, 992 insertions, 222 deletions
diff --git a/Help/command/install.rst b/Help/command/install.rst index b2742d6..ffc1926 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -38,6 +38,13 @@ are executed in order during installation. The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the default copying behavior of ``install()``. +.. versionchanged:: 3.31 + Projects can enable :prop_gbl:`INSTALL_PARALLEL` to enable a parallel + installation. When using the parallel install, subdirectories added by calls + to the :command:`add_subdirectory` command are installed independently + and the order that install rules added in different subdirectories will run is + not guaranteed. + .. _`common options`: There are multiple signatures for this command. Some of them define diff --git a/Help/envvar/CMAKE_INSTALL_PARALLEL_LEVEL.rst b/Help/envvar/CMAKE_INSTALL_PARALLEL_LEVEL.rst new file mode 100644 index 0000000..84b5930 --- /dev/null +++ b/Help/envvar/CMAKE_INSTALL_PARALLEL_LEVEL.rst @@ -0,0 +1,11 @@ +CMAKE_INSTALL_PARALLEL_LEVEL +---------------------------- + +.. versionadded:: 3.31 + +.. include:: ENV_VAR.txt + +Specifies the default maximum number of concurrent processes to use when +installing using ``cmake --install``. + +This has no impact unless :prop_gbl:`INSTALL_PARALLEL` is enabled. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index a69ace6..68ee79a 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -52,6 +52,7 @@ Environment Variables that Control the Build /envvar/CMAKE_GENERATOR_PLATFORM /envvar/CMAKE_GENERATOR_TOOLSET /envvar/CMAKE_INSTALL_MODE + /envvar/CMAKE_INSTALL_PARALLEL_LEVEL /envvar/CMAKE_INSTALL_PREFIX /envvar/CMAKE_LANG_COMPILER_LAUNCHER /envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index fea661a..a195787 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -109,6 +109,7 @@ Properties on Targets /prop_tgt/ADDITIONAL_CLEAN_FILES /prop_tgt/AIX_EXPORT_ALL_SYMBOLS + /prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE /prop_tgt/ALIAS_GLOBAL /prop_tgt/ALIASED_TARGET /prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 315c73d..1d6331e 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -106,6 +106,7 @@ Variables that Provide Information /variable/CMAKE_SCRIPT_MODE_FILE /variable/CMAKE_SHARED_LIBRARY_PREFIX /variable/CMAKE_SHARED_LIBRARY_SUFFIX + /variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX /variable/CMAKE_SHARED_MODULE_PREFIX /variable/CMAKE_SHARED_MODULE_SUFFIX /variable/CMAKE_SIZEOF_VOID_P @@ -346,6 +347,7 @@ Variables that Describe the System /variable/MSVC_VERSION /variable/MSYS /variable/UNIX + /variable/WASI /variable/WIN32 /variable/WINCE /variable/WINDOWS_PHONE @@ -360,6 +362,7 @@ Variables that Control the Build :maxdepth: 1 /variable/CMAKE_ADSP_ROOT + /variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE /variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS /variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS /variable/CMAKE_ANDROID_API @@ -614,6 +617,7 @@ Variables for Languages /variable/CMAKE_LANG_COMPILER_TARGET /variable/CMAKE_LANG_COMPILER_VERSION /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY + /variable/CMAKE_LANG_CREATE_SHARED_LIBRARY_ARCHIVE /variable/CMAKE_LANG_CREATE_SHARED_MODULE /variable/CMAKE_LANG_CREATE_STATIC_LIBRARY /variable/CMAKE_LANG_EXTENSIONS diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 48a9219..b1cd381 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -745,6 +745,15 @@ The options are: This option can be omitted if :envvar:`VERBOSE` environment variable is set. +.. option:: -j <jobs>, --parallel <jobs> + + .. versionadded:: 3.31 + + Install in parallel using the given number of jobs. Only available if + :prop_gbl:`INSTALL_PARALLEL` is enabled. The + :envvar:`CMAKE_INSTALL_PARALLEL_LEVEL` environment variable specifies a + default parallel level when this option is not provided. + Run :option:`cmake --install` with no options for quick help. Open a Project diff --git a/Help/prop_gbl/INSTALL_PARALLEL.rst b/Help/prop_gbl/INSTALL_PARALLEL.rst index 7b6632e..c30d6c9 100644 --- a/Help/prop_gbl/INSTALL_PARALLEL.rst +++ b/Help/prop_gbl/INSTALL_PARALLEL.rst @@ -3,18 +3,22 @@ INSTALL_PARALLEL .. versionadded:: 3.30 -Enables parallel installation option for the Ninja generator. +Enables parallel installation option for a project. The install code for each +subdirectory added with ``add_subdirectory`` can run independently. -When this property is ``ON``, ``install/local`` targets have the -console pool disabled, allowing them to run concurrently. +When using the Ninja generator, setting this property to ``ON``, causes +``install/local`` targets have the console pool disabled, allowing them to run +concurrently. This property also provides the target ``install/parallel``, which has an -explicit dependency on the ``install/local`` target for each subdirectory, -recursing down the project. +explicit dependency on the ``install/local`` target for each subdirectory. -Setting this property has no affect on the behavior of ``cmake --install``. -The install must be invoked by building the ``install/parallel`` target -directly. + .. versionadded:: 3.31 + + When this property is ``ON``, ``cmake --install`` can be given the ``-j <jobs>`` + or ``--parallel <jobs>`` option to specify a maximum number of jobs. + The :envvar:`CMAKE_INSTALL_PARALLEL_LEVEL` environment variable specifies a + default parallel level if this option is not provided. Calls to :command:`install(CODE)` or :command:`install(SCRIPT)` might depend on actions performed by an earlier :command:`install` command in a different diff --git a/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst b/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst new file mode 100644 index 0000000..7c37015 --- /dev/null +++ b/Help/prop_tgt/AIX_SHARED_LIBRARY_ARCHIVE.rst @@ -0,0 +1,20 @@ +AIX_SHARED_LIBRARY_ARCHIVE +-------------------------- + +.. versionadded:: 3.31 + +On AIX, enable creation of a shared library archive. This places +the shared object ``.so`` file inside an archive ``.a`` file. + +By default, CMake creates shared libraries on AIX as plain +shared object ``.so`` files for consistency with other UNIX platforms. +Alternatively, set this property to a true value to create a shared +library archive instead, as is AIX convention. + +When a shared library is archived the shared object in the archive +does not record any version information from :prop_tgt:`VERSION` or +:prop_tgt`SOVERSION` target properties. + +This property defaults to :variable:`CMAKE_AIX_SHARED_LIBRARY_ARCHIVE` +if that variable is set when a ``SHARED`` library target is created +by :command:`add_library`. diff --git a/Help/release/3.30.rst b/Help/release/3.30.rst index 6d515fd..558b1ea 100644 --- a/Help/release/3.30.rst +++ b/Help/release/3.30.rst @@ -242,3 +242,15 @@ Other Changes directory has already been populated. CMake 3.29 and earlier did not check this requirement, but it is now enforced, subject to policy :policy:`CMP0170`. + +Updates +======= + +Changes made since CMake 3.30.0 include the following. + +3.30.1 +------ + +* This version made no changes to documented features or interfaces. + Some implementation updates were made to support ecosystem changes + and/or fix regressions. diff --git a/Help/release/dev/aix-archive-shared-libraries.rst b/Help/release/dev/aix-archive-shared-libraries.rst new file mode 100644 index 0000000..467c367 --- /dev/null +++ b/Help/release/dev/aix-archive-shared-libraries.rst @@ -0,0 +1,6 @@ +aix-archive-shared-libraries +---------------------------- + +* On AIX, shared libraries may now be created as shared library archives. + See the :variable:`CMAKE_AIX_SHARED_LIBRARY_ARCHIVE` variable + and :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE` target property. diff --git a/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst b/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst new file mode 100644 index 0000000..10fdf04 --- /dev/null +++ b/Help/variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE.rst @@ -0,0 +1,10 @@ +CMAKE_AIX_SHARED_LIBRARY_ARCHIVE +-------------------------------- + +.. versionadded:: 3.31 + +On AIX, enable creation of shared library archives. + +This variable initializes the :prop_tgt:`AIX_SHARED_LIBRARY_ARCHIVE` +target property on ``SHARED`` library targets as they are created +by :command:`add_library`. See that target property for details. diff --git a/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY_ARCHIVE.rst b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY_ARCHIVE.rst new file mode 100644 index 0000000..a2d27aa --- /dev/null +++ b/Help/variable/CMAKE_LANG_CREATE_SHARED_LIBRARY_ARCHIVE.rst @@ -0,0 +1,8 @@ +CMAKE_<LANG>_CREATE_SHARED_LIBRARY_ARCHIVE +------------------------------------------ + +Rule variable to create a shared library with archive. + +This is a rule variable that tells CMake how to create a shared +library with an archive for the language <LANG>. This rule variable +is a ; delimited list of commands to run to perform the linking step. diff --git a/Help/variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX.rst b/Help/variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX.rst new file mode 100644 index 0000000..dc7e933 --- /dev/null +++ b/Help/variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX.rst @@ -0,0 +1,7 @@ +CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX +----------------------------------- + +The suffix for archived shared libraries that you link to. + +The suffix to use for the end of a archive containing a +shared library, ``.a`` on AIX. diff --git a/Help/variable/CMAKE_SYSTEM_NAME.rst b/Help/variable/CMAKE_SYSTEM_NAME.rst index e9ffec4..681ee03 100644 --- a/Help/variable/CMAKE_SYSTEM_NAME.rst +++ b/Help/variable/CMAKE_SYSTEM_NAME.rst @@ -85,6 +85,7 @@ Value Name ``UNIX_SV`` SCO UnixWare (pre release 7) ``UnixWare`` SCO UnixWare 7 ``visionOS`` Apple mixed reality operating system +``WASI`` WebAssembly System Interface ``watchOS`` Apple watch operating system ``Windows`` Windows stationary operating systems ``WindowsCE`` Windows Embedded Compact diff --git a/Help/variable/WASI.rst b/Help/variable/WASI.rst new file mode 100644 index 0000000..eacfc3f --- /dev/null +++ b/Help/variable/WASI.rst @@ -0,0 +1,7 @@ +WASI +---- + +.. versionadded:: 3.31 + +Set to ``1`` when the target system is WebAssembly System Interface +(:variable:`CMAKE_SYSTEM_NAME` is ``WASI``). diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index dc09b20..64420b3 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -187,7 +187,7 @@ function(cmake_parse_implicit_link_info2 text log_var obj_regex) if(EXTRA_PARSE_COMPUTE_IMPLICIT_LIBS) # Unix library. set(lib "${CMAKE_MATCH_1}") - if(search_static AND lib MATCHES "^(gfortran|stdc\\+\\+)$") + if(search_static AND lib MATCHES "^(gfortran|quadmath|stdc\\+\\+)$") # Search for the static library later, once all link dirs are known. set(lib "SEARCH_STATIC:${lib}") endif() diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake index 79aca93..c01b6cf 100644 --- a/Modules/CheckCSourceCompiles.cmake +++ b/Modules/CheckCSourceCompiles.cmake @@ -5,7 +5,7 @@ CheckCSourceCompiles -------------------- -Check if given C source compiles and links into an executable. +Check once if C source code can be built. .. command:: check_c_source_compiles @@ -14,19 +14,21 @@ Check if given C source compiles and links into an executable. check_c_source_compiles(<code> <resultVar> [FAIL_REGEX <regex1> [<regex2>...]]) - Check that the source supplied in ``<code>`` can be compiled as a C source - file and linked as an executable (so it must contain at least a ``main()`` - function). The result will be stored in the internal cache variable specified - by ``<resultVar>``, with a boolean true value for success and boolean false - for failure. If ``FAIL_REGEX`` is provided, then failure is determined by - checking if anything in the output matches any of the specified regular + Check once that the source supplied in ``<code>`` can be built. The result is + stored in the internal cache variable specified by ``<resultVar>``, with + boolean ``true`` for success and boolean ``false`` for failure. + + If ``FAIL_REGEX`` is provided, then failure is determined by checking + if anything in the compiler output matches any of the specified regular expressions. - The check is only performed once, with the result cached in the variable named - by ``<resultVar>``. Every subsequent CMake run will reuse this cached value - rather than performing the check again, even if the ``<code>`` changes. In - order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. + + See also :command:`check_source_runs` to run compiled source. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_c_source_compiles()``: diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake index 7531236..7c03c4a 100644 --- a/Modules/CheckCXXSourceCompiles.cmake +++ b/Modules/CheckCXXSourceCompiles.cmake @@ -5,7 +5,7 @@ CheckCXXSourceCompiles ---------------------- -Check if given C++ source compiles and links into an executable. +Check once if C++ source code can be built. .. command:: check_cxx_source_compiles @@ -14,19 +14,21 @@ Check if given C++ source compiles and links into an executable. check_cxx_source_compiles(<code> <resultVar> [FAIL_REGEX <regex1> [<regex2>...]]) - Check that the source supplied in ``<code>`` can be compiled as a C++ source - file and linked as an executable (so it must contain at least a ``main()`` - function). The result will be stored in the internal cache variable specified - by ``<resultVar>``, with a boolean true value for success and boolean false - for failure. If ``FAIL_REGEX`` is provided, then failure is determined by - checking if anything in the output matches any of the specified regular + Check once that the source supplied in ``<code>`` can be built. The result is + stored in the internal cache variable specified by ``<resultVar>``, with + boolean ``true`` for success and boolean ``false`` for failure. + + If ``FAIL_REGEX`` is provided, then failure is determined by checking + if anything in the compiler output matches any of the specified regular expressions. - The check is only performed once, with the result cached in the variable named - by ``<resultVar>``. Every subsequent CMake run will reuse this cached value - rather than performing the check again, even if the ``<code>`` changes. In - order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. + + See also :command:`check_source_runs` to run compiled source. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_cxx_source_compiles()``: diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake index ed374ef..4cbe67a 100644 --- a/Modules/CheckFortranSourceCompiles.cmake +++ b/Modules/CheckFortranSourceCompiles.cmake @@ -7,7 +7,7 @@ CheckFortranSourceCompiles .. versionadded:: 3.1 -Check if given Fortran source compiles and links into an executable. +Check once if Fortran source code can be built. .. command:: check_fortran_source_compiles @@ -18,40 +18,25 @@ Check if given Fortran source compiles and links into an executable. [SRC_EXT <extension>] ) - Checks that the source supplied in ``<code>`` can be compiled as a Fortran - source file and linked as an executable. The ``<code>`` must be a Fortran - ``program``. - - .. code-block:: cmake - - check_fortran_source_compiles("program test - error stop - end program" - HAVE_ERROR_STOP - SRC_EXT .F90) - - This command can help avoid costly build processes when a compiler lacks support - for a necessary feature, or a particular vendor library is not compatible with - the Fortran compiler version being used. This generate-time check may advise the - user of such before the main build process. See also the - :command:`check_fortran_source_runs` command to run the compiled code. - - The result will be stored in the internal cache - variable ``<resultVar>``, with a boolean true value for success and boolean - false for failure. + Check once that the source supplied in ``<code>`` can be built. The result is + stored in the internal cache variable specified by ``<resultVar>``, with + boolean ``true`` for success and boolean ``false`` for failure. If ``FAIL_REGEX`` is provided, then failure is determined by checking - if anything in the output matches any of the specified regular expressions. + if anything in the compiler output matches any of the specified regular + expressions. By default, the test source file will be given a ``.F`` file extension. The ``SRC_EXT`` option can be used to override this with ``.<extension>`` instead-- ``.F90`` is a typical choice. - The check is only performed once, with the result cached in the variable named - by ``<resultVar>``. Every subsequent CMake run will reuse this cached value - rather than performing the check again, even if the ``<code>`` changes. In - order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + See also :command:`check_source_runs` to run compiled source. + + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_fortran_source_compiles()``: diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake index bc0cac1..c6e09db 100644 --- a/Modules/CheckOBJCSourceCompiles.cmake +++ b/Modules/CheckOBJCSourceCompiles.cmake @@ -7,7 +7,7 @@ CheckOBJCSourceCompiles .. versionadded:: 3.16 -Check if given Objective-C source compiles and links into an executable. +Check once if Objective-C source can be built. .. command:: check_objc_source_compiles @@ -16,19 +16,21 @@ Check if given Objective-C source compiles and links into an executable. check_objc_source_compiles(<code> <resultVar> [FAIL_REGEX <regex1> [<regex2>...]]) - Check that the source supplied in ``<code>`` can be compiled as a Objectie-C source - file and linked as an executable (so it must contain at least a ``main()`` - function). The result will be stored in the internal cache variable specified - by ``<resultVar>``, with a boolean true value for success and boolean false - for failure. If ``FAIL_REGEX`` is provided, then failure is determined by - checking if anything in the output matches any of the specified regular + Check once that the source supplied in ``<code>`` can be built. The result is + stored in the internal cache variable specified by ``<resultVar>``, with + boolean ``true`` for success and boolean ``false`` for failure. + + If ``FAIL_REGEX`` is provided, then failure is determined by checking + if anything in the compiler output matches any of the specified regular expressions. - The check is only performed once, with the result cached in the variable named - by ``<resultVar>``. Every subsequent CMake run will reuse this cached value - rather than performing the check again, even if the ``<code>`` changes. In - order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. + + See also :command:`check_source_runs` to run compiled source. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_objc_source_compiles()`` diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake index 366d7d5..4a18c21 100644 --- a/Modules/CheckOBJCXXSourceCompiles.cmake +++ b/Modules/CheckOBJCXXSourceCompiles.cmake @@ -7,7 +7,7 @@ CheckOBJCXXSourceCompiles .. versionadded:: 3.16 -Check if given Objective-C++ source compiles and links into an executable. +Check once if Objective-C++ source can be built. .. command:: check_objcxx_source_compiles @@ -16,19 +16,21 @@ Check if given Objective-C++ source compiles and links into an executable. check_objcxx_source_compiles(<code> <resultVar> [FAIL_REGEX <regex1> [<regex2>...]]) - Check that the source supplied in ``<code>`` can be compiled as a Objective-C++ source - file and linked as an executable (so it must contain at least a ``main()`` - function). The result will be stored in the internal cache variable specified - by ``<resultVar>``, with a boolean true value for success and boolean false - for failure. If ``FAIL_REGEX`` is provided, then failure is determined by - checking if anything in the output matches any of the specified regular + Check once that the source supplied in ``<code>`` can be built. The result is + stored in the internal cache variable specified by ``<resultVar>``, with + boolean ``true`` for success and boolean ``false`` for failure. + + If ``FAIL_REGEX`` is provided, then failure is determined by checking + if anything in the compiler output matches any of the specified regular expressions. - The check is only performed once, with the result cached in the variable named - by ``<resultVar>``. Every subsequent CMake run will reuse this cached value - rather than performing the check again, even if the ``<code>`` changes. In - order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. + + See also :command:`check_source_runs` to run compiled source. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_objcxx_source_compiles()`` diff --git a/Modules/CheckSourceCompiles.cmake b/Modules/CheckSourceCompiles.cmake index af905a4..b79726a 100644 --- a/Modules/CheckSourceCompiles.cmake +++ b/Modules/CheckSourceCompiles.cmake @@ -8,7 +8,7 @@ CheckSourceCompiles .. versionadded:: 3.19 -Check if given source compiles and links into an executable. +Check once if source code can be built for a given language. .. command:: check_source_compiles @@ -18,40 +18,50 @@ Check if given source compiles and links into an executable. [FAIL_REGEX <regex1> [<regex2>...]] [SRC_EXT <extension>]) - Check that the source supplied in ``<code>`` can be compiled as a source - file for the requested language and linked as an executable. The result - will be stored in the internal cache variable specified by ``<resultVar>``, - with a boolean true value for success and boolean false for failure. If - ``FAIL_REGEX`` is provided, then failure is determined by checking if - anything in the compiler output matches any of the specified regular + Check once that the source supplied in ``<code>`` can be built for code + language ``<lang>``. The result is stored in the internal cache variable + specified by ``<resultVar>``, with boolean ``true`` for success and + boolean ``false`` for failure. + + If ``FAIL_REGEX`` is provided, then failure is determined by checking + if anything in the compiler output matches any of the specified regular expressions. By default, the test source file will be given a file extension that matches the requested language. The ``SRC_EXT`` option can be used to override this with ``.<extension>`` instead. - The ``<code>`` must contain a valid main program. For example: + The C example checks if the compiler supports the ``noreturn`` attribute: .. code-block:: cmake + set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + check_source_compiles(C - "#include <stdlib.h> - #include <stdnoreturn.h> - noreturn void f(){ exit(0); } - int main(void) { f(); return 1; }" + "#if !__has_c_attribute(noreturn) + #error \"No noreturn attribute\" + #endif" HAVE_NORETURN) + The Fortran example checks if the compiler supports the ``pure`` procedure + attribute: + + .. code-block:: cmake + + set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + check_source_compiles(Fortran - "program test - error stop - end program" - HAVE_ERROR_STOP) - - The check is only performed once, with the result cached in the variable - named by ``<resultVar>``. Every subsequent CMake run will reuse this cached - value rather than performing the check again, even if the ``<code>`` changes. - In order to force the check to be re-evaluated, the variable named by - ``<resultVar>`` must be manually removed from the cache. + "pure subroutine foo() + end subroutine" + HAVE_PURE) + + Internally, :command:`try_compile` is used to compile the source. If + :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` is set to ``EXECUTABLE`` (default), + the source is compiled and linked as an executable program. If set to + ``STATIC_LIBRARY``, the source is compiled but not linked. In any case, all + functions must be declared as usual. + + See also :command:`check_source_runs` to run compiled source. The compile and link commands can be influenced by setting any of the following variables prior to calling ``check_source_compiles()``: diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index f68d629..f133f1b 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -973,6 +973,14 @@ if(CMAKE_CROSSCOMPILING) endforeach() endif() +# Determine windows search path suffix for libraries +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64") + set(_CUDAToolkit_win_search_dirs lib/x64) + set(_CUDAToolkit_win_stub_search_dirs lib/x64/stubs) + endif() +endif() + # If not already set we can simply use the toolkit root or it's a scattered installation. if(NOT CUDAToolkit_TARGET_DIR) # Not cross compiling @@ -1028,12 +1036,12 @@ unset(CUDAToolkit_CUBLAS_INCLUDE_DIR) find_library(CUDA_CUDART NAMES cudart PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES} - PATH_SUFFIXES lib64 lib/x64 + PATH_SUFFIXES lib64 ${_CUDAToolkit_win_search_dirs} ) find_library(CUDA_CUDART NAMES cudart PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES} - PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs + PATH_SUFFIXES lib64/stubs ${_CUDAToolkit_win_stub_search_dirs} lib/stubs stubs ) if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) @@ -1125,7 +1133,7 @@ if(CUDAToolkit_FOUND) NAMES ${search_names} HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS} ENV CUDA_PATH - PATH_SUFFIXES nvidia/current lib64 lib/x64 lib + PATH_SUFFIXES nvidia/current lib64 ${_CUDAToolkit_win_search_dirs} lib # Support NVHPC splayed math library layout math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64 math_libs/lib64 @@ -1140,7 +1148,7 @@ if(CUDAToolkit_FOUND) NAMES ${search_names} HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS} ENV CUDA_PATH - PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs + PATH_SUFFIXES lib64/stubs ${_CUDAToolkit_win_stub_search_dirs} lib/stubs stubs ) endif() if(CUDA_${lib_name}_LIBRARY MATCHES "/stubs/" AND NOT CUDA_${lib_name}_LIBRARY MATCHES "\\.a$" AND NOT WIN32) @@ -1389,3 +1397,6 @@ if(_CUDAToolkit_Pop_ROOT_PATH) list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0) unset(_CUDAToolkit_Pop_ROOT_PATH) endif() + +unset(_CUDAToolkit_win_search_dirs) +unset(_CUDAToolkit_win_stub_search_dirs) diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake index f6616fb..093efa1 100644 --- a/Modules/Platform/AIX-GNU.cmake +++ b/Modules/Platform/AIX-GNU.cmake @@ -30,6 +30,14 @@ macro(__aix_compiler_gnu lang) "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" ) + # Create an archive for shared library if CMAKE_AIX_SHARED_LIBRARY_ARCHIVE is used. + string(REPLACE " <SONAME_FLAG><TARGET_SONAME> -o <TARGET>" " -o <TARGET_SONAME>" + CMAKE_${lang}_CREATE_SHARED_LIBRARY_ARCHIVE "${CMAKE_${lang}_CREATE_SHARED_LIBRARY}") + list(APPEND CMAKE_${lang}_CREATE_SHARED_LIBRARY_ARCHIVE + "<CMAKE_AR> -X32_64 rc <TARGET> <TARGET_SONAME>" + "rm -f <TARGET_SONAME>" + ) + set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>" "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") diff --git a/Modules/Platform/AIX-LLVMFlang-Fortran.cmake b/Modules/Platform/AIX-LLVMFlang-Fortran.cmake new file mode 100644 index 0000000..07772a7 --- /dev/null +++ b/Modules/Platform/AIX-LLVMFlang-Fortran.cmake @@ -0,0 +1,2 @@ +include(Platform/AIX-GNU) +__aix_compiler_gnu(Fortran) diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake index cd202cb..485f31e 100644 --- a/Modules/Platform/AIX-XL.cmake +++ b/Modules/Platform/AIX-XL.cmake @@ -34,6 +34,14 @@ macro(__aix_compiler_xl lang) "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>" ) + # Create an archive for shared library if CMAKE_AIX_SHARED_LIBRARY_ARCHIVE is used. + string(REPLACE " <SONAME_FLAG><TARGET_SONAME> -o <TARGET>" " -o <TARGET_SONAME>" + CMAKE_${lang}_CREATE_SHARED_LIBRARY_ARCHIVE "${CMAKE_${lang}_CREATE_SHARED_LIBRARY}") + list(APPEND CMAKE_${lang}_CREATE_SHARED_LIBRARY_ARCHIVE + "<CMAKE_AR> -X32_64 rc <TARGET> <TARGET_SONAME>" + "rm -f <TARGET_SONAME>" + ) + set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>" "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") diff --git a/Modules/Platform/AIX.cmake b/Modules/Platform/AIX.cmake index 03cef51..dcc9837 100644 --- a/Modules/Platform/AIX.cmake +++ b/Modules/Platform/AIX.cmake @@ -1,5 +1,6 @@ set(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so +set(CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX ".a") # .a set(CMAKE_AIX_IMPORT_FILE_PREFIX "") set(CMAKE_AIX_IMPORT_FILE_SUFFIX ".imp") set(CMAKE_DL_LIBS "-lld") diff --git a/Modules/Platform/WASI-Initialize.cmake b/Modules/Platform/WASI-Initialize.cmake new file mode 100644 index 0000000..b49713f --- /dev/null +++ b/Modules/Platform/WASI-Initialize.cmake @@ -0,0 +1 @@ +set(WASI 1) diff --git a/Modules/Platform/WASI.cmake b/Modules/Platform/WASI.cmake new file mode 100644 index 0000000..8e4a05b --- /dev/null +++ b/Modules/Platform/WASI.cmake @@ -0,0 +1 @@ +# WASI Platform diff --git a/Modules/SystemInformation.in b/Modules/SystemInformation.in index f2aef50..50b5720 100644 --- a/Modules/SystemInformation.in +++ b/Modules/SystemInformation.in @@ -6,6 +6,7 @@ CMAKE_STATIC_LIBRARY_PREFIX == "${CMAKE_STATIC_LIBRARY_PREFIX}" CMAKE_STATIC_LIBRARY_SUFFIX == "${CMAKE_STATIC_LIBRARY_SUFFIX}" CMAKE_SHARED_LIBRARY_PREFIX == "${CMAKE_SHARED_LIBRARY_PREFIX}" CMAKE_SHARED_LIBRARY_SUFFIX == "${CMAKE_SHARED_LIBRARY_SUFFIX}" +CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX == "${CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX}" CMAKE_SHARED_MODULE_PREFIX == "${CMAKE_SHARED_MODULE_PREFIX}" CMAKE_SHARED_MODULE_SUFFIX == "${CMAKE_SHARED_MODULE_SUFFIX}" diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 185ebfe..1d2b7dd 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -336,6 +336,8 @@ add_library( cmInstallTargetGenerator.cxx cmInstallDirectoryGenerator.h cmInstallDirectoryGenerator.cxx + cmInstallScriptHandler.h + cmInstallScriptHandler.cxx cmJSONHelpers.cxx cmJSONHelpers.h cmJSONState.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index ccd9011..ce1b900 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 30) -set(CMake_VERSION_PATCH 20240717) +set(CMake_VERSION_PATCH 20240719) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx index 3a5806b..b8e5db1 100644 --- a/Source/CTest/cmCTestCurl.cxx +++ b/Source/CTest/cmCTestCurl.cxx @@ -19,6 +19,7 @@ cmCTestCurl::cmCTestCurl(cmCTest* ctest) , CurlOpts(ctest) { this->SetProxyType(); + cmCurlInitOnce(); // In windows, this will init the winsock stuff ::curl_global_init(CURL_GLOBAL_ALL); this->Curl = curl_easy_init(); diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index e69a7fe..85c77be 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -171,6 +171,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( headers = ::curl_slist_append(headers, h.c_str()); } + cmCurlInitOnce(); /* In windows, this will init the winsock stuff */ ::curl_global_init(CURL_GLOBAL_ALL); cmCTestCurlOpts curlOpts(this->CTest); diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx index ddd5f69..65fccd0 100644 --- a/Source/cmCurl.cxx +++ b/Source/cmCurl.cxx @@ -39,6 +39,11 @@ # define CURL_SSLVERSION_TLSv1_3 CURL_SSLVERSION_LAST #endif +// curl versions before 7.64.1 referred to Secure Transport as DarwinSSL +#if defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM < 0x074001 +# define CURLSSLBACKEND_SECURETRANSPORT CURLSSLBACKEND_DARWINSSL +#endif + // Make sure we keep up with new TLS versions supported by curl. // Do this only for our vendored curl to avoid breaking builds // against external future versions of curl. @@ -47,6 +52,30 @@ static_assert(CURL_SSLVERSION_LAST == 8, "A new CURL_SSLVERSION_ may be available!"); #endif +void cmCurlInitOnce() +{ + // curl 7.56.0 introduced curl_global_sslset. +#if defined(__APPLE__) && defined(CMAKE_USE_SYSTEM_CURL) && \ + defined(LIBCURL_VERSION_NUM) && LIBCURL_VERSION_NUM >= 0x073800 + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; + + cm::optional<std::string> curl_ssl_backend = + cmSystemTools::GetEnvVar("CURL_SSL_BACKEND"); + if (!curl_ssl_backend || curl_ssl_backend->empty()) { + curl_version_info_data* cv = curl_version_info(CURLVERSION_FIRST); + // curl 8.3.0 through 8.5.x did not re-initialize LibreSSL correctly, + // so prefer the Secure Transport backend by default in those versions. + if (cv->version_num >= 0x080300 && cv->version_num < 0x080600) { + curl_global_sslset(CURLSSLBACKEND_SECURETRANSPORT, NULL, NULL); + } + } +#endif +} + cm::optional<int> cmCurlParseTLSVersion(cm::string_view tls_version) { cm::optional<int> v; diff --git a/Source/cmCurl.h b/Source/cmCurl.h index 8b8c88b..bb2221f 100644 --- a/Source/cmCurl.h +++ b/Source/cmCurl.h @@ -11,6 +11,7 @@ #include <cm3p/curl/curl.h> +void cmCurlInitOnce(); cm::optional<int> cmCurlParseTLSVersion(cm::string_view tls_version); cm::optional<std::string> cmCurlPrintTLSVersion(int curl_tls_version); std::string cmCurlSetCAInfo(::CURL* curl, const std::string& cafile = {}); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 88555b6..5a12afe 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2166,6 +2166,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args, url = cmCurlFixFileURL(url); ::CURL* curl; + cmCurlInitOnce(); ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); if (!curl) { @@ -2539,6 +2540,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args, url = cmCurlFixFileURL(url); ::CURL* curl; + cmCurlInitOnce(); ::curl_global_init(CURL_GLOBAL_DEFAULT); curl = ::curl_easy_init(); if (!curl) { diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 727d452..af72326 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -2294,6 +2294,9 @@ std::string cmGeneratorTarget::GetCreateRuleVariable( return this->GetFeatureSpecificLinkRuleVariable(var, lang, config); } case cmStateEnums::SHARED_LIBRARY: + if (this->IsArchivedAIXSharedLibrary()) { + return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY_ARCHIVE"; + } return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY"; case cmStateEnums::MODULE_LIBRARY: return "CMAKE_" + lang + "_CREATE_SHARED_MODULE"; @@ -2938,7 +2941,7 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames( cmValue soversion = this->GetProperty("SOVERSION"); if (!this->HasSOName(config) || this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") || - this->IsFrameworkOnApple()) { + this->IsFrameworkOnApple() || this->IsArchivedAIXSharedLibrary()) { // Versioning is supported only for shared libraries and modules, // and then only when the platform supports an soname flag. version = nullptr; @@ -2971,6 +2974,11 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames( } targetNames.Real += cmStrCat(targetNames.Base, components.suffix); targetNames.SharedObject = targetNames.Real; + } else if (this->IsArchivedAIXSharedLibrary()) { + targetNames.SharedObject = + cmStrCat(components.prefix, targetNames.Base, ".so"); + targetNames.Real = + cmStrCat(components.prefix, targetNames.Base, components.suffix); } else { // The library's soname. this->ComputeVersionedName(targetNames.SharedObject, components.prefix, @@ -3054,8 +3062,13 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames( // The executable name. targetNames.Base = components.base; - targetNames.Output = - components.prefix + targetNames.Base + components.suffix; + + if (this->IsArchivedAIXSharedLibrary()) { + targetNames.Output = components.prefix + targetNames.Base; + } else { + targetNames.Output = + components.prefix + targetNames.Base + components.suffix; + } // The executable's real name on disk. #if defined(__CYGWIN__) @@ -4801,6 +4814,11 @@ bool cmGeneratorTarget::IsFrameworkOnApple() const return this->Target->IsFrameworkOnApple(); } +bool cmGeneratorTarget::IsArchivedAIXSharedLibrary() const +{ + return this->Target->IsArchivedAIXSharedLibrary(); +} + bool cmGeneratorTarget::IsImportedFrameworkFolderOnApple( const std::string& config) const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 1e6ff78..0c86201 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -891,6 +891,9 @@ public: /** Return whether this target is a CFBundle (plugin) on Apple. */ bool IsCFBundleOnApple() const; + /** Return whether this target is a shared library on AIX. */ + bool IsArchivedAIXSharedLibrary() const; + /** Assembly types. The order of the values of this enum is relevant because of smaller/larger comparison operations! */ enum ManagedType diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index bf2f0fc..9edbce3 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -135,6 +135,13 @@ cmGlobalGenerator::cmGlobalGenerator(cmake* cm) cm->GetState()->SetWatcomWMake(false); cm->GetState()->SetWindowsShell(false); cm->GetState()->SetWindowsVSIDE(false); + +#if !defined(CMAKE_BOOTSTRAP) + Json::StreamWriterBuilder wbuilder; + wbuilder["indentation"] = "\t"; + this->JsonWriter = + std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter()); +#endif } cmGlobalGenerator::~cmGlobalGenerator() @@ -1758,6 +1765,30 @@ void cmGlobalGenerator::Generate() } } +#if !defined(CMAKE_BOOTSTRAP) +void cmGlobalGenerator::WriteJsonContent(const std::string& path, + const Json::Value& value) const +{ + cmsys::ofstream ftmp(path.c_str()); + this->JsonWriter->write(value, &ftmp); + ftmp << '\n'; + ftmp.close(); +} + +void cmGlobalGenerator::WriteInstallJson() const +{ + if (this->GetCMakeInstance()->GetState()->GetGlobalPropertyAsBool( + "INSTALL_PARALLEL")) { + Json::Value index(Json::objectValue); + index["InstallScripts"] = Json::arrayValue; + for (const auto& file : this->InstallScripts) { + index["InstallScripts"].append(file); + } + this->WriteJsonContent("CMakeFiles/InstallScripts.json", index); + } +} +#endif + bool cmGlobalGenerator::ComputeTargetDepends() { cmComputeTargetDepends ctd(this); @@ -3732,3 +3763,8 @@ cmGlobalGenerator::StripCommandStyle cmGlobalGenerator::GetStripCommandStyle( return StripCommandStyle::Default; #endif } + +void cmGlobalGenerator::AddInstallScript(std::string const& file) +{ + this->InstallScripts.push_back(file); +} diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 33c9889..5011c17 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -91,6 +91,9 @@ struct GeneratedMakeCommand bool RequiresOutputForward = false; }; } +namespace Json { +class StreamWriter; +} /** \class cmGlobalGenerator * \brief Responsible for overseeing the generation process for the entire tree @@ -655,6 +658,8 @@ public: bool CheckCMP0171() const; + void AddInstallScript(std::string const& file); + protected: // for a project collect all its targets by following depend // information, and also collect all the targets @@ -674,6 +679,12 @@ protected: virtual bool ComputeTargetDepends(); +#if !defined(CMAKE_BOOTSTRAP) + void WriteJsonContent(const std::string& fname, + const Json::Value& value) const; + void WriteInstallJson() const; +#endif + virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const; bool ApplyCXXStdTargets(); @@ -790,6 +801,10 @@ private: std::map<std::string, int> LanguageToLinkerPreference; std::map<std::string, std::string> LanguageToOriginalSharedLibFlags; +#if !defined(CMAKE_BOOTSTRAP) + std::unique_ptr<Json::StreamWriter> JsonWriter; +#endif + #ifdef __APPLE__ std::map<std::string, StripCommandStyle> StripCommandStyleMap; #endif @@ -882,6 +897,8 @@ private: std::map<std::string, cmInstallRuntimeDependencySet*> RuntimeDependencySetsByName; + std::vector<std::string> InstallScripts; + #if !defined(CMAKE_BOOTSTRAP) // Pool of file locks cmFileLockPool FileLockPool; diff --git a/Source/cmInstallScriptHandler.cxx b/Source/cmInstallScriptHandler.cxx new file mode 100644 index 0000000..ad1e5cb --- /dev/null +++ b/Source/cmInstallScriptHandler.cxx @@ -0,0 +1,119 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmInstallScriptHandler.h" + +#include <algorithm> +#include <cstddef> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include <cm/memory> + +#include <cm3p/json/reader.h> +#include <cm3p/json/value.h> +#include <cm3p/uv.h> + +#include "cmJSONState.h" +#include "cmProcessOutput.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmUVHandlePtr.h" +#include "cmUVProcessChain.h" +#include "cmUVStream.h" + +using InstallScript = cmInstallScriptHandler::InstallScript; + +cmInstallScriptHandler::cmInstallScriptHandler(const std::string& binary_dir, + std::vector<std::string>& args) +{ + const std::string& file = + cmStrCat(binary_dir, "/CMakeFiles/InstallScripts.json"); + if (cmSystemTools::FileExists(file)) { + int compare; + cmSystemTools::FileTimeCompare( + cmStrCat(binary_dir, "/CMakeFiles/cmake.check_cache"), file, &compare); + if (compare < 1) { + args.insert(args.end() - 1, "-DCMAKE_INSTALL_LOCAL_ONLY=1"); + Json::CharReaderBuilder rbuilder; + auto JsonReader = + std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); + std::vector<char> content; + Json::Value value; + cmJSONState state(file, &value); + for (auto const& script : value["InstallScripts"]) { + this->commands.push_back(args); + this->commands.back().emplace_back(script.asCString()); + } + } + } +} + +bool cmInstallScriptHandler::isParallel() +{ + return !this->commands.empty(); +} + +int cmInstallScriptHandler::install(unsigned int j) +{ + cm::uv_loop_ptr loop; + loop.init(); + std::vector<InstallScript> scripts; + for (auto const& cmd : this->commands) { + scripts.push_back(InstallScript(cmd)); + } + std::size_t working = 0; + std::size_t installed = 0; + std::size_t i = 0; + + while (installed < scripts.size()) { + for (auto queue = std::min(j - working, scripts.size() - i); queue > 0; + --queue) { + scripts[i].start(loop, [&scripts, &working, &installed, i]() { + scripts[i].printResult(++installed, scripts.size()); + --working; + }); + ++i; + } + uv_run(loop, UV_RUN_DEFAULT); + } + return 0; +} + +InstallScript::InstallScript(const std::vector<std::string>& cmd) +{ + this->name = cmSystemTools::RelativePath( + cmSystemTools::GetCurrentWorkingDirectory(), cmd.back()); + this->command = cmd; +} + +void InstallScript::start(cm::uv_loop_ptr& loop, + std::function<void()> callback) +{ + cmUVProcessChainBuilder builder; + builder.AddCommand(this->command) + .SetExternalLoop(*loop) + .SetMergedBuiltinStreams(); + this->chain = cm::make_unique<cmUVProcessChain>(builder.Start()); + this->pipe.init(this->chain->GetLoop(), 0); + uv_pipe_open(this->pipe, this->chain->OutputStream()); + this->streamHandler = cmUVStreamRead( + this->pipe, + [this](std::vector<char> data) { + std::string strdata; + cmProcessOutput(cmProcessOutput::Auto) + .DecodeText(data.data(), data.size(), strdata); + this->output.push_back(strdata); + }, + std::move(callback)); +} + +void InstallScript::printResult(std::size_t n, std::size_t total) +{ + cmSystemTools::Stdout(cmStrCat("[", n, "/", total, "] ", this->name, "\n")); + for (auto const& line : this->output) { + cmSystemTools::Stdout(line); + } +} diff --git a/Source/cmInstallScriptHandler.h b/Source/cmInstallScriptHandler.h new file mode 100644 index 0000000..3cd6164 --- /dev/null +++ b/Source/cmInstallScriptHandler.h @@ -0,0 +1,40 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include <cstddef> +#include <functional> +#include <memory> +#include <string> +#include <vector> + +#include "cmUVHandlePtr.h" +#include "cmUVProcessChain.h" +#include "cmUVStream.h" + +class cmInstallScriptHandler +{ +public: + cmInstallScriptHandler() = default; + cmInstallScriptHandler(const std::string&, std::vector<std::string>&); + bool isParallel(); + int install(unsigned int j); + class InstallScript + { + public: + InstallScript(const std::vector<std::string>&); + void start(cm::uv_loop_ptr&, std::function<void()>); + void printResult(std::size_t n, std::size_t total); + + private: + std::vector<std::string> command; + std::vector<std::string> output; + std::string name; + std::unique_ptr<cmUVProcessChain> chain; + std::unique_ptr<cmUVStreamReadHandle> streamHandler; + cm::uv_pipe_ptr pipe; + }; + +private: + std::vector<std::vector<std::string>> commands; +}; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index e7998ea..526eed6 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -66,7 +66,7 @@ void computeFilesToInstall( // Library interface name. std::string fromSOName; std::string toSOName; - if (library != output) { + if (!library.empty() && library != output) { haveNamelink = true; fromSOName = cmStrCat(fromDirConfig, library); toSOName = library; @@ -403,6 +403,10 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles( files.From.emplace_back(std::move(from1)); files.To.emplace_back(std::move(to1)); + } else if (this->Target->IsArchivedAIXSharedLibrary()) { + // Install only the archive on AIX. + computeFilesToInstall(files, this->NamelinkMode, fromDirConfig, + targetNames.Output, {}, targetNames.Real); } else { computeFilesToInstall(files, this->NamelinkMode, fromDirConfig, targetNames.Output, targetNames.SharedObject, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index e6d56d3..2d038b4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -500,6 +500,7 @@ void cmLocalGenerator::GenerateInstallRules() toplevel_install = 1; } file += "/cmake_install.cmake"; + this->GetGlobalGenerator()->AddInstallScript(file); cmGeneratedFileStream fout(file); fout.SetCopyIfDifferent(true); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 481c52d..225e63b 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -169,6 +169,11 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) std::string linkRuleVar = cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY"); + if (this->GeneratorTarget->IsArchivedAIXSharedLibrary()) { + linkRuleVar = + cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY_ARCHIVE"); + } + std::string extraFlags; this->GetTargetLinkFlags(extraFlags, linkLanguage); this->LocalGenerator->AddConfigVariableFlags( @@ -788,7 +793,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( vars.LinkLibraries = linkLibs.c_str(); vars.ObjectsQuoted = buildObjs.c_str(); std::string targetOutSOName; - if (this->GeneratorTarget->HasSOName(this->GetConfigName())) { + if (this->GeneratorTarget->HasSOName(this->GetConfigName()) || + this->GeneratorTarget->IsArchivedAIXSharedLibrary()) { vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage); targetOutSOName = this->LocalGenerator->ConvertToOutputFormat( this->TargetNames.SharedObject, cmOutputConverter::SHELL); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 77c3e6a..c37e4c2 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -1459,7 +1459,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmNinjaVars symlinkVars; bool const symlinkNeeded = - (targetOutput != targetOutputReal && !gt->IsFrameworkOnApple()); + (targetOutput != targetOutputReal && !gt->IsFrameworkOnApple() && + !gt->IsArchivedAIXSharedLibrary()); if (!symlinkNeeded) { vars["POST_BUILD"] = postBuildCmdLine; } else { diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 15197ba..35c8367 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -161,10 +161,6 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( cmSystemTools::ReplaceString(command, "$(ARGS)", ""); command = gg->ExpandCFGIntDir(command, config); - if (command.find('$') != std::string::npos) { - return; - } - std::string ccConfig; if (genTarget->Target->IsPerConfig() && genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index d646cce..c95be77 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1673,43 +1673,13 @@ bool cmQtAutoGenInitializer::InitRccTargets() if (!qrc.Unique) { ccName += cmStrCat('_', qrc.QrcPathChecksum); } - cmTarget* autoRccTarget = nullptr; - // When CMAKE_GLOBAL_AUTORCC_TARGET is ON and qrc is not generated, - // Add generate a timestamp file and a custom command to touch it. - // This will ensure that the global autorcc target is run only when the - // qrc file changes. - if (!qrc.Generated && this->Rcc.GlobalTarget) { - cm::string_view const timestampFileName = "global_rcc_timestamp"; - auto const outputFile = - cmStrCat(this->Dir.Build, "/", timestampFileName); - commandLines.push_back(cmMakeCommandLine( - { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile })); - cc->SetByproducts(ccOutput); - cc->SetDepends(ccDepends); - cc->SetEscapeOldStyle(false); - cc->SetOutputs(outputFile); - cc->SetCommandLines(commandLines); - this->LocalGen->AddCustomCommandToOutput(std::move(cc)); - this->AddGeneratedSource(outputFile, this->Rcc); - ccDepends.clear(); - ccDepends.push_back(outputFile); - - auto ccRccTarget = cm::make_unique<cmCustomCommand>(); - ccRccTarget->SetWorkingDirectory(this->Dir.Work.c_str()); - ccRccTarget->SetComment(ccComment.c_str()); - ccRccTarget->SetStdPipesUTF8(true); - ccRccTarget->SetDepends(ccDepends); - ccRccTarget->SetEscapeOldStyle(false); - - autoRccTarget = this->LocalGen->AddUtilityCommand( - ccName, true, std::move(ccRccTarget)); - } else { - cc->SetByproducts(ccOutput); - cc->SetDepends(ccDepends); - cc->SetEscapeOldStyle(false); - autoRccTarget = - this->LocalGen->AddUtilityCommand(ccName, true, std::move(cc)); - } + + cc->SetByproducts(ccOutput); + cc->SetDepends(ccDepends); + cc->SetEscapeOldStyle(false); + cmTarget* autoRccTarget = + this->LocalGen->AddUtilityCommand(ccName, true, std::move(cc)); + // Create autogen generator target this->LocalGen->AddGeneratorTarget( cm::make_unique<cmGeneratorTarget>(autoRccTarget, this->LocalGen)); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a6e6984..d609d80 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -407,6 +407,8 @@ TargetProperty const StaticTargetProperties[] = { { "VS_USE_DEBUG_LIBRARIES"_s, IC::NonImportedTarget }, // ---- OpenWatcom { "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources }, + // ---- AIX + { "AIX_SHARED_LIBRARY_ARCHIVE"_s, IC::SharedLibraryTarget }, // -- Language // ---- C COMMON_LANGUAGE_PROPERTIES(C), @@ -1284,6 +1286,12 @@ bool cmTarget::IsFrameworkOnApple() const this->IsApple() && this->GetPropertyAsBool("FRAMEWORK")); } +bool cmTarget::IsArchivedAIXSharedLibrary() const +{ + return (this->GetType() == cmStateEnums::SHARED_LIBRARY && this->IsAIX() && + this->GetPropertyAsBool("AIX_SHARED_LIBRARY_ARCHIVE")); +} + bool cmTarget::IsAppBundleOnApple() const { return (this->GetType() == cmStateEnums::EXECUTABLE && this->IsApple() && @@ -2997,7 +3005,9 @@ const char* cmTarget::GetSuffixVariableInternal( case cmStateEnums::SHARED_LIBRARY: switch (artifact) { case cmStateEnums::RuntimeBinaryArtifact: - return "CMAKE_SHARED_LIBRARY_SUFFIX"; + return this->IsArchivedAIXSharedLibrary() + ? "CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX" + : "CMAKE_SHARED_LIBRARY_SUFFIX"; case cmStateEnums::ImportLibraryArtifact: return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_SUFFIX" : "CMAKE_IMPORT_LIBRARY_SUFFIX"; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 220ac13..347d59b 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -234,6 +234,9 @@ public: //! Return whether this target is a shared library Framework on Apple. bool IsFrameworkOnApple() const; + //! Return whether to archive shared library or not on AIX. + bool IsArchivedAIXSharedLibrary() const; + //! Return whether this target is an executable Bundle on Apple. bool IsAppBundleOnApple() const; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index f5fd8d2..6c995c4 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3893,6 +3893,14 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( cudaOptions.AddFlag("CudaRuntime", "None"); } + if (this->ProjectType == VsProjectType::vcxproj && this->MSTools) { + // Suppress inheritance of host compiler optimization flags + // when the project does not specify any optimization flags for CUDA. + if (!cudaOptions.HasFlag("Optimization")) { + cudaOptions.AddFlag("Optimization", ""); + } + } + this->CudaOptions[configName] = std::move(pOptions); return true; } diff --git a/Source/cmXCOFF.cxx b/Source/cmXCOFF.cxx index a6d278d..923b6d9 100644 --- a/Source/cmXCOFF.cxx +++ b/Source/cmXCOFF.cxx @@ -16,10 +16,19 @@ # define __XCOFF32__ # define __XCOFF64__ # include <xcoff.h> +# define __AR_BIG__ +# include <ar.h> #else # error "This source may be compiled only on AIX." #endif +// Function to align a number num with align_num bytes. +size_t align(size_t num, int align_num) +{ + align_num = 1 << (align_num); + return (((num + align_num - 1) / align_num) * align_num); +} + class cmXCOFFInternal { public: @@ -79,6 +88,12 @@ struct XCOFF64 }; const unsigned char xcoff64_magic[] = { 0x01, 0xF7 }; +enum class IsArchive +{ + No, + Yes, +}; + template <typename XCOFF> class Impl : public cmXCOFFInternal { @@ -93,6 +108,20 @@ class Impl : public cmXCOFFInternal std::streamoff LoaderImportFileTablePos = 0; std::vector<char> LoaderImportFileTable; + bool Read(fl_hdr& x) + { + // FIXME: Add byte swapping if needed. + return static_cast<bool>( + this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))); + } + + bool Read(ar_hdr& x) + { + // FIXME: Add byte swapping if needed. + return static_cast<bool>( + this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))); + } + bool Read(typename XCOFF::filehdr& x) { // FIXME: Add byte swapping if needed. @@ -130,18 +159,40 @@ class Impl : public cmXCOFFInternal public: Impl(cmXCOFF* external, std::unique_ptr<std::iostream> fin, - cmXCOFF::Mode mode); + cmXCOFF::Mode mode, IsArchive IsBigArchive, int nextEvenBytePos); cm::optional<cm::string_view> GetLibPath() override; bool SetLibPath(cm::string_view libPath) override; bool RemoveLibPath() override; + + // Needed for SetLibPath () to move in a archive while write. + IsArchive is_big_archive; + int nextEvenByte; + int bytes_to_align; }; template <typename XCOFF> Impl<XCOFF>::Impl(cmXCOFF* external, std::unique_ptr<std::iostream> fin, - cmXCOFF::Mode mode) + cmXCOFF::Mode mode, IsArchive IsBigArchive, + int nextEvenBytePos) : cmXCOFFInternal(external, std::move(fin), mode) { + this->is_big_archive = IsBigArchive; + this->nextEvenByte = nextEvenBytePos; + if (this->is_big_archive == IsArchive::Yes) { + fl_hdr header; + this->Stream->read(reinterpret_cast<char*>(&header), sizeof(fl_hdr)); + + long long fstmoff = std::atoll(header.fl_fstmoff); + this->Stream->seekg(fstmoff, std::ios::beg); + + ar_hdr arHeader; + this->Stream->read(reinterpret_cast<char*>(&arHeader), sizeof(ar_hdr)); + + // Move the pointer to next even byte after reading headers. + this->Stream->seekg(this->nextEvenByte, std::ios::cur); + } + if (!this->Read(this->FileHeader)) { this->SetErrorMessage("Failed to read XCOFF file header."); return; @@ -158,6 +209,7 @@ Impl<XCOFF>::Impl(cmXCOFF* external, std::unique_ptr<std::iostream> fin, this->SetErrorMessage("XCOFF loader section missing."); return; } + this->bytes_to_align = this->AuxHeader.o_algndata; if (!this->Stream->seekg((this->AuxHeader.o_snloader - 1) * sizeof(typename XCOFF::scnhdr), std::ios::cur)) { @@ -172,17 +224,33 @@ Impl<XCOFF>::Impl(cmXCOFF* external, std::unique_ptr<std::iostream> fin, this->SetErrorMessage("XCOFF loader section header missing STYP_LOADER."); return; } - if (!this->Stream->seekg(this->LoaderSectionHeader.s_scnptr, - std::ios::beg)) { + if (is_big_archive == IsArchive::Yes) { + size_t header_len = this->nextEvenByte + sizeof(fl_hdr) + sizeof(ar_hdr); + size_t scnptrFromArchiveStart = this->LoaderSectionHeader.s_scnptr + + align(header_len, this->bytes_to_align); + if (!this->Stream->seekg(scnptrFromArchiveStart, std::ios::beg)) { + this->SetErrorMessage("Failed to seek to XCOFF loader header."); + return; + } + } else if (!this->Stream->seekg(this->LoaderSectionHeader.s_scnptr, + std::ios::beg)) { this->SetErrorMessage("Failed to seek to XCOFF loader header."); return; } + if (!this->Read(this->LoaderHeader)) { this->SetErrorMessage("Failed to read XCOFF loader header."); return; } - this->LoaderImportFileTablePos = - this->LoaderSectionHeader.s_scnptr + this->LoaderHeader.l_impoff; + if (is_big_archive == IsArchive::Yes) { + size_t header_len = sizeof(fl_hdr) + sizeof(ar_hdr) + this->nextEvenByte; + size_t scnptrFromArchiveStartPlusOff = this->LoaderSectionHeader.s_scnptr + + this->LoaderHeader.l_impoff + align(header_len, this->bytes_to_align); + this->LoaderImportFileTablePos = scnptrFromArchiveStartPlusOff; + } else { + this->LoaderImportFileTablePos = + this->LoaderSectionHeader.s_scnptr + this->LoaderHeader.l_impoff; + } if (!this->Stream->seekg(this->LoaderImportFileTablePos)) { this->SetErrorMessage( "Failed to seek to XCOFF loader import file id table."); @@ -251,9 +319,18 @@ bool Impl<XCOFF>::SetLibPath(cm::string_view libPath) this->LoaderImportFileTable = std::move(ift); } - if (!this->Stream->seekp(this->LoaderSectionHeader.s_scnptr + - offsetof(typename XCOFF::ldhdr, l_istlen), - std::ios::beg)) { + size_t scnptr; + if (this->is_big_archive == IsArchive::Yes) { + size_t header_len = sizeof(fl_hdr) + sizeof(ar_hdr) + this->nextEvenByte; + scnptr = this->LoaderSectionHeader.s_scnptr + + offsetof(typename XCOFF::ldhdr, l_istlen) + + align(header_len, this->bytes_to_align); + } else { + scnptr = this->LoaderSectionHeader.s_scnptr + + offsetof(typename XCOFF::ldhdr, l_istlen); + } + + if (!this->Stream->seekp(scnptr, std::ios::beg)) { this->SetErrorMessage( "Failed to seek to XCOFF loader header import file id table length."); return false; @@ -285,6 +362,30 @@ bool Impl<XCOFF>::RemoveLibPath() } } +IsArchive check_if_big_archive(const char* fname) +{ + int len = std::strlen(fname); + if (len < 2) { + return IsArchive::No; + } + + if (std::strcmp(fname + len - 2, ".a") == 0) { + return IsArchive::Yes; + } else { + return IsArchive::No; + } +} + +size_t getLastWordLen(const std::string& path) +{ + std::size_t lastSlashPos = path.find_last_of("/\\"); + if (lastSlashPos == std::string::npos) { + return path.length(); + } + + return (path.length() - lastSlashPos - 1); +} + //============================================================================ // External class implementation. @@ -305,6 +406,44 @@ cmXCOFF::cmXCOFF(const char* fname, Mode mode) // Read the XCOFF magic number. unsigned char magic[2]; + + // To hold the length of the shared object name in the path. + int nextEvenByte = 0; + + // Read archive name length. + int archive_name_length = 0; + // If a big archive, we will read the archive file headers first. + // Then move to the next even byte to get the magic number. + if (check_if_big_archive(fname) == IsArchive::Yes) { + fl_hdr header; + f->read(reinterpret_cast<char*>(&header), sizeof(fl_hdr)); + + if (std::strncmp(header.fl_magic, AIAMAGBIG, SAIAMAG) != 0) { + this->ErrorMessage = "Not a valid archive file or wrong format"; + + return; + } + long long fstmoff = std::atoll(header.fl_fstmoff); + f->seekg(fstmoff, std::ios::beg); + + ar_hdr arHeader; + f->read(reinterpret_cast<char*>(&arHeader), sizeof(ar_hdr)); + + // We will sometimes get /opt/freeware/lib/libshared.a. So extract + // the last part only. + // Example: libshared.a [We need to length of "libshared.a" characters]. + archive_name_length = static_cast<int>(getLastWordLen(std::string(fname))); + + // Move to the next even byte. + if (archive_name_length % 2 == 0) { + nextEvenByte = archive_name_length + 2; + } else { + nextEvenByte = archive_name_length + 1; + } + + f->seekg(nextEvenByte, std::ios::cur); + } + if (!f->read(reinterpret_cast<char*>(magic), sizeof(magic))) { this->ErrorMessage = "Error reading XCOFF magic number."; return; @@ -316,9 +455,11 @@ cmXCOFF::cmXCOFF(const char* fname, Mode mode) // Check the XCOFF type. if (magic[0] == xcoff32_magic[0] && magic[1] == xcoff32_magic[1]) { - this->Internal = cm::make_unique<Impl<XCOFF32>>(this, std::move(f), mode); + this->Internal = cm::make_unique<Impl<XCOFF32>>( + this, std::move(f), mode, check_if_big_archive(fname), nextEvenByte); } else if (magic[0] == xcoff64_magic[0] && magic[1] == xcoff64_magic[1]) { - this->Internal = cm::make_unique<Impl<XCOFF64>>(this, std::move(f), mode); + this->Internal = cm::make_unique<Impl<XCOFF64>>( + this, std::move(f), mode, check_if_big_archive(fname), nextEvenByte); } else { this->ErrorMessage = "File is not a XCOFF32 or XCOFF64 binary."; } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 775265f..7c64cee 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2936,6 +2936,7 @@ int cmake::Generate() this->SaveCache(this->GetHomeOutputDirectory()); #if !defined(CMAKE_BOOTSTRAP) + this->GetGlobalGenerator()->WriteInstallJson(); this->FileAPI->WriteReplies(); #endif diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 43d22ee..a8bbeca 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -27,6 +27,7 @@ #include "cmConsoleBuf.h" #include "cmDocumentationEntry.h" #include "cmGlobalGenerator.h" +#include "cmInstallScriptHandler.h" #include "cmList.h" #include "cmMakefile.h" #include "cmMessageMetadata.h" @@ -431,6 +432,17 @@ int extract_job_number(std::string const& command, } return jobs; } +std::function<bool(std::string const&)> extract_job_number_lambda_builder( + std::string& dir, int& jobs, const std::string& flag) +{ + return [&dir, &jobs, flag](std::string const& value) -> bool { + jobs = extract_job_number(flag, value); + if (jobs < 0) { + dir.clear(); + } + return true; + }; +}; #endif int do_build(int ac, char const* const* av) @@ -453,20 +465,10 @@ int do_build(int ac, char const* const* av) std::string presetName; bool listPresets = false; - auto jLambda = [&](std::string const& value) -> bool { - jobs = extract_job_number("-j", value); - if (jobs < 0) { - dir.clear(); - } - return true; - }; - auto parallelLambda = [&](std::string const& value) -> bool { - jobs = extract_job_number("--parallel", value); - if (jobs < 0) { - dir.clear(); - } - return true; - }; + auto jLambda = extract_job_number_lambda_builder(dir, jobs, "-j"); + auto parallelLambda = + extract_job_number_lambda_builder(dir, jobs, "--parallel"); + auto targetLambda = [&](std::string const& value) -> bool { if (!value.empty()) { cmList values{ value }; @@ -789,9 +791,14 @@ int do_install(int ac, char const* const* av) std::string defaultDirectoryPermissions; std::string prefix; std::string dir; + int jobs = 0; bool strip = false; bool verbose = cmSystemTools::HasEnv("VERBOSE"); + auto jLambda = extract_job_number_lambda_builder(dir, jobs, "-j"); + auto parallelLambda = + extract_job_number_lambda_builder(dir, jobs, "--parallel"); + auto verboseLambda = [&](std::string const&) -> bool { verbose = true; return true; @@ -808,6 +815,9 @@ int do_install(int ac, char const* const* av) CommandArgument{ "--default-directory-permissions", CommandArgument::Values::One, CommandArgument::setToValue(defaultDirectoryPermissions) }, + CommandArgument{ "-j", CommandArgument::Values::One, jLambda }, + CommandArgument{ "--parallel", CommandArgument::Values::One, + parallelLambda }, CommandArgument{ "--prefix", CommandArgument::Values::One, CommandArgument::setToValue(prefix) }, CommandArgument{ "--strip", CommandArgument::Values::Zero, @@ -824,7 +834,6 @@ int do_install(int ac, char const* const* av) inputArgs.reserve(ac - 3); cm::append(inputArgs, av + 3, av + ac); for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) { - std::string const& arg = inputArgs[i]; bool matched = false; bool parsed = false; @@ -855,6 +864,10 @@ int do_install(int ac, char const* const* av) " --component <comp> = Component-based install. Only install <comp>.\n" " --default-directory-permissions <permission> \n" " Default install permission. Use default permission <permission>.\n" + " -j <jobs> --parallel <jobs>\n" + " Build in parallel using the given number of jobs. \n" + " The CMAKE_INSTALL_PARALLEL_LEVEL environment variable\n" + " specifies a default parallel level when this option is not given.\n" " --prefix <prefix> = The installation prefix CMAKE_INSTALL_PREFIX.\n" " --strip = Performing install/strip.\n" " -v --verbose = Enable verbose output.\n" @@ -908,9 +921,29 @@ int do_install(int ac, char const* const* av) } args.emplace_back("-P"); - args.emplace_back(dir + "/cmake_install.cmake"); - return cm.Run(args) ? 1 : 0; + auto handler = cmInstallScriptHandler(dir, args); + int ret = 0; + if (!handler.isParallel()) { + args.emplace_back(cmStrCat(dir, "/cmake_install.cmake")); + ret = int(bool(cm.Run(args))); + } else { + if (!jobs) { + jobs = 1; + auto envvar = cmSystemTools::GetEnvVar("CMAKE_INSTALL_PARALLEL_LEVEL"); + if (envvar.has_value()) { + jobs = extract_job_number("", envvar.value()); + if (jobs < 1) { + std::cerr << "Value of CMAKE_INSTALL_PARALLEL_LEVEL environment" + " variable must be a positive integer.\n"; + return 1; + } + } + } + ret = handler.install(jobs); + } + + return int(ret > 0); #endif } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 41a3f10..69f48f5 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -493,6 +493,7 @@ if(BUILD_TESTING) ADD_TEST_MACRO(OutDir runtime/OutDir) ADD_TEST_MACRO(OutName exe.OutName.exe) ADD_TEST_MACRO(ObjectLibrary UseCshared) + ADD_TEST_MACRO(SharedLibraryArchive UseSLA) ADD_TEST_MACRO(NewlineArgs NewlineArgs) ADD_TEST_MACRO(SetLang SetLangX) ADD_TEST_MACRO(EmptyProperty EmptyProperty) diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index c145907..d492811 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -412,6 +412,10 @@ add_custom_target(do_check_command_line ALL COMMENT "Checking custom target command line escapes ($dollar-signs$)" ) add_dependencies(do_check_command_line check_command_line) +add_custom_command(TARGET do_check_command_line POST_BUILD VERBATIM + COMMAND ${CMAKE_COMMAND} -E echo "POST_BUILD command with $dollar-signs$" + COMMENT "Checking custom target POST_BUILD command line escapes ($dollar-signs$)" +) add_custom_target(pre_check_command_line COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index 28118ba..4a6db97 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -482,6 +482,9 @@ add_library(testMod1 MODULE empty.cpp) add_library(testMod2 MODULE empty.cpp) set_property(TARGET testMod2 PROPERTY BUNDLE 1) +add_library(testSharedLibArchiveAIX SHARED testSharedLibArchiveAIX.c) +set_property(TARGET testSharedLibArchiveAIX PROPERTY AIX_SHARED_LIBRARY_ARCHIVE 1) + install(TARGETS testLibRequired EXPORT RequiredExp DESTINATION lib INCLUDES DESTINATION @@ -622,6 +625,7 @@ install( systemlib testInterfaceIncludeUser testInterfaceIncludeUser2 + testSharedLibArchiveAIX EXPORT exp RUNTIME DESTINATION $<1:bin>$<0:/wrong> LIBRARY DESTINATION $<1:lib>$<0:/wrong> NAMELINK_SKIP @@ -699,6 +703,7 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 te testExeWithPluginHelper testExePluginHelperObj testMod1 testMod2 testLibPerConfigDest + testSharedLibArchiveAIX NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake ) diff --git a/Tests/ExportImport/Export/testSharedLibArchiveAIX.c b/Tests/ExportImport/Export/testSharedLibArchiveAIX.c new file mode 100644 index 0000000..25a29e0 --- /dev/null +++ b/Tests/ExportImport/Export/testSharedLibArchiveAIX.c @@ -0,0 +1,10 @@ +#if defined(_WIN32) || defined(__CYGWIN__) +# define EXPORT __declspec(dllexport) +#else +# define EXPORT +#endif + +EXPORT int testSharedLibArchiveAIX(void) +{ + return 0; +} diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 632825d..84a50a6 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -68,6 +68,7 @@ target_link_libraries(imp_testExe1 exp_testLib7 exp_testLibCycleA exp_testLibPerConfigDest + exp_testSharedLibArchiveAIX exp_testStaticLibWithPlugin ) @@ -123,6 +124,7 @@ target_link_libraries(imp_testExe1b bld_testLib7 bld_testLibCycleA bld_testLibPerConfigDest + bld_testSharedLibArchiveAIX bld_testStaticLibWithPlugin ) diff --git a/Tests/ExportImport/Import/A/imp_testExe1.c b/Tests/ExportImport/Import/A/imp_testExe1.c index e409b1c..7f30c5d 100644 --- a/Tests/ExportImport/Import/A/imp_testExe1.c +++ b/Tests/ExportImport/Import/A/imp_testExe1.c @@ -11,6 +11,7 @@ extern int testLib7(void); extern int testLibCycleA1(void); extern int testLibPerConfigDest(void); extern int testStaticLibPlugin(void); +extern int testSharedLibArchiveAIX(void); /* Switch a symbol between debug and optimized builds to make sure the proper library is found from the testLib4 link interface. */ @@ -26,6 +27,6 @@ int main(void) return (testLib2() + generated_by_testExe1() + testLib3() + testLib4() + testLib5() + testLib6() + testLib7() + testLibCycleA1() + testLibPerConfigDest() + testStaticLibPlugin() + - generated_by_testExe3() + generated_by_testExe4() + testLib4lib() + - testLib4libcfg()); + testSharedLibArchiveAIX() + generated_by_testExe3() + + generated_by_testExe4() + testLib4lib() + testLib4libcfg()); } diff --git a/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake b/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake index 1f6f7d4..8060ec4 100644 --- a/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake +++ b/Tests/RunCMake/Autogen_5/RunCMakeTest.cmake @@ -27,21 +27,5 @@ if (DEFINED with_qt_version) endblock() endforeach() endif() - if (RunCMake_GENERATOR MATCHES "Ninja") - block() - set(RunCMake_TEST_BINARY_DIR - ${RunCMake_BINARY_DIR}/RccGlobalAutoRcc-build) - run_cmake_with_options(RccExample ${RunCMake_TEST_OPTIONS} - -DCMAKE_GLOBAL_AUTORCC_TARGET=ON) - set(RunCMake_TEST_NO_CLEAN 1) - set(RunCMake_TEST_VARIANT_DESCRIPTION "-First-build") - run_cmake_command(RccGlobalAutoRcc-build ${CMAKE_COMMAND} - --build . --config Debug) - set(RunCMake_TEST_VARIANT_DESCRIPTION "-Second-build-nothing-to-do") - set(RunCMake_TEST_NOT_EXPECT_stdout "Automatic RCC for data.qrc") - run_cmake_command(RccGlobalAutoRcc-build ${CMAKE_COMMAND} - --build . --config Debug) - endblock() - endif() endif() endif () diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index db5ef96..c9ba025 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -258,8 +258,8 @@ if(CMAKE_GENERATOR MATCHES "Ninja") add_RunCMake_test(NinjaPrivateDeps -DCMAKE_C_OUTPUT_EXTENSION=${CMAKE_C_OUTPUT_EXTENSION} -DRunCMake_GENERATOR_IS_MULTI_CONFIG=${_isMultiConfig}) - add_RunCMake_test(InstallParallel) endif() +add_RunCMake_test(InstallParallel) add_RunCMake_test(CTest) if(NOT CMake_TEST_EXTERNAL_CMAKE) diff --git a/Tests/RunCMake/InstallParallel/RunCMakeTest.cmake b/Tests/RunCMake/InstallParallel/RunCMakeTest.cmake index ae3f112..d8ce61b 100644 --- a/Tests/RunCMake/InstallParallel/RunCMakeTest.cmake +++ b/Tests/RunCMake/InstallParallel/RunCMakeTest.cmake @@ -1,17 +1,36 @@ include(RunCMake) -function(install_test test parallel install_target check_script) +function(install_test test parallel install_arg) + cmake_parse_arguments(ARGS "NINJA;TOUCH_CACHE" "VERIFY_SCRIPT" "" ${ARGN}) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-install) set(RunCMake_TEST_OPTIONS -DINSTALL_PARALLEL=${parallel}) + set(RunCMake_TEST_OUTPUT_MERGE 1) if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) endif() run_cmake(install) set(RunCMake_TEST_NO_CLEAN 1) - run_cmake_command(${test}-install ${CMAKE_COMMAND} --build . --config Debug -t ${install_target}) + if (ARGS_TOUCH_CACHE) + run_cmake_command(${test}-touch + ${CMAKE_COMMAND} -E touch ${RunCMake_TEST_BINARY_DIR}/CMakeFiles/cmake.check_cache) + endif() + if (ARGS_NINJA) + run_cmake_command(${test}-install ${CMAKE_COMMAND} --build . --config Debug -t ${install_arg}) + else() + run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . -j ${install_arg}) + endif() set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY ${RunCMake_SOURCE_DIR}) - run_cmake_command(verify-parallel ${CMAKE_COMMAND} -P ${check_script} ${RunCMake_TEST_BINARY_DIR}/.ninja_log) + if (ARGS_VERIFY_SCRIPT) + run_cmake_command(${test}-verify-parallel + ${CMAKE_COMMAND} -P ${ARGS_VERIFY_SCRIPT} ${RunCMake_TEST_BINARY_DIR}/.ninja_log) +endif() endfunction() -install_test(parallel 1 install/parallel check-parallel.cmake) -install_test(no-parallel 0 install check-single.cmake) +install_test(parallel 1 4) +install_test(no-parallel 0 4) +install_test(out-of-date-json 1 4 TOUCH_CACHE) + +if(RunCMake_GENERATOR MATCHES "Ninja") + install_test(ninja-parallel 1 install/parallel VERIFY_SCRIPT check-parallel.cmake NINJA) + install_test(ninja-no-parallel 0 install VERIFY_SCRIPT check-single.cmake NINJA) +endif() diff --git a/Tests/RunCMake/InstallParallel/no-parallel-install-stderr.txt b/Tests/RunCMake/InstallParallel/ninja-no-parallel-install-stdout.txt index 8f69a04..8f69a04 100644 --- a/Tests/RunCMake/InstallParallel/no-parallel-install-stderr.txt +++ b/Tests/RunCMake/InstallParallel/ninja-no-parallel-install-stdout.txt diff --git a/Tests/RunCMake/InstallParallel/ninja-parallel-install-stdout.txt b/Tests/RunCMake/InstallParallel/ninja-parallel-install-stdout.txt new file mode 100644 index 0000000..e75f142 --- /dev/null +++ b/Tests/RunCMake/InstallParallel/ninja-parallel-install-stdout.txt @@ -0,0 +1,15 @@ +\[1\/5\] Installing only the local directory... +\-\- Install configuration:.* +installing:.* +\[2\/5\] Installing only the local directory... +\-\- Install configuration:.* +installing:.* +\[3\/5\] Installing only the local directory... +\-\- Install configuration:.* +installing:.* +\[4\/5\] Installing only the local directory... +\-\- Install configuration:.* +installing:.* +\[5\/5\] Installing only the local directory... +\-\- Install configuration:.* +installing:.* diff --git a/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt b/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt new file mode 100644 index 0000000..8f69a04 --- /dev/null +++ b/Tests/RunCMake/InstallParallel/no-parallel-install-stdout.txt @@ -0,0 +1,5 @@ +installing:.* +installing:.* +installing:.* +installing:.* +installing:.* diff --git a/Tests/RunCMake/InstallParallel/out-of-date-json-install-stdout.txt b/Tests/RunCMake/InstallParallel/out-of-date-json-install-stdout.txt new file mode 100644 index 0000000..8f69a04 --- /dev/null +++ b/Tests/RunCMake/InstallParallel/out-of-date-json-install-stdout.txt @@ -0,0 +1,5 @@ +installing:.* +installing:.* +installing:.* +installing:.* +installing:.* diff --git a/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt b/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt index e0d2a56..f2a68fc 100644 --- a/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt +++ b/Tests/RunCMake/InstallParallel/parallel-install-stdout.txt @@ -1,15 +1,15 @@ -\[1\/5\] Installing only the local directory... -\-\- Install configuration: \"Debug\" +\[1\/5\] .* +\-\- Install configuration:.* installing:.* -\[2\/5\] Installing only the local directory... -\-\- Install configuration: \"Debug\" +\[2\/5\] .* +\-\- Install configuration:.* installing:.* -\[3\/5\] Installing only the local directory... -\-\- Install configuration: \"Debug\" +\[3\/5\] .* +\-\- Install configuration:.* installing:.* -\[4\/5\] Installing only the local directory... -\-\- Install configuration: \"Debug\" +\[4\/5\] .* +\-\- Install configuration:.* installing:.* -\[5\/5\] Installing only the local directory... -\-\- Install configuration: \"Debug\" +\[5\/5\] .* +\-\- Install configuration:.* installing:.* diff --git a/Tests/RunCMake/ParseImplicitData/linux-Fortran-GNU-13.3.0-static-libquadmath.input b/Tests/RunCMake/ParseImplicitData/linux-Fortran-GNU-13.3.0-static-libquadmath.input new file mode 100644 index 0000000..b1ab2f0 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitData/linux-Fortran-GNU-13.3.0-static-libquadmath.input @@ -0,0 +1,80 @@ +CMAKE_LANG=Fortran +CMAKE_LINKER=/usr/bin/ld +CMAKE_Fortran_COMPILER_ABI= +CMAKE_Fortran_COMPILER_AR=/usr/bin/gcc-ar-13 +CMAKE_Fortran_COMPILER_ARCHITECTURE_ID= +CMAKE_Fortran_COMPILER_EXTERNAL_TOOLCHAIN= +CMAKE_Fortran_COMPILER_ID=GNU +CMAKE_Fortran_COMPILER_LAUNCHER= +CMAKE_Fortran_COMPILER_LOADED=1 +CMAKE_Fortran_COMPILER_RANLIB=/usr/bin/gcc-ranlib-13 +CMAKE_Fortran_COMPILER_TARGET= +CMAKE_Fortran_COMPILER_VERSION=13.3.0 +CMAKE_Fortran_COMPILER_VERSION_INTERAL= +CMAKE_Fortran_IMPLICIT_LINK_LIBRARY_quadmath=/usr/lib/gcc/x86_64-linux-gnu/13/libquadmath.a +Change Dir: '/tmp/ii/CMakeFiles/CMakeTmp' + +Run Build Command(s): /tmp/CMake/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_9b1c8/fast +/usr/bin/gmake -f CMakeFiles/cmTC_9b1c8.dir/build.make CMakeFiles/cmTC_9b1c8.dir/build +gmake[1]: Entering directory '/tmp/ii/CMakeFiles/CMakeTmp' +Building Fortran object CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o +/usr/bin/gfortran -static-libquadmath -v -c /tmp/CMake/Modules/CMakeFortranCompilerABI.F -o CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o +Using built-in specs. +COLLECT_GCC=/usr/bin/gfortran +OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 13.3.0-1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=3 +Thread model: posix +Supported LTO compression algorithms: zlib zstd +gcc version 13.3.0 (Debian 13.3.0-1) +COLLECT_GCC_OPTIONS='-static-libquadmath' '-v' '-c' '-o' 'CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_9b1c8.dir/' + /usr/libexec/gcc/x86_64-linux-gnu/13/f951 /tmp/CMake/Modules/CMakeFortranCompilerABI.F -ffixed-form -cpp=/tmp/ccPxd9HW.f90 -quiet -v -imultiarch x86_64-linux-gnu /tmp/CMake/Modules/CMakeFortranCompilerABI.F -quiet -dumpdir CMakeFiles/cmTC_9b1c8.dir/ -dumpbase CMakeFortranCompilerABI.F.F -dumpbase-ext .F -mtune=generic -march=x86-64 -version -fintrinsic-modules-path /usr/lib/gcc/x86_64-linux-gnu/13/finclude -fpre-include=/usr/include/finclude/x86_64-linux-gnu/math-vector-fortran.h -o /tmp/ccWH03h1.s +GNU Fortran (Debian 13.3.0-1) version 13.3.0 (x86_64-linux-gnu) + compiled by GNU C version 13.3.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include" +#include "..." search starts here: +#include <...> search starts here: + /usr/lib/gcc/x86_64-linux-gnu/13/finclude + /usr/lib/gcc/x86_64-linux-gnu/13/include + /usr/local/include + /usr/include/x86_64-linux-gnu + /usr/include +End of search list. +COLLECT_GCC_OPTIONS='-static-libquadmath' '-v' '-c' '-o' 'CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_9b1c8.dir/' + as -v --64 -o CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o /tmp/ccWH03h1.s +GNU assembler version 2.42.50 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.42.50.20240625 +COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-static-libquadmath' '-v' '-c' '-o' 'CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.' +Linking Fortran executable cmTC_9b1c8 +/tmp/CMake/bin/cmake -E cmake_link_script CMakeFiles/cmTC_9b1c8.dir/link.txt --verbose=1 +/usr/bin/gfortran -v -Wl,-v -static-libquadmath CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o -o cmTC_9b1c8 +Driving: /usr/bin/gfortran -v -Wl,-v -static-libquadmath CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o -o cmTC_9b1c8 -l gfortran -l m -shared-libgcc +Using built-in specs. +COLLECT_GCC=/usr/bin/gfortran +COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Debian 13.3.0-1' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=3 +Thread model: posix +Supported LTO compression algorithms: zlib zstd +gcc version 13.3.0 (Debian 13.3.0-1) +Reading specs from /usr/lib/gcc/x86_64-linux-gnu/13/libgfortran.spec +rename spec lib to liborig +COLLECT_GCC_OPTIONS='-v' '-static-libquadmath' '-o' 'cmTC_9b1c8' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_9b1c8-' +COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-static-libquadmath' '-o' 'cmTC_9b1c8' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_9b1c8.' + /usr/libexec/gcc/x86_64-linux-gnu/13/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccBedNT7.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_9b1c8 /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/13 -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/13/../../.. -v CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o -lgfortran -lm -lgcc_s -lgcc --as-needed -Bstatic -lquadmath -Bdynamic --no-as-needed -lm -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o +collect2 version 13.3.0 +/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccBedNT7.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o cmTC_9b1c8 /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/13 -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/13/../../.. -v CMakeFiles/cmTC_9b1c8.dir/CMakeFortranCompilerABI.F.o -lgfortran -lm -lgcc_s -lgcc --as-needed -Bstatic -lquadmath -Bdynamic --no-as-needed -lm -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o +GNU ld (GNU Binutils for Debian) 2.42.50.20240625 +COLLECT_GCC_OPTIONS='-v' '-static-libquadmath' '-o' 'cmTC_9b1c8' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_9b1c8.' +gmake[1]: Leaving directory '/tmp/ii/CMakeFiles/CMakeTmp' diff --git a/Tests/RunCMake/ParseImplicitIncludeInfo/ParseImplicitIncludeInfo.cmake b/Tests/RunCMake/ParseImplicitIncludeInfo/ParseImplicitIncludeInfo.cmake index c5bb5d7..c58722d 100644 --- a/Tests/RunCMake/ParseImplicitIncludeInfo/ParseImplicitIncludeInfo.cmake +++ b/Tests/RunCMake/ParseImplicitIncludeInfo/ParseImplicitIncludeInfo.cmake @@ -24,6 +24,7 @@ set(targets linux-C-GNU-10.2.1-static-libgcc linux-CXX-GNU-10.2.1-static-libstdc++ linux-Fortran-GNU-10.2.1-static-libgfortran + linux-Fortran-GNU-13.3.0-static-libquadmath linux-C-GNU-12.2.0 linux-CXX-GNU-12.2.0 linux-Fortran-GNU-12.2.0 linux-C-Intel-18.0.0.20170811 linux-CXX-Intel-18.0.0.20170811 linux-C-Intel-2021.10.0.20230609 linux-CXX-Intel-2021.10.0.20230609 linux-Fortran-Intel-2021.10.0.20230609 diff --git a/Tests/RunCMake/ParseImplicitIncludeInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output b/Tests/RunCMake/ParseImplicitIncludeInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output new file mode 100644 index 0000000..defc375 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitIncludeInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output @@ -0,0 +1 @@ +/usr/lib/gcc/x86_64-linux-gnu/13/finclude;/usr/lib/gcc/x86_64-linux-gnu/13/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake index 8d6c739..c988536 100644 --- a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake +++ b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake @@ -24,6 +24,7 @@ set(targets linux-C-GNU-10.2.1-static-libgcc linux-CXX-GNU-10.2.1-static-libstdc++ linux-Fortran-GNU-10.2.1-static-libgfortran + linux-Fortran-GNU-13.3.0-static-libquadmath linux-C-GNU-12.2.0 linux-CXX-GNU-12.2.0 linux-Fortran-GNU-12.2.0 linux-C-Intel-18.0.0.20170811 linux-CXX-Intel-18.0.0.20170811 linux-C-Intel-2021.10.0.20230609 linux-CXX-Intel-2021.10.0.20230609 linux-Fortran-Intel-2021.10.0.20230609 diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output new file mode 100644 index 0000000..1595560 --- /dev/null +++ b/Tests/RunCMake/ParseImplicitLinkInfo/results/linux-Fortran-GNU-13.3.0-static-libquadmath.output @@ -0,0 +1,4 @@ +libs=gfortran;m;gcc_s;gcc;/usr/lib/gcc/x86_64-linux-gnu/13/libquadmath.a;m;c;gcc_s;gcc +dirs=/usr/lib/gcc/x86_64-linux-gnu/13;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib +library_arch=x86_64-linux-gnu +linker_tool=/usr/bin/ld diff --git a/Tests/SharedLibraryArchive/CMakeLists.txt b/Tests/SharedLibraryArchive/CMakeLists.txt new file mode 100644 index 0000000..7077181 --- /dev/null +++ b/Tests/SharedLibraryArchive/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.30) +project(SharedLibraryArchive C) + +set(CMAKE_AIX_SHARED_LIBRARY_ARCHIVE 1) + +add_library(sla SHARED sla.c) +get_property(aix_sla TARGET sla PROPERTY AIX_SHARED_LIBRARY_ARCHIVE) +if(NOT aix_sla) + message(FATAL_ERROR "AIX_SHARED_LIBRARY_ARCHIVE not initialized on SHARED library") +endif() +add_custom_command(TARGET sla POST_BUILD VERBATIM + COMMAND ${CMAKE_COMMAND} -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -Dsla=$<TARGET_FILE:sla> -P${CMAKE_CURRENT_SOURCE_DIR}/sla-check.cmake + ) + +add_executable(UseSLA use_sla.c) +get_property(aix_sla TARGET UseSLA PROPERTY AIX_SHARED_LIBRARY_ARCHIVE) +if(aix_sla) + message(FATAL_ERROR "AIX_SHARED_LIBRARY_ARCHIVE initialized on EXECUTABLE") +endif() +target_link_libraries(UseSLA PRIVATE sla) diff --git a/Tests/SharedLibraryArchive/sla-check.cmake b/Tests/SharedLibraryArchive/sla-check.cmake new file mode 100644 index 0000000..bc1fee5 --- /dev/null +++ b/Tests/SharedLibraryArchive/sla-check.cmake @@ -0,0 +1,9 @@ +if(CMAKE_SYSTEM_NAME STREQUAL "AIX") + if(NOT sla MATCHES [[/libsla\.a]]) + message(FATAL_ERROR "sla library does not look like an archive:\n ${sla}") + endif() + execute_process(COMMAND ar t ${sla} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE sla_members) + if(NOT sla_members MATCHES [[^libsla\.so]]) + message(FATAL_ERROR "sla library archive does not have expected members:\n ${sla_members}") + endif() +endif() diff --git a/Tests/SharedLibraryArchive/sla.c b/Tests/SharedLibraryArchive/sla.c new file mode 100644 index 0000000..5bc452f --- /dev/null +++ b/Tests/SharedLibraryArchive/sla.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int sla(void) +{ + return 0; +} diff --git a/Tests/SharedLibraryArchive/use_sla.c b/Tests/SharedLibraryArchive/use_sla.c new file mode 100644 index 0000000..0b82135 --- /dev/null +++ b/Tests/SharedLibraryArchive/use_sla.c @@ -0,0 +1,9 @@ +#ifdef _WIN32 +__declspec(dllimport) +#endif + int sla(void); + +int main(void) +{ + return sla(); +} |