如何在CMake中设置库链接优先级以覆盖指定方法?
解决符号重复定义及自定义包装优先调用的方案
以下是几种无需修改MyClass即可解决问题的方法:
1. 调整链接顺序,优先加载自定义实现
链接器会按照库的链接顺序解析符号,先找到的符号定义会被优先使用。你可以把包含自定义C包装的代码打包成一个静态库,然后将其放在BFciLib之前链接:
# 先把包装代码编译成静态库 add_library(BFciLibWrapper STATIC src/ClassWithCWrappers.cpp) # 链接时让自定义库优先于原库 target_link_libraries(NewMain PRIVATE BFciLibWrapper BFciLib GL ${GTKMM_LIBRARIES})
如果不想单独做库,也可以确保包装代码的源文件在编译时先于原库链接(CMake中源文件的顺序也会影响符号解析优先级)。
2. 使用链接器的符号包装选项(GCC/Clang)
针对GCC或Clang工具链,可以用--wrap选项让链接器自动替换目标符号:
- 把你的包装函数命名为
__wrap_原函数名,比如原函数是bfci_device_init,你的包装函数就叫__wrap_bfci_device_init - 在CMake中给
NewMain添加链接选项:
target_link_options(NewMain PRIVATE "-Wl,--wrap=bfci_device_init")
这样所有对bfci_device_init的调用都会被转到你的包装函数,如果你需要在包装里调用原函数,可以直接使用__real_bfci_device_init。
3. 利用宏替换重定向函数调用
在MyClass包含BFciLib头文件之前,通过宏定义把原函数名替换为你的包装函数名:
在ClassWithCWrappers.hpp中添加:
// 替换目标函数名 #define bfci_device_init my_bfci_device_init // 包含原库头文件 #include <BFciLib.h> // 取消宏定义,避免影响其他代码 #undef bfci_device_init
这样MyClass里调用bfci_device_init时,实际会调用你的my_bfci_device_init,原库的其他函数不受影响。注意要确保这个宏定义的作用范围只覆盖MyClass的编译单元。
4. 静态库符号优先级处理(针对静态BFciLib)
如果BFciLib是静态库,链接器在处理静态库时只会提取当前未解析符号所需的目标文件。你可以把自定义包装编译成静态库并优先链接,链接器会先使用你的包装符号,不会再从BFciLib中提取对应的目标文件,自然避免重复定义。
内容的提问来源于stack exchange,提问作者user3253067
相关产品推荐
相关产品推荐

