Можно ли при компиляции указать путь к файлу #include относительно текущего каталога пользователя?
Я знаю, что можно указать путь к файлу #include либо относительно каталога, в котором находится файл, как абсолютный путь к файлу, либо относительно любого из каталогов в системной переменной $PATH. Есть ли способ вместо этого указать его относительно текущего каталога пользователя, когда программа компилируется? Допустим, у меня есть следующая файловая структура:
|--dir_a/
| |--a.c
| |--a.h
|--dir_b/
| |--b.c
| |--b.h
|--makefile
Теперь предположим, что я хочу #include файл dir_a/a.h из dir_b/b.h. Используя расположение dir_b/b.h, это можно записать так: это:
#include ../dir_a/a.h
Однако, на мой взгляд, у этого подхода есть серьезный недостаток, поскольку он жестко кодирует расположение файлов относительно друг друга, что означает, что перемещение файла потребует обновления пути к файлу везде, где этот файл был включен.
Использование абсолютных путей к файлам позволило бы избежать этой проблемы, но вместо этого жестко закодировало бы расположение проекта в файловой системе, что кажется плохой практикой.
Наконец, используя теги <> для указания пути к файлу это также неосуществимо, поскольку я не могу предположить, что проект будет перечислен в переменной $PATH.
Поэтому я хочу иметь возможность указать пути относительно того, откуда пользователь компилирует (или, еще лучше, из расположения файла makefile). В приведенном выше примере это позволило бы мне использовать следующее утверждение для #include dir_a/a.h из dir_b/b.h:
#include dir_a/a.h
Я думаю, что это было бы идеальным решением. Это сделало бы утверждения #include более последовательными и более простыми для выполнения, а также избегайте недостатков, которые я перечислил выше. Можно ли это сделать каким-либо образом, например. с флагом компилятора или что-то в этом роде? Я использую gcc в качестве компилятора.3 ответа:
Если вы последовательно используете
<>includes, то опций-Iв файле makefile должно быть достаточно. Макет каталога показывает только одинmakefile, в Родительском каталоге. Это могло бы использовать-Idir_a -Idir_bВ параметрах компилятора, а также .файлы c могли бы просто сделать
#include <a.h> #include <b.h>Одна из проблем с цитируемыми включениями заключается в том, что их поведение с другими компиляторами может отличаться, как отмечено в В чем разница между
#include <filename>и#include “filename”? (стандарт не был достаточно ясным). С помощью расширение gcc, вероятно, не улучшает эту ситуацию.
Мне удалось решить мою проблему.
Первая часть решения включает указание флага
-iquoteвgccпри компиляции. Изman gcc:Вторая часть головоломки заключалась в том, как найти путь к-iquotedir Add the directory dir to the head of the list of directories to be searched for header files only for the case of #include "file"; they are not searched for #include <file>, otherwise just like -I.makefileвнутри самогоmakefile. Ответ работал для меня. Я вставляю решение здесь для удобства:ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))Edit : хотя этот подход работает, этот ответ более удобен для кросс-компилятора, поэтому я лично собираюсь использовать тот.