www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Module without object file?

reply kdevel <kdevel vogtner.de> writes:
In a project I have this "controller" function:

```
void create_fso (O) (Request req)
{
    :
    auto npathname = (extract name from req)
    :
    O.create (npathname);
    :
}

public import fsobjects;
```

which creates a file system object. The possible object types I 
collected in a separate module ``fsobject.d``:

```
module fsobjects;

import std.file : write;
import std.file : mkdir;

struct File {
    enum title = "file";
    enum void function (string) create = (fn => write (fn, ""));
}

struct Directory {
    enum title = "directory";
    enum void function (string) create = (fn => mkdir (fn));
}
```

Within the router the controller templates are instantiated as

```
    register_action (GET | POST, "/file.create", 
&create_fso!(File));
    register_action (GET | POST, "/directory.create", 
&create_fso!(Directory));
```

This all works fine. But: Unless fsobjects.d is compiled linking 
fails with the error message

```
...  undefined reference to `_D9fsobjects12__ModuleInfoZ'
```

Is there any chance to rephrase fsobjects.d such that it becomes 
a "header only"/"compile only" file of which no object file must 
be presented to the linker?
Jan 04 2022
next sibling parent reply frame <frame86 live.com> writes:
On Tuesday, 4 January 2022 at 22:17:38 UTC, kdevel wrote:

 Is there any chance to rephrase fsobjects.d such that it 
 becomes a "header only"/"compile only" file of which no object 
 file must be presented to the linker?
You didn't show how you compiled your files. If you want the compiler to only compile, you have to tell it via `-c` switch. If the linker wants that reference, it's also needed. Maybe you forgot the `-i` switch then?
Jan 05 2022
parent reply kdevel <kdevel vogtner.de> writes:
On Thursday, 6 January 2022 at 02:37:41 UTC, frame wrote:
 On Tuesday, 4 January 2022 at 22:17:38 UTC, kdevel wrote:

 Is there any chance to rephrase fsobjects.d such that it 
 becomes a "header only"/"compile only" file of which no object 
 file must be presented to the linker?
You didn't show how you compiled your files.
Oops. Essentially with dmd -c without -i.
 If you want the compiler to only compile, you have to tell it 
 via `-c` switch.
 If the linker wants that reference, it's also needed. Maybe you 
 forgot the `-i` switch then?
In my setup make decides which file to (re)compile. Just found that dmd has the option -makedeps which resembles gcc's -M but theres no -MM to excluded dependencies from system files. Also gcc -M/-MM does not compile while dmd always generated object file(s), too. Is there any way to stop this object file generation?
Jan 06 2022
parent reply frame <frame86 live.com> writes:
On Thursday, 6 January 2022 at 22:54:59 UTC, kdevel wrote:

 In my setup make decides which file to (re)compile. Just found 
 that dmd has the option -makedeps which resembles gcc's -M but 
 theres no -MM to excluded dependencies from system files. Also 
 gcc -M/-MM does not compile while dmd always generated object 
 file(s), too. Is there any way to stop this object file 
 generation?
Yes, `-o-`. Not sure about `-MM` equivalent but if you manually process the dependencies you can filter the "system" files out anyway. I don't understand how your setup works. Is there any problem by recompiling those files with dmd `-i` switch?
Jan 07 2022
parent kdevel <kdevel vogtner.de> writes:
On Friday, 7 January 2022 at 09:18:29 UTC, frame wrote:
 On Thursday, 6 January 2022 at 22:54:59 UTC, kdevel wrote:

 In my setup make decides which file to (re)compile. Just found 
 that dmd has the option -makedeps which resembles gcc's -M but 
 theres no -MM to excluded dependencies from system files. Also 
 gcc -M/-MM does not compile while dmd always generated object 
 file(s), too. Is there any way to stop this object file 
 generation?
Yes, `-o-`. Not sure about `-MM` equivalent but if you manually process the dependencies you can filter the "system" files out anyway.
grep -v will do.
 I don't understand how your setup works. Is there any problem 
 by recompiling those files with dmd `-i` switch?
Everything works fine.
Jan 08 2022
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/4/22 5:17 PM, kdevel wrote:

 Is there any chance to rephrase fsobjects.d such that it becomes a 
 "header only"/"compile only" file of which no object file must be 
 presented to the linker?
Possibly. You see, you are importing another module. Since you are doing that, the module must participate in cycle detection at the beginning of running the program. The way D does this is to store the import graph inside a `ModuleInfo` struct stored in the object. When you import this file, the compiler sees that it has imports, and assumes you must have built the `ModuleInfo` in some object somewhere, so it outputs a reference for the import graph. What *might* work is to make all your things templates, which by definition are processed when instantiated, and then inside those template, do your imports. But I'm not sure, the compiler might still require the `ModuleInfo`. -Steve
Jan 05 2022
parent reply kdevel <kdevel vogtner.de> writes:
On Thursday, 6 January 2022 at 02:47:17 UTC, Steven Schveighoffer 
wrote:
 Possibly. You see, you are importing another module. Since you 
 are doing that, the module must participate in cycle detection 
 at the beginning of running the program.
IC. Had cyclic module dependencies twice within this project.
 The way D does this is to store the import graph inside a 
 `ModuleInfo` struct stored in the object.

 When you import this file, the compiler sees that it has 
 imports, and assumes you must have built the `ModuleInfo` in 
 some object somewhere, so it outputs a reference for the import 
 graph.
Makes sense. It seems that if there are just type definitions with enum constants the module is a "leaf module". As soon as I add the delegate which calls writefln ```somemodule.d struct File { enum title = "File"; enum void function (string) foo = (a => writefln ("a <%s>", a)); } ``` to the source the linker complains about the missing ModuleInfo.
Jan 06 2022
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/6/22 6:06 PM, kdevel wrote:
 When you import this file, the compiler sees that it has imports, and 
 assumes you must have built the `ModuleInfo` in some object somewhere, 
 so it outputs a reference for the import graph.
Makes sense. It seems that if there are just type definitions with enum constants the module is a "leaf module". As soon as I add the delegate which calls writefln ```somemodule.d struct File {    enum title = "File";    enum void function (string) foo = (a => writefln ("a <%s>", a)); } ``` to the source the linker complains about the missing ModuleInfo.
The reasons the compiler decides to require `ModuleInfo` are somewhat unspecified. I would have expected just importing std.stdio would do it, but maybe you have to actually use something from that module. -Steve
Jan 07 2022
prev sibling parent Johan <j j.nl> writes:
On Tuesday, 4 January 2022 at 22:17:38 UTC, kdevel wrote:
 
 Is there any chance to rephrase fsobjects.d such that it 
 becomes a "header only"/"compile only" file of which no object 
 file must be presented to the linker?
https://wiki.dlang.org/LDC-specific_language_changes#LDC_no_moduleinfo -Johan
Jan 07 2022