Is there any way to remove(or make local) symbols in an object file? I'm looking for something like objcopy --keep-global-symbol
on linux.
Or maybe there is a way to tell linker which symbols should be hidden? I found this page: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx which describes .Def files and my impression from the reading is that I can use these files not only for dll's but also for static libraries. Is this true?
I need this, because I link with 2 libraries A and B which export the same symbols. A is linked dynamically and B is linked statically. If a symbols is exported both by A and B I want my app to use symbol from A, plus I want to use some symbols from B (which are only in B).
If you install one of the Mingw GCC ports, e.g. mingw-w64,
then you will also get the ports of binutils
for Windows PE binaries and you will be able to use
the familar objcopy --keep-global-symbol
.
Find it in the bin
directory of your chosen installation, e.g. C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin
However...
You may well have an XY problem here, because the linker will resolve a symbol from the first library in the input sequence that defines it and ignore definitions in later libraries; so you may be able to give preference to the definitions from the DLL just by linking it before the static library. An illustration:
foo_static.c
#include <stdio.h>
void foo(void)
{
puts("foo_static");
}
bar_static.c
#include <stdio.h>
void bar(void)
{
puts("bar_static");
}
foo_dynamic.c
#include <stdio.h>
__declspec(dllexport) void foo(void)
{
puts("foo_dynamic");
}
gum_dynamic.c
#include <stdio.h>
__declspec(dllexport) void gum(void)
{
puts("gum_dynamic");
}
Compile the *_static.c
source files and archive the object files in a static library static.lib
:
>cl -c *_static.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
bar_static.c
foo_static.c
Generating Code...
>lib -out:static.lib *_static.obj
Microsoft (R) Library Manager Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Compile the *_dynamic.c
source files and link the object files in a DLL dynamic.dll
:
>cl -c *_dynamic.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo_dynamic.c
gum_dynamic.c
Generating Code...
>link -dll -out:dynamic.dll *_dynamic.obj
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library dynamic.lib and object dynamic.exp
Notice that function foo
is defined (differently) in static.lib
and dynamic.dll
.
bar
is defined only in static.lib
. gum
is defined only in dynamic.dll
Here is a program source that calls foo
, bar
and gum
:
main.c
extern void foo();
extern void bar();
extern void gum();
int main()
{
foo();
bar();
gum();
return 0;
}
which we compile:
>cl -c main.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Then we link a program prog
like this:
>link -out:prog.exe main.obj static.lib dynamic.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
with static.lib
first. The program outputs:
>prog.exe
foo_static
bar_static
gum_dynamic
So foo
was resolved from static.lib
and the definition from
dynamic.dll
was ignored.
Now lets relink with the order of the libraries reversed, and run prog
again:
>link -out:prog.exe main.obj dynamic.lib static.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
>prog.exe
foo_dynamic
bar_static
gum_dynamic
This time, foo
was resolved from dynamic.dll
and the definition from static.lib
was ignored.