CMake: как мне избежать получения абсолютных путей в целевых свойствах интерфейса? - PullRequest
0 голосов
/ 25 мая 2020

Общая проблема: Я получаю абсолютные пути в своих свойствах INTERFACE_LINK_LIBRARIES и INTERFACE_INCLUDE_DIRECTORIES для цели, что является проблемой, потому что эти переменные экспортируются через install(EXPORT), что будет означать проблемы, если все перемещено. Я проследил происхождение этих абсолютных путей до команды find_package, которая (для некоторых, но не для всех пакетов) устанавливает такие переменные, как Boost_LIBRARIES, с абсолютными путями. Когда они используются, например, с командой target_link_libraries, они попадают в INTERFACE_LINK_LIBRARIES.

Q: Как мне лучше всего избежать загрязнения экспортируемых целевых свойств абсолютными путями ?

Тривиальное решение, очевидно, состоит в том, чтобы просто перезаписать соответствующие переменные некоторыми строками, которые только называют библиотеки (жестко запрограммированы), но я думаю, должен быть лучший способ.

Specifi c проблема (пример): см. https://github.com/cartographer-project/cartographer/issues/1688


EDIT: My ( изменено) cartographer-config.cmake.in (примечание: вы можете игнорировать материал, связанный с ceres, так как это не доставляет мне проблем, хотя он помещает путь abs в подсказку):

# Copyright 2016 The Cartographer Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#  Usage from an external project:
#    In your CMakeLists.txt, add these lines:
#
#    find_package(cartographer REQUIRED)
#    target_link_libraries(MY_TARGET_NAME PUBLIC cartographer)

@PACKAGE_INIT@

set_and_check(CARTOGRAPHER_CMAKE_DIR "@PACKAGE_CARTOGRAPHER_CMAKE_DIR@")

find_dependency(Boost)
find_dependency(Lua)

set(CERES_DIR_HINTS @Ceres_DIR@)

if (cartographer_FIND_QUIETLY)
   find_package(Ceres QUIET HINTS ${CERES_DIR_HINTS})
elseif (cartographer_FIND_REQUIRED)
   find_package(Ceres REQUIRED HINTS ${CERES_DIR_HINTS})
else ()
   find_package(Ceres HINTS ${CERES_DIR_HINTS})
endif()

include("${CARTOGRAPHER_CMAKE_DIR}/CartographerTargets.cmake")                                                                                  

1 Ответ

1 голос
/ 25 мая 2020

Как лучше всего избежать загрязнения экспортируемых целевых свойств абсолютными путями?

Скрыть абсолютные пути за ИМПОРТИРОВАННОЙ целью:

# Express an external library via IMPORTED target
add_library(lib_external IMPORTED)
set_target_properties(lib_external PROPERTIES
  IMPORTED_LOCATION "${XXX_LIBRARY} (some absolute path)"
  INTERFACE_INCLUDE_DIRECTORIES "${XXX_INCLUDE_DIRECTORIES} (some absolute path)"
)

# Use external library via the target created
target_link_libraries(my_lib lib_external)

Таким образом, файл конфигурации для my_lib будет содержать только имя библиотеки IMPORTED, но не ее свойства.

В файле конфигурации вашего проекта вам просто нужно создать цель IMPORTED с с тем же именем и заполните его свойства в соответствии с текущим компьютером (где ваш проект используется ).

find_package для большинства современных пакетов (включая Boost) уже возвращает IMPORTED target. В файле конфигурации для вашего проекта вы можете использовать find_dependency , который обнаруживает пакет на текущем компьютере и снова создает цель IMPORTED.

Для старых пакетов, find_package просто возвращает XXX_LIBRARIES и XXX_INCLUDE_DIRECTORIES, вы можете создать IMPORTED target вручную . В файле конфигурации для вашего проекта вы также можете использовать find_dependency и снова создать IMPORTED target вручную .


При использовании макроса find_dependency не забудьте передать те же параметры , которые вы передали в find_package() в CMakeLists.txt проекта. Это первичный параметр COMPONENTS и такие переменные, как Boost_USE_STATIC_LIBS, которые влияют на поиск пакетов.

Если вы хотите указать требование VERSION, тогда это требование должно express двоичная совместимость библиотеки на целевой машине с библиотекой, для которой был создан проект .

HINST и PATHS параметры для find_package вряд ли нужно передавать на find_dependency: вызов find_dependency обрабатывается на целевой машине , пути которых могут отличаться от путей на машине сборки .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...