Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell the MinGW linker not to export all symbols?

I'm building a Windows dynamic library using the MinGW toolchain.

To build this library I'm statically linking to other 2 which offer an API and I have a .def file where I wrote the only symbol I want to be exported in my library.

The problem is that GCC is exporting all of the symbols including the ones from the libraries I'm linking to. Is there anyway to tell the linker just to export the symbols in the def file?

I know there is the option --export-all-symbols but there seems not to be the opposite to it.

Right now the last line of the build script has this structure:

g++ -shared CXXFLAGS DEFINES INCLUDES -o library.dll library.cpp DEF_FILE \
OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

EDIT: In the docs about the linker it says that --export-all-symbols is the default behavior and that it's disabled when you don't use that option explicitly if you provide a def file, except when it doesn't; the symbols in 3rd party libs are being exported anyway.

EDIT: Adding the option --exclude-libs LIBS or –exclude-symbols SYMBOLS doesn't prevent the symbols from the libraries from being exported.

like image 522
James R. Avatar asked May 11 '10 11:05

James R.


3 Answers

Not sure why there's no real answer to this, but here's what worked for me:

  1. Compilation of your object files:

    g++ -O0 -gdwarf-4 dll\dllmain.cpp -c -o dllmain.o
    
  2. Linking (-Wl,--exclude-all-symbols is important):

    g++ -Wl,--enable-auto-import -Wl,--out-implib,libsomelib.a -Wl,--exclude-all-symbols -shared dllmain.o -o somelib.dll
    

Then you choose which functions to export directly in source code of your DLL:

#include <windows.h>

__declspec(dllexport) void someExportedFunction() {
    MessageBox(NULL, "msgbox", "msgbox", MB_OK);
}

void nonExportedFunction() {
    MessageBox(NULL, "notexported", "notexported", MB_OK);
}

Verification:

C:\libtest>pedump -E somelib.dll

=== EXPORTS ===

# module "somelib.dll"
# flags=0x0  ts="2014-02-20 08:37:48"  version=0.0  ord_base=1
# nFuncs=1  nNames=1

  ORD ENTRY_VA  NAME
    1     1570  _Z20someExportedFunctionv

(pedump = http://pedump.me)

like image 93
antonone Avatar answered Nov 14 '22 13:11

antonone


You can use the option -Wl,--retain-symbols-file=file and then list the symbols you want to keep (one per line) in file. This will cause the linker to discard all other symbols, keeping just the ones you want.

like image 3
Chris Dodd Avatar answered Nov 14 '22 13:11

Chris Dodd


This is a recurrent issue. Here are two related questions in SO:

  • Removing exported symbols from a DLL and its associated import library (VS8)
  • https://stackoverflow.com/questions/9586262/how-to-know-exported-symbols-for-windows-dll-from-linux-mingw/9600759#9600759 (DEAD)

and outside SO:

  • http://boost.2283326.n4.nabble.com/unwanted-exported-symbols-in-a-DLL-which-statically-links-to-Boost-Library-td2590169.html
  • http://sourceforge.net/p/mingw/bugs/1134/

i.e. global / local exporting on the Windows platform is not handled at the linker level but but the provision of a .def file to complement the .dll.

Lacking a good answer, I did a python script that takes care of removing stuff from the dll export table, you can find it here .

like image 3
dsign Avatar answered Nov 14 '22 14:11

dsign