A suggestion for modules names / sharing code between projects
Mike Parker via Digitalmars-d
digitalmars-d at puremagic.com
Wed Mar 2 17:47:08 PST 2016
On Wednesday, 2 March 2016 at 20:40:39 UTC, Sebastien Alaiwan
wrote:
> However, it feels wrong that modules (foo, bar) inside the same
> package ("pkg") need to repeat the "absolute" package name when
> referencing each other, I mean "import pkg.foo" instead of
> "import foo". Not because of the extra typing, but because of
> the dependency it introduces. But as I said, maybe my vision is
> wrong.
The package name is part of the module name. If you use
thislib.somemod and thatlib.somemod, how would you disambiguate
them without the package name? Even in C and C++, libraries are
often distributed with header files in a sub directory, where the
top-level directory is intended to be added to the include path
and not the subdirecotry, otherwise two includes with the same
name conflict. Some libraries go further and prefix their header
files with a namespace (like sdl_foo.h, sdl_bar.h), because they
get no help from the compiler with this. Making the package name
part of the fully qualified module name helps minimize the
likelihood of such conflicts. It also gives a natural namespace
for conflicting symbols in two modules named foo. You can use
thispack.somemod.foo and thatpack.somemod.foo to disambiguate.
> - I only work with separate compilation, using gdc (Windows-dmd
> produces OMF, which is a dealbreaker ; but I use rdmd a lot for
> small programs).
-m64 or -m32mscoff
> - I often mix C code with D, sometimes, C++ code. I compile
> them using gcc/g++.
Assuming MinGW, the GDC is definitely your best bet here. The
flags above will get DMD to produce COFF for the MS linker, but
MinGW COFF and MS COFF are not always compatible.
>
> With this flat directory structure, the only way test.d can
> import files is by saying, "import stack;", not "import
> lib_algo.stack".
> (adding ".." to the list of import directories might do the
> trick, but this would definitely feel wrong).
It is wrong. You should add ../mylibs :)
> Now, let's see a project using this "lib_algo", I call it
> "myGame".
>
> $ cd myProjects
> $ find <files relevant to this discussion>
> myGame/lib_algo/options.d
> myGame/lib_algo/....
> myGame/lib_algo/array2d.d
> myGame/lib_algo/project.mk
> myGame/lib_algo/Makefile
> myGame/src/main.d
> myGame/Makefile
>
>
> "lib_algo" simply is an external (aka "git submodule"),
> pointing to a specific revision of the repository "lib_algo".
> The top-level "Makefile" of the projects includes
> "lib_algo/project.mk", and all is well, I can compose the list
> of source files to compile without having to rely on
> "convenience/intermediate" libraries.
>
> Now, if "src/main.d" wants to import "array2d.d", currently, I
> must write "import array2d.d", and add "-I myGame/lib_algo" to
> my compiler command line.
> I said in a previous post that this would not scale.
> That's because with this scheme, obviously, I can't have two
> modules having the same name, even if they belong to different
> libraries.
> Let's say I have "lib_algo/utils.d" and "lib_geom/utils.d", if
> "main.d" says "import utils.d", it's ambiguous.
Assuming that all of the libraries you are going to use are set
up the same way, then you can simply pass -ImyGame. Then you can
use lib_algo.utils, lib_geom.utils, and so on. What's the problem
with that?
>
> Clearly, "main.d" needs to say "import lib_algo.utils".
> However, if I do this,
> I must add a module declaration in "lib_algo/utils.d", and I
> must change
> "lib_algo/test.d" so it says "import lib_algo.utils".
>
> This is where it begins to feel clumsy. Why should lib_algo
> need to be
> modified in order to resolve an ambiguity happening in "myGame"
> ?
You shouldn't have to "change" it. This is how it should be set
up from the beginning. The idea is that you decide on a module
structure as soon as you start your project and then you stick to
it.
The module declaration is necessary when using packages because
otherwise DMD has no idea how far up the path to go to create a
default package name. That's why the it uses only the file name
when no module declaration is present. The package name is the
solution to *prevent* ambiguities, not to resolve them after the
fact. If you don't want lib_algo/util.d and lib_geom/util.d to
conflict, then the use both lib_algo and lib_geom as package
names in module declarations. How else would you propose
resolving the ambiguity?
>
> Moreover, we saw earlier that this modification of the import
> done by
> "lib_algo/test.d" had consequences on the directory structure
> of lib_algo.
> In order to be able to build the test executable for lib_algo,
> I now need to
> have the following structure:
> $ find lib_algo
> lib_algo/lib_algo/options.d
> lib_algo/lib_algo/....
> lib_algo/lib_algo/array2d.d
> lib_algo/test.d
> (test.d can be put inside the inner "lib_algo")
>
> Am I the only one to find this counterintuitive - and probably
> wrong?
> What am I missing there?
No, you don't have to set it up that way. If your top-level
directory is always named the same as your top-level package
name, then you can just use its parent directory.
mylibs/lib_algo/*.d
mylibs/lib_geom/*.d
dmd -Imylibs main.d
Done. Does not the same issue exist in C++? You either have to
keep all of your headers in a single directory or pass multiple
directories on the command line with -I.
What I used to do before I started using DUB exclusively was
model the system I used for C and C++ projects. For every new
project I created, I had created an imports subdirectory in the
project, then ran a script (written in D) to copy over the source
tree of the specific version of each library I wanted to use.
Then I added -Iimport on the command line when compiling. Done.
The package and module system is very intuitive to me and has
been from the beginning, so I'm still not quite sure what it is
about it that bothers you. The two major issues you bring up
here, the need to import package.module and how to structure your
projects, are easily resolved. Am I misunderstanding something?
More information about the Digitalmars-d
mailing list