cmake 链接“.a”文件,apply --whole-archive到.a文件中的单个.o文件?

wyyhbhjk  于 2023-11-19  发布在  Hive
关注(0)|答案(1)|浏览(188)

我有一个.a文件的单个.o文件,我想强制链接它,而不认为它是未使用的,但我不想占用整个静态库。
有没有一个选项可以告诉链接器考虑使用那个.o文件,而不引用那个.o文件中的伪变量?就像下面想象的语法一样?

gcc --use-o-file=archive.a:file.o  archive.a main.cc

字符串
其动机是Qt的一个..._qmltyperegistrations.cpp文件,其中Qt注册了几个与QML/JavaScript一起使用的类,其代码旨在在程序开始时执行。不幸的是,该文件被链接器丢弃,因为任何人都没有引用该文件的任何符号。
Qt的CMake函数本身显然不处理这个问题,所以我试着找到一个解决办法。如果这些文件被放入CMake的“OBJECT”库,而不是被添加到“STATIC”库,这应该会起作用。
回答后续的问题-所有的都是“是”,但我宁愿不在我的代码中引用。cc文件。我希望保留CMake函数背后的所有逻辑。

  • 你负责建立静态库吗?;

是的,我会的

  • 你能修改它的构建方式吗?你能创建一个可重定位的对象文件吗?

是的!这能解决问题吗?

  • 或者,您是否可以添加一个对象文件,其中包含(a)对必须链接的每个对象文件中至少一个相关符号的引用,以及(b)您的代码确实引用的符号(函数),即使它实际上没有被调用?

是的,我会的
我当前的解决方法是执行以下操作

execute_process(
   COMMAND ${CMAKE_COMMAND} -E echo "void qml_register_types_ZesFrontend() { }"
   COMMAND ${CMAKE_CXX_COMPILER} -xc++ -S -w -o - -
   COMMAND grep -Po [[^_Z.+(?=:)]]
   OUTPUT_VARIABLE mangled_initializer
)

target_link_options(zes_frontend INTERFACE SHELL:-u "${mangled_initializer}")


这首先生成在.o文件中定义的初始化函数的变形名,然后告诉编译器,无论何时链接.a文件,都应将其变形名视为未定义,以便链接.o文件
由于这有点粗糙,而且不是很可移植,我将用cmake生成一个临时输出文件,并在那里引用符号。

kcrjzv8t

kcrjzv8t1#

我最后的解决方法看起来像这样:

qt_add_qml_module(zes_frontend
   URI ZesFrontend
   ...
)

file(CONFIGURE 
   OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zes_frontend_qmltyperegistrationsuser.cpp 
   CONTENT "
      void qml_register_types_ZesFrontend();
      static volatile auto use = &qml_register_types_ZesFrontend;
   "
   @ONLY)
target_sources(zes_frontend INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/zes_frontend_qmltyperegistrationsuser.cpp)

字符串
使用file(CONFIGURE语法是为了访问CMake-Variables(例如模块的名称)。为了简单起见,我们在这里硬编码。

相关问题