Thread overview
DUB / compiling same source and config to different windows subsystems in 32/64 bit
Mar 04, 2019
Robert M. Münch
Mar 05, 2019
evilrat
Mar 05, 2019
Mike Parker
Mar 05, 2019
Mike Parker
Mar 05, 2019
evilrat
Mar 05, 2019
Mike Parker
Mar 05, 2019
Robert M. Münch
Mar 05, 2019
Mike Parker
Mar 05, 2019
Mike Parker
Mar 05, 2019
evilrat
March 04, 2019
Hi, when compiling a minimal Windows GUI app (using WinMain()) and compiling it with DUB, the 32-bit x86 version is a character subsystem EXE (writeln works) and for x86_64 it's a GUI subsystem EXE (writeln doesn't work). Since compiling the same source, with the same DUB config file, I would expect the x86 and x86_64 version to be equal.

That's the DUB JSON I use:

{
	"targetType" : "executable",

 	"libs-windows-x86_64": ["user32", "gdi32"],
 	"libs-windows-x86"   : ["gdi32"],
}

So, how can I get a character subsystem for x86_64 and a GUI subsystem for x86?

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

March 05, 2019
On Monday, 4 March 2019 at 18:34:09 UTC, Robert M. Münch wrote:
> Hi, when compiling a minimal Windows GUI app (using WinMain()) and compiling it with DUB, the 32-bit x86 version is a character subsystem EXE (writeln works) and for x86_64 it's a GUI subsystem EXE (writeln doesn't work). Since compiling the same source, with the same DUB config file, I would expect the x86 and x86_64 version to be equal.
>
> That's the DUB JSON I use:
>
> {
> 	"targetType" : "executable",
>
>  	"libs-windows-x86_64": ["user32", "gdi32"],
>  	"libs-windows-x86"   : ["gdi32"],
> }
>
> So, how can I get a character subsystem for x86_64 and a GUI subsystem for x86?

For MS linker just pass the linker flag /SUBSYSTEM:CONSOLE for console, or /SUBSYSTEM:WINDOWS for no console, it also detects that by the presence of WinMain(), more about linker[1]

This should do for MS linker

    "lflags-windows-x86_64": ["/SUBSYSTEM:CONSOLE"],
    "lflags-windows-x86_mscoff": ["/SUBSYSTEM:WINDOWS"]

For old optlink x86 it is a bit harder, you need to include special .def file that has instruction for linker, here is an example from dlangui[2], adding it with linker libs should work, probably, or maybe, or...

Ok while I writting this I checked dlangui example[3], so do this with that def file

    "sourceFiles-windows-x86": ["$PACKAGE_DIR/src/win_app.def"],

[1] https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2017
[2] https://github.com/buggins/dlangui/blob/master/src/win_app.def
[3] https://github.com/buggins/dlangui/blob/master/examples/example1/dub.json#L14
March 05, 2019
On Tuesday, 5 March 2019 at 02:13:30 UTC, evilrat wrote:

> This should do for MS linker
>
>     "lflags-windows-x86_64": ["/SUBSYSTEM:CONSOLE"],
>     "lflags-windows-x86_mscoff": ["/SUBSYSTEM:WINDOWS"]
>
> For old optlink x86 it is a bit harder, you need to include special .def file that has instruction for linker, here is an example from dlangui[2], adding it with linker libs should work, probably, or maybe, or...
>

No, you don't need a def file. OPTLINK understands the same option:

hello.d
```
void main() {
    import std.stdio;
    writeln("Hello");
```

`dmd hello` outputs "hello"
`dmd -L/SUBSYSTEM:windows hello` outputs nothing.
March 05, 2019
On Monday, 4 March 2019 at 18:34:09 UTC, Robert M. Münch wrote:
> Hi, when compiling a minimal Windows GUI app (using WinMain()) and compiling it with DUB, the 32-bit x86 version is a character subsystem EXE (writeln works) and for x86_64 it's a GUI subsystem EXE (writeln doesn't work). Since compiling the same source, with the same DUB config file, I would expect the x86 and x86_64 version to be equal.
>
> That's the DUB JSON I use:
>
> {
> 	"targetType" : "executable",
>
>  	"libs-windows-x86_64": ["user32", "gdi32"],
>  	"libs-windows-x86"   : ["gdi32"],
> }
>
> So, how can I get a character subsystem for x86_64 and a GUI subsystem for x86?

I stopped using WinMain with D a long time ago. It's not necessary. If you always use `main`, then both linkers will provide you with a console subsystem app by default. That's particularly useful during development. You can add a configuration to your dub.json that turns on the windows subsystem for both linkers.

For OPTLINK (x86) you only need to pass to the linker `/SUBSYSTEM:windows`.

For the MS linker (x86_mscoff, x86_64) you need to that and you need to specify that the entry point is `main`, because it will expect `WinMain` when you specify the windows subsystem. You can do that with `/ENTRY:mainCRTStartup`

https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2017
https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2017
March 05, 2019
On Tuesday, 5 March 2019 at 03:48:22 UTC, Mike Parker wrote:
> I stopped using WinMain with D a long time ago. It's not necessary. If you always use `main`, then both linkers will provide you with a console subsystem app by default. That's particularly useful during development. You can add a configuration to your dub.json that turns on the windows subsystem for both linkers.
>
> For OPTLINK (x86) you only need to pass to the linker `/SUBSYSTEM:windows`.
>
> For the MS linker (x86_mscoff, x86_64) you need to that and you need to specify that the entry point is `main`, because it will expect `WinMain` when you specify the windows subsystem. You can do that with `/ENTRY:mainCRTStartup`
>
> https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2017
> https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2017

All of this should be added on dub docs with small snippets and explanation as a section dedicated to Windows and maybe even on D docs as well, because you know, it shows up again and again from time to time.
March 05, 2019
On Tuesday, 5 March 2019 at 04:32:57 UTC, evilrat wrote:
> On Tuesday, 5 March 2019 at 03:48:22 UTC, Mike Parker wrote:
>> I stopped using WinMain with D a long time ago. It's not necessary. If you always use `main`, then both linkers will provide you with a console subsystem app by default. That's particularly useful during development. You can add a configuration to your dub.json that turns on the windows subsystem for both linkers.
>>
>> For OPTLINK (x86) you only need to pass to the linker `/SUBSYSTEM:windows`.
>>
>> For the MS linker (x86_mscoff, x86_64) you need to that and you need to specify that the entry point is `main`, because it will expect `WinMain` when you specify the windows subsystem. You can do that with `/ENTRY:mainCRTStartup`
>>
>> https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2017
>> https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2017
>
> All of this should be added on dub docs with small snippets and explanation as a section dedicated to Windows and maybe even on D docs as well, because you know, it shows up again and again from time to time

This has nothing to do with dub, so that’s the wrong place for it. The dmd for windows docs needs to make clear the distinction between the linkers and the differences in behavior, and point to the linked docs for options. I just checked the Optlink page and didn’t see /subsystem documented, so that needs to be fixed. I’ll put it on my todo list.
March 05, 2019
On 2019-03-05 05:03:42 +0000, Mike Parker said:

> On Tuesday, 5 March 2019 at 04:32:57 UTC, evilrat wrote:
>> On Tuesday, 5 March 2019 at 03:48:22 UTC, Mike Parker wrote:
>>> I stopped using WinMain with D a long time ago. It's not necessary. If you always use `main`, then both linkers will provide you with a console subsystem app by default. That's particularly useful during development. You can add a configuration to your dub.json that turns on the windows subsystem for both linkers.
>>> 
>>> For OPTLINK (x86) you only need to pass to the linker `/SUBSYSTEM:windows`.
>>> 
>>> For the MS linker (x86_mscoff, x86_64) you need to that and you need to specify that the entry point is `main`, because it will expect `WinMain` when you specify the windows subsystem. You can do that with `/ENTRY:mainCRTStartup`
>>> 
>>> https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=vs-2017 
>>> 
>>> https://docs.microsoft.com/en-us/cpp/build/reference/entry-entry-point-symbol?view=vs-2017 
>>> 
>> 
>> All of this should be added on dub docs with small snippets and explanation as a section dedicated to Windows and maybe even on D docs as well, because you know, it shows up again and again from time to time
> 
> This has nothing to do with dub, so that’s the wrong place for it. The dmd for windows docs needs to make clear the distinction between the linkers and the differences in behavior, and point to the linked docs for options. I just checked the Optlink page and didn’t see /subsystem documented, so that needs to be fixed. I’ll put it on my todo list.

My missing point was, that I didn't expect to work with two different links. And I totally agree, DUB needs to mention this. Make everyones live easy. I don't want to dig through fragmented information, collect and sort all pieces etc. That's just waste of time. If I use DUB, I want to see all things around building D programs. That simple... Is there an

I have never seen *-x86_mscoff mentioned anywhere...

-- 
Robert M. Münch
http://www.saphirion.com
smarter | better | faster

March 05, 2019
On Tuesday, 5 March 2019 at 07:10:51 UTC, Robert M. Münch wrote:
t.
>
> My missing point was, that I didn't expect to work with two different links. And I totally agree, DUB needs to mention this. Make everyones live easy. I don't want to dig through fragmented information, collect and sort all pieces etc. That's just waste of time. If I use DUB, I want to see all things around building D programs. That simple... Is there an
>
> I have never seen *-x86_mscoff mentioned anywhere...

Again, this has nothing to do with dub. It's the behavior of the linkers. When you use WinMain, the MS Linker will give you a windows subsystem by default. When you use main, it will give you a console subsystem.

DMD gained the -m32mscoff a good while ago in order to enable coff output and compatibility with the MS linker in 32-bit mode. Built-in dub support came much later with x86_mscoff. *That* needs to be documented in the dub docs, but the behavior of the various linkers out there is beyond the scope of dub's documentation. Instead, it belongs in the DMD windows documentation. It's currently missing:

https://dlang.org/dmd-windows.html#linking
March 05, 2019
On Tuesday, 5 March 2019 at 07:25:40 UTC, Mike Parker wrote:

> documentation. Instead, it belongs in the DMD windows documentation. It's currently missing:
>
> https://dlang.org/dmd-windows.html#linking

The 32-bit COFF support is missing there I mean. It does specifically mention that there are different linkers involved in the 32-bit and 64-bit toolchain.
March 05, 2019
On Tuesday, 5 March 2019 at 05:03:42 UTC, Mike Parker wrote:
>
> This has nothing to do with dub, so that’s the wrong place for it. The dmd for windows docs needs to make clear the distinction between the linkers and the differences in behavior, and point to the linked docs for options. I just checked the Optlink page and didn’t see /subsystem documented, so that needs to be fixed. I’ll put it on my todo list.

That's right, it is not part of the dub itself, however it is directly related to it(both compiler and writing that dub platform/config specific project parts), and that adds value on usability. Such info is invaluable addition, just put it in the extra section like "How-to's" or another similar cookbook recipe-like one.

This will help users that are new to Windows(esp. advanced super duper *nix power users) to solve their problem instantly where this simple, easy to follow steps with a bit of explanation is placed in a proper place.

Not to mention that there is definitely more such topics that are frequently asked but people forced to dig through forums and projects on github to gather that knowledge piece by piece.