Skip to content

Get things building #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
env:
global:
- LC_CTYPE=en_US.UTF-8
matrix:
include:
- os: osx
language: objective-c
osx_image: xcode8.2
before_install:
- export PATH=/usr/local/opt/llvm/bin:"${PATH}"
- brew install llvm
- sudo swift utils/make-pkgconfig.swift
script:
- swift test
notifications:
slack:
secure: ek/+U+e44bqP8+QCHojy2LhrN9iwY3N/TNNqNG5FZrp09Vidrd5KXWJOXFxlGrpeWdgTpi089YbEdTfxpcDIudUqDqLwPzS7wePiG2cEC1OT6l3yrhI4AvOe7EsNSOX8gzkuEnmrZVHwLLGe7JeR7JIQKoHMZsBcPYDnO8kRP0Ei3zOh47YUn75SE87egAgZOVBDbZYO3GWRa4WX64s8gaQYQ9a7EoUY0oX9rQ48FJs3rmEIhvIXdcOj9bGX7+o0j7l+IFial/Qh+B6bp4XkZU/tUVP6cuNVI1vxE1weVGCBhgt5wLhXTMewzoE5D1IgMZHVuzIBcDbBthSzQRttLSlYar6xTjXtRtOnb8tqZMWfUj3HBYCFYqtz7PGnZ3IflEVsPJW6tgSsoeB6egjzb8APP9mvhm8+zb1jQG1dqXLWErMjWqhlyPVPmHrxU2w/OLWLAJPY94GVmLnSuOw2pSz41spuEY80JcVVzoRbAOQWrwAujq2S3k93yvKpGq4eaT72Mt8g1CyZesByvzcLk99LEJSpqOIxUqXBd4RwHhay/sq8LllyyqY8ORsxEgwQluOAjEhATO/t/HUsu2ndn1k38U1c4HqXW7FDs1hffYEzZ/PGxciCS6Vt1bfST+iq34pzqpanENQCnX6mSR+D+M7mHlCWdsUihmxEcs5knuM=
12 changes: 12 additions & 0 deletions Package.pins
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"autoPin": true,
"pins": [
{
"package": "cclang",
"reason": null,
"repositoryURL": "https://github.com/trill-lang/cclang",
"version": "0.0.1"
}
],
"version": 1
}
29 changes: 14 additions & 15 deletions Sources/Clang/EvalResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,55 @@ import cclang
#endif

protocol EvalResultKind {
var clang: CXEvalResultKind { get }
var clang: CXEvalResult { get }
}

public struct IntResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
public var value: Int {
return Int(clang_EvalResult_getAsInt(clang))
}
}

public struct FloatResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
public var value: Double {
return Int(clang_EvalResult_getAsDouble(clang))
return Double(clang_EvalResult_getAsDouble(clang))
}
}

public struct ObjCStrLiteralResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
public var value: String {
return String(cString: clang_EvalResult_getAsString(clang))
return String(cString: clang_EvalResult_getAsStr(clang))
}
}

public struct StrLiteralResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
public var value: String {
return String(cString: clang_EvalResult_getAsString(clang))
return String(cString: clang_EvalResult_getAsStr(clang))
}
}

public struct CFStrResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
public var value: String {
return String(cString: clang_EvalResult_getAsString(clang))
return String(cString: clang_EvalResult_getAsStr(clang))
}
}

public struct OtherResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
}

public struct UnExposedResult: EvalResultKind {
let clang: CXEvalResultKind
let clang: CXEvalResult
}

/// Converts a CXEvalResultKind to a EvalResultKind, returning `nil` if it was unsuccessful
func convertEvalResultKind(_ clang: CXEvalResultKind) -> EvalResultKind? {
if <#clang thing is null?#> { return nil }
switch <#Get clang kind#> {
func convertEvalResultKind(_ clang: CXEvalResult) -> EvalResultKind? {
switch clang_EvalResult_getKind(clang) {
case CXEval_Int: return IntResult(clang: clang)
case CXEval_Float: return FloatResult(clang: clang)
case CXEval_ObjCStrLiteral: return ObjCStrLiteralResult(clang: clang)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Clang/Utilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ extension CXString {
}

extension Collection where Iterator.Element == String, IndexDistance == Int {
func withUnsafeCStringBuffer<Result>(_ f: (UnsafeMutableBufferPointer<UnsafePointer<Int8>?>) throws -> Result) rethrows -> Result {
func withUnsafeCStringBuffer<Result>(_ f: @escaping (UnsafeMutableBufferPointer<UnsafePointer<Int8>?>) throws -> Result) rethrows -> Result {
let ptr = UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.allocate(capacity: self.count)
defer { freelist(ptr, count: self.count) }
for (idx, str) in enumerated() {
str.withCString { cStr in
ptr[idx] = strdup(cStr)
}
}
let constPtr = unsafeBitCast(ptr, to: UnsafeMutablePointer<UnsafePointer<Int8>?>.self)

return try ptr.withMemoryRebound(to: Optional<UnsafePointer<Int8>>.self, capacity: self.count) { constPtr in
return try f(UnsafeMutableBufferPointer(start: constPtr, count: self.count))
}
}
}

Expand Down
119 changes: 119 additions & 0 deletions utils/make-pkgconfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/env swift
import Foundation

/// Runs the specified program at the provided path.
/// - parameter path: The full path of the executable you
/// wish to run.
/// - parameter args: The arguments you wish to pass to the
/// process.
/// - returns: The standard output of the process, or nil if it was empty.
func run(_ path: String, args: [String] = []) -> String? {
print("Running \(path) \(args.joined(separator: " "))...")
let pipe = Pipe()
let process = Process()
process.launchPath = path
process.arguments = args
process.standardOutput = pipe
process.launch()
process.waitUntilExit()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
guard let result = String(data: data, encoding: .utf8)?
.trimmingCharacters(in: .whitespacesAndNewlines),
!result.isEmpty else { return nil }
return result
}

/// Finds the location of the provided binary on your system.
func which(_ name: String) -> String? {
return run("/usr/bin/which", args: [name])
}

extension String: Error {
/// Replaces all occurrences of characters in the provided set with
/// the provided string.
func replacing(charactersIn characterSet: CharacterSet,
with separator: String) -> String {
let components = self.components(separatedBy: characterSet)
return components.joined(separator: separator)
}
}

func makeFile() throws {
let pkgConfigPath = "/usr/local/lib/pkgconfig"
let pkgConfigDir = URL(fileURLWithPath: pkgConfigPath)

// Make /usr/local/lib/pkgconfig if it doesn't already exist
if !FileManager.default.fileExists(atPath: pkgConfigPath) {
try FileManager.default.createDirectory(at: pkgConfigDir,
withIntermediateDirectories: true)
}
let cllvmPath = pkgConfigDir.appendingPathComponent("cclang.pc")

/// Ensure we have llvm-config in the PATH
guard let llvmConfig = which("llvm-config-3.9") ?? which("llvm-config") else {
throw "Failed to find llvm-config. Ensure llvm-config is installed and " +
"in your PATH"
}

/// Extract the info we need from llvm-config

print("Found llvm-config at \(llvmConfig)...")

let version = run(llvmConfig, args: ["--version"])!
.replacing(charactersIn: .newlines, with: "")

guard version.hasPrefix("3.9") else {
throw "ClangSwift requires LLVM version >=3.9.0, but you have \(version)"
}

let libFlags = [
"-L/usr/local/Cellar/llvm/3.9.1/lib",
"-lclangEdit",
"-lclangFrontendTool",
"-lclang",
"-lclangAST",
"-lclangLex",
"-lclangBasic",
"-lclangDriver",
"-lclangAnalysis",
"-lclangIndex",
"-lclangASTMatchers",
"-lclangSema",
"-lclangParse",
].joined(separator: " ")

let cFlags = "-I/usr/local/Cellar/llvm/3.9.1/include"
// SwiftPM has a whitelisted set of cflags that it understands, and
// unfortunately that includes almost everything but the include dir.

/// Emit the pkg-config file to the path

let s = [
"Name: cclang",
"Description: The llvm library",
"Version: \(version)",
"Libs: \(libFlags)",
"Requires.private:",
"Cflags: \(cFlags)",
].joined(separator: "\n")

print("Writing pkg-config file to \(cllvmPath.path)...")

try s.write(toFile: cllvmPath.path, atomically: true, encoding: .utf8)

print("\nSuccessfully wrote pkg-config file!")
print("Make sure to re-run this script when you update LLVM.")
}

do {
try makeFile()
} catch {
#if os(Linux)
// FIXME: Printing the thrown error that here crashes on Linux.
print("Unexpected error occured while writing the config file. Check permissions and try again.")
#else
print("error: \(error)")
#endif
exit(-1)
}