1--
2-- test_gmake2_pch.lua
3-- Validate the setup for precompiled headers in makefiles.
4-- (c) 2016-2017 Jason Perkins, Blizzard Entertainment and the Premake project
5--
6
7	local p = premake
8	local suite = test.declare("gmake2_pch")
9
10	local p = premake
11	local gmake2 = p.modules.gmake2
12
13	local project = p.project
14
15
16
17--
18-- Setup and teardown
19--
20
21	local wks, prj
22	function suite.setup()
23		os.chdir(_TESTS_DIR)
24		gmake2.cpp.initialize()
25		wks, prj = test.createWorkspace()
26	end
27
28	local function prepareVars()
29		local cfg = test.getconfig(prj, "Debug")
30		gmake2.cpp.pch(cfg)
31	end
32
33	local function prepareRules()
34		local cfg = test.getconfig(prj, "Debug")
35		gmake2.cpp.pchRules(cfg.project)
36	end
37
38	local function prepareFlags()
39		local project = test.getproject(wks, 1)
40		gmake2.cpp.createRuleTable(project)
41		gmake2.cpp.createFileTable(project)
42		gmake2.cpp.outputFileRuleSection(project)
43	end
44
45--
46-- If no header has been set, nothing should be output.
47--
48
49	function suite.noConfig_onNoHeaderSet()
50		prepareVars()
51		test.isemptycapture()
52	end
53
54
55--
56-- If a header is set, but the NoPCH flag is also set, then
57-- nothing should be output.
58--
59
60	function suite.noConfig_onHeaderAndNoPCHFlag()
61		pchheader "include/myproject.h"
62		flags "NoPCH"
63
64		files { 'a.cpp', 'b.cpp' }
65
66		prepareFlags()
67		test.capture [[
68# File Rules
69# #############################################
70
71$(OBJDIR)/a.o: a.cpp
72	@echo $(notdir $<)
73	$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
74$(OBJDIR)/b.o: b.cpp
75	@echo $(notdir $<)
76	$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
77]]
78	end
79
80
81--
82-- If a header is specified and the NoPCH flag is not set, then
83-- the header can be used.
84--
85
86	function suite.config_onPchEnabled()
87		pchheader "include/myproject.h"
88		prepareVars()
89		test.capture [[
90PCH = include/myproject.h
91PCH_PLACEHOLDER = $(OBJDIR)/$(notdir $(PCH))
92GCH = $(PCH_PLACEHOLDER).gch
93		]]
94	end
95
96
97--
98-- The PCH can be specified relative the an includes search path.
99--
100
101	function suite.pch_searchesIncludeDirs()
102		pchheader "premake.h"
103		includedirs { "../../../src/host" }
104		prepareVars()
105		test.capture [[
106PCH = ../../../src/host/premake.h
107		]]
108	end
109
110
111--
112-- Verify the format of the PCH rules block for a C++ file.
113--
114
115	function suite.buildRules_onCpp()
116		pchheader "include/myproject.h"
117		prepareRules()
118		test.capture [[
119ifneq (,$(PCH))
120$(OBJECTS): $(GCH) | $(PCH_PLACEHOLDER)
121$(GCH): $(PCH) | prebuild
122	@echo $(notdir $<)
123	$(SILENT) $(CXX) -x c++-header $(ALL_CXXFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
124$(PCH_PLACEHOLDER): $(GCH) | $(OBJDIR)
125ifeq (posix,$(SHELLTYPE))
126	$(SILENT) touch "$@"
127else
128	$(SILENT) echo $null >> "$@"
129endif
130else
131$(OBJECTS): | prebuild
132endif
133		]]
134	end
135
136
137--
138-- Verify the format of the PCH rules block for a C file.
139--
140
141	function suite.buildRules_onC()
142		language "C"
143		pchheader "include/myproject.h"
144		prepareRules()
145		test.capture [[
146ifneq (,$(PCH))
147$(OBJECTS): $(GCH) | $(PCH_PLACEHOLDER)
148$(GCH): $(PCH) | prebuild
149	@echo $(notdir $<)
150	$(SILENT) $(CC) -x c-header $(ALL_CFLAGS) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<"
151$(PCH_PLACEHOLDER): $(GCH) | $(OBJDIR)
152ifeq (posix,$(SHELLTYPE))
153	$(SILENT) touch "$@"
154else
155	$(SILENT) echo $null >> "$@"
156endif
157else
158$(OBJECTS): | prebuild
159endif
160		]]
161	end
162
163
164
165	--
166	-- If the header is located on one of the include file
167	-- search directories, it should get found automatically.
168	--
169
170		function suite.findsPCH_onIncludeDirs()
171			location "MyProject"
172			pchheader "premake.h"
173			includedirs { "../../../src/host" }
174			prepareVars()
175			test.capture [[
176PCH = ../../../../src/host/premake.h
177			]]
178		end
179
180--
181-- If the header is located on one of the include file
182-- search directories, it should get found automatically.
183--
184
185	function suite.PCHFlag()
186		pchheader "include/myproject.h"
187
188		files { 'a.cpp', 'b.cpp' }
189
190		prepareFlags()
191		test.capture [[
192# File Rules
193# #############################################
194
195$(OBJDIR)/a.o: a.cpp
196	@echo $(notdir $<)
197	$(SILENT) $(CXX) -include $(PCH_PLACEHOLDER) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
198$(OBJDIR)/b.o: b.cpp
199	@echo $(notdir $<)
200	$(SILENT) $(CXX) -include $(PCH_PLACEHOLDER) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
201]]
202	end
203
204	function suite.PCHFlag_PerFile()
205		pchheader "include/myproject.h"
206
207		files { 'a.cpp', 'b.cpp' }
208
209		filter { "files:a.cpp" }
210			flags "NoPCH"
211
212		prepareFlags()
213		test.capture [[
214# File Rules
215# #############################################
216
217$(OBJDIR)/a.o: a.cpp
218	@echo $(notdir $<)
219	$(SILENT) $(CXX) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
220$(OBJDIR)/b.o: b.cpp
221	@echo $(notdir $<)
222	$(SILENT) $(CXX) -include $(PCH_PLACEHOLDER) $(ALL_CXXFLAGS) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"
223]]
224	end
225