www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Imports and Subfolders and Links (Oh, My!)

reply Ron Tarrant <rontarrant gmail.com> writes:
Trying to wrap my brain around imports, etc.

In various places around the Internet, I've read that if I have 
modules in a subfolder/subdirectory, my import statement would 
look like this:

import subfolder.ModuleName;

And in the module files, the first statement is:

module ModuleName;

However, I'm having trouble getting past the compile errors.

Scenario:
current folder contains - main.d

In main.d, the import statements:
import app.CountryTreeView
import app.CountryListStore

In the subfolder (named: app) I have two module files:
  - CountryTreeView.d (module CountryTreeView)
  - CountryListStore.d (module CountryListStore)

When I compile using:

dmd -m64 -Lgtkd.lib main.d

I get a bunch of unresolved external symbol errors for classes 
and modules. The import statements in main.d don't import 
anything from the subfolder.

Removing 'app.' from the import statements and compiling with:

dmd -m64 -Lgktd.lib main.d -Iapp CountryListStore CountryTreeView

it works.

Two questions:
1) Under what circumstances would I prefix the folder/directory 
name in a statement importing modules I've built myself?
2) What would the dmd compile command look like?
Dec 07 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 7 December 2018 at 16:39:34 UTC, Ron Tarrant wrote:
 import subfolder.ModuleName;

 And in the module files, the first statement is:

 module ModuleName;
That's wrong: the import name and the module name should always match, in full, including all the dot parts. So if you "import app.modulename;", the other file must have "module app.modulename;"
 dmd -m64 -Lgtkd.lib main.d
Moreover, you should either 1) list all modules in your application not in a library on the command line, or 2) if using the newest compiler versions, pass the -i flag so the compiler will automatically include them for you.
Dec 07 2018
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Friday, 7 December 2018 at 16:43:02 UTC, Adam D. Ruppe wrote:
 That's wrong: the import name and the module name should always 
 match, in full, including all the dot parts.

 So if you "import app.modulename;", the other file must have 
 "module app.modulename;"
Okay. I guess the instructions I saw were for an earlier version of D... or I misunderstood. (either is likely?)
 Moreover, you should either 1) list all modules in your 
 application
Are you talking about a list of import statements here or is there another way/place I would list them?
 not in a library on the command line,
I'm not sure what you mean by 'library' in this statement.
 or 2) if using the newest compiler versions, pass the -i flag 
 so the compiler will automatically include them for you.
I tried this and it worked. Just still trying to understand when it would be necessary to use a prefix and dot separator in an import statement. The bottom line here is, I have an application (Corkboard) I wrote in PHPGtk years ago and I'm learning D by transposing it. I'd like to maintain the code organization I had in the original — subfolders, etc. At the same time, I'd like to put my big-boy pants on and make it look like I know what I'm doing when I compile rather than compiling modules over and over needlessly. Does D have the concept of makefiles? I haven't run across any reference to such things so far.
Dec 07 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 08/12/2018 6:41 AM, Ron Tarrant wrote:
 Does D have the concept of makefiles? I haven't run across any reference 
 to such things so far.
Make isn't a D specification application (it doesn't really specialize in any language) dmd, druntime and Phobos are all built using it. Though for user code, dub is the package+build manager that is more commonly used.
Dec 07 2018
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Dec 08, 2018 at 06:48:46AM +1300, rikki cattermole via
Digitalmars-d-learn wrote:
 On 08/12/2018 6:41 AM, Ron Tarrant wrote:
 Does D have the concept of makefiles? I haven't run across any
 reference to such things so far.
Make isn't a D specification application (it doesn't really specialize in any language) dmd, druntime and Phobos are all built using it. Though for user code, dub is the package+build manager that is more commonly used.
You can surely use Makefiles to compile your D code. DMD, druntime, and Phobos use Makefiles. :-D Though due to limitations with makefiles, I prefer to use SCons. I'd use dub as a package manager, but I find its limitations as a build manager too frustrating and a total deal-breaker for the kind of builds I need to do, so I generally avoid using it as such. T -- Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
Dec 07 2018
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 7 December 2018 at 17:41:47 UTC, Ron Tarrant wrote:
 Are you talking about a list of import statements here or is 
 there another way/place I would list them?
On the dmd command line. So say your program has a.d and b.d, you would compile with `dmd a.d b.d`. Or as you had some success with, the newer compilers let you just do `dmd -i a.d` and it finds the rest based on the import statements.
 I'm not sure what you mean by 'library' in this statement.
For example, since you are using gtkd.lib, you don't have to include all of gtkd's source files. (The compiler needs to be able to FIND them, but you don't have to list them.) If you were using a makefile, you may only list one file at a time to compile each separately, then link together all the generate .obj files as a separate step.
 Just still trying to understand when it would be necessary to 
 use a prefix and dot separator in an import statement.
The most practical answer is "always". There's some exceptions that work for simple cases, but even then you put yourself at potential conflicts if some library author decided to pick the same name. So you are really better off just always using some prefix and always listing the full name. module myprojectname.mymodulename; at the top of every file in your source tree. (Or you can use more dots if you want to further subdivide it, like "myprojectname.helper.whatever.mymodulename"). And when importing it, always list the full name, exactly the same as you listed it in the module definition. import myprojectname.mymodulename; import myprojectname.helper.whatever.mymodulename; Every time you use it, from any location. Then it will work in all cases, whether compiling all at once (which I recommend btw), or using a makefile, or any other build system, even if you decide to bring in more libraries or your program grows beyond the super simple cases. You can organize the subfolders based on those dot names (or do the dot names based on the subfolders if that is existing) and that will ease the process a bit more. But regardless of the folder layout and file locations, always use the full names and be sure they match in module and import statements.
 when I compile rather than compiling modules over and over 
 needlessly.
Oh, lots of us compile everything at once. It works quite well and is fast for many applications that you don't need to do anything more.
 Does D have the concept of makefiles? I haven't run across any 
 reference to such things so far.
Yes, you can use a makefile with D basically the same as with C. But you may find it actually builds slower than just dmd -i main.d....
Dec 07 2018
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Dec 07, 2018 at 07:01:18PM +0000, Adam D. Ruppe via Digitalmars-d-learn
wrote:
 On Friday, 7 December 2018 at 17:41:47 UTC, Ron Tarrant wrote:
[...]
 when I compile rather than compiling modules over and over
 needlessly.
Oh, lots of us compile everything at once. It works quite well and is fast for many applications that you don't need to do anything more.
Yes, the D compiler is fast enough that for a small project, recompiling everything vs. compile a single source file doesn't make a noticeable difference in compilation time. For larger projects, the general recommendation is to use the package as your unit of recompilation, i.e., if you have your source tree structure like this: package1/ package1/mod1.d package1/mod2.d package2/ package2/mod1.d package2/mod2.d then when you recompile, if package1/* hasn't been touched, but package2/mod2.d was changed, then recompile package2/* into a static library, and relink your application. The above example is greatly simplified, of course; generally, your package subdirs would have 10+ source files or so before this sort of per-package recompilation actually benefits compilation times. In some of my projects, where package subdirs are relatively small, I just lump the source files inside together with everything else and just recompile the whole thing at once. IME, separately recompiling individual .d files generally slows down compilation rather than speed it up -- the linker has more work to do to resolve cross-references that the compiler would have statically resolved had you passed all source files at once instead.
 Does D have the concept of makefiles? I haven't run across any
 reference to such things so far.
Yes, you can use a makefile with D basically the same as with C. But you may find it actually builds slower than just dmd -i main.d....
This is true for most small to medium-sized projects. For larger projects, it does help to compile different packages separately (perhaps in parallel if your build system supports that). In my own projects, I actually use my build system more to resolve other complex tasks than to individually compile D source files; I'd just specify what amounts to `dmd *.d` in a single build rule, and most of the rest of the build script is to handle other tasks, like generating code from input data, preprocessing resource files, building/signing packages, compiling code in other languages (Java, C, etc.), installation to the staging area for testing, etc.. So ironically, most of my build rules concern stuff other than compilation. :-D T -- Stop staring at me like that! It's offens... no, you'll hurt your eyes!
Dec 07 2018
parent reply Ron Tarrant <rontarrant gmail.com> writes:
So, the upshot of it all seems to be that the -i's have it.
Dec 07 2018
parent Ron Tarrant <rontarrant gmail.com> writes:
Thanks everyone.
Dec 09 2018