www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CMake and D

reply Jan Allersma <janallersma gmail.com> writes:
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)


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")


project (framework)

add_executable(framework main.o viewer.cpp)


#INCLUDE(main.o)


INCLUDE(FindPkgConfig)


PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)


INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS})


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.
Aug 04 2022
parent reply Johan <j j.nl> writes:
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
Aug 04 2022
next sibling parent pascal111 <judas.the.messiah.111 gmail.com> writes:
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.
Aug 04 2022
prev sibling parent reply Jan Allersma <janallersma gmail.com> writes:
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!
Aug 06 2022
parent reply Jan Allersma <janallersma gmail.com> writes:
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.
Aug 06 2022
parent reply Jan Allersma <janallersma gmail.com> writes:
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`!
Aug 06 2022
parent rempas <rempas tutanota.com> writes:
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!
Aug 07 2022