A suggestion for modules names / sharing code between projects
Sebastien Alaiwan via Digitalmars-d
digitalmars-d at puremagic.com
Wed Mar 2 12:40:39 PST 2016
On Wednesday, 2 March 2016 at 08:50:50 UTC, Mike Parker wrote:
> I'm curious what sort of system you have in mind. How does the
> current system not work for you and what would you prefer to
> see?
First, you must know that I've been a C++ programmer for way too
much time ;
and that my way of thinking about modules has probably been -
badly - shaped accordingly :-).
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.
I'm going to answer your first question, I hope you don't get
bored before the end ;-)
First some generic stuff:
- The libraries I write are source-only, and I never install them
system-wide, as many projects might depend on different revisions
of one library.
- 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).
- I often mix C code with D, sometimes, C++ code. I compile them
using gcc/g++.
- My build system is composed of simple dependency-aware
non-recursive makefiles (BTW, this is a great way to keep your
code decoupled, otherwise you might not get feedback that you're
making a dependency mess soon enough!)
This is the best way I found to be able to checkout one project,
type 'make',
and have everything build properly, wether I'm doing it on
GNU/Linux or on Windows (MSYS).
Everything is under version control using GNU Bazaar (which
basically is to git what D is to C++).
I have a small library, which I call "lib_algo", containing
semi-related utilities (containers, topological sort, etc.) which
I use in many projects.
$ cd myLibs
$ find lib_algo -name "*.d" -or -name "*.mk" -or name "Makefile"
lib_algo/options.d
lib_algo/misc.d
lib_algo/pointer.d
lib_algo/set.d
lib_algo/queue.d
lib_algo/algebraic.d
lib_algo/vector.d
lib_algo/bresenham.d
lib_algo/topological.d
lib_algo/fix_array.d
lib_algo/test.d
lib_algo/pool.d
lib_algo/stack.d
lib_algo/list.d
lib_algo/array2d.d
lib_algo/project.mk
lib_algo/Makefile
(I know, there's some overlap with Phobos today)
The project.mk simply contains the list of source files of the
library.
The test.d file actually contains a main function, which I use to
run manual tests of the library functionalities. It's not
included in the project.mk list. And it obviously must import the
files needing to be tested.
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).
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.
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" ?
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?
(And please, don't tell me that I need to switch to
dub+git+dmd+D_source_files_only ; I like my tools to be
composable)
Thanks for reading!
More information about the Digitalmars-d
mailing list