Ограничить #include только поиском в текущем каталоге - PullRequest
4 голосов
/ 15 марта 2020

#include по соглашению использует кавычки против угловых скобок, чтобы указать, должен ли препроцессор искать текущий каталог перед каталогами системных заголовков.

Предположим, вы хотите искать только текущий каталог и остановитесь с ошибкой, если файл там не найден. Допустимо ли это делать с путем, а не только с именем файла? Такие как

#include "./foo.h"

Ответы [ 2 ]

3 голосов
/ 15 марта 2020

Стандартный #include синтаксис не поддерживает то, что вы запрашиваете.

Однако вы можете обойти эту проблему двумя способами:

  1. Если вы только Нужно включить файлы в текущий каталог, тогда флага G CC -nostdinc будет достаточно. Он подавляет стандартные пути включения и оставляет только текущий каталог.

    $ echo 'int func(void) {return 1;}' > foo.h
    $ echo '#include "foo.h"' | gcc -E -              # success
    $ echo '#include "foo.h"' | gcc -nostdinc -E -    # success
    $ echo '#include "stdio.h"' | gcc -E -            # success
    $ echo '#include "stdio.h"' | gcc -nostdinc -E -  # failure
    
  2. Если вы также хотите иметь возможность включать другие файлы, вы можете использовать командную строку define, чтобы указать абсолютный путь к текущему каталогу и использовать его для включения файлов, которые находятся строго в текущем каталоге, используя их полный путь. Это все еще позволит вам использовать обычный синтаксис включения для других библиотек, а также довольно легко интегрировать в Makefile.

    Файл для импорта строго из текущего каталога (foo.h):

    int func(void) {return 1;}
    

    Файл, в который вы хотите выполнить импорт (test.c):

    #define XSTR(x) #x
    #define STR(x) XSTR(x)
    #define ABSOLUTE_PATH(lib) STR(CUR_DIR_PATH/lib)
    
    #include ABSOLUTE_PATH(foo.h)
    

    Командная строка:

    $ gcc -DCUR_DIR_PATH=$(pwd) -E test.c
    

    Добавление #include ABSOLUTE_PATH(stdio.h) к test.c приведет к тому, что вышеприведенный сбой, как и предполагалось:

    $ echo '#include ABSOLUTE_PATH(stdio.h)' >> test.c
    $ gcc -DCUR_DIR_PATH=$(pwd) -E test.c
    test.c:7:33: fatal error: /home/marco/stdio.h: No such file or directory
    

    Протестировано с G CC и лязг и все отлично работает.

2 голосов
/ 15 марта 2020

Это будет зависеть от компилятора, так как стандарт называет его определяемым реализацией .

Интересно, что G CC документы также не имеют В любом случае, говорить об этом нельзя, но, несмотря на здравый смысл, предполагающий, что ваша гипотеза верна, эксперименты с G CC 4.8.5 говорят об обратном:

$ mkdir test
$ touch test/inc.h
$ echo '#include "./inc.h"' > test.cpp
$ g++ test.cpp -Itest -c
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
...