Multiple GDExtension linking

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By MEDBVLL

TL;DR

Say I have two GDExtensions, A and B, and that I use both in my project. However, extension A also needs to use a static function from extension B.

How do I link them together using SCons?


More detailed question:

I have two GDExtensions, voxel_engine and seed_generator, I want to use seed_generator for multiple other extensions such as the voxel_engine itself (to set pseudo-random noise), and other extensions like procedural character creation, and whatnot. The point of this is to have the project be as modular as possible.

Currently, I figured I must add the LIBPATH and LIBS of my seed_generator to my environment like so (voxel engine SConscript):

env.Append(LIBPATH=['../../gdextension/seed_generator/'])
env.Append(LIBS=['seed_generator.windows.template_debug.dev.x86_64'])

However, while it does find the .lib, it gives me an unresolved external symbol error:

voxel_world.windows.template_debug.dev.x86_64.obj : error LNK2019: unresolved external symbol "public: static unsigned int __cdecl seed_generator::SeedGenerator::generate_random_seed(class godot::String)" (?generate_random_seed@SeedGenerator@seed_generator@@SAIVString@godot@@@Z) referenced in function "public: void __cdecl voxel_engine::VoxelWorld::update(void)" (?update@VoxelWorld@voxel_engine@@QEAAXXZ)

The code in question is this (voxel_world::Update()):

#include <seed_generator/include/seed_generator.hpp>

namespace voxel_engine
{
    ...

    void VoxelWorld::update()
    {
        if (!generator.is_valid())
        {
            UtilityFunctions::printerr("generator is not valid!");
            return;
        }
        else
        {
            seed = String::num_uint64(seed_generator::SeedGenerator::generate_random_seed(seed));
        }
    }

And the seed_generator code:

uint32_t SeedGenerator::generate_random_seed(String p_string)
{
    uint32_t seed;
    if (p_string == DEFAULT_SEED_OVERRIDE)
    {
        RandomNumberGenerator rng;

        rng.randomize();
        seed = rng.randi() % UINT_MAX;
    }
    else
    {
        seed = fnv1a_32(p_string);
    }

    return seed;
}

Additionally, I modified the SConstruct to use different environments per each extension, as I figured that should be the ideal usage:

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

godot_cpp_env = SConscript("libs/godot-cpp/SConstruct")


# GDExtension

env = godot_cpp_env.Clone()
SConscript("game/extensions/seed_generator/SConscript", exports='env')

env = godot_cpp_env.Clone()
SConscript("game/extensions/voxel_engine/SConscript", exports='env')

How do I link them together using SCons?

:bust_in_silhouette: Reply From: MEDBVLL

I forgor to add GDE_EXPORT to my header file in my function