Почему g ++ не находит прекомпилированный заголовок, который находится в -I include-path? - PullRequest
8 голосов
/ 30 апреля 2019

Я пытаюсь построить предварительно скомпилированный заголовок и исполняемый файл, вот так:

g++ -g -Wall -std=c++17 \
    -c ./src/pch.hpp -o ./build/pch.hpp.gch

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./build/ -include pch.hpp

Файл pch.hpp.gch создан правильно. Но для каждого из файлов .cpp я получаю следующую ошибку:

1 error generated.
<built-in>:1:10: fatal error: 'pch.hpp' file not found
#include "pch.hpp"

Я думаю, что моя строка компиляции верна, основываясь на документации gcc Precompiled Headers :

  • -I./build/ говорит ему добавить каталог build в путь поиска include.
  • -include pch.hpp добавляет директиву #include <pch.hpp> к каждому файлу.
  • Компилятор ищет предварительно скомпилированные заголовки с суффиксом .gch для каждой из своих директив #include.

Почему моя строка компиляции не работает должным образом?


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

Если я изменю включение для поиска файла .gch, то файл будет найден, в соответствии с тем, что я ожидал. То есть -include pch.hpp.gch вместо -include pch.hpp.
Но тогда PCH интерпретируется как двоичный файл, и компиляция завершается неудачно:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./build/ -include pch.hpp.gch
./build/pch.hpp.gch:2:22: error: source file is not valid UTF-8

Я не удивлен, что #include <pch.hpp.gch> не компилируется. Но я упоминаю об этом, поскольку кажется, что в моей исходной команде папка build ищется (как я и ожидал), но механизм, который знает, что вместо обычного заголовка используется файл .gch, не активный. Weird.

В качестве альтернативы, , если я добавлю папку src в путь поиска заголовка, она будет работать:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -I./src/ -I./build/ -include pch.hpp

Я не понимаю, почему добавление другого , нерелевантного include-path что-то решает. Weird.


Мое текущее рабочее решение - полностью удалить директиву -I include-path, а указать более полный путь к build/pch.hpp:

g++ -g -Wall -std=c++17 \
        -c ./src/*.cpp  \
        -include ./build/pch.hpp

Этот работает как положено. Я не уверен, почему это необходимо, и это странно и неудобно.

Это то, как предполагается использовать PCH? Почему моя оригинальная линия не работает, и что я собираюсь делать вместо этого?

1 Ответ

7 голосов
/ 07 мая 2019

Из документации :

Предварительно скомпилированный заголовочный файл ищется, когда #include замечено в компиляции. Когда он ищет включенный файл (см. Путь поиска в препроцессоре C), компилятор ищет предварительно скомпилированный заголовок в каждом каталоге непосредственно перед тем, как он ищет включаемый файл в этом каталоге. Искомое имя - это имя, указанное в #include с добавлением «.gch». Если предварительно скомпилированный заголовочный файл не может быть использован, он игнорируется.

Например, если у вас есть #include "all.h", и у вас есть all.h.gch в том же каталоге, что и all.h, тогда, если возможно, используется предварительно скомпилированный заголовочный файл, а оригинальный заголовок используется в противном случае.

Это означает, что компилятор должен быть в состоянии найти ОБА h-файл и gch-файл при сборке cpp. Таким образом, они ОБА должны находиться в одном каталоге или в том же пути поиска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...