如何使用交叉编译器为 ARM 构建静态库 .a?

How to build static library .a for ARM using cross compiler?

我正在尝试为 ARM 设备静态编译 cpp-netlib and rpclib。(与 ZEDboard 相同)

我所做的一切都是在 CMakeLists.txt 文件中更改了编译器和系统设置。

    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR arm)

    set(CMAKE_SYSROOT /home/a/buildroot-2018.05/output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/)
    set(tools /home/a/buildroot-2018.05/output/host/bin/)
    set(CMAKE_C_COMPILER ${tools}arm-buildroot-linux-uclibcgnueabihf-gcc)
    set(CMAKE_CXX_COMPILER ${tools}arm-buildroot-linux-uclibcgnueabihf-g++)

    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

在 cmake i 运行 make 创建 Makefile 之后,没有产生任何输出。据我了解构建目录应该出现。

对于 rpclib,事情变得更好了。它已经编译了 librpc.a 文件,但不幸的是它没有 link 进入我的程序。

arm-buildroot-linux-uclibcgnueabihf-g++ -I/home/a/rpclib/include/ -Xlinker -static /home/a/rpclib/librpc.a main.cpp

产生这个输出:

/home/a/buildroot-2018.05/output/host/lib/gcc/arm-buildroot-linux-uclibcgnueabihf/6.4.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: cannot find -lgcc_s
/home/a/buildroot-2018.05/output/host/lib/gcc/arm-buildroot-linux-uclibcgnueabihf/6.4.0/../../../../arm-buildroot-linux-uclibcgnueabihf/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status

但是sysroot目录下有gcc_s

~/buildroot-2018.05/output/host/arm-buildroot-linux-uclibcgnueabihf$ find ./ -name *gcc_s*

./sysroot/lib/libgcc_s.so
./sysroot/lib/libgcc_s.so.1
./sysroot/usr/include/boost/asio/detail/gcc_sync_fenced_block.hpp
./sysroot/usr/include/boost/atomic/detail/caps_gcc_sync.hpp
./sysroot/usr/include/boost/atomic/detail/ops_gcc_sync.hpp
./sysroot/usr/include/boost/atomic/detail/ops_gcc_sparc.hpp
./sysroot/usr/include/boost/atomic/detail/caps_gcc_sparc.hpp
./sysroot/usr/include/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp
./lib/libgcc_s.so
./lib/libgcc_s.so.1

我想我遗漏了一些关于交叉编译的重要信息。 所以基本上我有 3 个问题:

实际上buildroot支持构建静态库。
使用 buildroot 构建自定义库的步骤:

  1. 在 buildroot/package 文件夹中创建一个名为目标库的文件夹。 例如我的路径看起来像这样 /home/a/buildroot-2018.05/package/rpclib
  2. 在目标库目录中创建 Config.in 文件,其中包含可在 buildroot manual or better
  3. 中检查的所需参数
  4. 创建 [包名].mk
  5. 然后在/buildroot/package/Config.in
  6. 中添加条目
  7. 然后可以在 menuconfig/target 包中标记要安装的包

我的 Config.in rpclib 文件

config BR2_PACKAGE_RPCLIB
bool "rpclib"
depends on BR2_INSTALL_LIBSTDCPP
depends on BR2_USE_WCHAR
help
  rpclib is a modern C++ msgpack-RPC server and client library

  http://rpclib.net

我的rpclib.mk文件

RPCLIB_VERSION = v2.2.1
RPCLIB_SITE = $(call github,rpclib,rpclib,$(RPCLIB_VERSION))
RPCLIB_INSTALL_STAGING = YES
RPCLIB_INSTALL_TARGET = NO
RPCLIB_CONF_OPTS = -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF

$(eval $(cmake-package))

并在 buildroot/package 目录 Config.in 中输入

source "package/rpclib/Config.in"

执行 make 后我收到了

./output/host/arm-buildroot-linux-uclibcgnueabihf/sysroot/usr/lib/librpc.a

在我的 little beatle (https://gitlab.com/melviso1/beatle) 工作,我有一个自定义的 makefile,用于构建 rpclib 而无需使用 cmake 东西(我很抱歉,但我真的很讨厌 cmake 和类似的工具)。也许这会有所帮助。 将其放在 rpclib 的根目录中以进行构建、清理或安装。请查看以下脚本中的选项卡,因为我在这里粘贴可能会造成一些损失。 我用它来编译 arm 中的 rpclib。对于交叉编译,您可以编辑和更改构建工具。

CXXFLAGS=-std=c++0x -O3 -pthread -DASIO_STANDALONE -DRPCLIB_ASIO=clmdep_asio -DRPCLIB_FMT=clmdep_fmt -DRPCLIB_MSGPACK=clmdep_msgpack -Wall 

INCLUDE=-Iinclude -I./dependencies/include

OBJS=obj/format.o obj/posix.o obj/client.o obj/client_error.o obj/response.o obj/server_session.o obj/dispatcher.o obj/optional.o obj/rpc_error.o obj/server.o obj/this_handler.o obj/this_server.o obj/this_session.o

all: obj librpc.a

obj:
    mkdir -p obj

librpc.a: $(OBJS)
    ar -r -s librpc.a $(OBJS)

obj/format.o: dependencies/src/format.cc
    g++ $(CXXFLAGS) $(INCLUDE) -c ./dependencies/src/format.cc -o     obj/format.o

obj/posix.o: dependencies/src/posix.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./dependencies/src/posix.cc -o obj/posix.o

obj/client.o: lib/rpc/client.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/client.cc -o obj/client.o

obj/client_error.o: lib/rpc/detail/client_error.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/client_error.cc -o     obj/client_error.o

obj/response.o: lib/rpc/detail/response.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/response.cc -o obj/response.o

obj/server_session.o: lib/rpc/detail/server_session.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/detail/server_session.cc -o     obj/server_session.o

obj/dispatcher.o: lib/rpc/dispatcher.cc
g++ $(CXXFLAGS) $(INCLUDE) -c ./lib/rpc/dispatcher.cc -o obj/dispatcher.o

obj/optional.o: lib/rpc/nonstd/optional.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

obj/rpc_error.o: lib/rpc/rpc_error.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

obj/server.o: lib/rpc/server.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

obj/this_handler.o: ./lib/rpc/this_handler.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

obj/this_server.o: lib/rpc/this_server.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

obj/this_session.o: ./lib/rpc/this_session.cc
g++ $(CXXFLAGS) $(INCLUDE) -c $< -o $@

install:
    cp -rf include/rpc /usr/local/include/
    cp librpc.a /usr/local/lib/

uninstall:
    rm -rf /usr/local/include/rpc
    rm /usr/local/lib/librpc.a

clean:
    rm -f librpc.a
    rm -f obj/*

.PHONY: obj clean install uninstall`