Thread overview
Strange behaviour of rdmd vs. dmd concerning main function
Feb 09, 2017
berni
Feb 09, 2017
berni
Feb 09, 2017
Daniel Kozak
Feb 09, 2017
berni
Feb 09, 2017
Daniel Kozak
Feb 10, 2017
Mike Parker
Feb 10, 2017
berni
Feb 17, 2017
berni
Feb 17, 2017
ag0aep6g
February 09, 2017
I've got two source files in two directories:

Common/common.d

>module common;
>
>import std.stdio;
>
>int main(string[] args)
>{
>    Foo foo = cast(Foo)Object.factory("special.Bar");
>
>    foo.do_something();
>
>    return 0;
>}
>
>abstract class Foo {
>    abstract void do_something();
>}

Special/special.d

>module special;
>
>import std.stdio;
>import common;
>
>class Bar : Foo {
>    override void do_something()
>    {
>        writeln("works");
>    }
>}

Now I try to run it with rdmd and dmd and get quite different results:

>$> rdmd -ICommon Special/special.d
>works
>$> dmd -ICommon Special/special.d
>/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
>(.text+0x20): undefined reference to `main'
>special.o:(.data.rel.ro+0x18): undefined reference to `_D6common12__ModuleInfoZ'
>special.o:(.data._D7special3Bar7__ClassZ+0x50): undefined reference to `_D6common3Foo7__ClassZ'
>collect2: error: ld returned 1 exit status
>Error: linker exited with status 1

I encountered this, when I was curious if I can move the main function to a diffent module, because it will be the same in several modules anyway. When testing with rdmd, everything worked. Later, I found out, that with dmd it doesn't. (And with gdc and ldc2 it doesn't work too.)

For me, this looks like a bug in either rdmd or dmd. But maybe there is something about it that I do not understand.
February 09, 2017
On Thu, Feb 09, 2017 at 03:39:18PM +0000, berni via Digitalmars-d-learn wrote:
> Now I try to run it with rdmd and dmd and get quite different results:

dmd only compiles in the files you actually pass to it. rdmd will try to find the required files automatically.

Since you didn't pass the file with the function to dmd, it knows it exists, but leaves it out of the final link (it assumes it might come from a library or something). That's why you see the error.

rdmd exists because it handles it more automatically.

February 09, 2017
> dmd only compiles in the files you actually pass to it. rdmd will try to find the required files automatically.
>
> Since you didn't pass the file with the function to dmd, it knows it exists, but leaves it out of the final link (it assumes it might come from a library or something). That's why you see the error.

Ah ok, I understand. So calling with "dmd Special/special.d Common/common.d" works.

But when I compile common.d to common.o (with dmd -c common.d) and remove common.d after that is there still a possibility to link? The obvious doesn't work:

>$> dmd Special/special.d Common/common.o Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>import path[0] = /usr/include/dmd/phobos
>import path[1] = /usr/include/dmd/druntime/import

February 09, 2017
Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):

>> dmd only compiles in the files you actually pass to it. rdmd will try to find the required files automatically.
>>
>> Since you didn't pass the file with the function to dmd, it knows it exists, but leaves it out of the final link (it assumes it might come from a library or something). That's why you see the error.
>
> Ah ok, I understand. So calling with "dmd Special/special.d Common/common.d" works.
>
> But when I compile common.d to common.o (with dmd -c common.d) and remove common.d after that is there still a possibility to link? The obvious doesn't work:
>
>> $> dmd Special/special.d Common/common.o Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>> import path[0] = /usr/include/dmd/phobos
>> import path[1] = /usr/include/dmd/druntime/import
>
Thats ok too, you still need to add -ICommon
dmd -ICommon Special/special.d Common/common.o
February 09, 2017
On Thursday, 9 February 2017 at 19:10:55 UTC, Daniel Kozak wrote:
> Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):
>
>>> [...]
>>
>> Ah ok, I understand. So calling with "dmd Special/special.d Common/common.d" works.
>>
>> But when I compile common.d to common.o (with dmd -c common.d) and remove common.d after that is there still a possibility to link? The obvious doesn't work:
>>
>>> [...]
>>
> Thats ok too, you still need to add -ICommon
> dmd -ICommon Special/special.d Common/common.o

Doesn't work here:

>$> dmd -ICommon Special/special.d Common/common.o
>Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>import path[0] = Common
>import path[1] = /usr/include/dmd/phobos
>import path[2] = /usr/include/dmd/druntime/import
February 09, 2017
Dne 9.2.2017 v 21:10 berni via Digitalmars-d-learn napsal(a):

> On Thursday, 9 February 2017 at 19:10:55 UTC, Daniel Kozak wrote:
>> Dne 9.2.2017 v 17:20 berni via Digitalmars-d-learn napsal(a):
>>
>>>> [...]
>>>
>>> Ah ok, I understand. So calling with "dmd Special/special.d Common/common.d" works.
>>>
>>> But when I compile common.d to common.o (with dmd -c common.d) and remove common.d after that is there still a possibility to link? The obvious doesn't work:
>>>
>>>> [...]
>>>
>> Thats ok too, you still need to add -ICommon
>> dmd -ICommon Special/special.d Common/common.o
>
> Doesn't work here:
>
>> $> dmd -ICommon Special/special.d Common/common.o
>> Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>> import path[0] = Common
>> import path[1] = /usr/include/dmd/phobos
>> import path[2] = /usr/include/dmd/druntime/import
Which version of dmd you have?
It should work, you probably do something wrong, I have use your example files so do you change them somehow?
February 10, 2017
On Thursday, 9 February 2017 at 16:20:29 UTC, berni wrote:
>> dmd only compiles in the files you actually pass to it. rdmd will try to find the required files automatically.
>>
>> Since you didn't pass the file with the function to dmd, it knows it exists, but leaves it out of the final link (it assumes it might come from a library or something). That's why you see the error.
>
> Ah ok, I understand. So calling with "dmd Special/special.d Common/common.d" works.
>
> But when I compile common.d to common.o (with dmd -c common.d) and remove common.d after that is there still a possibility to link? The obvious doesn't work:
>
>>$> dmd Special/special.d Common/common.o Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>>import path[0] = /usr/include/dmd/phobos
>>import path[1] = /usr/include/dmd/druntime/import

This is not a linker error. It's a compiler error. You need common.d for the import, so the compiler can know which symbols are available. For any modules you import, you need either the original source file (.d) or a D interface (header) file (.di) which contains the type & function declarations and any template implementations you need.
February 10, 2017
>>>$> dmd Special/special.d Common/common.o Special/special.d(4): Error: module common is in file 'common.d' which cannot be read
>>>import path[0] = /usr/include/dmd/phobos
>>>import path[1] = /usr/include/dmd/druntime/import
>
> This is not a linker error. It's a compiler error. You need common.d for the import, so the compiler can know which symbols are available. For any modules you import, you need either the original source file (.d) or a D interface (header) file (.di) which contains the type & function declarations and any template implementations you need.

That worked. With "dmd -c -Hd=Common Common/common.d" I created a common.di file then I removed the common.d and could compile with "dmd -ICommon Special/special.d Common/common.o". With this, common.d does not need to be recompiled a lot of times if there are several special.d-files. Thank you!


February 17, 2017
Something similar happend now, but this time it works with dmd and rdmd produces the error:

The command that works is

dmd a.d b.o

where b.o is a precompiled c file, similar to https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.c

When using rdmd it doesn't work anymore. When I make rdmd --chatty, I can find the reason: b.o is ommited in the call of dmd. How can I make rdmd pass this parameter to dmd too?
February 17, 2017
On 02/17/2017 07:41 PM, berni wrote:
> The command that works is
>
> dmd a.d b.o
>
> where b.o is a precompiled c file, similar to
> https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.c
>
> When using rdmd it doesn't work anymore. When I make rdmd --chatty, I
> can find the reason: b.o is ommited in the call of dmd. How can I make
> rdmd pass this parameter to dmd too?

You have to pass the .o file before the .d file. rdmd interprets everything that comes after the .d file as arguments to the generated program.