首页 > 解决方案 > 检查库构建的标志或选项(-frecord-gcc-switches)

问题描述

我想检查正在调查的库,构建了哪些标志和选项?

我正在尝试使用带有选项的 gcc 编译器-frecord-gcc-switches来理解我的简单共享库,但没有运气。

以下是构成共享库的一段代码:

#include "shared.h"
unsigned int add(unsigned int a, unsigned int b)
{
    printf("\n Inside add()\n");
    return (a+b);
}

shared.h 看起来像:

#include<stdio.h>
extern unsigned int add(unsigned int a, unsigned int b);

我运行以下命令来创建共享库:

gcc -c -Wall -Werror -fPIC -frecord-gcc-switches shared.c
gcc -shared -frecord-gcc-switches -o libshared.so shared.o

readelf -n libshared.so了我

Displaying notes found in: .note.gnu.build-id
  Owner                 Data size       Description
  GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 8466741f5849aac95570ec68d172f9077f175f89

如何检查用于构建生成的库的选项/标志或其他库?

顺便说一句我用

$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

标签: linuxgccdynamic-library

解决方案


该选项-frecord-gcc-switches仅在编译中有效,在链接中无效,因此您可以将其省略:

$ gcc -shared -frecord-gcc-switches -o libshared.so shared.o

至少在 ELF 目标文件中,编译选项作为字符串列表写入目标文件的一个名为.GCC.command.line. 记录默认编译选项以及明确给出的选项。

如果包含此部分的多个目标文件链接到一个共享库或程序,则所有输入.GCC.command.line 部分都将合并到一个同名的输出部分中,显然是对字符串进行了重复数据删除。因此,如果使用不同的选项编译不同的源文件,则应用于每个源文件的选项可能并不明显。

要从中检索记录的选项libshared.so,请运行:

$ readelf --string-dump=.GCC.command.line libshared.so

输出将类似于:

String dump of section '.GCC.command.line':
  [     0]  -I .
  [     5]  -imultiarch x86_64-linux-gnu
  [    22]  -D_GNU_SOURCE
  [    30]  file1.cpp
  [    3a]  -mtune=generic
  [    49]  -march=x86-64
  [    57]  -Wextra
  [    5f]  -frecord-gcc-switches
  [    75]  -fasynchronous-unwind-tables
  [    92]  -fstack-protector-strong
  [    ab]  -Wformat
  [    b4]  -Wformat-security
  [    c6]  -fstack-clash-protection
  [    df]  -fcf-protection
  [    ef]  file2.cpp
  [    f9]  file3.cpp
  [   103]  -Wpedantic

由于链接不会向此信息添加任何内容,因此直接从目标文件而不是它们链接到的程序或共享库中检索它更有意义:

$ readelf --string-dump=.GCC.command.line file.o

从那时起,就不会弄错记录的选项所指的汇编。

请注意手册中的此警告

此开关仅在某些目标上实现,并且录制的确切格式取决于目标和二进制文件格式


推荐阅读