Linking a GDExtension to another

Godot Version

Godot 4.4.1, on Linux mint

Question :

I made a GDExtension that is working fine. Now, I would like to make a second GDExtension using some classes from the first one. I will call them GDExt_1 and GDExt_2 respectively. However every time I start the project, I get the following error (I edited the paths for clarity/privacy reasons) :

  ERROR: Can't open dynamic library: /home/[...]/[PROJECT_NAME]/bin/GDExt_2.linux.template_debug.x86_64.so. Error: /home/[...]l/[PROJECT_NAME]/bin/GDExt_2.linux.template_debug.x86_64.so: undefined symbol: _ZTIN6girder18GdrBtNodeBehaviourE.
  ERROR: Can't open GDExtension dynamic library: 'res://bin/GDExt_2.gdextension'.

The symbol in the error correspond to a class from GDExt_1 I am trying to inherit from in GDExt_2. I believe this is a linking error because this class is correctly registered and can be instantiated in the editor. I could not find any documentation or answered forum topics about linking a GDExtension to another.
The folder structure for the GDExtensions are the same as the one in the docs’ example.

What I have tried so far :

Adding the first GDExt_1 to GDExt_2’s dependencies in the GDExt_2.gdextension file :

[dependencies]

linux.debug.x86_64 = {
    "res://bin/GDExt_1.linux.template_debug.x86_64.so" : ""
}



Modifying GDExt_2’s SConstruct file. I temporarily pasted the compiled dynamic library of GDExt_1 in the same folder for the compilation to succeed.

#!/usr/bin/env python
import os
import sys

env = SConscript("godot-cpp/SConstruct")

module_name = "GDExt_2"


# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp")

env.Append(LIBS=["GDExt_1.linux.template_debug.x86_64"], LIBPATH=['.', "./bin/"], RPATH=["$ORIGIN"])

library = env.SharedLibrary(
    "bin/{}{}{}".format(module_name, env["suffix"], env["SHLIBSUFFIX"]),
    source=sources,
)

Default(library)


GDExt_1’s SConstruct file, which works fine, for comparison :

#!/usr/bin/env python
import os
import sys

env = SConscript("godot-cpp/SConstruct")

module_name = "GDExt_1"


# tweak this if you want to use different folders, or more folders, to store your source code in.
env.Append(CPPPATH=["src/"])
sources = Glob("src/*.cpp")


library = env.SharedLibrary(
    "bin/{}{}{}".format(module_name, env["suffix"], env["SHLIBSUFFIX"]),
    source=sources,
)

Default(library)

I just solved this issue myself. I made all of the above changes you made, but had the same Undefined Symbol issue as you. I solved that by compiling the module I was linking against (GDExt_1 in your case) with symbols_visibility=visible

3 Likes

Thank you, hidden symbols were the problem. Also, I found out the GDE_EXPORT macro can be used to make only some symbols visible. It’s used to make the library init function visible in the default example.

1 Like