针对OpenWRT的CMake/Linker交叉编译
CMake/Linker cross compile for OpenWRT
不幸的是,由于链接问题,我暂停了在OpenWRT下移植我的一个软件,但为了深入了解上述问题,我需要简要地向您介绍我的软件的一些细节。
它由三个模块组成:LIB-1、LIB-2和APP。
我正在使用Netbeans/C++和CMake在LUbuntu下开发它。我是CMake的交叉编译(我成功地遵循了本指南http://www.vtk.org/Wiki/CMake_Cross_Com…chain_file)和一个我已经通过最新的官方BUILDROOT工具构建了一个工具链和一个目标Generic-x86 OpenWRT映像(它在VirtualBox下像魅力一样工作)。
我将CMAKE_LIBRARY_OUTPUT_DIRECTORY和CMAKE_RUNTIME_OUTPUT_DIRECT设置为一个公用文件夹(${CMAKE_BINARY_DIR}/bin),以便将所有二进制文件都放在同一文件夹中。
现在,我为LUbuntu构建了项目,在ouput文件夹中,我找到了LIB-1.so、LIB-2.so和APP,正如预期的那样。然后我在APP上执行"ldd",我看到它像预期的那样引用了LIB-1.so和LIB-2.so。通过详细的CMake输出,我还看到CMake设置(如预期)指向"${CMake_BINARY_DIR}/bin"的RPATH。
现在进入问题细节。。。
我为OpenWRT构建了项目,在输出文件夹中,我找到了所有这三个文件,正如预期的那样。然后我执行ldd和objdump-x,我看到APP链接到/bin/LIB-1.so和/bin/LIB-2.so'(文件名加上相对路径前缀!!)。另一个区别是CMake(我不知道为什么)没有在链接命令行上添加RPATH!
为了让APP链接到两个库,而不使用相对的"/bin'路径,我必须将两个SO文件放在APP链接文件夹中,并手动运行链接器剥离'/bin/"前缀,并添加"-Wl,-rpath,${CMAKE_BINARY_DIR}/bin"。
有人能解释一下吗:
1) 为什么CMake使用不同的命令行参数链接两个平台?
2) 如何链接CMake避免嵌入相对。SO路径?
3) 如果没有读者使用CMake,有人能告诉我是否存在G++链接器的额外参数,以从引用的LIB中剥离相对路径吗?
非常感谢!
目前我找到了一个解决方法。
我创建了一个类似这样的bash脚本(openwrt-fix-libs):
#!/bin/bash
TARGET_NAME=$1
OUTPUT_DIR=$2
# Prologue
ECHO_PREFIX=[----]
echo "$ECHO_PREFIX Fixing OpenWRT library imports for "$TARGET_NAME"..."
# Dependencies copy
echo "$ECHO_PREFIX Copying libraries locally from "$OUTPUT_DIR"...";
cp $OUTPUT_DIR/*.so .
if [ $? != 0 ]; then
exit 1
fi
# Link command hacking
LINK_COMMAND=./CMakeFiles/$TARGET_NAME.dir/link.txt
echo "$ECHO_PREFIX Hacking link command at "$LINK_COMMAND"..."
LINK_COMMAND=$(cat $LINK_COMMAND | sed -e 's/../bin///g')
#echo "$ECHO_PREFIX <$LINK_COMMAND>"
if [ $? != 0 ]; then
exit 1
fi
# Re-linking
echo "$ECHO_PREFIX Re-linking...";
$LINK_COMMAND
if [ $? != 0 ]; then
exit 1
fi
# Update rebuilt binary
echo "$ECHO_PREFIX Updating "$TARGET_NAME" binary..."
cp *$TARGET_NAME* ${OUTPUT_DIR}
if [ $? != 0 ]; then
exit 1
fi
# Epilogue
echo "$ECHO_PREFIX Libraries imports successfully fixed."
然后,我在我需要的任何模块的CMakeLists.txt文件中添加了这个自定义命令:
if (_PLATFORM STREQUAL "OPENWRT")
add_custom_command(
TARGET ${_TARGET_NAME}
POST_BUILD COMMAND ${_GLOBAL_SCRIPTS_DIR}/openwrt-fix-libs ${_TARGET_NAME} ${_GLOBAL_OUTPUT_DIR}
)
endif (_PLATFORM STREQUAL "OPENWRT")
其中_PLATFORM是我为OpenWRT编译时在命令行上设置的符号,_GLOBAL_SCRIPTS_DIR为我的项目脚本文件夹,_GLOBAL_OUTPUT_DIR然后bin位于CMake构建根目录中。
我希望它对你也有用。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 用于交叉编译和CMake的预处理器宏的单元测试
- 在Linux上使用Clang / OLLVM交叉编译helloworld Windows可执行文件时的问题
- 无法使用 aarch64-unknown-nto-qnx7.0.0-g++-5.4.0 编译器交叉编译 QNX 平台的
- 如何使用导出的函数交叉编译 DLL
- 交叉编译:特殊的交叉编译器还是只是带有选项 -march 的 gcc?
- 交叉编译时包括外部库
- 如何交叉编译C++文件
- SFML 交叉编译 for Windows on Linux.
- 使用 cmake 交叉编译 libwebsockets
- 使用cmake交叉编译gRPC
- 为什么Qt必须从源代码构建以进行交叉编译?
- 交叉编译树莓派
- Microsoft Visual Studio 2019交叉编译CMake库 - 有效,但存在SEG错误
- Jlibfprint 交叉编译
- 在Linux上交叉编译Windows应用程序时如何链接到Winsock?
- GPS 的交叉编译显示"unrecognized option"
- clang 交叉编译命令找不到头文件
- 交叉编译时 NDK 工具链中的 /system/bin/linker 在哪里
- 针对OpenWRT的CMake/Linker交叉编译