views:

133

answers:

3

Hello, 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.

+1  A: 

Disclaimer: I've only done this on Linux, but AFAIK it should work on Windows as well

You can use the -fvisibility=hidden option; for more info see http://gcc.gnu.org/wiki/Visibility

janneb
I'm afraid it doesn't help in a Windows environment (at least with my compiler). I'm getting "visibility attribute not supported in this configuration; ignored" warnings even in a foo test, but thanks anyway!
James R.
A: 

Did you read this on the page you supplied alink to, regarding behaviour if --export-all-symbols is not used explicitly - auto export is disabled if:

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

Have you tried explicitly exporting only the functions you are interested in? It's very easy to get names wrong in DEF file, because of mangling, so this method should be more reliable.

anon
I've marked like that the symbols I want to be exported, and they are, but I can't access the sources of the libraries I'm linking to. I can't take that marking away from there.
James R.
@James You can't take away exporting once it has been done, I'm afraid.
anon
Aha, thank you then, so the symbols exported by other libraries must remain.
James R.
A: 

You can use dllwrap if your distribution of binutils (either native or cross compiling) provides it.

It can produce DLLs using the interface in a DEF file (under the hood it calls gcc, ld and dlltool to do so). The difference between using this and passing a DEF file to GCC directly is that the definitions in the file are treated differently.

For example, if you have a symbol rename in the export file:

_SomeFuntion = _SomeFunction@12

GCC will create 2 exports, one by the name of _SomeFunction and the other one with the decorated name while dllwrap will only export _SomeFuntion. So if you only add to the DEF file the symbols you want to be exported you will end up only with them in the library.

dllwrap by default uses the C compiler driver since it has no way of knowing otherwise. As you're linking C++ code, you have to use the option --driver-name c++ to set the driver. If you happen to have the MinGW executables with a prefix you have to include it too in the driver name (e.g. i686-mingw32-c++ instead of c++) and you may need to use the option --dlltool-name too.

Try using these two lines instead of the one you posted:

g++ -c CXXFLAGS DEFINES INCLUDES -o library.o library.cpp
dllwrap -o library.dll --driver-name c++ --def DEF_FILE OBJECT_FILES LIBS -Wl,--enable-stdcall-fixup

The first one generates an object file from the code of library.cpp and the second one assembles the dynamic library. The OBJECT_FILES thing (which I assume to be other object files you generated previously) should have library.o there too.

That said, I have to tell you dllwrap was already deprecated in 2006 and there is no documentation on it in the official binutils package; to get some info you may call it with --help as usual. It can generate an import library in case you need it too.

Xandy
Thank you for your answer! It works, unless the symbols are specified in the `def` file they're not exported, even the ones from the libraries. I will use dllwrap, I'm using binutils 2.20 and dllwrap is still there so maybe it's still maintained.If it's deprecated... shouldn't there be a way to do the same thing using only gcc and cia?
James R.