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

Foundation: repair the build for Android API level 28+ #4889

Closed
wants to merge 9 commits into from

Conversation

compnerd
Copy link
Member

The newer level introduces APIs with additional nullability attribution. This causes issues as the attribution sometimes collides with expectations. Unwrap more cases to appease the nullability attributes. One problematic area of this change is the handling for Process.run(). The posix spawn APIs are described as:

typedef struct __posix_spawnattr* posix_spawnattr_t;
int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr);

As the inner _Nonnull appertains to posix_spawnattr_t, it expects a non-null pointer to a non-null pointer. However, as struct __posix_spawnattr is opaque, we cannot allocate space for it and thus must be acceptable to take a pointer to null to permit the allocation.

@compnerd
Copy link
Member Author

CC: @drodriguez @finagolfin @etcwilde

@compnerd
Copy link
Member Author

@swift-ci please test

@finagolfin
Copy link
Member

I have a similar pull submitted months ago, #4850, that simply has not been reviewed, which only doesn't have your posix_spawn modifications here.

compnerd and others added 2 commits April 29, 2024 16:39
The newer level introduces APIs with additional nullability
attribution. This causes issues as the attribution sometimes collides
with expectations. Unwrap more cases to appease the nullability
attributes. One problematic area of this change is the handling for
`Process.run()`. The posix spawn APIs are described as:

```
typedef struct __posix_spawnattr* posix_spawnattr_t;
int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr);
```

As the inner `_Nonnull` appertains to `posix_spawnattr_t`, it expects a
non-null pointer to a non-null pointer. However, as
`struct __posix_spawnattr` is opaque, we cannot allocate space for it
and thus must be acceptable to take a pointer to null to permit the
allocation.
@hyp
Copy link
Contributor

hyp commented Apr 30, 2024

@swift-ci please test

@finagolfin
Copy link
Member

Oh, nice, I was just going to try building this repo natively on Android with your recent compiler pulls, will apply your Glibc-replacing changes here.

I also need to reconcile my earlier pull #4850 for the nullability annotations in NDK 26 with Saleem's first commit here, will try to get to that this week.

@finagolfin
Copy link
Member

I ran the tests natively on Android 13 with my pull #4850, the last two commits of this pull, and your two stdlib pulls adding the Android overlay, which got these 47 tests regressing:

TestFoundation.TestNSArray-test_writeToFile (SIGTRAP)                                                                                                        
TestFoundation.TestNSArray-test_initWithContentsOfFile (SIGTRAP)                                                                                             
TestFoundation.TestNSArray-test_initMutableWithContentsOfFile (SIGTRAP)                                                                                      
TestFoundation.TestNSArray-test_initMutableWithContentsOfURL (SIGTRAP)                                                                                      
TestFoundation.TestNSData-test_writeFailure (SIGTRAP)     
TestFoundation.TestNSData-test_writeToURLPermissions (SIGTRAP)                                                                                              
TestFoundation.TestNSData-test_writeToURLPermissionsWithAtomic (SIGTRAP)                                                                                    
TestFoundation.TestNSDictionary-test_writeToFile (SIGTRAP)                                                                                                  
TestFoundation.TestNSDictionary-test_initWithContentsOfFile (SIGTRAP)                                                                                       
TestFoundation.TestFileManager-test_createFile (SIGTRAP)     
TestFoundation.TestFileManager-test_fileAttributes (SIGTRAP)                                                                                                
TestFoundation.TestFileManager-test_setFileAttributes (SIGTRAP)                                                                                             
TestFoundation.TestFileManager-test_pathEnumerator (SIGTRAP)                                                                                                
TestFoundation.TestFileManager-test_copyItemAtPathToPath (SIGTRAP)                                                                                          
TestFoundation.TestFileManager-test_copyItemsPermissions (SIGTRAP)                                                                                          
TestFoundation.TestFileManager-test_emptyFilename (SIGTRAP)                                                                                                 
TestFoundation.TestFileManager-test_getRelationship (SIGTRAP)                                                                                               
TestFoundation.TestFileManager-test_displayNames (SIGTRAP)                                                                                                  
TestFoundation.TestFileManager-test_getItemReplacementDirectory (SIGTRAP)                                                                                   
TestFoundation.TestFileManager-test_contentsEqual (SIGTRAP)                                                                                                 
TestFoundation.TestHTTPCookieStorage-test_sharedCookieStorageAccessedFromMultipleThreads (SIGTRAP)                                                          
TestFoundation.TestHTTPCookieStorage-test_BasicStorageAndRetrieval (SIGTRAP)     
TestFoundation.TestHTTPCookieStorage-test_deleteCookie (SIGTRAP)                                                                                            
TestFoundation.TestHTTPCookieStorage-test_removeCookies (SIGTRAP)                                                                                           
TestFoundation.TestHTTPCookieStorage-test_cookiesForURL (SIGTRAP)                                                                                           
TestFoundation.TestHTTPCookieStorage-test_cookiesForURLWithMainDocumentURL (SIGTRAP)                                                                        
TestFoundation.TestHTTPCookieStorage-test_cookieInXDGSpecPath (SIGTRAP)                                                                                     
TestFoundation.TestHTTPCookieStorage-test_descriptionCookie (SIGTRAP)                                                                                       
TestFoundation.TestHTTPCookieStorage-test_cookieDomainMatching (SIGTRAP)                                                                                    
TestFoundation.TestHTTPCookieStorage-test_sorting (SIGTRAP)                                                                                                 
TestFoundation.TestNSString-test_writeToURLHasBOM_UTF32 (SIGTRAP)                                                                                          
TestFoundation.TestURLCache-testStorageRoundtrip (SIGTRAP)                                                                                                 
TestFoundation.TestURLCache-testNoDiskUsageIfDisabled (SIGTRAP)                                                                                            
TestFoundation.TestURLCache-testShrinkingDiskCapacityEvictsItems (SIGTRAP)                                                                                 
TestFoundation.TestURLCache-testNoMemoryUsageIfDisabled (SIGTRAP)                                                                                          
TestFoundation.TestURLCache-testShrinkingMemoryCapacityEvictsItems (SIGTRAP)                                                                               
TestFoundation.TestURLCache-testRemovingOne (SIGTRAP)                                                                                                      
TestFoundation.TestURLCache-testRemovingAll (SIGTRAP)                                                                                                      
TestFoundation.TestURLCache-testRemovingSince (SIGTRAP)                                                                                                    
TestFoundation.TestURLCache-testStoringTwiceOnlyHasOneEntry (SIGTRAP)     
TestFoundation.TestURLSession-test_downloadTaskWithURL (SIGTRAP)                                                                                           
TestFoundation.TestURLSession-test_downloadTaskWithURLRequest (SIGTRAP)                                                                                    
TestFoundation.TestURLSession-test_gzippedDownloadTask (SIGTRAP)     
TestFoundation.TestURLSession-test_cookiesStorage (SIGTRAP)                                                                                                
TestFoundation.TestURLSession-test_previouslySetCookiesAreSentInLaterRequests (SIGTRAP)                                                                    
TestFoundation.TestURLSession-test_setCookieHeadersCanBeIgnored (SIGTRAP)     
TestFoundation.TestURLSession-test_redirectionWithSetCookies (SIGTRAP)

We'll need to look into these before these pulls can be merged.

@finagolfin
Copy link
Member

Alright, found the two remaining mode_t tweaks that fixed all 47 test regressions and submitted a pull in compnerd#1.

@hyp
Copy link
Contributor

hyp commented May 20, 2024

@finagolfin THanks! I just got ability to run the foundation tests on devices, and I saw some of these crashes, so I will test your PR now!

@hyp
Copy link
Contributor

hyp commented May 21, 2024

@finagolfin I confirmed that your PR fixed the crashes, thanks! I also updated the PR to make sure we can still build for armv7 and i686.

@finagolfin
Copy link
Member

@hyp, how are you running the tests, cross-compiling this repo from linux then moving the TestFoundation binary to an Android device? I have never tried that with cross-compilation, but intend to set it up on the CI one day.

@hyp
Copy link
Contributor

hyp commented May 21, 2024

I built the Android test package for Foundation on Windows using build.ps1 (swiftlang/swift#72014) , and then copied over all the libs, TestFoundation executable and files to run on device as well. That seemed to work.

@compnerd
Copy link
Member Author

@swift-ci please test

This allows us to prevent the ambiguity for various STATX defines from linux/stat.h when building for Android, as those are defined in the Android platform module
@hyp
Copy link
Contributor

hyp commented May 28, 2024

updated to simplify PR now that we don't have an ambiguity between Android and SwiftAndroid constants

@hyp
Copy link
Contributor

hyp commented May 28, 2024

@swift-ci please test

@hyp
Copy link
Contributor

hyp commented May 28, 2024

@swift-ci please test

@hyp
Copy link
Contributor

hyp commented Jun 15, 2024

@swift-ci please test

@hyp
Copy link
Contributor

hyp commented Jun 15, 2024

I would like to merge this in next week

@finagolfin
Copy link
Member

Simply remove the two force unwraps in the tests that I commented above, as I already submitted those changes in my earlier pull.

I will reconcile Saleem's first commit with my earlier pull this weekend, and once we hash that overlap out in the coming week, this pull should be ready for merging.

@hyp
Copy link
Contributor

hyp commented Jun 17, 2024

@swift-ci please test windows platform

@finagolfin
Copy link
Member

@hyp, happy to report that I ran the Swift compiler validation suite with the March 1 trunk snapshot plus your new Android overlay and after making the couple small tweaks to the Termux headers I mentioned, most of the remaining ~20% of C++ Interop tests now pass. 😃

One in particular still doesn't build though and I'm seeing this same error when trying to build the latest June 13 trunk snapshot compiler, perhaps you can take a look?

<testcase classname="Swift(android-aarch64).Interop/Cxx/class" name="memory-layout-execution.swift" time="0.64">
  <failure><![CDATA[Script:
--
: 'RUN: at line 1';   rm -rf "/data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/test-android-aarch64/Interop/Cxx/class/Output/memory-layout-execution.swift.tmp" && mkdir -p "/data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/test-android-aarch64/Interop/Cxx/class/Output/memory-layout-execution.swift.tmp"
: 'RUN: at line 2';   /data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/bin/swiftc -target aarch64-unknown-linux-android -toolchain-stdlib-rpath  -module-cache-path /data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/swift-test-results/aarch64-unknown-linux-android/clang-module-cache -swift-version 4  -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 9999:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.0:macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.1:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.2:macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.3:macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.4:macOS 11.3, iOS 14.5, watchOS 7.4, tvOS 14.5' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.5:macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.6:macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.7:macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.8:macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.9:macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 5.10:macOS 14.4, iOS 17.4, watchOS 10.4, tvOS 17.4' -Xfrontend -define-availability -Xfrontend 'SwiftStdlib 6.0:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999'  /data/data/com.termux/files/home/swift/test/Interop/Cxx/class/memory-layout-execution.swift -I /data/data/com.termux/files/home/swift/test/Interop/Cxx/class/Inputs -o /data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/test-android-aarch64/Interop/Cxx/class/Output/memory-layout-execution.swift.tmp/class_layout -Xfrontend -enable-experimental-cxx-interop
: 'RUN: at line 3';   echo /data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/test-android-aarch64/Interop/Cxx/class/Output/memory-layout-execution.swift.tmp/class_layout
: 'RUN: at line 4';   /usr/bin/env LD_LIBRARY_PATH='/data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/lib/swift/android:/data/data/com.termux/files/home/build/Ninja-Release/libdispatch-android-aarch64'  /data/data/com.termux/files/home/build/Ninja-Release/swift-android-aarch64/test-android-aarch64/Interop/Cxx/class/Output/memory-layout-execution.swift.tmp/class_layout 2&>1
--
Exit Code: 1

Command Output (stderr):
--
<unknown>:0: warning: the '-enable-experimental-cxx-interop' flag is deprecated; please pass '-cxx-interoperability-mode=' instead
<unknown>:0: note: Swift will maintain source compatibility for imported APIs based on the selected compatibility mode, so updating the Swift compiler will not change how APIs are imported
<module-includes>:1:10: note: in file included from <module-includes>:1:
1 │ #include "memory-layout.h"
  │          ╰─ note: in file included from <module-includes>:1:
2 │ 

/data/data/com.termux/files/home/swift/test/Interop/Cxx/class/Inputs/memory-layout.h:8:3: error: missing '#include <stdint.h>'; 'uint32_t' must be declared before it is used
 6 │ 
 7 │ class PrivateMemberLayout {
 8 │   uint32_t a;
   │   ╰─ error: missing '#include <stdint.h>'; 'uint32_t' must be declared before it is used
 9 │ 
10 │ public:

/data/data/com.termux/files/usr/include/stdint.h:65:23: note: declaration here is not visible
 63 │ 
 64 │ typedef __int32_t     int32_t;
 65 │ typedef __uint32_t    uint32_t;
    │                       ╰─ note: declaration here is not visible
 66 │ 
 67 │ typedef __int64_t     int64_t;

<module-includes>:1:10: note: in file included from <module-includes>:1:
1 │ #include "memory-layout.h"
  │          ╰─ note: in file included from <module-includes>:1:
2 │ 

/data/data/com.termux/files/home/swift/test/Interop/Cxx/class/Inputs/memory-layout.h:19:19: error: 'PrivateMemberLayout' does not refer to a value
 5 │ #include <cstdint>
 6 │ 
 7 │ class PrivateMemberLayout {
   │       ╰─ note: declared here
 8 │   uint32_t a;
 9 │ 
   ┆
17 │ 
18 │ inline size_t offsetOfPrivateMemberLayout_b() {
19 │   return offsetof(PrivateMemberLayout, b);
   │                   ╰─ error: 'PrivateMemberLayout' does not refer to a value
20 │ }
21 │ 

<module-includes>:1:10: note: in file included from <module-includes>:1:
1 │ #include "memory-layout.h"
  │          ╰─ note: in file included from <module-includes>:1:
2 │ 

/data/data/com.termux/files/home/swift/test/Interop/Cxx/class/Inputs/memory-layout.h:19:40: error: use of undeclared identifier 'b'
17 │ 
18 │ inline size_t offsetOfPrivateMemberLayout_b() {
19 │   return offsetof(PrivateMemberLayout, b);
   │                                        ╰─ error: use of undeclared identifier 'b'
20 │ }
21 │ 

/data/data/com.termux/files/home/swift/test/Interop/Cxx/class/memory-layout-execution.swift:8:8: error: could not build C module 'MemoryLayout'
 6 │ // REQUIRES: executable_test
 7 │ 
 8 │ import MemoryLayout
   │        ╰─ error: could not build C module 'MemoryLayout'
 9 │ import StdlibUnittest
10 │ 

--
]]></failure>
</testcase>

Since it's a build error, you should be able to reproduce by removing the executable_test label for that test and cross-compiling that test as part of a host-test run. Let me know what you think.

@hyp
Copy link
Contributor

hyp commented Jun 17, 2024

@finagolfin
Thanks for looking into it! The issue with stdint in Termux you're seeing is happening I believe because the NDK has outdated clang builtin headers module map (clang/lib/Header/module.modulemap), where the _Builtin_stdint module is not present. Can you check that?

We don't see it when building on a linux host because there we're using builtin headers that Swift gets from its embedded clang, and those have up to date module map.

@hyp
Copy link
Contributor

hyp commented Jun 17, 2024

@compnerd do you think this looks good now?
@jmschonfeld @parkera please let me know if you have any other comments! If not, we will merge it in in the next couple of days.

@compnerd
Copy link
Member Author

Yeap, seems ready to me!

@parkera
Copy link
Contributor

parkera commented Jun 17, 2024

We have a gigantic patch coming in to add Cmake support to the 'package' branch (not so great of a name now, but that tracks building SCL-F on top of S-F as part of the toolchain). That branch will become main once it is ready: #4959. Time span is hopefully days at this point.

I would really like to hold on this until after that lands. Then we can make sure that we have a working Android build as part of landing this.

@hyp
Copy link
Contributor

hyp commented Jun 17, 2024

I see, I will keep track of that change then and we will try to wait. I will test these changes together with that change in the mean time.

@finagolfin
Copy link
Member

finagolfin commented Jun 18, 2024

The issue with stdint in Termux you're seeing is happening I believe because the NDK has outdated clang builtin headers module map (clang/lib/Header/module.modulemap), where the _Builtin_stdint module is not present. Can you check that?

Sure, but no, the tests always use the freshly-built Swift compiler, which links to the newly-generated clang headers from the Swift-forked LLVM, which does have that module. However, if you look at the error, the issue is with the stdint.h directly in the NDK sysroot, ie the problem is not with the clang builtin headers, whether from the NDK or the Swift-forked LLVM.

You're right that this build issue is not reproducible when cross-compiling though, as I just tried it, so I looked again and there is another stdint.h addition to the Termux headers that may be causing this. I will try excluding that and check if it's the cause.

I will test these changes together with that change in the mean time.

Hold on, I have not reconciled the first commit from this pull with my earlier pull yet. I'll try to get that done today.

@hyp
Copy link
Contributor

hyp commented Jun 21, 2024

@swift-ci please test

@hyp
Copy link
Contributor

hyp commented Jun 24, 2024

@parkera I see you merged that PR into the 'package' branch, but 'package' is not yet main right? I tested this PR on top of 'package' and after resolving some merge conflicts and compile errors I can get back to the build of Android foundation and build it. Also, it seems that 'package' is unable to build foundation for Windows now using build.ps1.
I would like to merge this PR into 'main' now to unblock some further Android work and allow us to start distributing a toolchain to our engineers. Once it's merged, I will update 'package' and remerge it there to make sure that 'package' is up-to-date. Is that ok with you?

@compnerd
Copy link
Member Author

CC: @jmschonfeld

@finagolfin
Copy link
Member

I think they're still working on getting the swift-corelibs-foundation tests working in the new branch, swiftlang/swift#74594.

I would like to merge this PR into 'main' now to unblock some further Android work and allow us to start distributing a toolchain to our engineers.

Why would it matter whats in the main branch to start distributing a private toolchain to your engineers? Hopefully, you've given out such a private toolchain built from your own local branch and extensively tested it internally before ever trying to get such patches merged upstream.

let stream = fts_open(ps, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil)
let stream = ps.withMemoryRebound(to: UnsafeMutablePointer<CChar>.self, capacity: 2) { rebound_ps in
#if canImport(Android)
let arg = rebound_ps
Copy link
Member

Choose a reason for hiding this comment

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

This change and the similar one 370 lines below are likely no longer needed after swiftlang/swift#74829. Try it out and see, I will check natively on Android also.

@finagolfin
Copy link
Member

Alright, swift-foundation was finally merged, so we can rework this now and get it in. @compnerd's first commit here significantly overlaps with my earlier pull #4850, so I will update that based on his review comments there, then this one can be updated not to overlap and we can get both in this week.

@parkera
Copy link
Contributor

parkera commented Jul 16, 2024

@finagolfin thanks for your patience

@finagolfin
Copy link
Member

thanks for your patience

No problem, @hyp was the one in a hurry. 😉

Now that swift-foundation was merged into trunk, my earlier pull #4850 and this one will have to be significantly reworked. In the meantime, I have submitted a modified version of #4850 for the 6.0 branch, #5010, and I suggest the same be done for this pull, ie modify it and apply it to 6.0 on top of mine.

We know the changes in these two pulls are needed for 6.0, where swift-foundation will presumably not be merged, so let's get these into the 6.0 branch, then we can rework and expand these for trunk, that now uses the swift-foundation rewrite.

@parkera
Copy link
Contributor

parkera commented Jul 17, 2024

Actually we are planning to take the re-core in the Swift 6.0 branch. We're getting set up to make that PR now.

@finagolfin
Copy link
Member

Actually we are planning to take the re-core in the Swift 6.0 branch. We're getting set up to make that PR now.

OK, I didn't think you'd want such a big change as the re-core in 6.0 this late, but presumably you've tested it enough and know it works.

I will instead get #4850 building with the re-cored trunk then.

@finagolfin
Copy link
Member

@hyp, does your #4994 get the re-core building and passing most tests on Android, or are significantly more changes needed for that?

@finagolfin
Copy link
Member

@compnerd, I think this can be closed, with all necessary changes added to #5024 instead.

@compnerd
Copy link
Member Author

@finagolfin yeah, thanks for the reminder!

@compnerd compnerd closed this Aug 18, 2024
@compnerd compnerd deleted the bionic branch August 18, 2024 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants