Я пытаюсь воспроизвести ситуацию, которая происходит только на некоторых машинах.Чтобы воспроизвести его, я создаю каталог с 2000 файлами:
mkdir /tmp/test
cd /tmp/test
for f in $(seq 1 2000); do touch $f.txt; done
Затем я использую следующий Makefile (упрощенный из реального варианта использования):
FILES:=$(shell find . -name '*.txt')
%.done: %.txt
@echo "done $@"
toolong:
@$(foreach file,$(sort $(FILES)), \
if $(MAKE) $(file); \
then echo "did $(file)" >> $@; \
else echo "failed $(file)" >> $@; fi; )
Запуск make
производитНеудивительно, что ошибка:
make: execvp: /bin/sh: Argument list too long
Этот вопрос представляет решение, которое работает.Однако мне нужно точно понять, почему эта ошибка не возникает на компьютерах моих коллег.Я пробовал следующие вещи:
- Увеличение предела стека (
ulimit -s
дает одинаковый результат на обеих машинах, 8192, и увеличение его ничего не меняет); - Проверка
getconf ARG_MAX
(2097152 на обеих машинах); - Проверка
MAX_ARG_STRLEN
(131072 на обеих машинах); - Использование другой оболочки (
zsh
используется на обеих машинах; я также пытался bash
, dash
и sh
, через export SHELL=<shell> make
, а также путем замены символической ссылки /bin/sh -> /bin/bash
ссылкой на dash
).
Наконец, я попытался перекомпилировать Make изисточник, и понял, что даже когда я компилирую ту же версию Make (4.1) в моей тестовой машине Ubuntu, я получаю то же поведение, что и в своей Fedora, то есть ошибка «список аргументов слишком длинный».
make --version
показывает только одну разницу между ними:
Версия из пакета apt
:
GNU Make 4.1 Создано для x86_64- pc -linux-gnu
Версия, скомпилированная из исходного кода (./configure && make
):
GNU Make 4.1 Создано для x86_64- неизвестно -linux-gnu
Я даже пытался скомпилировать make-dfsg , что приводит к идентичным make --version
, но результат такой же, как и с моей другой скомпилированной вручную сборкой.
Увеличив количество файлов в Ubuntu, мне удалось определить, что фактические ограничения в размере сгенерированной командыследующие строки:
- Fedora или Arch Linux (оба с Make 4.2.1) или Ubuntu с вручную скомпилированным Make 4.1: 128 КБ (~ 1200 файлов);
- Debian Sidили Ubuntu, оба с Make 4.1, установленным из пакета
apt
: 2 МБ (~ 19300 файлов).
Мне бы очень хотелось понять (1), почему существует это различие, и (2)как я могу скомпилировать Make для получения более высокого предела, чтобы у меня было одинаковое поведение на обеих машинах.