У меня есть библиотека под названием Print
и функция println
, которая имитирует printf
. Если скомпилировано с директивой USE_DEBUG_PRINT
, println
на самом деле что-то напечатает. Если он скомпилирован без этого определения, он ничего не печатает.
Затем я хочу использовать эту библиотеку внутри другой библиотеки, назовем ее A
. A
использует Print
с этой директивой. Другая библиотека, «B», использует «Print» без этой директивы, поэтому println
имеет для них другое поведение.
Однако при компиляции в приложение, в зависимости от порядка ссылок, B
будет использовать println
из A
или наоборот. Это происходит потому, что символ println
определен для обеих библиотек, поэтому компоновщик просто выбирает первую.
Как я могу вместо этого сделать Print
«приватным» для этих библиотек? Я не хочу, чтобы кто-либо, использующий A
или B
, независимо от этого имел доступ к функции println
, чтобы их можно было просто «объединить» вместе, не допуская println
к файлам 1.txt
и используя их только в своих реализациях.
Я использую Clang и CMake для создания как библиотек, так и приложения. Print
— это библиотека объектов, а остальные — статические.
Вы имеете в виду статическое связывание или динамическое связывание?
они статические или разделяемые библиотеки? Если они статичны, вы ничего не можете сделать, кроме как дать функциям разные имена/пространства имен.
Кроме того, в любом случае, если вам удалось получить определение в каждой библиотеке, это указывает на то, что println
является встроенной функцией. В этом случае вы даже не можете предотвратить его встраивание в сайты вызовов. Даже если он не является встроенным, вам нужно убедиться, что он определен в отдельной единице перевода без какой-либо оптимизации времени компоновки или (для динамической компоновки) что -fsemantic-interposition
включен ((на данный момент?) по умолчанию на gcc, но не лязг).
вы можете связать любую версию библиотеки, которую хотите, просто используйте make/cmake/...... и передайте это определение через параметры компиляции
«Печать — это библиотека объектов»: что вы имеете в виду под «библиотекой объектов»? Что еще более важно: является ли println
встроенной функцией и где/как она определяется? Как вам удается компилировать библиотеки с разными версиями определения?
Похоже, у вас есть две библиотеки с идентичными API и в основном идентичными функциями, для которых вы поддерживаете единую базу кода. Я не знаю, используется ли println() внутри библиотеки. Если нет, вы можете попробовать изменить библиотеку и включить функции printlnDebug() и printlnDoNothing(). Затем вы можете предоставить 2 разных файловых интерфейса .h для клиентов. Эти файлы .h обеспечили бы тривиальную маршрутизацию println() в анонимном пространстве имен. С более обширным удалением с библиотекой это также может быть изменено для обработки внутреннего случая println().
Мне удалось решить эту проблему, выполнив следующие действия:
println
помечен как static
.Таким образом, его можно включить в любой файл .cpp
и скомпилировать с заданными параметрами, не затрагивая другие компиляции.
Радости нарушения ODR.