-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: refactor platform support for easier ports. #38364
Comments
The last time I worked on a port (risc-v), finding all the arch-specific code was far from the most difficult part. And this reorganization would take a lot of effort, cause a lot of code churn, and maybe cause import graph problems. (Just splitting up ssa rewrite rules per architecture, which I still want to do for other reasons, is pretty non-trivial, even using shortcuts like dot imports.) One clear win would be reducing the amount of arch-specific code, or (in some cases) writing semi-shared code generators. We’ve done some of that, but there might be other opportunities outstanding. I don’t think that requires a proposal, though; certainly not a generic one (as opposed to one discussing a particular change to make). |
There are currently a lot of duplicate copies of, for example, the shims that go between the Go calling convention and the C calling convention, neither of which varies all that much across most platforms. (See #18352.) |
@josharian perhaps it is true that it it isn't hard to find where the platform specific code is, but when we look at the diff in the original issue, it touches files all over the place. It seems to me that the platform support in Go could be better structured. I can agree that in stead of a single large refactoring, this could be done gradually. This issue can then be used to plan and track these gradual changes. |
How about a "configure" step which produces temporary files for a build? That should work for at least the trivial changes. If the build shouldn't rely on a shell script, you could A list of files for the tamago patch is in #37503 (comment) @beoran I don't think the issue needs the proposal template since it isn't a language change. |
We already have go generate for generating files, we could use that to generate more boilerplate and use it better. I will remove the proposal template once @ianlancetaylor confirms it is not necessary. Edit: When looking at the diffstat it is strange that files for architectures other than ARM have to be changed to add a new ARM port. That suggests code that is too tightly coupled. |
For starters if posix and unix OSes would have their own build tags a lot of:
or
Would have probably been spared. Maybe an initial improvement could be having tags that represent familes to spare a large number of such changes? |
One programmer's "too tightly coupled" is another programmer's "avoids unnecessary abstraction". I'm not saying we have anywhere near the perfect balance now. But I think that striving for complete abstraction, like "adding a new port doesn't touch anything outside a particular directory" is both unrealistic and likely to add complexity rather than remove it. But again, overall, I'm generally in favor of clean-up, organization, and de-duplication, evaluated on a case by case basis. |
Previous discussion about adding a |
I'm not sure it helps much to move all the platform-specific code out of cmd/compile/internal and cmd/link/internal and into a set of shared internal directories. We've already done the architecture split there; moving it elsewhere doesn't make things much easier. I agree with @josharian that this is something to be judged on a case-by-case basis. |
I do think that we should revive #20322, currently on proposal-hold. |
And how about using |
I don't quite see how we can use But I'm not sure why using |
I don't really understand what you are suggesting. If you mean to move all the current OS-specific code out of places like runtime, time, os, etc into a new single "platform" package, I'm not sure that's particularly helpful. The current packages have much narrower scopes and are easier to design than the "platform" package would be. Having to be able to encode every possible variation into "platform" will be unwieldy. To take just one example, path/filepath has a Separator constant. It's not clear that platform should provide that instead. Then which will people import? |
Basically, what I am suggesting is that we think of different ways how we could make supporting different platforms easier together. Having "platform" packages could be one way to do that, yes, but sine you know the Go source code better than I do, I am willing to accept that it might not be a viable approach. However, as you said in the original issue:
To me, this suggests that the Go developers often have problems where one change for one platform can easily cause problems for other platforms. This then suggests to me that the problem might be that the code is too tightly coupled. This issue is about thinking of ways, together to improve this issue, so even for existing ports, it becomes easier to maintain them. So perhaps having full platform packages is not the way to go, certainly not for directory separators and the like, but perhaps it could be possible to factor platform-specific code better, such as partial per platform packages, or using sub-packages per platform for the current standard library packages. And yes, #20322 is likely to help this issue if tamago decided to be unix. Although, perhaps, an even better idea would be to rethink the way build tags are used currently for platform support. Build tags allow us to compile platform-specific code, but I always felt they are a bit of an unclean solution. Another approach could be to allow GOOS to be set to "none", and then, allow this as a build tag and recognise this in file names, but not generate any different code, and cause all existing OS specific code that does not match "none" to be not compiled. The result will not link, perhaps not even compile, but it will be up to the people maintaining the port to make this work using patches. Likewise, unsupported but reasonable values of GOARCH, say, names of common architectures, could be allowed. |
I can see how that follows, but I don't think it's quite right. A more accurate way of saying this is that Go developers often have problems where a change to the general purpose code requires separate individual tweaks to each individual platform. |
Thanks for clarifying that. The question is then, how can we alleviate this? |
The way to alleviate this would be to focus on specific, concrete changes, such as the unix build tag. The specific suggestion in this issue, namely the centralized platform package, won't work well with the standard library and is basically a non-starter. But it would be good to identify other possible changes. We definitely want to make it easier to build out-of-tree ports. It doesn't scale to put all the ports in the tree. But we want to find ways that don't complicate the rest of the build too much (why the platform suggestion fails). It sounds like we should close this issue in favor of #20322 and any other as-yet-unfiled suggestions. |
That is fair enough, since I admitted my specific suggestion may not work, so this issue had no actionable content left. Let's focus on concrete issues. I will leave it up to people who are actually making ports to come up with more detailed suggestions. I do hope the Unix build tag will be added soonish. I hereby retract this issue. |
Proposal
I propose to refactor the support for platforms, architectures and operation systems in the Go run time and compiler so it becomes easier to write a new port, also for third parties, and simpler to maintain current ports.
Currently, support for platforms is spread out all over the code base of Go, using build tags or target specific go files. While this is understandable for historic reasons, it does make it hard to develop a port of Go to a new platform. The platform support should be better factored so this becomes easier.
This could be done in several ways, but my first idea, which is open for debate, would be to create a package platform with sub packages for architecture, OS, and arhcitecture-os combinations if needed, and then have sub-sub packages for the compiler and for the runtime. Another idea would be for such architecture support to be split of in Go modules.
This issue was first mentioned in #37503.
Proposal template
I am experienced, I have been using Go for 10 years since before v1.0.
Batch files, Basic, C, C++, D, Java, Javascript, Lua, Objective-C, Oberon, Pascal, PHP, Python, R, Ruby, Shell scripts, Visual Basic, ...
It would make it easier how to learn how to make a port of Go to a new OS or architecture and to maintain existing OS and architectures.
This idea is based on the proposal proposal: all: add bare metal ARM support #37503.
In stead of porting to a specific platform, we see in that issue that too many files have to be changed to make a port. This issue is specifically about ameliorating that situation.
People who want to port Go to a new platform, and people who have to support an existing Go platform.
Yes, if refactored correctly, this should change nothing at all in how Go works.
This is still to be debated how we will change the code.
All tools that use platform-specific code will be affected. Those who use the run time API will not be affected.
None, if done correctly.
None, if done correctly.
Groso modo, either use packages, or use modules for each platform and concentrate the platform -dependent code in them.
Not applicable.
No effect.
No.
No .
No.
The text was updated successfully, but these errors were encountered: