【问题标题】:CMake/Linker cross compile for OpenWRT用于 OpenWRT 的 CMake/Linker 交叉编译
【发布时间】:2016-08-25 18:53:53
【问题描述】:

很遗憾,由于链接问题,我暂停了在 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_DIRECTORY 设置为一个公共文件夹 (${CMAKE_BINARY_DIR}/bin),以便将所有二进制文件放在同一个文件夹中。

现在,我为 LUbuntu 构建项目,并在输出文件夹中找到 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 中去除相对路径?

非常感谢!

【问题讨论】:

    标签: c++ linux gcc cmake openwrt


    【解决方案1】:

    暂时我找到了解决方法。

    我创建了一个这样的 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 然后在 CMake 构建根目录中的 bin

    希望它对你也有用。

    【讨论】:

      猜你喜欢
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      相关资源
      最近更新 更多