У меня есть библиотека под названием 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.