www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - ModuleInfo Error

reply Johnson Jones <JJ Dynomite.com> writes:
I routinely get this error when I forget to add a module that I 
import to the project. It throughs me for a loop because the 
error doesn't really make sense for what is actually wrong(or 
does it?):


Error 42: Symbol Undefined _D9DLLImport12__ModuleInfoZ 
(DLLImport.__ModuleInfo)

Adding DLLImport.d to the project solves the problem. I'm using 
Visual D so I guess adding the file to the project adds it to the 
includes on the command line.

I guess this is due to the fact that the module does not have a 
library backing and the __ModuleInfo function isn't generated for 
it so it doesn't exist anywhere? (Just guessing)

Surely we could get a better error message for this or dmd could 
somehow try and automatically remedy the situation?

What is __ModuleInfo? An automatically generated function for a 
module by dmd when a module is compiled? If so, why not keep 
track of all the modules that have bee used and if this error 
occurs, compile the module or do whatever needs to be done so the 
error is not necessary?

New users to D will be thrown by this error. It is meaningless as 
far as being helpful and there is virtually no online help for 
it... and one doesn't get this for standard stuff like phobos 
modules, again, I guess because they have a library that has 
these functions in it. I'm pretty sure dmd could auto detect this 
issue and try to resolve it internally. I've gotten it several 
times in different projects in the past.
Aug 09 2017
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 August 2017 at 21:29:07 UTC, Johnson Jones wrote:
 I routinely get this error when I forget to add a module that I 
 import to the project.
You learn it pretty quickly though, don't you?
 I guess this is due to the fact that the module does not have a 
 library backing and the __ModuleInfo function isn't generated 
 for it so it doesn't exist anywhere? (Just guessing)
Yeah, basically. __ModuleInfo isn't a function, rather it is a block of static data telling the runtime where its static ctors, dtors, unittests, etc. are, but same idea. When you compile a .d file, the module info is automatically generated and put in the file with the functions you write. When you import a module, the compiler emits a reference to that moduleinfo so it can run its static ctors, etc., if present in your program. Importing a module without linking in its library or object file causes the error you see.
 Surely we could get a better error message for this or dmd 
 could somehow try and automatically remedy the situation?
So it technically isn't actually dmd generating that error... it happens at the link step, after dmd is done. Though dmd could parse the linker output and replace it with different text... but that is a pretty big pain and like I hinted above, this is the kind of thing you might be slightly baffled by the first time, but quickly learn what it means so the ongoing cost is pretty small. Replacing the text from the linker isn't just a one time implementation either: it'd have to keep up with changes from other linkers or version updates, and would likely break any special output (such as colors) that it tries to do. However...
 If so, why not keep track of all the modules that have bee used 
 and if this error occurs, compile the module or do whatever 
 needs to be done so the error is not necessary?
...that's what rdmd does. I think it is distributed with the compiler. dmd itself doesn't do that though since a valid use case (and fairly common with dmd's corporate users) is to compile and link separately, like people do with C++, to improve working with their complex build systems (speed, external assets, proprietary libraries, etc. don't work as well with my preferred "dmd *.d" strategy so they make it fancy af), so automatically compiling everything would actually be a step backward for those people. But you might want to try using rdmd. You just pass it the function with main and it figures out the rest by walking the import path, then calls dmd to actually compile.
 New users to D will be thrown by this error. It is meaningless 
 as far as being helpful and there is virtually no online help 
 for it...
It is a FAQ... though cannot easily be found. Maybe you (or someone else) should ask on SO and put an answer up there so we can start linking to that?
Aug 09 2017
parent reply Johnson Jones <JJ Dynomite.com> writes:
On Wednesday, 9 August 2017 at 22:00:56 UTC, Adam D. Ruppe wrote:
 On Wednesday, 9 August 2017 at 21:29:07 UTC, Johnson Jones 
 wrote:
 I routinely get this error when I forget to add a module that 
 I import to the project.
You learn it pretty quickly though, don't you?
no ;/ I have a memory like a rock. Which is either infinite or zero ;/ I tend to do a lot of things and after months of not seeing something I tend to flush my cache. Specially if I don't program in D for a while. It's one thing when you do something every day but when you do things in squirts, you tend to memorize what you need to know for that purpose then soon forget when you no longer need it.
 I guess this is due to the fact that the module does not have 
 a library backing and the __ModuleInfo function isn't 
 generated for it so it doesn't exist anywhere? (Just guessing)
Yeah, basically. __ModuleInfo isn't a function, rather it is a block of static data telling the runtime where its static ctors, dtors, unittests, etc. are, but same idea. When you compile a .d file, the module info is automatically generated and put in the file with the functions you write. When you import a module, the compiler emits a reference to that moduleinfo so it can run its static ctors, etc., if present in your program. Importing a module without linking in its library or object file causes the error you see.
 Surely we could get a better error message for this or dmd 
 could somehow try and automatically remedy the situation?
So it technically isn't actually dmd generating that error... it happens at the link step, after dmd is done. Though dmd could parse the linker output and replace it with different text... but that is a pretty big pain and like I hinted above, this is the kind of thing you might be slightly baffled by the first time, but quickly learn what it means so the ongoing cost is pretty small. Replacing the text from the linker isn't just a one time implementation either: it'd have to keep up with changes from other linkers or version updates, and would likely break any special output (such as colors) that it tries to do. However...
 If so, why not keep track of all the modules that have bee 
 used and if this error occurs, compile the module or do 
 whatever needs to be done so the error is not necessary?
...that's what rdmd does. I think it is distributed with the compiler. dmd itself doesn't do that though since a valid use case (and fairly common with dmd's corporate users) is to compile and link separately, like people do with C++, to improve working with their complex build systems (speed, external assets, proprietary libraries, etc. don't work as well with my preferred "dmd *.d" strategy so they make it fancy af), so automatically compiling everything would actually be a step backward for those people. But you might want to try using rdmd. You just pass it the function with main and it figures out the rest by walking the import path, then calls dmd to actually compile.
 New users to D will be thrown by this error. It is meaningless 
 as far as being helpful and there is virtually no online help 
 for it...
It is a FAQ... though cannot easily be found. Maybe you (or someone else) should ask on SO and put an answer up there so we can start linking to that?
Well, I use Visual D and not sure if it can use rdmd(I'm sure it can be hacked) . Is there any benefits or downsides to doing this? I guess it's not a huge deal at the end of the day... but stuff like this just shouldn't be an issue. Are we going to be dealing with such things 50 years down the road? (well, not us, but the next generation?) I find most of the problems that we have(not just as programmers, but as human beings) tend to be because people cannot cut ties with the past and learn from their mistakes. Do we even need to separate the linker and compiler? Shouldn't they be able to communicate with each other internally to get the most information they can to make our lives easier? A simple switch could be used to separate linking and compiling. I feel that "modern" programming is still trapped in the past and we all ultimately suffer from it. Most people just don't realize how much better it could be. How many people have quit using D because of all the issues it has or simply because it doesn't have the momentum to carry them through life? I've seen a couple recently simply cut ties. They wouldn't have to do this if they could make a living using D, which means that D is has failed them, which is sad ;/ I don't think the powers at be really comprehend those things as they have don't have to worry nor experience those things to understand... hence, there is no motivation to get D on the right footing so it is not such a problem. An unfortunate set of circumstances. Anyways, I'll just try to remember, ranting about that stuff makes it stick in my mind better I guess, and at least a forum search of __ModuleInfo should bring up something ;)
Aug 09 2017
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 9 August 2017 at 22:43:03 UTC, Johnson Jones wrote:
 Well, I use Visual D and not sure if it can use rdmd(I'm sure 
 it can be hacked)
I don't know.
 because people cannot cut ties with the past and learn from 
 their mistakes.  Do we even need to separate the linker and 
 compiler?
Like I said though, a lot of D's corporate users see this as being a major feature for their productivity. So it isn't quite as clear cut that one way is better than the other. But Walter has said he is interested in doing an integrated linker and getting benefits from it, just that's a lot more work than it sounds like and he has a lot of other things to do...
Aug 10 2017
parent reply Johan <j j.nl> writes:
On Thursday, 10 August 2017 at 14:32:04 UTC, Adam D. Ruppe wrote:
 On Wednesday, 9 August 2017 at 22:43:03 UTC, Johnson Jones 
 wrote:

 because people cannot cut ties with the past and learn from 
 their mistakes.  Do we even need to separate the linker and 
 compiler?
Like I said though, a lot of D's corporate users see this as being a major feature for their productivity. So it isn't quite as clear cut that one way is better than the other.
Separating compilation and linking is helpful for example for reducing the build time of incremental builds and parallelizing builds. A number of language semantics I personally understand in terms of separate codegen and linking, but I am not sure if that's strictly needed (D being a systems language, probably it is). Separate compilation is also needed for cross-language interop (e.g. for a mixed C++/D codebase).
 But Walter has said he is interested in doing an integrated 
 linker and getting benefits from it, just that's a lot more 
 work than it sounds like and he has a lot of other things to 
 do...
Kinke has added LLD to LDC for MSVC, and for other platforms it is a WIP. See https://github.com/ldc-developers/ldc/pull/2142 , https://github.com/ldc-developers/ldc/pull/2203 . So already LDC running on Linux can generate a Windows executable. -Johan
Aug 10 2017
parent Steef Boerrigter <sxmboer gmail.com> writes:
On Thursday, 10 August 2017 at 16:05:07 UTC, Johan wrote:
 On Thursday, 10 August 2017 at 14:32:04 UTC, Adam D. Ruppe 
 wrote:
 On Wednesday, 9 August 2017 at 22:43:03 UTC, Johnson Jones 
 wrote:

 because people cannot cut ties with the past and learn from 
 their mistakes.  Do we even need to separate the linker and 
 compiler?
Like I said though, a lot of D's corporate users see this as being a major feature for their productivity. So it isn't quite as clear cut that one way is better than the other.
Separating compilation and linking is helpful for example for reducing the build time of incremental builds and parallelizing builds. A number of language semantics I personally understand in terms of separate codegen and linking, but I am not sure if that's strictly needed (D being a systems language, probably it is). Separate compilation is also needed for cross-language interop (e.g. for a mixed C++/D codebase).
 But Walter has said he is interested in doing an integrated 
 linker and getting benefits from it, just that's a lot more 
 work than it sounds like and he has a lot of other things to 
 do...
Kinke has added LLD to LDC for MSVC, and for other platforms it is a WIP. See https://github.com/ldc-developers/ldc/pull/2142 , https://github.com/ldc-developers/ldc/pull/2203 . So already LDC running on Linux can generate a Windows executable. -Johan
I have been struggling with this same linking problem. I have a library folder with *.o files that I compiled into a static library: mylibrary.a In this folder, I have a package.d that publicly imports all the .d sources in that folder (as is recommended). I compile an application in the main folder as follows: dmd -I=mylibrary mylibrary/mylibrary.a application.d Initially, this worked fine, but, at some point after adding stuff to the library, I started having the aforementioned linking problem. For me, the problem was fixed when I compiled package.d into package.o (dmd -c package.d) and added it to the .a file. I am guessing, for shared objects (.so files) you also need to add the package.o file to the library in order for it to include the reference to moduleInfo. Note that compiling the same program with dmd application.d mylibrary/*.d also works, because that includes the package.d file. If package.d is omitted from the list you get the exact same ld: undefined reference to _...._ModuleInfoZ
Oct 24 2022