www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - compile: link dynamic OR static library in Windows

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
I have never programmed in Windows, so I don't quite understand 
how to link the library correctly. I have a compiled Postgres 
library from under mingw. There is both a static library `*.a` 
and a dynamic library `*.dll`. I don't understand how to compile 
my project correctly at all. I tried to do everything through dub 
first.json, then I realized that the idea was too rash and 
decided to compile a simple project through the CLI. In the end , 
here 's what happened:

```sh
PS C:\sources\pxe-restore\source> dmd -i app.d 
-LC:\msys64\home\user\postgresql-15.1\installed\mingw64\lib\libpq.dll
lld-link: error: 
C:\msys64\home\user\postgresql-15.1\installed\mingw64\lib\libpq.dll: bad file
type. Did you specify a DLL instead of an import library?
lld-link: error: could not open 'pq.lib': no such file or 
directory
Error: linker exited with status 1
```

After Googling a bit, I came across [this 
page](https://wiki.dlang.org/Win32_DLLs_in_D#Using_a_D_class_from_a_DLL). Do I
really need to rewrite the header of the Postgres library to use it in my
project?

Do I need to list all the functions called from the library? Or 
is there a way to somehow attach it in a more civilized way 
through a simple `dmd`?
Feb 04 2023
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On Windows you don't link directly against a DLL.

You link against a static library (.lib) of the same name.

The binding doesn't change between a static library and a shared library 
as long as you're linking during the compilation sequence and not during 
runtime.

For dub, it should be as simple as putting the name of the dll (and with 
that the import library) into the libs directive. As long as its some 
place where the linker will see it and is the right arch, it should work.

Treat the import library like a static library, because that is what it is.
Feb 04 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Saturday, 4 February 2023 at 15:56:41 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On Windows you don't link directly against a DLL.

 You link against a static library (.lib) of the same name.

 The binding doesn't change between a static library and a 
 shared library as long as you're linking during the compilation 
 sequence and not during runtime.
I don't understand why the compiler doesn't see the library. ```sh User WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source -rw-r--r-- 1 User Отсутствует 37002 Nov 9 06:45 'C:\Program Files\PostgreSQL\15\lib\libpq.lib' User WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source lld-link: error: could not open 'pq.lib': no such file or directory Error: linker exited with status 1 ```
Feb 05 2023
parent reply user1234 <user1234 12.de> writes:
On Sunday, 5 February 2023 at 11:52:01 UTC, Alexander Zhirov 
wrote:
 On Saturday, 4 February 2023 at 15:56:41 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 [...]
I don't understand why the compiler doesn't see the library. ```sh User WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source -rw-r--r-- 1 User Отсутствует 37002 Nov 9 06:45 'C:\Program Files\PostgreSQL\15\lib\libpq.lib' User WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source lld-link: error: could not open 'pq.lib': no such file or directory Error: linker exited with status 1 ```
try ``` dmd -i app.d -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq ``` the first linker command gives a search path, the second a libname.
Feb 05 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Sunday, 5 February 2023 at 13:37:16 UTC, user1234 wrote:
 try

 ```
 dmd -i app.d -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq
 ```

 the first linker command gives a search path, the second a 
 libname.
It doesn't work ```sh C:\sources\pxe-restore\source>dmd -i app.d -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq Error: cannot find input file `Files\PostgreSQL\15\lib'.d` import path[0] = C:\D\dmd2\windows\bin64\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin64\..\..\src\druntime\import C:\sources\pxe-restore\source>dmd -i app.d -L'-L"C:\Program Files\PostgreSQL\15\lib"' LINK : fatal error LNK1104: не удается открыть файл "'-LC:\Program Files\PostgreSQL\15\lib'.obj" Error: linker exited with status 1104 C:\sources\pxe-restore\source>dmd -i app.d -L-L'C:\Program Files\PostgreSQL\15\lib' Error: cannot find input file `Files\PostgreSQL\15\lib'.d` import path[0] = C:\D\dmd2\windows\bin64\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin64\..\..\src\druntime\import ```
Feb 05 2023
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 06/02/2023 6:16 PM, Alexander Zhirov wrote:
 C:\sources\pxe-restore\source>dmd -i app.d -L'-LC:\Program
Files\PostgreSQL\15\lib' -Llpq
Source files go after flags. $ dmd -i -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq app.d
Feb 05 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 6 February 2023 at 05:20:33 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 Source files go after flags.

 $ dmd -i -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq app.d
For some reason, the `obj` file is link instead of the library. ```sh C:\sources\pxe-restore\source>dmd -L'-LC:\Program\ Files\PostgreSQL\15\lib' -Llpq -i app.d Error: cannot find input file `Files\PostgreSQL\15\lib'.d` import path[0] = C:\D\dmd2\windows\bin64\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin64\..\..\src\druntime\import C:\sources\pxe-restore\source>dmd -L'-L"C:\Program\ Files\PostgreSQL\15\lib"' -Llpq -i app.d LINK : fatal error LNK1104: не удается открыть файл "'-LC:\Program\ Files\PostgreSQL\15\lib'.obj" Error: linker exited with status 1104 ```
Feb 05 2023
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Ah doh, MSVC link doesn't use -L.

$ dmd -i "-L/LIBPATH:C:\Program Files\PostgreSQL\15\lib" -Llpq app.d

I think that is the option you want.

Worst case scenario just copy the files to your working directory and it 
should find it without the additional search path.
Feb 05 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 6 February 2023 at 05:45:35 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 Ah doh, MSVC link doesn't use -L.

 $ dmd -i "-L/LIBPATH:C:\Program Files\PostgreSQL\15\lib" -Llpq 
 app.d

 I think that is the option you want.

 Worst case scenario just copy the files to your working 
 directory and it should find it without the additional search 
 path.
He doesn't want to anyway. I have already put the library in the source code folder. But it still pulls up the `*.obj` format for some reason. ```sh C:\sources\pxe-restore\source>ls app.d app.obj arsd azh libpq.lib pkg C:\sources\pxe-restore\source>dmd -i "-L/LIBPATH:C:\Program Files\PostgreSQL\15\lib" -Llpq app.d LINK : fatal error LNK1181: не удается открыть входной файл "lpq.obj" Error: linker exited with status 1181 C:\sources\pxe-restore\source>dmd -i "-L/LIBPATH:C:\sources\pxe-restore\source" -Llpq app.d LINK : fatal error LNK1181: не удается открыть входной файл "lpq.obj" Error: linker exited with status 1181 ```
Feb 05 2023
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On other platforms the -Lfile I think would work.

On Windows you have to link against the import library not DLL directly.

You can pass it to the compiler:

$ dmd -i "-L/LIBPATH:C:\Program Files\PostgreSQL\15\lib" pq.lib app.d

Should work. Sorry, I should have revisted this from the get go, rather 
than just tinkering with what others were posting.
Feb 05 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 6 February 2023 at 06:59:09 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On other platforms the -Lfile I think would work.

 On Windows you have to link against the import library not DLL 
 directly.

 You can pass it to the compiler:

 $ dmd -i "-L/LIBPATH:C:\Program Files\PostgreSQL\15\lib" pq.lib 
 app.d

 Should work. Sorry, I should have revisted this from the get 
 go, rather than just tinkering with what others were posting.
It doesn't work anyway... Is it possible to collect all this from under mingw so that the linker is not Microsoft, but `ld'?
Feb 05 2023
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 06/02/2023 8:43 PM, Alexander Zhirov wrote:
 Is it possible to collect all this from under mingw so that the linker 
 is not Microsoft, but `ld'?
Maybe. Keep in mind that mingw isn't the system toolchain, you'll probably run into issues using it else where. You should really be using MSVC. We support the system toolchain solely pretty much. So I just downloaded libpq from the site (64bit version for Windows, 15.1). https://www.enterprisedb.com/download-postgresql-binaries Copied lib+bin directory into working directory from the zip file. ```sh alpha DESKTOP-RB97SA4 /tmp/test_libpq $ tree -L 1 . ├── bin ├── lib ├── test.d ├── test.exe └── test.obj 2 directories, 3 files ``` Source file: ```d module test; import std.stdio; void main() { writeln("start"); PGconn* conn = PQconnectdb("connection string"); assert(conn !is null); PQfinish(conn); writeln("end"); } struct PGconn; extern(C) { PGconn* PQconnectdb(const char *conninfo); void PQfinish(PGconn* conn); } ``` Output: ```sh alpha DESKTOP-RB97SA4 /tmp/test_libpq $ dmd -m64 lib/libpq.lib test.d alpha DESKTOP-RB97SA4 /tmp/test_libpq $ PATH=$PATH:lib:bin ./test start end ``` I had to modify the PATH variable to setup the lib and bin directories for DLL lookup (bash syntax for Cygwin). Appears to work fine.
Feb 06 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Monday, 6 February 2023 at 08:23:37 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 [...]
Yes, your solution works. I apologize for my inattention. I should have checked earlier in your way. Most likely Adam has a [problem](https://github.com/adamdruppe/arsd/issues/364) with linking in the library.
Feb 06 2023
prev sibling parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Saturday, 4 February 2023 at 15:52:33 UTC, Alexander Zhirov 
wrote:

 PS C:\sources\pxe-restore\source> dmd -i app.d 
 -LC:\msys64\home\user\postgresql-15.1\installed\mingw64\lib\libpq.dll
 lld-link: error: 
 C:\msys64\home\user\postgresql-15.1\installed\mingw64\lib\libpq.dll: bad file
type. Did you specify a DLL instead of an import library?
 lld-link: error: could not open 'pq.lib': no such file or 
 directory
 Error: linker exited with status 1
 through a simple `dmd`?
On Windows, dub's default behavior is to search for "foo.lib", usually compiled with Visual Studio C/C++ compilers. However, you have mingw-compiled "libfoo.a". I would not use MinGW-compiled libs with d compilers. I don't know how d compilers improved to support it, but in the past, I experienced ABI compatibility issues with d and MinGW. I took a quick look at https://www.postgresql.org/download/. When I tried to download, I saw that the archive contained *.lib files. So, why don't you use them? you will also need definitions of the functions in your d code like `extern(C) void fooDB();`. I am not sure how [importC](https://dlang.org/spec/importc.html) is usable with PostgreSQL. In addition, there are some bindings in the dub registry https://code.dlang.org/search?q=PostgreSQL.
Feb 04 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Saturday, 4 February 2023 at 17:02:11 UTC, Ferhat Kurtulmuş 
wrote:
 On Windows, dub's default behavior is to search for "foo.lib", 
 usually compiled with Visual Studio C/C++ compilers. However, 
 you have mingw-compiled "libfoo.a". I would not use 
 MinGW-compiled libs with d compilers. I don't know how d 
 compilers improved to support it, but in the past, I 
 experienced ABI compatibility issues with d and MinGW.
I can't link to the library `*.a` and I don't understand why? ```sh PS C:\sources\pxe-restore\source> dmd -i app.d C:\msys64\home\user\postgresql-15.1\installed\mingw64\lib\libpq.a Error: unrecognized file extension a ``` Is there any way to convert the library `dll` to `lib`? Without using Visual Studio? On Saturday, 4 February 2023 at 17:02:11 UTC, Ferhat Kurtulmuş wrote:
 you will also need definitions of the functions in your d code 
 like `extern(C) void fooDB();`. I am not sure how 
 [importC](https://dlang.org/spec/importc.html) is usable with 
 PostgreSQL. In addition, there are some bindings in the dub 
 registry https://code.dlang.org/search?q=PostgreSQL.
At this stage, everything is fine. I'm using a project that I build on Linux without any problems. All connections are set up there.
Feb 04 2023