www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - dmd -unittest -main -run: undefined reference to

reply kdevel <kdevel vogtner.de> writes:
In the current working directory b/ I have

package.d
```
module b;
import c;

void bar (string s)
{
    mkdir (s);
}
```

c/package.d
```
module c;
package import std.file;
```

    $ dmd -unittest -main package.d c/package.d

produces the binary "package" as expected, but

    $ dmd -unittest -main -run package.d c/package.d

fails with

    package.o:(.data.rel.ro+0x10): undefined reference to 
`_D1c12__ModuleInfoZ'
    collect2: ld returned 1 exit status
    Error: linker exited with status 1

Why this?
May 01 2019
parent reply ag0aep6g <anonymous example.com> writes:
On 02.05.19 00:25, kdevel wrote:
 dmd -unittest -main -run package.d c/package.d
That doesn't compile c/package.d. Everything after `-run package.d` is interpreted as an argument to the compiled program. I.e., that line effectively does this: dmd -unittest -main package.d ./package c/package.d You need to put c/package.d before -run: dmd -unittest -main c/package.d -run package.d Or use -i so that DMD compiles the imported module automatically: dmd -unittest -main -i -run package.d
May 01 2019
next sibling parent reply kdevel <kdevel vogtner.de> writes:
On Wednesday, 1 May 2019 at 22:35:12 UTC, ag0aep6g wrote:
 On 02.05.19 00:25, kdevel wrote:
 dmd -unittest -main -run package.d c/package.d
That doesn't compile c/package.d. Everything after `-run package.d` is interpreted as an argument to the compiled program.
Thanks for the information. Wouldn't it be better, if everything directly after the `-run` would be taken as argument to the programm? In this case dmd -unittest -main -run package.d would immediately fail due to missing source. [...]
 Or use -i so that DMD compiles the imported module 
 automatically:

     dmd -unittest -main -i -run package.d
That looks nice.
May 01 2019
parent Seb <seb wilzba.ch> writes:
On Wednesday, 1 May 2019 at 22:46:34 UTC, kdevel wrote:
 On Wednesday, 1 May 2019 at 22:35:12 UTC, ag0aep6g wrote:
 On 02.05.19 00:25, kdevel wrote:
 dmd -unittest -main -run package.d c/package.d
That doesn't compile c/package.d. Everything after `-run package.d` is interpreted as an argument to the compiled program.
Thanks for the information. Wouldn't it be better, if everything directly after the `-run` would be taken as argument to the programm? In this case dmd -unittest -main -run package.d would immediately fail due to missing source.
Would be, but would also be a breaking change. In the past it has been discussed to use e.g. `--` as a separator, but that PR was rejected because it could only be done in a useful way with breaking changes :/
May 01 2019
prev sibling parent reply kdevel <kdevel vogtner.de> writes:
On Wednesday, 1 May 2019 at 22:35:12 UTC, ag0aep6g wrote:
[...]
 Or use -i so that DMD compiles the imported module 
 automatically:

     dmd -unittest -main -i -run package.d
Now I have: a/main.d a/b/package.d a/b/c/package.d b/package.d and c/package.d as before. a/main.d is ``` import b; void dummy () { string s = "test"; mkdir (s); } ``` In cwd a/ with $ dmd -unittest -main -i -run main.d I get b/package.d(2): Error: module `c` is in file 'c.d' which cannot be read import path[0] = /.../dmd2/linux/bin64/../../src/phobos import path[1] = /.../dmd2/linux/bin64/../../src/druntime/import Why does dmd not get it? I have to supply -I=b explicitly. Which leads me to the actual problem I wanted to post: $ dmd -unittest -main -I=b -run main.d main.d(6): Error: undefined identifier mkdir The problem I see here is that b passes the isolated unittest. But when it is used undefined symbols show up. I stumbled over this problem while using a project as submodule which uses msgpack-d as its submodule. Only if I restrict the import like in import msgpack : unpack, pack; my submodule's unittest fails right away. My submodule corresponds to b/package.d in this thread. I suppose the line package import std.file, core.stdc.string; in msgpack-d's file packer.d causes the export of mkdir. Right?
May 01 2019
parent ag0aep6g <anonymous example.com> writes:
On 02.05.19 01:18, kdevel wrote:
 Now I have:
 
 a/main.d
 a/b/package.d
 a/b/c/package.d
 
 b/package.d and c/package.d as before.
For reference, a/b/c/package.d is this: module c; package import std.file; And a/b/package.d starts with: module b; import c;
 a/main.d is
 
 ```
 import b;
 
 void dummy ()
 {
     string s = "test";
     mkdir (s);
 }
 ```
 
 In cwd a/ with
 
     $ dmd -unittest -main -i -run main.d
 
 I get
 
     b/package.d(2): Error: module `c` is in file 'c.d' which cannot be read
     import path[0] = /.../dmd2/linux/bin64/../../src/phobos
     import path[1] = /.../dmd2/linux/bin64/../../src/druntime/import
 
 Why does dmd not get it?
If you want c to be part of the package b, you have to state that in the module declaration and when importing it. In c/package.d: module b.c; In b/package.d: import b.c; Module declarations and imports are always absolute. They're not relative to the current package. If you add a new root directory on top, you have to adjust those declarations in all files.
 I have to supply -I=b explicitly. Which leads 
 me to
 the actual problem I wanted to post:
 
     $ dmd -unittest -main -I=b -run main.d
     main.d(6): Error: undefined identifier mkdir
main only imports b. And b doesn't expose mkdir. You can either import c (or rather b.c) in main, or make b's import of c public. By the way, `package import` seems to work just like `public import`, not restricting anything. Looks like a compiler bug.
 The problem I see here is that b passes the isolated unittest. But when 
 it is used undefined symbols show up. I stumbled over this problem while 
 using a project as submodule which uses msgpack-d as its submodule. Only 
 if I restrict
 the import like in
 
     import msgpack : unpack, pack;
 
 my submodule's unittest fails right away. My submodule corresponds to 
 b/package.d in this thread. I suppose the line
 
      package import std.file, core.stdc.string;
 
 in msgpack-d's file packer.d causes the export of mkdir. Right?
"Export" in the sense of D identifier visibility, yes. Note that an "undefined identifier" error is different from one about an "undefined reference". The former is the compiler saying it can't find the definition of a D identifier. The latter is the linker saying it can't find a symbol in the object files.
May 02 2019