Thread overview
dub, ldc2, MS VS 2015, static c library
Dec 16, 2016
dm
Dec 16, 2016
Nicholas Wilson
Dec 16, 2016
dm
Dec 16, 2016
Nicholas Wilson
Dec 16, 2016
dm
Dec 16, 2016
kinke
Dec 16, 2016
dm
Dec 16, 2016
dm
December 16, 2016
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

## Warning for package sl ##

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-9C4A611E39233F32B4FA0F867429B08B\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?
December 16, 2016
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
>
> ## Warning for package sl ##
>
> 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-9C4A611E39233F32B4FA0F867429B08B\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.
December 16, 2016
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-9C4A611E39233F32B4FA0F867429B08B\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.
```
December 16, 2016
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-9C4A611E39233F32B4FA0F867429B08B\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.)
December 16, 2016
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.
December 16, 2016
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-CD89D45874AE7C4F9D5C24A2CFF55DF4\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"
December 16, 2016
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.
December 16, 2016
> 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);