ld and WIN32 (cygwin/mingw) lib名搜索顺序

ld and WIN32 (cygwin/mingw)

http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/win32.html

 

This section describes some of the win32 specific ld issues. See Section 3.1 Command Line Options for detailed decription of the command line options mentioned here.

import libraries

The standard Windows linker creates and uses so-called import libraries, which contains information for linking to dll's. They are regular static archives and are handled as any other static archive. The cygwin and mingw ports of ld have specific support for creating such libraries provided with the -out-implib command line option.

exporting DLL symbols

The cygwin/mingw ld has several ways to export symbols for dll's.

using auto-export functionality

By default ld exports symbols with the auto-export functionality, which is controlled by the following command line options:

  • -export-all-symbols [This is the default]

  • -exclude-symbols

  • -exclude-libs

If, however, -export-all-symbols is not given explicitly on the command line, then the default auto-export behavior will be disabled if either of the following are true:

  • A DEF file is used.

  • Any symbol in any object file was marked with the __declspec(dllexport) attribute.

using a DEF file

Another way of exporting symbols is using a DEF file. A DEF file is an ASCII file containing definitions of symbols which should be exported when a dll is created. Usually it is named <dll name>.def and is added as any other object file to the linker's command line. The file's name must end in .def or .DEF .

gcc -o <output> <objectfiles> <dll name>.def

Using a DEF file turns off the normal auto-export behavior, unless the -export-all-symbols option is also used.

Here is an example of a DEF file for a shared library called xyz.dll :

LIBRARY "xyz.dll" BASE=0x10000000

EXPORTS
foo
bar
_bar = bar

This example defines a base address and three symbols. The third symbol is an alias for the second. For the complete format specification see ld/deffilep.y in the binutils sources.

While linking a shared dll, ld is able to create a DEF file with the -output-def <file> command line option.

Using decorations

Another way of marking symbols for export is to modify the source code itself, so that when building the DLL each symbol to be exported is declared as:

__declspec(dllexport) int a_variable
__declspec(dllexport) void a_function(int with_args)

All such symbols will be exported from the DLL. If, however, any of the object files in the DLL contain symbols decorated in this way, then the normal auto-export behavior is disabled, unless the -export-all-symbols option is also used.

Note that object files that wish to access these symbols must not decorate them with dllexport. Instead, they should use dllimport, instead:

__declspec(dllimport) int a_variable
__declspec(dllimport) void a_function(int with_args)

This complicates the structure of library header files, because when included by the library itself the header must declare the variables and functions as dllexport, but when included by client code the header must declare them as dllimport. There are a number of idioms that are typically used to do this; often client code can omit the __declspec() declaration completely. See -enable-auto-import and automatic data imports for more imformation.

 

automatic data imports

The standard Windows dll format supports data imports from dlls only by adding special decorations (dllimport/dllexport), which let the compiler produce specific assembler instructions to deal with this issue. This increases the effort necessary to port existing Un*x code to these platforms, especially for large c++ libraries and applications. The auto-import feature, which was initially provided by Paul Sokolovsky, allows one to omit the decorations to archieve a behavior that conforms to that on POSIX/Un*x platforms. This feature is enabled with the -enable-auto-import command-line option, although it is enabled by default on cygwin/mingw. The -enable-auto-import option itself now serves mainly to suppress any warnings that are ordinarily emitted when linked objects trigger the feature's use.

auto-import of variables does not always work flawlessly without additional assistance. Sometimes, you will see this message

"variable '<var>' can't be auto-imported. Please read the documentation for ld's -enable-auto-import for details."

The -enable-auto-import documentation explains why this error occurs, and several methods that can be used to overcome this difficulty. One of these methods is the runtime pseudo-relocs feature, described below.

For complex variables imported from DLLs (such as structs or classes), object files typically contain a base address for the variable and an offset (addend ) within the variable-to specify a particular field or public member, for instance. Unfortunately, the runtime loader used in win32 environments is incapable of fixing these references at runtime without the additional information supplied by dllimport/dllexport decorations. The standard auto-import feature described above is unable to resolve these references.

The -enable-runtime-pseudo-relocs switch allows these references to be resolved without error, while leaving the task of adjusting the references themselves (with their non-zero addends) to specialized code provided by the runtime environment. Recent versions of the cygwin and mingw environments and compilers provide this runtime support; older versions do not. However, the support is only necessary on the developer's platform; the compiled result will run without error on an older system.

-enable-runtime-pseudo-relocs is not the default; it must be explicitly enabled as needed.

 

direct linking to a dll

The cygwin/mingw ports of ld support the direct linking, including data symbols, to a dll without the usage of any import libraries. This is much faster and uses much less memory than does the traditional import library method, expecially when linking large libraries or applications. When ld creates an import lib, each function or variable exported from the dll is stored in its own bfd, even though a single bfd could contain many exports. The overhead involved in storing, loading, and processing so many bfd's is quite large, and explains the tremendous time, memory, and storage needed to link against particularly large or complex libraries when using import libs.

Linking directly to a dll uses no extra command-line switches other than -L and -l , because ld already searches for a number of names to match each library. All that is needed from the developer's perspective is an understanding of this search, in order to force ld to select the dll instead of an import library.

For instance, when ld is called with the argument -lxxx it will attempt to find, in the first directory of its search path,

libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll

before moving on to the next directory in the search path.

(*) Actually, this is not cygxxx.dll but in fact is <prefix>xxx.dll , where <prefix> is set by the ld option -dll-search-prefix=<prefix> . In the case of cygwin, the standard gcc spec file includes -dll-search-prefix=cyg , so in effect we actually search for cygxxx.dll .

Other win32-based unix environments, such as mingw or pw32, may use other <prefix> es, although at present only cygwin makes use of this feature. It was originally intended to help avoid name conflicts among dll's built for the various win32/un*x environments, so that (for example) two versions of a zlib dll could coexist on the same machine.

The generic cygwin/mingw path layout uses a bin directory for applications and dll's and a lib directory for the import libraries (using cygwin nomenclature):

bin/
cygxxx.dll
lib/
libxxx.dll.a (in case of dll's)
libxxx.a (in case of static archive)

Linking directly to a dll without using the import library can be done two ways:

1. Use the dll directly by adding the bin path to the link line

gcc -Wl,-verbose  -o a.exe -L../bin/ -lxxx

However, as the dll's often have version numbers appended to their names (cygncurses-5.dll ) this will often fail, unless one specifies -L../bin -lncurses-5 to include the version. Import libs are generally not versioned, and do not have this difficulty.

2. Create a symbolic link from the dll to a file in the lib directory according to the above mentioned search pattern. This should be used to avoid unwanted changes in the tools needed for making the app/dll.

ln -s bin/cygxxx.dll lib/[cyg|lib|]xxx.dll[.a]

Then you can link without any make environment changes.

gcc -Wl,-verbose  -o a.exe -L../lib/ -lxxx

This technique also avoids the version number problems, because the following is perfectly legal

bin/
cygxxx-5.dll
lib/
libxxx.dll.a -> ../bin/cygxxx-5.dll

Linking directly to a dll without using an import lib will work even when auto-import features are exercised, and even when -enable-runtime-pseudo-relocs is used.

Given the improvements in speed and memory usage, one might justifiably wonder why import libraries are used at all. There are two reasons:

1. Until recently, the link-directly-to-dll functionality did not work with auto-imported data.

2. Sometimes it is necessary to include pure static objects within the import library (which otherwise contains only bfd's for indirection symbols that point to the exports of a dll). Again, the import lib for the cygwin kernel makes use of this ability, and it is not possible to do this without an import lib.

So, import libs are not going away. But the ability to replace true import libs with a simple symbolic link to (or a copy of) a dll, in most cases, is a useful addition to the suite of tools binutils makes available to the win32 developer. Given the massive improvements in memory requirements during linking, storage requirements, and linking speed, we expect that many developers will soon begin to use this feature whenever possible.

symbol aliasing
adding additional names

Sometimes, it is useful to export symbols with additional names. A symbol foo will be exported as foo , but it can also be exported as _foo by using special directives in the DEF file when creating the dll. This will affect also the optional created import library. Consider the following DEF file:

LIBRARY "xyz.dll" BASE=0x61000000

EXPORTS
foo
_foo = foo

The line _foo = foo maps the symbol foo to _foo .

Another method for creating a symbol alias is to create it in the source code using the "weak" attribute:

void foo () { /* Do something.  */; }
void _foo () __attribute__ ((weak, alias ("foo")));

See the gcc manual for more information about attributes and weak symbols.

renaming symbols

Sometimes it is useful to rename exports. For instance, the cygwin kernel does this regularly. A symbol _foo can be exported as foo but not as _foo by using special directives in the DEF file. (This will also affect the import library, if it is created). In the following example:

LIBRARY "xyz.dll" BASE=0x61000000

EXPORTS
_foo = foo

The line _foo = foo maps the exported symbol foo to _foo .

Note: using a DEF file disables the default auto-export behavior, unless the -export-all-symbols command line option is used. If, however, you are trying to rename symbols, then you should list all desired exports in the DEF file, including the symbols that are not being renamed, and do not use the -export-all-symbols option. If you list only the renamed symbols in the DEF file, and use -export-all-symbols to handle the other symbols, then the both the new names and the original names for the the renamed symbols will be exported. In effect, you'd be aliasing those symbols, not renaming them, which is probably not what you wanted.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值