【问题标题】:Linker and dependencies链接器和依赖项
【发布时间】:2011-10-31 03:28:12
【问题描述】:

对于 Linux/g++ 项目,我编写了一个帮助程序库(“libcommon.a”),用于两个不同的程序(“客户端”和“服务器”)。 oshelper.cpp 是几个源文件中的一个,它有一组不相关的实用程序函数:

// header file
#ifndef OSHELPER_H
#define OSHELPER_H
    size_t GetConsoleWidth();
    uint32_t GetMillisecondCounter();
#endif

// -----------------------------------------
// Code file
#include "commonincludes.h"
#include "oshelper.h"

size_t GetConsoleWidth()
{
    struct winsize ws = {};
    ioctl(0, TIOCGWINSZ, &ws);
    return ws.ws_col;
}

uint32_t GetMillisecondCounter()
{
    timespec ts={};
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (uint32_t)(ts.tv_nsec / 1000000 + ts.tv_sec * 1000);
}

两个程序都链接到包含这些函数的库(libcommon.a 或 -lcommon)。

“客户端”程序调用 GetConsoleWidth 和 GetMillisecondCounter 函数。由于 GetMillisecondCounter 最终取决于对“clock_gettime”的调用,因此 -lrt 是链接器的必需参数,以便链接 librt。这是预期的。

"server" 只是调用 GetConsoleWidth。它从不调用 GetMillisecondCounter。但是如果没有传递“-lrt”,链接器就会抱怨对clock_gettime 的未解析引用。这显然是通过将 -lrt 传递给 g++ 来解决的。然后“ldd server”显示 librt.so.1 仍然是运行时依赖项。因此,与clock_gettime 的链接显然没有得到优化。

但是当我将 GetConsoleWidth 的实现分离到一个 单独 源文件(但仍然是 libcommon.a 的一部分)时,链接器停止抱怨对 clock_gettime 的未解析引用并且不再坚持我通过在-lrt中。

就好像 g++ 链接器只能剔除未使用的目标文件,但不能剔除未使用的函数调用。

这是怎么回事?

更新:编译器和链接器命令行尽可能基本:

g++ -c oshelper.cpp
g++ -c someotherfile.cpp
etc...
ar -rv libcommon.a oshelper.o someotherfile.o ...

g++ server.cpp -lcommon -lpthread -o server
g++ client.cpp -lcommon -lrt -o client

【问题讨论】:

  • 你能显示你的编译和链接命令吗? (这里不复制。)
  • @Mat - 编译器和链接器命令是最基本的。但是我更新了上面的内容以引用它。

标签: gcc linker g++


【解决方案1】:

如果没有特殊的命令,一个 .o 是完整链接的,因此所有依赖项都是必需的。

您需要使用将所有符号放在单独的部分中的编译器标志在库中构建编译单元,然后使用“垃圾收集”部分的选项调用链接器,以便只有直接或间接从 main (并且可能是ctors/dtors)被链接进来。

我不知道确切的命令,但搜索 gcc 参数,如 -ffunction-sections -fdata-sections -fvtable-gc 和 -gc-section(s)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 2011-01-18
    • 2015-03-06
    • 2011-10-16
    • 2023-03-08
    相关资源
    最近更新 更多