swiftc main.swift -emit-module-path main.swiftmodule -emit-executable -enable-private-imports -Xfrontend -enable-implicit-dynamic
./main
-> printsFrom original bar()
swiftc -emit-library inject.swift -o inject.dylib -I . -Xlinker -undefined -Xlinker suppress -Xlinker -flat_namespace -Xfrontend -disable-access-control
DYLD_INSERT_LIBRARIES=inject.dylib ./main
-> printsFrom replacement bar()
- Passing
-Xfrontend -enable-implicit-dynamic
removes you from having to adddynamic
to everything you want to be replacable - Passing
-enable-private-imports
to themain.swift
build, and then-Xfrontend -disable-access-control
to the dylib build stops you from having to make thingspublic
unnecessarily. Depending on the use case if the symbols arepublic
already you could remove these flags - The dylib compilation depends on the main module. I was hoping I could use a string or something instead and specify
main.Foo.bar
explicitly instead of having to dependmain
directly for building - There must be a better way than passing
-undefined suppress -flat_namespace
to the linker for the dylib compilation. You could pass-U SYMBOL
but I think that's a bit more annoying to track down and maintain
Useful reference: https://tech.guardsquare.com/posts/swift-native-method-swizzling