首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >链接多个静态库

链接多个静态库
EN

Stack Overflow用户
提问于 2021-03-16 13:50:47
回答 1查看 859关注 0票数 0

首先,我要说,这是我第一次真正干涉GCC,所以如果这个问题不是很有建设性,或者之前有人回答了,我很抱歉。

我有两个静态库:

"L1.h“

代码语言:javascript
运行
复制
void __attribute__((weak)) Logger_Init(void) { // Invalid... }

"L2.h“

代码语言:javascript
运行
复制
void Logger_Init(void);

"L2.c“

代码语言:javascript
运行
复制
void Logger_Init(void)
{
   // Do stuff...
}

我的目标是让某些可执行文件将"L2“包含到编译过程中,并覆盖”L1“的Logger_Init实现。

我读过这里,您不能链接两个静态库,但是我检查是否在运行时调用Logger_Init,所以我需要在编译期间声明函数。

在可执行项目中,有一个添加库路径和名称的选项,我在其中添加了这两个库。我的第一个问题是,这里的顺序重要吗?我在下面使用了这两个命令,这并没有什么区别(它们被修剪了很多,但我假设这是相关的部分)。

代码语言:javascript
运行
复制
gcc -L(L1_PATH) -L(L2_PATH) -l(L1_NAME) -l(L2_NAME)

gcc -L(L2_PATH) -L(L1_PATH) -l(L2_NAME) -l(L1_NAME)

我在这里的主要问题是如何告诉链接器(?)函数在另一个静态库中有一个很强的定义,或者类似的东西?

我还读到过使用__attribute__((weak))对静态库没有多大帮助,但我并不真正理解为什么,它似乎正是我想要实现的。

我可以在这里编译和运行所有东西,但是没有调用Logger_Init的“Logger_Init”实现。

我是在嵌入式环境中工作,所以使用动态/共享库是不可能的。

编辑:

每一个请求,Bodo,这是整个命令列表。我不是在写这些命令,它们都是由Vitis自动生成的。这就是我运行代码的地方。我把它打开,让它裂开。超过一半的东西对我来说都是胡说八道,我很抱歉我的肚子肿了。向最底层是有用的东西。

代码语言:javascript
运行
复制
make all 

make --no-print-directory pre-build

a9-linaro-pre-build-step

' '

make --no-print-directory main-build

'Building file: ../src/main.c'

'Invoking: ARM v7 gcc compiler'

arm-none-eabi-gcc -Wall -O0 -g3 -c -fmessage-length=0 -MT"src/main.o"
-mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -v -IC:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include
-MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.c"

Using built-in specs.

COLLECT_GCC=C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\x86_64-oesdk-mingw32\usr\bin\arm-xilinx-eabi\arm-xilinx-eabi-gcc.exe

Target: arm-xilinx-eabi

Configured with: ../../../../../../work-shared/gcc-9.2.0-r0/gcc-9.2.0/configure
--build=x86_64-linux --host=x86_64-oesdk-mingw32 --target=arm-xilinx-eabi --prefix=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr --exec_prefix=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr
--bindir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi
--sbindir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi
--libexecdir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/libexec/arm-xilinx-eabi
--datadir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/share
--sysconfdir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/etc --sharedstatedir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/com
--localstatedir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/var
--libdir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/lib/arm-xilinx-eabi
--includedir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/us r/include
--oldincludedir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/include
--infodir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/share/info --mandir=/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/share/man
--disable-silent-rules --disable-dependency-tracking --with-libtool-sysroot=/scratch/mhatle/baremetal-toolchains/20200708-172230/build/aarch32-tc-x86_64-mingw32/work/x86_64-nativesdk-mingw32-oesdk-mingw32/gcc-cross-canadian-arm/9.2.0-r0/recipe-sysroot
--enable-clocale=generic --with-gnu-ld --enable-shared --enable-languages=c,c++ --enable-threads=posix --enable-multilib --enable-c99 --enable-long-long --enable-libstdcxx-pch --program-prefix=arm-xilinx-eabi- --without-local-prefix --enable-lto --disable-libssp --enable-libitm --disable-bootstrap --disable-libmudflap --with-system-zlib --enable-linker-build-id --with-ppl=no --with-cloog=no --enable-checking=release --enable-cheaders=c_global --without-isl --with-gxx-include-dir=/not/exist/usr/include/c++/9.2.0 --wi th-build-time-tools=/scratch/mhatle/baremetal-toolchains/20200708-172230/build/aarch32-tc-x86_64-mingw32/work/x86_64-nativesdk-mingw32-oesdk-mingw32/gcc-cross-canadian-arm/9.2.0-r0/recipe-sysroot-native/usr/arm-xilinx-eabi/bin
--with-build-sysroot=/scratch/mhatle/baremetal-toolchains/20200708-172230/build/aarch32-tc-x86_64-mingw32/work/x86_64-nativesdk-mingw32-oesdk-mingw32/gcc-cross-canadian-arm/9.2.0-r0/recipe-sysroot
--enable-poison-system-directories --disable-nls --enable-initfini-array --without-headers --with-newlib --disable-libstdcxx-pch --with-newlib --disable-threads --enable-plugins --with-gnu-as --disable-libitm --with-multilib-list=aprofile --enable-multilib --disable-nls --enable-mingw-wildcard --with-sysroot=/not/exist

Thread model: single

gcc version 9.2.0 (GCC) 

COLLECT_GCC_OPTIONS='--sysroot=C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi' '-Wall' '-O0' '-g3' '-c' '-fmessage-length=0' '-MT' 'src/main.o' '-mcpu=cortex-a9' '-mfpu=vfpv3' '-mfloat-abi=hard' '-v' '-I' 'C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include' '-MMD' '-MP' '-MF' 'src/main.d' '-MT' 'src/main.o' '-o' 'src/main.o' '-marm' '-march=armv7-a+mp+sec+vfpv3'

 c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../libexec/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/cc1.exe
-quiet -v -I C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include
-imultilib thumb/v7-a+fp/hard -iprefix c:\xilinx\vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\x86_64-oesdk-mingw32\usr\bin\arm-xilinx-eabi\../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/
-isysroot C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi
-MMD src/main.d -MF src/main.d -MP -MT src/main.o -MT src/main.o -dD -D__USES_INITFINI__ ../src/main.c -quiet -dumpbase main.c -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -marm -march=armv7-a+mp+sec+vfpv3 -auxbase-strip src/main.o -g3 -O0 -Wall -version -fmessage-length=0 -o C:\Users\M257B~1.BLA\AppData\Local\Temp\ccOuqloW.s

GNU C17 (GCC) version 9.2.0 (arm-xilinx-eabi)

    compiled by GNU C version 9.2.0, GMP version 6.1.2, MPFR version
4.0.2, MPC version 1.1.0, isl version none

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072

ignoring nonexistent directory "c:\xilinx\vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\x86_64-oesdk-mingw32\usr\bin\arm-xilinx-eabi\../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/../../../../../arm-xilinx-eabi/include"

ignoring duplicate directory "c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/lib/arm-xilinx-eabi/gcc/../../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/include"

ignoring nonexistent directory "C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi/usr/lib/arm-xilinx-eabi/9.2.0/include"

ignoring nonexistent directory "C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi/usr/local/oecore-x86_64/sysroots/x86_64-oesdk-mingw32/usr/lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/../../../../include"

ignoring duplicate directory "c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/lib/arm-xilinx-eabi/gcc/../../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/include-fixed"

ignoring nonexistent directory "c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/lib/arm-xilinx-eabi/gcc/../../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/../../../../../arm-xilinx-eabi/include"

#include "..." search starts here:

#include <...> search starts here:

 C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include

 c:\xilinx\vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\x86_64-oesdk-mingw32\usr\bin\arm-xilinx-eabi\../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/include

 c:\xilinx\vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\x86_64-oesdk-mingw32\usr\bin\arm-xilinx-eabi\../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/include-fixed

 C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi/usr/include

End of search list.

GNU C17 (GCC) version 9.2.0 (arm-xilinx-eabi)

    compiled by GNU C version 9.2.0, GMP version 6.1.2, MPFR version
4.0.2, MPC version 1.1.0, isl version none

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072

Compiler executable checksum: 2516cb1a757555b312b0344a413e7d9c

COLLECT_GCC_OPTIONS='--sysroot=C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi' '-Wall' '-O0' '-g3' '-c' '-fmessage-length=0' '-MT' 'src/main.o' '-mcpu=cortex-a9' '-mfpu=vfpv3' '-mfloat-abi=hard' '-v' '-I' 'C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include' '-MMD' '-MP' '-MF' 'src/main.d' '-MT' 'src/main.o' '-o' 'src/main.o' '-marm' '-march=armv7-a+mp+sec+vfpv3'

 c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../libexec/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/as.exe
-v -I C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include
-march=armv7-a+mp+sec -mfloat-abi=hard -mfpu=vfpv3 -meabi=5 -o src/main.o C:\Users\M257B~1.BLA\AppData\Local\Temp\ccOuqloW.s

GNU assembler version 2.32.0 (arm-xilinx-eabi) using BFD version (GNU Binutils) 2.32.0.20190204

COMPILER_PATH=c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../libexec/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/;c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../libexec/arm-xilinx-eabi/gcc/

LIBRARY_PATH=C:/Xilinx/Vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/bin//../aarch32-xilinx-eabi/usr/lib/thumb/v7-a+fp/hard/;c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../lib/arm-xilinx-eabi/gcc/arm-xilinx-eabi/9.2.0/;c:/xilinx/vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/x86_64-oesdk-mingw32/usr/bin/arm-xilinx-eabi/../../lib/arm-xilinx-eabi/gcc/;C:/Xilinx/Vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/bin//../aarch32-xilinx-eabi/usr/lib/arm-xilinx-eabi/9.2.0/;C:/Xilinx/Vitis/2020.2/gnu/aarch32/nt/gcc-arm-none-eabi/bin//../aarch32-xilinx-eabi/usr/lib/

COLLECT_GCC_OPTIONS='--sysroot=C:\Xilinx\Vitis\2020.2\gnu\aarch32\nt\gcc-arm-none-eabi\bin\\..\aarch32-xilinx-eabi' '-Wall' '-O0' '-g3' '-c' '-fmessage-length=0' '-MT' 'src/main.o' '-mcpu=cortex-a9' '-mfpu=vfpv3' '-mfloat-abi=hard' '-v' '-I' 'C:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bspinclude/include' '-MMD' '-MP' '-MF' 'src/main.d' '-MT' 'src/main.o' '-o' 'src/main.o' '-marm' '-march=armv7-a+mp+sec+vfpv3'

'Finished building: ../src/main.c'

' '

'Building target: PicoZed_Main.elf'

'Invoking: ARM v7 gcc linker'

arm-none-eabi-gcc
-L"C:\Projects\Xilinx\Experiment\PicoZed\PicoZed.vitis\Library1\Debug" -L"C:\Projects\Xilinx\Experiment\PicoZed\PicoZed.vitis\Library2\Debug" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -specs=Xilinx.spec -Wl,-T -Wl,../src/lscript.ld -LC:/Projects/Xilinx/Experiment/PicoZed/PicoZed.vitis/PicoZed/export/PicoZed/sw/PicoZed/standalone_domain/bsplib/lib
-o "PicoZed_Main.elf"  ./src/main.o   -lLibrary1 -lLibrary2 -Wl,--start-group,-lxil,-lgcc,-lc,--end-group

'Finished building target: PicoZed_Main.elf'

' '

'Invoking: ARM v7 Print Size'

arm-none-eabi-size PicoZed_Main.elf  |tee "PicoZed_Main.elf.size"

   text    data     bss     dec     hex filename

  18736    1144   22568   42448    a5d0 PicoZed_Main.elf

'Finished building: PicoZed_Main.elf.size'

' '
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-16 16:29:27

我的第一个问题是,这里的顺序重要吗?

是的,字面上是从gcc文献

-l库 ..。 在命令中写入此选项的位置有所不同;链接器按照指定的顺序搜索和处理库和对象文件。因此,‘foo.o -lz bar.o’在文件foo.o之后但在bar.o之前搜索库‘z’。如果bar.o引用‘z’中的函数,则可能不会加载这些函数。如何告诉链接器?函数在另一个静态库中有一个很强的定义,或者类似的东西?

典型的现代嵌入:

代码语言:javascript
运行
复制
-Wl,--whole-archive -l(L1_NAME) -l(L2_NAME) -Wl,--no-whole-archive 

另一种选择是解压缩两个库,并将对象文件传递给gcc。

但我不太明白为什么

链接器按顺序搜索到库中的第一个符号。所以不管你先放哪一个--弱的或者强的--那个符号都会被使用,下面所有的符号都会被忽略。

我可以在这里编译和运行所有东西,但是没有调用Logger_Init的“Logger_Init”实现。

这很奇怪,因为在您的文章中的-l(L2_NAME) -l(L1_NAME)应该会导致调用l2实现。MCVE:

代码语言:javascript
运行
复制
cat >Makefile <<EOF
all: l1.a l2.a main.o
    gcc main.o l1.a l2.a
    ./a.out
    gcc main.o l2.a l1.a
    ./a.out
l2.a: l2.o
    ar rcs $@ $<
l1.a: l1.o
    ar rcs $@ $<
EOF
cat >main.c <<EOF
int main() {
    void Logger_Init();
    Logger_Init();
}

EOF
cat >l1.c <<EOF
void __attribute__((weak)) Logger_Init(void) {
    puts("I am weak");
}

EOF
cat >l2.c <<EOF
void Logger_Init(void)
{
   puts("I am strong");
}

EOF

在以下方面的成果:

代码语言:javascript
运行
复制
$ make
...
gcc main.o l1.a l2.a
./a.out
I am weak
gcc main.o l2.a l1.a
./a.out
I am strong

即。以第一名为准。我还用-L. -ll2 -ll1对它进行了测试,并将库重命名为libl*.a --同样的结果。我怀疑你的检查方法有缺陷。

他有44年了,是个留着长胡子的爷爷。使用一些现代的东西,比如cmake。

使用weak属性可能会导致非常糟糕的意大利面代码,以后很难修复和重构。考虑在get/set访问器中使用函数指针。

你能告诉我们更多关于为什么你认为弱函数是坏的吗?

以意见为基础:

缺点:

  • 编译器特有的语法,非便携代码,非标准.
  • 如果不可重入,很难修补以允许传递用户指定的上下文.
  • 您可以从代码中的任何位置重写该函数。这基本上是你的意大利面代码的辣酱。
  • IDE很困惑,不知道从哪里跳到定义,因为有两个。
  • 难以进行单元测试,因为:
    • 一个可执行文件可以提供函数的一个重载,因此:
    • 具有多个可执行文件的单元测试需要编写更多的。
      • 这使得使用IDE“转到定义”功能变得非常糟糕,因为这样您就会得到越来越多相同函数的定义。

代码语言:javascript
运行
复制
- unit testing with a wrapper with a settable function pointer is the solution, which... it could be just implemented as the callback itself.
  • 如果它意味着是来自库/子系统的回调:
    • 基本上允许该库的一个实例
    • 随着编程的发展,需要同一个库的多个实例。
    • 这需要从多个代码位置编写/合并单个入口点--一个位置。
    • 合并多个项目很困难,因为:
      • 想象一个库有一个弱回调
      • 两个使用该库并覆盖弱回调的库。
      • 如果不能将这两个库放在一起,您将得到一个函数的重复定义。
      • 它需要修补或选择性地编译该库。
      • 它需要一个带有调用库的调度表的单一入口点。
      • 意大利面代码。

  • 正如OP -链接与顺序相关的静态库的问题所指出的,需要使用编译器特定的语法--whole-archive来解决。因为它取决于顺序,它可以是令人惊讶的,有时工作,有时不工作,导致令人惊讶和意外的错误,因为您只改变了库和oops的顺序-您的应用程序不工作。

类似于全局变量的问题。基本上和信号的问题一样。与信号相同的解决方案--使用函数指针。就像使用SA_SIGINFOsigaction一样,允许传递带有自定义void *context指针的自定义函数指针。

优势:

  • 更快的代码
  • 少打字

有什么可以分享的经验吗?

嗯,我使用和研究了弱函数(或未定义的)函数作为库的回调,结果导致代码很难合并,很难重构。

STM32 HAL库是用弱函数实现的,它们随后可选地启用了函数指针,现在它们的源代码中有#if (USE_HAL_*_REGISTER_CALLBACKS == 1)内容,请参阅ex uart.h#L248

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66656557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档