Какой обычный механизм регистрации местоположения поиска заголовка в Linux? - PullRequest
1 голос
/ 11 апреля 2019

Предположим, я загружаю библиотеку в linux и собираю ее: настраиваю, делаю, делаю, делаю, устанавливаю.

Библиотека поставляется с заголовками, которые я хочу включить в проект.Как компилятор узнает, где искать заголовки?

  • Ответ Дрю Дормана на Этот вопрос Приведен хороший пример того, как проверить, где компилятор ищет заголовкина уровне системы:

    <code>gcc -print-prog-name=cc1plus</code> -v
  • Включать папки можно добавить в make-файл с аргументом -I для проекта.Естественно, их можно увидеть в Makefile.

Существуют ли другие механизмы для регистрации местоположений заголовков, которые я не рассматривал?Эти комбинированные методы дают мне полное представление, или, говоря иначе, если я смотрю в этих местах, я видел все, что можно увидеть, предполагая, что я использую gnu-make?Наконец, есть ли удобный способ заставить Make показать мне места, которые он проверяет на наличие заголовков?

Справочная информация: библиотеки, с которыми я имею дело, это zeromq и буферы протокола google.Платформа CentOS.Компилятор жалуется, что не может найти заголовки.Я построил эту программу на суррогатной системе (Fedora), которая, казалось, не нуждалась в дополнительном вмешательстве для обеспечения доступности этих заголовков.

1 Ответ

0 голосов
/ 13 апреля 2019

Не существует обычного механизма для регистрации местоположения поиска заголовка в Linux (или другой Unix-подобной ОС).

GCC встроенный , для вашей системы, со значением по умолчаниюсписок каталогов поиска препроцессора для каждого из C и C ++.Вы можете отобразить этот список для C с помощью команды (среди прочих):

$ gcc -x c  -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...
$ [CNTL-C]

и для C ++:

$ gcc -x c++  -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/8"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/8
 /usr/include/x86_64-linux-gnu/c++/8
 /usr/include/c++/8/backward
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...
$ [CNTL-C]

Обратите внимание, что каталоги поиска по умолчанию отличаются для C иC ++: список C ++ является надмножеством C-списка.Поиск в C-списке выполняется при обычной компиляции исходных файлов C:

gcc [options...] foo.c ...

, а в C ++ -списке - при компиляции исходных кодов C ++ обычным способом:

g++ [options...] foo.cpp bar.cc gum.cxx ...

Существует только два других способа сообщения каталогов поиска заголовка препроцессору: -

Вы можете явно указать каталоги поиска в командной строке, используя один из параметров:

-I dir
-iquote dir
-isystem dir
-idirafter dir

согласно руководству: 3.15 Параметры поиска в каталоге

Или вы можете перечислить поисковые каталоги в настройках одной из переменных среды, которые препроцессор интерпретирует как список поисковых каталогов.Для C это:

CPATH
C_INCLUDE_PATH

, а для C ++:

CPATH
CPLUS_INCLUDE_PATH

согласно руководство: 3.20 Переменные среды, влияющие на GCC

В Linux можно дать переменной среды постоянное общесистемное определение по умолчанию, определив его в одном из файлов привилегий root /etc/environment, /etc/profile, /etc/profile.d/, /etc/bash.bashrc.Таким образом, если какой-либо агент определит CPATH и или C_INCLUDE_PATH|CPLUS_INCLUDE_PATH в одном из этих файлов как : пунктурованный список каталогов, это фактически зарегистрирует эти каталоги как каталоги поиска GCC для C| C ++.Однако установки GCC не устанавливают такие параметры: они могут быть установлены только пользователем root.Вы можете проверить, и если вы рисуете пробел, то эти переменные могут быть влиятельными, только если они определены в переходной оболочке.Их использование в системах сборки крайне редко, именно из-за непрозрачной зависимости, которую они вводят в рабочую среду.

Команды, которые я использовал выше для отображения каталогов поиска по умолчанию, чувствительны к добавлению каталогов не по умолчаниюлюбой из двух возможных способов:

$ mkdir my_include

$ gcc -x c  -I my_include -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 my_include
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

или:

$ gcc -x c  -iquote my_include -E -Wp,-v -
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
 my_include
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

или:

$ export CPLUS_INCLUDE_PATH=my_include
$ gcc -x c++  -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/8"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 my_include
 /usr/include/c++/8
 /usr/include/x86_64-linux-gnu/c++/8
 /usr/include/c++/8/backward
 /usr/lib/gcc/x86_64-linux-gnu/8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

Есть ли удобный способ получить Make toпокажите мне, где он проверяет заголовки?

Make не знает процессов компиляции и связанных с ними концепций: он не знает, что проверка заголовков когда-либо происходит вход его работы.При выполнении make-файла могут быть запущены команды, которые вызывают интерфейс GCC для выполнения компиляции, а затем it попытается найти заголовочные файлы, как описано выше.

Прочие вещиПри равной вероятности причина того, что компиляция кода должна быть успешной в некоторой системе Fedora, но не в какой-то системе CentOS, например, не может быть решена проблема #include <google/protobuf/someheader.h>, заключается в том, что какой-то пользователь с привилегиями root установил либо пакет разработки protobuf-develили архив с исходным кодом protobuf в системе Fedora, и никто не делал этого в системе CentOS.

Если protobuf действительно правильно установлен в обеих системах, то другие вещи не равны.

Возможно, google/protobuf/someheader.h - это заголовок, который предоставляется (более новой?) Версией protobuf, которая установлена ​​в системе Fedora, но не предоставляется (более старой?) Версией, котораяустановлен в системе CentOS.

Несколько других неравенств могут объяснить вашу ситуацию, но выКонкретные детали этапов установки пакетов Fedora и CentOS и конкретные примеры успешных и неудачных сборок можно было бы описать только умозрительно.Это почти наверняка не объясняется тем, что вы сейчас не знаете о методах GCC по разрешению директив #include.

Аналогичные соображения применимы к сбою компиляции, который вы найдете в отношении zeromq заголовков.

...