digitalmars.D.learn - Undefined Reference calling D from C using static linking
- data pulverizer (60/60) Mar 23 2017 I am trying to call a D function from C. Here is the D code:
- Nicholas Wilson (8/19) Mar 23 2017 It has to do with module references to druntime stuff. You can
- data pulverizer (31/38) Mar 23 2017 Many thanks, I tried:
- Nicholas Wilson (7/51) Mar 23 2017 Those functions are the bounds checking function, the non
- data pulverizer (9/69) Mar 23 2017 I just compiled `dmd -c dcode.d -betterC -boundscheck=off`
- Nicholas Wilson (5/26) Mar 23 2017 Getting dmd to do the linking should work.
- Jacob Carlborg (5/9) Mar 23 2017 As an ugly workaround, you can defined the "_d_dso_registry" symbol
I am trying to call a D function from C. Here is the D code: ``` /* dcode.d */ extern (C) nothrow nogc system { double multNum(double x, double y) { return x*y; } } ``` Then the C code: ``` /* ccode.c */ #include <stdio.h> #include <stdlib.h> #include <stddef.h> extern double multNum(double x, double y); int main() { printf("output: %f", multNum(3.0, 4.0)); return 0; } ``` Then I compile with: ``` ldc2 -c dcode.d gcc -c ccode.c gcc -o output ccode.o dcode.o ``` I get the error: ``` dcode.o: In function `ldc.register_dso': dcode.d:(.text.ldc.register_dso+0x6e): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` Compiler versions: ``` $ ldc2 --version LDC - the LLVM D compiler (1.1.0): based on DMD v2.071.2 and LLVM 3.9.1 built with LDC - the LLVM D compiler (1.1.0) Default target: x86_64-unknown-linux-gnu Host CPU: ivybridge http://dlang.org - http://wiki.dlang.org/LDC Registered Targets: x86 - 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64 ``` ``` $ gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ``` I would appreciate it if someone could point out my mistake. Thank you in advance
Mar 23 2017
On Thursday, 23 March 2017 at 09:11:28 UTC, data pulverizer wrote:I am trying to call a D function from C. Here is the D code: ``` /* dcode.d */ extern (C) nothrow nogc system { double multNum(double x, double y) { return x*y; } } ``` [...]It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work.
Mar 23 2017
On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote:It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work.Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ```
Mar 23 2017
On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote:On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote:Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you.It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work.Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ```
Mar 23 2017
On Thursday, 23 March 2017 at 11:32:25 UTC, Nicholas Wilson wrote:On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote:I just compiled `dmd -c dcode.d -betterC -boundscheck=off` (-betterC probably makes -boundscheck=off irrelevant but I threw it in as a prayer) I am still getting: ``` dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ```On Thursday, 23 March 2017 at 10:16:22 UTC, Nicholas Wilson wrote:Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you.It has to do with module references to druntime stuff. You can either try adding a pragma(LDC_no_module_info); //I think it is spelled correctly. or you can use ldc to link and it will link druntime gcc ccode.c -c ldc2 dcode.d code.o I don't know how well that will work.Many thanks, I tried: ``` pragma(LDC_no_moduleinfo) // https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo ``` which worked, your method of doing the final compilation using ldc2 (or dmd) also works :-) Is there a dmd equivalent for `pragma(LDC_no_module_info);`? Attempting the final compilation `gcc -o output ccode.o dcode.o` after the second stage compilation `dmd -c dcode.d` gives an error: ``` dcode.o: In function `_D5dcode7__arrayZ': dcode.d:(.text._D5dcode7__arrayZ+0x23): undefined reference to `_d_arraybounds' dcode.o: In function `_D5dcode8__assertFiZv': dcode.d:(.text._D5dcode8__assertFiZv+0x23): undefined reference to `_d_assert' dcode.o: In function `_D5dcode15__unittest_failFiZv': dcode.d:(.text._D5dcode15__unittest_failFiZv+0x23): undefined reference to `_d_unittest' dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ``` ``` dmd --version DMD64 D Compiler v2.073.2 Copyright (c) 1999-2016 by Digital Mars written by Walter Bright ```
Mar 23 2017
On Thursday, 23 March 2017 at 12:06:14 UTC, data pulverizer wrote:On Thursday, 23 March 2017 at 11:32:25 UTC, Nicholas Wilson wrote:Getting dmd to do the linking should work. You may wish to see what mir (github.com/libmir) does to build in it's "Better C" mode, so i'm sure it is possible, I just don't know the incantations, sorry. Perhaps someone else can help.On Thursday, 23 March 2017 at 10:49:37 UTC, data pulverizer wrote:I just compiled `dmd -c dcode.d -betterC -boundscheck=off` (-betterC probably makes -boundscheck=off irrelevant but I threw it in as a prayer) I am still getting: ``` dcode.o:(.text.d_dso_init[.data.d_dso_rec]+0x22): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status ```[...]Those functions are the bounds checking function, the non unittest assert function, the unittest function an module initialisation function respectively. dmd -boundscheck=off -release should get rid of the first two, you didn't compile with -unittest so I'm not sure why the thord one is there at all. For _d_dso_registry all i can suggest is see what -betterC gets you.
Mar 23 2017
On 2017-03-23 13:26, Nicholas Wilson wrote:Getting dmd to do the linking should work. You may wish to see what mir (github.com/libmir) does to build in it's "Better C" mode, so i'm sure it is possible, I just don't know the incantations, sorry. Perhaps someone else can help.As an ugly workaround, you can defined the "_d_dso_registry" symbol yourself. To be sure, it should match the signature in the runtime. -- /Jacob Carlborg
Mar 23 2017