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

[libc++] Remove explicit mentions of __need_FOO macros #119025

Merged
merged 2 commits into from
Dec 17, 2024

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Dec 6, 2024

This change has a long history. It was first attempted naively in https://reviews.llvm.org/D131425, which didn't work because we broke the ability for code to include e.g. <stdio.h> multiple times and get different definitions based on the pre-defined macros.

However, in #86843 we managed to simplify <stddef.h> by including the underlying system header outside of any include guards, which worked.

This patch applies the same simplification we did to <stddef.h> to the other headers that currently mention __need_FOO macros explicitly.

@ldionne ldionne requested a review from a team as a code owner December 6, 2024 20:26
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Dec 6, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 6, 2024

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

This change has a long history. It was first attempted naively in https://reviews.llvm.org/D131425, which didn't work because we broke the ability for code to include e.g. <stdio.h> multiple times and get different definitions based on the pre-defined macros.

However, in #86843 we managed to simplify <stddef.h> by including the underlying system header outside of any include guards, which worked.

This patch applies the same simplification we did to <stddef.h> to the other headers that currently mention __need_FOO macros explicitly.


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

4 Files Affected:

  • (modified) libcxx/include/module.modulemap (+4-4)
  • (modified) libcxx/include/stdio.h (+14-15)
  • (modified) libcxx/include/stdlib.h (+15-16)
  • (modified) libcxx/include/wchar.h (+20-21)
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index ed2b7fb1921642..db36ad5bc69592 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -2265,15 +2265,15 @@ module std_stdbool_h [system] {
   textual header "stdbool.h"
 }
 module std_stddef_h [system] {
-  // <stddef.h>'s __need_* macros require textual inclusion.
+  // <stddef.h> supports being included multiple times with different pre-defined macros
   textual header "stddef.h"
 }
 module std_stdio_h [system] {
-  // <stdio.h>'s __need_* macros require textual inclusion.
+  // <stdio.h> supports being included multiple times with different pre-defined macros
   textual header "stdio.h"
 }
 module std_stdlib_h [system] {
-  // <stdlib.h>'s __need_* macros require textual inclusion.
+  // <stdlib.h> supports being included multiple times with different pre-defined macros
   textual header "stdlib.h"
 }
 module std_string_h [system] {
@@ -2289,7 +2289,7 @@ module std_uchar_h [system] {
   export *
 }
 module std_wchar_h [system] {
-  // <wchar.h>'s __need_* macros require textual inclusion.
+  // <wchar.h> supports being included multiple times with different pre-defined macros
   textual header "wchar.h"
 }
 module std_wctype_h [system] {
diff --git a/libcxx/include/stdio.h b/libcxx/include/stdio.h
index 3aa559393f1853..2516e9b78342d6 100644
--- a/libcxx/include/stdio.h
+++ b/libcxx/include/stdio.h
@@ -7,17 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__need_FILE) || defined(__need___FILE)
-
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
-
-#  include_next <stdio.h>
-
-#elif !defined(_LIBCPP_STDIO_H)
-#  define _LIBCPP_STDIO_H
-
 /*
     stdio.h synopsis
 
@@ -98,11 +87,21 @@ int ferror(FILE* stream);
 void perror(const char* s);
 */
 
-#  include <__config>
+#include <__config>
 
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+// The inclusion of the system's <stdio.h> is intentionally done once outside of any include
+// guards because some code expects to be able to include the underlying system header multiple
+// times to get different definitions based on the macros that are set before inclusion.
+#if __has_include_next(<stdio.h>)
+#  include_next <stdio.h>
+#endif
+
+#ifndef _LIBCPP_STDIO_H
+#  define _LIBCPP_STDIO_H
 
 #  if __has_include_next(<stdio.h>)
 #    include_next <stdio.h>
diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h
index 358b10c0392a52..84f8882be41dbb 100644
--- a/libcxx/include/stdlib.h
+++ b/libcxx/include/stdlib.h
@@ -7,17 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__need_malloc_and_calloc)
-
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
-
-#  include_next <stdlib.h>
-
-#elif !defined(_LIBCPP_STDLIB_H)
-#  define _LIBCPP_STDLIB_H
-
 /*
     stdlib.h synopsis
 
@@ -84,11 +73,21 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 */
 
-#  include <__config>
+#include <__config>
 
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+// The inclusion of the system's <stdlib.h> is intentionally done once outside of any include
+// guards because some code expects to be able to include the underlying system header multiple
+// times to get different definitions based on the macros that are set before inclusion.
+#if __has_include_next(<stdlib.h>)
+#  include_next <stdlib.h>
+#endif
+
+#if !defined(_LIBCPP_STDLIB_H)
+#  define _LIBCPP_STDLIB_H
 
 #  if __has_include_next(<stdlib.h>)
 #    include_next <stdlib.h>
@@ -146,6 +145,6 @@ inline _LIBCPP_HIDE_FROM_ABI lldiv_t div(long long __x, long long __y) _NOEXCEPT
 #      endif
 #    endif // _LIBCPP_MSVCRT
 } // extern "C++"
-#  endif   // __cplusplus
+#  endif // __cplusplus
 
 #endif // _LIBCPP_STDLIB_H
diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h
index b7cd5d7fc62cde..66d7f8f8de8603 100644
--- a/libcxx/include/wchar.h
+++ b/libcxx/include/wchar.h
@@ -7,17 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if defined(__need_wint_t) || defined(__need_mbstate_t)
-
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
-
-#  include_next <wchar.h>
-
-#elif !defined(_LIBCPP_WCHAR_H)
-#  define _LIBCPP_WCHAR_H
-
 /*
     wchar.h synopsis
 
@@ -105,23 +94,33 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 
 */
 
-#  include <__config>
-#  include <stddef.h>
+#include <__config>
 
-#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#    pragma GCC system_header
-#  endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
 
 // We define this here to support older versions of glibc <wchar.h> that do
 // not define this for clang.
-#  ifdef __cplusplus
-#    define __CORRECT_ISO_CPP_WCHAR_H_PROTO
-#  endif
+#if defined(__cplusplus) && !defined(__CORRECT_ISO_CPP_WCHAR_H_PROTO)
+#  define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+#endif
+
+// The inclusion of the system's <wchar.h> is intentionally done once outside of any include
+// guards because some code expects to be able to include the underlying system header multiple
+// times to get different definitions based on the macros that are set before inclusion.
+#if __has_include_next(<wchar.h>)
+#  include_next <wchar.h>
+#endif
+
+#ifndef _LIBCPP_WCHAR_H
+#  define _LIBCPP_WCHAR_H
+
+#  include <__mbstate_t.h> // provide mbstate_t
+#  include <stddef.h>      // provide size_t
 
 #  if __has_include_next(<wchar.h>)
 #    include_next <wchar.h>
-#  else
-#    include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of <wchar.h>
 #  endif
 
 // Determine whether we have const-correct overloads for wcschr and friends.

@ldionne ldionne force-pushed the review/remove-need-macros branch 2 times, most recently from 135c6ab to 310c3ea Compare December 10, 2024 15:30
This change has a long history. It was first attempted naively in
https://reviews.llvm.org/D131425, which didn't work because we broke
the ability for code to include e.g. <stdio.h> multiple times and get
different definitions based on the pre-defined macros.

However, in llvm#86843 we managed to simplify <stddef.h> by including
the underlying system header outside of any include guards, which
worked.

This patch applies the same simplification we did to <stddef.h> to
the other headers that currently mention __need_FOO macros explicitly.
…his is happening and it looks like a potential compiler bug. XFAILing the AIX test for now until this can be investigated.
@ldionne ldionne force-pushed the review/remove-need-macros branch from 310c3ea to 057a39d Compare December 16, 2024 17:09
Comment on lines +52 to +53
// TODO: Fix seemingly circular inclusion or <wchar.h> on AIX
// UNSUPPORTED: LIBCXX-AIX-FIXME
Copy link
Member Author

Choose a reason for hiding this comment

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

@daltenty This appears to start failing on AIX after this patch, see e.g. https://buildkite.com/llvm-project/libcxx-ci/builds/39304#0193b131-ead6-42af-b231-48d8de48b2a6. I don't understand why it fails though, since we have proper include guards in wchar.h around the functions that are seemingly re-defined. Since I don't have access to an AIX box matching the CI to reproduce, it would be helpful if someone on the AIX side could take a look.

@ldionne ldionne merged commit ce4ac99 into llvm:main Dec 17, 2024
63 checks passed
@ldionne ldionne deleted the review/remove-need-macros branch December 17, 2024 14:52
@petrhosek
Copy link
Member

petrhosek commented Dec 17, 2024

We started seeing a different failure on our downstream builders after this change:

FAILED: libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o 
/b/s/w/ir/x/w/llvm_build/./bin/clang++ --target=aarch64-unknown-linux-gnu --sysroot=/b/s/w/ir/x/w/cipd/linux -DLIBCXX_BUILDING_LIBCXXABI -DLIBC_NAMESPACE=__llvm_libc_common_utils -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LIBCPP_BUILDING_LIBRARY -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -D_LIBCPP_LINK_PTHREAD_LIB -D_LIBCPP_LINK_RT_LIB -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/s/w/ir/x/w/llvm-llvm-project/libcxx/src -I/b/s/w/ir/x/w/llvm_build/include/aarch64-unknown-linux-gnu/c++/v1 -I/b/s/w/ir/x/w/llvm_build/include/c++/v1 -I/b/s/w/ir/x/w/llvm-llvm-project/libcxxabi/include -I/b/s/w/ir/x/w/llvm-llvm-project/runtimes/cmake/Modules/../../../libc --target=aarch64-unknown-linux-gnu -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -ffile-prefix-map=/b/s/w/ir/x/w/llvm_build/runtimes/runtimes-aarch64-unknown-linux-gnu-bins=../../../llvm-llvm-project -ffile-prefix-map=/b/s/w/ir/x/w/llvm-llvm-project/= -no-canonical-prefixes -O2 -g -DNDEBUG -std=c++2b -UNDEBUG -faligned-allocation -nostdinc++ -fvisibility-inlines-hidden -fvisibility=hidden -fsized-deallocation -Wall -Wextra -Wnewline-eof -Wshadow -Wwrite-strings -Wno-unused-parameter -Wno-long-long -Werror=return-type -Wextra-semi -Wundef -Wunused-template -Wformat-nonliteral -Wzero-length-array -Wdeprecated-redundant-constexpr-static-def -Wno-user-defined-literals -Wno-covered-switch-default -Wno-suggest-override -Wno-error -MD -MT libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -MF libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o.d -o libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -c /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp:12:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/from_chars_floating_point.h:25:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/to_chars_floating_point.h:20:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__algorithm/find.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwchar:114:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwctype:57:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wctype.h:65:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wctype.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wchar.h:121:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__mbstate_t.h:47:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wchar.h:36:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/stdio.h:109:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/stdio.h:74:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/libio.h:31:
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:24:3: error: unknown type name '__mbstate_t'
   24 |   __mbstate_t __state;
      |   ^
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:29:3: error: unknown type name '__mbstate_t'
   29 |   __mbstate_t __state;
      |   ^
2 errors generated.

This is while building libc++ for aarch64 Linux against Debian 8 "jessie" sysroot.

@glandium
Copy link
Contributor

We started seeing a different failure on our downstream builders after this change:

FAILED: libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o 
/b/s/w/ir/x/w/llvm_build/./bin/clang++ --target=aarch64-unknown-linux-gnu --sysroot=/b/s/w/ir/x/w/cipd/linux -DLIBCXX_BUILDING_LIBCXXABI -DLIBC_NAMESPACE=__llvm_libc_common_utils -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LIBCPP_BUILDING_LIBRARY -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -D_LIBCPP_LINK_PTHREAD_LIB -D_LIBCPP_LINK_RT_LIB -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/s/w/ir/x/w/llvm-llvm-project/libcxx/src -I/b/s/w/ir/x/w/llvm_build/include/aarch64-unknown-linux-gnu/c++/v1 -I/b/s/w/ir/x/w/llvm_build/include/c++/v1 -I/b/s/w/ir/x/w/llvm-llvm-project/libcxxabi/include -I/b/s/w/ir/x/w/llvm-llvm-project/runtimes/cmake/Modules/../../../libc --target=aarch64-unknown-linux-gnu -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -ffile-prefix-map=/b/s/w/ir/x/w/llvm_build/runtimes/runtimes-aarch64-unknown-linux-gnu-bins=../../../llvm-llvm-project -ffile-prefix-map=/b/s/w/ir/x/w/llvm-llvm-project/= -no-canonical-prefixes -O2 -g -DNDEBUG -std=c++2b -UNDEBUG -faligned-allocation -nostdinc++ -fvisibility-inlines-hidden -fvisibility=hidden -fsized-deallocation -Wall -Wextra -Wnewline-eof -Wshadow -Wwrite-strings -Wno-unused-parameter -Wno-long-long -Werror=return-type -Wextra-semi -Wundef -Wunused-template -Wformat-nonliteral -Wzero-length-array -Wdeprecated-redundant-constexpr-static-def -Wno-user-defined-literals -Wno-covered-switch-default -Wno-suggest-override -Wno-error -MD -MT libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -MF libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o.d -o libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -c /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp:12:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/from_chars_floating_point.h:25:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/to_chars_floating_point.h:20:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__algorithm/find.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwchar:114:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwctype:57:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wctype.h:65:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wctype.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wchar.h:121:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__mbstate_t.h:47:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wchar.h:36:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/stdio.h:109:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/stdio.h:74:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/libio.h:31:
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:24:3: error: unknown type name '__mbstate_t'
   24 |   __mbstate_t __state;
      |   ^
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:29:3: error: unknown type name '__mbstate_t'
   29 |   __mbstate_t __state;
      |   ^
2 errors generated.

This is while building libc++ for aarch64 Linux against Debian 8 "jessie" sysroot.

Same here, while building libcxx-fuzzing for x86-64 linux against Debian jessie sysroot.

@ldionne
Copy link
Member Author

ldionne commented Dec 18, 2024

This would seem to point to a missing include in the system headers that is being exposed by this patch, but it's really hard to tell without having a local repro. I tried installing Debian Jessie in a Docker image but I can't get anything to work in it, apt-get update won't even work.

@petrhosek
Copy link
Member

This would seem to point to a missing include in the system headers that is being exposed by this patch, but it's really hard to tell without having a local repro. I tried installing Debian Jessie in a Docker image but I can't get anything to work in it, apt-get update won't even work.

If you want to reproduce this locally, you can download our sysroot from https://chrome-infra-packages.appspot.com/p/fuchsia/third_party/sysroot/linux/+/dCkoVcYlgGIP_pmR61ZMIrSDgdrV81BtxcPeTRuyqlUC and use it with CMAKE_SYSROOT.

We still use Debian 8 "jessie" as our sysroot because it corresponds to Ubuntu 14.04 which is still used by a number of projects (including Android) and that way we can guarantee that binaries produced by our toolchain will run there, but we don't actually do any builds on Debian 8 "jessie" or ubuntu 14.04.

@ldionne
Copy link
Member Author

ldionne commented Dec 18, 2024

I am trying to run in a ubuntu Docker image with your sysroot and hitting some failures:

$ cmake -S runtimes/ -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_C_COMPILER=clang-19 -DCMAKE_SYSROOT=/tmp/sysroot-linux -GNinja
-- Performing standalone runtimes build.
-- The C compiler identification is Clang 19.1.6
-- The CXX compiler identification is Clang 19.1.6
-- The ASM compiler identification is Clang with GNU-like command-line
-- Found assembler: /usr/bin/clang-19
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: /usr/bin/clang-19
-- Check for working C compiler: /usr/bin/clang-19 - broken
CMake Error at /usr/share/cmake-3.28/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "/usr/bin/clang-19"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/tmp/llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-vkoXgV'

    Run Build Command(s): /usr/bin/ninja -v cmTC_94ff8
    [1/2] /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux    -MD -MT CMakeFiles/cmTC_94ff8.dir/testCCompiler.c.o -MF CMakeFiles/cmTC_94ff8.dir/testCCompiler.c.o.d -o CMakeFiles/cmTC_94ff8.dir/testCCompiler.c.o -c /tmp/llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-vkoXgV/testCCompiler.c
    [2/2] : && /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux   CMakeFiles/cmTC_94ff8.dir/testCCompiler.c.o -o cmTC_94ff8   && :
    FAILED: cmTC_94ff8
    : && /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux   CMakeFiles/cmTC_94ff8.dir/testCCompiler.c.o -o cmTC_94ff8   && :
    /usr/bin/ld: cannot find crtbeginS.o: No such file or directory
    /usr/bin/ld: cannot find -lgcc: No such file or directory
    /usr/bin/ld: cannot find -lgcc_s: No such file or directory
    clang-19: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.





  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:23 (project)


-- Configuring incomplete, errors occurred!

If you want me to investigate, I'm happy to do that but I'll need a clear reproducer.

@petrhosek
Copy link
Member

If you want me to investigate, I'm happy to do that but I'll need a clear reproducer.

Our sysroot doesn't contain libgcc since we always use compiler-rt and libunwind, so you need -DCMAKE_{SHARED,MODULE,EXE}_LINKER_FLAGS="--rtlib=compiler-rt --unwindlib=libunwind".

@ldionne
Copy link
Member Author

ldionne commented Dec 19, 2024

Now I get:

CMake Error at /usr/share/cmake-3.28/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "/usr/bin/clang-19"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/tmp/llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-byXI6P'

    Run Build Command(s): /usr/bin/ninja -v cmTC_b2c1b
    [1/2] /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux    -MD -MT CMakeFiles/cmTC_b2c1b.dir/testCCompiler.c.o -MF CMakeFiles/cmTC_b2c1b.dir/testCCompiler.c.o.d -o CMakeFiles/cmTC_b2c1b.dir/testCCompiler.c.o -c /tmp/llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-byXI6P/testCCompiler.c
    [2/2] : && /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux  --rtlib=compiler-rt --unwindlib=libunwind CMakeFiles/cmTC_b2c1b.dir/testCCompiler.c.o -o cmTC_b2c1b   && :
    FAILED: cmTC_b2c1b
    : && /usr/bin/clang-19 --sysroot=/tmp/sysroot-linux  --rtlib=compiler-rt --unwindlib=libunwind CMakeFiles/cmTC_b2c1b.dir/testCCompiler.c.o -o cmTC_b2c1b   && :
    /usr/bin/ld: cannot find -lunwind: No such file or directory
    clang-19: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

Sorry, but I can't play whack-a-mole like that. Can you please provide a working reproducer (e.g. a script that sets up the necessary Docker image + CMake invocation), a pre-commit CI bot that catches it, or perform the analysis of why this is now failing yourself? Otherwise, that isn't really workable -- this patch is correct according to our CI, and that's how we determine what's supported. I don't want to be pedantic and use that criterion to dismiss arbitrary breakage, but we do need to draw a line about where contributor responsibility ends and consumers' responsibility begins, otherwise folks can offload arbitrary troubleshooting to us.

@glandium
Copy link
Contributor

Please try the sysroot from #119025 (comment)

@petrhosek
Copy link
Member

I tested the following instructions locally and confirmed that it reproduces the failure:

docker run --rm -it ubuntu:24.04
$ apt-get update
$ apt install lsb-release wget software-properties-common gnupg git cmake ninja-build zstd
$ wget https://apt.llvm.org/llvm.sh
$ chmod +x llvm.sh
$ ./llvm.sh 19 all
$ wget https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/b2JMQqG2TSWBboQasE6Lag/runs/0/artifacts/public%2Fbuild%2Fsysroot-x86_64-linux-gnu.tar.zst
$ tar -xf public%2Fbuild%2Fsysroot-x86_64-linux-gnu.tar.zst
$ git clone https://github.com/llvm/llvm-project
$ cd llvm-project
$ cmake -S runtimes/ -B build -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_C_COMPILER=clang-19 -DCMAKE_SYSROOT=/sysroot-x86_64-linux-gnu -GNinja
$ ninja -C build

@ldionne
Copy link
Member Author

ldionne commented Dec 19, 2024

Thanks for the steps, I followed exactly that but I still get:

CMake Error at /usr/share/cmake-3.28/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "/usr/bin/clang-19"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: '/llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-w2zQf9'

    Run Build Command(s): /usr/bin/ninja -v cmTC_5116d
    [1/2] /usr/bin/clang-19 --sysroot=/sysroot-x86_64-linux-gnu    -MD -MT CMakeFiles/cmTC_5116d.dir/testCCompiler.c.o -MF CMakeFiles/cmTC_5116d.dir/testCCompiler.c.o.d -o CMakeFiles/cmTC_5116d.dir/testCCompiler.c.o -c /llvm-project/build/CMakeFiles/CMakeScratch/TryCompile-w2zQf9/testCCompiler.c
    [2/2] : && /usr/bin/clang-19 --sysroot=/sysroot-x86_64-linux-gnu   CMakeFiles/cmTC_5116d.dir/testCCompiler.c.o -o cmTC_5116d   && :
    FAILED: cmTC_5116d
    : && /usr/bin/clang-19 --sysroot=/sysroot-x86_64-linux-gnu   CMakeFiles/cmTC_5116d.dir/testCCompiler.c.o -o cmTC_5116d   && :
    /usr/bin/ld: cannot find Scrt1.o: No such file or directory
    /usr/bin/ld: cannot find crti.o: No such file or directory
    /usr/bin/ld: cannot find crtbeginS.o: No such file or directory
    /usr/bin/ld: cannot find -lgcc: No such file or directory
    /usr/bin/ld: cannot find -lgcc_s: No such file or directory
    /usr/bin/ld: cannot find -lc: No such file or directory
    /usr/bin/ld: cannot find -lgcc: No such file or directory
    /usr/bin/ld: cannot find -lgcc_s: No such file or directory
    /usr/bin/ld: cannot find crtendS.o: No such file or directory
    /usr/bin/ld: cannot find crtn.o: No such file or directory
    clang-19: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

@petrhosek
Copy link
Member

petrhosek commented Dec 19, 2024

Are you using an Arm machine by any chance? What's the output of uname -a (inside the container)?

@zeroomega
Copy link
Contributor

Not sure if it is helpful for understanding the underlying issue. I reproduced the issue locally and used -dD and -E to see the pre-processed file. And noticed a difference in handling the headers

Before this patch:

system wchar.h ->(include) libcxx/stdio.h ->(include) system stdio.h ->(end of included file) libcxx/stdio.h ->(include) system wchar.h -> define mbstate_t type -> ... -> (include) system _G_config.h -> define __need_mbstate_t -> (include) system wchar.h (but skipped due to header macro) -> used __need_mbstate_t

After this patch:

system wchar.h ->(include) libcxx/stdio.h ->(include) system stdio.h -> (end of included file) libcxx/stdio.h -> (include) system stdio.h -> (end of included file) libcxx/stdio.h ->(include) system stdio.h -> ... -> system _G_config.h -> define __need_mbstate_t -> system wchar.h (but skipped due to header macro) -> use before define error

It appears to me after this patch, during the processing of wchar.h, before the definition of the mbstate_t types, libcxx stdio.h header caused the _G_config.h to be included and processed. Despite the _G_config.hincludes the wchar.h, the wchar's include macro was already defined at this point so it has no effect. Before this patch, the wchar.h will finish processing before _G_config.h was included. In a local experiment, I reverted your change to the stdio.h but keep the rest of the patch unchanged, the build passed. Also in my local reproduction, the i386-linux and x64-linux runtimes are also affected by this build failure, not just arm64.

@ldionne
Copy link
Member Author

ldionne commented Dec 20, 2024

Isn't that a circular dependency in the system headers?

After the patch, it looks like we have

system wchar.h -> ... -> (include) system stdio.h -> ... -> system _G_config.h -> define __need_mbstate_t -> system wchar.h

How does including just the system's wchar.h header differ from that? Does that also fail (I can't imagine)?

@petrhosek
Copy link
Member

The behavior of system wchar.h differs based on which __need_FOO macros; this is the case for other system headers as well, not just wchar.h, so the fact that it's being included multiple times is likely working as intended in this case.

@ldionne Would it be possible to revert this change? I plan to continue looking into this issue to see if there's another way to achieve the same result without breaking the compatibility with older sysroots, but I'd like to avoid leaving our downstream builders completely broken for the next two weeks since that will mean will loose test coverage during that time.

@kongy
Copy link
Collaborator

kongy commented Dec 22, 2024

We started seeing a different failure on our downstream builders after this change:

FAILED: libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o 
/b/s/w/ir/x/w/llvm_build/./bin/clang++ --target=aarch64-unknown-linux-gnu --sysroot=/b/s/w/ir/x/w/cipd/linux -DLIBCXX_BUILDING_LIBCXXABI -DLIBC_NAMESPACE=__llvm_libc_common_utils -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_LIBCPP_BUILDING_LIBRARY -D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -D_LIBCPP_LINK_PTHREAD_LIB -D_LIBCPP_LINK_RT_LIB -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/s/w/ir/x/w/llvm-llvm-project/libcxx/src -I/b/s/w/ir/x/w/llvm_build/include/aarch64-unknown-linux-gnu/c++/v1 -I/b/s/w/ir/x/w/llvm_build/include/c++/v1 -I/b/s/w/ir/x/w/llvm-llvm-project/libcxxabi/include -I/b/s/w/ir/x/w/llvm-llvm-project/runtimes/cmake/Modules/../../../libc --target=aarch64-unknown-linux-gnu -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -ffile-prefix-map=/b/s/w/ir/x/w/llvm_build/runtimes/runtimes-aarch64-unknown-linux-gnu-bins=../../../llvm-llvm-project -ffile-prefix-map=/b/s/w/ir/x/w/llvm-llvm-project/= -no-canonical-prefixes -O2 -g -DNDEBUG -std=c++2b -UNDEBUG -faligned-allocation -nostdinc++ -fvisibility-inlines-hidden -fvisibility=hidden -fsized-deallocation -Wall -Wextra -Wnewline-eof -Wshadow -Wwrite-strings -Wno-unused-parameter -Wno-long-long -Werror=return-type -Wextra-semi -Wundef -Wunused-template -Wformat-nonliteral -Wzero-length-array -Wdeprecated-redundant-constexpr-static-def -Wno-user-defined-literals -Wno-covered-switch-default -Wno-suggest-override -Wno-error -MD -MT libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -MF libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o.d -o libcxx/src/CMakeFiles/cxx_static.dir/charconv.cpp.o -c /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/charconv.cpp:12:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/from_chars_floating_point.h:25:
In file included from /b/s/w/ir/x/w/llvm-llvm-project/libcxx/src/include/to_chars_floating_point.h:20:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__algorithm/find.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwchar:114:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/cwctype:57:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wctype.h:65:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wctype.h:33:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/wchar.h:121:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/__mbstate_t.h:47:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/wchar.h:36:
In file included from /b/s/w/ir/x/w/llvm_build/include/c++/v1/stdio.h:109:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/stdio.h:74:
In file included from /b/s/w/ir/x/w/cipd/linux/usr/include/libio.h:31:
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:24:3: error: unknown type name '__mbstate_t'
   24 |   __mbstate_t __state;
      |   ^
/b/s/w/ir/x/w/cipd/linux/usr/include/_G_config.h:29:3: error: unknown type name '__mbstate_t'
   29 |   __mbstate_t __state;
      |   ^
2 errors generated.

This is while building libc++ for aarch64 Linux against Debian 8 "jessie" sysroot.

Same here, while building libcxx-fuzzing for x86-64 linux against Debian jessie sysroot.

This change also broke Android's ToT integration in the same way.

petrhosek added a commit to petrhosek/llvm-project that referenced this pull request Dec 23, 2024
This was introduced in llvm#119025 and not only seems unnecessary, it broke
the build with older versions of glibc.
petrhosek added a commit that referenced this pull request Dec 23, 2024
This was introduced in #119025 and not only seems unnecessary, it broke
the build with older versions of glibc.
@petrhosek
Copy link
Member

The breakage should be addressed by #120946, at least on our side the builders are back to green. Let me know if you still see the issue.

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
None yet
Development

Successfully merging this pull request may close these issues.

7 participants