简体   繁体   中英

CMake/Linker cross compile for OpenWRT

unfortunately I have paused the porting of a software of mine under OpenWRT due to a linking problem, but in order to go deeper into the above issue I need to briefly give you some details about my software.

It is made of three modules: LIB-1, LIB-2 and APP.

I'm developing it under LUbuntu with Netbeans/C++ and CMake. I'm cross compiling by CMake (I successfully followed this guide http://www.vtk.org/Wiki/CMake_Cross_Com … chain_file ) and a I have built a toolchain and a target Generic-x86 OpenWRT image by the latest official BUILDROOT tool (it works under VirtualBox like a charm).

I set the CMAKE_LIBRARY_OUTPUT_DIRECTORY and CMAKE_RUNTIME_OUTPUT_DIRECTORY to a common folder (${CMAKE_BINARY_DIR}/bin) in order to have all the binaries into the same folder.

Now, I build the project for LUbuntu and inside the ouput folder I find LIB-1.so, LIB-2.so and APP, as expected. Then I execute 'ldd' on APP and I see it referencing LIB-1.so and LIB-2.so as expected. By the verbose CMake output I see also that CMake sets (as expected) the RPATH which points to '${CMAKE_BINARY_DIR}/bin'.

Now go into the issue details...

I build the project for OpenWRT and inside the output folder I find all the three files, as expected. Then I execute 'ldd' and 'objdump -x' and I see that APP links to '../bin/LIB-1.so' and '../bin/LIB-2.so' (file name plus a relative path prefix!!!). The other difference is that CMake (I don't know why) does not add the RPATH on the linking command line!

In order to get APP linked to the two libraries without the relative '../bin' path, I have to put the two SO files inside the APP linking folder, and manually run the linker stripping the '../bin/' prefix, and adding '-Wl,-rpath,${CMAKE_BINARY_DIR}/bin' too.

Could anybody explain me:

1) Why CMake links the two platforms using different command line parameters?

2) How can I link with CMake avoind embedding the relative .SO path?

3) If none of the readers uses CMake, could somebody tell me if exists an additional parameter for the G++ linker to strip relative paths from the referenced LIBs?

Thank you very much!

for the moment I found a workaround.

I create a bash script like this ( 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."

Then I added into the CMakeLists.txt file of any module I need it this custom command:

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")

Where _PLATFORM is a symbol set by me on the command line when I compile for OpenWRT, _GLOBAL_SCRIPTS_DIR is my project scripts folder, and _GLOBAL_OUTPUT_DIR then bin inside the CMake building root.

I hope it maybe useful for you too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM