digitalmars.D.learn - dmd -unittest -main -run: undefined reference to
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
On 02.05.19 00:25, kdevel wrote:dmd -unittest -main -run package.d c/package.dThat 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
On Wednesday, 1 May 2019 at 22:35:12 UTC, ag0aep6g wrote:On 02.05.19 00:25, kdevel wrote: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. [...]dmd -unittest -main -run package.d c/package.dThat doesn't compile c/package.d. Everything after `-run package.d` is interpreted as an argument to the compiled program.Or use -i so that DMD compiles the imported module automatically: dmd -unittest -main -i -run package.dThat looks nice.
May 01 2019
On Wednesday, 1 May 2019 at 22:46:34 UTC, kdevel wrote:On Wednesday, 1 May 2019 at 22:35:12 UTC, ag0aep6g wrote: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 :/On 02.05.19 00:25, kdevel wrote: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.dmd -unittest -main -run package.d c/package.dThat doesn't compile c/package.d. Everything after `-run package.d` is interpreted as an argument to the compiled program.
May 01 2019
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.dNow 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
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 mkdirmain 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