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

Interop: Compiling with C++17 or higher on Ubuntu 22.04 fails with cyclic header dependencies in libstdc++ #75661

Closed
ADKaster opened this issue Aug 2, 2024 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. c++ interop Feature: Interoperability with C++

Comments

@ADKaster
Copy link
Contributor

ADKaster commented Aug 2, 2024

Description

When building on a Linux system with libstdc++ higher than version 10 (the current version is 14, and Ubuntu Jammy ships 11) there is a cyclic dependency in the clang module graph for the standard library.

The check in <prefix>//lib/swift/linux/libstdcxx.h includes <execution> in c++17 or higher modes. With libstdc++-11-dev or higher and libtbb-dev, installed, this introduces a cyclic dependency between the _Builtin_intrinsics module and std.

Reproduction

With the following 3 files, the issue is easy to see with the official swift 6.0 snapshot docker containers:

Lib.h

#include <memory>

#include <stdio.h>

void foo() { puts("hi");  }

module.modulemap

module lib {
    header "Lib.h"
}

main.swift

import lib

print("hi")

After putting all these 4 files in one directory, the error can be reproduced with the following shell commands that launch a swift nightly docker container, and installs libtbb-dev.

docker run -it --rm -v $PWD:/workspace swiftlang/swift:nightly-6.0-jammy
apt update && apt install -y libtbb-dev
swiftc -emit-executable -o test -Xcc -std=c++17 -cxx-interoperability-mode=default -I /workspace /workspace/main.swift

The error is as follows:

- error: cyclic dependency in module 'std': std -> _Builtin_intrinsics -> std
/workspace/Lib.h:1:10: note: while building module 'std' imported from /workspace/Lib.h:1:
1 | #include <memory>
  |          `- note: while building module 'std' imported from /workspace/Lib.h:1:
2 | 
3 | #include <stdio.h>

/usr/include/tbb/../oneapi/tbb/detail/_machine.h:42:10: note: while building module '_Builtin_intrinsics' imported from /usr/include/tbb/../oneapi/tbb/detail/_machine.h:42:
 40 | #endif
 41 | #if __TBB_x86_64 || __TBB_x86_32
 42 | #include <immintrin.h> // _mm_pause
    |          `- note: while building module '_Builtin_intrinsics' imported from /usr/include/tbb/../oneapi/tbb/detail/_machine.h:42:
 43 | #endif
 44 | #if (_WIN32)

<module-includes>:2:10: note: in file included from <module-includes>:2:
 1 | extern "C" {
 2 | #include "immintrin.h"
   |          `- note: in file included from <module-includes>:2:
 3 | }
 4 | extern "C" {

/usr/lib/swift/clang/include/immintrin.h:26:10: note: in file included from /usr/lib/swift/clang/include/immintrin.h:26:
 24 | #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
 25 |     defined(__SSE__)
 26 | #include <xmmintrin.h>
    |          `- note: in file included from /usr/lib/swift/clang/include/immintrin.h:26:
 27 | #endif
 28 | 

/usr/lib/swift/clang/include/xmmintrin.h:31:10: note: in file included from /usr/lib/swift/clang/include/xmmintrin.h:31:
  29 |  * a standard library to provide allocation routines. */
  30 | #if __STDC_HOSTED__
  31 | #include <mm_malloc.h>
     |          `- note: in file included from /usr/lib/swift/clang/include/xmmintrin.h:31:
  32 | #endif
  33 | 

/usr/lib/swift/clang/include/mm_malloc.h:13:10: note: in file included from /usr/lib/swift/clang/include/mm_malloc.h:13:
11 | #define __MM_MALLOC_H
12 | 
13 | #include <stdlib.h>
   |          `- note: in file included from /usr/lib/swift/clang/include/mm_malloc.h:13:
14 | 
15 | #ifdef _WIN32

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/stdlib.h:36:11: error: cyclic dependency in module 'std': std -> _Builtin_intrinsics -> std
34 | #define _GLIBCXX_STDLIB_H 1
35 | 
36 | # include <cstdlib>
   |           `- error: cyclic dependency in module 'std': std -> _Builtin_intrinsics -> std
37 | 
38 | using std::abort;

/workspace/Lib.h:1:10: note: while building module 'std' imported from /workspace/Lib.h:1:
1 | #include <memory>
  |          `- note: while building module 'std' imported from /workspace/Lib.h:1:
2 | 
3 | #include <stdio.h>

<module-includes>:1:10: note: in file included from <module-includes>:1:
  1 | #include "libstdcxx.h"
    |          `- note: in file included from <module-includes>:1:
  2 | #include "algorithm"
  3 | #include "bitset"

/usr/lib/swift/linux/libstdcxx.h:6:10: note: in file included from /usr/lib/swift/linux/libstdcxx.h:6:
4 | // Only include <execution> if tbb is installed.
5 | #if __has_include("execution") && __has_include(<tbb/blocked_range.h>)
6 | #include "execution"
  |          `- note: in file included from /usr/lib/swift/linux/libstdcxx.h:6:
7 | #endif
8 | 

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/execution:32:11: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/execution:32:
30 | #if __cplusplus >= 201703L
31 | # include <bits/c++config.h>
32 | # include <pstl/glue_execution_defs.h>
   |           `- note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/execution:32:
33 | 
34 | # define _PSTL_EXECUTION_POLICIES_DEFINED 1

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/glue_execution_defs.h:50:10: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/glue_execution_defs.h:50:
48 | } // namespace std
49 | 
50 | #include "algorithm_impl.h"
   |          `- note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/glue_execution_defs.h:50:
51 | #include "numeric_impl.h"
52 | #include "parallel_backend.h"

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/algorithm_impl.h:22:10: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/algorithm_impl.h:22:
  20 | #include "memory_impl.h"
  21 | #include "parallel_backend_utils.h"
  22 | #include "parallel_backend.h"
     |          `- note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/algorithm_impl.h:22:
  23 | #include "parallel_impl.h"
  24 | #include "unseq_backend_simd.h"

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend.h:20:14: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend.h:20:
18 | }
19 | #elif defined(_PSTL_PAR_BACKEND_TBB)
20 | #    include "parallel_backend_tbb.h"
   |              `- note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend.h:20:
21 | namespace __pstl
22 | {

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend_tbb.h:19:10: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend_tbb.h:19:
  17 | 
  18 | // Bring in minimal required subset of Intel TBB
  19 | #include <tbb/blocked_range.h>
     |          `- note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/pstl/parallel_backend_tbb.h:19:
  20 | #include <tbb/parallel_for.h>
  21 | #include <tbb/parallel_reduce.h>

/usr/include/tbb/blocked_range.h:17:10: note: in file included from /usr/include/tbb/blocked_range.h:17:
15 | */
16 | 
17 | #include "../oneapi/tbb/blocked_range.h"
   |          `- note: in file included from /usr/include/tbb/blocked_range.h:17:
18 | 

/usr/include/tbb/../oneapi/tbb/blocked_range.h:22:10: note: in file included from /usr/include/tbb/../oneapi/tbb/blocked_range.h:22:
 20 | #include <cstddef>
 21 | 
 22 | #include "detail/_range_common.h"
    |          `- note: in file included from /usr/include/tbb/../oneapi/tbb/blocked_range.h:22:
 23 | #include "detail/_namespace_injection.h"
 24 | 

/usr/include/tbb/../oneapi/tbb/detail/_range_common.h:21:10: note: in file included from /usr/include/tbb/../oneapi/tbb/detail/_range_common.h:21:
 19 | 
 20 | #include "_config.h"
 21 | #include "_utils.h"
    |          `- note: in file included from /usr/include/tbb/../oneapi/tbb/detail/_range_common.h:21:
 22 | #if __TBB_CPP20_CONCEPTS_PRESENT
 23 | #include <concepts>

/usr/include/tbb/../oneapi/tbb/detail/_utils.h:26:10: note: in file included from /usr/include/tbb/../oneapi/tbb/detail/_utils.h:26:
 24 | #include "_config.h"
 25 | #include "_assert.h"
 26 | #include "_machine.h"
    |          `- note: in file included from /usr/include/tbb/../oneapi/tbb/detail/_utils.h:26:
 27 | 
 28 | namespace tbb {

/usr/include/tbb/../oneapi/tbb/detail/_machine.h:42:10: error: could not build module '_Builtin_intrinsics'
 40 | #endif
 41 | #if __TBB_x86_64 || __TBB_x86_32
 42 | #include <immintrin.h> // _mm_pause
    |          `- error: could not build module '_Builtin_intrinsics'
 43 | #endif
 44 | #if (_WIN32)

<module-includes>:1:10: note: in file included from <module-includes>:1:
1 | #include "Lib.h"
  |          `- note: in file included from <module-includes>:1:
2 | 

/workspace/Lib.h:1:10: error: could not build module 'std'
1 | #include <memory>
  |          `- error: could not build module 'std'
2 | 
3 | #include <stdio.h>

/workspace/main.swift:1:8: error: could not build C module 'lib'
1 | import lib
  |        `- error: could not build C module 'lib'
2 | 
3 | print("hi")

Removing the -Xcc -std=c++17 causes the error to go away, because we are no longer trying to use tbb/execution

Expected behavior

including any C++ standard library header in C++17, C++20, C++23 or C++26 mode should not error out the swift compiler.

The support for <execution> on Linux should either be removed or fixed for Swift 6.0.

Note that this was not an issue in the Ubuntu 20.04 containers, because they only ship libstdc++-10-dev.

Environment

swiftc -version:
Swift version 6.0-dev (LLVM d83ae228657c9e1, Swift 0382996)
Target: x86_64-unknown-linux-gnu

docker image list:
swiftlang/swift nightly-6.0-jammy dbdffe58b5a0 13 hours ago 3.51GB

Additional information

https://forums.swift.org/t/swift-5-9-release-on-ubuntu-22-04-fails-to-build-std-module/67659/4

@ADKaster ADKaster added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Aug 2, 2024
ADKaster added a commit to ADKaster/swift that referenced this issue Aug 2, 2024
@MaxDesiatov MaxDesiatov added c++ interop Feature: Interoperability with C++ and removed triage needed This issue needs more specific labels labels Aug 16, 2024
@egorzhdan
Copy link
Contributor

I extracted #76166 to track the future fix for this.
Since this has a workaround and isn't blocking anymore, I am closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. c++ interop Feature: Interoperability with C++
Projects
None yet
Development

No branches or pull requests

3 participants