A Flutter plugin of Clash, support Windows/Mac/Android/iOS.
Extract clash core from FClash.
Using ffigen to create bridge tween clash core and dart.
- Requires Golang >= 1.2
- Requires
mingw-w64for build Windows dll from mac. - Requires
FiloSottile/musl-cross/musl-crossfor build Linux so from mac.
cd fclash
./build_libclash.shIt will print like so
Building libclash.dylib
Building libclash.dll
Building libclash.so
./dist/libclash.dll: PE32+ executable (DLL) (console) x86-64 (stripped to external PDB), for MS Windows
./dist/libclash.h: c program text, ASCII text
./dist/android/armeabi-v7a/libclash.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, Go BuildID=***, stripped
./dist/android/arm64-v8a/libclash.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, Go BuildID=***, stripped
./dist/libclash.dylib: Mach-O 64-bit dynamically linked shared library x86_64- It will create
libclash.dll,libclash.dylib,libclash.so,Libclash.xcframeworkandlibclash.hinfclash/distdirectory.
- Requires LLVM (Installing LLVM)
dart run ffigen- Add
libclash.dylibintoRunner/Frameworks(you can uncheckCopy items if neededif you want). - Set to
Embed & Signoflibclash.dylibinTARGETS > Runner > General > Frameworks, Libraries, and Embedded content. - Add
libclash.dylibintoTARGETS > Runner > Build Phases > Copy Bundle Resources. - Change the status of
libclash.dylibintoOptionalinTARGETS > Runner > Build Phases > Link Binary With Libraries. - Add path which
libclash.dylibcan be found at (typically$(PROJECT_DIR)/../fclash/dist) intoTARGETS > Runner > Build Settings > Search Paths > Library Search Paths. - Remove App sand box in
TARGETS > Signing & Capabilitiesif you want to set as system proxy. - Set
TARGETS > Runner > Build Settings > Architectures > Architecturesintox86_64(because libclash.dylib is only built for x86_64).
- Add these into
windows/CMakeList.txt, thePATH_TO_LIBCLASH.DLLtypically is../fclash/dist/libclash.dll.# Install libclash install(FILES "PATH_TO_LIBCLASH.DLL" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime)
- Set
minSdkVersionto19in app-levelbuild.gradle. - Modify app-level
build.gradleandroid { defaultConfig { ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' } // ... } // ... }
- Recommend to set all targets
Minimum Developments>=15.0due to the 15MB RAM limitation on lower iOS.
- Create a
NetworkExtensiontarget namedPacketTunnel, the XCode will auto create a file namedPacketTunnelProvider.swift. - Create a
Frameworktarget namedClashClient, the XCode will auto create a Group(folder) namedClashClient. - Add
LibClash.xcframeworkinto project by right click onProject Navigator > Runner > Frameworksand selectAdd Files to "Runner", with Copy if needed checked. - Add
ClashClient.frameworkintoTARGET > Runner > General > Frameworks, Libraries, and Embedded contentwithEmbed & Sign. - Add
ClashClient.frameworkintoTARGET > PacketTunnel > General > Frameworks, Libraries, and Embedded contentwithDo Not Embed. - Add
PacketTunnel.appexintoTARGET > Runner > General > Frameworks, Libraries, and Embedded contentwithEmbed Without Signing. - Add
Libclash.xcframeworkintoTARGET > ClashClient > General > Frameworks, Libraries, and Embedded contentwithDo Not Embed. - Add
Tun2SocksKit-mainintoPacketTunnelbySwift Package Manager (SPM)from https://github.com/EbrahimTahernejad/Tun2SocksKit with bothTun2SocksKitandTun2SocksKitClibs. - Add
Network Extensionboth inRunnerandPacketTunnel'sSigning & Capabilitiestab.- Check
Packet Tunnel.
- Check
- Add
App Groupsboth inRunnerandPacketTunnel'sSigning & Capabilitiestab.- Check
group.<yourBundleId>
- Check
- Check all targets'
Minimum Developmentsare the same.
- Delete
ClashClient/ClashClient.h. - Copy and add all files of
example/ios/ClashClient/toClashClienttarget. - Copy and add all files of
example/ios/ClashService/toRunnertarget. - Copy
example/ios/PacketTunnel/PacketTunnelProvider.swifttoPacketTunneltarget. - Modify
AppDelegate.swift- Add
MethodHandler.register(with: self.registrar(forPlugin: MethodHandler.name)!).
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) MethodHandler.register(with: self.registrar(forPlugin: MethodHandler.name)!) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
- Add
Some features on iOS may be difference to other platform
because Clash must be running on Network Extensions
so I made a dummy Clash running on App for yaml resolving, delay testing, and a true Clash running on Network Extension for packet tunneling
unsupported features
- startLog/stopLog (no logStream, only in Console.app)
- getConnection
- closeConnection
- closeAllConnection
- Move
Embed Foundation Extensionsabove toRun ScriptinRunner'sBuild Phases.
- Edit Scheme, uncheck
Debug executable(but will causeflutter runfailure).