Как сделать так, чтобы #include <> просматривал подпапку стандартного системного каталога? - PullRequest
1 голос
/ 07 мая 2020

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

Я установил библиотеку C ++ под названием ibex. Он содержит файл ibex.h и подпапку ibex, а подпапка содержит дополнительные файлы заголовков, которые вызываются ibex.h. И ibex.h, и его подпапка находятся в / usr / local / include. Я подтвердил, что это находится в моем стандартном системном каталоге.

Я пытаюсь запустить пример кода с веб-сайта ibex под названием foo. cpp

#include <ibex.h>
#include <iostream>

using namespace std;
using namespace ibex;

int main(int argc, char** argv) {
  Interval x(0,1);
  cout << "My first interval:" << x << endl;
}

, но получаю сообщение об ошибке

In file included from (filelocationremoved)/foo.cpp:1:
/usr/local/include/ibex.h:6:10: fatal error: 'ibex_Setting.h' file not found

Таким образом, в основном он может найти ibex.h, но не будет искать в подпапке ibex_Setting.h (или любой другой файл в подпапке). Есть ли способ заставить его просматривать все файлы в этой подпапке, как если бы они были в папке / usr / local / include, не перемещая их все?

Спасибо!

Исходное сообщение:

Я начинающий пользователь c ++ (в основном использую Matlab и немного Python), но мне нужно использовать c ++ для библиотеки ibex (http://www.ibex-lib.org). Я пытаюсь скомпилировать их базовый пример c, но у меня возникают проблемы. Я надеюсь, что некоторые из опытных пользователей могут здесь помочь, поскольку у меня нет прогресса.

Примечания:

  • Запуск MacOS Catalina
  • Использование Sublime text для моя IDE
  • У меня установлен Xcode, и я могу запустить пример приветственного мира
  • Установленный ibex, используя: brew install ibex

Я пытаюсь запустить следующий пример кода из их документации называется foo. cpp

#include <ibex.h>
#include <iostream>

using namespace std;
using namespace ibex;

int main(int argc, char** argv) {
  Interval x(0,1);
  cout << "My first interval:" << x << endl;
}

, но появляется ошибка

In file included from (filelocationremoved)/foo.cpp:1:
/usr/local/include/ibex.h:6:10: fatal error: 'ibex_Setting.h' file not found

Файл ibex_Setting.h является одним из многих файлов, вызываемых ibex.h. У меня есть файл ibex.h, расположенный в / usr / local / include, и он, кажется, может его найти. У меня также есть псевдоним папки ibex (где находятся все соответствующие подфайлы) в той же папке / usr / local / include. Но он не будет искать в этой подпапке. Эта подпапка была создана brew link ibex, что, как я полагаю, должно сделать ее доступной для поиска. Если я перемещаю ibex_Setting.h в папку / usr / local / include, он затем находит его, но переходит к следующему файлу, который не может найти (также находится в / usr / local / include / ibex). В папке достаточно файлов, поэтому я не хочу вручную перемещать их все в / usr / local / include. Кроме того, было бы глупо делать это.

В документации ibex также сказано, что нужно сделать это: export DYLD_LIBRARY_PATH=[prefix]/lib, где префикс - это расположение папки. Моя libibex.dylib находится в / usr / local / lib, которую я использовал. Это не помогло. Я уверен, что не предоставляю достаточно информации, но опять же, я новичок в C ++, поэтому даже не знаю, что еще включить. Любая помощь будет принята с благодарностью!

Спасибо

Ответы [ 2 ]

0 голосов
/ 09 мая 2020

Я не знаком с XCode и Sublime Text, но могу показать вам демонстрацию проблемы и способы ее решения на уровне компилятора. Вы можете определить, как применить это в настройках компилятора вашей IDE.

Вот содержимое папки проекта для программы:

$ ls -R
.:
header.h  main.cpp  subfolder

./subfolder:
subheader.h

А вот исходные файлы и заголовки:

$ cat main.cpp
#include <header.h>

int main()
{
    return foo();
}

$ cat header.h
#ifndef HEADER_H
#define HEADER_H

#include <subheader.h>

inline int foo() {
    return bar();
}

#endif

$ cat subfolder/subheader.h 
#ifndef SUBHEADER_H
#define SUBHEADER_H

inline int bar() {
    return 42;
}

#endif

Сначала я пытаюсь скомпилировать prog вот так:

$ g++ -Wall -o prog main.cpp
main.cpp:1:10: fatal error: header.h: No such file or directory
    1 | #include <header.h>
      |          ^~~~~~~~~~
compilation terminated.

, что не работает, потому что препроцессор не знает, где искать систему заголовок <header.h>. (В этом контексте системный заголовок просто означает файл заголовка, указанный в <...>, в отличие от локального заголовка , который будет указан в "...", и будет выполняться поиск for в текущем каталоге при запуске компилятора).

Я могу исправить это, добавив опцию препроцессора -I dir, которая сообщает препроцессору искать файлы заголовков в каталоге dir. Поскольку header.h находится в текущем каталоге в этой демонстрации, я просто буду использовать . в качестве имени каталога, а не вводить полное имя каталога.

$ g++ -Wall -I. -o prog main.cpp
In file included from main.cpp:1:
./header.h:4:10: fatal error: subheader.h: No such file or directory
    4 | #include <subheader.h>
      |          ^~~~~~~~~~~~~
compilation terminated.

Это исправление включило header.h быть найденным, но тогда в header.h такая же проблема с <subheader.h>.

Я исправляю это таким же образом:

$ g++ -Wall -I. -I./subfolder -o prog main.cpp
$ ./prog
$ echo $?
42

и теперь все в порядке .

Итак, в первом приближении вам нужно сделать настройки в вашем проекте IDE, чтобы указать, что -I/usr/local/include и -I/usr/local/include/subfolder передаются команде компиляции. Но на самом деле первый вам не понадобится, потому что /usr/local/include всегда является каталогом поиска компилятора по умолчанию для файлов заголовков. Ответы на этот вопрос могут вам помочь, хотя он старый.

Есть ли какой-либо вариант, аналогичный -I dir, который заставит препроцессор искать рекурсивно в подпапках dir для разрешения #include <...> директив? Нет, нет.

Обратите внимание, что если бы я закодировал header.h с помощью:

#include <subfolder/subheader.h>

вместо:

#include <subheader.h>

, то я мог бы скомпилировать моя программа при второй попытке, g++ -Wall -I. -o prog main.cpp.

Хорошо организованные пакеты, как правило, имеют свои директивы #include <...> с необходимыми элементами пути, такими как <subfolder/subheader.h>, чтобы обеспечить успешную компиляцию максимум с одним -I base/path option, где base/path - общий префикс пути для всех директив #include <...>. Но некоторые пакеты этого не делают, и этому может быть хорошее объяснение.

0 голосов
/ 07 мая 2020

/ usr / local / include - это то место, где находится ibex.h. Попробуйте добавить путь к подкаталогам, в которых есть ibex_Setting.h, в Дополнительные подключаемые каталоги. Или, если вы не нашли дополнительных настроек включаемых каталогов, используйте ../../../Path, чтобы найти ваши включаемые файлы.

...