Apple: Handle generation and comsuption of text-based stubs (.tbd files)
Fixes: #24123stage/master/nightly/2023/03/02
parent
fcbd723a50
commit
ede33f30cf
|
@ -158,6 +158,9 @@ that may be installed:
|
|||
``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
|
||||
* On AIX, the *linker import file* created for executables with
|
||||
:prop_tgt:`ENABLE_EXPORTS` enabled.
|
||||
* On macOS, the *linker import file* created for shared libraries with
|
||||
:prop_tgt:`ENABLE_EXPORTS` enabled (except when marked as ``FRAMEWORK``,
|
||||
see below).
|
||||
|
||||
``LIBRARY``
|
||||
Target artifacts of this kind include:
|
||||
|
@ -308,6 +311,11 @@ the following additional arguments:
|
|||
value of ``COMPONENT``. It is an error to use this parameter outside of a
|
||||
``LIBRARY`` block.
|
||||
|
||||
.. versionchanged:: 3.27
|
||||
This parameter is also usable for an ``ARCHIVE`` block to manage
|
||||
the linker import file created, on macOS, for shared libraries with
|
||||
:prop_tgt:`ENABLE_EXPORTS` enabled.
|
||||
|
||||
Consider the following example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
@ -342,6 +350,11 @@ the following additional arguments:
|
|||
option installs nothing. It is an error to use this parameter outside of a
|
||||
``LIBRARY`` block.
|
||||
|
||||
.. versionchanged:: 3.27
|
||||
This parameter is also usable for an ``ARCHIVE`` block to manage
|
||||
the linker import file created, on macOS, for shared libraries with
|
||||
:prop_tgt:`ENABLE_EXPORTS` enabled.
|
||||
|
||||
When ``NAMELINK_ONLY`` is given, either ``NAMELINK_COMPONENT`` or
|
||||
``COMPONENT`` may be used to specify the installation component of the
|
||||
namelink, but ``COMPONENT`` should generally be preferred.
|
||||
|
@ -355,6 +368,11 @@ the following additional arguments:
|
|||
installs the library. It is an error to use this parameter outside of a
|
||||
``LIBRARY`` block.
|
||||
|
||||
.. versionchanged:: 3.27
|
||||
This parameter is also usable for an ``ARCHIVE`` block to manage
|
||||
the linker import file created, on macOS, for shared libraries with
|
||||
:prop_tgt:`ENABLE_EXPORTS` enabled.
|
||||
|
||||
If ``NAMELINK_SKIP`` is specified, ``NAMELINK_COMPONENT`` has no effect. It
|
||||
is not recommended to use ``NAMELINK_SKIP`` in conjunction with
|
||||
``NAMELINK_COMPONENT``.
|
||||
|
|
|
@ -797,6 +797,10 @@ An *archive* output artifact of a buildsystem target may be:
|
|||
created by the :command:`add_executable` command when its
|
||||
:prop_tgt:`ENABLE_EXPORTS` target property is set.
|
||||
|
||||
* On macOS: the linker import file (e.g. ``.tbd``) of a shared library target
|
||||
created by the :command:`add_library` command with the ``SHARED`` option and
|
||||
when its :prop_tgt:`ENABLE_EXPORTS` target property is set.
|
||||
|
||||
The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`
|
||||
target properties may be used to control archive output artifact locations
|
||||
and names in the build tree.
|
||||
|
|
|
@ -1503,6 +1503,76 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
|||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Full path to the linker import file. On DLL platforms, it would be the
|
||||
``.lib`` file. On AIX, for the executables, and on macOS, for the shared
|
||||
libraries, it could be, respectively, the ``.imp`` or ``.tbd`` import file,
|
||||
depending of the value of :prop_tgt:`ENABLE_EXPORTS` property.
|
||||
|
||||
An empty string is returned when there is no import file associated with the
|
||||
target.
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE_BASE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Base name of file linker import file of the target ``tgt`` without prefix and
|
||||
suffix. For example, if target file name is ``libbase.tbd``, the base name is
|
||||
``base``.
|
||||
|
||||
See also the :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`
|
||||
target properties and their configuration specific variants
|
||||
:prop_tgt:`OUTPUT_NAME_<CONFIG>` and :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>`.
|
||||
|
||||
The :prop_tgt:`<CONFIG>_POSTFIX` and :prop_tgt:`DEBUG_POSTFIX` target
|
||||
properties can also be considered.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE_PREFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Prefix of the import file of the target ``tgt``.
|
||||
|
||||
See also the :prop_tgt:`IMPORT_PREFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE_SUFFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Suffix of the import file of the target ``tgt``.
|
||||
|
||||
The suffix corresponds to the file extension (such as ".lib" or ".tbd").
|
||||
|
||||
See also the :prop_tgt:`IMPORT_SUFFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Name of the import file of the target target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_IMPORT_FILE_DIR:tgt>
|
||||
|
||||
Directory of the import file of the target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_FILE:tgt>
|
||||
|
||||
File used when linking to the ``tgt`` target. This will usually
|
||||
|
@ -1510,13 +1580,22 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
|||
but for a shared library on DLL platforms, it would be the ``.lib``
|
||||
import library associated with the DLL.
|
||||
|
||||
.. versionadded:: 3.27
|
||||
On macOS, it could be the ``.tbd`` import file associated with the shared
|
||||
library, depending of the value of :prop_tgt:`ENABLE_EXPORTS` property.
|
||||
|
||||
This generator expression is equivalent to
|
||||
:genex:`$<TARGET_LINKER_LIBRARY_FILE>` or
|
||||
:genex:`$<TARGET_LINKER_IMPORT_FILE>` generator expressions, depending of the
|
||||
characteristics of the target and the platform.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_FILE_BASE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.15
|
||||
|
||||
Base name of file used to link the target ``tgt``, i.e.
|
||||
``$<TARGET_LINKER_FILE_NAME:tgt>`` without prefix and suffix. For example,
|
||||
if target file name is ``libbase.a``, the base name is ``base``.
|
||||
:genex:`$<TARGET_LINKER_FILE_NAME:tgt>` without prefix and suffix. For
|
||||
example, if target file name is ``libbase.a``, the base name is ``base``.
|
||||
|
||||
See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
|
||||
and :prop_tgt:`LIBRARY_OUTPUT_NAME` target properties and their configuration
|
||||
|
@ -1570,9 +1649,151 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
|||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
File used when linking o the ``tgt`` target is done using directly the
|
||||
library, and not an import file. This will usually be the library that
|
||||
``tgt`` represents (``.a``, ``.so``, ``.dylib``). So, on DLL platforms, it
|
||||
will be an empty string.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Base name of library file used to link the target ``tgt``, i.e.
|
||||
:genex:`$<TARGET_LINKER_LIBRARY_FILE_NAME:tgt>` without prefix and suffix.
|
||||
For example, if target file name is ``libbase.a``, the base name is ``base``.
|
||||
|
||||
See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
|
||||
and :prop_tgt:`LIBRARY_OUTPUT_NAME` target properties and their configuration
|
||||
specific variants :prop_tgt:`OUTPUT_NAME_<CONFIG>`,
|
||||
:prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>` and
|
||||
:prop_tgt:`LIBRARY_OUTPUT_NAME_<CONFIG>`.
|
||||
|
||||
The :prop_tgt:`<CONFIG>_POSTFIX` and :prop_tgt:`DEBUG_POSTFIX` target
|
||||
properties can also be considered.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE_PREFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Prefix of the library file used to link target ``tgt``.
|
||||
|
||||
See also the :prop_tgt:`PREFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE_SUFFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Suffix of the library file used to link target ``tgt``.
|
||||
|
||||
The suffix corresponds to the file extension (such as ".a" or ".dylib").
|
||||
|
||||
See also the :prop_tgt:`SUFFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Name of the library file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_LIBRARY_FILE_DIR:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Directory of the library file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
File used when linking to the ``tgt`` target is done using an import
|
||||
file. This will usually be the import file that ``tgt`` represents
|
||||
(``.lib``, ``.tbd``). So, when no import file is involved in the link step,
|
||||
an empty string is returned.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Base name of the import file used to link the target ``tgt``, i.e.
|
||||
:genex:`$<TARGET_LINKER_IMPORT_FILE_NAME:tgt>` without prefix and suffix.
|
||||
For example, if target file name is ``libbase.tbd``, the base name is ``base``.
|
||||
|
||||
See also the :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
|
||||
target properties and their configuration
|
||||
specific variants :prop_tgt:`OUTPUT_NAME_<CONFIG>` and
|
||||
:prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>`.
|
||||
|
||||
The :prop_tgt:`<CONFIG>_POSTFIX` and :prop_tgt:`DEBUG_POSTFIX` target
|
||||
properties can also be considered.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE_PREFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Prefix of the import file used to link target ``tgt``.
|
||||
|
||||
See also the :prop_tgt:`IMPORT_PREFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE_SUFFIX:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Suffix of the import file used to link target ``tgt``.
|
||||
|
||||
The suffix corresponds to the file extension (such as ".lib" or ".tbd").
|
||||
|
||||
See also the :prop_tgt:`IMPORT_SUFFIX` target property.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Name of the import file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_LINKER_IMPORT_FILE_DIR:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Directory of the import file used to link target ``tgt``.
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_SONAME_FILE:tgt>
|
||||
|
||||
File with soname (``.so.3``) where ``tgt`` is the name of a target.
|
||||
|
||||
.. genex:: $<TARGET_SONAME_FILE_NAME:tgt>
|
||||
|
||||
Name of file with soname (``.so.3``).
|
||||
|
@ -1582,11 +1803,35 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
|||
|
||||
.. genex:: $<TARGET_SONAME_FILE_DIR:tgt>
|
||||
|
||||
Directory of with soname (``.so.3``).
|
||||
Directory of file with soname (``.so.3``).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on (see policy :policy:`CMP0112`).
|
||||
|
||||
.. genex:: $<TARGET_SONAME_IMPORT_FILE:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Import file with soname (``.3.tbd``) where ``tgt`` is the name of a target.
|
||||
|
||||
.. genex:: $<TARGET_SONAME_IMPORT_FILE_NAME:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Name of the import file with soname (``.3.tbd``).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_SONAME_IMPORT_FILE_DIR:tgt>
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Directory of the import file with soname (``.3.tbd``).
|
||||
|
||||
Note that ``tgt`` is not added as a dependency of the target this
|
||||
expression is evaluated on.
|
||||
|
||||
.. genex:: $<TARGET_PDB_FILE:tgt>
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
|
|
@ -428,6 +428,7 @@ Variables that Control the Build
|
|||
/variable/CMAKE_DEPENDS_USE_COMPILER
|
||||
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||
/variable/CMAKE_ENABLE_EXPORTS
|
||||
/variable/CMAKE_EXECUTABLE_ENABLE_EXPORTS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG_INIT
|
||||
|
@ -507,6 +508,7 @@ Variables that Control the Build
|
|||
/variable/CMAKE_POSITION_INDEPENDENT_CODE
|
||||
/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
||||
/variable/CMAKE_RUNTIME_OUTPUT_DIRECTORY_CONFIG
|
||||
/variable/CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS
|
||||
/variable/CMAKE_SHARED_LINKER_FLAGS
|
||||
/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG
|
||||
/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG_INIT
|
||||
|
|
|
@ -6,4 +6,7 @@ ARCHIVE_OUTPUT_DIRECTORY
|
|||
.. |CMAKE_XXX_OUTPUT_DIRECTORY| replace:: :variable:`CMAKE_ARCHIVE_OUTPUT_DIRECTORY`
|
||||
.. include:: XXX_OUTPUT_DIRECTORY.txt
|
||||
|
||||
.. |IDEM| replace:: in the same directory
|
||||
.. include:: MACOS_IMPORT_FILES.txt
|
||||
|
||||
See also the :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>` target property.
|
||||
|
|
|
@ -5,4 +5,7 @@ ARCHIVE_OUTPUT_NAME
|
|||
.. |xxx| replace:: archive
|
||||
.. include:: XXX_OUTPUT_NAME.txt
|
||||
|
||||
.. |IDEM| replace:: with the same name
|
||||
.. include:: MACOS_IMPORT_FILES.txt
|
||||
|
||||
See also the :prop_tgt:`ARCHIVE_OUTPUT_NAME_<CONFIG>` target property.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
ENABLE_EXPORTS
|
||||
--------------
|
||||
|
||||
Specify whether an executable exports symbols for loadable modules.
|
||||
Specify whether an executable or a shared library exports symbols.
|
||||
|
||||
Normally an executable does not export any symbols because it is the
|
||||
final program. It is possible for an executable to export symbols to
|
||||
|
@ -28,4 +28,29 @@ varies by platform:
|
|||
automatically bind symbols when the module is loaded.
|
||||
|
||||
This property is initialized by the value of the variable
|
||||
:variable:`CMAKE_ENABLE_EXPORTS` if it is set when a target is created.
|
||||
:variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` if it is set when an executable
|
||||
target is created.
|
||||
|
||||
.. versionadded:: 3.27
|
||||
On macOS, to link with a shared library (standard one as well as framework),
|
||||
a linker import file (e.g. a text-based stubs file, with ``.tbd`` extension)
|
||||
can be used instead of the shared library itself.
|
||||
|
||||
The generation of these linker import files, as well as the consumption, is
|
||||
controlled by this property. When this property is set to true, CMake will
|
||||
generate a ``.tbd`` file for each shared library created by
|
||||
:command:`add_library` command. This allow other targets to use this ``.tbd``
|
||||
file to link to the library with the :command:`target_link_libraries`
|
||||
command.
|
||||
|
||||
.. note::
|
||||
|
||||
For compatibility purpose, this property will be ignored if
|
||||
:prop_tgt:`XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS <XCODE_ATTRIBUTE_<an-attribute>>`
|
||||
target property or the
|
||||
:variable:`CMAKE_XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS <CMAKE_XCODE_ATTRIBUTE_<an-attribute>>`
|
||||
variable is set to ``NO``.
|
||||
|
||||
This property is initialized by the value of the variable
|
||||
:variable:`CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS` if it is set when a shared
|
||||
library target is created.
|
||||
|
|
|
@ -3,7 +3,13 @@ IMPORTED_IMPLIB
|
|||
|
||||
Full path to the import library for an ``IMPORTED`` target.
|
||||
|
||||
Set this to the location of the ``.lib`` part of a Windows DLL, or on
|
||||
AIX set it to an import file created for executables that export symbols
|
||||
(see the :prop_tgt:`ENABLE_EXPORTS` target property).
|
||||
Ignored for non-imported targets.
|
||||
This property may be set:
|
||||
|
||||
* On DLL platforms, to the location of the ``.lib`` part of the DLL.
|
||||
* On AIX, to an import file (e.g. ``.imp``) created for executables that export
|
||||
symbols (see the :prop_tgt:`ENABLE_EXPORTS` target property).
|
||||
* On macOS, to an import file (e.g. ``.tbd``) created for shared libraries (see
|
||||
the :prop_tgt:`ENABLE_EXPORTS` target property). For frameworks this is the
|
||||
location of the ``.tbd`` file symlink just inside the framework folder.
|
||||
|
||||
This property is ignored for non-imported targets.
|
||||
|
|
|
@ -27,5 +27,5 @@ selected and its :prop_tgt:`IMPORTED_LOCATION_<CONFIG>` value used.
|
|||
To get the location of an imported target read one of the :prop_tgt:`LOCATION`
|
||||
or ``LOCATION_<CONFIG>`` properties.
|
||||
|
||||
For platforms with import libraries (e.g. Windows) see also
|
||||
For platforms with import libraries (e.g. Windows, AIX or macOS) see also
|
||||
:prop_tgt:`IMPORTED_IMPLIB`.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
.. note::
|
||||
|
||||
On macOS, this property will be ignored for the linker import files (e.g.
|
||||
``.tbd`` files, see :prop_tgt:`ENABLE_EXPORTS` property for details) when:
|
||||
|
||||
* The :prop_tgt:`FRAMEWORK` is set, because the framework layout cannot be
|
||||
changed.
|
||||
* The :generator:`Xcode` generator is used, due to the limitations and
|
||||
constraints of the ``Xcode`` tool.
|
||||
|
||||
In both cases, the linker import files will be generated |IDEM| as the shared
|
||||
library.
|
|
@ -0,0 +1,6 @@
|
|||
Apple-tbd-files-management
|
||||
--------------------------
|
||||
|
||||
* Support for text-based stubs (i.e. ``.tbd`` files) was added on macOS
|
||||
platform. This capability is managed through the :prop_tgt:`ENABLE_EXPORTS`
|
||||
property.
|
|
@ -8,3 +8,7 @@ Specify whether executables export symbols for loadable modules.
|
|||
This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
|
||||
property for executable targets when they are created by calls to the
|
||||
:command:`add_executable` command. See the property documentation for details.
|
||||
|
||||
This command has been superseded by the
|
||||
:variable:`CMAKE_EXECUTABLE_ENABLE_EXPORTS` command. It is provided for
|
||||
compatibility with older CMake code.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
CMAKE_EXECUTABLE_ENABLE_EXPORTS
|
||||
-------------------------------
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Specify whether executables export symbols for loadable modules.
|
||||
|
||||
This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
|
||||
property for executable targets when they are created by calls to the
|
||||
:command:`add_executable` command. See the property documentation for details.
|
||||
|
||||
This variable supersede the :variable:`CMAKE_ENABLE_EXPORTS` variable.
|
|
@ -0,0 +1,10 @@
|
|||
CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS
|
||||
-----------------------------------
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
Specify whether shared library generates an import file.
|
||||
|
||||
This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
|
||||
property for shared library targets when they are created by calls to the
|
||||
:command:`add_library` command. See the property documentation for details.
|
|
@ -6,6 +6,7 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_RANLIB "@_CMAKE_ASM_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
|
||||
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
|
||||
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@")
|
||||
|
|
|
@ -27,6 +27,7 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_C_COMPILER_RANLIB "@CMAKE_C_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_COMPILER_IS_GNUCC @CMAKE_COMPILER_IS_GNUCC@)
|
||||
set(CMAKE_C_COMPILER_LOADED 1)
|
||||
set(CMAKE_C_COMPILER_WORKS @CMAKE_C_COMPILER_WORKS@)
|
||||
|
|
|
@ -28,6 +28,7 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_CXX_COMPILER_RANLIB "@CMAKE_CXX_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_COMPILER_IS_GNUCXX @CMAKE_COMPILER_IS_GNUCXX@)
|
||||
set(CMAKE_CXX_COMPILER_LOADED 1)
|
||||
set(CMAKE_CXX_COMPILER_WORKS @CMAKE_CXX_COMPILER_WORKS@)
|
||||
|
|
|
@ -165,6 +165,7 @@ else()
|
|||
set(_CMAKE_READELF_NAMES "readelf")
|
||||
set(_CMAKE_DLLTOOL_NAMES "dlltool")
|
||||
set(_CMAKE_ADDR2LINE_NAMES "addr2line")
|
||||
set(_CMAKE_TAPI_NAMES "tapi")
|
||||
|
||||
# Prepend toolchain-specific names.
|
||||
if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL Clang)
|
||||
|
@ -201,7 +202,7 @@ else()
|
|||
list(PREPEND _CMAKE_LINKER_NAMES "armlink")
|
||||
endif()
|
||||
|
||||
list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE)
|
||||
list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE TAPI)
|
||||
endif()
|
||||
|
||||
foreach(_CMAKE_TOOL IN LISTS _CMAKE_TOOL_VARS)
|
||||
|
@ -225,6 +226,20 @@ if(NOT CMAKE_RANLIB)
|
|||
set(CMAKE_RANLIB : CACHE INTERNAL "noop for ranlib")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_TAPI)
|
||||
# try to pick-up from Apple toolchain
|
||||
execute_process(COMMAND xcrun --find tapi
|
||||
OUTPUT_VARIABLE _xcrun_out
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
RESULT_VARIABLE _xcrun_failed)
|
||||
if(NOT _xcrun_failed AND EXISTS "${_xcrun_out}")
|
||||
set_property(CACHE CMAKE_TAPI PROPERTY VALUE "${_xcrun_out}")
|
||||
endif()
|
||||
unset(_xcrun_out)
|
||||
unset(_xcrun_failed)
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_PLATFORM_HAS_INSTALLNAME)
|
||||
find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
|
||||
|
|
|
@ -14,6 +14,7 @@ set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
|
|||
set(CMAKE_AR "@CMAKE_AR@")
|
||||
set(CMAKE_Fortran_COMPILER_AR "@CMAKE_Fortran_COMPILER_AR@")
|
||||
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_Fortran_COMPILER_RANLIB "@CMAKE_Fortran_COMPILER_RANLIB@")
|
||||
set(CMAKE_COMPILER_IS_GNUG77 @CMAKE_COMPILER_IS_GNUG77@)
|
||||
set(CMAKE_Fortran_COMPILER_LOADED 1)
|
||||
|
|
|
@ -58,3 +58,4 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_HIP_COMPILER_RANLIB "@CMAKE_HIP_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
|
|
|
@ -25,6 +25,7 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_OBJC_COMPILER_RANLIB "@CMAKE_OBJC_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_COMPILER_IS_GNUOBJC @CMAKE_COMPILER_IS_GNUOBJC@)
|
||||
set(CMAKE_OBJC_COMPILER_LOADED 1)
|
||||
set(CMAKE_OBJC_COMPILER_WORKS @CMAKE_OBJC_COMPILER_WORKS@)
|
||||
|
|
|
@ -26,6 +26,7 @@ set(CMAKE_RANLIB "@CMAKE_RANLIB@")
|
|||
set(CMAKE_OBJCXX_COMPILER_RANLIB "@CMAKE_OBJCXX_COMPILER_RANLIB@")
|
||||
set(CMAKE_LINKER "@CMAKE_LINKER@")
|
||||
set(CMAKE_MT "@CMAKE_MT@")
|
||||
set(CMAKE_TAPI "@CMAKE_TAPI@")
|
||||
set(CMAKE_COMPILER_IS_GNUOBJCXX @CMAKE_COMPILER_IS_GNUOBJCXX@)
|
||||
set(CMAKE_OBJCXX_COMPILER_LOADED 1)
|
||||
set(CMAKE_OBJCXX_COMPILER_WORKS @CMAKE_OBJCXX_COMPILER_WORKS@)
|
||||
|
|
|
@ -45,6 +45,8 @@ set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
|
|||
set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".tbd" ".so")
|
||||
set(CMAKE_SHARED_MODULE_PREFIX "lib")
|
||||
set(CMAKE_SHARED_MODULE_SUFFIX ".so")
|
||||
set(CMAKE_APPLE_IMPORT_FILE_PREFIX "lib")
|
||||
set(CMAKE_APPLE_IMPORT_FILE_SUFFIX ".tbd")
|
||||
set(CMAKE_MODULE_EXISTS 1)
|
||||
set(CMAKE_DL_LIBS "")
|
||||
if(NOT "${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5")
|
||||
|
@ -108,6 +110,9 @@ foreach(lang C CXX Fortran OBJC OBJCXX)
|
|||
set(CMAKE_${lang}_FRAMEWORK_SEARCH_FLAG -F)
|
||||
endforeach()
|
||||
|
||||
# To generate text-based stubs
|
||||
set(CMAKE_CREATE_TEXT_STUBS "<CMAKE_TAPI> stubify -isysroot <CMAKE_OSX_SYSROOT> -o <TARGET_IMPLIB> <TARGET>")
|
||||
|
||||
# Defines LINK_LIBRARY features for frameworks
|
||||
set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK "LINKER:-framework,<LIBRARY>")
|
||||
set(CMAKE_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "cmState.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
|
||||
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
|
||||
|
|
|
@ -72,6 +72,10 @@ SETUP_LANGUAGE(swift_properties, Swift);
|
|||
std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
|
||||
std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
|
||||
std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
|
||||
std::string const kCMAKE_EXECUTABLE_ENABLE_EXPORTS =
|
||||
"CMAKE_EXECUTABLE_ENABLE_EXPORTS";
|
||||
std::string const kCMAKE_SHARED_LIBRARY_ENABLE_EXPORTS =
|
||||
"CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS";
|
||||
std::string const kCMAKE_HIP_ARCHITECTURES = "CMAKE_HIP_ARCHITECTURES";
|
||||
std::string const kCMAKE_HIP_RUNTIME_LIBRARY = "CMAKE_HIP_RUNTIME_LIBRARY";
|
||||
std::string const kCMAKE_ISPC_INSTRUCTION_SETS = "CMAKE_ISPC_INSTRUCTION_SETS";
|
||||
|
@ -997,6 +1001,8 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
|
|||
vars.insert(kCMAKE_CUDA_ARCHITECTURES);
|
||||
vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
|
||||
vars.insert(kCMAKE_ENABLE_EXPORTS);
|
||||
vars.insert(kCMAKE_EXECUTABLE_ENABLE_EXPORTS);
|
||||
vars.insert(kCMAKE_SHARED_LIBRARY_ENABLE_EXPORTS);
|
||||
vars.insert(kCMAKE_HIP_ARCHITECTURES);
|
||||
vars.insert(kCMAKE_HIP_RUNTIME_LIBRARY);
|
||||
vars.insert(kCMAKE_ISPC_INSTRUCTION_SETS);
|
||||
|
|
|
@ -254,7 +254,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
|
|||
if (target->HasImportLibrary(config)) {
|
||||
std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
|
||||
std::string value =
|
||||
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
|
||||
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact, true);
|
||||
if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
|
||||
target->GetImplibGNUtoMS(config, value, value,
|
||||
"${CMAKE_IMPORT_LIBRARY_SUFFIX}");
|
||||
|
|
|
@ -1063,7 +1063,8 @@ void cmExportFileGenerator::GenerateImportTargetCode(
|
|||
}
|
||||
|
||||
// Mark the imported executable if it has exports.
|
||||
if (target->IsExecutableWithExports()) {
|
||||
if (target->IsExecutableWithExports() ||
|
||||
(target->IsSharedLibraryWithExports() && target->HasImportLibrary(""))) {
|
||||
os << "set_property(TARGET " << targetName
|
||||
<< " PROPERTY ENABLE_EXPORTS 1)\n";
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
|
|||
|
||||
// Append the installed file name.
|
||||
value += cmInstallTargetGenerator::GetInstallFilename(
|
||||
target, config, cmInstallTargetGenerator::NameImplib);
|
||||
target, config, cmInstallTargetGenerator::NameImplibReal);
|
||||
|
||||
// Store the property.
|
||||
properties[prop] = value;
|
||||
|
@ -430,6 +430,19 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
|
|||
properties[prop] = cmJoin(objects, ";");
|
||||
importedLocations.insert(prop);
|
||||
} else {
|
||||
if (target->IsFrameworkOnApple() && target->HasImportLibrary(config)) {
|
||||
// store as well IMPLIB value
|
||||
auto importProp = cmStrCat("IMPORTED_IMPLIB", suffix);
|
||||
auto importValue =
|
||||
cmStrCat(value,
|
||||
cmInstallTargetGenerator::GetInstallFilename(
|
||||
target, config, cmInstallTargetGenerator::NameImplibReal));
|
||||
|
||||
// Store the property.
|
||||
properties[importProp] = importValue;
|
||||
importedLocations.insert(importProp);
|
||||
}
|
||||
|
||||
// Construct the property name.
|
||||
std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
|
||||
|
||||
|
|
|
@ -2658,10 +2658,14 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
|
|||
|
||||
class ArtifactDirTag;
|
||||
class ArtifactLinkerTag;
|
||||
class ArtifactLinkerLibraryTag;
|
||||
class ArtifactLinkerImportTag;
|
||||
class ArtifactNameTag;
|
||||
class ArtifactImportTag;
|
||||
class ArtifactPathTag;
|
||||
class ArtifactPdbTag;
|
||||
class ArtifactSonameTag;
|
||||
class ArtifactSonameImportTag;
|
||||
class ArtifactBundleDirTag;
|
||||
class ArtifactBundleDirNameTag;
|
||||
class ArtifactBundleContentDirTag;
|
||||
|
@ -2770,6 +2774,38 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactSonameImportTag>
|
||||
{
|
||||
static std::string Create(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The target soname file (.so.1).
|
||||
if (target->IsDLLPlatform()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_SONAME_IMPORT_FILE is not allowed "
|
||||
"for DLL target platforms.");
|
||||
return std::string();
|
||||
}
|
||||
if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_SONAME_IMPORT_FILE is allowed only for "
|
||||
"SHARED libraries.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return cmStrCat(target->GetDirectory(
|
||||
context->Config, cmStateEnums::ImportLibraryArtifact),
|
||||
'/',
|
||||
target->GetSOName(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact));
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
|
||||
{
|
||||
|
@ -2817,7 +2853,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
|
|||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The file used to link to the target (.so, .lib, .a).
|
||||
// The file used to link to the target (.so, .lib, .a) or import file
|
||||
// (.lib, .tbd).
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_FILE is allowed only for libraries and "
|
||||
|
@ -2832,6 +2869,55 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerLibraryTag>
|
||||
{
|
||||
static std::string Create(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The file used to link to the target (.dylib, .so, .a).
|
||||
if (!target->IsLinkable() ||
|
||||
target->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_LIBRARY_FILE is allowed only for libraries "
|
||||
"with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!target->IsDLLPlatform() ||
|
||||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
return target->GetFullPath(context->Config,
|
||||
cmStateEnums::RuntimeBinaryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerImportTag>
|
||||
{
|
||||
static std::string Create(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The file used to link to the target (.lib, .tbd).
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_IMPORT_FILE is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFullPath(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
|
||||
{
|
||||
|
@ -2929,6 +3015,21 @@ struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetFilesystemArtifactResultCreator<ArtifactImportTag>
|
||||
{
|
||||
static std::string Create(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* /*unused*/)
|
||||
{
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFullPath(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact, true);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArtifactT>
|
||||
struct TargetFilesystemArtifactResultGetter
|
||||
{
|
||||
|
@ -3054,12 +3155,24 @@ struct TargetFilesystemArtifactNodeGroup
|
|||
static const TargetFilesystemArtifactNodeGroup<ArtifactNameTag>
|
||||
targetNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactImportTag>
|
||||
targetImportNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag>
|
||||
targetLinkerNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerLibraryTag>
|
||||
targetLinkerLibraryNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerImportTag>
|
||||
targetLinkerImportNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactSonameTag>
|
||||
targetSoNameNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactSonameImportTag>
|
||||
targetSoNameImportNodeGroup;
|
||||
|
||||
static const TargetFilesystemArtifactNodeGroup<ArtifactPdbTag>
|
||||
targetPdbNodeGroup;
|
||||
|
||||
|
@ -3098,6 +3211,22 @@ struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetOutputNameArtifactResultGetter<ArtifactImportTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* /*unused*/)
|
||||
{
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetOutputName(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact) +
|
||||
target->GetFilePostfix(context->Config);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
|
||||
{
|
||||
|
@ -3105,7 +3234,8 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
|
|||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The file used to link to the target (.so, .lib, .a).
|
||||
// The library file used to link to the target (.so, .lib, .a) or import
|
||||
// file (.lin, .tbd).
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_FILE_BASE_NAME is allowed only for "
|
||||
|
@ -3121,6 +3251,56 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The library file used to link to the target (.so, .lib, .a).
|
||||
if (!target->IsLinkable() ||
|
||||
target->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_LIBRARY_FILE_BASE_NAME is allowed only for "
|
||||
"libraries with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!target->IsDLLPlatform() ||
|
||||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
return target->GetOutputName(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact) +
|
||||
target->GetFilePostfix(context->Config);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerImportTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
// The import file used to link to the target (.lib, .tbd).
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_IMPORT_FILE_BASE_NAME is allowed only for "
|
||||
"libraries and executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetOutputName(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact) +
|
||||
target->GetFilePostfix(context->Config);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
|
||||
{
|
||||
|
@ -3192,15 +3372,27 @@ struct TargetFileBaseNameArtifact : public TargetArtifactBase
|
|||
|
||||
static const TargetFileBaseNameArtifact<ArtifactNameTag>
|
||||
targetFileBaseNameNode;
|
||||
static const TargetFileBaseNameArtifact<ArtifactImportTag>
|
||||
targetImportFileBaseNameNode;
|
||||
static const TargetFileBaseNameArtifact<ArtifactLinkerTag>
|
||||
targetLinkerFileBaseNameNode;
|
||||
static const TargetFileBaseNameArtifact<ArtifactLinkerLibraryTag>
|
||||
targetLinkerLibraryFileBaseNameNode;
|
||||
static const TargetFileBaseNameArtifact<ArtifactLinkerImportTag>
|
||||
targetLinkerImportFileBaseNameNode;
|
||||
static const TargetFileBaseNameArtifact<ArtifactPdbTag>
|
||||
targetPdbFileBaseNameNode;
|
||||
|
||||
class ArtifactFilePrefixTag;
|
||||
class ArtifactImportFilePrefixTag;
|
||||
class ArtifactLinkerFilePrefixTag;
|
||||
class ArtifactLinkerLibraryFilePrefixTag;
|
||||
class ArtifactLinkerImportFilePrefixTag;
|
||||
class ArtifactFileSuffixTag;
|
||||
class ArtifactImportFileSuffixTag;
|
||||
class ArtifactLinkerFileSuffixTag;
|
||||
class ArtifactLinkerLibraryFileSuffixTag;
|
||||
class ArtifactLinkerImportFileSuffixTag;
|
||||
|
||||
template <typename ArtifactT>
|
||||
struct TargetFileArtifactResultGetter
|
||||
|
@ -3221,6 +3413,20 @@ struct TargetFileArtifactResultGetter<ArtifactFilePrefixTag>
|
|||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactImportFilePrefixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent*)
|
||||
{
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFilePrefix(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
|
@ -3228,9 +3434,10 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
|
|||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_PREFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_FILE_PREFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -3243,6 +3450,52 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
|
|||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFilePrefixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable() ||
|
||||
target->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_LIBRARY_FILE_PREFIX is allowed only for libraries "
|
||||
"with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!target->IsDLLPlatform() ||
|
||||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
return target->GetFilePrefix(context->Config,
|
||||
cmStateEnums::RuntimeBinaryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFilePrefixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_IMPORT_FILE_PREFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFilePrefix(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
|
@ -3253,6 +3506,20 @@ struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
|
|||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactImportFileSuffixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent*)
|
||||
{
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFileSuffix(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
|
@ -3260,9 +3527,10 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
|
|||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_SUFFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_FILE_SUFFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
@ -3274,6 +3542,51 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
|
|||
return target->GetFileSuffix(context->Config, artifact);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFileSuffixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable() ||
|
||||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
::reportError(context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_LIBRARY_FILE_SUFFIX is allowed only for "
|
||||
"libraries with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (!target->IsDLLPlatform() ||
|
||||
target->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
||||
return target->GetFileSuffix(context->Config,
|
||||
cmStateEnums::RuntimeBinaryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFileSuffixTag>
|
||||
{
|
||||
static std::string Get(cmGeneratorTarget* target,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content)
|
||||
{
|
||||
if (!target->IsLinkable()) {
|
||||
::reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"TARGET_LINKER_IMPORT_FILE_SUFFIX is allowed only for libraries and "
|
||||
"executables with ENABLE_EXPORTS.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (target->HasImportLibrary(context->Config)) {
|
||||
return target->GetFileSuffix(context->Config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
return std::string{};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArtifactT>
|
||||
struct TargetFileArtifact : public TargetArtifactBase
|
||||
|
@ -3304,11 +3617,23 @@ struct TargetFileArtifact : public TargetArtifactBase
|
|||
};
|
||||
|
||||
static const TargetFileArtifact<ArtifactFilePrefixTag> targetFilePrefixNode;
|
||||
static const TargetFileArtifact<ArtifactImportFilePrefixTag>
|
||||
targetImportFilePrefixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerFilePrefixTag>
|
||||
targetLinkerFilePrefixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerLibraryFilePrefixTag>
|
||||
targetLinkerLibraryFilePrefixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerImportFilePrefixTag>
|
||||
targetLinkerImportFilePrefixNode;
|
||||
static const TargetFileArtifact<ArtifactFileSuffixTag> targetFileSuffixNode;
|
||||
static const TargetFileArtifact<ArtifactImportFileSuffixTag>
|
||||
targetImportFileSuffixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerFileSuffixTag>
|
||||
targetLinkerFileSuffixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerLibraryFileSuffixTag>
|
||||
targetLinkerLibraryFileSuffixNode;
|
||||
static const TargetFileArtifact<ArtifactLinkerImportFileSuffixTag>
|
||||
targetLinkerImportFileSuffixNode;
|
||||
|
||||
static const struct ShellPathNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
|
@ -3376,23 +3701,52 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
|
|||
{ "CONFIGURATION", &configurationNode },
|
||||
{ "CONFIG", &configurationTestNode },
|
||||
{ "TARGET_FILE", &targetNodeGroup.File },
|
||||
{ "TARGET_IMPORT_FILE", &targetImportNodeGroup.File },
|
||||
{ "TARGET_LINKER_FILE", &targetLinkerNodeGroup.File },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE", &targetLinkerLibraryNodeGroup.File },
|
||||
{ "TARGET_LINKER_IMPORT_FILE", &targetLinkerImportNodeGroup.File },
|
||||
{ "TARGET_SONAME_FILE", &targetSoNameNodeGroup.File },
|
||||
{ "TARGET_SONAME_IMPORT_FILE", &targetSoNameImportNodeGroup.File },
|
||||
{ "TARGET_PDB_FILE", &targetPdbNodeGroup.File },
|
||||
{ "TARGET_FILE_BASE_NAME", &targetFileBaseNameNode },
|
||||
{ "TARGET_IMPORT_FILE_BASE_NAME", &targetImportFileBaseNameNode },
|
||||
{ "TARGET_LINKER_FILE_BASE_NAME", &targetLinkerFileBaseNameNode },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE_BASE_NAME",
|
||||
&targetLinkerLibraryFileBaseNameNode },
|
||||
{ "TARGET_LINKER_IMPORT_FILE_BASE_NAME",
|
||||
&targetLinkerImportFileBaseNameNode },
|
||||
{ "TARGET_PDB_FILE_BASE_NAME", &targetPdbFileBaseNameNode },
|
||||
{ "TARGET_FILE_PREFIX", &targetFilePrefixNode },
|
||||
{ "TARGET_IMPORT_FILE_PREFIX", &targetImportFilePrefixNode },
|
||||
{ "TARGET_LINKER_FILE_PREFIX", &targetLinkerFilePrefixNode },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE_PREFIX",
|
||||
&targetLinkerLibraryFilePrefixNode },
|
||||
{ "TARGET_LINKER_IMPORT_FILE_PREFIX", &targetLinkerImportFilePrefixNode },
|
||||
{ "TARGET_FILE_SUFFIX", &targetFileSuffixNode },
|
||||
{ "TARGET_IMPORT_FILE_SUFFIX", &targetImportFileSuffixNode },
|
||||
{ "TARGET_LINKER_FILE_SUFFIX", &targetLinkerFileSuffixNode },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE_SUFFIX",
|
||||
&targetLinkerLibraryFileSuffixNode },
|
||||
{ "TARGET_LINKER_IMPORT_FILE_SUFFIX", &targetLinkerImportFileSuffixNode },
|
||||
{ "TARGET_FILE_NAME", &targetNodeGroup.FileName },
|
||||
{ "TARGET_IMPORT_FILE_NAME", &targetImportNodeGroup.FileName },
|
||||
{ "TARGET_LINKER_FILE_NAME", &targetLinkerNodeGroup.FileName },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE_NAME",
|
||||
&targetLinkerLibraryNodeGroup.FileName },
|
||||
{ "TARGET_LINKER_IMPORT_FILE_NAME",
|
||||
&targetLinkerImportNodeGroup.FileName },
|
||||
{ "TARGET_SONAME_FILE_NAME", &targetSoNameNodeGroup.FileName },
|
||||
{ "TARGET_SONAME_IMPORT_FILE_NAME",
|
||||
&targetSoNameImportNodeGroup.FileName },
|
||||
{ "TARGET_PDB_FILE_NAME", &targetPdbNodeGroup.FileName },
|
||||
{ "TARGET_FILE_DIR", &targetNodeGroup.FileDir },
|
||||
{ "TARGET_IMPORT_FILE_DIR", &targetImportNodeGroup.FileDir },
|
||||
{ "TARGET_LINKER_FILE_DIR", &targetLinkerNodeGroup.FileDir },
|
||||
{ "TARGET_LINKER_LIBRARY_FILE_DIR",
|
||||
&targetLinkerLibraryNodeGroup.FileDir },
|
||||
{ "TARGET_LINKER_IMPORT_FILE_DIR", &targetLinkerImportNodeGroup.FileDir },
|
||||
{ "TARGET_SONAME_FILE_DIR", &targetSoNameNodeGroup.FileDir },
|
||||
{ "TARGET_SONAME_IMPORT_FILE_DIR", &targetSoNameImportNodeGroup.FileDir },
|
||||
{ "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
|
||||
{ "TARGET_BUNDLE_DIR", &targetBundleDirNode },
|
||||
{ "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
|
||||
|
|
|
@ -458,6 +458,11 @@ std::string const& cmGeneratorTarget::GetSafeProperty(
|
|||
const char* cmGeneratorTarget::GetOutputTargetType(
|
||||
cmStateEnums::ArtifactType artifact) const
|
||||
{
|
||||
if (this->IsFrameworkOnApple() || this->GetGlobalGenerator()->IsXcode()) {
|
||||
// import file (i.e. .tbd file) is always in same location as library
|
||||
artifact = cmStateEnums::RuntimeBinaryArtifact;
|
||||
}
|
||||
|
||||
switch (this->GetType()) {
|
||||
case cmStateEnums::SHARED_LIBRARY:
|
||||
if (this->IsDLLPlatform()) {
|
||||
|
@ -470,9 +475,15 @@ const char* cmGeneratorTarget::GetOutputTargetType(
|
|||
return "ARCHIVE";
|
||||
}
|
||||
} else {
|
||||
// For non-DLL platforms shared libraries are treated as
|
||||
// library targets.
|
||||
return "LIBRARY";
|
||||
switch (artifact) {
|
||||
case cmStateEnums::RuntimeBinaryArtifact:
|
||||
// For non-DLL platforms shared libraries are treated as
|
||||
// library targets.
|
||||
return "LIBRARY";
|
||||
case cmStateEnums::ImportLibraryArtifact:
|
||||
// Library import libraries are treated as archive targets.
|
||||
return "ARCHIVE";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::STATIC_LIBRARY:
|
||||
|
@ -2518,7 +2529,8 @@ bool cmGeneratorTarget::CanGenerateInstallNameDir(
|
|||
return !skip;
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetSOName(const std::string& config) const
|
||||
std::string cmGeneratorTarget::GetSOName(
|
||||
const std::string& config, cmStateEnums::ArtifactType artifact) const
|
||||
{
|
||||
if (this->IsImported()) {
|
||||
// Lookup the imported soname.
|
||||
|
@ -2546,7 +2558,9 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
|
|||
return "";
|
||||
}
|
||||
// Compute the soname that will be built.
|
||||
return this->GetLibraryNames(config).SharedObject;
|
||||
return artifact == cmStateEnums::RuntimeBinaryArtifact
|
||||
? this->GetLibraryNames(config).SharedObject
|
||||
: this->GetLibraryNames(config).ImportLibrary;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -5088,10 +5102,18 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
|
|||
f = cmStrCat(dir, '/', targetNames.PDB);
|
||||
gg->AddToManifest(f);
|
||||
}
|
||||
|
||||
dir = this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
|
||||
if (!targetNames.ImportOutput.empty()) {
|
||||
f = cmStrCat(dir, '/', targetNames.ImportOutput);
|
||||
gg->AddToManifest(f);
|
||||
}
|
||||
if (!targetNames.ImportLibrary.empty()) {
|
||||
f =
|
||||
cmStrCat(this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact),
|
||||
'/', targetNames.ImportLibrary);
|
||||
f = cmStrCat(dir, '/', targetNames.ImportLibrary);
|
||||
gg->AddToManifest(f);
|
||||
}
|
||||
if (!targetNames.ImportReal.empty()) {
|
||||
f = cmStrCat(dir, '/', targetNames.ImportReal);
|
||||
gg->AddToManifest(f);
|
||||
}
|
||||
}
|
||||
|
@ -5211,14 +5233,20 @@ std::string cmGeneratorTarget::NormalGetFullPath(
|
|||
}
|
||||
break;
|
||||
case cmStateEnums::ImportLibraryArtifact:
|
||||
fpath += this->GetFullName(config, cmStateEnums::ImportLibraryArtifact);
|
||||
if (realname) {
|
||||
fpath +=
|
||||
this->NormalGetRealName(config, cmStateEnums::ImportLibraryArtifact);
|
||||
} else {
|
||||
fpath +=
|
||||
this->GetFullName(config, cmStateEnums::ImportLibraryArtifact);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return fpath;
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::NormalGetRealName(
|
||||
const std::string& config) const
|
||||
const std::string& config, cmStateEnums::ArtifactType artifact) const
|
||||
{
|
||||
// This should not be called for imported targets.
|
||||
// TODO: Split cmTarget into a class hierarchy to get compile-time
|
||||
|
@ -5229,12 +5257,13 @@ std::string cmGeneratorTarget::NormalGetRealName(
|
|||
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
|
||||
}
|
||||
|
||||
if (this->GetType() == cmStateEnums::EXECUTABLE) {
|
||||
// Compute the real name that will be built.
|
||||
return this->GetExecutableNames(config).Real;
|
||||
}
|
||||
Names names = this->GetType() == cmStateEnums::EXECUTABLE
|
||||
? this->GetExecutableNames(config)
|
||||
: this->GetLibraryNames(config);
|
||||
|
||||
// Compute the real name that will be built.
|
||||
return this->GetLibraryNames(config).Real;
|
||||
return artifact == cmStateEnums::RuntimeBinaryArtifact ? names.Real
|
||||
: names.ImportReal;
|
||||
}
|
||||
|
||||
cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
|
||||
|
@ -5279,17 +5308,16 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
|
|||
// The library name.
|
||||
targetNames.Base = components.base;
|
||||
targetNames.Output =
|
||||
components.prefix + targetNames.Base + components.suffix;
|
||||
cmStrCat(components.prefix, targetNames.Base, components.suffix);
|
||||
|
||||
if (this->IsFrameworkOnApple()) {
|
||||
targetNames.Real = components.prefix;
|
||||
if (!this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
targetNames.Real += "Versions/";
|
||||
targetNames.Real += this->GetFrameworkVersion();
|
||||
targetNames.Real += "/";
|
||||
targetNames.Real +=
|
||||
cmStrCat("Versions/", this->GetFrameworkVersion(), '/');
|
||||
}
|
||||
targetNames.Real += targetNames.Base + components.suffix;
|
||||
targetNames.SharedObject = targetNames.Real + components.suffix;
|
||||
targetNames.Real += cmStrCat(targetNames.Base, components.suffix);
|
||||
targetNames.SharedObject = targetNames.Real;
|
||||
} else {
|
||||
// The library's soname.
|
||||
this->ComputeVersionedName(targetNames.SharedObject, components.prefix,
|
||||
|
@ -5302,11 +5330,36 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
|
|||
targetNames.Output, version);
|
||||
}
|
||||
|
||||
// The import library name.
|
||||
// The import library names.
|
||||
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->GetType() == cmStateEnums::MODULE_LIBRARY) {
|
||||
targetNames.ImportLibrary =
|
||||
this->GetFullNameInternal(config, cmStateEnums::ImportLibraryArtifact);
|
||||
NameComponents const& importComponents =
|
||||
this->GetFullNameInternalComponents(config,
|
||||
cmStateEnums::ImportLibraryArtifact);
|
||||
targetNames.ImportOutput = cmStrCat(
|
||||
importComponents.prefix, importComponents.base, importComponents.suffix);
|
||||
|
||||
if (this->IsFrameworkOnApple() && this->IsSharedLibraryWithExports()) {
|
||||
targetNames.ImportReal = components.prefix;
|
||||
if (!this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
targetNames.ImportReal +=
|
||||
cmStrCat("Versions/", this->GetFrameworkVersion(), '/');
|
||||
}
|
||||
targetNames.ImportReal +=
|
||||
cmStrCat(importComponents.base, importComponents.suffix);
|
||||
targetNames.ImportLibrary = targetNames.ImportOutput;
|
||||
} else {
|
||||
// The import library's soname.
|
||||
this->ComputeVersionedName(
|
||||
targetNames.ImportLibrary, importComponents.prefix,
|
||||
importComponents.base, importComponents.suffix,
|
||||
targetNames.ImportOutput, soversion);
|
||||
|
||||
// The import library's real name on disk.
|
||||
this->ComputeVersionedName(
|
||||
targetNames.ImportReal, importComponents.prefix, importComponents.base,
|
||||
importComponents.suffix, targetNames.ImportOutput, version);
|
||||
}
|
||||
}
|
||||
|
||||
// The program database file name.
|
||||
|
@ -5368,6 +5421,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
|
|||
// The import library name.
|
||||
targetNames.ImportLibrary =
|
||||
this->GetFullNameInternal(config, cmStateEnums::ImportLibraryArtifact);
|
||||
targetNames.ImportReal = targetNames.ImportLibrary;
|
||||
targetNames.ImportOutput = targetNames.ImportLibrary;
|
||||
|
||||
// The program database file name.
|
||||
targetNames.PDB = this->GetPDBName(config);
|
||||
|
@ -5449,15 +5504,18 @@ cmGeneratorTarget::GetFullNameInternalComponents(
|
|||
}
|
||||
|
||||
// Compute the full name for main target types.
|
||||
const std::string configPostfix = this->GetFilePostfix(config);
|
||||
std::string configPostfix = this->GetFilePostfix(config);
|
||||
|
||||
// frameworks have directory prefix but no suffix
|
||||
// frameworks have directory prefix
|
||||
std::string fw_prefix;
|
||||
if (this->IsFrameworkOnApple()) {
|
||||
fw_prefix =
|
||||
cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/');
|
||||
targetPrefix = cmValue(fw_prefix);
|
||||
targetSuffix = nullptr;
|
||||
if (!isImportedLibraryArtifact) {
|
||||
// no suffix
|
||||
targetSuffix = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->IsCFBundleOnApple()) {
|
||||
|
@ -5476,8 +5534,8 @@ cmGeneratorTarget::GetFullNameInternalComponents(
|
|||
// When using Xcode, the postfix should be part of the suffix rather than
|
||||
// the base, because the suffix ends up being used in Xcode's
|
||||
// EXECUTABLE_SUFFIX attribute.
|
||||
if (this->IsFrameworkOnApple() &&
|
||||
this->GetGlobalGenerator()->GetName() == "Xcode") {
|
||||
if (this->IsFrameworkOnApple() && this->GetGlobalGenerator()->IsXcode()) {
|
||||
configPostfix += *targetSuffix;
|
||||
targetSuffix = cmValue(configPostfix);
|
||||
} else {
|
||||
outBase += configPostfix;
|
||||
|
@ -8544,15 +8602,35 @@ bool cmGeneratorTarget::IsExecutableWithExports() const
|
|||
return this->Target->IsExecutableWithExports();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::IsSharedLibraryWithExports() const
|
||||
{
|
||||
return this->Target->IsSharedLibraryWithExports();
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const
|
||||
{
|
||||
bool generate_Stubs = true;
|
||||
if (this->GetGlobalGenerator()->IsXcode()) {
|
||||
// take care of CMAKE_XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS variable
|
||||
// as well as XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS property
|
||||
if (cmValue propGenStubs =
|
||||
this->GetProperty("XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS")) {
|
||||
generate_Stubs = propGenStubs == "YES";
|
||||
} else if (cmValue varGenStubs = this->Makefile->GetDefinition(
|
||||
"CMAKE_XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS")) {
|
||||
generate_Stubs = varGenStubs == "YES";
|
||||
}
|
||||
}
|
||||
|
||||
return (this->IsDLLPlatform() &&
|
||||
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
this->IsExecutableWithExports()) &&
|
||||
// Assemblies which have only managed code do not have
|
||||
// import libraries.
|
||||
this->GetManagedType(config) != ManagedType::Managed) ||
|
||||
(this->IsAIX() && this->IsExecutableWithExports());
|
||||
(this->IsAIX() && this->IsExecutableWithExports()) ||
|
||||
(this->Makefile->PlatformSupportsAppleTextStubs() &&
|
||||
this->IsSharedLibraryWithExports() && generate_Stubs);
|
||||
}
|
||||
|
||||
bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
|
||||
|
|
|
@ -273,7 +273,9 @@ public:
|
|||
std::string NormalGetFullPath(const std::string& config,
|
||||
cmStateEnums::ArtifactType artifact,
|
||||
bool realname) const;
|
||||
std::string NormalGetRealName(const std::string& config) const;
|
||||
std::string NormalGetRealName(const std::string& config,
|
||||
cmStateEnums::ArtifactType artifact =
|
||||
cmStateEnums::RuntimeBinaryArtifact) const;
|
||||
|
||||
/** Get the names of an object library's object files underneath
|
||||
its object file directory. */
|
||||
|
@ -348,7 +350,9 @@ public:
|
|||
const std::string* GetExportMacro() const;
|
||||
|
||||
/** Get the soname of the target. Allowed only for a shared library. */
|
||||
std::string GetSOName(const std::string& config) const;
|
||||
std::string GetSOName(const std::string& config,
|
||||
cmStateEnums::ArtifactType artifact =
|
||||
cmStateEnums::RuntimeBinaryArtifact) const;
|
||||
|
||||
struct NameComponents
|
||||
{
|
||||
|
@ -740,6 +744,8 @@ public:
|
|||
std::string Base;
|
||||
std::string Output;
|
||||
std::string Real;
|
||||
std::string ImportOutput;
|
||||
std::string ImportReal;
|
||||
std::string ImportLibrary;
|
||||
std::string PDB;
|
||||
std::string SharedObject;
|
||||
|
@ -786,6 +792,10 @@ public:
|
|||
|
||||
bool IsExecutableWithExports() const;
|
||||
|
||||
/* Return whether this target is a shared library with capability to generate
|
||||
* a file describing symbols exported (for example, .tbd file on Apple). */
|
||||
bool IsSharedLibraryWithExports() const;
|
||||
|
||||
/** Return whether or not the target has a DLL import library. */
|
||||
bool HasImportLibrary(std::string const& config) const;
|
||||
|
||||
|
|
|
@ -1270,6 +1270,10 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
|
|||
}
|
||||
CM_FALLTHROUGH;
|
||||
case cmStateEnums::EXECUTABLE: {
|
||||
if (target->IsApple() && target->HasImportLibrary(config)) {
|
||||
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
|
||||
config, cmStateEnums::ImportLibraryArtifact, realname)));
|
||||
}
|
||||
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
|
||||
config, cmStateEnums::RuntimeBinaryArtifact, realname)));
|
||||
break;
|
||||
|
|
|
@ -1739,7 +1739,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
|
|||
std::string str_so_file =
|
||||
cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
|
||||
std::string str_link_file =
|
||||
cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
|
||||
cmStrCat("$<TARGET_LINKER_LIBRARY_FILE:", gtgt->GetName(), '>');
|
||||
cmCustomCommandLines cmd = cmMakeSingleCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
|
||||
str_file, str_so_file, str_link_file });
|
||||
|
@ -1754,6 +1754,27 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
|
|||
postbuild.push_back(std::move(command));
|
||||
}
|
||||
|
||||
if (gtgt->HasImportLibrary("") && !gtgt->IsFrameworkOnApple()) {
|
||||
// create symbolic links for .tbd file
|
||||
std::string file = cmStrCat("$<TARGET_IMPORT_FILE:", gtgt->GetName(), '>');
|
||||
std::string soFile =
|
||||
cmStrCat("$<TARGET_SONAME_IMPORT_FILE:", gtgt->GetName(), '>');
|
||||
std::string linkFile =
|
||||
cmStrCat("$<TARGET_LINKER_IMPORT_FILE:", gtgt->GetName(), '>');
|
||||
cmCustomCommandLines symlink_command = cmMakeSingleCommandLine(
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library", file,
|
||||
soFile, linkFile });
|
||||
|
||||
cmCustomCommand command;
|
||||
command.SetCommandLines(symlink_command);
|
||||
command.SetComment("Creating import symlinks");
|
||||
command.SetWorkingDirectory("");
|
||||
command.SetBacktrace(this->CurrentMakefile->GetBacktrace());
|
||||
command.SetStdPipesUTF8(true);
|
||||
|
||||
postbuild.push_back(std::move(command));
|
||||
}
|
||||
|
||||
cmXCodeObject* legacyCustomCommandsBuildPhase = nullptr;
|
||||
cmXCodeObject* preBuildPhase = nullptr;
|
||||
cmXCodeObject* preLinkPhase = nullptr;
|
||||
|
@ -2682,6 +2703,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
|
|||
|
||||
buildSettings->AddAttribute("LIBRARY_STYLE",
|
||||
this->CreateString("DYNAMIC"));
|
||||
|
||||
if (gtgt->HasImportLibrary(configName)) {
|
||||
// Request .tbd file generation
|
||||
buildSettings->AddAttribute("GENERATE_TEXT_BASED_STUBS",
|
||||
this->CreateString("YES"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cmStateEnums::EXECUTABLE: {
|
||||
|
|
|
@ -553,34 +553,35 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
|
||||
// Enforce argument rules too complex to specify for the
|
||||
// general-purpose parser.
|
||||
if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
|
||||
objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
|
||||
bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
|
||||
if (runtimeArgs.GetNamelinkOnly() || objectArgs.GetNamelinkOnly() ||
|
||||
frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
|
||||
privateHeaderArgs.GetNamelinkOnly() ||
|
||||
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly() ||
|
||||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
|
||||
[](const cmInstallCommandFileSetArguments& fileSetArg)
|
||||
-> bool { return fileSetArg.GetNamelinkOnly(); }) ||
|
||||
cxxModuleBmiArgs.GetNamelinkOnly()) {
|
||||
status.SetError(
|
||||
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
|
||||
"The NAMELINK_ONLY option may be specified only following LIBRARY.");
|
||||
"TARGETS given NAMELINK_ONLY option not in LIBRARY or ARCHIVE group. "
|
||||
"The NAMELINK_ONLY option may be specified only following LIBRARY or "
|
||||
"ARCHIVE.");
|
||||
return false;
|
||||
}
|
||||
if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
|
||||
objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
|
||||
bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
|
||||
if (runtimeArgs.GetNamelinkSkip() || objectArgs.GetNamelinkSkip() ||
|
||||
frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
|
||||
privateHeaderArgs.GetNamelinkSkip() ||
|
||||
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip() ||
|
||||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
|
||||
[](const cmInstallCommandFileSetArguments& fileSetArg)
|
||||
-> bool { return fileSetArg.GetNamelinkSkip(); }) ||
|
||||
cxxModuleBmiArgs.GetNamelinkSkip()) {
|
||||
status.SetError(
|
||||
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
|
||||
"The NAMELINK_SKIP option may be specified only following LIBRARY.");
|
||||
"TARGETS given NAMELINK_SKIP option not in LIBRARY or ARCHIVE group. "
|
||||
"The NAMELINK_SKIP option may be specified only following LIBRARY or "
|
||||
"ARCHIVE.");
|
||||
return false;
|
||||
}
|
||||
if (archiveArgs.HasNamelinkComponent() ||
|
||||
runtimeArgs.HasNamelinkComponent() ||
|
||||
if (runtimeArgs.HasNamelinkComponent() ||
|
||||
objectArgs.HasNamelinkComponent() ||
|
||||
frameworkArgs.HasNamelinkComponent() ||
|
||||
bundleArgs.HasNamelinkComponent() ||
|
||||
|
@ -592,9 +593,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
-> bool { return fileSetArg.HasNamelinkComponent(); }) ||
|
||||
cxxModuleBmiArgs.HasNamelinkComponent()) {
|
||||
status.SetError(
|
||||
"TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. "
|
||||
"The NAMELINK_COMPONENT option may be specified only following "
|
||||
"LIBRARY.");
|
||||
"TARGETS given NAMELINK_COMPONENT option not in LIBRARY or ARCHIVE "
|
||||
"group. The NAMELINK_COMPONENT option may be specified only following "
|
||||
"LIBRARY or ARCHIVE.");
|
||||
return false;
|
||||
}
|
||||
if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) {
|
||||
|
@ -674,6 +675,14 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
} else if (libraryArgs.GetNamelinkSkip()) {
|
||||
namelinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
|
||||
}
|
||||
// Select the mode for installing symlinks to versioned imported libraries.
|
||||
cmInstallTargetGenerator::NamelinkModeType importlinkMode =
|
||||
cmInstallTargetGenerator::NamelinkModeNone;
|
||||
if (archiveArgs.GetNamelinkOnly()) {
|
||||
importlinkMode = cmInstallTargetGenerator::NamelinkModeOnly;
|
||||
} else if (archiveArgs.GetNamelinkSkip()) {
|
||||
importlinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
|
||||
}
|
||||
|
||||
// Check if there is something to do.
|
||||
if (targetList.empty()) {
|
||||
|
@ -725,6 +734,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
bool installsArchive = false;
|
||||
bool installsLibrary = false;
|
||||
bool installsNamelink = false;
|
||||
bool installsImportlink = false;
|
||||
bool installsRuntime = false;
|
||||
bool installsObject = false;
|
||||
bool installsFramework = false;
|
||||
|
@ -742,6 +752,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
std::unique_ptr<cmInstallTargetGenerator> archiveGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> libraryGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> namelinkGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> importlinkGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> runtimeGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> objectGenerator;
|
||||
std::unique_ptr<cmInstallTargetGenerator> frameworkGenerator;
|
||||
|
@ -885,6 +896,32 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
}
|
||||
namelinkOnly =
|
||||
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
|
||||
|
||||
if (target.GetMakefile()->PlatformSupportsAppleTextStubs() &&
|
||||
target.IsSharedLibraryWithExports()) {
|
||||
// Apple .tbd files use the ARCHIVE properties
|
||||
if (!archiveArgs.GetDestination().empty()) {
|
||||
artifactsSpecified = true;
|
||||
}
|
||||
if (importlinkMode !=
|
||||
cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
archiveGenerator = CreateInstallTargetGenerator(
|
||||
target, archiveArgs, true, helper.Makefile->GetBacktrace(),
|
||||
helper.GetLibraryDestination(&archiveArgs));
|
||||
archiveGenerator->SetImportlinkMode(
|
||||
cmInstallTargetGenerator::NamelinkModeSkip);
|
||||
}
|
||||
if (importlinkMode !=
|
||||
cmInstallTargetGenerator::NamelinkModeSkip) {
|
||||
importlinkGenerator = CreateInstallTargetGenerator(
|
||||
target, archiveArgs, true, helper.Makefile->GetBacktrace(),
|
||||
helper.GetLibraryDestination(&archiveArgs), false, true);
|
||||
importlinkGenerator->SetImportlinkMode(
|
||||
cmInstallTargetGenerator::NamelinkModeOnly);
|
||||
}
|
||||
namelinkOnly =
|
||||
(importlinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
|
||||
}
|
||||
}
|
||||
if (runtimeDependencySet && libraryGenerator) {
|
||||
runtimeDependencySet->AddLibrary(libraryGenerator.get());
|
||||
|
@ -1157,6 +1194,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
installsArchive = installsArchive || archiveGenerator;
|
||||
installsLibrary = installsLibrary || libraryGenerator;
|
||||
installsNamelink = installsNamelink || namelinkGenerator;
|
||||
installsImportlink = installsImportlink || importlinkGenerator;
|
||||
installsRuntime = installsRuntime || runtimeGenerator;
|
||||
installsObject = installsObject || objectGenerator;
|
||||
installsFramework = installsFramework || frameworkGenerator;
|
||||
|
@ -1169,6 +1207,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
helper.Makefile->AddInstallGenerator(std::move(archiveGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(namelinkGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(importlinkGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(objectGenerator));
|
||||
helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator));
|
||||
|
@ -1203,6 +1242,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
|
|||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
libraryArgs.GetNamelinkComponent());
|
||||
}
|
||||
if (installsImportlink) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
archiveArgs.GetNamelinkComponent());
|
||||
}
|
||||
if (installsRuntime) {
|
||||
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
|
||||
runtimeArgs.GetComponent());
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/optional>
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
|
@ -40,6 +43,84 @@ std::string computeInstallObjectDir(cmGeneratorTarget* gt,
|
|||
objectDir += gt->GetName();
|
||||
return objectDir;
|
||||
}
|
||||
|
||||
void computeFilesToInstall(
|
||||
cmInstallTargetGenerator::Files& files,
|
||||
cmInstallTargetGenerator::NamelinkModeType namelinkMode,
|
||||
std::string const& fromDirConfig, std::string const& output,
|
||||
std::string const& library, std::string const& real,
|
||||
cm::optional<std::function<void(std::string const&)>> GNUToMS = cm::nullopt)
|
||||
{
|
||||
bool haveNamelink = false;
|
||||
auto convert = [&GNUToMS](std::string const& file) {
|
||||
if (GNUToMS) {
|
||||
(*GNUToMS)(file);
|
||||
}
|
||||
};
|
||||
|
||||
// Library link name.
|
||||
std::string fromName = cmStrCat(fromDirConfig, output);
|
||||
std::string toName = output;
|
||||
|
||||
// Library interface name.
|
||||
std::string fromSOName;
|
||||
std::string toSOName;
|
||||
if (library != output) {
|
||||
haveNamelink = true;
|
||||
fromSOName = cmStrCat(fromDirConfig, library);
|
||||
toSOName = library;
|
||||
}
|
||||
|
||||
// Library implementation name.
|
||||
std::string fromRealName;
|
||||
std::string toRealName;
|
||||
if (real != output && real != library) {
|
||||
haveNamelink = true;
|
||||
fromRealName = cmStrCat(fromDirConfig, real);
|
||||
toRealName = real;
|
||||
}
|
||||
|
||||
// Add the names based on the current namelink mode.
|
||||
if (haveNamelink) {
|
||||
files.NamelinkMode = namelinkMode;
|
||||
// With a namelink we need to check the mode.
|
||||
if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
// Install the namelink only.
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
convert(output);
|
||||
} else {
|
||||
// Install the real file if it has its own name.
|
||||
if (!fromRealName.empty()) {
|
||||
files.From.emplace_back(fromRealName);
|
||||
files.To.emplace_back(toRealName);
|
||||
convert(real);
|
||||
}
|
||||
|
||||
// Install the soname link if it has its own name.
|
||||
if (!fromSOName.empty()) {
|
||||
files.From.emplace_back(fromSOName);
|
||||
files.To.emplace_back(toSOName);
|
||||
convert(library);
|
||||
}
|
||||
|
||||
// Install the namelink if it is not to be skipped.
|
||||
if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
convert(output);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Without a namelink there will be only one file. Install it
|
||||
// if this is not a namelink-only rule.
|
||||
if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
convert(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmInstallTargetGenerator::cmInstallTargetGenerator(
|
||||
|
@ -56,6 +137,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator(
|
|||
{
|
||||
this->ActionsPerConfig = true;
|
||||
this->NamelinkMode = NamelinkModeNone;
|
||||
this->ImportlinkMode = NamelinkModeNone;
|
||||
}
|
||||
|
||||
cmInstallTargetGenerator::~cmInstallTargetGenerator() = default;
|
||||
|
@ -247,18 +329,21 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles(
|
|||
this->Target->GetLibraryNames(config);
|
||||
if (this->ImportLibrary) {
|
||||
// There is a bug in cmInstallCommand if this fails.
|
||||
assert(this->NamelinkMode == NamelinkModeNone);
|
||||
assert(this->Target->Makefile->PlatformSupportsAppleTextStubs() ||
|
||||
this->ImportlinkMode == NamelinkModeNone);
|
||||
|
||||
std::string from1 = fromDirConfig + targetNames.ImportLibrary;
|
||||
std::string to1 = targetNames.ImportLibrary;
|
||||
files.From.emplace_back(std::move(from1));
|
||||
files.To.emplace_back(std::move(to1));
|
||||
std::string targetNameImportLib;
|
||||
if (this->Target->GetImplibGNUtoMS(config, targetNames.ImportLibrary,
|
||||
targetNameImportLib)) {
|
||||
files.From.emplace_back(fromDirConfig + targetNameImportLib);
|
||||
files.To.emplace_back(targetNameImportLib);
|
||||
}
|
||||
auto GNUToMS = [this, &config, &files,
|
||||
&fromDirConfig](const std::string& lib) {
|
||||
std::string importLib;
|
||||
if (this->Target->GetImplibGNUtoMS(config, lib, importLib)) {
|
||||
files.From.emplace_back(fromDirConfig + importLib);
|
||||
files.To.emplace_back(importLib);
|
||||
}
|
||||
};
|
||||
|
||||
computeFilesToInstall(
|
||||
files, this->ImportlinkMode, fromDirConfig, targetNames.ImportOutput,
|
||||
targetNames.ImportLibrary, targetNames.ImportReal, GNUToMS);
|
||||
|
||||
// An import library looks like a static library.
|
||||
files.Type = cmInstallType_STATIC_LIBRARY;
|
||||
|
@ -318,66 +403,9 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles(
|
|||
files.From.emplace_back(std::move(from1));
|
||||
files.To.emplace_back(std::move(to1));
|
||||
} else {
|
||||
bool haveNamelink = false;
|
||||
|
||||
// Library link name.
|
||||
std::string fromName = fromDirConfig + targetNames.Output;
|
||||
std::string toName = targetNames.Output;
|
||||
|
||||
// Library interface name.
|
||||
std::string fromSOName;
|
||||
std::string toSOName;
|
||||
if (targetNames.SharedObject != targetNames.Output) {
|
||||
haveNamelink = true;
|
||||
fromSOName = fromDirConfig + targetNames.SharedObject;
|
||||
toSOName = targetNames.SharedObject;
|
||||
}
|
||||
|
||||
// Library implementation name.
|
||||
std::string fromRealName;
|
||||
std::string toRealName;
|
||||
if (targetNames.Real != targetNames.Output &&
|
||||
targetNames.Real != targetNames.SharedObject) {
|
||||
haveNamelink = true;
|
||||
fromRealName = fromDirConfig + targetNames.Real;
|
||||
toRealName = targetNames.Real;
|
||||
}
|
||||
|
||||
// Add the names based on the current namelink mode.
|
||||
if (haveNamelink) {
|
||||
files.NamelinkMode = this->NamelinkMode;
|
||||
// With a namelink we need to check the mode.
|
||||
if (this->NamelinkMode == NamelinkModeOnly) {
|
||||
// Install the namelink only.
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
} else {
|
||||
// Install the real file if it has its own name.
|
||||
if (!fromRealName.empty()) {
|
||||
files.From.emplace_back(fromRealName);
|
||||
files.To.emplace_back(toRealName);
|
||||
}
|
||||
|
||||
// Install the soname link if it has its own name.
|
||||
if (!fromSOName.empty()) {
|
||||
files.From.emplace_back(fromSOName);
|
||||
files.To.emplace_back(toSOName);
|
||||
}
|
||||
|
||||
// Install the namelink if it is not to be skipped.
|
||||
if (this->NamelinkMode != NamelinkModeSkip) {
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Without a namelink there will be only one file. Install it
|
||||
// if this is not a namelink-only rule.
|
||||
if (this->NamelinkMode != NamelinkModeOnly) {
|
||||
files.From.emplace_back(fromName);
|
||||
files.To.emplace_back(toName);
|
||||
}
|
||||
}
|
||||
computeFilesToInstall(files, this->NamelinkMode, fromDirConfig,
|
||||
targetNames.Output, targetNames.SharedObject,
|
||||
targetNames.Real);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,6 +453,12 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
|
|||
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
|
||||
fname = targetNames.ImportLibrary;
|
||||
}
|
||||
} else if (nameType == NameImplibReal) {
|
||||
// Use the import library name.
|
||||
if (!target->GetImplibGNUtoMS(config, targetNames.ImportReal, fname,
|
||||
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
|
||||
fname = targetNames.ImportReal;
|
||||
}
|
||||
} else if (nameType == NameReal) {
|
||||
// Use the canonical name.
|
||||
fname = targetNames.Real;
|
||||
|
@ -434,11 +468,14 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
|
|||
}
|
||||
} else {
|
||||
cmGeneratorTarget::Names targetNames = target->GetLibraryNames(config);
|
||||
if (nameType == NameImplib) {
|
||||
if (nameType == NameImplib || nameType == NameImplibReal) {
|
||||
const auto& importName = nameType == NameImplib
|
||||
? targetNames.ImportLibrary
|
||||
: targetNames.ImportReal;
|
||||
// Use the import library name.
|
||||
if (!target->GetImplibGNUtoMS(config, targetNames.ImportLibrary, fname,
|
||||
if (!target->GetImplibGNUtoMS(config, importName, fname,
|
||||
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
|
||||
fname = targetNames.ImportLibrary;
|
||||
fname = importName;
|
||||
}
|
||||
} else if (nameType == NameSO) {
|
||||
// Use the soname.
|
||||
|
|
|
@ -39,6 +39,10 @@ public:
|
|||
NamelinkModeSkip
|
||||
};
|
||||
void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; }
|
||||
void SetImportlinkMode(NamelinkModeType mode)
|
||||
{
|
||||
this->ImportlinkMode = mode;
|
||||
}
|
||||
|
||||
std::string GetInstallFilename(const std::string& config) const;
|
||||
|
||||
|
@ -50,7 +54,8 @@ public:
|
|||
NameNormal,
|
||||
NameImplib,
|
||||
NameSO,
|
||||
NameReal
|
||||
NameReal,
|
||||
NameImplibReal
|
||||
};
|
||||
|
||||
static std::string GetInstallFilename(const cmGeneratorTarget* target,
|
||||
|
@ -121,6 +126,7 @@ protected:
|
|||
cmGeneratorTarget* Target = nullptr;
|
||||
std::string const FilePermissions;
|
||||
NamelinkModeType NamelinkMode;
|
||||
NamelinkModeType ImportlinkMode;
|
||||
bool const ImportLibrary;
|
||||
bool const Optional;
|
||||
};
|
||||
|
|
|
@ -85,6 +85,7 @@ static auto ruleReplaceVars = { "CMAKE_${LANG}_COMPILER",
|
|||
"CMAKE_RANLIB",
|
||||
"CMAKE_LINKER",
|
||||
"CMAKE_MT",
|
||||
"CMAKE_TAPI",
|
||||
"CMAKE_CUDA_HOST_COMPILER",
|
||||
"CMAKE_CUDA_HOST_LINK_LAUNCHER",
|
||||
"CMAKE_CL_SHOWINCLUDES_PREFIX" };
|
||||
|
@ -134,6 +135,13 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
|
|||
this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
|
||||
}
|
||||
|
||||
// OSX SYSROOT can be required by some tools, like tapi
|
||||
{
|
||||
cmValue osxSysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
|
||||
this->VariableMappings["CMAKE_OSX_SYSROOT"] =
|
||||
osxSysroot.IsEmpty() ? "/" : this->EscapeForShell(*osxSysroot, true);
|
||||
}
|
||||
|
||||
if (cmValue appleArchSysroots =
|
||||
this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) {
|
||||
std::string const& appleArchs =
|
||||
|
|
|
@ -2493,6 +2493,11 @@ bool cmMakefile::PlatformIsAppleEmbedded() const
|
|||
return this->GetAppleSDKType() != AppleSDK::MacOS;
|
||||
}
|
||||
|
||||
bool cmMakefile::PlatformSupportsAppleTextStubs() const
|
||||
{
|
||||
return this->IsOn("APPLE") && this->IsSet("CMAKE_TAPI");
|
||||
}
|
||||
|
||||
const char* cmMakefile::GetSONameFlag(const std::string& language) const
|
||||
{
|
||||
std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
|
||||
|
|
|
@ -562,6 +562,10 @@ public:
|
|||
/** Return whether the target platform is Apple iOS. */
|
||||
bool PlatformIsAppleEmbedded() const;
|
||||
|
||||
/** Return whether the target platform supports generation of text base stubs
|
||||
(.tbd file) describing exports (Apple specific). */
|
||||
bool PlatformSupportsAppleTextStubs() const;
|
||||
|
||||
/** Retrieve soname flag for the specified language if supported */
|
||||
const char* GetSONameFlag(const std::string& language) const;
|
||||
|
||||
|
|
|
@ -465,9 +465,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
|||
std::string outpathImp;
|
||||
if (this->GeneratorTarget->IsFrameworkOnApple()) {
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
cmOSXBundleGenerator::SkipParts bundleSkipParts;
|
||||
if (this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
|
||||
bundleSkipParts.TextStubs = false;
|
||||
}
|
||||
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
|
||||
outpath, this->GetConfigName());
|
||||
outpath, this->GetConfigName(),
|
||||
bundleSkipParts);
|
||||
outpath += '/';
|
||||
if (!this->TargetNames.ImportLibrary.empty()) {
|
||||
outpathImp = this->GeneratorTarget->GetDirectory(
|
||||
this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
|
||||
cmSystemTools::MakeDirectory(outpathImp);
|
||||
outpathImp += '/';
|
||||
}
|
||||
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
|
||||
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
|
||||
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
|
||||
|
@ -679,11 +690,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
|||
}
|
||||
|
||||
// Expand the rule variables.
|
||||
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
this->LocalGenerator->CreateRulePlaceholderExpander());
|
||||
bool useWatcomQuote =
|
||||
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
|
||||
std::vector<std::string> real_link_commands;
|
||||
{
|
||||
bool useWatcomQuote =
|
||||
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
|
||||
|
||||
// Set path conversion for link script shells.
|
||||
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
|
||||
|
||||
|
@ -816,8 +828,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
|||
launcher = cmStrCat(val, ' ');
|
||||
}
|
||||
|
||||
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
this->LocalGenerator->CreateRulePlaceholderExpander());
|
||||
// Construct the main link rule and expand placeholders.
|
||||
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
|
||||
if (useArchiveRules) {
|
||||
|
@ -950,6 +960,86 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
|
|||
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
|
||||
commands, false);
|
||||
|
||||
// Add rule to generate text-based stubs, if required
|
||||
if (this->GeneratorTarget->IsApple() &&
|
||||
this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
|
||||
auto genStubsRule =
|
||||
this->Makefile->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
|
||||
auto genStubs_commands = cmExpandedList(genStubsRule);
|
||||
|
||||
std::string TBDFullPath =
|
||||
cmStrCat(outpathImp, this->TargetNames.ImportOutput);
|
||||
std::string TBDFullPathReal =
|
||||
cmStrCat(outpathImp, this->TargetNames.ImportReal);
|
||||
std::string TBDFullPathSO =
|
||||
cmStrCat(outpathImp, this->TargetNames.ImportLibrary);
|
||||
|
||||
// Expand placeholders.
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
std::string target = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal),
|
||||
cmOutputConverter::SHELL, useWatcomQuote);
|
||||
vars.Target = target.c_str();
|
||||
std::string TBDOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathReal),
|
||||
cmOutputConverter::SHELL, useWatcomQuote);
|
||||
rulePlaceholderExpander->SetTargetImpLib(TBDOutPathReal);
|
||||
for (std::string& command : genStubs_commands) {
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
|
||||
command, vars);
|
||||
}
|
||||
outputs.clear();
|
||||
outputs.push_back(TBDFullPathReal);
|
||||
if (this->TargetNames.ImportLibrary != this->TargetNames.ImportReal) {
|
||||
outputs.push_back(TBDFullPathSO);
|
||||
}
|
||||
if (this->TargetNames.ImportOutput != this->TargetNames.ImportLibrary &&
|
||||
this->TargetNames.ImportOutput != this->TargetNames.ImportReal) {
|
||||
outputs.push_back(TBDFullPath);
|
||||
}
|
||||
this->ExtraFiles.insert(TBDFullPath);
|
||||
|
||||
depends.clear();
|
||||
depends.push_back(targetFullPathReal);
|
||||
|
||||
// Add a rule to create necessary symlinks for the library.
|
||||
// Frameworks are handled by cmOSXBundleGenerator.
|
||||
if (TBDFullPath != TBDFullPathReal &&
|
||||
!this->GeneratorTarget->IsFrameworkOnApple()) {
|
||||
auto TBDOutPathSO = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathSO),
|
||||
cmOutputConverter::SHELL, useWatcomQuote);
|
||||
auto TBDOutPath = this->LocalGenerator->ConvertToOutputFormat(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPath),
|
||||
cmOutputConverter::SHELL, useWatcomQuote);
|
||||
|
||||
std::string symlink =
|
||||
cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_library ", TBDOutPathReal,
|
||||
' ', TBDOutPathSO, ' ', TBDOutPath);
|
||||
commands1.push_back(std::move(symlink));
|
||||
this->LocalGenerator->CreateCDCommand(
|
||||
commands1, this->Makefile->GetCurrentBinaryDirectory(),
|
||||
this->LocalGenerator->GetBinaryDirectory());
|
||||
cm::append(genStubs_commands, commands1);
|
||||
commands1.clear();
|
||||
}
|
||||
|
||||
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
|
||||
genStubs_commands, false);
|
||||
|
||||
// clean actions for apple specific outputs
|
||||
// clean actions for ImportLibrary are already specified
|
||||
if (this->TargetNames.ImportReal != this->TargetNames.ImportLibrary) {
|
||||
libCleanFiles.insert(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathReal));
|
||||
}
|
||||
if (this->TargetNames.ImportOutput != this->TargetNames.ImportReal &&
|
||||
this->TargetNames.ImportOutput != this->TargetNames.ImportLibrary) {
|
||||
libCleanFiles.insert(
|
||||
this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPath));
|
||||
}
|
||||
}
|
||||
|
||||
// Write the main driver rule to build everything in this target.
|
||||
this->WriteTargetDriverRule(targetFullPath, relink);
|
||||
|
||||
|
|
|
@ -204,6 +204,15 @@ std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaFatbinaryRule(
|
|||
'_', config);
|
||||
}
|
||||
|
||||
std::string cmNinjaNormalTargetGenerator::TextStubsGeneratorRule(
|
||||
const std::string& config) const
|
||||
{
|
||||
return cmStrCat(
|
||||
"TEXT_STUBS_GENERATOR__",
|
||||
cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
|
||||
'_', config);
|
||||
}
|
||||
|
||||
struct cmNinjaRemoveNoOpCommands
|
||||
{
|
||||
bool operator()(std::string const& cmd)
|
||||
|
@ -527,6 +536,45 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
|
|||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
if (this->GetGeneratorTarget()->IsApple() &&
|
||||
this->GetGeneratorTarget()->HasImportLibrary(config)) {
|
||||
cmNinjaRule rule(this->TextStubsGeneratorRule(config));
|
||||
rule.Comment = cmStrCat("Rule for generating text-based stubs for ",
|
||||
this->GetVisibleTypeName(), '.');
|
||||
rule.Description = "Creating text-based stubs $out";
|
||||
|
||||
std::string cmd =
|
||||
this->GetMakefile()->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
|
||||
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
|
||||
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
|
||||
cmRulePlaceholderExpander::RuleVariables vars;
|
||||
vars.Target = "$in";
|
||||
rulePlaceholderExpander->SetTargetImpLib("$out");
|
||||
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
|
||||
cmd, vars);
|
||||
|
||||
rule.Command =
|
||||
this->GetLocalGenerator()->BuildCommandLine({ cmd }, config, config);
|
||||
this->GetGlobalGenerator()->AddRule(rule);
|
||||
|
||||
if (tgtNames.ImportOutput != tgtNames.ImportReal &&
|
||||
!this->GetGeneratorTarget()->IsFrameworkOnApple()) {
|
||||
cmNinjaRule slRule("CMAKE_SYMLINK_IMPORT_LIBRARY");
|
||||
{
|
||||
std::string cmakeCommand =
|
||||
this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
|
||||
std::string slCmd =
|
||||
cmStrCat(cmakeCommand, " -E cmake_symlink_library $in $SONAME $out");
|
||||
slRule.Command = this->GetLocalGenerator()->BuildCommandLine(
|
||||
{ slCmd }, config, config);
|
||||
}
|
||||
slRule.Description = "Creating import library symlink $out";
|
||||
slRule.Comment = "Rule for creating import library symlink.";
|
||||
this->GetGlobalGenerator()->AddRule(slRule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
|
||||
|
@ -1030,9 +1078,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||
// the current configuration has a postfix. The non-postfix configuration
|
||||
// Info.plist can be used by all the other configurations.
|
||||
if (!postFix.empty()) {
|
||||
bundleSkipParts.infoPlist = true;
|
||||
bundleSkipParts.InfoPlist = true;
|
||||
}
|
||||
}
|
||||
if (gt->HasImportLibrary(config)) {
|
||||
bundleSkipParts.TextStubs = false;
|
||||
}
|
||||
|
||||
this->OSXBundleGenerator->CreateFramework(
|
||||
tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
|
||||
|
@ -1214,7 +1265,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||
|
||||
cmGlobalNinjaGenerator::CCOutputs byproducts(this->GetGlobalGenerator());
|
||||
|
||||
if (!tgtNames.ImportLibrary.empty()) {
|
||||
if (!gt->IsApple() && !tgtNames.ImportLibrary.empty()) {
|
||||
const std::string impLibPath = localGen.ConvertToOutputFormat(
|
||||
targetOutputImplib, cmOutputConverter::SHELL);
|
||||
vars["TARGET_IMPLIB"] = impLibPath;
|
||||
|
@ -1471,6 +1522,55 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
|
|||
// Add aliases for the file name and the target name.
|
||||
globalGen->AddTargetAlias(tgtNames.Output, gt, config);
|
||||
globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
|
||||
|
||||
if (this->GetGeneratorTarget()->IsApple() &&
|
||||
this->GetGeneratorTarget()->HasImportLibrary(config)) {
|
||||
auto dirTBD =
|
||||
gt->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
|
||||
auto targetTBD =
|
||||
this->ConvertToNinjaPath(cmStrCat(dirTBD, '/', tgtNames.ImportReal));
|
||||
this->EnsureParentDirectoryExists(targetTBD);
|
||||
cmNinjaBuild build(this->TextStubsGeneratorRule(config));
|
||||
build.Comment = cmStrCat("Generate the text-based stubs file ", targetTBD);
|
||||
build.Outputs.push_back(targetTBD);
|
||||
build.ExplicitDeps.push_back(targetOutputReal);
|
||||
globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
|
||||
|
||||
if (tgtNames.ImportOutput != tgtNames.ImportReal &&
|
||||
!this->GetGeneratorTarget()->IsFrameworkOnApple()) {
|
||||
auto outputTBD =
|
||||
this->ConvertToNinjaPath(cmStrCat(dirTBD, '/', tgtNames.ImportOutput));
|
||||
std::string const soNameTBD = this->ConvertToNinjaPath(
|
||||
cmStrCat(dirTBD, '/', tgtNames.ImportLibrary));
|
||||
|
||||
cmNinjaBuild slBuild("CMAKE_SYMLINK_IMPORT_LIBRARY");
|
||||
slBuild.Comment = cmStrCat("Create import library symlink ", outputTBD);
|
||||
cmNinjaVars slVars;
|
||||
|
||||
// If one link has to be created.
|
||||
if (targetTBD == soNameTBD || outputTBD == soNameTBD) {
|
||||
slVars["SONAME"] = this->GetLocalGenerator()->ConvertToOutputFormat(
|
||||
soNameTBD, cmOutputConverter::SHELL);
|
||||
} else {
|
||||
slVars["SONAME"].clear();
|
||||
slBuild.Outputs.push_back(soNameTBD);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(soNameTBD);
|
||||
}
|
||||
}
|
||||
slBuild.Outputs.push_back(outputTBD);
|
||||
if (firstForConfig) {
|
||||
globalGen->GetByproductsForCleanTarget(config).push_back(outputTBD);
|
||||
}
|
||||
slBuild.ExplicitDeps.push_back(targetTBD);
|
||||
slBuild.Variables = std::move(slVars);
|
||||
|
||||
globalGen->WriteBuild(this->GetImplFileStream(fileConfig), slBuild);
|
||||
}
|
||||
|
||||
// Add alias for the import file name
|
||||
globalGen->AddTargetAlias(tgtNames.ImportOutput, gt, config);
|
||||
}
|
||||
}
|
||||
|
||||
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
|
||||
|
|
|
@ -25,6 +25,7 @@ private:
|
|||
std::string LanguageLinkerCudaDeviceCompileRule(
|
||||
const std::string& config) const;
|
||||
std::string LanguageLinkerCudaFatbinaryRule(const std::string& config) const;
|
||||
std::string TextStubsGeneratorRule(const std::string& config) const;
|
||||
|
||||
const char* GetVisibleTypeName() const;
|
||||
void WriteLanguagesRules(const std::string& config);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmValue.h"
|
||||
|
||||
class cmSourceFile;
|
||||
|
||||
|
@ -77,7 +78,7 @@ void cmOSXBundleGenerator::CreateFramework(
|
|||
std::string frameworkVersion = this->GT->GetFrameworkVersion();
|
||||
|
||||
std::string name = cmSystemTools::GetFilenameName(targetName);
|
||||
if (!skipParts.infoPlist) {
|
||||
if (!skipParts.InfoPlist) {
|
||||
// Configure the Info.plist file
|
||||
std::string plist = newoutpath;
|
||||
if (!this->Makefile->PlatformIsAppleEmbedded()) {
|
||||
|
@ -120,6 +121,17 @@ void cmOSXBundleGenerator::CreateFramework(
|
|||
cmSystemTools::CreateSymlink(oldName, newName);
|
||||
this->Makefile->AddCMakeOutputFile(newName);
|
||||
|
||||
if (!skipParts.TextStubs) {
|
||||
// foo.tbd -> Versions/Current/foo.tbd
|
||||
cmValue tbdSuffix =
|
||||
this->Makefile->GetDefinition("CMAKE_APPLE_IMPORT_FILE_SUFFIX");
|
||||
oldName = cmStrCat("Versions/Current/", name, tbdSuffix);
|
||||
newName = cmStrCat(contentdir, name, tbdSuffix);
|
||||
cmSystemTools::RemoveFile(newName);
|
||||
cmSystemTools::CreateSymlink(oldName, newName);
|
||||
this->Makefile->AddCMakeOutputFile(newName);
|
||||
}
|
||||
|
||||
// Resources -> Versions/Current/Resources
|
||||
if (this->MacContentFolders->find("Resources") !=
|
||||
this->MacContentFolders->end()) {
|
||||
|
|
|
@ -20,11 +20,10 @@ public:
|
|||
|
||||
struct SkipParts
|
||||
{
|
||||
SkipParts()
|
||||
: infoPlist(false)
|
||||
{
|
||||
}
|
||||
bool infoPlist; // NOLINT(modernize-use-default-member-init)
|
||||
SkipParts() {} // NOLINT(modernize-use-equals-default)
|
||||
|
||||
bool InfoPlist = false;
|
||||
bool TextStubs = true;
|
||||
};
|
||||
|
||||
// create an app bundle at a given root, and return
|
||||
|
@ -35,7 +34,7 @@ public:
|
|||
// create a framework at a given root
|
||||
void CreateFramework(const std::string& targetName, const std::string& root,
|
||||
const std::string& config,
|
||||
const SkipParts& skipParts = SkipParts());
|
||||
const SkipParts& skipParts = SkipParts{});
|
||||
|
||||
// create a cf bundle at a given root
|
||||
void CreateCFBundle(const std::string& targetName, const std::string& root,
|
||||
|
|
|
@ -445,7 +445,7 @@ TargetProperty const StaticTargetProperties[] = {
|
|||
{ "AUTORCC_OPTIONS"_s, IC::CanCompileSources },
|
||||
|
||||
// Linking properties
|
||||
{ "ENABLE_EXPORTS"_s, IC::ExecutableTarget },
|
||||
{ "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
|
||||
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
|
||||
{ "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
|
||||
{ "LINK_SEARCH_END_STATIC"_s, IC::CanCompileSources },
|
||||
|
@ -1031,6 +1031,31 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
|||
defKey += "CMAKE_";
|
||||
auto initProperty = [this, mf, &defKey](const std::string& property,
|
||||
const char* default_value) {
|
||||
// special init for ENABLE_EXPORTS
|
||||
// For SHARED_LIBRARY, only CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS variable
|
||||
// is used
|
||||
// For EXECUTABLE, CMAKE_EXECUTABLE_ENABLE_EXPORTS or else
|
||||
// CMAKE_ENABLE_EXPORTS variables are used
|
||||
if (property == "ENABLE_EXPORTS"_s) {
|
||||
// Replace everything after "CMAKE_"
|
||||
defKey.replace(
|
||||
defKey.begin() + 6, defKey.end(),
|
||||
cmStrCat(this->impl->TargetType == cmStateEnums::EXECUTABLE
|
||||
? "EXECUTABLE"
|
||||
: "SHARED_LIBRARY",
|
||||
'_', property));
|
||||
if (cmValue value = mf->GetDefinition(defKey)) {
|
||||
this->SetProperty(property, value);
|
||||
return;
|
||||
}
|
||||
if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY) {
|
||||
if (default_value) {
|
||||
this->SetProperty(property, default_value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Replace everything after "CMAKE_"
|
||||
defKey.replace(defKey.begin() + 6, defKey.end(), property);
|
||||
if (cmValue value = mf->GetDefinition(defKey)) {
|
||||
|
@ -1205,6 +1230,12 @@ bool cmTarget::IsExecutableWithExports() const
|
|||
this->GetPropertyAsBool("ENABLE_EXPORTS"));
|
||||
}
|
||||
|
||||
bool cmTarget::IsSharedLibraryWithExports() const
|
||||
{
|
||||
return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
|
||||
this->GetPropertyAsBool("ENABLE_EXPORTS"));
|
||||
}
|
||||
|
||||
bool cmTarget::IsFrameworkOnApple() const
|
||||
{
|
||||
return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
|
||||
|
@ -2657,7 +2688,8 @@ const char* cmTarget::GetSuffixVariableInternal(
|
|||
case cmStateEnums::RuntimeBinaryArtifact:
|
||||
return "CMAKE_SHARED_LIBRARY_SUFFIX";
|
||||
case cmStateEnums::ImportLibraryArtifact:
|
||||
return "CMAKE_IMPORT_LIBRARY_SUFFIX";
|
||||
return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_SUFFIX"
|
||||
: "CMAKE_IMPORT_LIBRARY_SUFFIX";
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
|
@ -2698,7 +2730,8 @@ const char* cmTarget::GetPrefixVariableInternal(
|
|||
case cmStateEnums::RuntimeBinaryArtifact:
|
||||
return "CMAKE_SHARED_LIBRARY_PREFIX";
|
||||
case cmStateEnums::ImportLibraryArtifact:
|
||||
return "CMAKE_IMPORT_LIBRARY_PREFIX";
|
||||
return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_PREFIX"
|
||||
: "CMAKE_IMPORT_LIBRARY_PREFIX";
|
||||
}
|
||||
break;
|
||||
case cmStateEnums::MODULE_LIBRARY:
|
||||
|
|
|
@ -221,6 +221,10 @@ public:
|
|||
//! Return whether this target is an executable with symbol exports enabled.
|
||||
bool IsExecutableWithExports() const;
|
||||
|
||||
//! Return whether this target is a shared library with symbol exports
|
||||
//! enabled.
|
||||
bool IsSharedLibraryWithExports() const;
|
||||
|
||||
//! Return whether this target is a shared library Framework on Apple.
|
||||
bool IsFrameworkOnApple() const;
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,12 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY FRAMEWORK TRUE)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
set_property(TARGET foo PROPERTY LIBRARY_OUTPUT_DIRECTORY $<CONFIG>)
|
||||
|
||||
install(TARGETS foo EXPORT foo FRAMEWORK DESTINATION DESTINATION "${CMAKE_BINARY_DIR}/$<CONFIG>")
|
||||
install(EXPORT foo DESTINATION lib/foo NAMESPACE foo-install::)
|
||||
install(FILES foo-config.cmake.in RENAME foo-config.cmake DESTINATION lib/foo)
|
||||
|
||||
export(TARGETS foo NAMESPACE foo-build:: FILE Release/foo.cmake)
|
|
@ -0,0 +1,62 @@
|
|||
enable_language(C)
|
||||
|
||||
find_package(foo REQUIRED CONFIG NO_DEFAULT_PATH)
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo-install::foo)
|
||||
|
||||
get_property(is_framework TARGET foo-install::foo PROPERTY FRAMEWORK)
|
||||
if (NOT is_framework)
|
||||
message(SEND_ERROR "foo-build::foo: FRAMEWORK not set.")
|
||||
endif()
|
||||
get_property(enable_exports TARGET foo-install::foo PROPERTY ENABLE_EXPORTS)
|
||||
if (CAMKE_TAPI AND NOT enable_exports)
|
||||
message(SEND_ERROR "foo-install::foo: ENABLE_EXPORTS not set.")
|
||||
endif()
|
||||
|
||||
get_property(implib TARGET foo-install::foo PROPERTY IMPORTED_IMPLIB_RELEASE)
|
||||
if (CAMKE_TAPI AND NOT implib)
|
||||
message(SEND_ERROR "foo-install::foo: IMPORTED_IMPLIB_RELEASE not set.")
|
||||
endif()
|
||||
if (CAMKE_TAPI AND NOT implib MATCHES "foo.framework/Versions/A/foo.tbd$")
|
||||
message(SEND_ERROR "foo-install::foo: ${implib}: wrong value for IMPORTED_IMPLIB_RELEASE.")
|
||||
endif()
|
||||
|
||||
get_property(location TARGET foo-install::foo PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
if (NOT location)
|
||||
message(SEND_ERROR "foo-install::foo: IMPORTED_LOCATION_RELEASE not set.")
|
||||
endif()
|
||||
if (NOT location MATCHES "foo.framework/Versions/A/foo$")
|
||||
message(SEND_ERROR "foo-install::foo: ${location}: wrong value for IMPORTED_LOCATION_RELEASE.")
|
||||
endif()
|
||||
|
||||
|
||||
include(${foo_BUILD}/foo.cmake)
|
||||
|
||||
add_executable(main2 main.c)
|
||||
target_link_libraries(main2 PRIVATE foo-build::foo)
|
||||
|
||||
get_property(is_framework TARGET foo-build::foo PROPERTY FRAMEWORK)
|
||||
if (NOT is_framework)
|
||||
message(SEND_ERROR "foo-build::foo: FRAMEWORK not set.")
|
||||
endif()
|
||||
get_property(enable_exports TARGET foo-build::foo PROPERTY ENABLE_EXPORTS)
|
||||
if (CAMKE_TAPI AND NOT enable_exports)
|
||||
message(SEND_ERROR "foo-build::foo: ENABLE_EXPORTS not set.")
|
||||
endif()
|
||||
|
||||
get_property(implib TARGET foo-build::foo PROPERTY IMPORTED_IMPLIB_RELEASE)
|
||||
if (CAMKE_TAPI AND NOT implib)
|
||||
message(SEND_ERROR "foo-build::foo: IMPORTED_IMPLIB_RELEASE not set.")
|
||||
endif()
|
||||
if (CAMKE_TAPI AND NOT implib STREQUAL "${foo_BUILD}/foo.framework/Versions/A/foo.tbd")
|
||||
message(SEND_ERROR "foo-build::foo: ${implib}: wrong value for IMPORTED_IMPLIB_RELEASE.")
|
||||
endif()
|
||||
|
||||
get_property(location TARGET foo-build::foo PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
if (NOT location)
|
||||
message(SEND_ERROR "foo-build::foo: IMPORTED_LOCATION_RELEASE not set.")
|
||||
endif()
|
||||
if (NOT location STREQUAL "${foo_BUILD}/foo.framework/Versions/A/foo")
|
||||
message(SEND_ERROR "foo-build::foo: ${location}: wrong value for IMPORTED_LOCATION_RELEASE.")
|
||||
endif()
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/Framework-Release-generated.cmake")
|
|
@ -0,0 +1,59 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
set_property(TARGET foo PROPERTY FRAMEWORK TRUE)
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo)
|
||||
|
||||
|
||||
install(TARGETS foo FRAMEWORK DESTINATION "${CMAKE_BINARY_DIR}/INSTALL")
|
||||
|
||||
# LIBRARY and ARCHIVE should be ignored
|
||||
install(TARGETS foo FRAMEWORK DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2"
|
||||
LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/lib"
|
||||
ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/dev")
|
||||
|
||||
|
||||
set (GENERATE_CONTENT "if (\"${CMAKE_TAPI}\")
|
||||
set (APPLE_TEXT_STUBS_SUPPORTED TRUE)
|
||||
endif()\n\n")
|
||||
|
||||
string (APPEND GENERATE_CONTENT [[
|
||||
macro (CHECK_FILE test_msg path)
|
||||
if (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" not found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (CHECK_SYMLINK test_msg path)
|
||||
if(NOT IS_SYMLINK "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" is not a symbolic link\n")
|
||||
elseif (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" is not a valid symlink\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
check_file("DYLIB file" "$<TARGET_FILE:foo>")
|
||||
check_symlink("Public DYLIB file" "$<TARGET_LINKER_LIBRARY_FILE:foo>")
|
||||
check_file("executable file" "$<TARGET_FILE:main>")
|
||||
|
||||
check_file("Installed DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/foo.framework/Versions/A/$<TARGET_FILE_NAME:foo>")
|
||||
check_symlink("Installed Public DULIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/foo.framework/$<TARGET_FILE_NAME:foo>")
|
||||
check_file("Installed DULIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/foo.framework/Versions/A/$<TARGET_FILE_NAME:foo>")
|
||||
check_symlink("Installed Public DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/foo.framework/$<TARGET_FILE_NAME:foo>")
|
||||
|
||||
if (APPLE_TEXT_STUBS_SUPPORTED)
|
||||
check_file("TBD file" "$<TARGET_IMPORT_FILE:foo>")
|
||||
check_symlink("Public TBD file" "$<TARGET_LINKER_IMPORT_FILE:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/foo.framework/Versions/A/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed Public TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/foo.framework/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/foo.framework/Versions/A/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed Public TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/foo.framework/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
endif()
|
||||
]])
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Framework-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1,12 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
set_property(TARGET foo PROPERTY LIBRARY_OUTPUT_DIRECTORY $<CONFIG>)
|
||||
set_property(TARGET foo PROPERTY ARCHIVE_OUTPUT_DIRECTORY $<CONFIG>)
|
||||
|
||||
install(TARGETS foo EXPORT foo DESTINATION "${CMAKE_BINARY_DIR}/$<CONFIG>")
|
||||
install(EXPORT foo DESTINATION lib/foo NAMESPACE foo-install::)
|
||||
install(FILES foo-config.cmake.in RENAME foo-config.cmake DESTINATION lib/foo)
|
||||
|
||||
export(TARGETS foo NAMESPACE foo-build:: FILE Release/foo.cmake)
|
|
@ -0,0 +1,54 @@
|
|||
enable_language(C)
|
||||
|
||||
find_package(foo REQUIRED CONFIG NO_DEFAULT_PATH)
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo-install::foo)
|
||||
|
||||
get_property(enable_exports TARGET foo-install::foo PROPERTY ENABLE_EXPORTS)
|
||||
if (CMAKE_TAPI AND NOT enable_exports)
|
||||
message(SEND_ERROR "foo-install::foo: ENABLE_EXPORTS not set.")
|
||||
endif()
|
||||
|
||||
get_property(implib TARGET foo-install::foo PROPERTY IMPORTED_IMPLIB_RELEASE)
|
||||
if (CMAKE_TAPI AND NOT implib)
|
||||
message(SEND_ERROR "foo-install::foo: IMPORTED_IMPLIB_RELEASE not set.")
|
||||
endif()
|
||||
if (CMAKE_TAPI AND NOT implib MATCHES "Release/libfoo.tbd$")
|
||||
message(SEND_ERROR "foo-install::foo: ${implib}: wrong value for IMPORTED_IMPLIB_RELEASE.")
|
||||
endif()
|
||||
|
||||
get_property(location TARGET foo-install::foo PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
if (NOT location)
|
||||
message(SEND_ERROR "foo-install::foo: IMPORTED_LOCATION_RELEASE not set.")
|
||||
endif()
|
||||
if (NOT location MATCHES "Release/libfoo.dylib$")
|
||||
message(SEND_ERROR "foo-install::foo: ${location}: wrong value for IMPORTED_LOCATION_RELEASE.")
|
||||
endif()
|
||||
|
||||
|
||||
include(${foo_BUILD}/foo.cmake)
|
||||
|
||||
add_executable(main2 main.c)
|
||||
target_link_libraries(main2 PRIVATE foo-build::foo)
|
||||
|
||||
get_property(enable_exports TARGET foo-build::foo PROPERTY ENABLE_EXPORTS)
|
||||
if (CMAKE_TAPI AND NOT enable_exports)
|
||||
message(SEND_ERROR "foo-build::foo: ENABLE_EXPORTS not set.")
|
||||
endif()
|
||||
|
||||
get_property(implib TARGET foo-build::foo PROPERTY IMPORTED_IMPLIB_RELEASE)
|
||||
if (CMAKE_TAPI AND NOT implib)
|
||||
message(SEND_ERROR "foo-build::foo: IMPORTED_IMPLIB_RELEASE not set.")
|
||||
endif()
|
||||
if (CMAKE_TAPI AND NOT implib STREQUAL "${foo_BUILD}/libfoo.tbd")
|
||||
message(SEND_ERROR "foo-build::foo: ${implib}: wrong value for IMPORTED_IMPLIB_RELEASE.")
|
||||
endif()
|
||||
|
||||
get_property(location TARGET foo-build::foo PROPERTY IMPORTED_LOCATION_RELEASE)
|
||||
if (NOT location)
|
||||
message(SEND_ERROR "foo-build::foo: IMPORTED_LOCATION_RELEASE not set.")
|
||||
endif()
|
||||
if (NOT location STREQUAL "${foo_BUILD}/libfoo.dylib")
|
||||
message(SEND_ERROR "foo-build::foo: ${location}: wrong value for IMPORTED_LOCATION_RELEASE.")
|
||||
endif()
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/LibraryWithOutputs-Release-generated.cmake")
|
|
@ -0,0 +1,52 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
set_property(TARGET foo PROPERTY ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/TBD/$<CONFIG>")
|
||||
set_property(TARGET foo PROPERTY ARCHIVE_OUTPUT_NAME "tbd")
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo)
|
||||
|
||||
|
||||
set (GENERATE_CONTENT "if (\"${CMAKE_TAPI}\")
|
||||
set (APPLE_TEXT_STUBS_SUPPORTED TRUE)
|
||||
endif()\n\n")
|
||||
|
||||
string (APPEND GENERATE_CONTENT [[
|
||||
macro (CHECK_FILE test_msg path)
|
||||
if (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" not found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
check_file("DYLIB file" "$<TARGET_FILE:foo>")
|
||||
check_file("executable file" "$<TARGET_FILE:main>")
|
||||
|
||||
if (APPLE_TEXT_STUBS_SUPPORTED)
|
||||
check_file("TBD file" "$<TARGET_IMPORT_FILE:foo>")
|
||||
]])
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
# ARCHIVE outputs are ignored by this generator
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\n if (NOT \"$<TARGET_IMPORT_FILE_DIR:foo>\" STREQUAL \"${CMAKE_BINARY_DIR}/$<CONFIG>\")
|
||||
string (APPEND RunCMake_TEST_FAILED \"Wrong directory for TBD file: \\\"$<TARGET_IMPORT_FILE_DIR:foo>\\\"\n\")
|
||||
endif()
|
||||
if (NOT \"$<TARGET_IMPORT_FILE_BASE_NAME:foo>\" STREQUAL \"foo\")
|
||||
string (APPEND RunCMake_TEST_FAILED \"Wrong base name for TBD file: \\\"$<TARGET_IMPORT_FILE_BASE_NAME:foo>\\\"\n\")
|
||||
endif()\n")
|
||||
else()
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\n if (NOT \"$<TARGET_IMPORT_FILE_DIR:foo>\" STREQUAL \"${CMAKE_BINARY_DIR}/TBD/$<CONFIG>\")
|
||||
string (APPEND RunCMake_TEST_FAILED \"Wrong directory for TBD file: \\\"$<TARGET_IMPORT_FILE_DIR:foo>\\\"\n\")
|
||||
endif()
|
||||
if (NOT \"$<TARGET_IMPORT_FILE_BASE_NAME:foo>\" STREQUAL \"tbd\")
|
||||
string (APPEND RunCMake_TEST_FAILED \"Wrong base name for TBD file: \\\"$<TARGET_IMPORT_FILE_BASE_NAME:foo>\\\"\n\")
|
||||
endif()\n")
|
||||
endif()
|
||||
string (APPEND GENERATE_CONTENT "endif()\n")
|
||||
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/LibraryWithOutputs-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/LibraryWithVersions-Release-generated.cmake")
|
|
@ -0,0 +1,96 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
set_property (TARGET foo PROPERTY VERSION 2.5.0)
|
||||
set_property (TARGET foo PROPERTY SOVERSION 2.0.0)
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo)
|
||||
|
||||
|
||||
install(TARGETS foo DESTINATION "${CMAKE_BINARY_DIR}/INSTALL" COMPONENT default)
|
||||
|
||||
install(TARGETS foo ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/dev1" NAMELINK_SKIP COMPONENT default)
|
||||
install(TARGETS foo ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/dev2" NAMELINK_ONLY COMPONENT default)
|
||||
|
||||
install(TARGETS foo ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL3"
|
||||
COMPONENT lib3 NAMELINK_COMPONENT dev3)
|
||||
install(TARGETS foo ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL4"
|
||||
COMPONENT lib4 NAMELINK_COMPONENT dev4)
|
||||
|
||||
|
||||
set (GENERATE_CONTENT "if (\"${CMAKE_TAPI}\")
|
||||
set (APPLE_TEXT_STUBS_SUPPORTED TRUE)
|
||||
endif()\n\n")
|
||||
|
||||
string (APPEND GENERATE_CONTENT [[
|
||||
cmake_policy (SET CMP0011 NEW)
|
||||
cmake_policy (SET CMP0057 NEW)
|
||||
|
||||
macro (CHECK_FILE test_msg path)
|
||||
if (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" not found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (CHECK_SYMLINK test_msg path)
|
||||
if (NOT IS_SYMLINK "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" is not a symbolic link\n")
|
||||
elseif (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" not a valid symlink\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (CHECK_NOFILE test_msg path)
|
||||
if (EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" was found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (CHECK_INSTALLED test_msg dir file)
|
||||
file(GLOB installed_files LIST_DIRECTORIES FALSE RELATIVE "${dir}" "${dir}/*")
|
||||
if (NOT "${file}" IN_LIST installed_files)
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${dir}/${file}\" not found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
check_file("DYLIB file" "$<TARGET_FILE:foo>")
|
||||
check_symlink("Linkable DYLIB file" "$<TARGET_LINKER_LIBRARY_FILE:foo>")
|
||||
check_symlink("SONAME DYLIB file" "$<TARGET_SONAME_FILE:foo>")
|
||||
check_file("executable file" "$<TARGET_FILE:main>")
|
||||
|
||||
check_file("Installed DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_FILE_NAME:foo>")
|
||||
check_symlink("Installed Linkable DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_LINKER_LIBRARY_FILE_NAME:foo>")
|
||||
check_symlink("Installed SONAME DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_SONAME_FILE_NAME:foo>")
|
||||
|
||||
if (APPLE_TEXT_STUBS_SUPPORTED)
|
||||
check_file("TBD file" "$<TARGET_IMPORT_FILE:foo>")
|
||||
check_symlink("Linkable TBD file" "$<TARGET_LINKER_IMPORT_FILE:foo>")
|
||||
check_symlink("SONAME TBD file" "$<TARGET_SONAME_IMPORT_FILE:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed Linkable TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_LINKER_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed SONAME TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_SONAME_IMPORT_FILE_NAME:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev1/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed SONAME TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev1/$<TARGET_SONAME_IMPORT_FILE_NAME:foo>")
|
||||
check_nofile("Installed Linkable TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev1/$<TARGET_LINKER_IMPORT_FILE_NAME:foo>")
|
||||
|
||||
check_installed("Installed Linkable TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev2" "$<TARGET_LINKER_IMPORT_FILE_NAME:foo>")
|
||||
check_nofile("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev2/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_nofile("Installed SONAME TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev2/$<TARGET_SONAME_IMPORT_FILE_NAME:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL3/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed SONAME TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL3/$<TARGET_SONAME_IMPORT_FILE_NAME:foo>")
|
||||
check_nofile("Installed Linkable TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL3/$<TARGET_LINKER_IMPORT_FILE_NAME:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL4/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed SONAME TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL4/$<TARGET_SONAME_IMPORT_FILE_NAME:foo>")
|
||||
check_symlink("Installed Linkable TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL4/$<TARGET_LINKER_IMPORT_FILE_NAME:foo>")
|
||||
endif()
|
||||
]])
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/LibraryWithVersions-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1,58 @@
|
|||
include(RunCMake)
|
||||
|
||||
function(build_project test)
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
|
||||
endif()
|
||||
run_cmake(${test})
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
if ("${ARGC}" GREATER "1")
|
||||
# custom install step
|
||||
cmake_language(CALL ${ARGV1})
|
||||
else()
|
||||
run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --config Release)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
build_project(Simple)
|
||||
build_project(Framework)
|
||||
build_project(LibraryWithOutputs)
|
||||
|
||||
|
||||
function(LibraryWithVersions-install)
|
||||
run_cmake_command(LibraryWithVersions-install-component-lib3 ${CMAKE_COMMAND} --install . --config Release --component lib3)
|
||||
run_cmake_command(LibraryWithVersions-install-component-lib4 ${CMAKE_COMMAND} --install . --config Release --component lib4)
|
||||
run_cmake_command(LibraryWithVersions-install-components-dev4 ${CMAKE_COMMAND} --install . --config Release --component dev4)
|
||||
run_cmake_command(LibraryWithVersions-install ${CMAKE_COMMAND} --install . --config Release --component default)
|
||||
endfunction()
|
||||
|
||||
build_project(LibraryWithVersions LibraryWithVersions-install)
|
||||
|
||||
|
||||
function(build_ExportImport_project test)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-export-build)
|
||||
set(CMAKE_INSTALL_PREFIX ${RunCMake_TEST_BINARY_DIR}/root)
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
|
||||
endif()
|
||||
run_cmake(${test}-export)
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${test}-export-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
run_cmake_command(${test}-export-install ${CMAKE_COMMAND} --install . --prefix ${CMAKE_INSTALL_PREFIX} --config Release)
|
||||
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-import-build)
|
||||
set (foo_BUILD "${RunCMake_BINARY_DIR}/${test}-export-build")
|
||||
if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
string (APPEND foo_BUILD "/Release")
|
||||
endif()
|
||||
run_cmake_with_options(${test}-import -Dfoo_DIR=${CMAKE_INSTALL_PREFIX}/lib/foo
|
||||
-Dfoo_BUILD=${RunCMake_BINARY_DIR}/${test}-export-build/Release)
|
||||
run_cmake_command(${test}-import-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
endfunction()
|
||||
|
||||
build_ExportImport_project(Library)
|
||||
build_ExportImport_project(Framework)
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/Simple-Release-generated.cmake")
|
|
@ -0,0 +1,41 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library(foo SHARED foo.c)
|
||||
set_property(TARGET foo PROPERTY ENABLE_EXPORTS TRUE)
|
||||
|
||||
add_executable(main main.c)
|
||||
target_link_libraries(main PRIVATE foo)
|
||||
|
||||
|
||||
install(TARGETS foo DESTINATION "${CMAKE_BINARY_DIR}/INSTALL")
|
||||
|
||||
install(TARGETS foo LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/lib"
|
||||
ARCHIVE DESTINATION "${CMAKE_BINARY_DIR}/INSTALL2/dev")
|
||||
|
||||
|
||||
set (GENERATE_CONTENT "if (\"${CMAKE_TAPI}\")
|
||||
set (APPLE_TEXT_STUBS_SUPPORTED TRUE)
|
||||
endif()\n\n")
|
||||
|
||||
string (APPEND GENERATE_CONTENT [[
|
||||
macro (CHECK_FILE test_msg path)
|
||||
if (NOT EXISTS "${path}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: \"${path}\" not found\n")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
check_file("DYLIB file" "$<TARGET_FILE:foo>")
|
||||
check_file("executable file" "$<TARGET_FILE:main>")
|
||||
|
||||
check_file("Installed DYLIB file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/lib/$<TARGET_FILE_NAME:foo>")
|
||||
|
||||
if (APPLE_TEXT_STUBS_SUPPORTED)
|
||||
check_file("TBD file" "$<TARGET_IMPORT_FILE:foo>")
|
||||
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
check_file("Installed TBD file" "${RunCMake_TEST_BINARY_DIR}/INSTALL2/dev/$<TARGET_IMPORT_FILE_NAME:foo>")
|
||||
endif()
|
||||
]])
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Simple-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1 @@
|
|||
include(${CMAKE_CURRENT_LIST_DIR}/foo.cmake)
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
int foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
extern int foo(void);
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo();
|
||||
}
|
|
@ -357,6 +357,7 @@ add_RunCMake_test(GenEx-DEVICE_LINK)
|
|||
add_RunCMake_test(GenEx-LINK_LIBRARY)
|
||||
add_RunCMake_test(GenEx-LINK_GROUP)
|
||||
add_RunCMake_test(GenEx-TARGET_FILE -DLINKER_SUPPORTS_PDB=${LINKER_SUPPORTS_PDB})
|
||||
add_RunCMake_test(GenEx-TARGET_IMPORT_FILE)
|
||||
add_RunCMake_test(GenEx-GENEX_EVAL)
|
||||
add_RunCMake_test(GenEx-TARGET_PROPERTY)
|
||||
add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS)
|
||||
|
@ -515,6 +516,7 @@ add_RunCMake_test(BundleUtilities)
|
|||
if(APPLE)
|
||||
add_RunCMake_test(INSTALL_NAME_DIR)
|
||||
add_RunCMake_test(MacOSVersions)
|
||||
add_RunCMake_test(AppleTextStubs)
|
||||
endif()
|
||||
|
||||
function(add_RunCMake_test_try_compile)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,21 @@
|
|||
include(RunCMake)
|
||||
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
|
||||
function(run_cmake_with_config test)
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
|
||||
endif()
|
||||
run_cmake(${test})
|
||||
endfunction()
|
||||
|
||||
run_cmake(TARGET_LINKER_IMPORT_FILE-non-valid-target)
|
||||
run_cmake(TARGET_LINKER_LIBRARY_FILE-non-valid-target)
|
||||
run_cmake_with_config(TARGET_IMPORT_FILE)
|
||||
run_cmake_with_config(TARGET_IMPORT_FILE_SUFFIX)
|
||||
|
||||
set (Windows_platforms Windows CYGWIN MSYS)
|
||||
if (NOT CMAKE_HOST_SYSTEM_NAME IN_LIST Windows_platforms)
|
||||
run_cmake(TARGET_SONAME_IMPORT_FILE-non-valid-target)
|
||||
run_cmake_with_config(TARGET_SONAME_IMPORT_FILE)
|
||||
endif()
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/TARGET_IMPORT_FILE-Release-generated.cmake")
|
|
@ -0,0 +1,47 @@
|
|||
enable_language(C)
|
||||
|
||||
set (platforms_with_import Windows CYGWIN MSYS)
|
||||
|
||||
set (GENERATE_CONTENT [[
|
||||
macro (CHECK_VALUE test_msg value expected)
|
||||
if (NOT "${value}" STREQUAL "${expected}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: actual result:\n [${value}]\nbut expected:\n [${expected}]\n")
|
||||
endif()
|
||||
endmacro()
|
||||
]])
|
||||
|
||||
add_library (shared1 SHARED empty.c)
|
||||
add_library (static1 STATIC empty.c)
|
||||
add_executable (exec1 empty.c)
|
||||
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_IMPORT_FILE shared library\" \"$<TARGET_IMPORT_FILE:shared1>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${platforms_with_import}>,$<TARGET_LINKER_IMPORT_FILE:shared1>,>\")
|
||||
check_value (\"TARGET_LINKER_FILE shared library\" \"$<TARGET_LINKER_FILE:shared1>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${platforms_with_import}>,$<TARGET_LINKER_IMPORT_FILE:shared1>,$<TARGET_LINKER_LIBRARY_FILE:shared1>>\")
|
||||
check_value (\"TARGET_IMPORT_FILE static library\" \"$<TARGET_IMPORT_FILE:static1>\" \"\")
|
||||
check_value (\"TARGET_IMPORT_FILE executable\" \"$<TARGET_IMPORT_FILE:exec1>\" \"\")\n")
|
||||
|
||||
|
||||
set(lib_with_import ${platforms_with_import})
|
||||
set(exec_with_import ${platforms_with_import})
|
||||
if (APPLE AND CMAKE_TAPI)
|
||||
list(APPEND lib_with_import Darwin)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
|
||||
list(APPEND exec_with_import "AIX")
|
||||
endif()
|
||||
set(CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS TRUE)
|
||||
set(CMAKE_EXECUTABLE_ENABLE_EXPORTS TRUE)
|
||||
|
||||
add_library (shared2 SHARED empty.c)
|
||||
add_executable (exec2 empty.c)
|
||||
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_IMPORT_FILE shared library\" \"$<TARGET_IMPORT_FILE:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${lib_with_import}>,$<TARGET_LINKER_IMPORT_FILE:shared2>,>\")
|
||||
check_value (\"TARGET_LINKER_FILE shared library\" \"$<TARGET_LINKER_FILE:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${lib_with_import}>,$<TARGET_LINKER_IMPORT_FILE:shared2>,$<TARGET_LINKER_LIBRARY_FILE:shared2>>\")
|
||||
check_value (\"TARGET_IMPORT_FILE executable\" \"$<TARGET_IMPORT_FILE:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${exec_with_import}>,$<TARGET_LINKER_IMPORT_FILE:exec2>,>\")\n")
|
||||
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TARGET_IMPORT_FILE-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/TARGET_IMPORT_FILE_SUFFIX-Release-generated.cmake")
|
|
@ -0,0 +1,44 @@
|
|||
enable_language (C)
|
||||
|
||||
set (platforms_with_import Windows CYGWIN MSYS)
|
||||
|
||||
set (GENERATE_CONTENT [[
|
||||
macro (CHECK_VALUE test_msg value expected)
|
||||
if (NOT "${value}" STREQUAL "${expected}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: actual result:\n [${value}]\nbut expected:\n [${expected}]\n")
|
||||
endif()
|
||||
endmacro()
|
||||
]])
|
||||
|
||||
add_library (shared1 SHARED empty.c)
|
||||
add_library (static1 STATIC empty.c)
|
||||
add_executable (exec1 empty.c)
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_IMPORT_FILE_SUFFIX executable default\" \"$<TARGET_IMPORT_FILE_SUFFIX:exec1>\" \"\")
|
||||
check_value (\"TARGET_IMPORT_FILE_SUFFIX shared default\" \"$<TARGET_IMPORT_FILE_SUFFIX:shared1>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${platforms_with_import}>,$<TARGET_LINKER_IMPORT_FILE_SUFFIX:shared1>,>\")
|
||||
check_value (\"TARGET_FILE_SUFFIX static default\" \"$<TARGET_IMPORT_FILE_SUFFIX:static1>\" \"\")
|
||||
check_value (\"TARGET_IMPORT_FILE_SUFFIX executable default\" \"$<TARGET_IMPORT_FILE_SUFFIX:exec1>\" \"\")\n")
|
||||
|
||||
|
||||
|
||||
if (APPLE AND CMAKE_TAPI)
|
||||
list(APPEND platforms_with_import Darwin)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
|
||||
list(APPEND platforms_with_import AIX)
|
||||
endif()
|
||||
set(CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS TRUE)
|
||||
set(CMAKE_EXECUTABLE_ENABLE_EXPORTS TRUE)
|
||||
|
||||
add_library (shared2 SHARED empty.c)
|
||||
add_executable (exec2 empty.c)
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_IMPORT_FILE_SUFFIX executable default\" \"$<TARGET_IMPORT_FILE_SUFFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${platforms_with_import}>,$<TARGET_LINKER_IMPORT_FILE_SUFFIX:exec2>,>\")
|
||||
check_value (\"TARGET_IMPORT_FILE_SUFFIX shared default\" \"$<TARGET_IMPORT_FILE_SUFFIX:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${platforms_with_import}>,$<TARGET_LINKER_IMPORT_FILE_SUFFIX:shared2>,>\")\n")
|
||||
|
||||
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TARGET_IMPORT_FILE_SUFFIX-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,9 @@
|
|||
CMake Error at TARGET_LINKER_IMPORT_FILE-non-valid-target.cmake:[0-9]+ \(file\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_LINKER_IMPORT_FILE:exe1>
|
||||
|
||||
TARGET_LINKER_IMPORT_FILE is allowed only for libraries and executables
|
||||
with ENABLE_EXPORTS.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
enable_language(C)
|
||||
|
||||
add_executable(exe1 empty.c)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
|
||||
CONTENT "[$<TARGET_LINKER_IMPORT_FILE:exe1>]"
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,9 @@
|
|||
CMake Error at TARGET_LINKER_LIBRARY_FILE-non-valid-target.cmake:[0-9]+ \(file\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_LINKER_LIBRARY_FILE:exe1>
|
||||
|
||||
TARGET_LINKER_LIBRARY_FILE is allowed only for libraries with
|
||||
ENABLE_EXPORTS.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
enable_language(C)
|
||||
|
||||
add_executable(exe1 empty.c)
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
|
||||
CONTENT "[$<TARGET_LINKER_LIBRARY_FILE:exe1>]"
|
||||
)
|
|
@ -0,0 +1 @@
|
|||
include ("${RunCMake_TEST_BINARY_DIR}/TARGET_SONAME_IMPORT_FILE-Release-generated.cmake")
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,8 @@
|
|||
CMake Error at TARGET_SONAME_IMPORT_FILE-non-valid-target.cmake:[0-9]+ \(file\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_SONAME_IMPORT_FILE:static1>
|
||||
|
||||
TARGET_SONAME_IMPORT_FILE is allowed only for SHARED libraries.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
|
@ -0,0 +1,8 @@
|
|||
enable_language(C)
|
||||
|
||||
add_library (static1 STATIC empty.c)
|
||||
set_property (TARGET static1 PROPERTY VERSION 2.5.0)
|
||||
set_property (TARGET static1 PROPERTY SOVERSION 2.0.0)
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test.txt"
|
||||
CONTENT "[$<TARGET_SONAME_IMPORT_FILE:static1>]")
|
|
@ -0,0 +1,32 @@
|
|||
enable_language(C)
|
||||
|
||||
set (GENERATE_CONTENT [[
|
||||
macro (CHECK_VALUE test_msg value expected)
|
||||
if (NOT "${value}" STREQUAL "${expected}")
|
||||
string (APPEND RunCMake_TEST_FAILED "${test_msg}: actual result:\n [${value}]\nbut expected:\n [${expected}]\n")
|
||||
endif()
|
||||
endmacro()
|
||||
]])
|
||||
|
||||
add_library (shared1 SHARED empty.c)
|
||||
set_property (TARGET shared1 PROPERTY VERSION 2.5.0)
|
||||
set_property (TARGET shared1 PROPERTY SOVERSION 2.0.0)
|
||||
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_SONAME_IMPORT_FILE shared library\" \"$<TARGET_SONAME_IMPORT_FILE:shared1>\" \"\")\n")
|
||||
|
||||
|
||||
|
||||
add_library (shared2 SHARED empty.c)
|
||||
set_property(TARGET shared2 PROPERTY ENABLE_EXPORTS ON)
|
||||
set_property (TARGET shared2 PROPERTY VERSION 2.5.0)
|
||||
set_property (TARGET shared2 PROPERTY SOVERSION 2.0.0)
|
||||
|
||||
|
||||
string (APPEND GENERATE_CONTENT
|
||||
"\ncheck_value (\"TARGET_SONAME_IMPORT_FILE shared library\" \"$<TARGET_SONAME_IMPORT_FILE:shared2>\" \"$<$<BOOL:${CMAKE_TAPI}>:$<PATH:REPLACE_EXTENSION,LAST_ONLY,$<TARGET_SONAME_FILE:shared2>,.tbd>>\")\n")
|
||||
|
||||
|
||||
file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TARGET_SONAME_IMPORT_FILE-$<CONFIG>-generated.cmake"
|
||||
CONTENT "${GENERATE_CONTENT}")
|
|
@ -1,5 +1,6 @@
|
|||
^CMake Error at TARGETS-NAMELINK_COMPONENT-bad-all\.cmake:5 \(install\):
|
||||
install TARGETS given NAMELINK_COMPONENT option not in LIBRARY group\. The
|
||||
NAMELINK_COMPONENT option may be specified only following LIBRARY\.
|
||||
install TARGETS given NAMELINK_COMPONENT option not in LIBRARY or ARCHIVE
|
||||
group\. The NAMELINK_COMPONENT option may be specified only following
|
||||
LIBRARY or ARCHIVE\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
^CMake Error at TARGETS-NAMELINK_COMPONENT-bad-exc\.cmake:5 \(install\):
|
||||
install TARGETS given NAMELINK_COMPONENT option not in LIBRARY group\. The
|
||||
NAMELINK_COMPONENT option may be specified only following LIBRARY\.
|
||||
install TARGETS given NAMELINK_COMPONENT option not in LIBRARY or ARCHIVE
|
||||
group\. The NAMELINK_COMPONENT option may be specified only following
|
||||
LIBRARY or ARCHIVE\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
|
|
Loading…
Reference in New Issue