Thread overview
Module without object file?
Jan 04, 2022
kdevel
Jan 06, 2022
frame
Jan 06, 2022
kdevel
Jan 07, 2022
frame
Jan 08, 2022
kdevel
Jan 06, 2022
kdevel
Jan 07, 2022
Johan
January 04, 2022

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?

January 06, 2022

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?

January 05, 2022

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

January 06, 2022

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?

January 06, 2022

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

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.

January 07, 2022

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?

January 07, 2022

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

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

January 07, 2022

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

January 08, 2022

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.