Каков самый надежный способ использования GNUMake с именами файлов, содержащими пробелы?

Я хочу использовать GNUMake для запуска make-файла на основе правил, который создает набор файлов C в структуре каталогов (в файловой системе Windows).

Корневой каталог, некоторые подкаталоги и некоторые файлы содержат пробелы.

Пример файла: "C:\Documents and Settings\<username>\My Documents\Test Dir\Build Me.c"

GNUMake на самом деле не работает, когда пути к файлам содержат пробелы. Я читал о возможных способах решения этой проблемы (удаление пробелов из моих имен файлов, использование формата 8.3, замена пробелов на ? или \\ и т. д.), но ни один из них не идеален (или нет?)

Есть ли серебряная пуля, которая решит эту проблему?

Кстати, я застрял с GNUMake, я не могу использовать другой инструмент make.


person demoncodemonkey    schedule 20.03.2009    source источник


Ответы (6)


Проще всего действительно исправить имена файлов.

Однако, если это не удастся, напишите свои команды, чтобы поместить имена файлов в двойные кавычки. Самый простой и безопасный способ — поместить все имена файлов в макросы; Хитрость заключается в том, что вам нужно избегать двойных кавычек, которые Make в противном случае захочет съесть саму себя.

Итак: FN="\"C:\My Documents\myfiles.c\"" FN2="C:\My Documents\myfile2.c"

или используйте $(CC) $(CFLAGS) "$(FN2)"

Хитрость здесь заключается в том, чтобы повторить вашу командную строку с помощью echo

echo $(CC) $(CFLAGS) "$(FN2)"

или используйте make -d, чтобы получить все подробности о том, что пытается сделать make.

Возможно, вам придется немного повозиться с этим, в частности, вам может понадобиться удвоить побеги.

person Charlie Martin    schedule 21.03.2009
comment
Исправить имена файлов? Имена не нарушены. Инструменты, которые не могут обрабатывать пробелы, сломаны. Пример пути даже является стандартом MS (я подозреваю, что это была тактика, чтобы подтолкнуть разработчиков к исправлению их сломанных инструментов, которые не могут обрабатывать пробелы). - person Qwertie; 01.05.2012
comment
Нет, не работают инструменты, использующие имена файлов, не соответствующие стандарту UNIX. Также операционные системы. - person Charlie Martin; 02.05.2012
comment
Операционные системы и инструменты, разрешающие пробелы, не работают?! - person Qwertie; 06.06.2012
comment
Ага. А вы, ребята, убирайтесь с моей лужайки. - person Charlie Martin; 08.06.2012

Возможно, вы сможете избежать пробелов в вашем make-файле, то есть:

$(CC) $(CFLAGS) 'C:\Documents\ and\ Settings\<username>\My\ Documents\Test\ Dir\Build Me.c'

На всякий случай я добавил одинарные кавычки, но не знаю, работает ли это, если вы используете терминал Windows (а не cygwin и т. д.).

person Dana the Sane    schedule 20.03.2009
comment
Может быть, так как у меня нет под рукой установки Windows, чтобы проверить, чтобы быть уверенным. Я не могу придумать причину, почему это не сработает. - person Dana the Sane; 23.05.2012

Я нашел большое вдохновение на http://www.mail-archive.com/[email protected]/msg05201.html, что меня вдохновило. Мое собственное тестовое приложение состоит из каталога файлов FLV Jazz времен Второй мировой войны, загруженных с YouTube, и подкаталога audio, в котором я хотел бы хранить аудиоверсии OGA каждого из них. И, конечно же, имена файлов содержат пробелы. Затем я хотел бы запустить ffmpeg2theora для

Вот Makefile GNUMake, который я собрал для работы. Спасибо всем подсказкам на этом сайте, а также указанному выше сайту!

sq = $(subst $(sp),?,$1)
qs = $(subst ?,$(sp),$1)

e :=
sp := $(e) $(e)

FLVS := $(foreach file,var,$(call sq,$(wildcard *.flv)))
FLVS := $(subst .flv?,.flv ,$(FLVS))

AUDIOS := $(patsubst %.flv,audio/%.oga,$(FLVS))

.PHONY: audios show

audios: $(AUDIOS)

$(AUDIOS) : $(FLVS)
    ffmpeg2theora --novideo -o "$(call qs,$@)" "$(call qs,$(notdir $(patsubst %.oga,audio/%.flv,$@)))"

show:
    echo $(FLVS)
    echo $(AUDIOS)
person Brian Yoder    schedule 11.10.2010
comment
Или вы можете заменить другие символы и преобразовать их обратно в пробелы, когда это необходимо. s+ = $(subst \ ,+,$1) +s = $(subst +,\ ,$1) $(call s+,foo bar): $(call s+,bar baz) @echo Making $(call +s,$@) from $(call +s,$<) - person Mr_Moneybags; 01.02.2015

Обычно я использовал что-то вроде комбинации ответа Даны Разумного и ответа Брайана Йодера.

Вы просто используете функцию $(subst), чтобы заменить все вхождения пробелов экранированными пробелами. НАПРИМЕР:

empty := 
space := $(empty) $(empty)
program_files := $(subst $(space),\$(space),$(ProgramFiles))

(Обратите внимание, что в некоторых старых версиях make для Windows вам также потребуется использовать еще один $(subst), чтобы изменить обратную косую черту пути на косую черту)

person T.E.D.    schedule 27.06.2012

Если пробелы есть только в «корневой» части пути, вы можете смонтировать этот каталог по пути без пробелов. Это можно сделать несколькими способами: из командной строки ("net use" или "subst") или из Проводника (Инструменты > Подключить сетевой диск). Таким образом, C:\Documents and Settings\\My Documents\Test Dir" может стать X:\BuildMe.c

Однако, если в именах файлов или в каталогах ниже «корневого» каталога сборки есть пробелы, то, вероятно, нет идеальных решений. Я использовал другие предложения, которые вы упомянули (имена 8.3, замена пробелов другим символом), и они работают, но у них есть свои проблемы.

person jdigital    schedule 21.03.2009
comment
Он должен работать во всех случаях. т.е. когда корневой каталог содержит пробел, а также сами подкаталоги, а также сами имена файлов. - person demoncodemonkey; 25.03.2009

Я просто добавляю «одинарные кавычки» вокруг оскорбительной строки: - '$(TARGET_DIR)'

Пример: (это помогло мне заставить erlang.mk правильно работать в Windows!)

app:: $(C_SRC_ENV)
    @mkdir -p priv/
    $(c_src_verbose) $(CC) $(CFLAGS) $(C_SRC_DIR)/*.c -fPIC -shared -o $(C_SRC_OUTPUT) \
        -I '$(ERTS_INCLUDE_DIR)' $(C_SRC_OPTS)

'$(ERTS_INCLUDE_DIR)' теперь правильно расширяется до 'c:/Program Files/erl7.0/erts-7.0/include/'

использование make -d также помогает выявить неверные пути

person Charles Okwuagwu    schedule 23.07.2015