GNU Compile Tools, 可执行文件, 静态链接库, 动态链接库

本文详细介绍了如何使用GCC编译器构建C/C++项目的静态链接库和动态链接库,包括预处理、编译、链接等关键步骤,并解释了位置相关代码(PDC)与位置无关代码(PIC)的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于一个编译型语言,编译器工作时总要经过预处理、编译、链接等几个过程。以 C/C++ 为例:预处理器(cpp)将每个 .c/.cpp 文件中 #include 的头文件都合并到 .c/.cpp 文件中,并且对其进行宏扩展,由此生成数个编译单元。一般来说每个 .c/.cpp 文件对应一个编译单元。随后,编译器(cc)将每个编译单元翻译成本地二进制代码,在 GNU/Linux 中后缀是 .o,在 ms vc 中后缀 .obj。这种二进制代码又被称为 object 文件,和最终的目标文件一样也有 code, data, heap, statck 等数据段,但却不可以被运行(缺少入口点)。链接器(ld)将多个 object 文件在目标文件中重新定位,也就是 relocate 的过程,再加入额外的一些代码(其他的链接文件),最终生成目标文件。目标文件可以是可执行文件,静态链接文件,或者动态链接文件。


Make static or shared library

在 GNU/Linux 系统中静态链接文件实际上就是多个 .o 文件的压缩包。假设我们有 cool.h cool.c 和 some.c 文件,要得到静态链接库 libcool.a。首先使用如下指令得到相应的 object 文件 cool.o 和 some.o:

    gcc -c cool.c

    gcc -c some.c

用这种方法生成的 object 文件称为 PDC 即位置相关代码(position-dependence code)。再使用如下指令可以得到静态链接文件 libcool.a:

    ar -r libcool.a cool.o some.o
    ranlib libcool.a

静态链接库 libcool.a 遵从 GNU/Linux 规定的静态链接库命名规范,必须是"libyour_library_name.a"

在 GNU/Linux 中动态链接文件,必需通过链接器 ld 生成。假设我们有 hot.c other.c 等文件要生成动态链接库 libhot.so 。首先使用如下指令得到相应的 object 文件 hot.o 和 some.o

    gcc -fPIC -c hot.c
    gcc -fPIC -c other.c

参数 -fPIC 指定生成的 object 文件为位置无关代码(position-independence code),只有 PIC 可以被用作生成动态链接库。然后使用如下指令得到动态库:
   
    ld -Bshared -o libhot.so hot.o other.o

或者可以使用编译器的ld wrapper:
   
   
gcc -shared -o libhot.so hot.o other.o

也可以使用编译器直接生成动态库:

   
gcc -fPIC -shared -o libhot.so hot.c other.c

这里选项 -shared 指示目标文件的类型是动态链接库,动态库的命名规范是"libyour_library_name.so"


Link static or shared library

上面提到,在链接过程中需要从其他的链接文件中引入一些额外的代码,比如:在我们的程序里用到了 jpeg 的解码函数我们就需要从 libjpeg 中导入我们需要的函数
<think>我们将在x86架构的电脑上配置ARM交叉编译环境,并编译静态版本的Qt。整个过程分为几个步骤:安装交叉编译工具链、配置Qt源码、编译静态Qt库、配置Qt Creator使用交叉编译工具链。 ### 1. 安装交叉编译工具链 针对ARM64(aarch64)平台,我们可以使用gcc交叉编译工具链。在Ubuntu系统上,可以通过以下命令安装: ```bash sudo apt update sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu ``` 验证安装: ```bash aarch64-linux-gnu-gcc --version aarch64-linux-gnu-g++ --version ``` ### 2. 下载Qt源码 选择Qt版本(这里以5.12.8为例): ```bash wget https://download.qt.io/archive/qt/5.12/5.12.8/single/qt-everywhere-src-5.12.8.tar.xz tar xvf qt-everywhere-src-5.12.8.tar.xz cd qt-everywhere-src-5.12.8 ``` ### 3. 配置Qt源码进行交叉编译 在Qt源码目录下,创建一个配置脚本(如`configure_arm64.sh`): ```bash #!/bin/bash # 设置交叉编译工具链 export TOOLCHAIN_PREFIX=aarch64-linux-gnu- export CC=${TOOLCHAIN_PREFIX}gcc export CXX=${TOOLCHAIN_PREFIX}g++ export AR=${TOOLCHAIN_PREFIX}ar export RANLIB=${TOOLCHAIN_PREFIX}ranlib # 配置选项 ./configure \ -static \ -release \ -prefix /opt/Qt-5.12.8-arm64-static \ -confirm-license \ -opensource \ -make libs \ -xplatform linux-aarch64-gnu-g++ \ -no-pch \ -no-opengl \ -no-openssl \ -no-glib \ -skip webengine \ -nomake tools \ -nomake examples \ -nomake tests ``` 注意:我们需要为交叉编译指定一个特定的平台描述(xplatform)。在Qt源码中,已经有一些平台描述模板,我们可以复制一个并修改。 #### 创建交叉编译平台描述文件 进入Qt源码目录的`qtbase/mkspecs`,复制`linux-g++`为`linux-aarch64-gnu-g++`: ```bash cd qtbase/mkspecs cp -r linux-g++ linux-aarch64-gnu-g++ cd linux-aarch64-gnu-g++ ``` 编辑`qmake.conf`文件,修改为以下内容: ```makefile # # qmake configuration for building with aarch64-linux-gnu-g++ # MAKEFILE_GENERATOR = UNIX CONFIG += incremental QMAKE_INCREMENTAL_STYLE = sublib include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # modifications to g++.conf QMAKE_CC = $${CROSS_COMPILE}gcc QMAKE_CXX = $${CROSS_COMPILE}g++ QMAKE_LINK = $${CROSS_COMPILE}g++ QMAKE_LINK_SHLIB = $${CROSS_COMPILE}g++ # modifications to linux.conf QMAKE_AR = $${CROSS_COMPILE}ar cqs QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip # 添加额外的库路径(根据实际情况调整) QMAKE_INCDIR += QMAKE_LIBDIR += # 添加额外的链接库(如果需要) # QMAKE_LIBS += load(qt_config) ``` ### 4. 编译并安装 回到Qt源码根目录,运行配置脚本并编译: ```bash chmod +x configure_arm64.sh ./configure_arm64.sh make -j$(nproc) sudo make install ``` 编译过程可能需要较长时间。完成后,静态Qt库将安装在`/opt/Qt-5.12.8-arm64-static`目录。 ### 5. 配置Qt Creator 1. 打开Qt Creator,进入`工具`->`选项`->`Kits`。 2. 添加编译器: - 在`编译器`选项卡中,手动添加`C`和`C++`编译器: - 路径:`/usr/bin/aarch64-linux-gnu-gcc`(C编译器) - 路径:`/usr/bin/aarch64-linux-gnu-g++`(C++编译器) 3. 添加Qt版本: - 在`Qt Versions`选项卡中,点击`添加`,选择安装目录下的qmake(例如:`/opt/Qt-5.12.8-arm64-static/bin/qmake`)。 4. 添加构建套件(Kit): - 在`Kits`选项卡中,点击`添加`: - 名称:`ARM64 Static Qt` - 设备类型:`通用Linux设备` - 编译器:选择之前添加的C和C++交叉编译器 - Qt版本:选择刚才添加的Qt版本 - 设置sysroot(如果有,指向ARM64的根文件系统,如果没有可以留空) ### 6. 创建和编译Qt项目 在Qt Creator中创建新项目,选择刚才配置的套件(`ARM64 Static Qt`)。在项目配置中,确保添加了静态编译选项: ```qmake # 在项目.pro文件中添加 CONFIG += static ``` 然后编译项目,生成的可执行文件即为ARM64平台的静态可执行文件。 ### 注意事项 1. **交叉编译依赖**:交叉编译时需要目标平台的系统根文件系统(sysroot),包含目标平台的头文件和库。如果没有,需要从目标平台复制或下载。在配置Qt时,可以通过`-sysroot`选项指定。 2. **静态编译的局限性**:静态编译会将所有依赖库(包括Qt)链接到可执行文件,因此文件较大。同时,注意许可证问题(特别是GPL库)。 3. **插件处理**:静态编译时,Qt的插件(如图像格式插件)需要以静态方式链接到程序中。在代码中,可以通过`Q_INIT_RESOURCE`来初始化资源,并在`.pro`文件中添加静态插件: ```qmake QTPLUGIN += qjpeg STATICPLUGINS += qjpeg ``` ### 引用 [^1]: [Qt教程3-Ubuntu(x86_64)上配置arm64(aarch64)交叉编译环境及QT编译arm64架构工程](https://example.com) [^2]: [Qt5静态编译_arm交叉编译](https://example.com) [^3]: [Ubuntu C++(Cmake版) X86 -> ARM64 Dockcorss 交叉编译使用过程](https://example.com) [^4]: [一键编译QT5源码脚本(交叉编译arm64、mips64版本)](https://example.com) §§相关问题§§ 1. 如何为交叉编译准备目标平台的sysroot? 2. 静态编译Qt程序时如何处理动态加载的插件? 3. 如何减小静态编译生成的Qt程序体积? 4. 在ARM平台上部署静态编译的Qt程序需要注意哪些问题?</think># x86电脑上ARM交叉编译静态Qt配置指南 ## 环境准备与工具链安装 ### 1. 安装交叉编译工具链 ```bash # 安装ARM64交叉编译工具 sudo apt update sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu # 验证安装 aarch64-linux-gnu-gcc --version ``` ### 2. 下载Qt源码 ```bash wget https://download.qt.io/archive/qt/5.12/5.12.8/single/qt-everywhere-src-5.12.8.tar.xz tar xvf qt-everywhere-src-5.12.8.tar.xz cd qt-everywhere-src-5.12.8 ``` ## 配置ARM交叉编译环境 ### 1. 创建交叉编译配置文件 在`qtbase/mkspecs/linux-aarch64-gnu-g++/`目录下创建`qmake.conf`: ```makefile # qmake configuration for ARM64 cross-compilation MAKEFILE_GENERATOR = UNIX CONFIG += incremental gdb_dwarf_index QMAKE_INCREMENTAL_STYLE = sublib include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # 交叉编译工具链设置 QMAKE_CC = aarch64-linux-gnu-gcc QMAKE_CXX = aarch64-linux-gnu-g++ QMAKE_LINK = aarch64-linux-gnu-g++ QMAKE_LINK_SHLIB = aarch64-linux-gnu-g++ # 工具链 QMAKE_AR = aarch64-linux-gnu-ar cqs QMAKE_OBJCOPY = aarch64-linux-gnu-objcopy QMAKE_NM = aarch64-linux-gnu-nm -P QMAKE_STRIP = aarch64-linux-gnu-strip load(qt_config) ``` ### 2. 配置Qt静态编译选项 ```bash ./configure -static -release \ -prefix /opt/Qt-arm64-static-5.12.8 \ -xplatform linux-aarch64-gnu-g++ \ -sysroot /path/to/arm64-sysroot \ -no-opengl \ -skip webengine \ -nomake examples \ -nomake tests \ -qt-zlib \ -qt-libjpeg \ -qt-libpng \ -qt-pcre \ -opensource -confirm-license ``` ## 编译与安装 ### 1. 编译静态Qt库 ```bash make -j$(nproc) sudo make install ``` ### 2. 验证安装 ```bash # 检查ARM架构的qmake file /opt/Qt-arm64-static-5.12.8/bin/qmake # 应显示:ELF 64-bit LSB executable, ARM aarch64... ``` ## Qt Creator配置 ### 1. 添加交叉编译器 1. 打开Qt Creator 2. 转到 **工具 > 选项 > Kits > 编译器** 3. 添加 **C++** 编译器: - 名称:`ARM64 GCC` - 路径:`/usr/bin/aarch64-linux-gnu-g++` 4. 添加 **C** 编译器: - 名称:`ARM64 GCC` - 路径:`/usr/bin/aarch64-linux-gnu-gcc` ### 2. 添加Qt版本 1. 转到 **Qt版本** 标签 2. 点击 **添加** 3. 选择:`/opt/Qt-arm64-static-5.12.8/bin/qmake` 4. 名称:`Qt 5.12.8 ARM64 Static` ### 3. 配置构建套件 1. 转到 **Kits** 标签 2. 点击 **添加** 3. 配置: - 名称:`ARM64 Static Build` - 设备类型:`通用Linux设备` - 编译器:选择之前添加的ARM64 GCC - Qt版本:选择`Qt 5.12.8 ARM64 Static` - Qt mkspec:`linux-aarch64-gnu-g++` ## 创建ARM静态编译项目 ### 项目文件配置(.pro) ```qmake # 使用静态编译 CONFIG += static # 指定ARM交叉编译套件 QT += core gui widgets # 添加静态插件 QTPLUGIN += qjpeg qgif STATICPLUGINS += qjpeg STATICPLUGINS += qgif # 源文件 SOURCES += main.cpp \ mainwindow.cpp HEADERS += mainwindow.h ``` ### 编译部署 ```bash # 在ARM设备上执行 scp your_app root@arm-device:/opt/ ssh root@arm-device "chmod +x /opt/your_app && /opt/your_app" ``` ## 关键注意事项 1. **Sysroot配置**: - 需要准备ARM64的根文件系统(sysroot) - 包含目标系统的头文件和库 - 可通过`debootstrap`创建: ```bash sudo debootstrap --arch=arm64 bionic /path/to/sysroot ``` 2. **静态编译优化**: ```bash # 减小可执行文件大小 aarch64-linux-gnu-strip --strip-unneeded your_app # 使用UPX压缩 upx --best --lzma your_app ``` 3. **依赖处理**: - 使用`ldd`检查动态依赖: ```bash aarch64-linux-gnu-ldd your_app ``` - 静态编译应显示"not a dynamic executable" 4. **交叉编译CMake项目**: ```cmake cmake_minimum_required(VERSION 3.5) project(MyArmProject) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) set(CMAKE_FIND_ROOT_PATH /opt/Qt-arm64-static-5.12.8) set(CMAKE_PREFIX_PATH ${CMAKE_FIND_ROOT_PATH}) find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) add_executable(my_app main.cpp) target_link_libraries(my_app Qt5::Core Qt5::Gui Qt5::Widgets) ``` ## 常见问题解决 1. **缺少头文件**: ```bash sudo apt install linux-libc-dev-arm64-cross ``` 2. **链接错误**: - 确保所有依赖库都有ARM64静态版本 - 在配置中添加`-L/path/to/arm-libs` 3. **QPA插件问题**: ```bash # 在配置中添加 -qt-xcb -xcb-xlib ``` 4. **字体渲染问题**: ```cpp // 在main.cpp中加载字体 QFontDatabase::addApplicationFont(":/fonts/NotoSansCJK-Regular.ttf"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值