Browse Source

Merge pull request #308 from touilleMan/shared-cpp-module

Document how to build custom C++ module as shared library
Rémi Verschelde 8 years ago
parent
commit
ed3ed1db02
1 changed files with 100 additions and 0 deletions
  1. 100 0
      reference/custom_modules_in_c++.rst

+ 100 - 0
reference/custom_modules_in_c++.rst

@@ -220,6 +220,106 @@ now do:
 
 And the output will be ``60``.
 
+Improving the build system for development
+------------------------------------------
+
+So far we defined a clean and simple SCsub that allows us to add the sources
+of our new module as part of the Godot binary.
+
+This static approach is fine when we want to build a release version of our
+game given we want all the modules in a single binary.
+
+However the trade-of is every single change means a full recompilation of the
+game. Even if SCons is able to detect and recompile only the file that have
+changed, finding such files and eventually linking the final binary is a
+long and costly part.
+
+The solution to avoid such a cost is to build our own module as a shared
+library that will be dynamically loaded when starting our game's binary.
+
+.. code:: python
+
+    # SCsub
+    Import('env')
+
+    sources = [
+        "register_types.cpp",
+        "sumator.cpp"
+    ]
+
+    # First, create a custom env for the shared library.
+    module_env = env.Clone()
+    module_env.Append(CXXFLAGS='-fPIC')  # Needed to compile shared library
+    # We don't want godot's dependencies to be injected into our shared library.
+    module_env['LIBS'] = []
+
+    # Now define the shared library. Note that by default it would be built
+    # into the module's folder, however it's better to output it into `bin`
+    # next to the godot binary.
+    shared_lib = module_env.SharedLibrary(target='#bin/sumator', source=sources)
+
+    # Finally notify the main env it has our shared lirary as a new dependency.
+    # To do so, SCons wants the name of the lib with it custom suffixes
+    # (e.g. ".x11.tools.64") but without the final ".so".
+    # We pass this along with the directory of our library to the main env.
+    shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
+    env.Append(LIBS=[shared_lib_shim])
+    env.Append(LIBPATH=['#bin'])
+
+Once compiled, we should end up with a ``bin`` directory containing both the
+``godot*`` binary and our ``libsumator*.so``. However given the .so is not in
+a standard directory (like ``/usr/lib``), we have to help our binary find it
+during runtime with the ``LD_LIBRARY_PATH`` environ variable:
+
+::
+
+    user@host:~/godot$ export LD_LIBRARY_PATH=`pwd`/bin/
+    user@host:~/godot$ ./bin/godot*
+
+**note**: Pay attention you have to ``export`` the environ variable otherwise
+you won't be able to play you project from within the editor.
+
+On top of that, it would be nice to be able to select whether to compile our
+module as shared library (for development) or as a par of the godot binary
+(for release). To do that we can define a custom flag to be passed to SCons
+using the `ARGUMENT` command:
+
+.. code:: python
+
+    # SCsub
+    Import('env')
+
+    sources = [
+        "register_types.cpp",
+        "sumator.cpp"
+    ]
+
+    module_env = env.Clone()
+    module_env.Append(CXXFLAGS=['-O2', '-std=c++11'])
+
+    if ARGUMENTS.get('sumator_shared', 'no') == 'yes':
+        # Shared lib compilation
+        module_env.Append(CXXFLAGS='-fPIC')
+        module_env['LIBS'] = []
+        shared_lib = module_env.SharedLibrary(target='#bin/sumator', source=sources)
+        shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0]
+        env.Append(LIBS=[shared_lib_shim])
+        env.Append(LIBPATH=['#bin'])
+    else:
+        # Static compilation
+        module_env.add_source_files(env.modules_sources, sources)
+
+Now by default ``scons`` command will build our module as part of godot's binary
+and as a shared library when passing ``sumator_shared=yes``.
+
+Finally you can even speedup build further by explicitly specifying your
+shared module as target in the scons command:
+
+::
+
+    user@host:~/godot$ scons sumator_shared=yes bin/sumator.x11.tools.64.so
+
+
 Summing up
 ----------