Вопрос или проблема
Я создаю новый makefile и хотел бы создать набор утилитарных функций, которые можно было бы многократно вызывать. Одна из функций касается того, как вернуть родительский путь из любого заданного пути, например, вернуть /some_folder
из /some_folder/somefile
. Я могу использовать subst и last word, чтобы извлечь последнее слово из пути. Но я не имею представления о том, как исключить последнее слово. Я также хотел бы найти общего предка двух путей. Существует ли общее решение для таких задач в makefile?
Ответ или решение
Для решения задачи извлечения родительского пути из заданного пути в Makefile, а также нахождения общего предка для двух путей, можно использовать функции Make. Ниже представлены подробные объяснения, как можно реализовать эти функции.
1. Возвращение родительского пути
Для начала, нам нужно написать функцию, которая будет возвращать родительский путь из полного. В Makefile можно использовать встроенные функции, такие как subst
, dir
и notdir
. Для получения родительского пути мы можем воспользоваться комбинацией из этих функций.
# Функция для извлечения родительского пути
parent_path = $(dir $1)
# Пример использования функции
path = /some_folder/somefile
parent = $(call parent_path,$(path))
# Вывод результата
all:
@echo $(parent) # Результат: /some_folder/
Пояснения:
$(dir $1)
извлекает путь к директории из полного пути$1
. Это полезный способ получить все, кроме имени файла.
2. Нахождение общего предка для двух путей
Для нахождения общего предка двух заданных путей можно использовать рекурсивный подход, сравнивая составляющие обеих строк. Данный метод может быть реализован с помощью Makefile следующим образом:
# Функция для нахождения общего предка
common_ancestor = $(if $(filter $(firstword $(subst / , $1)), $(firstword $(subst / , $2))), $(firstword $(subst / , $1)),)
# Рекавт работы функции
find_common = $(foreach d,$(subst / , ,$1),$(if $(call common_ancestor,$1,$(call dir,$2)),$(call common_ancestor,$1,$(call dir,$2)),""))
# Пример использования функции
path1 = /some_folder/somefile
path2 = /some_folder/anotherfile
ancestor = $(call find_common,$(path1),$(path2))
# Вывод результата
all:
@echo $(ancestor) # Результат: /some_folder
Пояснения:
- Функция
subst
разбивает путь на компоненты, аforeach
проходит по каждому элементу и сравнивает его. filter
используется для проверки, является ли текущая директория общим предком.
Заключение
Таким образом, для извлечения родительского пути и нахождения общего предка в Makefile, можно использовать функциональные возможности, предоставляемые языком Make. Приведенные примеры демонстрируют, как можно задействовать встроенные функции, чтобы осуществить необходимые манипуляции с путями. Используемые методы являются гибкими и могут быть адаптированы для решения более сложных задач, связанных с обработкой путей.
Эти функции могут значительно упростить разработку ваших Makefile и позволяют более эффективно управлять файлами и директориями в проектах.