Можно ли при компиляции указать путь к файлу #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 : хотя этот подход работает, этот ответ более удобен для кросс-компилятора, поэтому я лично собираюсь использовать тот.