Библиотека включает в себя пути с одинаковым именем заголовка
Каков наилучший способ включить файл с таким же именем в другую папку из дополнительных каталогов include?
Пример:
lib1/include/foo.h
lib2/include/foo.h
где оба lib1/include и lib2/include добавляются в дополнительные каталоги include.
Edit:
Библиотеки из разных SDK, и каждый разработчик устанавливает их на свое место. Единственное, что есть уверенность в том, что обе папки в IDE включают дополнительные пути
метод 1:
#include "../../lib1/include/foo.h
method2:
Добавить lib1/include перед lib2/include в пути поиска и потому, что они выполняются по порядку с помощью:
#include "foo.h"
lib1/include/foo.h будет включен
Ответы
Ответ 1
Во-первых, этот ответ предполагает, что включенные охранники для двух заголовков совместимы (т.е. не одни и те же символы).
Одна вещь, которую вы можете сделать, - создать ссылки в известных местах в интересующих заголовочных файлах, давая своим ссылкам разные имена. Например, предположим, что ваши две библиотеки установлены в $LIB1PATH и $LIB2PATH, которые могут иметь разные значения в разных средах сборки. Таким образом, заголовки, которые вы хотите получить, находятся в $LIB1PATH/include/foo.h и $LIB2PATH/include/foo.h.
Вы можете пойти двумя способами с этим. Одним из них является создание прямых ссылок. Это может выглядеть так в дереве каталогов проекта:
$PROJDIR/
include/
lib_include/
lib1_foo.h -> $LIB1PATH/include/foo.h
lib2_foo.h -> $LIB2PATH/include/foo.h
src/
Это может оказаться сложным, если ваш код находится в репозитории, потому что вы не можете проверить эти ссылки; они были бы неправы в других средах. Кроме того, если у вас есть много этих ссылок и несколько библиотек, вам придется воссоздавать их все, когда перемещаются lib1 или lib2... не круто. Вы можете обойти эту проблему, создав ссылки в каталоге, который содержит каталог проекта:
$PROJDIR/
include/
lib_include/
lib1_foo.h -> ../../lib1/include/foo.h
lib2_foo.h -> ../../lib2/include/foo.h
src/
lib1 -> $LIB1PATH/
lib2 -> $LIB2PATH/
В обоих случаях вам нужно убедиться, что $PROJDIR/lib_include
находится на вашем пути включения. Кроме того, вам нужно иметь $LIB1PATH/include
и $LIB2PATH/include
в вашем пути включения, если два заголовка foo.h
вытащить больше заголовков из этих каталогов. Вы также можете поместить ссылки в include
и избавиться от lib_include
, но мне нравится держать эти вещи в отдельности.
Ответ 2
#include "lib1/include/foo.h"
#include "lib2/include/foo.h"
Является прекрасным до тех пор, пока это фактический относительный путь к этим заголовкам и включенные охранники отличаются. Например, если оба foo.h используют
#ifndef _foo_h_
то это даст вам то, чего вы не хотите (оно будет включать только одно, а не то, и другое зависит от порядка выполнения).
Ответ 3
Вы можете просто сделать это:
#include "lib1/include/foo.h"
#include "lib2/include/foo.h"
и убедитесь, что родительские каталоги как lib1
, так и lib2
находятся в вашем пути поиска для include (но not фактических подкаталогов include
).
Обратите внимание, что если оба заголовка используют тот же символ, что и защитник включения, то этот метод не будет работать - вам нужно будет определить неопределенный конфликт между двумя:
#include "lib1/include/foo.h"
#undef FOO_H
#include "lib2/include/foo.h"
Ответ 4
Интересно, что с 4 ответами и 1709 мнениями в настоящий момент никто еще не советовал такое легкое и простое решение.
Вы можете включать файлы, как хотите, единственная реальная проблема, с которой вы собираетесь столкнуться, - это те же заголовки охранников. Таким образом, вы должны создать заголовок, который будет содержать конфликтующие файлы заголовков. Позвольте называть его inc_foo_lib1_lib2.h
. В этом файле вы включаете первый foo.h
, а затем, если заголовок защиты был определен, определите его, затем включите второй foo.h
.
В качестве примера предположим, что foo.h
имеет защиту заголовка FOO_H_INCLUDED
, тогда ваш inc_foo_lib1_lib2.h
выглядит так:
#include "lib1/foo.h"
#ifdef FOO_H_INCLUDED
#undef FOO_H_INCLUDED
#else
COMPILATION ERROR — the header guard was changed!
#endif //FOO_H_INCLUDED
#include "lib2/foo.h"
Ответ 5
Я бы включил файлы из однозначного каталога, который находится в списке -I
(То есть путь к каталогу, который содержит lib1 и lib2):
#include "lib1/include/foo.h"
#include "lib2/include/foo.h"
Поэтому не будет никакой двусмысленности, потому что прекомпилятор будет смотреть на lib1/include/foo.h
в своем списке каталогов и которые не происходят из lib1/include/
или lib2/include/
, а только из родительского каталога.
Как было сказано ранее: будьте осторожны с охранниками, даже если для заголовка lib имя должно содержать имя lib, чтобы избежать таких недоразумений.