Skip to content
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

Remove explicit -D_POSIX_C_SOURCE global compiler options when building with picolibc #67040

Conversation

keith-packard
Copy link
Collaborator

@keith-packard keith-packard commented Dec 28, 2023

Picolibc now has explicit Zephyr support so we no longer need _POSIX_C_SOURCE defined to get the complete Zephyr C Library API

@zephyrbot
Copy link
Collaborator

zephyrbot commented Dec 28, 2023

The following west manifest projects have been modified in this Pull Request:

Name Old Revision New Revision Diff
picolibc zephyrproject-rtos/picolibc@1a5c603 zephyrproject-rtos/picolibc@5415d37 (zephyr-no-posix-define) zephyrproject-rtos/picolibc@1a5c603b..5415d37a

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@keith-packard
Copy link
Collaborator Author

Ideally, the one for the toolchain would depend on the version of picolibc provided, but I have no idea how to make that work.

@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch 2 times, most recently from 4d7c06b to 8ed02d5 Compare December 28, 2023 18:12
@zephyrbot zephyrbot added platform: ESP32 Espressif ESP32 area: native port Host native arch port (native_sim) area: Wi-Fi Wi-Fi labels Dec 28, 2023
@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch from 8ed02d5 to 731ed67 Compare December 28, 2023 18:12
@@ -6,7 +6,7 @@

#define DT_DRV_COMPAT espressif_esp32_wifi

#define _POSIX_C_SOURCE 200809
#define _POSIX_C_SOURCE 200809L
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed as there is no non-standard posix call in Espressif's sources.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll mix that in once I've got things building.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like that worked!

@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch 2 times, most recently from 6e57e5b to 3bb9463 Compare December 28, 2023 20:39
@keith-packard
Copy link
Collaborator Author

The compliance check failure is from the strerror_r test -- strerror_r is not part of the Zephyr C library interface, and so the test must define _POSIX_C_SOURCE=200809L to gain access to that symbol. I could remove this test, or we could add the function to the Zephyr API. Anyone have a preference?

@aescolar
Copy link
Member

The compliance check failure is from the strerror_r test -- strerror_r is not part of the Zephyr C library interface, and so the test must define _POSIX_C_SOURCE=200809L to gain access to that symbol. I could remove this test, or we could add the function to the Zephyr API. Anyone have a preference?

I guess adding it to the Zephyr API is a bit against the point (of these rules https://docs.zephyrproject.org/latest/contribute/coding_guidelines/index.html#rule-a-5-c-standard-library-usage-restrictions-in-zephyr-codebase )
I would not have a strong objection to removing that part of the test.
Though I guess another option would be to ignore the conformance check warning? (this PR is not adding the function use, it is just exposing it)

@keith-packard
Copy link
Collaborator Author

My personal thinking would be that code in Zephyr should expect to need to set the same macros as in other systems when using C library extension functions. And that having that requirement would relax the requirement on the C libraries (be it newlib, or glibc, or..) or their integration to have special treatment for Zephyr.

Oh, that's a very interesting idea. While we say that the Zephyr C library API includes a few POSIX extensions, we simply require that applications using those functions request them through the "normal" mechanism -- #define _POSIX_C_SOURCE 200809L, instead of expecting them to be present automatically. That would make integration with other C libraries far simpler; ones with limited POSIX support (like picolibc and newlib) would not need to do anything special. For those without POSIX support, Zephyr would provide wrapper headers that checked for _POSIX_C_SOURCE before adding the non ISO-C APIs as well as using #include_next to pull in the underlying C library headers.

One downside is that this would make it very difficult to detect code which is using non-ISO C APIs which are not part of the Zephyr API. Another is that we would have to stick #define _POSIX_C_SOURCE 200809L defines in some core Zephyr code which is using these APIs, which makes the first downside leak into the Zephyr core.

@@ -133,7 +133,7 @@ if (CONFIG_GPROF)
target_link_options(native_simulator INTERFACE "-pg")
endif()

zephyr_compile_definitions(_POSIX_C_SOURCE=200809 _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED)
zephyr_compile_definitions(_POSIX_C_SOURCE=200809L _XOPEN_SOURCE=600 _XOPEN_SOURCE_EXTENDED)
Copy link
Member

@cfriedt cfriedt Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Darn - I guess this line might still be an issue because it changes cflags globally for the entire build, which would violate rules A.4 and likely A.5 of the Coding Guidelines.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another PR fixing this. It does not need to be done in one go.

@@ -73,6 +73,9 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
endif()
zephyr_link_libraries(c)

# newlib needs this to expose the full Zephyr C Library API
zephyr_compile_definitions(_POSIX_C_SOURCE=200809L)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use this instead? That would change the definition to a local one rather than a global one (which would conflict in many places).

Suggested change
zephyr_compile_definitions(_POSIX_C_SOURCE=200809L)
zephyr_library_compile_definitions(_POSIX_C_SOURCE=200809L)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the whole point of this define is to ensure that newlib exposes the Zephyr C API as defined by Rule A.4 in the Coding Guidelines. Unless and until newlib itself is fixed to provide Zephyr compatibility, we can either

  1. Abandon Rule A.4 and assert that Zephyr only uses ISO C interfaces
  2. Define _POSIX_C_SOURCE=200809L globally
  3. Find some alternative mechanism to get newlib to expose the extended functions.

Copy link
Member

@aescolar aescolar Jan 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keith-packard would it be an option to only expose by default the ISO C interface, but still allow those extra functions defined in Rule A.4 (thru individual waives in PRs that need to use them, where setting the _POSIX_C_SOURCE macro is allowed in particular cases). Effectively what you described here: #67040 (comment)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying that we require applications define _POSIX_C_SOURCE=200809L to gain access to the extended functions? Because if it's not required, then we're adding implicit dependencies on using only a C library with Zephyr compatibility (picolibc or the minimal C library).

That would certainly be easier for C library developers, but it seems like it will require careful auditing of changes in any file with such a definition to ensure that it doesn't accidentally start depending on additional POSIX functionality.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying that we require ..

Yes

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that would also require allowing core Zephyr files to contain such definitions; have tooling that prevents valid code from being merged will slow down development. Because once the definition is present in a source file, no future changes to that file will see the same review, hence allowing non-approved functions to leak in. Alternatively, more sophisticated tooling that detected the use of POSIX functions beyond the approved list.

Copy link
Member

@aescolar aescolar Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that in general that would be the case, and that would be very far from ideal.

Though today a quick check seems to show:

  • there is nothing in the "zephyr kernel" using strnlen() (the only exception in A.4).
  • for more peripheral code in the tree, there is a few uses of strnlen() and strtok_r() (rule A.5 exceptions).

But given that today, at least for the tests we are running, all those built with just this
123bdfb
I wonder if it would be best to, by now, postpone this particular point (I would very much like to have @stephanosio on this discussion), and not do this particular line change (or that other commit) in this PR; The rest of the PR seems fully uncontroversial and an overall improvement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't remove instances of #define _POSIX_C_SOURCE in most places without somehow dealing with newlib's lack of Zephyr support. Otherwise, building code with newlib that uses strnlen will fail.

Copy link
Member

@cfriedt cfriedt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would still be slightly more ideal to remove application conformance macros from global cflags.

@keith-packard
Copy link
Collaborator Author

It would still be slightly more ideal to remove application conformance macros from global cflags.

That requires that upstream newlib be fixed to provide Zephyr support.

@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch from d7fd9ac to 0ff2cd9 Compare January 30, 2024 19:06
@keith-packard keith-packard changed the title Remove explicit -D_POSIX_C_SOURCE global compiler options when building with picolibc libc/newlib: Wrap string.h to expose strnlen and strtok_r as needed Jan 30, 2024
@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch from 0ff2cd9 to 177b4f2 Compare January 30, 2024 19:28
@keith-packard
Copy link
Collaborator Author

This steals @cfriedt 's idea to wrap string.h and add the non ISO-C declarations there, but is newlib specific and so doesn't risk breaking other C libaries.

@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch from 177b4f2 to 19a50f8 Compare January 30, 2024 20:01
@aescolar
Copy link
Member

aescolar commented Jan 31, 2024

Hi @keith-packard , this PR now has a very different content and target than originally. That can be quite confusing for reviewers, as the previous comments and commits are unrelated. Moreover some may have already muted this PR, and the merge criteria does not properly account for PRs that morph.
The old PR content, commits and comments were relevant as they documented a discussion, and were linked from several other PRs.
May I ask you to create a new PR for the new content, push back the old commits to this branch, revert the PR title and original description and close this PR so it remains as an archive of the discussion?

Setting the DNM label due to this.

@aescolar aescolar added the DNM This PR should not be merged (Do Not Merge) label Jan 31, 2024
cfriedt
cfriedt previously approved these changes Jan 31, 2024
Copy link
Member

@cfriedt cfriedt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to me. Thanks @keith-packard

Or if you prefer to make a separate PR, sure. I have no issues with the current incantation though.

Not totally necessary, but FWIR there are some CI errors right now that this will fix, so it might be a good idea to file a bug report.

CI errors are priority: high, so that will ensure it gets merged with the release (IIRC, we require zero high priority issues with a release).

@cfriedt cfriedt added the bug The issue is a bug, or the PR is fixing a bug label Jan 31, 2024
@keith-packard keith-packard force-pushed the picolibc-no-posix-define branch from 19a50f8 to d7fd9ac Compare January 31, 2024 20:55
@zephyrbot zephyrbot added manifest manifest-picolibc and removed DNM This PR should not be merged (Do Not Merge) labels Jan 31, 2024
@keith-packard keith-packard changed the title libc/newlib: Wrap string.h to expose strnlen and strtok_r as needed Remove explicit -D_POSIX_C_SOURCE global compiler options when building with picolibc Jan 31, 2024
@keith-packard
Copy link
Collaborator Author

I've reset this PR back to the state before it became just patches for newlib compatibility. It's no longer relevant for anything but historical purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: C Library C Standard Library area: native port Host native arch port (native_sim) area: Wi-Fi Wi-Fi bug The issue is a bug, or the PR is fixing a bug manifest manifest-picolibc platform: ESP32 Espressif ESP32
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants