Skip to content

Commit 4ffaf0d

Browse files
committed
Merge pull request #217 from aciidb0mb3r/c_exec
build C executables
2 parents df26dac + d7c6ca1 commit 4ffaf0d

File tree

8 files changed

+59
-15
lines changed

8 files changed

+59
-15
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import PackageDescription
2+
3+
let package = Package(
4+
name: "CExecutable"
5+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <stdio.h>
2+
3+
int main() {
4+
int a = 5;
5+
printf("hello %d", a);
6+
}

Sources/Build/Command.compile(ClangModule).swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extension Command {
2121
let mkdir = Command.createDirectory(wd)
2222

2323
let inputs = module.dependencies.map{ $0.targetName } + module.sources.paths + [mkdir.node]
24-
let productPath = Path.join(prefix, "lib\(module.c99name).so")
24+
let productPath = Path.join(prefix, module.type == .Library ? "lib\(module.c99name).so" : module.c99name)
2525

2626
var args: [String] = []
2727
#if os(Linux)
@@ -56,7 +56,12 @@ extension Command {
5656
}
5757

5858
args += module.sources.paths
59-
args += ["-shared", "-o", productPath]
59+
60+
if module.type == .Library {
61+
args += ["-shared"]
62+
}
63+
64+
args += ["-o", productPath]
6065

6166
let clang = ShellTool(
6267
description: "Compiling \(module.name)",

Sources/Build/describe().swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public func describe(prefix: String, _ conf: Configuration, _ modules: [Module],
4343
//FIXME: Generate modulemaps if possible
4444
//Since we're not generating modulemaps currently we'll just emit empty module map file
4545
//if it not present
46-
if !module.moduleMapPath.isFile {
46+
if module.type == .Library && !module.moduleMapPath.isFile {
4747
try POSIX.mkdir(module.moduleMapPath.parentDirectory)
4848
try fopen(module.moduleMapPath, mode: .Write) { fp in
4949
try fputs("\n", fp)

Sources/PackageType/Module.swift

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,25 @@ public class Module {
3737
}
3838
}
3939

40+
public enum ModuleType {
41+
case Library, Executable
42+
}
43+
44+
public protocol ModuleTypeProtocol {
45+
var sources: Sources { get }
46+
var type: ModuleType { get }
47+
var mainFile: String { get }
48+
}
49+
50+
extension ModuleTypeProtocol {
51+
public var type: ModuleType {
52+
let isLibrary = !sources.relativePaths.contains { path in
53+
path.basename.lowercased() == mainFile
54+
}
55+
return isLibrary ? .Library : .Executable
56+
}
57+
}
58+
4059
extension Module: Hashable, Equatable {
4160
public var hashValue: Int { return c99name.hashValue }
4261
}
@@ -52,16 +71,11 @@ public class SwiftModule: Module {
5271
self.sources = sources
5372
super.init(name: name)
5473
}
74+
}
5575

56-
public enum ModuleType {
57-
case Library, Executable
58-
}
59-
60-
public var type: ModuleType {
61-
let isLibrary = !sources.relativePaths.contains { path in
62-
path.basename.lowercased() == "main.swift"
63-
}
64-
return isLibrary ? .Library : .Executable
76+
extension SwiftModule: ModuleTypeProtocol {
77+
public var mainFile: String {
78+
return "main.swift"
6579
}
6680
}
6781

@@ -84,6 +98,12 @@ public class ClangModule: CModule {
8498
}
8599
}
86100

101+
extension ClangModule: ModuleTypeProtocol {
102+
public var mainFile: String {
103+
return "main.c"
104+
}
105+
}
106+
87107
public class TestModule: SwiftModule {
88108

89109
public init(basename: String, sources: Sources) {

Sources/Transmute/Error.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,5 @@ extension Module {
2727
public enum Error: ErrorProtocol {
2828
case NoSources(String)
2929
case MixedSources(String)
30-
case CExecutableNotSupportedYet(String) //TODO: Remove this when add Support for C Exectuable
3130
}
3231
}

Sources/Transmute/Package+modules.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ extension Package {
8383

8484
if !cSources.isEmpty {
8585
guard swiftSources.isEmpty else { throw Module.Error.MixedSources(path) }
86-
//FIXME: Support executables for C languages
87-
guard !cSources.contains({ $0.basename == "main.c" }) else { throw Module.Error.CExecutableNotSupportedYet(path) }
8886
return ClangModule(name: name, sources: Sources(paths: cSources, root: path))
8987
}
9088

Tests/Functional/TestClangModules.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ class TestClangModulesTestCase: XCTestCase {
6363
XCTAssertDirectoryExists(prefix, "Bar/Packages/Foo-1.2.3")
6464
}
6565
}
66+
67+
func testCExecutable() {
68+
fixture(name: "ValidLayouts/SingleModule/CExecutable") { prefix in
69+
XCTAssertBuilds(prefix)
70+
let exec = ".build/debug/CExecutable"
71+
XCTAssertFileExists(prefix, exec)
72+
let output = try popen([Path.join(prefix, exec)])
73+
XCTAssertEqual(output, "hello 5")
74+
}
75+
}
6676
}
6777

6878

@@ -75,6 +85,7 @@ extension TestClangModulesTestCase {
7585
("testExternalSimpleCDep", testExternalSimpleCDep),
7686
("testiquoteDep", testiquoteDep),
7787
("testCUsingCDep", testCUsingCDep),
88+
("testCExecutable", testCExecutable),
7889
]
7990
}
8091
}

0 commit comments

Comments
 (0)