make-файл с созданием дерева каталогов, подходящим для параллели (-j) сборка

Система. Конфигурация. ConfigurationSettings. AppSettings["MyKey"];

AppSettings удержали от использования и теперь считают устаревшим. [ ссылка ]

, Кроме того, appSettings раздел app.config был заменен разделом applicationSettings.

, Поскольку кто-то еще упомянул, необходимо использовать Систему. Конфигурация. ConfigurationManager [ ссылка ], который является новым для.Net 2.0

8
задан P Shved 14 December 2009 в 17:22
поделиться

3 ответа

Проблема с вашим make-файлом заключается в том, что создание ваших объектных файлов не зависит от создания соответствующих каталогов (только фальшивая цель "все") . Такая зависимость необходима для опции -j , и даже без нее ваш make-файл работает только случайно. Есть два (правильных) способа наложить указанную зависимость.

Каталоги как отдельные цели

Вы создали цель для создания каталога; то, что осталось, просто поместите как предварительное условие в правило объектного файла:

$(BUILD)/temp_directory/%.o: %.c   |   dirtree
        $(CC) $^ -o $@

Символ вертикальной черты | означает, что грязное дерево является «предварительным условием только для заказа» . Он используется, когда «грязное дерево» является предварительным условием, но изменения в грязном дереве не делают объектные файлы недействительными и не влияют на результат команды компиляции.

Здесь важно использование предварительного условия «только порядок». Дело в том, что цель dirtyree будет переделываться при каждом вызове Make. Это приведет к тому, что все, что от него зависит, также будет переделано, поэтому он будет каждый раз перестраивать все объектные файлы.

Создание каталогов в командах оболочки

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

$(BUILD)/temp_directory/%.o: %.c
        @mkdir -p $(@D)
        $(CC) $^ -o $@

Обратите внимание на использование $ (@ D) . Он раскрывается как «каталог для целевого файла». Таким образом, его можно использовать единообразно во многих местах и ​​даже с помощью переменной.

Mkdir=@mkdir -p $(@D)
$(BUILD)/temp_directory/%.o: %.c
        $(Mkdir)
        $(CC) $^ -o $@
$(INSTALL_DIR)/%: src_dir/%
        $(Mkdir)
        cp -p $^ $@

Оба способа обеспечивают создание каталога до вызова команд компиляции. Оба способа требуют, чтобы вы вводили текст (либо | dirtyree , либо $ (Mkdir) ) для каждого правила, которое в нем нуждается. Оба способа совместимы с -j , но второе решение требует, чтобы mkdir -p был потокобезопасным (поскольку две такие команды одновременно могут попытаться создать один и тот же каталог, а одна из они потерпят неудачу).

Хотя в большинстве систем это реализовано таким образом, что mkdir -p более или менее потокобезопасен, в некоторых системах ( как в некоторых системах Solaris, например ), они менее потокобезопасны, чем другие. Однако, даже в инструментальной цепочке GNU mkdir -p может дать сбой, если они одновременно вызовут один и тот же вызов библиотеки mkdir (2) .

Если вы хотите быть очень безопасным , вы также можете обойти это. В чем может быть проблема? Эти два сценария mkdir -p пытаются создать один и тот же каталог и конфликтуют где-то внутри библиотеки C. Тогда один из этих mkdir будет успешным, а другой - нет. Однако, если вызванный вами mkdir завершился неудачно, это может быть связано с небезопасностью потока, только если каталог был создан параллельным mkdir . Так что достаточно просто проверить, что целевой каталог создан после вызова mkdir :

Mkdir=@mkdir -p $(@D) || test -d $(@D)

(У этого решения также есть проблема с режимом: mkdir может не работать, если каталог существует, но не t соответствует umask, так что вы можете проверить и это. Но, думаю, это уже слишком.)

15
ответ дан 5 December 2019 в 07:58
поделиться

I'm not sure I fully understand your question. However, I can say this: if your build breaks when you add parallelism, then it's an indication that you haven't defined the dependencies correctly. Ask yourself, "Do the directories need to exist before the object files are generated?" If the answer is "yes", then the directories should be listed as prerequisites of the object files. In other words:

${OBJFILES}: dirtree

And yes, that is pretty much the standard way to do this :)

4
ответ дан 5 December 2019 в 07:58
поделиться

You could have the rules for building the object files call mkdir -p as their first action.

2
ответ дан 5 December 2019 в 07:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: