libstdc++.so: 添加符号时出错:文件格式错误
libstdc++.so: error adding symbols: File in wrong format
我正在尝试构建自己的库。它在 x86 linux 上工作,所以我想为 MIPS Linux(小端。)
构建
我正在使用 sourcery codebench in Mento Graphics and buildroot 和 CMake。
我配置了 build_all.sh 如下。
#!/bin/bash -ev
export TARGETROOT="/usr/mipsel-buildroot-linux-gnu/sysroot"
mkdir -p mips_build
cd mips_build
cmake -DCMAKE_SYSTEM_NAME="Linux" \
-DCMAKE_C_COMPILER="${CROSS_COMPILE}gcc" \
-DCMAKE_CXX_COMPILER="${CROSS_COMPILE}g++" \
-DCMAKE_AR="${CROSS_COMPILE}ar" \
-DCMAKE_C_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
-DCMAKE_CXX_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
../
make
cd ..
其中$CROSS_COMPILE=/home/vagrant/bd1/mips-2014.05/bin/mips-linux-gnu-
和CMakeFiles.txt如下。
make_minimum_required (VERSION 2.6)
set(EMSG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../src/eagle_msg/include )
set(EMSG_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib )
set (PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJECT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(LIBRARIES
libemsg.a
libzmq.a
libprotobuf.a
libprotobuf-c.a
libpthread.a
libstdc++.a
)
#For controller : Client
SET(EXECUTABLE test_controller)
project (${EXECUTABLE})
include_directories(
${PROJECT_INCLUDE_DIR}
${EMSG_INCLUDE_DIR}
$ENV{TARGETROOT}/usr/include
)
link_directories(
${PROJECT_LIB_DIR}
${EMSG_LIB_DIR}
$ENV{TARGETROOT}/usr/lib
)
set(SRCS
test_controller.cpp
)
add_executable( ${EXECUTABLE} ${SRCS})
target_link_libraries( ${EXECUTABLE} ${LIBRARIES} )
然后就会报如下错误。
[ 40%] Built target emsg
Linking CXX executable ../../../bin/test_controller
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: *** [../bin/test_controller] Error 1
make[1]: *** [test/emsg_test/CMakeFiles/test_controller.dir/all] Error 2
于是查看了libstdc++.so的格式。然后是ELF 32位LSB共享对象,MIPS,MIPS32。那是正确的版本。那我该怎么做才能解决呢?
/usr/mipsel-buildroot-linux-gnu/sysroot# file /usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.*
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.a: current ar archive
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6.0.19: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, with unknown capability 0xf41 = 0x756e6700, not stripped
新信息
好像是buildroot的问题。我检查了 mips-linux-gnu-gcc 的 sysroot 值。
这是安装buildroot之前的结果。
$ mips-linux-gnu-gcc --print-sysroot
/home/vagrant/bd1/mips-2014.05/bin/../mips-linux-gnu/libc
这是安装buildroot后的结果。
$ mips-linux-gnu-gcc --print-sysroot
/usr/usr/mipsel-buildroot-linux-gnu/sysroot/soft-float/el
我也发现了 post 类似的问题。但这是老问题了。
找到原因了。主要原因是 sysroot 路径。 Buildroot 将所有工具链组织到 $BUILDROOT/output/host/ 中。所以你应该像下面这样改变 PATH 环境。
HOST_BINARY="$BUILDROOT/output/host/usr/bin"
PATH="${PATH}:${HOST_BINARY}"
其中 $BUILDROOT
是提取 buildroot 的文件夹。
您应该使用下面的工具链 $BUILDROOT/output/host/usr/bin
。
请使用Buildroot提供的CMake工具链文件。它是在 $(HOST_DIR)/usr/share/buildroot/toolchainfile.cmake
中生成的。这样使用:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/host/usr/share/buildroot/toolchainfile.cmake
然后您可以删除所有其他 -DCMAKE_ 变量,因为工具链文件向 CMake 指示要使用哪个编译器、哪些标志等。
我正在尝试构建自己的库。它在 x86 linux 上工作,所以我想为 MIPS Linux(小端。)
构建我正在使用 sourcery codebench in Mento Graphics and buildroot 和 CMake。
我配置了 build_all.sh 如下。
#!/bin/bash -ev
export TARGETROOT="/usr/mipsel-buildroot-linux-gnu/sysroot"
mkdir -p mips_build
cd mips_build
cmake -DCMAKE_SYSTEM_NAME="Linux" \
-DCMAKE_C_COMPILER="${CROSS_COMPILE}gcc" \
-DCMAKE_CXX_COMPILER="${CROSS_COMPILE}g++" \
-DCMAKE_AR="${CROSS_COMPILE}ar" \
-DCMAKE_C_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
-DCMAKE_CXX_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
../
make
cd ..
其中$CROSS_COMPILE=/home/vagrant/bd1/mips-2014.05/bin/mips-linux-gnu-
和CMakeFiles.txt如下。
make_minimum_required (VERSION 2.6)
set(EMSG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../src/eagle_msg/include )
set(EMSG_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib )
set (PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJECT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(LIBRARIES
libemsg.a
libzmq.a
libprotobuf.a
libprotobuf-c.a
libpthread.a
libstdc++.a
)
#For controller : Client
SET(EXECUTABLE test_controller)
project (${EXECUTABLE})
include_directories(
${PROJECT_INCLUDE_DIR}
${EMSG_INCLUDE_DIR}
$ENV{TARGETROOT}/usr/include
)
link_directories(
${PROJECT_LIB_DIR}
${EMSG_LIB_DIR}
$ENV{TARGETROOT}/usr/lib
)
set(SRCS
test_controller.cpp
)
add_executable( ${EXECUTABLE} ${SRCS})
target_link_libraries( ${EXECUTABLE} ${LIBRARIES} )
然后就会报如下错误。
[ 40%] Built target emsg
Linking CXX executable ../../../bin/test_controller
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: *** [../bin/test_controller] Error 1
make[1]: *** [test/emsg_test/CMakeFiles/test_controller.dir/all] Error 2
于是查看了libstdc++.so的格式。然后是ELF 32位LSB共享对象,MIPS,MIPS32。那是正确的版本。那我该怎么做才能解决呢?
/usr/mipsel-buildroot-linux-gnu/sysroot# file /usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.*
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.a: current ar archive
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6.0.19: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, with unknown capability 0xf41 = 0x756e6700, not stripped
新信息
好像是buildroot的问题。我检查了 mips-linux-gnu-gcc 的 sysroot 值。
这是安装buildroot之前的结果。
$ mips-linux-gnu-gcc --print-sysroot
/home/vagrant/bd1/mips-2014.05/bin/../mips-linux-gnu/libc
这是安装buildroot后的结果。
$ mips-linux-gnu-gcc --print-sysroot
/usr/usr/mipsel-buildroot-linux-gnu/sysroot/soft-float/el
我也发现了 post 类似的问题。但这是老问题了。
找到原因了。主要原因是 sysroot 路径。 Buildroot 将所有工具链组织到 $BUILDROOT/output/host/ 中。所以你应该像下面这样改变 PATH 环境。
HOST_BINARY="$BUILDROOT/output/host/usr/bin"
PATH="${PATH}:${HOST_BINARY}"
其中 $BUILDROOT
是提取 buildroot 的文件夹。
您应该使用下面的工具链 $BUILDROOT/output/host/usr/bin
。
请使用Buildroot提供的CMake工具链文件。它是在 $(HOST_DIR)/usr/share/buildroot/toolchainfile.cmake
中生成的。这样使用:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/host/usr/share/buildroot/toolchainfile.cmake
然后您可以删除所有其他 -DCMAKE_ 变量,因为工具链文件向 CMake 指示要使用哪个编译器、哪些标志等。