Browse Source

LINK_LIBRARY: Add features for library support on Apple

Marc Chevrier 3 years ago
parent
commit
9fb1dff070

+ 2 - 2
Help/manual/cmake-generator-expressions.7.rst

@@ -1157,7 +1157,7 @@ Output-Related Expressions
     expression.
 
   The ``library-list`` argument can hold CMake targets or external libraries.
-  Any ``CMake`` target of type :ref:`OBJECT <Object Libraries>` or
+  Any CMake target of type :ref:`OBJECT <Object Libraries>` or
   :ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and
   will be handled in the standard way.
 
@@ -1187,7 +1187,7 @@ Output-Related Expressions
     ``end-group``, as supported by ``GNU ld``, the :genex:`LINK_GROUP`
     generator expression can be used.
 
-  ``CMake`` pre-defines some features of general interest:
+  CMake pre-defines some features of general interest:
 
   .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
 

+ 10 - 0
Help/release/dev/Apple-link-library.rst

@@ -0,0 +1,10 @@
+Apple-link-library
+------------------
+
+* The :genex:`LINK_LIBRARY` generator expression gained the ability to link
+  libraries in various ways when targeting ``Apple`` platforms. The following
+  new features were added:
+
+  * ``NEEDED_LIBRARY``
+  * ``REEXPORT_LIBRARY``
+  * ``WEAK_LIBRARY``

+ 1 - 1
Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst

@@ -22,6 +22,6 @@ features independent from the link language.
 Predefined Features
 ^^^^^^^^^^^^^^^^^^^
 
-``CMake`` pre-defines some features of general interest:
+CMake pre-defines some features of general interest:
 
 .. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt

+ 1 - 1
Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst

@@ -27,6 +27,6 @@ set.
 Predefined Features
 ^^^^^^^^^^^^^^^^^^^
 
-``CMake`` pre-defines some features of general interest:
+CMake pre-defines some features of general interest:
 
 .. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt

+ 30 - 7
Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt

@@ -1,6 +1,7 @@
 **Features available in all environments**
 
-* ``DEFAULT``: This feature enables default link expression. This is mainly
+``DEFAULT``
+  This feature enables default link expression. This is mainly
   useful with :prop_tgt:`LINK_LIBRARY_OVERRIDE` and
   :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties.
 
@@ -9,21 +10,27 @@
 It is assumed that the linker used is the one provided by `XCode` or is
 compatible with it.
 
-* ``FRAMEWORK``: This option tells the linker to search for the specified
+Framework support
+
+``FRAMEWORK``
+  This option tells the linker to search for the specified
   framework (use linker option ``-framework``).
-* ``NEEDED_FRAMEWORK``: This is the same as the ``FRAMEWORK`` feature but means
+``NEEDED_FRAMEWORK``
+  This is the same as the ``FRAMEWORK`` feature but means
   to really link with the framework even if no symbols are used from it (use
   linker option ``-needed_framework``).
-* ``REEXPORT_FRAMEWORK``: This is the same as the ``FRAMEWORK`` feature but
+``REEXPORT_FRAMEWORK``
+  This is the same as the ``FRAMEWORK`` feature but
   also specifies that all symbols in that framework should be available to
   clients linking to the library being created (use linker option
   ``-reexport_framework``).
-* ``WEAK_FRAMEWORK``: This is the same as the ``FRAMEWORK`` feature but forces
+``WEAK_FRAMEWORK``
+  This is the same as the ``FRAMEWORK`` feature but forces
   the framework and all references to it to be marked as weak imports (use
   linker option ``-weak_framework``).
 
-Features for framework linking have a special handling in ``CMake``: the
-framework can be specified as a ``CMake`` framework target or file path. In the
+Features for framework linking have a special handling in CMake: the
+framework can be specified as a CMake framework target or file path. In the
 first case, the target must have the :prop_tgt:`FRAMEWORK` target property set
 as ``TRUE`` to enable framework handling. In the later case, if the path
 includes a directory part, this one will be specified as framework search path
@@ -45,3 +52,19 @@ at link step.
    * (/path/to/)?FwName(.framework)?
    * (/path/to/)?FwName.framework/FwName
    * (/path/to/)?FwName.framework/Versions/\*/FwName
+
+Library support
+
+``NEEDED_LIBRARY``
+  This is the same as specifying a link item (target or
+  library) but means to really link with the item even if no symbols are used
+  from it (use linker option ``-needed_library`` or ``-needed-l``).
+``REEXPORT_LIBRARY``
+  This is the same as specifying a link item (target or
+  library) but also specifies that all symbols in that item should be available
+  to clients linking to the library being created (use linker option
+  ``-reexport_library`` or ``-reexport-l``).
+``WEAK_LIBRARY``
+  This is the same as specifying a link item (target or
+  library) but forces the item and all references to it to be marked as weak
+  imports (use linker option ``-weak_library`` or ``-weak-l``).

+ 10 - 0
Modules/Platform/Darwin.cmake

@@ -121,6 +121,16 @@ set(CMAKE_LINK_LIBRARY_USING_REEXPORT_FRAMEWORK_SUPPORTED TRUE)
 set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK "LINKER:-weak_framework,<LIBRARY>")
 set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK_SUPPORTED TRUE)
 
+# Defines link features for libraries
+set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY "PATH{LINKER:-needed_library <LIBRARY>}NAME{LINKER:-needed-l<LIB_ITEM>}")
+set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY_SUPPORTED TRUE)
+
+set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY "PATH{LINKER:-reexport_library <LIBRARY>}NAME{LINKER:-reexport-l<LIB_ITEM>}")
+set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY_SUPPORTED TRUE)
+
+set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY "PATH{LINKER:-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}")
+set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY_SUPPORTED TRUE)
+
 # default to searching for frameworks first
 if(NOT DEFINED CMAKE_FIND_FRAMEWORK)
   set(CMAKE_FIND_FRAMEWORK FIRST)

+ 6 - 0
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/External/CMakeLists.txt

@@ -0,0 +1,6 @@
+
+cmake_minimum_required(VERSION 3.23)
+
+project(External LANGUAGES C)
+
+add_library(external SHARED ../unref.c)

+ 13 - 0
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/RunCMakeTest.cmake

@@ -97,3 +97,16 @@ if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION GREAT
 
   run_cmake_target(apple_framework target-needed_framework main-target-needed_framework)
 endif()
+
+# Apple library features
+if(APPLE AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang"))
+  run_cmake(apple_library_external)
+  run_cmake_target(apple_library_external build external)
+  run_cmake_with_options(apple_library "-DRunCMake_BINARY_DIR=${RunCMake_BINARY_DIR}")
+  run_cmake_target(apple_library reexport_library main-reexport_library)
+  run_cmake_target(apple_library weak_library main-weak_library)
+endif()
+
+if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION GREATER_EQUAL "12")
+  run_cmake_target(apple_library needed_library main-needed_library)
+endif()

+ 24 - 0
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/apple_library.cmake

@@ -0,0 +1,24 @@
+
+enable_language(C)
+
+add_library(lib SHARED base.c lib.c)
+
+# feature NEEDED_FRAMEWORK
+add_executable(main-needed_library main.c)
+target_link_directories(main-needed_library PRIVATE "${RunCMake_BINARY_DIR}/apple_library_external-build"
+                                                     "${RunCMake_BINARY_DIR}/apple_library_external-build/$<CONFIG>")
+target_link_libraries(main-needed_library PRIVATE "$<LINK_LIBRARY:NEEDED_LIBRARY,lib,external>")
+
+
+# feature REEXPORT_FRAMEWORK
+add_executable(main-reexport_library main.c)
+target_link_directories(main-reexport_library PRIVATE "${RunCMake_BINARY_DIR}/apple_library_external-build"
+                                                      "${RunCMake_BINARY_DIR}/apple_library_external-build/$<CONFIG>")
+target_link_libraries(main-reexport_library PRIVATE "$<LINK_LIBRARY:REEXPORT_LIBRARY,lib,external>")
+
+
+# feature WEAK_FRAMEWORK
+add_executable(main-weak_library main.c)
+target_link_directories(main-weak_library PRIVATE "${RunCMake_BINARY_DIR}/apple_library_external-build"
+                                                  "${RunCMake_BINARY_DIR}/apple_library_external-build/$<CONFIG>")
+target_link_libraries(main-weak_library PRIVATE "$<LINK_LIBRARY:WEAK_LIBRARY,lib,external>")

+ 4 - 0
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/apple_library_external.cmake

@@ -0,0 +1,4 @@
+
+enable_language(C)
+
+add_library(external SHARED unref.c)

+ 1 - 1
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/base.c

@@ -4,6 +4,6 @@
 __declspec(dllexport)
 #  endif
 #endif
-  void base()
+  void base(void)
 {
 }

+ 2 - 2
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/lib.c

@@ -4,12 +4,12 @@
 __declspec(dllimport)
 #  endif
 #endif
-  void base();
+  void base(void);
 
 #if defined(_WIN32)
 __declspec(dllexport)
 #endif
-  void lib()
+  void lib(void)
 {
   base();
 }

+ 3 - 3
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/main.c

@@ -2,14 +2,14 @@
 #if defined(_WIN32)
 __declspec(dllimport)
 #endif
-  void lib();
+  void lib(void);
 
 #if defined(_WIN32)
 __declspec(dllimport)
 #endif
-  void unref();
+  void unref(void);
 
-int main()
+int main(void)
 {
   lib();
   unref();

+ 1 - 1
Tests/RunCMake/target_link_libraries-LINK_LIBRARY/unref.c

@@ -3,6 +3,6 @@
 #if defined(_WIN32)
 __declspec(dllexport)
 #endif
-  void unref()
+  void unref(void)
 {
 }