1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
--
-- xcode4_project.lua
-- Generate an Xcode4 C/C++ project.
-- Copyright (c) 2009 Jason Perkins and the Premake project
--
local xcode = premake.xcode
local xcode6 = xcode.xcode6
local tree = premake.tree
--
-- Create a tree corresponding to what is shown in the Xcode project browser
-- pane, with nodes for files and folders, resources, frameworks, and products.
--
-- @param prj
-- The project being generated.
-- @returns
-- A tree, loaded with metadata, which mirrors Xcode's view of the project.
--
function xcode6.buildprjtree(prj)
local tr = premake.project.buildsourcetree(prj)
-- create a list of build configurations and assign IDs
tr.configs = {}
for _, cfgname in ipairs(prj.solution.configurations) do
for _, platform in ipairs(prj.solution.xcode.platforms) do
local cfg = premake.getconfig(prj, cfgname, platform)
cfg.xcode = {}
cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode, cfgname)
cfg.xcode.projectid = xcode.newid(tr, cfgname)
table.insert(tr.configs, cfg)
end
end
-- convert localized resources from their filesystem layout (English.lproj/MainMenu.xib)
-- to Xcode's display layout (MainMenu.xib/English).
tree.traverse(tr, {
onbranch = function(node)
if path.getextension(node.name) == ".lproj" then
local lang = path.getbasename(node.name) -- "English", "French", etc.
-- create a new language group for each file it contains
for _, filenode in ipairs(node.children) do
local grpnode = node.parent.children[filenode.name]
if not grpnode then
grpnode = tree.insert(node.parent, tree.new(filenode.name))
grpnode.kind = "vgroup"
end
-- convert the file node to a language node and add to the group
filenode.name = path.getbasename(lang)
tree.insert(grpnode, filenode)
end
-- remove this directory from the tree
tree.remove(node)
end
end
})
-- fix .xcassets files, they should be treated as a file, not a folder
tree.traverse(tr, {
onbranch = function(node)
if path.getextension(node.name) == ".xcassets" then
node.children = {}
end
end
})
-- the special folder "Frameworks" lists all linked frameworks
tr.frameworks = tree.new("Frameworks")
for cfg in premake.eachconfig(prj) do
for _, link in ipairs(premake.getlinks(cfg, "system", "fullpath")) do
local name = path.getname(link)
if xcode.isframework(name) and not tr.frameworks.children[name] then
node = tree.insert(tr.frameworks, tree.new(name))
node.path = link
end
end
end
-- only add it to the tree if there are frameworks to link
if #tr.frameworks.children > 0 then
tree.insert(tr, tr.frameworks)
end
-- the special folder "Products" holds the target produced by the project; this
-- is populated below
tr.products = tree.insert(tr, tree.new("Products"))
-- the special folder "Projects" lists sibling project dependencies
tr.projects = tree.new("Projects")
for _, dep in ipairs(premake.getdependencies(prj, "sibling", "object")) do
-- create a child node for the dependency's xcodeproj
local xcpath = xcode.getxcodeprojname(dep)
local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath)))
xcnode.path = xcpath
xcnode.project = dep
xcnode.productgroupid = xcode.newid(xcnode, "prodgrp")
xcnode.productproxyid = xcode.newid(xcnode, "prodprox")
xcnode.targetproxyid = xcode.newid(xcnode, "targprox")
xcnode.targetdependid = xcode.newid(xcnode, "targdep")
-- create a grandchild node for the dependency's link target
local cfg = premake.getconfig(dep, prj.configurations[1])
node = tree.insert(xcnode, tree.new(cfg.linktarget.name))
node.path = cfg.linktarget.fullpath
node.cfg = cfg
end
if #tr.projects.children > 0 then
tree.insert(tr, tr.projects)
end
-- Final setup
tree.traverse(tr, {
onnode = function(node)
-- assign IDs to every node in the tree
node.id = xcode.newid(node)
-- assign build IDs to buildable files
if xcode.getbuildcategory(node) then
node.buildid = xcode.newid(node, "build")
end
-- remember key files that are needed elsewhere
if string.endswith(node.name, "Info.plist") then
tr.infoplist = node
end
if string.endswith(node.name, ".entitlements") then
tr.entitlements = node
end
end
}, true)
-- Plug in the product node into the Products folder in the tree. The node
-- was built in xcode.preparesolution() in xcode_common.lua; it contains IDs
-- that are necessary for inter-project dependencies
node = tree.insert(tr.products, prj.xcode.projectnode)
node.kind = "product"
node.path = node.cfg.buildtarget.fullpath
node.cfgsection = xcode.newid(node, "cfg")
node.resstageid = xcode.newid(node, "rez")
node.sourcesid = xcode.newid(node, "src")
node.fxstageid = xcode.newid(node, "fxs")
return tr
end
--
-- Generate an Xcode4 .xcodeproj for a Premake project.
--
-- @param prj
-- The Premake project to generate.
--
function xcode6.project(prj)
local tr = xcode6.buildprjtree(prj)
xcode6.Header(tr)
xcode6.PBXProject(tr)
xcode.PBXBuildFile(tr)
xcode.PBXContainerItemProxy(tr)
xcode.PBXFileReference(tr,prj)
xcode.PBXFrameworksBuildPhase(tr)
xcode.PBXGroup(tr)
xcode.PBXNativeTarget(tr)
xcode.PBXReferenceProxy(tr)
xcode.PBXResourcesBuildPhase(tr)
xcode.PBXShellScriptBuildPhase(tr)
xcode.PBXSourcesBuildPhase(tr,prj)
xcode.PBXVariantGroup(tr)
xcode.PBXTargetDependency(tr)
xcode.XCBuildConfiguration(tr)
xcode.XCBuildConfigurationList(tr)
xcode6.PBXConfigsGroup()
xcode6.Footer(tr)
end
---------------------------------------------------------------------------
-- Section generator functions, in the same order in which they appear
-- in the .pbxproj file
---------------------------------------------------------------------------
function xcode6.Header()
_p('// !$*UTF8*$!')
_p('{')
_p(1,'archiveVersion = 1;')
_p(1,'classes = {}')
_p(1,'objectVersion = 46;')
_p(1,'rootObject = __RootObject_;')
_p(1,'objects = {')
end
function xcode6.PBXProject(tr)
_p(2,'__RootObject_ = {')
_p(3,'isa = PBXProject;')
_p(3,'attributes = {LastUpgradeCheck = 9999;};')
_p(3,'buildConfigurationList = ___RootConfs_;', tr.name)
_p(3,'compatibilityVersion = "Xcode 3.2";')
_p(3,'developmentRegion = English;')
_p(3,'hasScannedForEncodings = 0;')
_p(3,'knownRegions = (en);')
_p(3,'mainGroup = ___RootGroup_;')
_p(3,'projectDirPath = "";')
_p(3,'projectRoot = "";')
_p(3,'targets = (')
for _, node in ipairs(tr.products.children) do
_p(4,'%s /* %s */,', node.targetid, node.name)
end
_p(3,');')
if #tr.projects.children > 0 then
_p(3,'projectReferences = (')
for _, node in ipairs(tr.projects.children) do
_p(4,'{')
_p(5,'ProductGroup = %s /* Products */;', node.productgroupid)
_p(5,'ProjectRef = %s /* %s */;', node.id, path.getname(node.path))
_p(4,'},')
end
_p(3,');')
end
_p(2,'};')
_p('')
end
function xcode6.PBXConfigsGroup()
_p(2, "_____Configs_ = {")
_p(3, "isa = PBXGroup;")
_p(3, "children = (")
-- '__PBXFileRef_SGLMath.xcodeproj/Configs/Project.xcconfig'
_p(3, ");")
_p(3, "name = Configs;")
_p(3, "sourceTree = '<group>';")
_p(2, "};")
end
function xcode6.Footer()
_p(1,'};')
_p('}')
end
|