1 /** 2 * Copyright: Copyright (c) 2015 Jacob Carlborg. All rights reserved. 3 * Authors: Jacob Carlborg 4 * Version: Initial created: Jan 31, 2015 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module clang.Compiler; 8 9 import std.path; 10 import std.typetuple : staticMap; 11 12 import clang.c.Index; 13 14 struct Compiler 15 { 16 private 17 { 18 version (Windows) 19 enum root = `C:\`; 20 21 else 22 enum root = "/"; 23 24 string virtualPath_; 25 string[] sysRootFlag_; 26 27 static template toInternalHeader (string file) 28 { 29 enum toInternalHeader = InternalHeader(file, import(file)); 30 } 31 32 static struct InternalHeader 33 { 34 string filename; 35 string content; 36 } 37 38 enum internalHeaders_ = [ 39 staticMap!( 40 toInternalHeader, 41 "__stddef_max_align_t.h", 42 "float.h", 43 "limits.h", 44 "stdarg.h", 45 "stdbool.h", 46 "stddef.h" 47 ) 48 ]; 49 } 50 51 string[] internalFlags () 52 { 53 import std.algorithm : map; 54 import std.array : array; 55 import std.range : chain; 56 57 return extraIncludePaths 58 .map!(path => "-I" ~ path) 59 .chain(sysRootFlag) 60 .array; 61 } 62 63 CXUnsavedFile[] internalHeaders () 64 { 65 import std.algorithm : map; 66 import std.array : array; 67 import std..string : toStringz; 68 69 return internalHeaders_.map!((e) { 70 auto path = buildPath(virtualPath, e.filename); 71 return CXUnsavedFile(path.toStringz, e.content.ptr, cast(uint)e.content.length); 72 }).array(); 73 } 74 75 private: 76 77 string[] extraIncludePaths () 78 { 79 return [virtualPath]; 80 } 81 82 string virtualPath () 83 { 84 import std.random; 85 import std.conv; 86 87 if (virtualPath_.length) 88 return virtualPath_; 89 90 return virtualPath_ = buildPath(root, uniform(1, 10_000_000).to!string); 91 } 92 93 string[] sysRootFlag () 94 { 95 if (sysRootFlag_.length) 96 return sysRootFlag_; 97 98 version (OSX) 99 { 100 import std..string : strip; 101 import std.array : join; 102 import std.format : format; 103 import std.process : execute; 104 105 import dstep.core.Exceptions : DStepException; 106 107 static immutable command = ["xcrun", "--show-sdk-path", "--sdk", "macosx"]; 108 const result = execute(command); 109 110 if (result.status == 0) 111 return sysRootFlag_ = ["-isysroot", result.output.strip]; 112 113 enum fmt = "Failed get the path of the SDK.\nThe command '%s' " ~ 114 "returned the following output:\n%s"; 115 116 const message = format!fmt(command.join(" "), result.output); 117 throw new DStepException(message); 118 } 119 120 else 121 return null; 122 } 123 }