链接程序和库指南

指定版本绑定

根据包含版本定义的共享库创建动态库时,可以指示链接编辑器将绑定仅限于特定版本定义。实际上,利用链接编辑器可以控制目标文件到特定接口的绑定。

可以使用文件控制指令来控制目标文件的绑定需求。此指令通过链接编辑器的 -M 选项以及关联的 mapfile 提供。可以使用以下文件控制指令语法:


name - version [ version ... ] [ $ADDVERS=version ];

此绑定控制在下面的情况下很有用:

以下示例说明了版本控制机制的用法。此示例使用包含以下版本接口定义的共享库 libfoo.so.1


$ pvs -dsv libfoo.so.1

        libfoo.so.1:

                _end;

                _GLOBAL_OFFSET_TABLE_;

                _DYNAMIC;

                _edata;

                _PROCEDURE_LINKAGE_TABLE_;

                _etext;

        SUNW_1.1:

                foo1;

                foo2;

                SUNW_1.1;

        SUNW_1.2:           {SUNW_1.1}:

                bar;

版本定义 SUNW_1.1SUNW_1.2 表示 libfoo.so.1 内的接口,这些接口分别在软件 Release XRelease X+1 中提供。

可以使用以下版本控制 mapfile 指令来生成应用程序,使其只绑定到 Release X 中提供的接口:


$ cat mapfile

libfoo.so - SUNW_1.1;

例如,假设您开发一个应用程序 prog,并且要确保此应用程序可以在 Release X 中运行。这样此应用程序只能使用此发行版中提供的接口。如果应用程序错误地引用了符号 bar,便会与所需接口不兼容。链接编辑器会将此情形报告为未定义的符号错误:


$ cat prog.c

extern void foo1();

extern void bar();



main()

{

        foo1();

        bar();

}

$ cc -o prog prog.c -M mapfile -L. -R. -lfoo

Undefined           first referenced

 symbol                 in file

bar                     prog.o  (symbol belongs to unavailable \

                                version ./libfoo.so (SUNW_1.2))

ld: fatal: Symbol referencing errors. No output written to prog

为了与 SUNW_1.1 接口兼容,必须删除对 bar 的引用。可以对应用程序重新进行处理以删除对 bar 的需求,也可以在创建应用程序时添加 bar 的实现。


注 –

缺省情况下,还会根据任意文件控制指令来检验链接编辑过程中遇到的共享库依赖项。使用环境变量 LD_NOVERSION 可抑制任何共享库依赖项的版本验证。


到其他版本定义的绑定

要使记录的版本依赖项多于从目标文件的正常符号绑定中生成的版本依赖项,请使用 $ADDVERS 文件控制指令。本节介绍此附加绑定可能有用的情况。

在一个 libfoo.so.1 示例中,假设在 Release X+2, 中,版本定义 SUNW_1.1 分为两个标准发行版:STAND_ASTAND_B。要保持兼容性,必须维护 SUNW_1.1 版本定义。在本示例中,此版本定义表示为继承两个标准定义:


$ pvs -dsv libfoo.so.1

        libfoo.so.1:

                _end;

                _GLOBAL_OFFSET_TABLE_;

                _DYNAMIC;

                _edata;

                _PROCEDURE_LINKAGE_TABLE_;

                _etext;

        SUNW_1.1:           {STAND_A, STAND_B}:

                SUNW_1.1;

        SUNW_1.2:           {SUNW_1.1}:

                bar;

        STAND_A:

                foo1;

                STAND_A;

        STAND_B:

                foo2;

                STAND_B;

如果应用程序 prog 的唯一需求是接口符号 foo1,则此应用程序将仅依赖于版本定义 STAND_A。这将阻止在 libfoo.so.1 小于 Release X+2 的系统上运行 prog。尽管早期的发行版具有接口 foo1,但没有版本定义 STAND_A

生成应用程序 prog 时,可以通过创建对 SUNW_1.1 的依赖性来使其要求与早期发行版一致:


$ cat mapfile

libfoo.so - SUNW_1.1 $ADDVERS=SUNW_1.1;

$ cat prog

extern void foo1();



main()

{

        foo1();

}

$ cc -M mapfile -o prog prog.c -L. -R. -lfoo

$ pvs -r prog

        libfoo.so.1 (SUNW_1.1);

此显式依赖性足以涵盖实际的依赖性要求。此依赖性可满足与旧发行版的兼容性。

创建弱版本定义 (weak version definition)介绍了如何使用弱版本定义 (weak version definition) 标记内部实现更改。这些版本定义非常适用于指示针对目标文件所做的错误修复以及性能改善。如果需要弱版本,可以生成对此版本定义的显式依赖性。当错误修复或性能改善对于目标文件的正常工作至关重要时,创建此类依赖性非常重要。

在上一个 libfoo.so.1 示例中,假设在软件 Release X+3 中以弱版本定义 (weak version definition) SUNW_1.2.1 引入了错误修复:


$ pvs -dsv libfoo.so.1

        libfoo.so.1:

                _end;

                _GLOBAL_OFFSET_TABLE_;

                _DYNAMIC;

                _edata;

                _PROCEDURE_LINKAGE_TABLE_;

                _etext;

        SUNW_1.1:           {STAND_A, STAND_B}:

                SUNW_1.1;

        SUNW_1.2:           {SUNW_1.1}:

                bar;

        STAND_A:

                foo1;

                STAND_A;

        STAND_B:

                foo2;

                STAND_B;

        SUNW_1.2.1 [WEAK]:  {SUNW_1.2}:

                SUNW_1.2.1;

通常,如果根据此共享库生成应用程序,则生成的应用程序将记录与版本定义 SUNW_1.2.1 的弱依赖性。此依赖性仅用于提供信息。如果运行时使用的 libfoo.so.1 中不存在此版本定义,则此依赖性不会导致终止应用程序。

文件控制指令 $ADDVERS 可用于生成版本定义的显式依赖性。如果此定义为弱定义,则此显式引用还会导致版本定义提升为强依赖性。

可以使用以下文件控制指令生成应用程序 prog,以强制满足 SUNW_1.2.1 接口在运行时可用的需求:


$ cat mapfile

libfoo.so - SUNW_1.1 $ADDVERS=SUNW_1.2.1;

$ cat prog

extern void foo1();



main()

{

        foo1();

}

$ cc -M mapfile -o prog prog.c -L. -R. -lfoo

$ pvs -r prog

        libfoo.so.1 (SUNW_1.2.1);

生成 prog 时创建了与接口 STAND_A 的显式依赖性。由于版本定义 SUNW_1.2.1 提升为强版本,因此它也会通过依赖性 STAND_A 进行标准化。在运行时,如果找不到版本定义 SUNW_1.2.1,则会产生致命错误。


注 –

如果处理少量的依赖项,可以使用链接编辑器的 -u 选项显式绑定到某个版本定义。使用此选项可以引用版本定义符号。但是,符号引用是不可选择的。如果是处理多个依赖项(包含多个类似命名的版本定义)时,则此方法可能不足以创建显式绑定。