-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
druntime: replaces top level version(..) branching by tags #15887
Conversation
Thanks for your pull request and interest in making D better, @denizzzka! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#15887" |
66e0826
to
b745afd
Compare
During the Dec 8 DLF monthly meeting, Walter was in favor of putting different OS'es (Windows, Linux, FreeBSD, macOS) in different folders. |
@dkorpel Is there a transcript or record somewhere? |
Mike posts summaries in the Announce forum, though it has a bit of delay. The latest one is: D Language Foundation October 2023 Quarterly Meeting Summary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok @denizzzka, time for the comments you requested at the forums.
I'm somewhat disappointed that this needs a script. On the other hand, a src/core/sync/event.d
that just read like version (Posix) public import coreconfig.posix.core.sync;
wouldn't be ideal either since it would require updating the public imports each time platforms are added, while this mechanism is smarter.
It would probably have been better to write the file copying script in D since that's what this repo usually does when the logic is about more than just flag setting. We require a host D compiler with a standard library anyway because we have compiler/src/build.d
. But asking you to rewrite it before accepting this would probably be more than it's worth so I don't.
But otherwise, I very much like this PR! I think it can also be a big help in the very thing I complained about, as we're getting rid of the version() else static assert(0, "unsupported")
thing along with version statements in general, meaning stubbing stuff is becoming easier than it was. It will be much easier than before to just copy files from the config/
directory and replace them with stubs when programming for platform that doesn't yet have DRuntime support.
Also I'm happy to hear Walter is interested in supporting this, or at least somthing along these lines. I recommend merging this.
Seems, there's nothing can do about it: something has to take over But Makefile scripts changes will be simplified in a short time because #15894 removes
Windows copying script line will be removed in a short time (see above) Copying which is used by GNU Make is implemented not in this PR and already used for years for
I completely agree!
Thank you for your feedback! |
To clarify, the idea is generally favourable. The means requires strict approval of both @kinke and @ibuclaw. One attempt at splitting these bindings into different architectures ~10 years ago sank - that there's too many potential to support didn't help. Making the OS the dividing line for the module system may be more palatable. It will have to be tested.
I don't know who "we" is and why they want to remove |
Of course.
With "we" I meant everyone involved. I could have also said "you" as in regular DMD contributors. In either case you're definitely included :-). As for the "why", it's what this PR does. Since versioning is done by picking the correct D files from |
Yes, didn't mean that as criticism. Just that I'd prefer if we could use the module system in the language to do this as well as the script. Since that doesn't seem possible though, at least not without some ugly tricks, the script is justified IMO. |
c82e33f
to
ed0f8e1
Compare
Important notice: this PR implies that Because of this, for example, we must provide something like This is same approach as different Linux kernel headers packages coresponding to a different kernel binaries, but derrived from one kernel source tree (Currently, same (Discussion https://forum.dlang.org/post/[email protected]) |
The cross-compilation use cases kill this approach IMO. LDC is an implicit cross-compiler, and its bundled druntime+Phobos source tree has been working fine for targeting all supported targets. Having to include separate trees is IMO out of the question. Then LDC doesn't use the upstream Makefile, but CMake. We don't have an How about splitting up the implementations in something like |
Will not work for a range of targets for which |
(Cross-compilation also was main reason to suggest this PR)
This is ~same approach as works current dmd/druntime Makefile. Except that they use predefined list of modules what needed to be copied into
At first sight this isn't looks as big problem: |
Adding an extra layer is as simple as adding a |
And also we want (as enhancement) to be able replace modules not as individual elements or the entire "platform implementations", but as sets of elements (by groups of modules belonging to a same tags) - this functionality is also implemented in the script from this PR and therefore needs to support from druntime build facility |
This is how tags support can be implemented for CMake: |
5c086a7
to
6954619
Compare
There is another option that solves only problem of external implementations: implement this PR but only with tags like In this case cross-linking routine will not changes and "versions hell" will not be resolved. But we will be able to create external implementations of needed functions. (And in this case we still need to move, for example, In the future, if the community decides to reorganise all druntime code with a such tag system, this can be easily done. But for now propose to accept tags as a standard mechanism for switching of external implementations |
In a short time I’ll move Event methods into a separate event_impl.d and revert tests back to event.d |
Done I think that it is better to maintain this specific module by this way Also, as side effect, becomes obvious pointlessness of the handler checks before each |
This is over engineered.. why a cryptic bash script to split files??? It should be as simple as this:
grep-able and easy to maintain Anything else is just bad |
You mean script or whole idea?
I hesitated to write on D because I was afraid of a potential chicken and egg problem. Bash script works on all our official platforms out of box. And script is a quite simple. On CMake same functionality can be implemented too, but it is need to provide same ability for GNU Make, so I decided to write one script and use it everywhere.
I'm not sure that I understand correctly what you mean here |
This is a necessary evil: Unfortunately, currently druntime isn't same as C rtl/crt. In these C terms druntime is a huge rtl + libc. Therefore we are forced to move from current versions to something like (in C terms) different include dirs for a different libc implementations And without that mechanism it will be impossible to explain to the community why some specific code suddenly needs to be allocated into a separate module (so that it can be replaced in some third party code) - the answer always will be: it is convenient for us as it is for now. Therefore, it is necessary to create a switching mechanism that will also be used by the official platforms. (By "official platforms" I mean druntime binaries that come with distributions from dlang.org or from packages maintainers) In addition, we already using a similar switching mechanism for core.sys.* (in ldc2 cmake scripts) and (my opinion) we need same approach for core.stdc.* - just a huge unmaintainable files (as for me, of course). So, cmake script can be replaced by this script with same result but for all compilers. Regular users won't notice anything. Only /etc/ldc.conf will got 8 lines like:
Thats all! (The fact that such lines aren't added for now (with the all these necessary currently |
It will be difficult to change it now. If at the time of core.sys.* creation there was a proposed mechanism then it would be great |
For the sake of discussing all currently used mechanisms, did you consider breaking up druntime into features rather than versions? https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/gcc/config.d.in This file is generated at configure-time for gdc after having tested what the target system has available. Obviously |
Actually, I exactly suggest to breaking it down into features (named "tags"). But proposed "features" can be provided also from outside of the official sources (and this is for free) In the above example, we do not have abilities to replace atomics with stubs (which is common for single-core platforms). Yes, maybe this will be solved by the replacement of a symbols during linking, but: there are dozens of such places in druntime, and are all a little different: somewhere it is need to replace class, somewhere need to replace bunch of enums, etc. Also, shove all druntime code into something like: version (CRuntime_Glibc)
{
version = Any_Have_Tgmath;
version = Any_Have_TgMath_Mod;
version = Any_Have_TgMath_NaN;
}
else version (NetBSD)
{
version = Any_Have_TgMath;
version = Any_Have_TgMath_Mod
}
else version (OpenBSD)
{
version = Any_Have_TgMath;
} ? In my opinion, this which will only complicate possible solution in the future. And it is not a cheap, it's a thousands lines, I think. Proposed in this PR approach allows us to achieve results "just right now". It will give us time to inventing some way to create static compilation branches based on standard language features. If successful, we will simply delete script, and even the ldc2 configuration file will continue to work (because it introduces only additional In the future, if a graceful solution will be found (without a script, etc), it will be possible to switch to it easily: until such a solution has been found, modules will move to a state more convenient for such hypotetical static branching due to the use of the proposed approach
So we found out that GDC also uses its own mechanism to perform near to the same task |
Let me make it more clear, that's what I mean (this is my current cmake script for ldc2): https://github.com/opendlang/opend/blob/fda4c0c698137a064b4cbef6255b7f90518f09db/ldc/runtime/CMakeLists.txt#L282 # Official targets
set(OfficialPlatforms
"windows" "osx" "dragonfly" "freebsd"
"linux" "netbsd" "openbsd" "sunos"
)
# Tags matrix for them
set(TAGS_windows "windows")
set(TAGS_osx "posix_threads")
set(TAGS_dragonfly "posix_threads")
set(TAGS_freebsd "posix_threads")
set(TAGS_linux "posix_threads")
set(TAGS_netbsd "posix_threads")
set(TAGS_openbsd "posix_threads")
set(TAGS_sunos "posix_threads") For each line of this matrix "official targets" imports is generated and then can be placed into a bundle with druntime binary. "windows" and "posix_threads" is a such "features". This works ~same as your sample from GDC, but for all targets (so as not to cause discontent ldc users who are used to cross-compile) and this format of a tags is universal between all compilers, applied to the entire druntime and usually does not require heavily changing *.d sources |
I don't know where atomics came from - if you're referring specifically to the three enums in gcc/config.d, the libatomic library is there to do the right thing for you, so no need to do anything special on the druntime side.
Also, it's subtly incorrect to hard code it like that. It assumes that these things won't change from one version of a platform to the next.
Not really. GDC is doing something completely different to here. The config module is a guide for the implementation of the core run-time library, rather than the public C library bindings. |
[snip]
That matrix makes some bold assumptions. You can't be that assertive about will be available from one version of a platform to the next, or platform-x86 has the same feature as platform-arm. To pick out one example from my reference.
This is FreeBSD and MacOS are two similar moving targets with their APIs. e.g (1): someone decided it would be a good idea to call |
More likely than not, ImportC will kill off the C run-time bindings as they currently are implemented in druntime. https://github.com/ibuclaw/dmpdecimal/blob/main/dmpdecimal.d#L29-L37 You can even check for symbols that might be missing in the C headers, and selectively expose them. https://github.com/ibuclaw/dmpdecimal/blob/main/dmpdecimal.d#L122-L127 |
Yes, I saw a reference to atomics library and remembered that I had to cover everything related to atomics with a stub that does nothing im my STM32 druntime binding (external
Ok By the way in the proposed "tag scheme" I do not distinguish between published by druntime bindings and internal implementations - any module can be switched using this mechanism (just move it to |
I am absolutely sure here: it is from these sources and imports corresponding druntime will be builded and tested for all these platforms
Discussed matrix intended only to ldc2 with its own unique ldc2.conf cross-compilation sections
Yes, such things will have to be checked in the same way during the compilation process. |
Here is everything lives forever in the name of backward compatibility :-) Well, that is, I think core.stdc.* files will stay with us for the next ~5 years |
@ibuclaw Okay, let's also see to the patch for the druntime which I want to away by this PR: https://gist.github.com/denizzzka/e8325b75af3cfd1a942a7306f82f33f4 This is current minimal hackish patch to support a third-party targets. 90% of its lines is a like: +version (DruntimeAbstractRt)
+{
+ public import external.rt.dmain : _d_cmain;
+}
+else (My own main() because before D code starts it is need to prepare environment. If it returns it is need be able also to revert environment back. Official rt.dmain already contains internal version branching but it is impossible to replace its code by external.) +else version (CRuntime_Abstract)
+{
+ public import external.libc.stddef : wchar_t;
+} (Picolibc currently is used - it isn't available in the official druntime sources. But remember what official core.libc.* already contain internal version branching for switching libc.) +version (DruntimeAbstractRt)
+ public import external.core.mutex;
+else (Whole core.sync.* end user API is need to be implemented from scratch. Same, core.sync.* is already contain version branching for all of its methods, but it is impossible to replace its code by external code.) And everything like that How this can be solved by an another graceful way? |
Yes, I thought well and - you were right! There is really is no exactly need to produce identical files, many (But I won't do anything for now - let community make a positive decision about whole approach first) |
e1b570b
to
388ebe4
Compare
50f6bbf
to
2bd80ee
Compare
2bd80ee
to
fb93ded
Compare
Implemented in https://github.com/denizzzka/dfruntime |
Squashed version of #15822
Forum: https://forum.dlang.org/post/[email protected]