Skip to content

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Feb 3, 2025

This partially reverts commit 5f2389d. That commit started checking whether
<features.h> was a valid include unconditionally, however codebases are free
to have such a header on their search path, which breaks compilation. LLVM
libc should instead provide a more standard way of getting configuration
macros like LLVM_LIBC.

After this patch, we only include <features.h> when we're on Linux or
when we're compiling for GPUs.

@ldionne ldionne added this to the LLVM 20.X Release milestone Feb 3, 2025
@ldionne ldionne requested a review from a team as a code owner February 3, 2025 21:26
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 3, 2025
@ldionne
Copy link
Member Author

ldionne commented Feb 3, 2025

CF #102036 (comment)

@llvmbot
Copy link
Member

llvmbot commented Feb 3, 2025

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

This reverts commit 5f2389d. That commit started checking whether <features.h> was a valid include, however codebases are free to have such a header on their search path, which breaks compilation. LLVM libc should instead provide a more standard way of getting configuration macros like LLVM_LIBC.


Full diff: https://github.com/llvm/llvm-project/pull/125587.diff

2 Files Affected:

  • (modified) libcxx/include/__configuration/platform.h (+3-6)
  • (modified) libcxx/include/__random/binomial_distribution.h (+1-2)
diff --git a/libcxx/include/__configuration/platform.h b/libcxx/include/__configuration/platform.h
index 2a92ce209b91f8b..27f68d04e8a8d9c 100644
--- a/libcxx/include/__configuration/platform.h
+++ b/libcxx/include/__configuration/platform.h
@@ -30,18 +30,15 @@
 // ... add new file formats here ...
 #endif
 
-// To detect which libc we're using
-#if __has_include(<features.h>)
-#  include <features.h>
-#endif
-
+// Need to detect which libc we're using if we're on Linux.
 #if defined(__linux__)
+#  include <features.h>
 #  if defined(__GLIBC_PREREQ)
 #    define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b)
 #  else
 #    define _LIBCPP_GLIBC_PREREQ(a, b) 0
 #  endif // defined(__GLIBC_PREREQ)
-#endif
+#endif   // defined(__linux__)
 
 #ifndef __BYTE_ORDER__
 #  error                                                                                                               \
diff --git a/libcxx/include/__random/binomial_distribution.h b/libcxx/include/__random/binomial_distribution.h
index 9538c15e2dc97b5..47790b674db5882 100644
--- a/libcxx/include/__random/binomial_distribution.h
+++ b/libcxx/include/__random/binomial_distribution.h
@@ -97,8 +97,7 @@ class _LIBCPP_TEMPLATE_VIS binomial_distribution {
   }
 };
 
-// The LLVM C library provides this with conflicting `noexcept` attributes.
-#if !defined(_LIBCPP_MSVCRT_LIKE) && !defined(__LLVM_LIBC__)
+#ifndef _LIBCPP_MSVCRT_LIKE
 extern "C" double lgamma_r(double, int*);
 #endif
 

@philnik777
Copy link
Contributor

Would it make sense to partially revert? IIUC this still works when targeting linux with the LLVM libc, so we could just revert the inclusion of <features.h> if available.

@jhuber6
Copy link
Contributor

jhuber6 commented Feb 3, 2025

I'd prefer a partial revert because this would break the GPU libc++ build. (Sorry I got sidetracked about setting up that build on a bot. I need to get @jplehr or @Artem-B to help me with that). We still can't run the tests clean, but a build is better than nothing.

@jhuber6
Copy link
Contributor

jhuber6 commented Feb 3, 2025

Might need to check for __AMDGPU__ and __NVPTX__ or something, since this is what lets us use lgamma and stuff. alternatively we could replace this with a cmake check that just sees if the environment can call lgamma_r.

@ldionne
Copy link
Member Author

ldionne commented Feb 4, 2025

My strong preference would be to include a standard header instead, but that would require LLVM libc to define its detection macro when such header is included.

I'd be okay with a partial revert only, but @jhuber6 would have to tell me what the check should be instead.

@jhuber6
Copy link
Contributor

jhuber6 commented Feb 4, 2025

My strong preference would be to include a standard header instead, but that would require LLVM libc to define its detection macro when such header is included.

I'd be okay with a partial revert only, but @jhuber6 would have to tell me what the check should be instead.

I think we already have a handful of __LLVM_LIBC__ tests that might also break on baremetal, cc @petrhosek. For my purposes specifically, you'd just put this in it.

#if (defined(__AMDGPU__) || defined(__NVPTX__))
#endif

Though that might break during offloading usage on Windows if the user has features.h?

LLVM libc should instead provide a more standard way of getting configuration macros like LLVM_LIBC.

But features.h is the standard way on Linux at least. We could always emit __features.h or something if we're really concerned.

This partially reverts commit 5f2389d. That commit started checking whether
<features.h> was a valid include unconditionally, however codebases are free
to have such a header on their search path, which breaks compilation. LLVM
libc should instead provide a more standard way of getting configuration
macros like __LLVM_LIBC__.

After this patch, we only include <features.h> when we're on Linux or
when we're compiling for GPUs.
@ldionne ldionne changed the title [libc++] Revert "Do not redeclare lgamma_r when targeting the LLVM C library (#102036) [libc++] Avoid including <features.h> on arbitrary platforms Feb 4, 2025
@petrhosek
Copy link
Member

petrhosek commented Feb 5, 2025

This is going to break other platforms supported by LLVM libc, most notably baremetal (for which we don't really have a great detection mechanism since there's no OS).

An alternative to using an LLVM libc provided header would be to store the value of LIBCXX_LIBC CMake option in __config_site and then use that. This could also eventually replace _LIBCPP_HAS_MUSL_LIBC.

@ldionne
Copy link
Member Author

ldionne commented Feb 5, 2025

This is going to break other platforms supported by LLVM libc, most notably baremetal (for which we don't really have a great detection mechanism since there's no OS).

An alternative to using an LLVM libc provided header would be to store the value of LIBCXX_LIBC CMake option in __config_site and then use that. This could also eventually replace _LIBCPP_HAS_MUSL_LIBC.

At first glance, I'm really not a huge fan of hardcoding the libc we're building on top of in __config_site. However, I do think that this is potentially a more elegant approach than what we do right now (a mix of _LIBCPP_HAS_MUSL_LIBC and auto-detection), and it would also solve some problems we have downstream so I think this might be generally useful.

I'm willing to work on that, but it's not something we'd be able to cherry-pick back to LLVM 20 given its complexity and the time it'll take to put something together. In the meantime, I think it's pretty urgent to restore to a behavior that works on mainstream platforms. If you have specific concerns about this patch breaking some new setups since the last release, perhaps we can carve them out using additional #ifdefs?

@jhuber6
Copy link
Contributor

jhuber6 commented Feb 5, 2025

I'm personally not concerned with the GPU stuff being broken on Clang-20 since the support is still experimental and I doubt anyone's depending on it.

@ldionne
Copy link
Member Author

ldionne commented Feb 7, 2025

@petrhosek Gentle ping. If you have specific concerns about landing this partial revert, please let me know ASAP so we can work on addressing them. Landing this patch addresses a regression that was introduced in LLVM 20 so I'd like to do this sooner rather than later.

@petrhosek
Copy link
Member

@petrhosek Gentle ping. If you have specific concerns about landing this partial revert, please let me know ASAP so we can work on addressing them. Landing this patch addresses a regression that was introduced in LLVM 20 so I'd like to do this sooner rather than later.

I believe this change should be fine, but I'll test it locally against our embedded projects just to be sure that nothing breaks.

@petrhosek
Copy link
Member

@petrhosek Gentle ping. If you have specific concerns about landing this partial revert, please let me know ASAP so we can work on addressing them. Landing this patch addresses a regression that was introduced in LLVM 20 so I'd like to do this sooner rather than later.

I believe this change should be fine, but I'll test it locally against our embedded projects just to be sure that nothing breaks.

I tested this locally and it looks like this change breaks the libc++ on baremetal. Specifically this condition no longer evaluates as true:

#if defined(__LLVM_LIBC__)
# define _LIBCPP_HAS_TIMESPEC_GET
#endif

We'll need some alternative. We could move the __LLVM_LIBC__ to __llvm-libc-common.h which is included from all other libc headers. We could also try to detect whether timespec_get is available without checking for a specific libc.

@petrhosek
Copy link
Member

Now that #126877 landed, this should be safe to land.

@ldionne ldionne merged commit cffc1ac into llvm:main Feb 15, 2025
81 checks passed
@ldionne ldionne deleted the review/fix-features-h-inclusion branch February 15, 2025 09:54
@ldionne
Copy link
Member Author

ldionne commented Feb 15, 2025

/cherry-pick cffc1ac

@llvmbot
Copy link
Member

llvmbot commented Feb 15, 2025

/pull-request #127310

@nico
Copy link
Contributor

nico commented Feb 15, 2025

Looks like this breaks cuda tests on Mac, at least in the gn build: http://45.33.8.238/macm1/100921/step_6.txt

I think the test isn't sufficiently hermetic and the test is to blame, but nevertheless check-clang is currently broken due to this PR.

@ldionne
Copy link
Member Author

ldionne commented Feb 18, 2025

Looks like this breaks cuda tests on Mac, at least in the gn build: http://45.33.8.238/macm1/100921/step_6.txt

I think the test isn't sufficiently hermetic and the test is to blame, but nevertheless check-clang is broken.

Ack, just saw this. I think it's easy to add another layer of guard with __has_include.

Edit: #127691

swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Feb 19, 2025
…5587)

This partially reverts commit 5f2389d. That commit started checking
whether <features.h> was a valid include unconditionally, however codebases
are free to have such a header on their search path, which breaks compilation.
LLVM libc now provides a more standard way of getting configuration macros
like __LLVM_LIBC__.

After this patch, we only include <features.h> when we're on Linux or
when we're compiling for GPUs.

(cherry picked from commit cffc1ac)
sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Feb 24, 2025
…5587)

This partially reverts commit 5f2389d. That commit started checking
whether <features.h> was a valid include unconditionally, however codebases
are free to have such a header on their search path, which breaks compilation.
LLVM libc now provides a more standard way of getting configuration macros
like __LLVM_LIBC__.

After this patch, we only include <features.h> when we're on Linux or
when we're compiling for GPUs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
Development

Successfully merging this pull request may close these issues.

6 participants