HeliumProject / Engine

C++ Game Engine (Under Construction!)
http://heliumproject.org/
Other
441 stars 70 forks source link

Fix component dependencies in assets #69

Closed gorlak closed 10 years ago

gorlak commented 10 years ago

Component types are C++ classes that are referenced in assets and allocated entirely by their registration with the reflection system.

In statically linked builds the compiler dead-strips those classes since it doesn't know we need them (since we don't call any functions or even a constructor until runtime). We need a script to extract all the relevant types and generate some glue code to ensure the compiler doesn't discard them at link time.

In dynamically linked builds (like the editor) we need a system to ensure we dynamically load modules that are relevant to assets that need them. This goes hand-in-hand with dynamically loading modules that are build for specific projects. We can probably take a load-everything-under-the sun approach for the time being. The editor just needs to know where to look for modules to load into its address space before starting to load assets.

gorlak commented 10 years ago

@aclysma what do you think? I think its the same problem in static vs. dll builds, but requires two entirely different solutions.

gorlak commented 10 years ago

Previously, and just for the dynamic side of this issue, you added some Force*Dll() functions to enforce static linkage of dynamic libraries, and I migrated that to using the module heap accessors in 35a258cd08aad9274422a1f1808963e2345a7f66. I just mocked up the dynamic side of this problem by just loading all sibling dlls in the running exe's directory and it resolves that linkage issue, zero code required.

sam-public commented 10 years ago

does /INCLUDE not work (for windows at least) ?

gorlak commented 10 years ago

@sam-public it does, and I have put it to work in the past, but its per-symbol instead of per-module, and you have to name-mangle the symbol you want. Were you thinking about using it for the dynamic link or static link side of this issue?

On the portability side, during a fully static link the counterparts to /INCLUDE actually yield a greedier link, including code we legitimately don't want included in the final executable (third-party lib code).

Ideally I would want a don't discard attribute / declspec that would just let us opt-in classes or functions we know we need.

gorlak commented 10 years ago

@sam-public: how I tried to use /INCLUDE: 35a258cd08aad9274422a1f1808963e2345a7f66

It got messy pretty quick, and it still didn't fix the problem for fully static builds. I would have to had forced a symbol reference for every type constructor, which would have necessitated a script to fetch the associated classes from the source code to hint the build system anyway. Generating some code that just alloc/dealloc each class of object is easier since I don't have to name-mangle the class names, and its completely portable.

sam-public commented 10 years ago

That is pretty unsatisfying... I wonder if something like this would work:

#pragma comment(linker, "/include: "  __FUNCDNAME__)

(still not portable, of course)

gorlak commented 10 years ago

@sam-public: clever!

gorlak commented 10 years ago

So, It appears that the dynamic loader fix I made may be all that is necessary on windows. It appears that the global constructors of the component classes that we are statically linking do in fact make it into the executable. This is evidenced by the successful running of ShapeShooter in Intermediate/Release configs, which are fully statically linked. Once @stine has the GL system working we can test out the other compilers/linkers to make sure they aren't dead-stripping the code either. However, those platforms have better linker flags to opt-in code from being dead-stripped (-load_all and -force_load). So this issue is solved for now since we only really support Windows since we only have a DX9 graphics subsystem.