Using InlineArray on macOS

Hello,

I can see in the Apple docs and in Xcode build errors that InlineArray is not available on macOS < 26. Why is that?

It's hard to understand as a non-compiler engineer why e.g. Span is available from the 6.2-snapshot toolchain on macOS, but InlineArray is not. InlineArray seems pretty low level and does not seem to require specific runtime support etc., so is this just an oversight?

Thanks for any insights you might be able to provide.

Span was specifically backported with a compatibility library, InlineArray was not. Someone from Apple will have to explain why, but one reason may be that InlineArray has runtime requirements and Span doesn’t.

2 Likes

It seems to me that it requires specific runtime support:

1 Like

There is currently no general mechanism to backward deploy new nominal types that were added to the standard library; Span was cooked up as a special case.

While that special case might generalize in the future, InlineArray presents another challenge because of integer generic parameters (whereas Span is just a plain old generic struct).

@Alejandro can correct me if I’m wrong but I don’t think there is any easy way to support nominal types with integer generic parameters on older runtimes.

There was a similar situation when parameter packs were added in Swift 5.9; there’s simply no way to get a generic nominal type with a parameter pack to work on an older runtime.

7 Likes

Thanks a lot @Slava_Pestov, that is helpful.

To explain a little more: I don’t care about forwards or backwards compatibility in this particular case. I’m developing a Postgres extension that will ultimately be deployed on Linux, not Mac.

Is there no „I don’t care“ switch that allows me to build and test this on Mac without using the system runtime libs? I could use a Linux container, but it seems like overkill for my use case. It feels weird that Mac is a worse development environment than Linux for this.

If you use a downloadable toolchain from swift.org, you can play tricks with DYLD_LIBRARY_PATH and/or the -rpath linker flag (I don’t remember the exact incarnation; I’m not near a computer right now, sorry) to have your binary link with the standard library in the toolchain instead of the OS. Once you get that working, you can then run swiftc with -disable-availability-checking and use any standard library declaration you want without restriction.

4 Likes

Don’t forget about the implementation differences between the macOS and Linux Foundation/stdlib. If you’re not planning to ship for macOS at all, you might want to use a container to avoid that.

3 Likes

This is exactly what I was after, thank you! Will try it out and report back.

@ksluder I’m not using Foundation at all. Curious what stdlib differences you have in mind but I’m pretty used to cross-platform swift dev so I’m not too concerned about this point.

1 Like

Ok, building with swift build ... -Xlinker -rpath -Xlinker /Users/myuser/Library/Developer/Toolchains/etc didn't have any effect so I gave up on that direction.

I tried with this for an hour or so with some other directions but couldn't get much further than this:

install_name_tool -change /usr/lib/swift/libswiftCore.dylib @rpath/libswiftCore.dylib .build/release/libMyLibrary.dylib

That indeed forces my library to load libswiftCore from ./ -> copying that library into the desired location simply crashes on load though. Maybe I need to do the same with more libraries. Since it's a postgres extension I'm working in the dark a bit.

I will see if I can get it running with a standalone executable tomorrow, and will hopefully get a stack trace or some clearer indication of the issue. Any magic invocations in the meantime would be much appreciated!

You don't need any of the complicated build flags. As long as you build your executable against the toolchain's SDK, you can run the program with DYLD_LIBRARY_PATH=/path/to/toolchain.xctoolchain/usr/lib/swift/macosx ./my_program

1 Like

This is a context where Visual Studio Code + Devcontainers can give you a very nice development experience. Essentially, you just stop locally developing on macOS entirely, instead using a container runtime to give you a Linux environment.

3 Likes

Thanks @alejandro, it's just a bit trickier because I'm building a dynamic library, not an executable. The dynamic library is loaded by the postgresql server.

Starting the postgres server via DYLD_LIBRARY_PATH=... brew services run postgresql@17 does not have any effect (nor does exporting the variable first and then starting the server).

So, I think if it's going to be macOS it'll have to be complicated build flags (or waiting another couple of months for 26 to be released..)

I don't think brew services starts the service from the same shell to inherit your env vars, you'll have to tweak services settings. Search for something like "brew services environment variable" on Stack Exchange etc. Seems like there are some solutions, but from a cursory search unclear how reliable they are. And there should be a way to start postgres directly from a shell invocation without using brew services run in the first place.

1 Like

Thanks @Max_Desiatov you're right.

It's a very niche problem I'm trying to solve, but for anyone else who runs into this, I was able to get the extension working in this way by starting postgres with the following command (instead of with brew):

LC_ALL=C DYLD_LIBRARY_PATH="$HOME/Library/Developer/Toolchains/swift-6.2-DEVELOPMENT-SNAPSHOT-2025-08-01-a.xctoolchain/usr/lib/swift/macosx" postgres -D /opt/homebrew/var/postgresql@17

Thanks again @Max_Desiatov @Alejandro @Slava_Pestov!

4 Likes