digitalmars.D.learn - compilation issues (dmd, rdmd, ldc2)
- kraxli (69/69) Feb 21 2016 I have problems with compiling a very simple program which loads
- anonymous (19/29) Feb 21 2016 dmd compiles the modules that you specify on the command line. By
- kraxli (17/47) Feb 21 2016 Thanks for coming back on that! The problem is the
- anonymous (11/30) Feb 21 2016 I don't think it works like that. If I remember correctly, you
- kraxli (8/41) Feb 21 2016 b) works! :-) Many thanks!!
- Adam D. Ruppe (17/21) Feb 21 2016 I didn't go much into it in D Cookbook since I don't use
- anonymous (17/27) Feb 21 2016 I investigated a bit on option a. The tilde (~) is the problem. Tilde
- kraxli (3/4) Feb 22 2016 Great this all works and good to know that D links as basic
I have problems with compiling a very simple program which loads a couple of modules/functions (which I would like to use later on). rdmd -I~/.dub/packages/consoled-1.0.0/source/ appX.d runs great :-) and also dub runs works. But dmd only returns: ´´´ $ dmd -I~/.dub/packages/consoled-1.0.0/source/ appX.d appX.o:(.rodata+0x98): undefined reference to `_D8consoled12__ModuleInfoZ' collect2: error: ld returned 1 exit status --- errorlevel 1 ´´´ What is going on here and what is the difference between dmd and rdmd? Moreover, ldc2 has conflicts with modules which is probably due to installation, linking and scope issues. How can I shrink the scope for ldc2 such that it only looks at the "right place" for modules (and where is that?) ? $ ldc2 -I~/.dub/packages/consoled-1.0.0/source/ appX.d /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range /usr/local/include/d/std/algorithm/iteration.d(59): Error: package name 'std.algorithm' conflicts with usage as a module name in file /usr/local/include/d/std/algorithm.d /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name range In case it is of any interest my dummy code is: ´´´ import std.stdio; import consoled; /* https://github.com/robik/ConsoleD */ import str = std.string; import curl = std.net.curl; import rx = std.regex; import std.algorithm.iteration : splitter, joiner; import std.algorithm : map; import std.typecons; import dt = std.datetime; import ar = std.array; import math = std.math : floor, ceil; import std.conv : to; import std.format : format; import std.array; import std.range.primitives; import json = std.json; import std.range : iota; void main(string[] args) { writeln("==================\nNice it compiles and runs :-)\n=================="); } ´´´ I am working on Ubuntu 14.04 (64bit), with dmd 2.070, rdmd build 20160127 and ldc2 (installed from source without any extra flags) is based on DMD v2.068.2 and LLVM 3.6.0.
Feb 21 2016
On Sunday, 21 February 2016 at 20:04:34 UTC, kraxli wrote:What is going on here and what is the difference between dmd and rdmd?dmd compiles the modules that you specify on the command line. By default, it then links an executable from the generated object files. The linking can only work when you give dmd all the code, either in source form or in compiled object form. When something is missing, you get "undefined reference" errors. That means, when your program has multiple source files (including libraries), you must put them all on the dmd command line. Or you can compile modules individually (without linking, -c flag), and then put the generated object files on the command line when linking. rdmd is a wrapper around dmd (or another, compatible compiler). It reads the dependency tree of the modules, and runs dmd on all of the source files at once. That means, you only need to put the root module on the command line for rdmd. rdmd reads the imports and generates a full list of source files for dmd.Moreover, ldc2 has conflicts with modules which is probably due to installation, linking and scope issues. How can I shrink the scope for ldc2 such that it only looks at the "right place" for modules (and where is that?) ? $ ldc2 -I~/.dub/packages/consoled-1.0.0/source/ appX.d /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name rangeI don't know what's going on there, but there shouldn't be a std/range.d with recent versions of phobos. It's a package since 2.067.0. Maybe a leftover from a previous installation?
Feb 21 2016
On Sunday, 21 February 2016 at 20:50:11 UTC, anonymous wrote:On Sunday, 21 February 2016 at 20:04:34 UTC, kraxli wrote:Thanks for coming back on that! The problem is the consoled-package which has the library: ~/.dub/packages/consoled-1.0.0/libconsoled.a So I link it (or aim to do it ;-) ) but dmd cannot find it: $ dmd -I~/.dub/packages/consoled-1.0.0/source -L-l~/.dub/packages/consoled-1.0.0/libconsoled appX.d /usr/bin/ld: cannot find -l~/.dub/packages/consoled-1.0.0/libconsoled collect2: error: ld returned 1 exit status --- errorlevel 1What is going on here and what is the difference between dmd and rdmd?dmd compiles the modules that you specify on the command line. By default, it then links an executable from the generated object files. The linking can only work when you give dmd all the code, either in source form or in compiled object form. When something is missing, you get "undefined reference" errors.That means, when your program has multiple source files (including libraries), you must put them all on the dmd command line. Or you can compile modules individually (without linking, -c flag), and then put the generated object files on the command line when linking. rdmd is a wrapper around dmd (or another, compatible compiler). It reads the dependency tree of the modules, and runs dmd on all of the source files at once. That means, you only need to put the root module on the command line for rdmd. rdmd reads the imports and generates a full list of source files for dmd.I just reinstalled it and it seems as it would have installed in the directory mentioned by ldc2: -- Installing: /usr/local/include/d/std/range -- Installing: /usr/local/include/d/std/range/primitives.d -- Installing: /usr/local/include/d/std/range/package.d -- Installing: /usr/local/include/d/std/range/interfaces.dMoreover, ldc2 has conflicts with modules which is probably due to installation, linking and scope issues. How can I shrink the scope for ldc2 such that it only looks at the "right place" for modules (and where is that?) ? $ ldc2 -I~/.dub/packages/consoled-1.0.0/source/ appX.d /usr/local/include/d/std/range.d(287): Error: module std.range from file /usr/local/include/d/std/range.d conflicts with package name rangeI don't know what's going on there, but there shouldn't be a std/range.d with recent versions of phobos. It's a package since 2.067.0. Maybe a leftover from a previous installation?
Feb 21 2016
On Sunday, 21 February 2016 at 21:21:30 UTC, kraxli wrote:Thanks for coming back on that! The problem is the consoled-package which has the library: ~/.dub/packages/consoled-1.0.0/libconsoled.a So I link it (or aim to do it ;-) ) but dmd cannot find it: $ dmd -I~/.dub/packages/consoled-1.0.0/source -L-l~/.dub/packages/consoled-1.0.0/libconsoled appX.d /usr/bin/ld: cannot find -l~/.dub/packages/consoled-1.0.0/libconsoled collect2: error: ld returned 1 exit status --- errorlevel 1I don't think it works like that. If I remember correctly, you can either a) do it the linker way: `dmd -L-L~/.dub/packages/consoled-1.0.0/ -L-lconsoled ...`, or b) do it the dmd way: `dmd ~/.dub/packages/consoled-1.0.0/libconsoled.a ...`.But is there a file /usr/local/include/d/std/range.d? If so, that's apparently not from your latest install, and it may confuse ldc. If there is no such file, then I can't make any sense of the error messages.I don't know what's going on there, but there shouldn't be a std/range.d with recent versions of phobos. It's a package since 2.067.0. Maybe a leftover from a previous installation?I just reinstalled it and it seems as it would have installed in the directory mentioned by ldc2: -- Installing: /usr/local/include/d/std/range -- Installing: /usr/local/include/d/std/range/primitives.d -- Installing: /usr/local/include/d/std/range/package.d -- Installing: /usr/local/include/d/std/range/interfaces.d
Feb 21 2016
On Sunday, 21 February 2016 at 21:35:55 UTC, anonymous wrote:On Sunday, 21 February 2016 at 21:21:30 UTC, kraxli wrote:b) works! :-) Many thanks!! a) doesn't work, I need to search for more information on linking as I would like to understand these kind of basics in D :-). The books I consulted so far (Learn D and D cookbook) did not help me to understand the linking so far ...Thanks for coming back on that! The problem is the consoled-package which has the library: ~/.dub/packages/consoled-1.0.0/libconsoled.a So I link it (or aim to do it ;-) ) but dmd cannot find it: $ dmd -I~/.dub/packages/consoled-1.0.0/source -L-l~/.dub/packages/consoled-1.0.0/libconsoled appX.d /usr/bin/ld: cannot find -l~/.dub/packages/consoled-1.0.0/libconsoled collect2: error: ld returned 1 exit status --- errorlevel 1I don't think it works like that. If I remember correctly, you can either a) do it the linker way: `dmd -L-L~/.dub/packages/consoled-1.0.0/ -L-lconsoled ...`, or b) do it the dmd way: `dmd ~/.dub/packages/consoled-1.0.0/libconsoled.a ...`.Oh yes there is such a file (and others). I need to clean these redundant files up ... Thanks here as well!But is there a file /usr/local/include/d/std/range.d? If so, that's apparently not from your latest install, and it may confuse ldc. If there is no such file, then I can't make any sense of the error messages.I don't know what's going on there, but there shouldn't be a std/range.d with recent versions of phobos. It's a package since 2.067.0. Maybe a leftover from a previous installation?I just reinstalled it and it seems as it would have installed in the directory mentioned by ldc2: -- Installing: /usr/local/include/d/std/range -- Installing: /usr/local/include/d/std/range/primitives.d -- Installing: /usr/local/include/d/std/range/package.d -- Installing: /usr/local/include/d/std/range/interfaces.d
Feb 21 2016
On Sunday, 21 February 2016 at 21:51:27 UTC, kraxli wrote:a) doesn't work, I need to search for more information on linking as I would like to understand these kind of basics in D :-). The books I consulted so far (Learn D and D cookbook) did not help me to understand the linking so far ...I didn't go much into it in D Cookbook since I don't use libraries like this... the easiest way IMO is to forget the -I switch exists, don't use it, and don't mess with .lib/.a files at all either. Just pass all the source files to the compiler together so like: dmd yourprogram.d /path/to/consoled/consoled.d and it will all just work because then the compiler knows where the module is (thus obviating -I) and can compile the source on-demand (thus skipping the library linking). But if you don't do it this way, linking is just getting all the *compiled* code together, whereas the -I think is just about getting all the *imported source* together. When you import something, the compiler reads the declarations for a module, but does not necessarily generate code for it. Linking links the generated code for the different modules together.
Feb 21 2016
On 21.02.2016 22:51, kraxli wrote:On Sunday, 21 February 2016 at 21:35:55 UTC, anonymous wrote:[...]I investigated a bit on option a. The tilde (~) is the problem. Tilde expansion is only done when it's the first character of a word. So you either have to replace the tilde with "/home/foo", or somehow make it the first character of a word for the shell. Since you can't just put a space there, you would have to hack around a bit. For example: dmd -L-L`echo ~`/.dub/packages/consoled-1.0.0/ ... Regarding learning about linking: dmd's -L flag just forwards its argument to the linker. The linker isn't D-specific. To learn about linking in D you can learn about compiling/linking in general (what's a compiler, what's a linker, what's an object file, etc.), and you can learn about the command line interface of the specific linker that dmd invokes. On Ubuntu, dmd calls gcc for linking, which in turn calls ld. So if you want to know what to put into those -L arguments, you have to learn the gcc/ld command lines.a) do it the linker way: `dmd -L-L~/.dub/packages/consoled-1.0.0/ -L-lconsoled ...`, or b) do it the dmd way: `dmd ~/.dub/packages/consoled-1.0.0/libconsoled.a ...`.b) works! :-) Many thanks!! a) doesn't work, I need to search for more information on linking as I would like to understand these kind of basics in D :-). The books I consulted so far (Learn D and D cookbook) did not help me to understand the linking so far ...
Feb 21 2016
On Sunday, 21 February 2016 at 22:53:17 UTC, anonymous wrote:On 21.02.2016 22:51, kraxli wrote:Great this all works and good to know that D links as basic gcc/llvm link. Thanks a lot to everybody - very helpful!
Feb 22 2016