Сделать / gcc загадочную ошибку 2: как получить больше информации?

У меня есть этот проект C++, который компилируется с использованием Makefile, и иногда, когда (мое предположение) есть некоторые пропущенные включения, я получаю загадочное сообщение "ошибка 2", и процесс make останавливается.
Я подозреваю, что пропущенные включают, потому что это в третий раз, когда я включал несуществующий заголовочный файл.

Это выглядит так:

---- Build tmp/foo.o ----
---- Build tmp/bar.o ----
---- Build tmp/toto.o ----
---- Build tmp/tata.o ----
make: *** [build_Project] Error 2

Это сводит меня с ума, потому что даже при использовании подробных команд (где показан каждый вызов g++) я ничего не вижу.
Я ожидал, что парень выдаст несколько ошибочных сообщений, таких как " не могу найти заголовок X " или " неопределенная ссылка на Y ", но ничего нет.

Мои варианты компиляции для gcc: -O0 -Wall -Werror -Wno-write-strings -fno-rtti -fno-exceptions, если это поможет.

Ах, и мы используем трюк Makefile, включающий зависимости:

ifneq ($(strip $(DEPENDS)),)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif
endif

(см. здесь и здесь для получения дополнительной информации)

Хотя это документированные вещи, я подозреваю, что моя проблема как-то связана с включением этих зависимостей.

Если вы уже наткнулись на эту проблему, не стесняйтесь комментировать это...

Заранее спасибо.

редактировать: хорошо, после небольшой игры, подавляя - перед -include $(DEPENDS) дает мне больше информации (make-файл останавливается на отсутствующем включенном файле).

make[1]: *** No rule to make target « foo.h », necessary for « tmp/bar.d ». Stop.

Теперь недостаток в том, что когда я запускаю make впервые получаю missing bar.d file сообщение для каждого файла зависимости, который должен быть включен (именно поэтому мы ставим - на первом месте). Любое решение?

2 ответа

Решение

Хорошо, мое редактирование решило проблему: размещение тире - перед include скрывает сообщения об ошибках от генерации зависимостей.

Примечание для дальнейшего: не пытайтесь перехитрить Марка.

Это специальный Makefile, возможно, с помощью какого-то инструмента, такого как CMake, который скрывает вывод компилятора, подобный следующему:

gcc -o a.out a.c 2>&1 > /dev/null

Если вы не знаете, что происходит, это хорошая идея, чтобы полностью пересмотреть систему сборки, попробуйте начать заново.

/dev/null 2>&1 на части:

Часть 1: >> перенаправление вывода. Используется для перенаправления вывода программы и добавления вывода в конец файла. Подробнее...

Часть 2: специальный файл / dev / null Это специальный файл псевдо-устройств. Команда

ls -l /dev/null

предоставит вам подробную информацию об этом файле:

crw-rw-rw-. 1 root root 1, 3 20 марта 18:37 /dev/null

Вы наблюдали crw? Это означает, что это файл псевдоустройства, который имеет тип специального символьного файла и обеспечивает последовательный доступ. /dev/null принимает и отклоняет все вводимые данные; не производит вывода (при чтении всегда возвращает указание на конец файла). Ссылка: Википедия

Часть 3: 2>&1 дескриптор файла

Всякий раз, когда вы выполняете программу, операционная система всегда открывает три файла: стандартный ввод, стандартный вывод и стандартную ошибку, поскольку мы знаем, что всякий раз, когда файл открывается, операционная система (из ядра) возвращает неотрицательное целое число, называемое дескриптором файла. Дескриптор файла для этих файлов - 0, 1 и 2 соответственно. Таким образом, 2> & 1 просто говорит о перенаправлении стандартной ошибки на стандартный вывод. & означает, что все, что следует далее, является дескриптором файла, а не именем файла. Короче говоря, с помощью этой команды вы говорите своей программе не кричать во время выполнения. В чем важность использования 2>&1? Если вы не хотите выводить какие-либо данные, даже в случае какой-либо ошибки в терминале. Чтобы объяснить более четко, давайте рассмотрим следующий пример:

$ ls -l> / dev / null

Для приведенной выше команды в терминале не было напечатано никаких выходных данных, но что, если эта команда выдает ошибку:

$ ls -l file_doesnot_exists> / dev / null

ls: нет доступа к file_doesnot_exists: нет такого файла или каталога

Несмотря на то, что я перенаправляю вывод в / dev / null, он печатается в терминале. Это связано с тем, что мы не перенаправляем вывод ошибок в / dev / null, поэтому, чтобы также перенаправить вывод ошибок, необходимо добавить 2>&1:

$ ls -l file_doesnot_exists> /dev/null 2>&1

Другие вопросы по тегам