Параллельный запуск mkdir -p в Mac OS X завершает работу до создания каталога.

У меня есть Makefile с несколькими заданиями.

Каждое задание выполняет mkdir -p $(OBJDIR), чтобы убедиться, что каталог объектов существует до запуска gcc.

Однако mkdir -p иногда не проверяет существование каталога перед возвратом. Я предполагаю, что происходит какое-то состояние гонки. И тогда компилятор дает сбой, так как не может записать в выходной файл.

Есть ли независимый от платформы способ выполнения mkdir -p, чтобы это состояние гонки не возникало?


Этот сбой, кажется, происходит только в OS X. Вопрос был отправлен в Stack Overflow, но на самом деле это вопрос системного администратора.


# script named 'test'
if [ "$1" == "run" ] ; then
  rm -rf XXX

  NOW=`date +%s`
  echo Now: $NOW
  THEN=`echo "$NOW + 10" | bc`
  RUNAT=`date -r $THEN +"%m%d%H%M.%S"`
  echo $RUNAT

  for i in {1..75}; do
    ./test $THEN &
    sleep 0.05
  done
  wait
  exit 0
fi

THEN=$1
# make sure things are cached
NOW=`python -c'import time; print repr(time.time())'`
NOW=`python -c'import time; print repr(time.time())'`

AMOUNT=`echo "$THEN - $NOW" | bc`
echo sleeping $AMOUNT
sleep $AMOUNT

mkdir -p XXX/YYY/ZZZ
touch XXX/YYY/ZZZ/hi

Я написал приведенный выше сценарий bash, но он не выдает прогнозируемой ошибки. Вставлю тач в makefile, возможно там прояснится в чем дело.

Оператор CC make-файла выглядит так:

$(OBJPATH)/%.o : %.cpp
        mkdir -p $(dir $@)
        @sleep 0.1
        $(CPP) $(INCPATH) $(_FLAGS) $(CPPFLAGS) $< -o $@

Оператор @sleep предназначен для того, чтобы, возможно, дождаться устранения состояния гонки, но, возможно, в конце концов, условия гонки нет.


person iamacomputer    schedule 02.01.2016    source источник
comment
Спросите на apple.stackexchange.com   -  person trojanfoe    schedule 02.01.2016
comment
mkdir -p не должен завершаться до создания каталога (хотя по какой-то причине может произойти сбой), поэтому здесь действительно не должно быть условий гонки. Я подозреваю, что что-то еще идет не так, но без дополнительной информации я понятия не имею, что это может быть. Можете ли вы сократить его до минимально полного примера (например, обрезать ненужные вещи, заменить команду компиляции на touch fileininoutputdirectory и т. д.) и добавить что к вопросу?   -  person Gordon Davisson    schedule 03.01.2016
comment
Вероятно, вы не установили зависимости, необходимые для того, чтобы make знал, что он должен сериализовать шаги mkdir -p и gcc. Он запускает их параллельно или, может быть, даже делает последнее раньше первого. Мы не сможем помочь, пока не увидим рассматриваемые правила make.   -  person Ken Thomases    schedule 03.01.2016
comment
Кен, он определенно выполняет шаг gcc после шага mkdir. Это состояние гонки между процессами, все они одновременно mkdir -p а затем записывают в файл внутри каталога.. Гордон - Я пытаюсь придумать, как настроить простой пример.   -  person iamacomputer    schedule 11.01.2016
comment
Я добавил touch $(dir $@)/direxists в правило для файлов cpp -> o перед компиляцией, и теперь makefile не умирает. Это определенно кладж, но пока я не столкнулся с ошибкой. Что это на самом деле означает, я не уверен... Я обновлю снова, если увижу ошибку с включенным кладжем.   -  person iamacomputer    schedule 11.01.2016
comment
У меня была аналогичная вам проблема, и я использовал mkdir -p. Однако некоторые из моих коллег используют Mac, и mkdir -p там работает не так надежно. Реальная ситуация была немного сложнее, но решение может вам пригодиться.   -  person carandraug    schedule 15.03.2016
comment
Я сейчас использую: $(OBJPATH)/%.o : %.cpp -@mkdir -p $(dir $@) @while [ ! -e $(dir $@) ]; do sleep 0.1; done $(CPP) $(INCPATH) $(_FLAGS) $(CPPFLAGS) $< -o $@ вроде работает... может просто совпадение   -  person iamacomputer    schedule 05.04.2016