Thread overview
CMake and D
Aug 04, 2022
Jan Allersma
Aug 04, 2022
Johan
Aug 04, 2022
pascal111
Aug 06, 2022
Jan Allersma
Aug 06, 2022
Jan Allersma
Aug 06, 2022
Jan Allersma
Aug 08, 2022
rempas
August 04, 2022

Hello,

I am trying to compile an application with both C++ and D source code.

First I have main.d:

extern (C++) void init();
extern (C++) void draw(int row, int column, int x, int y);
extern (C++) void render();

void main() {
    init();
    draw(3, 3, 0, 0);
    draw(3, 3, 2, 2);
    draw(3, 3, 1, 1);
    render();
}

And I have viewer.cpp:

void init() { ... }
void draw() { ... }
void render() { ... }

Lastly, I have CMakeLists.txt:

cmake_minimum_required (VERSION 3.0)
set(CMAKE_BUILD_TYPE Debug)

# Below line is for using C++14 standard
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")

# Our project name
project (framework)

add_executable(framework main.o viewer.cpp)

# DLang
#INCLUDE(main.o)

# For finding our SDL2 package!
INCLUDE(FindPkgConfig)

# Searching SDL2 package.
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)

# Including our external library's directory for header files!
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS})

# Linking SDL2 library with our project.
target_link_libraries(framework ${SDL2_LIBRARIES})

I execute the following lines in my terminal:

dmd -c main.d
cd build
cmake ..
make

And I get this error:

/usr/bin/ld: ../main.o: in function `main':
main.d:(.text.main[main]+0xc): undefined reference to `_d_run_main'
/usr/bin/ld: ../main.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry'

So something goes wrong with linking, but I dont know what.

August 04, 2022

On Thursday, 4 August 2022 at 20:29:30 UTC, Jan Allersma wrote:

>

So something goes wrong with linking, but I dont know what.

Execute dmd -v on some test program. It will output the linker line at the end of the output, the line starting with cc yourcode.o -o yourcode .... On that linker line you will see what libraries to add in your CMake script, such that when linking the C++ program and D object files, it pulls in the libraries that D expects (standard library).

cheers,
Johan

August 04, 2022

On Thursday, 4 August 2022 at 20:59:50 UTC, Johan wrote:

>

On Thursday, 4 August 2022 at 20:29:30 UTC, Jan Allersma wrote:

>

So something goes wrong with linking, but I dont know what.

Execute dmd -v on some test program. It will output the linker line at the end of the output, the line starting with cc yourcode.o -o yourcode .... On that linker line you will see what libraries to add in your CMake script, such that when linking the C++ program and D object files, it pulls in the libraries that D expects (standard library).

cheers,
Johan

It's nice feature in D that we can mix C code with it, because I know C is so jealous language.

August 06, 2022

On Thursday, 4 August 2022 at 20:59:50 UTC, Johan wrote:

>

On Thursday, 4 August 2022 at 20:29:30 UTC, Jan Allersma wrote:

>

So something goes wrong with linking, but I dont know what.

Execute dmd -v on some test program. It will output the linker line at the end of the output, the line starting with cc yourcode.o -o yourcode .... On that linker line you will see what libraries to add in your CMake script, such that when linking the C++ program and D object files, it pulls in the libraries that D expects (standard library).

cheers,
Johan

Thanks Johan!
All I needed to do was to pass phobos2 as argument for target_link_libraries.

Now I am getting some errors on running:

double free or corruption (fasttop)
Afgebroken (geheugendump gemaakt)

But that is an issue about something completely different, I presume. Thanks for the help!

August 06, 2022

I forgot that I have to add some DUB dependencies. So I have to use dub instead of dmd.
My strategy is to

  1. Create a D function which will be called in C++.
  2. Build a static library containing the D function (using dub build).
  3. Build an executable file with CMake.

However, I get an ld error:

/usr/bin/ld: ../libhello-sdl.a(app_1_144.o):(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/framework.dir/build.make:85: framework] Fout 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/framework.dir/all] Fout 2
make: *** [Makefile:84: all] Fout 2

I do not know what _d_dso_registry is. Therefore, I don't know how to solve this problem.

August 06, 2022

On Saturday, 6 August 2022 at 13:52:28 UTC, Jan Allersma wrote:

>

I forgot that I have to add some DUB dependencies. So I have to use dub instead of dmd.
My strategy is to

  1. Create a D function which will be called in C++.
  2. Build a static library containing the D function (using dub build).
  3. Build an executable file with CMake.

However, I get an ld error:

/usr/bin/ld: ../libhello-sdl.a(app_1_144.o):(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/framework.dir/build.make:85: framework] Fout 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/framework.dir/all] Fout 2
make: *** [Makefile:84: all] Fout 2

I do not know what _d_dso_registry is. Therefore, I don't know how to solve this problem.

I figured out a strategy to solve te problem:

  1. Create a C++ function which will be called in D.
  2. Build a static C++ library with CMake and add dependencies (In my case: SDL libraries)
  3. Create a new project (dub init).
  4. Add these lines to dub.json:
	"dflags": ["-L-lstdc++"],
	"lflags": ["-Lbuild", "-lframework", "-lSDL2"],
  • -L-lstdc++ is needed to use standard C++ functions.
  • -Lbuild is to add the build directory a library path (this is the directory where my earlier compiled C++ library is in).
  • -lframework is used to link my earlier compiled C++ library libframework.a.
  • And finally -lSDL2 because that is a dependency used by my C++ library.

Now I can add dependencies for my D code as well using dub add!

August 08, 2022

On Saturday, 6 August 2022 at 18:22:45 UTC, Jan Allersma wrote:

>

I figured out a strategy to solve te problem:

  1. Create a C++ function which will be called in D.
  2. Build a static C++ library with CMake and add dependencies (In my case: SDL libraries)
  3. Create a new project (dub init).
  4. Add these lines to dub.json:
	"dflags": ["-L-lstdc++"],
	"lflags": ["-Lbuild", "-lframework", "-lSDL2"],
  • -L-lstdc++ is needed to use standard C++ functions.
  • -Lbuild is to add the build directory a library path (this is the directory where my earlier compiled C++ library is in).
  • -lframework is used to link my earlier compiled C++ library libframework.a.
  • And finally -lSDL2 because that is a dependency used by my C++ library.

Now I can add dependencies for my D code as well using dub add!

Thank you for posting the solution! And you were fast enough to find
it yourself before anyone can arrive with the solution ;)

Happy coding my friend!