├── .gitignore ├── README.md ├── compile_ios.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── .gitignore └── xcuserdata │ └── adrianlabbe.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── compile_ios ├── RunExecutable.swift ├── gfortran │ └── gfortran.swift ├── iosenv │ ├── iosenv.swift │ └── sdkPath.swift ├── iosxcrun │ └── iosxcrun.swift └── main.swift └── install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | ._DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # compile_ios 2 | 3 | This command line program for Mac sets needed environment variables for compiling a C project for iOS arm64. 4 | 5 | Great for build Python modules with C shared libraries. 6 | 7 | ## Requirements 8 | 9 | macOS 10.9+ with Xcode and command line tools installed. 10 | 11 | ## Installation 12 | 13 | $ ./install.sh 14 | 15 | This will install the command. 16 | 17 | ## Usage 18 | 19 | $ iosenv 20 | 21 | `iosenv` command will open a shell, you can then build a C project from it for iOS. 22 | 23 | Projects wil not magically compile! This is just a helper, you will probably need to modify some environment variables to include other Header Search Paths. 24 | 25 | ## Build result 26 | 27 | iOS arm64 (iPhone 5S+, iPad Air+, iPod Touch 6G) binaries. Not for iOS simulator! 28 | 29 | ## Tested with 30 | 31 | - NumPy 32 | - Pandas 33 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C91380DA2463742400AA0935 /* gfortran.swift in Sources */ = {isa = PBXBuildFile; fileRef = C91380D92463742400AA0935 /* gfortran.swift */; }; 11 | C94A283121DAC7D700EDF855 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94A283021DAC7D700EDF855 /* main.swift */; }; 12 | C94A283E21DACB0500EDF855 /* iosenv.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94A283D21DACB0500EDF855 /* iosenv.swift */; }; 13 | C94A284021DACBA400EDF855 /* sdkPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94A283F21DACBA400EDF855 /* sdkPath.swift */; }; 14 | C94A284221DACE5C00EDF855 /* iosxcrun.swift in Sources */ = {isa = PBXBuildFile; fileRef = C94A284121DACE5C00EDF855 /* iosxcrun.swift */; }; 15 | C9E74E4521DBC0C20091FAF7 /* RunExecutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9E74E4421DBC0C20091FAF7 /* RunExecutable.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | C94A282B21DAC7D700EDF855 /* CopyFiles */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = /usr/share/man/man1/; 23 | dstSubfolderSpec = 0; 24 | files = ( 25 | ); 26 | runOnlyForDeploymentPostprocessing = 1; 27 | }; 28 | /* End PBXCopyFilesBuildPhase section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | C91380D92463742400AA0935 /* gfortran.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = gfortran.swift; sourceTree = ""; }; 32 | C94A282D21DAC7D700EDF855 /* compile_ios */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = compile_ios; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | C94A283021DAC7D700EDF855 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 34 | C94A283D21DACB0500EDF855 /* iosenv.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = iosenv.swift; sourceTree = ""; }; 35 | C94A283F21DACBA400EDF855 /* sdkPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sdkPath.swift; sourceTree = ""; }; 36 | C94A284121DACE5C00EDF855 /* iosxcrun.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = iosxcrun.swift; sourceTree = ""; }; 37 | C9E74E4421DBC0C20091FAF7 /* RunExecutable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunExecutable.swift; sourceTree = ""; }; 38 | /* End PBXFileReference section */ 39 | 40 | /* Begin PBXFrameworksBuildPhase section */ 41 | C94A282A21DAC7D700EDF855 /* Frameworks */ = { 42 | isa = PBXFrameworksBuildPhase; 43 | buildActionMask = 2147483647; 44 | files = ( 45 | ); 46 | runOnlyForDeploymentPostprocessing = 0; 47 | }; 48 | /* End PBXFrameworksBuildPhase section */ 49 | 50 | /* Begin PBXGroup section */ 51 | C91380D82463740F00AA0935 /* gfortran */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | C91380D92463742400AA0935 /* gfortran.swift */, 55 | ); 56 | path = gfortran; 57 | sourceTree = ""; 58 | }; 59 | C94A282421DAC7D700EDF855 = { 60 | isa = PBXGroup; 61 | children = ( 62 | C94A282F21DAC7D700EDF855 /* compile_ios */, 63 | C94A282E21DAC7D700EDF855 /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | C94A282E21DAC7D700EDF855 /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | C94A282D21DAC7D700EDF855 /* compile_ios */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | C94A282F21DAC7D700EDF855 /* compile_ios */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | C94A283021DAC7D700EDF855 /* main.swift */, 79 | C9E74E4421DBC0C20091FAF7 /* RunExecutable.swift */, 80 | C91380D82463740F00AA0935 /* gfortran */, 81 | C94A283B21DACADD00EDF855 /* iosxcrun */, 82 | C94A283C21DACAE300EDF855 /* iosenv */, 83 | ); 84 | path = compile_ios; 85 | sourceTree = ""; 86 | }; 87 | C94A283B21DACADD00EDF855 /* iosxcrun */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | C94A284121DACE5C00EDF855 /* iosxcrun.swift */, 91 | ); 92 | path = iosxcrun; 93 | sourceTree = ""; 94 | }; 95 | C94A283C21DACAE300EDF855 /* iosenv */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | C94A283D21DACB0500EDF855 /* iosenv.swift */, 99 | C94A283F21DACBA400EDF855 /* sdkPath.swift */, 100 | ); 101 | path = iosenv; 102 | sourceTree = ""; 103 | }; 104 | /* End PBXGroup section */ 105 | 106 | /* Begin PBXNativeTarget section */ 107 | C94A282C21DAC7D700EDF855 /* compile_ios */ = { 108 | isa = PBXNativeTarget; 109 | buildConfigurationList = C94A283421DAC7D700EDF855 /* Build configuration list for PBXNativeTarget "compile_ios" */; 110 | buildPhases = ( 111 | C94A282921DAC7D700EDF855 /* Sources */, 112 | C94A282A21DAC7D700EDF855 /* Frameworks */, 113 | C94A282B21DAC7D700EDF855 /* CopyFiles */, 114 | C94A284321DAD00D00EDF855 /* Make Symbolic links */, 115 | ); 116 | buildRules = ( 117 | ); 118 | dependencies = ( 119 | ); 120 | name = compile_ios; 121 | productName = compile_ios; 122 | productReference = C94A282D21DAC7D700EDF855 /* compile_ios */; 123 | productType = "com.apple.product-type.tool"; 124 | }; 125 | /* End PBXNativeTarget section */ 126 | 127 | /* Begin PBXProject section */ 128 | C94A282521DAC7D700EDF855 /* Project object */ = { 129 | isa = PBXProject; 130 | attributes = { 131 | LastSwiftUpdateCheck = 1010; 132 | LastUpgradeCheck = 1010; 133 | ORGANIZATIONNAME = "Adrian Labbé"; 134 | TargetAttributes = { 135 | C94A282C21DAC7D700EDF855 = { 136 | CreatedOnToolsVersion = 10.1; 137 | }; 138 | }; 139 | }; 140 | buildConfigurationList = C94A282821DAC7D700EDF855 /* Build configuration list for PBXProject "compile_ios" */; 141 | compatibilityVersion = "Xcode 9.3"; 142 | developmentRegion = en; 143 | hasScannedForEncodings = 0; 144 | knownRegions = ( 145 | en, 146 | ); 147 | mainGroup = C94A282421DAC7D700EDF855; 148 | productRefGroup = C94A282E21DAC7D700EDF855 /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | C94A282C21DAC7D700EDF855 /* compile_ios */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXShellScriptBuildPhase section */ 158 | C94A284321DAD00D00EDF855 /* Make Symbolic links */ = { 159 | isa = PBXShellScriptBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | ); 163 | inputFileListPaths = ( 164 | ); 165 | inputPaths = ( 166 | ); 167 | name = "Make Symbolic links"; 168 | outputFileListPaths = ( 169 | ); 170 | outputPaths = ( 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | shellPath = /bin/sh; 174 | shellScript = "EXECUTABLE=$BUILT_PRODUCTS_DIR/$EXECUTABLE_NAME\nXCRUN=$BUILT_PRODUCTS_DIR/iosxcrun\nENV=$BUILT_PRODUCTS_DIR/iosenv\nFORTRAN=$BUILT_PRODUCTS_DIR/gfortran\n\nln -s \"$EXECUTABLE\" \"$XCRUN\" || true\nln -s \"$EXECUTABLE\" \"$ENV\" || true\n"; 175 | showEnvVarsInLog = 0; 176 | }; 177 | /* End PBXShellScriptBuildPhase section */ 178 | 179 | /* Begin PBXSourcesBuildPhase section */ 180 | C94A282921DAC7D700EDF855 /* Sources */ = { 181 | isa = PBXSourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | C91380DA2463742400AA0935 /* gfortran.swift in Sources */, 185 | C94A284221DACE5C00EDF855 /* iosxcrun.swift in Sources */, 186 | C9E74E4521DBC0C20091FAF7 /* RunExecutable.swift in Sources */, 187 | C94A283121DAC7D700EDF855 /* main.swift in Sources */, 188 | C94A283E21DACB0500EDF855 /* iosenv.swift in Sources */, 189 | C94A284021DACBA400EDF855 /* sdkPath.swift in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXSourcesBuildPhase section */ 194 | 195 | /* Begin XCBuildConfiguration section */ 196 | C94A283221DAC7D700EDF855 /* Debug */ = { 197 | isa = XCBuildConfiguration; 198 | buildSettings = { 199 | ALWAYS_SEARCH_USER_PATHS = NO; 200 | CLANG_ANALYZER_NONNULL = YES; 201 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 202 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 203 | CLANG_CXX_LIBRARY = "libc++"; 204 | CLANG_ENABLE_MODULES = YES; 205 | CLANG_ENABLE_OBJC_ARC = YES; 206 | CLANG_ENABLE_OBJC_WEAK = YES; 207 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 208 | CLANG_WARN_BOOL_CONVERSION = YES; 209 | CLANG_WARN_COMMA = YES; 210 | CLANG_WARN_CONSTANT_CONVERSION = YES; 211 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 213 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 214 | CLANG_WARN_EMPTY_BODY = YES; 215 | CLANG_WARN_ENUM_CONVERSION = YES; 216 | CLANG_WARN_INFINITE_RECURSION = YES; 217 | CLANG_WARN_INT_CONVERSION = YES; 218 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 219 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 220 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 221 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 222 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 223 | CLANG_WARN_STRICT_PROTOTYPES = YES; 224 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 225 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 226 | CLANG_WARN_UNREACHABLE_CODE = YES; 227 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 228 | CODE_SIGN_IDENTITY = "-"; 229 | COPY_PHASE_STRIP = NO; 230 | DEBUG_INFORMATION_FORMAT = dwarf; 231 | ENABLE_STRICT_OBJC_MSGSEND = YES; 232 | ENABLE_TESTABILITY = YES; 233 | GCC_C_LANGUAGE_STANDARD = gnu11; 234 | GCC_DYNAMIC_NO_PIC = NO; 235 | GCC_NO_COMMON_BLOCKS = YES; 236 | GCC_OPTIMIZATION_LEVEL = 0; 237 | GCC_PREPROCESSOR_DEFINITIONS = ( 238 | "DEBUG=1", 239 | "$(inherited)", 240 | ); 241 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 242 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 243 | GCC_WARN_UNDECLARED_SELECTOR = YES; 244 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 245 | GCC_WARN_UNUSED_FUNCTION = YES; 246 | GCC_WARN_UNUSED_VARIABLE = YES; 247 | MACOSX_DEPLOYMENT_TARGET = 10.10; 248 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 249 | MTL_FAST_MATH = YES; 250 | ONLY_ACTIVE_ARCH = YES; 251 | SDKROOT = macosx; 252 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 253 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 254 | }; 255 | name = Debug; 256 | }; 257 | C94A283321DAC7D700EDF855 /* Release */ = { 258 | isa = XCBuildConfiguration; 259 | buildSettings = { 260 | ALWAYS_SEARCH_USER_PATHS = NO; 261 | CLANG_ANALYZER_NONNULL = YES; 262 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 263 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 264 | CLANG_CXX_LIBRARY = "libc++"; 265 | CLANG_ENABLE_MODULES = YES; 266 | CLANG_ENABLE_OBJC_ARC = YES; 267 | CLANG_ENABLE_OBJC_WEAK = YES; 268 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 269 | CLANG_WARN_BOOL_CONVERSION = YES; 270 | CLANG_WARN_COMMA = YES; 271 | CLANG_WARN_CONSTANT_CONVERSION = YES; 272 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 274 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 275 | CLANG_WARN_EMPTY_BODY = YES; 276 | CLANG_WARN_ENUM_CONVERSION = YES; 277 | CLANG_WARN_INFINITE_RECURSION = YES; 278 | CLANG_WARN_INT_CONVERSION = YES; 279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 280 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 281 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 282 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 283 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 284 | CLANG_WARN_STRICT_PROTOTYPES = YES; 285 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 286 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 287 | CLANG_WARN_UNREACHABLE_CODE = YES; 288 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 289 | CODE_SIGN_IDENTITY = "-"; 290 | COPY_PHASE_STRIP = NO; 291 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 292 | ENABLE_NS_ASSERTIONS = NO; 293 | ENABLE_STRICT_OBJC_MSGSEND = YES; 294 | GCC_C_LANGUAGE_STANDARD = gnu11; 295 | GCC_NO_COMMON_BLOCKS = YES; 296 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 297 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 298 | GCC_WARN_UNDECLARED_SELECTOR = YES; 299 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 300 | GCC_WARN_UNUSED_FUNCTION = YES; 301 | GCC_WARN_UNUSED_VARIABLE = YES; 302 | MACOSX_DEPLOYMENT_TARGET = 10.10; 303 | MTL_ENABLE_DEBUG_INFO = NO; 304 | MTL_FAST_MATH = YES; 305 | SDKROOT = macosx; 306 | SWIFT_COMPILATION_MODE = wholemodule; 307 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 308 | }; 309 | name = Release; 310 | }; 311 | C94A283521DAC7D700EDF855 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | CODE_SIGN_STYLE = Automatic; 315 | PRODUCT_NAME = "$(TARGET_NAME)"; 316 | SWIFT_VERSION = 4.2; 317 | }; 318 | name = Debug; 319 | }; 320 | C94A283621DAC7D700EDF855 /* Release */ = { 321 | isa = XCBuildConfiguration; 322 | buildSettings = { 323 | CODE_SIGN_STYLE = Automatic; 324 | PRODUCT_NAME = "$(TARGET_NAME)"; 325 | SWIFT_VERSION = 4.2; 326 | }; 327 | name = Release; 328 | }; 329 | /* End XCBuildConfiguration section */ 330 | 331 | /* Begin XCConfigurationList section */ 332 | C94A282821DAC7D700EDF855 /* Build configuration list for PBXProject "compile_ios" */ = { 333 | isa = XCConfigurationList; 334 | buildConfigurations = ( 335 | C94A283221DAC7D700EDF855 /* Debug */, 336 | C94A283321DAC7D700EDF855 /* Release */, 337 | ); 338 | defaultConfigurationIsVisible = 0; 339 | defaultConfigurationName = Release; 340 | }; 341 | C94A283421DAC7D700EDF855 /* Build configuration list for PBXNativeTarget "compile_ios" */ = { 342 | isa = XCConfigurationList; 343 | buildConfigurations = ( 344 | C94A283521DAC7D700EDF855 /* Debug */, 345 | C94A283621DAC7D700EDF855 /* Release */, 346 | ); 347 | defaultConfigurationIsVisible = 0; 348 | defaultConfigurationName = Release; 349 | }; 350 | /* End XCConfigurationList section */ 351 | }; 352 | rootObject = C94A282521DAC7D700EDF855 /* Project object */; 353 | } 354 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/project.xcworkspace/xcuserdata/.gitignore: -------------------------------------------------------------------------------- 1 | *.xcuserdatad 2 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/xcuserdata/adrianlabbe.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /compile_ios.xcodeproj/xcuserdata/adrianlabbe.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | compile_ios.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /compile_ios/RunExecutable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RunCommand.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbe on 1/1/19. 6 | // Copyright © 2019 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Runs command. 12 | /// 13 | /// - Parameters: 14 | /// - path: The path of the executable to run. 15 | /// - arguments: Arguments passed excluding the executable name. 16 | /// - standardOutput: `Pipe` or `FileHandle` that receives the output. 17 | /// - standardError: `Pipe` or `FileHandle` that receives the errors. 18 | /// - standardInput: `Pipe` or `FileHandle` for writting input. 19 | /// 20 | /// - Returns: The exit code. 21 | @discardableResult func RunExecutable(atPath path: String, withArguments arguments: [String] = [], standardOutput: Any? = FileHandle.standardOutput, standardError: Any? = FileHandle.standardError, standardInput: Any? = FileHandle.standardInput) -> Int { 22 | 23 | let executable = URL(fileURLWithPath: path) 24 | 25 | let p = Process() 26 | if #available(OSX 10.13, *) { 27 | p.executableURL = executable 28 | } else { 29 | p.launchPath = executable.path 30 | } 31 | p.arguments = arguments 32 | p.standardOutput = standardOutput 33 | p.standardError = standardError 34 | p.standardInput = standardInput 35 | 36 | if #available(OSX 10.13, *) { 37 | do { 38 | try p.run() 39 | } catch { 40 | fputs(error.localizedDescription+"\n", stderr) 41 | } 42 | } else { 43 | p.launch() 44 | } 45 | 46 | p.waitUntilExit() 47 | 48 | return Int(p.terminationStatus) 49 | } 50 | -------------------------------------------------------------------------------- /compile_ios/gfortran/gfortran.swift: -------------------------------------------------------------------------------- 1 | // 2 | // gfortran.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbé on 06-05-20. 6 | // Copyright © 2020 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func gfortran_main() { 12 | var arguments = ["-ff2c"] 13 | 14 | for (i, argument) in CommandLine.arguments.enumerated() { 15 | 16 | guard i != 0 else { 17 | continue 18 | } 19 | 20 | guard argument != "arm64" else { 21 | arguments.append("x86_64") 22 | continue 23 | } 24 | 25 | if argument.hasPrefix("-mmacosx-version-min=") || argument.hasPrefix("-mios-version-min=") { 26 | continue 27 | } 28 | 29 | arguments.append(argument) 30 | } 31 | 32 | RunExecutable(atPath: "/usr/local/bin/gfortran-9", withArguments: arguments) 33 | } 34 | -------------------------------------------------------------------------------- /compile_ios/iosenv/iosenv.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ios_environment.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbe on 12/31/18. 6 | // Copyright © 2018 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: - Find SDK path 12 | 13 | /// Opens a shell with environment for compilling projects for iOS 14 | func iosenv_main() { 15 | 16 | guard let iosxcrun = Bundle.main.path(forResource: "iosxcrun", ofType: nil) else { 17 | fputs("Cannot find 'iosxcrun' executable.\n", stderr) 18 | exit(1) 19 | } 20 | 21 | let environment = [ 22 | "CC" : "\(iosxcrun) --sdk iphoneos clang -mios-version-min=12.0 -isysroot \(sdkPath) -arch arm64", 23 | "CXX" : "\(iosxcrun) --sdk iphoneos clang++ -mios-version-min=12.0 -isysroot \(sdkPath) -arch arm64", 24 | 25 | "ARCHFLAGS" : "-arch arm64", 26 | "CFLAGS" : "-arch arm64 -mios-version-min=12.0 -isysroot \(sdkPath)", 27 | "CPPFLAGS" : "-arch arm64 -mios-version-min=12.0 -isysroot \(sdkPath)", 28 | "LDFLAGS" : "-arch arm64 -mios-version-min=12.0 -isysroot \(sdkPath)", 29 | 30 | "IPHONEOS_DEPLOYMENT_TARGET" : "11.0", 31 | 32 | "_PYTHON_HOST_PLATFORM" : "iphoneos-arm64", 33 | ] 34 | 35 | for (key, value) in environment { 36 | print("\(key)=\(value)") 37 | setenv(key, value, 1) 38 | } 39 | 40 | print("\nYou can now compile a C project for iOS from this subshell.\n") 41 | 42 | execv("/bin/bash", nil) 43 | } 44 | -------------------------------------------------------------------------------- /compile_ios/iosenv/sdkPath.swift: -------------------------------------------------------------------------------- 1 | // 2 | // sdkPath.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbe on 12/31/18. 6 | // Copyright © 2018 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Returns the iOS sdk path. 12 | var sdkPath: String = { 13 | var sdkPath: String? 14 | 15 | let sdkPipe = Pipe() 16 | sdkPipe.fileHandleForReading.readabilityHandler = { handle in 17 | if let str = String(data: handle.availableData, encoding: .utf8)?.replacingOccurrences(of: "\n", with: ""), FileManager.default.fileExists(atPath: str) { 18 | sdkPath = str 19 | } 20 | } 21 | 22 | let findSDK = RunExecutable(atPath: "/usr/bin/xcrun", withArguments: ["--sdk", "iphoneos", "--show-sdk-path"], standardOutput: sdkPipe) 23 | 24 | guard findSDK == 0, sdkPath != nil else { 25 | fputs("Cannot find SDK!\n", stderr) 26 | exit(1) 27 | } 28 | 29 | return sdkPath! 30 | }() 31 | -------------------------------------------------------------------------------- /compile_ios/iosxcrun/iosxcrun.swift: -------------------------------------------------------------------------------- 1 | // 2 | // compile.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbe on 12/31/18. 6 | // Copyright © 2018 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Filters arguments and pass them to `xcrun` to exclude Mac architecture. 12 | func iosxcrun_main() { 13 | var arguments = [String]() 14 | 15 | for (i, argument) in CommandLine.arguments.enumerated() { 16 | 17 | guard i != 0 else { 18 | continue 19 | } 20 | 21 | guard argument != "f95" else { 22 | arguments.append("c") 23 | continue 24 | } 25 | 26 | guard argument != "-arch" else { 27 | if CommandLine.arguments.indices.contains(i+1), CommandLine.arguments[i+1] == "arm64" { 28 | arguments.append(argument) 29 | } 30 | continue 31 | } 32 | 33 | guard argument != "-isysroot" else { 34 | if CommandLine.arguments.indices.contains(i+1) { 35 | arguments.append(argument) 36 | arguments.append(sdkPath) 37 | } 38 | continue 39 | } 40 | 41 | guard !argument.lowercased().contains("macosx") else { 42 | continue 43 | } 44 | 45 | guard argument != "x86_64" else { 46 | continue 47 | } 48 | 49 | guard argument != "-bundle" else { 50 | arguments.append("-dynamiclib") 51 | continue 52 | } 53 | 54 | if argument.contains("MacOSX.platform") { 55 | continue 56 | } 57 | 58 | if argument.hasPrefix("-mmacosx-version-min=") { 59 | continue 60 | } 61 | 62 | if (URL(fileURLWithPath: argument)).pathExtension == "sdk" { 63 | guard arguments.indices.contains(i-1) && arguments[i-1] == "-isysroot" else { 64 | print("Ignored alone SDK Path") 65 | continue 66 | } 67 | print("SDK Path detected") 68 | } 69 | 70 | if argument == "-framework" { 71 | if CommandLine.arguments.indices.contains(i+1), CommandLine.arguments[i+1] == "Cocoa" { 72 | continue 73 | } 74 | } 75 | 76 | if argument == "Cocoa" { 77 | if CommandLine.arguments.indices.contains(i-1), CommandLine.arguments[i-1] == "-framework" { 78 | continue 79 | } 80 | } 81 | 82 | arguments.append(argument) 83 | } 84 | 85 | print("Command: xcrun \(arguments.joined(separator: " "))") 86 | 87 | RunExecutable(atPath: "/usr/bin/xcrun", withArguments: arguments) 88 | } 89 | -------------------------------------------------------------------------------- /compile_ios/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // compile_ios 4 | // 5 | // Created by Adrian Labbe on 12/31/18. 6 | // Copyright © 2018 Adrian Labbé. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | switch URL(fileURLWithPath: CommandLine.arguments[0]).lastPathComponent { 12 | case "iosxcrun": iosxcrun_main() 13 | case "iosenv": iosenv_main() 14 | case "gfortran": gfortran_main() 15 | default: 16 | fputs("Unknown program name! Run 'iosxcrun', 'iosenv' or 'gfortran'.\n", stderr) 17 | exit(1) 18 | } 19 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd `dirname "$0"` 4 | 5 | PRODUCTS="build/Build/Products/Release" 6 | OUTPUT="/usr/local/bin" 7 | 8 | xcodebuild -scheme "compile_ios" -configuration Release -derivedDataPath build build 9 | 10 | if [ $? -eq 0 ]; then 11 | rm "$OUTPUT/compile_ios" || true 12 | cp "$PRODUCTS/compile_ios" "$OUTPUT/" 13 | 14 | rm "$OUTPUT/iosenv" || true 15 | cp "$PRODUCTS/iosenv" "$OUTPUT/" 16 | 17 | rm "$OUTPUT/iosxcrun" || true 18 | cp "$PRODUCTS/iosxcrun" "$OUTPUT/" 19 | fi 20 | --------------------------------------------------------------------------------