Как я могу исправить повторяющиеся цели с помощью Cmake?

В настоящее время я пытаюсь установить gr-matchstiq из GitHubLink и у меня возникли проблемы. Код больше не соответствует стандартам CMake.

В частности, в cmake 2.6 введена политика, согласно которой логические целевые имена должны быть уникальными (см.: CMP0002). Однако цель «ВСЕ» используется неоднократно. Я считаю, что это так, из-за ошибки, которую я получаю:

$ cmake -Wno-dev ../
-- Build type not specified: defaulting to release.
Traceback (most recent call last):
  File "<string>", line 2, in <module>
TypeError: Strings must be encoded before hashing
Traceback (most recent call last):
  File "<string>", line 2, in <module>
TypeError: Strings must be encoded before hashing
CMake Error at cmake/Modules/GrPython.cmake:115 (add_custom_target):
  add_custom_target cannot create target "ALL" because another target with
  the same name already exists.  The existing target is a custom target
  created in source directory "/home/me/Projects/gr-matchstiq/swig".
  See documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  cmake/Modules/GrPython.cmake:214 (GR_UNIQUE_TARGET)
  python/CMakeLists.txt:31 (GR_PYTHON_INSTALL)


Traceback (most recent call last):
  File "<string>", line 2, in <module>
TypeError: Strings must be encoded before hashing
CMake Error at cmake/Modules/GrPython.cmake:115 (add_custom_target):
  add_custom_target cannot create target "ALL" because another target with
  the same name already exists.  The existing target is a custom target
  created in source directory "/home/me/Projects/gr-matchstiq/swig".
  See documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
  cmake/Modules/GrPython.cmake:214 (GR_UNIQUE_TARGET)
  apps/CMakeLists.txt:22 (GR_PYTHON_INSTALL)


-- Configuring incomplete, errors occurred!
See also "/home/me/Projects/gr-matchstiq/build/CMakeFiles/CMakeOutput.log".
See also "/home/me/Projects/gr-matchstiq/build/CMakeFiles/CMakeError.log".

Код в cmake/Modules/GrPython.cmake:115:

add_custom_target(${_target} ALL DEPENDS ${ARGN})

Код в cmake/Modules/GrPython.cmake:214:

GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})

У меня почти нет опыта работы с cmake, поэтому я не уверен, какое исправление наиболее безопасно.

  1. В корневой файл CMakelists.txt добавьте строку (Примечание: это не сработало, но, возможно, я сделал что-то не так):

    set_property(GLOBAL ALLOW_DUPLICATE_TARGETS TRUE)

  2. Измените «ALL» cmake/Modules/GrPython.cmake:115 на что-то вроде «ALL_PY», т.е.

    add_custom_target(${_target} ALL_PY DEPENDS ${ARGN})

  3. Каким-то образом измените функцию GR_UNIQUE_TARGET (строки 107–116 GrPython.cmake):

########################################################################
# Create an always-built target with a unique name
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
########################################################################
function(GR_UNIQUE_TARGET desc)
    file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
    OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
    add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)

Или мне следует сделать что-то еще?

PS. Еще одно исправление, которое мне нужно было внести, было в строках 95-102:

########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print (sysconfig.get_python_lib(plat_specific=True, prefix=''))
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)

Первоначально в операторе печати Python не было символов «(» и «)», требуемых Python3)

PPS. Я понятия не имею, как обрабатывать или находить ошибки типа, поэтому разберусь с ними позже.

Похоже, что переменная _target никогда не устанавливается, поэтому строка add_custom_target(${_target} ALL DEPENDS ${ARGN}) сворачивается в add_custom_target(ALL DEPENDS ${ARGN}). Распечатайте _target, чтобы проверить и узнать, почему он никогда не устанавливается, это основная причина. Кстати, ALL в любом случае является недопустимым целевым именем в (более последних версиях) CMake.

Friedrich 05.10.2023 08:13

@Фридрих - Спасибо. Этому коду 9–10 лет, за исключением файла .cc &.h, которому 7 лет. Полагаю, что бы я ни делал, мне нужно будет изменить ВСЕ trgts на другое имя.

user1245262 05.10.2023 14:04

Нет. Вам необходимо убедиться, что _target не отключен. Больше ничего не трогай. Значение _target будет именем вашей цели. Взгляните на add_custom_target. ALL должен быть там в качестве второго аргумента.

Friedrich 05.10.2023 14:49

какая версия Python 2 установлена ​​на вашем компьютере и как именно вы ее установили?

starball 06.10.2023 00:35

@Фридрих - я поискал и нашел только два варианта использования _target. Оба были в функции GR_UNIQUE_TARGET в моем варианте №3. Как вы догадались, когда я добавляю message(_target = "${_target}"), я вижу, что _target не имеет значения (т. е. _target = ""). Могу ли я просто присвоить ему строковое значение? Мог ли этот код когда-нибудь сработать???

user1245262 06.10.2023 05:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

TL;DR: выберите вариант 3: вам нужно хешировать объект bytes.

Добавьте к строке, которая будет хешироваться, префикс b:

unique = hashlib.md5(b'${reldir}${ARGN}').hexdigest()[:5]

Обзор комментариев

CMake завершает работу с ошибкой, поскольку определено несколько целей с именем «ALL». Это связано с линией

add_custom_target(${_target} ALL DEPENDS ${ARGN})

где _target — неустановленная переменная. Таким образом, строка становится (я обозначу неустановленную переменную псевдосимволом <unset>):

add_custom_target(<unset> ALL DEPENDS ${ARGN})

и CMake видит только:

add_custom_target(ALL DEPENDS ${ARGN})

Согласно сигнатуре add_custom_target, первый аргумент — это имя цели, а необязательный ALL в качестве второго аргумента приведет к тому, что цель всегда будет создаваться. Без первого аргумента ALL становится первым и вызывает ошибку, которую мы видим. Это лишь второстепенная ошибка, давайте копнем глубже.

Пользовательская цель добавляется в функцию GR_UNIQUE_TARGET, и эта функция вызывается неоднократно. В ответ на вопрос: «Могу ли я просто присвоить ему строковое значение?» - Нет. Установка статической строки не будет работать и просто вернет вас обратно к целевому имени, а не к уникальному состоянию.

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

Взглянем на код Python

Я скопировал код Python и запустил его, и меня сразу же встретила следующая ошибка:

TypeError: Unicode-objects must be encoded before hashing

потому что хэш-библиотека Python 3 ожидает объекты в Юникоде bytes. Если вы дадите ему один, либо добавив префикс b, либо вызвав метод encode, код будет работать. Попробуйте следующую функцию (обратите внимание на добавленный b):

function(GR_UNIQUE_TARGET desc)
    file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
    execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5(b'${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
    OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
    add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)

В ответ на вопрос «могло ли это когда-нибудь сработать?» - Да, я так думаю. Возможно, это не самый элегантный способ сделать это, и он немного похож на один из этих, если ваш единственный инструмент — молоток… решения (однако у меня в ящике нет лучшей идеи), но определенно работоспособные. По совпадению, хеш-библиотека Python 2.7 была довольна объектом str, так что тогда она работала бы.

Другие вопросы по теме