Static library adding exports to executable?

Started by
6 comments, last by Kwizatz 8 years ago

First off, sorry if I misplaced this. It isn't directly game-programming related but since the offending library sort-of is I eventually settled on this forum.

(Edit: now that I think about it that motivation makes zero sense. Oh well, let's blame tiredness instead then :rolleyes: )

So I migrated my game engine from VS2010 to 2013 a few months back and got everything to run as intended with some rebuilt dependencies. However I recently noticed that my projects ends up exporting symbols for the Assimp library. This is a static library I've built myself to use the VS2013 platform toolset and is based on the Assimp 1.6.0 source. My question is why this is happening and what I can do to avoid it?

My guess would be that there is some compiler setting I have to specify when building the Assimb library (I am referencing several other static libraries that doesn't drag along all of their internal exports after all) but I'm lost as to which one. None of the functions in that library has any particular declspec or similar either.
Any suggestions on what to do about this?

Advertisement

In trying to understand the problem...

You you have a program that is using the assimp library, the open-source asset importing tool.

When you compile the final binary that links to a static build of assimp, the assimp library has functions available as exported functions which other programs can reach.

The program works fine, you have no compiler errors, the only concern is that some functions are visible externally?

If that's the case, looking over the assimp source in github, you'll possibly need to go through ../include/assimp/defs.h and change the calling conventions used through the system. Hopefully you understand the details of calling conventions if you want to do that, because getting it wrong breaks the API.

I usually declare all non-trivial functions in my code to export for easier debugging in the case of a crash. Unless it's significantly increasing the size of your executable, I wouldn't worry about it.

This generally means that you have defined some macro that you shouldn't have, or are not defining one that you should have.

Short version: Microsoft's linking setup for DLLs is pants-on-head retarded. You have to explicitly define symbols as dllexport while compiling the code linked into a DLL and must explicitly define symbols as dllimport while compiling any code external to the DLL. C++ projects thus end up using some macro machinery to turn a macro like MYLIB_PUBLIC_API into either dllexport while building a shared library, dllimport while for users of the shared library, or nothing both when building and consuming the library in a static mode.

Libraries usually have a pair of macros, e.g. MYLIB_STATIC or MYLIB_SHARED and a MYLIB_EXPORT. If you have the wrong combination of these macros defined while building a library, you can get an assortment of linker errors or - as in your case - unintended exports.

I usually declare all non-trivial functions in my code to export for easier debugging in the case of a crash.


... I'm having some trouble guessing how exporting symbols makes debugging easier in any significant capacity, as I've never once found the lack of symbol export to impair my ability to debug crashes even in extremely large and complex apps. Care to share?

Sean Middleditch – Game Systems Engineer – Join my team!

You you have a program that is using the assimp library, the open-source asset importing tool.

When you compile the final binary that links to a static build of assimp, the assimp library has functions available as exported functions which other programs can reach.

The program works fine, you have no compiler errors, the only concern is that some functions are visible externally?

Indeed, though the main problem lies in that they get jumbled into my intended exports for the dll build of my engine.

I only brought up them being in the executable version as well since that was additionally unexpected to me, ie. it shouldn't be my dll build settings that just "export everything imported" or similar.

Anyway, if it were just in the executable I probably wouldn't care about it but as it ends up in the dll builds, which are used by other people who have to sift through all these exports looking for my decorated functions in there (I can't just provide a header file for this since they're used through a language that doesn't support that), it is quite undesirable.

Libraries usually have a pair of macros, e.g. MYLIB_STATIC or MYLIB_SHARED and a MYLIB_EXPORT. If you have the wrong combination of these macros defined while building a library, you can get an assortment of linker errors or - as in your case - unintended exports.

Hm, I see, thanks.

The thing however is that the library in question doesn't have any explicitly declared macros or otherwise preceeding the function calls and they still end up exported, thus I was thinking that there may be some global linker flag to just "export everything".

... you'll possibly need to go through ../include/assimp/defs.h and change the calling conventions used through the system.

Thank you, I found ASSIMP_BUILD_DLL_EXPORT being unconditionally defined in there, hopefully undef:ing it should solve the issue! :)

Edit: aye, that solved it. Thanks again!


, I found ASSIMP_BUILD_DLL_EXPORT being unconditionally defined in there,

that would imply they intend the library to be linked dynamically, not statically, for some reason.

most likely because ASSIMP is an application library, not a game library, so there could be cases where two apps are running at the same time which both use the lib, which is what shared DLLs are for. game libs are almost never used by more than one game running at the same time, so DLLs are not required, and static linking is preferred for the faster load times, and slightly simpler development process.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I usually declare all non-trivial functions in my code to export for easier debugging in the case of a crash.


... I'm having some trouble guessing how exporting symbols makes debugging easier in any significant capacity, as I've never once found the lack of symbol export to impair my ability to debug crashes even in extremely large and complex apps. Care to share?

Not having an export entry doesn't make it impossible to find the source of a crash - there's many ways to get function name from the instruction pointer at the time of the crash, at least if you're the only one building the application. I just find it to be the simplest. And if you're developing an open-source application, it's the most reliable way to get a usable backtrace for custom builds.

that would imply they intend the library to be linked dynamically, not statically, for some reason.

No, that just means that the author of assimp didn't take the necessary measures for the generated static library symbols not to be marked as __declspec(dllexport) since not adding the extra preprocessor magick causes no immediate side effects... until you try to link an executable against two dlls that both independently linked against the static symbol exporting library.

Always err on the side of laziness or ignorance before cleverness or evil doing ^_^

This topic is closed to new replies.

Advertisement