From 6e61bb18e73bd5a57cd45d44351bac5d0f0ad326 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 5 Feb 2024 11:52:54 +0200 Subject: [PATCH] Fix importing TileDB in CMake versions prior to 3.18. (#4671) #4528 introduced a single `TileDB::tiledb`exported CMake target for TileDB with either static or dynamic linkage. For compatibility with previous versions, the targets `TileDB::tiledb_shared` or `TileDB::tiledb_static` were also defined depending on the linkage, as `ALIAS`es to `TileDB::tiledb`. As it turns out however, we cannot use `ALIAS` targets, because they are always declared in the global scope prior to CMake 3.18 and if `find_package(TileDB)` is not called in the top-level `CMakeLists.txt` file, it will fail with `add_library cannot create ALIAS target "TileDB::tiledb_shared" because target "TileDB::tiledb" is imported but not globally visible.`. Nor can we switch to using `IMPORTED INTERFACE` targets and linking them to `TileDB::tiledb`, because it would bring a minor breaking change[^1]. Because `TileDB::tiledb_shared` would become an `INTERFACE` library, it does not have an `IMPORTED_LOCATION` anymore, which would cause [calls to `install_target_libs(TileDB::tiledb_shared)`](https://github.com/TileDB-Inc/TileDB-VCF/blob/5bcc79b07935ac540c56bf6ed9ee0f5d60bf247e/libtiledbvcf/cmake/Modules/FindTileDB_EP.cmake#L121) to fail. Thankfully there is another solution. We set the [`EXPORT_NAME`](https://cmake.org/cmake/help/latest/prop_tgt/EXPORT_NAME.html) of the `tiledb` target to either `tiledb_shared` or `tiledb_static` depending on the linkage, and define `TileDB::tiledb` as an `IMPORTED INTERFACE` target[^2] to the linkage-specific target. This maintains full compatibility. [^1]: Something similar is the "breaking build system change" I talked about in https://github.com/TileDB-Inc/TileDB/pull/4408#issuecomment-1757962838. After removing the `install_target_libs` calls from this repository, the change in Curl did not afffect us and we could update much more easily. [^2]: In this opposite case the unified target _must_ be an `IMPORTED INTERFACE`. We cannot get the `IMPORTED_LOCATION` of `TileDB::tiledb`, but since the target is new this is not a breaking change. --- TYPE: BUILD DESC: Fix importing TileDB in CMake versions prior to 3.18. (cherry picked from commit ad0371fb8cc87abf9aa7c23e053d40b1f87fa80d) --- cmake/inputs/Config.cmake.in | 12 ++++++++---- tiledb/CMakeLists.txt | 9 +++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cmake/inputs/Config.cmake.in b/cmake/inputs/Config.cmake.in index ccea6a22cb3..6723ff3b036 100644 --- a/cmake/inputs/Config.cmake.in +++ b/cmake/inputs/Config.cmake.in @@ -44,10 +44,14 @@ endif() include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") check_required_components("@PROJECT_NAME@") -if(@BUILD_SHARED_LIBS@ AND NOT TARGET TileDB::tiledb_shared) # BUILD_SHARED_LIBS AND NOT TARGET TileDB::tiledb_shared - add_library(TileDB::tiledb_shared ALIAS TileDB::tiledb) -elseif(NOT TARGET TileDB::tiledb_static) - add_library(TileDB::tiledb_static ALIAS TileDB::tiledb) +if(NOT TARGET TileDB::tiledb) + if(TARGET TileDB::tiledb_shared) + add_library(TileDB::tiledb INTERFACE IMPORTED) + set_target_properties(TileDB::tiledb PROPERTIES INTERFACE_LINK_LIBRARIES TileDB::tiledb_shared) + elseif(TARGET TileDB::tiledb_static) + add_library(TileDB::tiledb INTERFACE IMPORTED) + set_target_properties(TileDB::tiledb PROPERTIES INTERFACE_LINK_LIBRARIES TileDB::tiledb_static) + endif() endif() # Define a convenience all-caps variable diff --git a/tiledb/CMakeLists.txt b/tiledb/CMakeLists.txt index a10c5350b4a..a3a96f2a7c6 100644 --- a/tiledb/CMakeLists.txt +++ b/tiledb/CMakeLists.txt @@ -842,6 +842,15 @@ endif() # the value of the BUILD_SHARED_LIBS variable. add_library(tiledb $) +# Export the target as either tiledb_shared or tiledb_static for compatibility. +# The exported config will create the unified tiledb target that links to either +# of them. +if(BUILD_SHARED_LIBS) + set_target_properties(tiledb PROPERTIES EXPORT_NAME tiledb_shared) +else() + set_target_properties(tiledb PROPERTIES EXPORT_NAME tiledb_static) +endif() + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/sm/c_api/tiledb_version.h" ver) string(REGEX MATCH "TILEDB_VERSION_MAJOR ([0-9]*)" _ ${ver})