This is a list of issues found while making the D ecosystem available on Linux distributions such as Debian and Fedora. It is a smaller, but priorized list of the general list of issues I find while working with D that can be viewed at dlang-quirks.md.
This list is ordered by priority, more pressing issues being at the top.
-
D has no stable ABI. This kind of enforces recompiling all D shared libraries and binaries in a Linux distribution with every new compiler version. This is possible, but a major pain which requires quite some amount of manpower (Debian does this for OCaml and Haskell) - getting people to use D if it is that much extra work is harder. It also means that you can not use the libraries which were compiled with LDC in an application that is compiled with GDC and vice versa. This is a real PITA for distros and users who might have binaries compiled with the "wrong" compiler. It reduces the usefulness of development D packages in distributions a lot, if you need to recompile everything again anyway. Static linking is also frowned upon by distributions, because it triggers rebuild cascades on every bugfix that we introduce, making devlivering security updates much harder and error-prone (embedded code copies are very difficult to handle). A stable D ABI, or at least a guarantee that the ABI will not change unless there is a good reason (and the ABI change will be announced in the release notes) would help a lot. Having a D ABI that is shared between DMD, LDC and GDC would be even better.
-
Dub doesn't use packages installed to system locations (dlang/dub#838) - this renders dub pretty much unusable for using it as part of the Linux distribution package tooling. Dub also writes into
$HOME
as part of the build process which is considered bad practice and is disallowed on build daemons at Debian (you need to add a hack for tools which expect$HOME
to be available) -
Dub: Can not version dependencies on other libraries (dlang/dub#906) - this makes it hard to determine compatibility if we package software written in D.
-
dub test
overrides the binary created bydub build
(prevents automatically running tests as part of the build process) (dlang/dub#840) -
No working Make/Ninja compatible depfile generation in LDC, DMD or GDC - this is especially important when not using dub (see the dub issues) and some other build system (Automake/CMake/Meson/..) is used instead. See ldc-developers/ldc#1802 for the LDC bug report.
-
There is no
dub install
command (dlang/dub#839) -
LDC doesn't support a lot of architectures / architecture support breaks from time to time. It would be quite nice to have D tools available on as many architectures as possible. (see ldc-developers/ldc#1636 for a bug report, build logs are here: https://buildd.debian.org/status/package.php?p=ldc)
The GDC issues have been separated out to not clutter the priorized overview.
-
GDC is not part of official GCC. This makes it difficult (or actually sometimes impossible) to ship it with some Linux distributions, e.g. RHEL and Fedora. On Debian, we inject GDC into the GCC build, which is also a bit weird. Having GDC in GCC proper would also give D much higher visibility.
-
GDC only supports an ancient version of the D standard library, which has many nice classes and also bugfixes missing. Because of that, it is almost impossible to compile modern D applications with GDC, and when developing a new application, support for GDC needs to be added explicitly and handled with a lot of care. This is an issue LDC doesn't have, and which is fragmenting the D ecosystem.
-
GDC does not support creating shared libraries at time, which is a big deal for distros which need it to reduce duplicate code and make security fixes easier.
- DMD is completely free software now, there is no obstacle to ship it in distributions anymore.
Either, it is the same code (ignoring wheel/binary distributions on PyPI which we can't use). The key difference is that these packages are natively installed into
/usr/lib/python3/dist-packages/
by whatever tool the Python community has come up with this time to handle packaging (setuptools and things like poetry seem to be the hot new thing right now...), and the packages in the location are natively picked up by any Python package before they even try to reach out to the web.It is not, no internet access is permitted at build-time at all. This ensures that we can reproducibly build all packages in the distribution and that the whole thing depends just on itself with no external service outages influencing anything, and no security issues in external tools having any impact.
Also, vendoring code is frowned upon and you usually need to justify code copies. So if your D project
foo-d
depends on dependencybar-d
, you should not embed the code ofbar-d
in thefoo-d
codebase, but instead create a separate package forbar-d
thatfoo-d
can the (build)depend on. That allows much easier tracking of what code is available in the distribution. Having multiple versions of a dependency is usually avoided, but occasionally we do have multiple ones (a very notable example is C++ Boost libraries, or even LLVM where multiple versions are shipped).There's an Upstream Guide, but that one is quite extensive and only a few sections may be relevant here: https://wiki.debian.org/UpstreamGuide
What you can do of course is set up a symlink farm where you link stuff from system locations into the dub cache, that's really tedious and messy though.
There's one D package, Lix, which embedded everything and added a bunch of hacks, but an approach like this isn't really scalable and a lot of tedious work to keep up to date (which is probably why the package is dropped from Debian releases and didn't receive much maintenance): https://salsa.debian.org/games-team/lix/-/tree/master/
Would be cool if we could set that globally somehow - keeping modifyable state is always quite messy.
My knowledge might be super obsolete here now, but last time I tried this, Dub attempted to write into locations in
/usr/share
where its system-wide packages were.Absolutely! I have this on my TODO list, but it needs to work again first - merging a patch that intentionally breaks CI would be a bit odd ^^ - At Debian we also continuously test if dub still works, which is quite useful and has found bugs in the past: https://ci.debian.net/packages/d/dub/testing/amd64/ (it also shows when code.dlang.org is down ^^)
You would need to have dpkg build a package to really see what works and what doesn't. The first method may be viable actually, if dub does not write into the locations of its dependencies. It would still be nice if one wouldn't need to manually have to specify the locations of each dependency, but it would work.
If you had a small-ish example, maybe a D project with just one or two dub dependencies, I could maybe rig up a small packaging example. Debian packaging actually doesn't need a ton of files or code to just get a working package out (but people new to it are usually intimidated by the many files, which are needed to get the package into Debian proper. Most of them are for QA and license review though).
No, I have been much less involved with D recently (even ported a large project away from it, to Python & C++, unfortunately) - but I think improving packaging would be a boon for D, increasing its visibility and strengthening the ecosystem. Anything that makes D more accessible and easy to use in any form would be a lot of help :-)
Btw, one thing that's obvious but also needs mentioning: When configuring dub to work with apps & libraries packaged for Debian/Ubuntu, we of course must not break it for people who need it to download from online repositories. So ideally, any solution would work for both :)