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-controlDYLD_INSERT_LIBRARIES=inject.dylib ./main-> printsFrom replacement bar()
- Passing
-Xfrontend -enable-implicit-dynamicremoves you from having to adddynamicto everything you want to be replacable - Passing
-enable-private-importsto themain.swiftbuild, and then-Xfrontend -disable-access-controlto the dylib build stops you from having to make thingspublicunnecessarily. Depending on the use case if the symbols arepublicalready 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.barexplicitly instead of having to dependmaindirectly for building - There must be a better way than passing
-undefined suppress -flat_namespaceto the linker for the dylib compilation. You could pass-U SYMBOLbut I think that's a bit more annoying to track down and maintain
Useful reference: https://tech.guardsquare.com/posts/swift-native-method-swizzling