Thread overview
pragma(linkerDirective,_) removes double quotes, dmd ignores LIB
Nov 27, 2022
NonNull
Nov 27, 2022
kinke
Nov 27, 2022
NonNull
Nov 28, 2022
NonNull
Nov 28, 2022
Adam D Ruppe
Nov 28, 2022
NonNull
Nov 28, 2022
NonNull
Nov 29, 2022
zjh
Nov 29, 2022
zjh
November 27, 2022

Hello, using dmd 2.100.2 and ldc2 1.30.0, compiling to 64-bits, Windows 10.

pragma(linkerDirective,_) strips double quotation marks,

so how can a linker command line like

/LIBPATH:"Path/containing spaces/to/needed/libs"

be passed on to the linker via this pragma? Is this a bug?

Note: the libs in question are installed in locations not determined by me.

I worked around this by setting a LIB environment variable containing the extra path I needed, so I didn't need the pragma. But this only worked for ldc2; dmd still complained it cannot find the necessary, ignoring the LIB environment variable. Is this a bug?

November 27, 2022

For LDC, you shouldn't need any double quotes, the compiler quotes the linker flag if it contains spaces.

November 27, 2022

On Sunday, 27 November 2022 at 17:37:50 UTC, kinke wrote:

>

For LDC, you shouldn't need any double quotes, the compiler quotes the linker flag if it contains spaces.

Didn't work for me with LDC:

This, which works at the command line with -L=:

enum LIBPATH = `/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.2\Lib\um\x64"`; pragma(linkerDirective, LIBPATH);

gave this:

warning LNK4229: invalid directive '/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.2\Lib\um\x64' encountered; ignored

and without the double quotes gave this:

fatal error LNK1276: invalid directive 'Files' found; does not start with '/'

This, which also works at the command line with -L=:

enum LIBPATH = `"/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.2\Lib\um\x64"`; pragma(linkerDirective, LIBPATH);

gave this:

warning LNK4229: invalid directive '/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.7.2\Lib\um\x64' encountered; ignored

So double quotes are not arriving at the destination.

November 28, 2022

On Sunday, 27 November 2022 at 17:37:50 UTC, kinke wrote:

>

For LDC, you shouldn't need any double quotes, the compiler quotes the linker flag if it contains spaces.

In fact I cannot find any way (multiple double quotes, escaped double quotes, different combinations of these) to get any double quotes whatsoever into the linker command line via pragma(linkerDirective,_).

The linker always complains and the quoted error always contains no double quotes.

The behavior of ldc2 is identical to that of dmd with all attempts.

pragma(linkerDirective,_) is broken apparently.

Please confirm or show how to use.

November 28, 2022
On Monday, 28 November 2022 at 14:19:46 UTC, NonNull wrote:
> double quotes whatsoever into the linker command line via pragma(linkerDirective,_).

linkerDirective doesn't add things to the linker command line at all.

https://dlang.org/spec/pragma.html#linkerDirective

"Implementation Defined: The string literal specifies a linker directive to be embedded in the generated object file. Linker directives are only supported for MS-COFF output. "


"embedded in the generated object file" is not "added to linker command line". Only some switches are supported for embedding and the syntax might be different. This is why the error message also says "invalid directive".

This is the Microsoft doc page for the feature the pragma uses:

https://learn.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?source=recommendations&view=msvc-170#linker

It looks like they actually removed some options in the recent update, I know /SUBSYSTEM used to work there too but it is no longer listed and there's people on the web saying it stopped working after updating to the 2022 visual studio. So yeah I think they removed support for that.

But /LIBPATH has never been supported as far as I know.

You'll want to use a build script/makefile/dub config/whatever to set linker command line options.
November 28, 2022
On Monday, 28 November 2022 at 14:41:01 UTC, Adam D Ruppe wrote:
> This is the Microsoft doc page for the feature the pragma uses:
>
> https://learn.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?source=recommendations&view=msvc-170#linker
>
> It looks like they actually removed some options in the recent update, I know /SUBSYSTEM used to work there too but it is no longer listed and there's people on the web saying it stopped working after updating to the 2022 visual studio. So yeah I think they removed support for that.
>
> But /LIBPATH has never been supported as far as I know.

Aha! Thank you: the MS doc page is very informative. So
https://dlang.org/spec/pragma.html#linkerDirective
is not simply a mechanism that via the object file can get any directive eventually to the linker as if on the command line.

I've been completely successful using pragma(lib,_) but looking carefully I see that
https://dlang.org/spec/pragma.html#lib
contains highly significant clues under "implementation defined" when compared to "implementation defined" under
https://dlang.org/spec/pragma.html#linkerDirective

--- pragma(lib,_) in effect guarantees to get the information through to the linker. It is not restricted to MS-COFF, and is not restricted to passing the information through the object file but may use "other means" left unspecified.

--- pragma(linkerDirective,_) IS restricted in these ways as you made clear.

So by comparison I should have realized, taking the hint "restricted to MS-COFF" that the documentation for the MS linker about what directives can be embedded in object files was pertinent, because who knows what MS may permit?! The clues were all there. But I didn't catch on. Sorry about the kerfuffle.

I have now successfully used pragma(lib,_) with a full path to link what's needed without resorting to external build stuff. I just need one pragma(lib,_) per library.

November 28, 2022

On Sunday, 27 November 2022 at 17:26:37 UTC, NonNull wrote:

>

I worked around this by setting a LIB environment variable containing the extra path I needed, so I didn't need the pragma. But this only worked for ldc2; dmd still complained it cannot find the necessary, ignoring the LIB environment variable. Is this a bug?

I set the LIB environment variable and now ldc2 main.d works. So I know LIB is set correctly.

But dmd main.d still has linking fail to find libraries at the location LIB.

I did both in a new console where echo %LIB% produced the expected path.

Any idea what may be going on with dmd?

November 29, 2022

On Monday, 28 November 2022 at 16:21:20 UTC, NonNull wrote:

>

Any idea what may be going on with dmd?

use sc.ini like this:

[Version]
version=7.51 Build 020

[Environment]
lj=E:\path
DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import" "-I%lj%\dimport"
LIB="%@P%\..\lib"

November 29, 2022

On Tuesday, 29 November 2022 at 01:08:03 UTC, zjh wrote:

>

...

[Environment64]
LIB=%@P%\..\lib;%lj%\dku;