1--
2-- clang.lua
3-- Clang toolset adapter for Premake
4-- Copyright (c) 2013 Jason Perkins and the Premake project
5--
6
7	local p = premake
8	p.tools.clang = {}
9	local clang = p.tools.clang
10	local gcc = p.tools.gcc
11	local config = p.config
12
13
14
15--
16-- Build a list of flags for the C preprocessor corresponding to the
17-- settings in a particular project configuration.
18--
19-- @param cfg
20--    The project configuration.
21-- @return
22--    An array of C preprocessor flags.
23--
24
25	function clang.getcppflags(cfg)
26
27		-- Just pass through to GCC for now
28		local flags = gcc.getcppflags(cfg)
29		return flags
30
31	end
32
33
34--
35-- Build a list of C compiler flags corresponding to the settings in
36-- a particular project configuration. These flags are exclusive
37-- of the C++ compiler flags, there is no overlap.
38--
39-- @param cfg
40--    The project configuration.
41-- @return
42--    An array of C compiler flags.
43--
44
45	clang.shared = {
46		architecture = gcc.shared.architecture,
47		flags = gcc.shared.flags,
48		floatingpoint = {
49			Fast = "-ffast-math",
50		},
51		strictaliasing = gcc.shared.strictaliasing,
52		optimize = {
53			Off = "-O0",
54			On = "-O2",
55			Debug = "-O0",
56			Full = "-O3",
57			Size = "-Os",
58			Speed = "-O3",
59		},
60		pic = gcc.shared.pic,
61		vectorextensions = gcc.shared.vectorextensions,
62		warnings = gcc.shared.warnings,
63		symbols = gcc.shared.symbols
64	}
65
66	clang.cflags = table.merge(gcc.cflags, {
67	})
68
69	function clang.getcflags(cfg)
70		local shared = config.mapFlags(cfg, clang.shared)
71		local cflags = config.mapFlags(cfg, clang.cflags)
72
73		local flags = table.join(shared, cflags)
74		flags = table.join(flags, clang.getwarnings(cfg))
75
76		return flags
77	end
78
79	function clang.getwarnings(cfg)
80		return gcc.getwarnings(cfg)
81	end
82
83
84--
85-- Build a list of C++ compiler flags corresponding to the settings
86-- in a particular project configuration. These flags are exclusive
87-- of the C compiler flags, there is no overlap.
88--
89-- @param cfg
90--    The project configuration.
91-- @return
92--    An array of C++ compiler flags.
93--
94
95	clang.cxxflags = table.merge(gcc.cxxflags, {
96	})
97
98	function clang.getcxxflags(cfg)
99		local shared = config.mapFlags(cfg, clang.shared)
100		local cxxflags = config.mapFlags(cfg, clang.cxxflags)
101		local flags = table.join(shared, cxxflags)
102		flags = table.join(flags, clang.getwarnings(cfg))
103		return flags
104	end
105
106
107--
108-- Returns a list of defined preprocessor symbols, decorated for
109-- the compiler command line.
110--
111-- @param defines
112--    An array of preprocessor symbols to define; as an array of
113--    string values.
114-- @return
115--    An array of symbols with the appropriate flag decorations.
116--
117
118	function clang.getdefines(defines)
119
120		-- Just pass through to GCC for now
121		local flags = gcc.getdefines(defines)
122		return flags
123
124	end
125
126	function clang.getundefines(undefines)
127
128		-- Just pass through to GCC for now
129		local flags = gcc.getundefines(undefines)
130		return flags
131
132	end
133
134
135
136--
137-- Returns a list of forced include files, decorated for the compiler
138-- command line.
139--
140-- @param cfg
141--    The project configuration.
142-- @return
143--    An array of force include files with the appropriate flags.
144--
145
146	function clang.getforceincludes(cfg)
147
148		-- Just pass through to GCC for now
149		local flags = gcc.getforceincludes(cfg)
150		return flags
151
152	end
153
154
155--
156-- Returns a list of include file search directories, decorated for
157-- the compiler command line.
158--
159-- @param cfg
160--    The project configuration.
161-- @param dirs
162--    An array of include file search directories; as an array of
163--    string values.
164-- @return
165--    An array of symbols with the appropriate flag decorations.
166--
167
168	function clang.getincludedirs(cfg, dirs, sysdirs)
169
170		-- Just pass through to GCC for now
171		local flags = gcc.getincludedirs(cfg, dirs, sysdirs)
172		return flags
173
174	end
175
176	clang.getrunpathdirs = gcc.getrunpathdirs
177
178--
179-- get the right output flag.
180--
181	function clang.getsharedlibarg(cfg)
182		return gcc.getsharedlibarg(cfg)
183	end
184
185--
186-- Build a list of linker flags corresponding to the settings in
187-- a particular project configuration.
188--
189-- @param cfg
190--    The project configuration.
191-- @return
192--    An array of linker flags.
193--
194
195	clang.ldflags = {
196		architecture = {
197			x86 = "-m32",
198			x86_64 = "-m64",
199		},
200		flags = {
201			LinkTimeOptimization = "-flto",
202		},
203		kind = {
204			SharedLib = function(cfg)
205				local r = { clang.getsharedlibarg(cfg) }
206				if cfg.system == "windows" and not cfg.flags.NoImportLib then
207					table.insert(r, '-Wl,--out-implib="' .. cfg.linktarget.relpath .. '"')
208				elseif cfg.system == p.LINUX then
209					table.insert(r, '-Wl,-soname=' .. p.quoted(cfg.linktarget.name))
210				elseif cfg.system == p.MACOSX then
211					table.insert(r, '-Wl,-install_name,' .. p.quoted('@rpath/' .. cfg.linktarget.name))
212				end
213				return r
214			end,
215			WindowedApp = function(cfg)
216				if cfg.system == p.WINDOWS then return "-mwindows" end
217			end,
218		},
219		system = {
220			wii = "$(MACHDEP)",
221		}
222	}
223
224	function clang.getldflags(cfg)
225		local flags = config.mapFlags(cfg, clang.ldflags)
226		return flags
227	end
228
229
230
231--
232-- Build a list of additional library directories for a particular
233-- project configuration, decorated for the tool command line.
234--
235-- @param cfg
236--    The project configuration.
237-- @return
238--    An array of decorated additional library directories.
239--
240
241	function clang.getLibraryDirectories(cfg)
242
243		-- Just pass through to GCC for now
244		local flags = gcc.getLibraryDirectories(cfg)
245		return flags
246
247	end
248
249
250--
251-- Build a list of libraries to be linked for a particular project
252-- configuration, decorated for the linker command line.
253--
254-- @param cfg
255--    The project configuration.
256-- @param systemOnly
257--    Boolean flag indicating whether to link only system libraries,
258--    or system libraries and sibling projects as well.
259-- @return
260--    A list of libraries to link, decorated for the linker.
261--
262
263	function clang.getlinks(cfg, systemonly, nogroups)
264		return gcc.getlinks(cfg, systemonly, nogroups)
265	end
266
267
268--
269-- Return a list of makefile-specific configuration rules. This will
270-- be going away when I get a chance to overhaul these adapters.
271--
272-- @param cfg
273--    The project configuration.
274-- @return
275--    A list of additional makefile rules.
276--
277
278	function clang.getmakesettings(cfg)
279
280		-- Just pass through to GCC for now
281		local flags = gcc.getmakesettings(cfg)
282		return flags
283
284	end
285
286
287--
288-- Retrieves the executable command name for a tool, based on the
289-- provided configuration and the operating environment. I will
290-- be moving these into global configuration blocks when I get
291-- the chance.
292--
293-- @param cfg
294--    The configuration to query.
295-- @param tool
296--    The tool to fetch, one of "cc" for the C compiler, "cxx" for
297--    the C++ compiler, or "ar" for the static linker.
298-- @return
299--    The executable command name for a tool, or nil if the system's
300--    default value should be used.
301--
302
303	clang.tools = {
304		cc = "clang",
305		cxx = "clang++",
306		ar = "ar"
307	}
308
309	function clang.gettoolname(cfg, tool)
310		return clang.tools[tool]
311	end
312