【问题标题】:CMake cross compilation fails during linking stage on host (target is Raspberry Pi)CMake 交叉编译在主机上的链接阶段失败(目标是 Raspberry Pi)
【发布时间】:2014-06-10 12:52:03
【问题描述】:

我的源码树是

cpp
├── bin
├── CMakeLists.txt
├── src
├── headers
├── Makefile
├── TestConfig.h
├── TestConfig.h.in
├── README.txt
├── third_party
├── x_build
└── xtoolchain.cmake

我正在使用crosstool-ng

编辑: 附加信息(可能对其他人有所帮助):我使用了 http://xecdesign.com/qemu-emulating-raspberry-pi-the-easy-way/ 的引用通过 QEMU 引导 RPI(重要的是,将 img 文件的大小调整为 8GB)。

qemu-img resize 2014-01-07-wheezy-raspbian.img +6G
sudo fdisk /dev/mmcblk0
- use "parted" or 'd' options to delete the 2nd partition and then recreate it but with a larger size. (don't worry, the data will remain). 1st partition is vfat.
- reboot to activate the partition changes.
- use "sudo resize2fs /dev/mmclk0p2" (or /dev/sda2 if symlink set in udev rules) to enlarge the root file system.
- use e2fsck -f /dev/mmcblk0p2 to perform a file system check.

使用apt-get 安装了所有lib<package>-dev 和其他库。然后关闭 QEMU

mkdir -p /tmp/rasp
sudo mount /home/test/raspberrypi/2014-01-07-wheezy-raspbian.img /tmp/rasp/ -o offset=$((122880*512))
cd $HOME/raspberrypi
sudo cp -ar /tmp/rasp ./rootfs
sudo chown -R $USER:$USER rootfs/home/pi
cd $HOME/raspberrypi/rootfs 

# also small hack around: error "Never use <bits/predefs.h> directly; include <stdc-predef.h> instead."
sudo cp /home/test/raspberrypi/rootfs/usr/include/features.h /home/test/raspberrypi/rootfs/usr/include/features.h-
sudo cp /home/test/local/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/sysroot/usr/include/features.h /home/test/raspberrypi/rootfs/usr/include
    sudo umount /tmp/rasp

我还设置了目标文件系统/home/test/raspberrypi/rootfs(这包含了已经安装的交叉编译所需的所有库)

xtoolchain.cmake 如下所示

# ========================= CROSS COMPILATION INITIALIZATION BEGIN =======================
# this one is important
SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)

# specify the cross compiler
SET(CMAKE_C_COMPILER
$ENV{HOME}/local/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER
$ENV{HOME}/local/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-g++)

# where is the target environment
#SET(CMAKE_FIND_ROOT_PATH
#/home/test/local/x-tools/arm-unknown-linux-gnueabi /home/test/raspberrypi/rootfs)

SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs)


# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

#include_directories ("/home/test/local/raspidev/include")
# ========================= CROSS COMPILATION INITIALIZATION END =========================

src 目录中的 CMakeLists.txt(这是在父目录中的 CMakeLists.txt 的补充,您可以从文件结构中看到)部分看起来像

cmake_minimum_required(VERSION 2.8)
...
...
...
#Change 1 to 0 to disable logging
add_definitions(-DENABLE_LOG=1)

set(CMAKE_PREFIX_PATH $ENV{HOME}/raspberrypi/rootfs/)
set(CMAKE_LIBRARY_PATH $ENV{HOME}/raspberrypi/rootfs/lib:$ENV{HOME}/raspberrypi/rootfs/usr/lib:$ENV{HOME}/raspberrypi/rootfs/usr/local/lib)
set(CMAKE_MODULE_PATH $ENV{HOME}/raspberrypi/rootfs/usr/share/cmake-2.8/Modules)

#rdynamic is for stack unwinding on crash
set(CMAKE_CXX_FLAGS "-W -O3 -g -Wall -std=c++0x -rdynamic -D_AIBTRACE ${CMAKE_CXX_FLAGS}")

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})

include_directories ("${PROJECT_SOURCE_DIR}/headers")
#add_subdirectory (headers)
...
...
...
# ======================== SQLITE3 =================================

pkg_check_modules(SQLITE3 REQUIRED sqlite3)
include_directories(${SQLITE3_INCLUDE_DIRS})
...
...  (...And other libraries)

我在x_build 目录中进行了源外构建。如下 cmake -DCMAKE_TOOLCHAIN_FILE=/home/test/xcompile/cpp/xtoolchain.cmake ../

奇怪的是,它似乎链接的是宿主库而不是目标库。 make VERBOSE=1 显示这个

它为所有库引发链接器错误(这些库肯定存在于目标系统rootfs

/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -lgmodule-2.0
/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -lgthread-2.0
/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -lxml2
/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -lglib-2.0
/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -lsqlite3
/home/test/local/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.7.3/../../../../arm-unknown-linux-gnueabi/bin/ld: cannot find -ldbus-1
collect2: error: ld returned 1 exit status

我有点迷茫。

编辑:

根据这里的要求,还有一些来自CMakeLists.txt的东西

set (SOURCES
file1.cc
file2.cc
main.cc
)

# Similarly, why not concise files grouping that will be reused ;)?
set (COMMONS_LIBS
${OpenCV_LIBS} 
pthread
${GLIBMM_LIBRARIES} 
${GTKMM_LIBRARIES} 
#${GSTMM_LIBRARIES}
${GSTREAMER_LIBRARIES}
${SQLITE3_LIBRARIES}
#${DBUS_GLIB_LIBRARY}
${DBUS_LIBRARIES}
${DBUS_GLIB_LIBRARIES}
${OPENSSL_LIBRARIES}
)

add_executable (
${EXE_DAEMON} 
${SOURCES} 
)

target_link_libraries( 
${EXE_DAEMON} 
$COMMONS_LIBS}
)

install (TARGETS 
${EXE_DAEMON} 
DESTINATION bin)

【问题讨论】:

  • 你能告诉我们完整的ld命令吗?
  • @Peter 我的编辑有帮助吗?
  • 你能在这里粘贴完整链接命令(创建上面显示的错误的命令),而不是创建它的 CMakeLists.txt 吗?
  • @Peter,找到解决方案,查看答案。我显然错过了一些路径。除了 cmake 博客页面上的跨工具链设置列表之外,这些似乎是必要的。
  • 请不要在标题中添加“[已解决]”。表明您的问题已解决的方法是接受答案。 (是的,接受你自己的答案是完全可以接受的。)

标签: c cmake raspberry-pi cross-compiling embedded-linux


【解决方案1】:

我在 CMakeLists.txt 中添加了以下内容,然后在下面进行了一些更改并使其正常工作!

include($ENV{HOME}/raspberrypi/rootfs/usr/share/cmake-2.8/Modules/FindPkgConfig.cmake)
set(CMAKE_PREFIX_PATH $ENV{HOME}/raspberrypi/rootfs/)
set(SYSROOT $ENV{HOME}/raspberrypi/rootfs/)
set (PKG_CONFIG_SYSROOT_DIR ${SYSROOT})
set(PKG_CONFIG_PATH ${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/local/lib/pkgconfig:${SYSROOT}/usr/lib/arm-linux-gnueabihf/pkgconfig:${SYSROOT}/usr/share/pkgconfig)
#Change 1 to 0 to disable logging
add_definitions(-DENABLE_LOG=1)
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config PATHS /usr/bin DOC "pkg-config executable" NO_CMAKE_FIND_ROOT_PATH)
set (CMAKE_CXX_FLAGS "-W -O3 -g -Wall -std=c++0x -rdynamic  -D_TRACE ${CMAKE_CXX_FLAGS}"  CACHE STRING "" FORCE)
#rdynamic is for stack unwinding on crash
set(CMAKE_PREFIX_PATH $ENV{HOME}/raspberrypi/rootfs/)
set(CMAKE_LIBRARY_PATH $ENV{HOME}/raspberrypi/rootfs/lib:$ENV{HOME}/raspberrypi/rootfs/usr/lib:$ENV{HOME}/raspberrypi/rootfs/usr/local/lib)
set(CMAKE_MODULE_PATH $ENV{HOME}/raspberrypi/rootfs/usr/share/cmake-2.8/Modules)

include_directories(SYSTEM
$ENV{HOME}/raspberrypi/rootfs/usr/include/arm-linux-gnueabihf
$ENV{HOME}/raspberrypi/rootfs/usr/include
$ENV{HOME}/raspberrypi/rootfs/usr/local/include
)

add_definitions(
-march=armv6zk 
-mfpu=vfp 
-mfloat-abi=hard
)

link_directories(

$ENV{HOME}/raspberrypi/rootfs/lib/arm-linux-gnueabihf
$ENV{HOME}/raspberrypi/rootfs/lib
$ENV{HOME}/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf
$ENV{HOME}/raspberrypi/rootfs/usr/lib
$ENV{HOME}/raspberrypi/rootfs/usr/local/lib
)   

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${CMAKE_CXX_FLAGS})

然后做了以下

sudo vim /home/test/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf/libpthread.so

编辑

OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/arm-linux-gnueabihf/libpthread.so.0 /usr/lib/arm-linux-gnueabihf/libpthread_nonshared.a )

OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libpthread.so.0 libpthread_nonshared.a )

同样,

sudo vim /home/test/raspberrypi/rootfs/usr/lib/arm-linux-gnueabihf/libc.so

编辑

OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/arm-linux-gnueabihf/libc.so.6 /usr/lib/arm-linux-gnueabihf/libc_nonshared.a  AS_NEEDED ( /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 ) ) 

OUTPUT_FORMAT(elf32-littlearm)
GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux-armhf.so.3 ) )

最后,我将-lpcre 库添加到我的COMMON_LIBS

编译成功。然后我通过 QEMU 启动 raspberrypi 并使用 scp scp daemon pi@&lt;ip address&gt;:~ 将生成的二进制文件传输到 PI 模拟器并运行它。多多!!!效果很好!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2014-04-10
    • 2013-10-10
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多