Commit 20305250 authored by Drew's avatar Drew

Emit iOS Xcodeprojects

parent bd7cd1b0
Pipeline #1707 passed with stage
......@@ -34,10 +34,16 @@
:script "mv .atllbuild/products/xcode_emit .atllbuild/products/xcode-emit"
}
:ioscheck {
:tool "shell"
:dependencies ["xcodeemit"]
:script "cd tests/fixtures/ios && ../../../.atllbuild/products/xcode-emit ios --platform ios"
}
:check {
:tool "shell"
:script ".atllbuild/products/xcode-emit xcodeemit"
:dependencies ["default"]
:dependencies ["default" "ioscheck"]
}
}
......
......@@ -17,6 +17,7 @@ import Foundation
enum OutputType {
case Executable
case StaticLibrary
case Application
}
import atpkg
......@@ -47,7 +48,10 @@ func process(tasks: [Task], package: Package) -> [PbxprojSerializable] {
//emit the pbxproj
let outputType : OutputType
if task["output-type"]?.string == "executable" {
outputType = .Executable
if iosPlatform {
outputType = .Application
}
else { outputType = .Executable }
}
else if task["output-type"]?.string == "static-library" {
outputType = .StaticLibrary
......@@ -81,8 +85,14 @@ func process(tasks: [Task], package: Package) -> [PbxprojSerializable] {
}
}
}
let product = PbxProductReference(name: taskname)
let type :PbxProductReference.ReferenceType
if iosPlatform {
type = PbxProductReference.ReferenceType.Application
}
else {
type = PbxProductReference.ReferenceType.Executable
}
let product = PbxProductReference(name: taskname, type:type)
let sourceRefs = sources.map() {PbxSourceFileReference(path:$0)}
......@@ -93,6 +103,9 @@ func process(tasks: [Task], package: Package) -> [PbxprojSerializable] {
for sourceRef in sourceRefs {
objects.append(sourceRef)
}
for file in target.otherFiles {
objects.append(file)
}
return objects
}
......
......@@ -33,6 +33,11 @@ if Process.arguments[1] == "--help" {
usage()
exit(1)
}
for (x,arg) in Process.arguments.enumerated() {
if arg == "--platform" && Process.arguments[x+1] == "ios" {
iosPlatform = true
}
}
let taskName = Process.arguments[1]
......
......@@ -13,6 +13,10 @@
// limitations under the License.
import Foundation
var iosPlatform = false
private func xcodeguid() -> String {
let choices = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]
var guid = ""
......@@ -153,7 +157,13 @@ struct PbxConfigurationHacks : PbxprojSerializable {
s += " MACOSX_DEPLOYMENT_TARGET = 10.11;\n"
s += " MTL_ENABLE_DEBUG_INFO = YES;\n"
s += " ONLY_ACTIVE_ARCH = YES;\n"
s += " SDKROOT = macosx;\n"
if iosPlatform {
s += " SDKROOT = iphoneos;\n"
s += " \"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n"
}
else {
s += " SDKROOT = macosx;\n"
}
s += " SWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n"
s += " };\n"
s += " name = Debug;\n"
......@@ -190,7 +200,13 @@ struct PbxConfigurationHacks : PbxprojSerializable {
s += " GCC_WARN_UNUSED_VARIABLE = YES;\n"
s += " MACOSX_DEPLOYMENT_TARGET = 10.11;\n"
s += " MTL_ENABLE_DEBUG_INFO = NO;\n"
s += " SDKROOT = macosx;\n"
if iosPlatform {
s += " SDKROOT = iphoneos;\n"
s += " \"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n"
}
else {
s += " SDKROOT = macosx;\n"
}
s += " };\n"
s += " name = Release;\n"
s += "};\n"
......@@ -241,6 +257,9 @@ struct PbxGroups : PbxprojSerializable {
for file in target.target.sourceFiles {
s += " \(file.guid) /* \(file.path) */,\n"
}
for file in target.target.otherFiles {
s += " \(file.guid) /* \(file.path) */,\n"
}
s += " );\n"
s += " path = \".\";\n"
s += " name = \"\(target.target.name)\";\n"
......@@ -259,7 +278,10 @@ struct PbxNativeTarget: PbxprojSerializable {
let outputType: OutputType
let sourceFiles: [PbxSourceFileReference]
let linkFiles: [PbxProductReference]
let configurationList = PbxTargetConfigurations()
let configurationList: PbxTargetConfigurations
//todo: This should be a more generic type than plists
let otherFiles: [PbxPlistFileReference]
let phases: PbxPhases
......@@ -269,6 +291,44 @@ struct PbxNativeTarget: PbxprojSerializable {
self.phases = PbxPhases(sourceFiles: sourceFiles, linkFiles: linkFiles)
self.sourceFiles = sourceFiles
self.linkFiles = linkFiles
if outputType == OutputType.Application {
var s = ""
s += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
s += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
s += "<plist version=\"1.0\">\n"
s += "<dict>\n"
s += " <key>CFBundleDevelopmentRegion</key>\n"
s += " <string>en</string>\n"
s += " <key>CFBundleExecutable</key>\n"
s += " <string>$(EXECUTABLE_NAME)</string>\n"
s += " <key>CFBundleIdentifier</key>\n"
s += " <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n"
s += " <key>CFBundleInfoDictionaryVersion</key>\n"
s += " <string>6.0</string>\n"
s += " <key>CFBundleName</key>\n"
s += " <string>$(PRODUCT_NAME)</string>\n"
s += " <key>CFBundlePackageType</key>\n"
s += " <string>APPL</string>\n"
s += " <key>CFBundleShortVersionString</key>\n"
s += " <string>1.0</string>\n"
s += " <key>CFBundleSignature</key>\n"
s += " <string>????</string>\n"
s += " <key>CFBundleVersion</key>\n"
s += " <string>1</string>\n"
s += " <key>LSRequiresIPhoneOS</key>\n"
s += " <true/>\n"
s += "</dict>\n"
s += "</plist>\n"
let plistName = "\(productReference.name)-xcode-emit-Info.plist"
try! s.write(toFile: plistName, atomically: false, encoding: NSUTF8StringEncoding)
self.otherFiles = [PbxPlistFileReference(path: plistName)]
self.configurationList = PbxTargetConfigurations(plistPath: plistName)
}
else {
self.configurationList = PbxTargetConfigurations(plistPath: nil)
self.otherFiles = []
}
}
func serialize() -> String {
var s = ""
......@@ -295,6 +355,8 @@ struct PbxNativeTarget: PbxprojSerializable {
case .StaticLibrary:
print("Warning: working around rdar://24221024")
s += " productType = \"com.apple.product-type.library.dynamic\";"
case .Application:
s += " productType = \"com.apple.product-type.application\";\n"
}
s += "};\n"
s += "/* End PBXNativeTarget section */\n"
......@@ -310,7 +372,23 @@ struct PbxTargetConfigurations: PbxprojSerializable {
let guid = xcodeguid()
let debugGUID = xcodeguid()
let releaseGUID = xcodeguid()
let plistPath: String?
func serialize() -> String {
//these settings are used several times
var sx = ""
sx += " PRODUCT_NAME = \"$(TARGET_NAME)\";\n"
//particularly when building a dynamic library, we need to tell Swift where to find its standard library
//@executable_path/Frameworks is for iOS/app bundles
sx += " LD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks /Library/Developer/Toolchains/swift-latest.xctoolchain/usr/lib/swift/macosx/\";\n"
//once we give it its standard library dynamically, let's force the executable not to include it.
sx += " SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES;\n"
if let plistPath = self.plistPath {
sx += " INFOPLIST_FILE = \(plistPath);\n"
}
sx += " PRODUCT_BUNDLE_IDENTIFIER = org.anarchytools.XcodeEmittedApp;\n"
var s = ""
s += "\(guid) /* Build configuration list for PBXNativeTarget */ = {\n"
s += " isa = XCConfigurationList;\n"
......@@ -323,20 +401,14 @@ struct PbxTargetConfigurations: PbxprojSerializable {
s += "\(debugGUID) /* Debug */ = {\n"
s += " isa = XCBuildConfiguration;\n"
s += " buildSettings = {\n"
s += " PRODUCT_NAME = \"$(TARGET_NAME)\";\n"
//particularly when building a dynamic library, we need to tell Swift where to find its standard library
s += " LD_RUNPATH_SEARCH_PATHS = \"/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/lib/swift/macosx/\";\n"
//once we give it its standard library dynamically, let's force the executable not to include it.
s += " SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES;\n"
s += sx
s += " };\n"
s += " name = Debug;\n"
s += "};\n"
s += "\(releaseGUID) /* Release */ = {\n"
s += " isa = XCBuildConfiguration;\n"
s += " buildSettings = {\n"
s += " PRODUCT_NAME = \"$(TARGET_NAME)\";\n"
//todo: do we need this?
//s += " SWIFT_INCLUDE_PATHS = .atllbuild/products/;\n"
s += sx
s += " };\n"
s += " name = Release;\n"
s += "};\n"
......@@ -393,15 +465,33 @@ struct PbxPhases: PbxprojSerializable {
}
struct PbxProductReference: PbxprojSerializable {
enum ReferenceType: String {
case Executable = "compiled.mach-o.executable"
case Application = "wrapper.application"
}
let name: String
let guid = xcodeguid()
let buildFile: PbxBuildFile
init(name: String) {
let type: ReferenceType
private var path: String {
switch(type){
case .Executable:
return name
case .Application:
return "\(name).app"
}
}
init(name: String, type: ReferenceType) {
self.name = name
self.buildFile = PbxBuildFile(path: name, fileRefGUID: guid)
self.type = type
}
func serialize() -> String {
var s = "\(guid) /* \(name) */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.executable\"; includeInIndex = 0; path = \(name); sourceTree = BUILT_PRODUCTS_DIR; };\n"
var s = "\(guid) /* \(name) */ = {isa = PBXFileReference; explicitFileType = \"\(self.type.rawValue)\"; includeInIndex = 0; path = \(path); sourceTree = BUILT_PRODUCTS_DIR; };\n"
s += buildFile.serialize()
return s
}
......@@ -431,6 +521,18 @@ struct PbxStaticLibraryFileReference: PbxprojSerializable {
}
}
struct PbxPlistFileReference: PbxprojSerializable {
let path: String
let guid = xcodeguid()
init(path: String) {
self.path = path
}
func serialize() -> String {
var s = "\(guid) /* \(path) */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = \(path); path = \(path); sourceTree = \"<group>\"; };"
return s
}
}
struct PbxSourceFileReference: PbxprojSerializable {
let path: String
let guid = xcodeguid()
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>15E65</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>main</string>
<key>CFBundleIdentifier</key>
<string>com.dca.SmallestiOSApp</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>SmallestiOSApp</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneSimulator</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string></string>
<key>DTPlatformName</key>
<string>iphonesimulator</string>
<key>DTPlatformVersion</key>
<string>9.3</string>
<key>DTSDKBuild</key>
<string>13E230</string>
<key>DTSDKName</key>
<string>iphonesimulator9.3</string>
<key>DTXcode</key>
<string>0730</string>
<key>DTXcodeBuild</key>
<string>7D175</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
<string>9.3</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
</dict>
</plist>
;; Copyright (c) 2016 Anarchy Tools Contributors.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http:;;www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; The build file for all of the targets of the Anarchy Tools build tool.
(package
:name "ios"
:tasks {
:ios {
:tool "atllbuild"
:sources ["src/**.swift"]
:name "main"
:output-type "executable"
}
}
)
print("hello world!")
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment