www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - dub, ldc2, MS VS 2015, static c library

reply dm <none email.com> writes:
Hi!
I'm trying to build my static c library and use it with my d 
application.
I'm making a library as described here: 
https://msdn.microsoft.com/en-us/library/ms235627(v=vs.90).aspx

My MS VS solution have file funcs.cpp:
```
#include <stdint.h>

int32_t myFunc(int32_t a, int32_t b)
{
	return a + b;
}
```
I'm build my library. Build is Release, target - x64. Got file 
mylib.lib.

Next I make app.d:
```
import std.stdio;

extern (C) int myFunc(int, int);

void main()
{
	writeln(myFunc(1, 2));
}
```

I put mylib.lib in root of my dub project:
```
E:\D\sl>ls
dub.sdl  mylib.lib  source

E:\D\sl>cat dub.sdl
name "sl"
description "A minimal D application."
libs-windows "mylib"
libs-posix "mylib"
dflags "-O5" "-m64" "-release" "-w"
```

Next I'm trying to build my app:
```
E:\D\sl>dub build --build=release --compiler=ldc2



The following compiler flags have been specified in the package 
description
file. They are handled by DUB and direct use in packages is 
discouraged.
Alternatively, you can set the DFLAGS environment variable to 
pass custom flags
to the compiler, or use one of the suggestions below:

-m64: Use --arch=x86/--arch=x86_64 to specify the target 
architecture
-release: Call dub with --build=release
-w: Use "buildRequirements" to control warning behavior

Performing "release" build using ldc2 for x86.
sl ~master: building configuration "application"...
Using Visual Studio: C:\Program Files (x86)\Microsoft Visual 
Studio 14.0\
sl.obj : error LNK2019: unresolved external symbol myFunc 
referenced in function _Dmain
.dub\build\application-release-windows-x86-ldc_0-9C4A611E39233F32B4F
0F867429B08B\sl.exe : fatal error LNK1120: 1 unresolved externals
Error: `C:\Windows\system32\cmd.exe /s /c "C:\ldc\bin\amd64.bat 
link.exe"` failed with status: 1120
ldc2 failed with exit code 1120.
```

ldc version:
```
E:\D\sl>ldc2 -version
LDC - the LLVM D compiler (0.17.1):
   based on DMD v2.068.2 and LLVM 3.7.1
   Default target: x86_64-pc-windows-msvc
   Host CPU: ivybridge
   http://dlang.org - http://wiki.dlang.org/LDC

   Registered Targets:
     arm      - ARM
     armeb    - ARM (big endian)
     cpp      - C++ backend
     mips     - Mips
     mips64   - Mips64 [experimental]
     mips64el - Mips64el [experimental]
     mipsel   - Mipsel
     ppc32    - PowerPC 32
     ppc64    - PowerPC 64
     ppc64le  - PowerPC 64 LE
     sparc    - Sparc
     sparcel  - Sparc LE
     sparcv9  - Sparc V9
     thumb    - Thumb
     thumbeb  - Thumb (big endian)
     x86      - 32-bit X86: Pentium-Pro and above
     x86-64   - 64-bit X86: EM64T and AMD64
```

What I'm doing wrong?
Dec 15 2016
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 16 December 2016 at 03:37:14 UTC, dm wrote:
 Hi!
 I'm trying to build my static c library and use it with my d 
 application.
 I'm making a library as described here: 
 https://msdn.microsoft.com/en-us/library/ms235627(v=vs.90).aspx

 My MS VS solution have file funcs.cpp:
^^^
 ```
 #include <stdint.h>

 int32_t myFunc(int32_t a, int32_t b)
 {
 	return a + b;
 }
 ```
 I'm build my library. Build is Release, target - x64. Got file 
 mylib.lib.

 Next I make app.d:
 ```
 import std.stdio;

 extern (C) int myFunc(int, int);
^^^ change this to extern(C++)
 void main()
 {
 	writeln(myFunc(1, 2));
 }
 ```

 I put mylib.lib in root of my dub project:
 ```
 E:\D\sl>ls
 dub.sdl  mylib.lib  source

 E:\D\sl>cat dub.sdl
 name "sl"
 description "A minimal D application."
 libs-windows "mylib"
 libs-posix "mylib"
 dflags "-O5" "-m64" "-release" "-w"
 ```

 Next I'm trying to build my app:
 ```
 E:\D\sl>dub build --build=release --compiler=ldc2



 The following compiler flags have been specified in the package 
 description
 file. They are handled by DUB and direct use in packages is 
 discouraged.
 Alternatively, you can set the DFLAGS environment variable to 
 pass custom flags
 to the compiler, or use one of the suggestions below:

 -m64: Use --arch=x86/--arch=x86_64 to specify the target 
 architecture
 -release: Call dub with --build=release
 -w: Use "buildRequirements" to control warning behavior

 Performing "release" build using ldc2 for x86.
 sl ~master: building configuration "application"...
 Using Visual Studio: C:\Program Files (x86)\Microsoft Visual 
 Studio 14.0\
 sl.obj : error LNK2019: unresolved external symbol myFunc 
 referenced in function _Dmain
 .dub\build\application-release-windows-x86-ldc_0-9C4A611E39233F32B4F
0F867429B08B\sl.exe : fatal error LNK1120: 1 unresolved externals
 Error: `C:\Windows\system32\cmd.exe /s /c "C:\ldc\bin\amd64.bat 
 link.exe"` failed with status: 1120
 ldc2 failed with exit code 1120.
 ```

 ldc version:
 ```
 E:\D\sl>ldc2 -version
 LDC - the LLVM D compiler (0.17.1):
   based on DMD v2.068.2 and LLVM 3.7.1
   Default target: x86_64-pc-windows-msvc
   Host CPU: ivybridge
   http://dlang.org - http://wiki.dlang.org/LDC

   Registered Targets:
     arm      - ARM
     armeb    - ARM (big endian)
     cpp      - C++ backend
     mips     - Mips
     mips64   - Mips64 [experimental]
     mips64el - Mips64el [experimental]
     mipsel   - Mipsel
     ppc32    - PowerPC 32
     ppc64    - PowerPC 64
     ppc64le  - PowerPC 64 LE
     sparc    - Sparc
     sparcel  - Sparc LE
     sparcv9  - Sparc V9
     thumb    - Thumb
     thumbeb  - Thumb (big endian)
     x86      - 32-bit X86: Pentium-Pro and above
     x86-64   - 64-bit X86: EM64T and AMD64
 ```

 What I'm doing wrong?
Your lib is a C++ lib and (because you didn't make myFunc `extern "C"`) it has C++ name mangling (_Z6myFunciii or something like it). On the D side you said it was extern(C) (_myFunc) therefore the linker can't find the symbol because the names don't match.
Dec 15 2016
parent reply dm <none email.com> writes:
On Friday, 16 December 2016 at 07:29:29 UTC, Nicholas Wilson 
wrote:
 extern (C) int myFunc(int, int);
^^^ change this to extern(C++) Your lib is a C++ lib and (because you didn't make myFunc `extern "C"`) it has C++ name mangling (_Z6myFunciii or something like it). On the D side you said it was extern(C) (_myFunc) therefore the linker can't find the symbol because the names don't match.
Doesn't works. ``` sl.obj : error LNK2019: unresolved external symbol "int __cdecl myFunc(int,int)" (?myFunc YAHHH Z) referenced in function _Dmain .dub\build\application-release-windows-x86-ldc_0-9C4A611E39233F32B4F 0F867429B08B\sl.exe : fatal error LNK1120: 1 unresolved externals Error: `C:\Windows\system32\cmd.exe /s /c "C:\ldc\bin\amd64.bat link.exe"` failed with status: 1120 ldc2 failed with exit code 1120. ```
Dec 15 2016
next sibling parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 16 December 2016 at 07:41:31 UTC, dm wrote:
 On Friday, 16 December 2016 at 07:29:29 UTC, Nicholas Wilson 
 wrote:
 extern (C) int myFunc(int, int);
^^^ change this to extern(C++) Your lib is a C++ lib and (because you didn't make myFunc `extern "C"`) it has C++ name mangling (_Z6myFunciii or something like it). On the D side you said it was extern(C) (_myFunc) therefore the linker can't find the symbol because the names don't match.
Doesn't works. ``` sl.obj : error LNK2019: unresolved external symbol "int __cdecl myFunc(int,int)" (?myFunc YAHHH Z) referenced in function _Dmain .dub\build\application-release-windows-x86-ldc_0-9C4A611E39233F32B4F 0F867429B08B\sl.exe : fatal error LNK1120: 1 unresolved externals Error: `C:\Windows\system32\cmd.exe /s /c "C:\ldc\bin\amd64.bat link.exe"` failed with status: 1120 ldc2 failed with exit code 1120. ```
It looks like it still can't find your function. Whats the linker command being generated? Try running whatever the equivalent of `nm` is on windows on sl.obj and mylib.lib and see what the difference is? (generally try to check with dmd before posting to the ldc, as you're likely to get more and better help faster in learn. even if it ldc specific you're still likely to get a faster response if its something generic like linker error. Internal complier errors and the like post here or submit a bug report.)
Dec 16 2016
parent dm <none email.com> writes:
On Friday, 16 December 2016 at 08:35:06 UTC, Nicholas Wilson 
wrote:
 It looks like it still can't find your function.

 Whats the linker command being generated? Try running whatever 
 the equivalent of `nm` is on windows on sl.obj and mylib.lib 
 and see what the difference is?
dumpbin of mylib.lib: http://pastebin.com/VhxPGg0P dumpbin of sl.obj: http://pastebin.com/10ns1yPV Looks like both have "?myFunc YAHHH Z"
 (generally try to check with dmd before posting to the ldc, as 
 you're likely to get more and better help faster in learn. even 
 if it ldc specific you're still likely to get a faster response 
 if its something generic like linker error. Internal complier 
 errors and the like post here or submit a bug report.)
Tried with dmd: ``` E:\D\sl>dub build --arch=x86_64 --build=release Performing "release" build using dmd for x86_64. sl ~master: building configuration "application"... Linking... sl.obj : error LNK2019: unresolved external symbol "int __cdecl myFunc(int,int)" (?myFunc YAHHH Z) referenced in function _Dmain .dub\build\application-release-windows-x86_64-dmd_2071-CD89D45874AE7C4F9D5 24A2CFF55DF4\sl.exe : fatal error LNK1120: 1 unresolved externals --- errorlevel 1120 dmd failed with exit code 1120. ``` dumpbin of dmd's sl.obj: http://pastebin.com/8XP5Kz7Y Seems it's also have "?myFunc YAHHH Z"
Dec 16 2016
prev sibling parent reply kinke <noone nowhere.com> writes:
On Friday, 16 December 2016 at 07:41:31 UTC, dm wrote:
 On Friday, 16 December 2016 at 07:29:29 UTC, Nicholas Wilson 
 wrote:
 extern (C) int myFunc(int, int);
^^^ change this to extern(C++) Your lib is a C++ lib and (because you didn't make myFunc `extern "C"`) it has C++ name mangling (_Z6myFunciii or something like it). On the D side you said it was extern(C) (_myFunc) therefore the linker can't find the symbol because the names don't match.
Doesn't works.
I guess dub doesn't forward the C++ lib to LDC. Try running it in verbose mode to check the command line. Linking manually without dub works, I assume. Btw, I'd very much recommend upgrading your LDC to the latest 1.1 beta, as there have been lots of bugfixes in the meantime, and it bundles DUB v1.1.1.
Dec 16 2016
parent reply dm <none email.com> writes:
On Friday, 16 December 2016 at 09:21:55 UTC, kinke wrote:
 I guess dub doesn't forward the C++ lib to LDC. Try running it 
 in verbose mode to check the command line. Linking manually 
 without dub works, I assume.
 Btw, I'd very much recommend upgrading your LDC to the latest 
 1.1 beta, as there have been lots of bugfixes in the meantime, 
 and it bundles DUB v1.1.1.
You right! I tried dub with --vverbose and realise it doesn't try to send mylib to ldc. Thanks all, problem solved. Solution is to add dflags "-O5" "-m64" "-release" "-w" "-L-lmylib" in dub.sdl And compile with dub build --compiler=ldc2 And btw I'll try new ldc release.
Dec 16 2016
parent dm <none email.com> writes:
 Solution is to add
 dflags "-O5" "-m64" "-release" "-w" "-L-lmylib"
 in dub.sdl
 And compile with dub build --compiler=ldc2
And of course extern (C++) int myFunc(int, int);
Dec 16 2016