[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The i386 PE linker supports the `-shared' option, which causes
the output to be a dynamically linked library (DLL) instead of a
normal executable. You should name the output *.dll
when you
use this option. In addition, the linker fully supports the standard
*.def
files, which may be specified on the linker command line
like an object file (in fact, it should precede archives it exports
symbols from, to ensure that they get linked in, just like a normal
object file).
In addition to the options common to all targets, the i386 PE linker support additional command line options that are specific to the i386 PE target. Options that take values may be separated from their values by either a space or an equals sign.
--add-stdcall-alias
--base-file file
--dll
LIBRARY
in a given .def
file.
--enable-stdcall-fixup
--disable-stdcall-fixup
_foo
might be linked to the function
_foo@12
, or the undefined symbol _bar@16
might be linked
to the function _bar
. When the linker does this, it prints a
warning, since it normally should have failed to link, but sometimes
import libraries generated from third-party dlls may need this feature
to be usable. If you specify `--enable-stdcall-fixup', this
feature is fully enabled and warnings are not printed. If you specify
`--disable-stdcall-fixup', this feature is disabled and such
mismatches are considered to be errors.
--export-all-symbols
DllMain@12
,
DllEntryPoint@0
, DllMainCRTStartup@12
, and
impure_ptr
will not be automatically
exported. Also, symbols imported from other DLLs will not be
re-exported, nor will symbols specifying the DLL's internal layout
such as those beginning with _head_
or ending with
_iname
. In addition, no symbols from libgcc
,
libstd++
, libmingw32
, or crtX.o
will be exported.
Symbols whose names begin with __rtti_
or __builtin_
will
not be exported, to help with C++ DLLs. Finally, there is an
extensive list of cygwin-private symbols that are not exported
(obviously, this applies on when building DLLs for cygwin targets).
These cygwin-excludes are: _cygwin_dll_entry@12
,
_cygwin_crt0_common@8
, _cygwin_noncygwin_dll_entry@12
,
_fmode
, _impure_ptr
, cygwin_attach_dll
,
cygwin_premain0
, cygwin_premain1
, cygwin_premain2
,
cygwin_premain3
, and environ
.
--exclude-symbols symbol,symbol,...
--exclude-libs lib,lib,...
--exclude-libs ALL
excludes symbols in all archive libraries from
automatic export. Symbols explicitly listed in a .def file are still exported,
regardless of this option.
--file-alignment
--heap reserve
--heap reserve,commit
--image-base value
--kill-at
--major-image-version value
--major-os-version value
--major-subsystem-version value
--minor-image-version value
--minor-os-version value
--minor-subsystem-version value
--output-def file
*.def
) may be used to create an import
library with dlltool
or may be used as a reference to
automatically or implicitly exported symbols.
--out-implib file
*.dll.a
or *.a
may be used to link clients against the generated DLL; this behavior
makes it possible to skip a separate dlltool
import library
creation step.
--enable-auto-image-base
--image-base
argument. By using a hash generated
from the dllname to create unique image bases for each DLL, in-memory
collisions and relocations which can delay program execution are
avoided.
--disable-auto-image-base
--image-base
) then use the platform
default.
--dll-search-prefix string
<string><basename>.dll
in preference to
lib<basename>.dll
. This behavior allows easy distinction
between DLLs built for the various "subplatforms": native, cygwin,
uwin, pw, etc. For instance, cygwin DLLs typically use
--dll-search-prefix=cyg
.
--enable-auto-import
_symbol
to __imp__symbol
for
DATA imports from DLLs, and create the necessary thunking symbols when
building the DLLs with those DATA exports. This generally will 'just
work' -- but sometimes you may see this message:
"variable '<var>' can't be auto-imported. Please read the
documentation for ld's --enable-auto-import
for details."
This message occurs when some (sub)expression accesses an address ultimately given by the sum of two constants (Win32 import tables only allow one). Instances where this may occur include accesses to member fields of struct variables imported from a DLL, as well as using a constant index into an array variable imported from a DLL. Any multiword variable (arrays, structs, long long, etc) may trigger this error condition. However, regardless of the exact data type of the offending exported variable, ld will always detect it, issue the warning, and exit.
There are several ways to address this difficulty, regardless of the data type of the exported variable:
One solution is to force one of the 'constants' to be a variable -- that is, unknown and un-optimizable at compile time. For arrays, there are two possibilities: a) make the indexee (the array's address) a variable, or b) make the 'constant' index a variable. Thus:
extern type extern_array[]; extern_array[1] --> { volatile type *t=extern_array; t[1] } |
or
extern type extern_array[]; extern_array[1] --> { volatile int t=1; extern_array[t] } |
For structs (and most other multiword data types) the only option is to make the struct itself (or the long long, or the ...) variable:
extern struct s extern_struct; extern_struct.field --> { volatile struct s *t=&extern_struct; t->field } |
or
extern long long extern_ll; extern_ll --> { volatile long long * local_ll=&extern_ll; *local_ll } |
A second method of dealing with this difficulty is to abandon
'auto-import' for the offending symbol and mark it with
__declspec(dllimport)
. However, in practice that
requires using compile-time #defines to indicate whether you are
building a DLL, building client code that will link to the DLL, or
merely building/linking to a static library. In making the choice
between the various methods of resolving the 'direct address with
constant offset' problem, you should consider typical real-world usage:
Original:
--foo.h extern int arr[]; --foo.c #include "foo.h" void main(int argc, char **argv){ printf("%d\n",arr[1]); } |
Solution 1:
--foo.h extern int arr[]; --foo.c #include "foo.h" void main(int argc, char **argv){ /* This workaround is for win32 and cygwin; do not "optimize" */ volatile int *parr = arr; printf("%d\n",parr[1]); } |
Solution 2:
--foo.h /* Note: auto-export is assumed (no __declspec(dllexport)) */ #if (defined(_WIN32) || defined(__CYGWIN__)) && \ !(defined(FOO_BUILD_DLL) || defined(FOO_STATIC)) #define FOO_IMPORT __declspec(dllimport) #else #define FOO_IMPORT #endif extern FOO_IMPORT int arr[]; --foo.c #include "foo.h" void main(int argc, char **argv){ printf("%d\n",arr[1]); } |
A third way to avoid this problem is to re-code your library to use a functional interface rather than a data interface for the offending variables (e.g. set_foo() and get_foo() accessor functions).
--disable-auto-import
_symbol
to
__imp__symbol
for DATA imports from DLLs.
--enable-extra-pe-debug
--section-alignment
--stack reserve
--stack reserve,commit
--subsystem which
--subsystem which:major
--subsystem which:major.minor
native
, windows
,
console
, and posix
. You may optionally set the
subsystem version also.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |