首页 文章

CMake / Linker交叉编译OpenWRT

提问于
浏览
0

不幸的是,由于链接问题,我暂停了OpenWRT下我的软件的移植,但为了更深入地解决上述问题,我需要简要介绍一下我的软件的一些细节 .

它由三个模块组成:LIB-1,LIB-2和APP .

我通过CMake交叉编译(我成功地遵循了本指南http://www.vtk.org/Wiki/CMake_Cross_Com … chain_file),并且我已经使用最新的官方BUILDROOT工具构建了一个工具链和目标Generic-x86 OpenWRT图像(它在VirtualBox下工作,就像一个魅力) .

我将CMAKE_LIBRARY_OUTPUT_DIRECTORY和CMAKE_RUNTIME_OUTPUT_DIRECTORY设置为公共文件夹($ / bin),以便将所有二进制文件放入同一文件夹中 .

现在,我为LUbuntu构建项目,并在ouput文件夹中找到LIB-1.so,LIB-2.so和APP,如预期的那样 . 然后我在APP上执行'ldd',我看到它按预期引用了LIB-1.so和LIB-2.so . 通过详细的CMake输出,我还看到CMake设置(如预期的)指向'$ / bin'的RPATH .

现在进入问题详情......

我为OpenWRT构建项目,并在输出文件夹中找到所有三个文件,如预期的那样 . 然后我执行'ldd'和'objdump -x',我看到APP链接到'../bin/LIB-1.so'和'../bin/LIB-2.so'(文件名加一个亲戚)路径前缀!!!) . 另一个区别是CMake(我不知道为什么)不会在链接命令行上添加RPATH!

为了让APP链接到没有相对'../bin'路径的两个库,我必须将两个SO文件放在APP链接文件夹中,并手动运行链接器剥去'../bin/'前缀,并添加'-Wl,-rpath,$ / bin' .

有人可以解释我:

1)为什么CMake使用不同的命令行参数链接两个平台?

2)如何与CMake链接避免嵌入相对的.SO路径?

3)如果没有读者使用CMake,有人可以告诉我是否存在G接头的附加参数来剥离引用的LIB的相对路径?

非常感谢你!

1 回答

  • 0

    目前我找到了解决方法 .

    我创建了一个这样的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构建根目录中 .

    我希望它对你也有用 .

相关问题