-
Notifications
You must be signed in to change notification settings - Fork 6.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
[RFC] On the way C libraries (don't) expose all functions defined in coding guideline rules A.4 and A.5 #68278
Comments
Wow - this sounds an awful lot like someone is being told what they think, rather than their opinion simply being asked of them.. Can you tag the developers you are referring to, here? So that maybe they could share their opinion themselves? |
They have been tagged. You are welcome to elaborate on your point of view. This is an RFC. |
I've modified #67040 so that it makes newlib expose the additional APIs by wrapping string.h. It seems like we should be able to do the same for any other C library? Even the native C library? |
Thanks @keith-packard , but that assumes an outcome for this RFC which is not given. I would prefer if we could discuss here first if we should expect C libraries integration to do this. If you think that it should be yes, you are more than welcome to motivate it. |
For the libraries Zephyr provides (either as source or as part of the SDK) we can. Though we create a source relationship which architecturally I would think is best to avoid. (i.e. "Is it good that any file in the OS side knows about C library implementation details instead of just relaying on the standard way of configuring it?") |
As an attempt to collect this conversation in one place, here a verbatim copy of @stephanosio comment: #68381 (comment) Just reiterating the bits from the conversation I had offline with @aescolar for the record
I would prefer not to clutter individual Zephyr source files with the libc feature test macros because:
I think libc awareness from the OS side and vice versa is something inevitable for optimal integration between the two (e.g. things like thread safety, reentrancy, atomics and threads all require awareness from both sides). Without it, the libc integration would not be "complete." |
Maybe I've misunderstood, but I do not believe point 2 accurately describes picolibc. It also seems that nobody has come forward to confirm their understanding is as described above otherwise. Just a suggestion, but it might be better to reword point 2 so that it only includes facts. E.g., if I were to reword point number 2, I would write
|
Who was tagged specifically? I don't know anyone with the understanding described in point 2. |
Personally, I would be happy to have application conformance macros in the minimal libc (as well as the posix headers) to conditionally declare various functions. Implementation conformance macros as well. That is part of #51211 already.
|
Thanks @stephanosio , to document my counters
Today the detection/enforcement through checkpatch is quite flawed: it does not detect usage of not allowed ISO functions, it does not detect SOURCE macros being set in cmake files; and setting these macros is anyhow technically correct and not in violation of these rules. I think it would be better fixing this detection anyhow, and I don't think it should be based on these macros being set.
As you mentioned it is a known standard. I would like to clarify that I am not proposing to sprinkle our source with defines to work around quirky C libraries or compilers. Setting
I think it's worth noting that: My overall feeling is that by going in this direction (so we require things like #68381 both in and out of tree) we are choosing a problematic path for both us and the users that will cause significantly more trouble, for a very limited benefit. |
As an extra motivation for this proposal, note the concern raised in That is, that the alternative for what is proposed in this RFC (i.e. assuming 2.), in its best case, couples the C library too tightly to Zephyr. |
After having a further discussion with @aescolar on this matter and giving more thought on the POSIX compliance and portability aspects (especially in regards to compatibility with the host C library for native POSIX and supporting other C libraries implementing these POSIX C extension functions), I think it may be beneficial to define The local definition of the feature test macros, however, should be strictly limited to This means:
@aescolar @cfriedt @keith-packard What do you think? |
I just spent 4.5 hours responding to somewhat related comments in another PR and have appointments and 8 hours of actual work to attend to at this point. Not to mention other obligations. This also seems to duplicate an issue that was filed prior to it #67283. Unfortunately, it may take some time for me to re-review this, so thanks for your patience. |
Just at a glance, the proposed solution in #67283 seems to be quite conservative - i.e. simply adjust checkpatch.pl to reduce false positives. I have to re-read this again at some point, but it seems like it's going far beyond .. also, there has been an RFC on the topic of POSIX application conformance macros for several weeks that seems to be blocked for some reason by @aescolar. I would hate to see the process of the other RFC circumvented. To me that does not seem right. |
@cfriedt It was my understanding that you, the POSIX API layer maintainer, wanted to ensure |
I'm not sure if I necessarily agree. We should stop pretending that hard-coding
This is true. However, we can also simply declare them in order to meet Coding Guidelines Rules A.4 and A.5, as we have always done. Since this is documented (and realistically is done due to shortcomings in < ISO C2x), it's a perfectly acceptable deviation. There are already conformant strnlen, strtok_r, and gmtime_r declarations and implementions in-tree. I think having those 3 functions declared in common libc headers is perfectly fine, with the implementations living in either common libc or lib/posix. It would be trivial to add a default-y Kconfig option to declare them so that systems with a conflicting definition (be it macro, inline, etc) can be accommodated (to explicitly n-select the declaration). It certainly would scale better (O(1) vs O(n)). Doing it this way means we still do not expose the kernel and core parts of the OS to the rest of the POSIX API.
Thank you for asking me for my opinion.
This is true for many reasons and here are just a few:
Manually redefining Even just in terms of usability - if the application is required to use a specific For non-application-facing code (in particular, arch/posix) hard-code away - as long as it is not a global cflag. I mean, even there I would encourage a consistent way of managing versions, but I do not want to overreach. |
One thing to note is that declaring the prototypes of these for other libaries is problematic.
Even though it is not the only way, there is a benefit of doing so: |
Background:
1.1) Most of these functions are part of the base C11 standard, two are (POSIX.1-2008) extensions.
SOURCE
macros. Picolibc and minimallibc do this. Newlib, the integration with the host C library for the native targets, or other libraries out there don't.SOURCE
macros in .c files. This has two problems: 4.1) it does not detect definitions in build files. 4.2) It blocks legitimate uses of these macros.This RFC does NOT try to discuss what should be in 1).
If focuses on 2)
Clarification needed
Has there been any kind of authoritative decision on 2) (i.e. TSC vote), or is this just an understanding reached in some PR discussion by a subset of developers?
Discussion on 2)
Today PicolibC ensures that these 2 extra functions prototypes are defined by treating Zephyr specially, with extra Zephyr specific ifdefs to detect and expose them. Newlib does not, and one cannot expect other C libraries the user may use to provide these.
The expectation that these 2 are exposed, sets a weird requirement on the C library integration
(See #67040 (comment) , #67040 (comment) , #67040 (comment) )
Under the assumption that 2) is the way forward, a simple way to work around this issue for C libraries without special Zephyr handling is to define globally the
_POSIX_C_SOURCE
macro. This is what PicolibC did before, and what #67040 proposed doing for Newlib.There is the minor disadvantage of doing this, that we can cause this macro to be redefined, causing a redefinition warning, either in tree or in users code.
So far the only issue with assuming that 2) is not the way forward, is that the
_POSIX_C_SOURCE
macro needs to be defined where those 2 functions are used. As such there is no drawback of this beyond a)_POSIX_C_SOURCE
needs to be defined in those files , and b) That checkpatch is triggered if that is done in the C source files themselves.a) is something one would need to do with another OS or C library, so something users should expect and technically correct. Avoiding to do this due to that checkpatch check seems the wrong reason, as checkpatch detection of this rules violation is anyhow both very limited and overeager.
Proposal
_POSIX_C_SOURCE
macro locally (in the C file or build for that file/library) where it uses these extra functions._POSIX_C_SOURCE
macro usage in .c files is fixed (i.e. does not warn for this use when only these 2 functions are used)._POSIX_C_SOURCE
be set for those 2 functions prototypes to be visible.Benefit of the proposal:
_ZEPHYR_VISIBLE
)References:
Additional notes
Please do not use this RFC to discuss what functions should be part of A.4 & A.5. Create other RFCs for that.
Edit: In proposal replaced "SOURCE macros" with "_POSIX_C_SOURCE macro" as this is the only one I really intended to discuss about here.
The text was updated successfully, but these errors were encountered: