Ported GMake PCH rules

This commit is contained in:
Jason Perkins 2012-06-12 15:57:45 -04:00
parent e15d115bbd
commit e45a6efbd4
5 changed files with 202 additions and 128 deletions

View File

@ -117,16 +117,16 @@
_p('\t$(PRELINKCMDS)')
_p('')
--[[
-- precompiler header rule
cpp.pchrules(prj)
--[[
-- per-file rules
for _, file in ipairs(prj.files) do
if path.iscppfile(file) then
_p('$(OBJDIR)/%s.o: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))
_p('\t@echo $(notdir $<)')
cpp.buildcommand(path.iscfile(file))
cpp.buildcommand_old(path.iscfile(file))
elseif (path.getextension(file) == ".rc") then
_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))
_p('\t@echo $(notdir $<)')
@ -205,11 +205,13 @@
cpp.platformtools(cfg, cc)
--]]
-- write target information
local targetinfo = config.gettargetinfo(cfg)
_p(' OBJDIR = %s', make.esc(cfg.objdir))
_p(' TARGETDIR = %s', make.esc(targetinfo.directory))
_p(' TARGET = $(TARGETDIR)/%s', make.esc(targetinfo.name))
-- write flags
_p(' DEFINES += %s', table.concat(toolset.getdefines(cfg.defines), " "))
_p(' INCLUDES += %s', table.concat(make.esc(toolset.getincludedirs(cfg.includedirs), " ")))
_p(' CPPFLAGS += %s $(DEFINES) $(INCLUDES)', table.concat(toolset.getcppflags(cfg), " "))
@ -220,10 +222,10 @@
local resflags = table.join(toolset.getdefines(cfg.resdefines), toolset.getincludedirs(cfg.resincludedirs), cfg.resoptions)
_p(' RESFLAGS += $(DEFINES) $(INCLUDES) %s', table.concat(resflags, " "))
--[[
-- set up precompiled headers
cpp.pchconfig(cfg)
--[[
_p(' LIBS += %s', table.concat(cc.getlinkflags(cfg), " "))
_p(' LDDEPS += %s', table.concat(_MAKE.esc(premake.getlinks(cfg, "siblings", "fullpath")), " "))
@ -273,6 +275,56 @@
end
--
-- Precompiled header support
--
function cpp.pchconfig(cfg)
if not cfg.flags.NoPCH and cfg.pchheader then
-- Visual Studio needs the PCH path to match the way it appears in
-- the project's #include statement. GCC needs the full path. Assume
-- the #include path is given, is search the include dirs for it.
local pchheader = cfg.pchheader
for _, incdir in ipairs(cfg.includedirs) do
local testname = path.join(incdir, cfg.pchheader)
if os.isfile(testname) then
pchheader = testname
break
end
end
local gch = make.esc(path.getname(pchheader))
_p(' PCH = %s', make.esc(project.getrelative(cfg.project, pchheader)))
_p(' GCH = $(OBJDIR)/%s.gch', gch)
_p(' CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/%s', gch)
end
end
function cpp.pchrules(prj)
_p('ifneq (,$(PCH))')
_p('$(GCH): $(PCH)')
_p('\t@echo $(notdir $<)')
_p('ifeq (posix,$(SHELLTYPE))')
_p('\t-$(SILENT) cp $< $(OBJDIR)')
_p('else')
_p('\t$(SILENT) xcopy /D /Y /Q "$(subst /,\\,$<)" "$(subst /,\\,$(OBJDIR))" 1>nul')
_p('endif')
cpp.buildcommand(prj)
_p('endif')
_p('')
end
--
-- Build command for a single file.
--
function cpp.buildcommand(prj)
local flags = iif(prj.language == "C", '$(CC) $(CFLAGS)', '$(CXX) $(CXXFLAGS)')
_p('\t$(SILENT) %s -o "$@" -MF $(@:%%.o=%%.d) -c "$<"', flags)
end
-----------------------------------------------------------------------------
-- Everything below this point is a candidate for deprecation
@ -384,7 +436,7 @@
if path.iscppfile(file) then
_p('$(OBJDIR)/%s.o: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))
_p('\t@echo $(notdir $<)')
cpp.buildcommand(path.iscfile(file))
cpp.buildcommand_old(path.iscfile(file))
elseif (path.getextension(file) == ".rc") then
_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))
_p('\t@echo $(notdir $<)')
@ -463,7 +515,7 @@
cpp.flags(cfg, cc)
-- set up precompiled headers
cpp.pchconfig(cfg)
cpp.pchconfig_old(cfg)
_p(' LIBS += %s', table.concat(cc.getlinkflags(cfg), " "))
_p(' LDDEPS += %s', table.concat(_MAKE.esc(premake.getlinks(cfg, "siblings", "fullpath")), " "))
@ -551,7 +603,7 @@
-- Precompiled header support
--
function cpp.pchconfig(cfg)
function cpp.pchconfig_old(cfg)
-- GCC needs the full path to the PCH, while Visual Studio needs
-- only the name (or rather, the name as specified in the #include
-- statement). Try to locate the PCH in the project.
@ -571,26 +623,12 @@
end
end
function cpp.pchrules(prj)
_p('ifneq (,$(PCH))')
_p('$(GCH): $(PCH)')
_p('\t@echo $(notdir $<)')
_p('ifeq (posix,$(SHELLTYPE))')
_p('\t-$(SILENT) cp $< $(OBJDIR)')
_p('else')
_p('\t$(SILENT) xcopy /D /Y /Q "$(subst /,\\,$<)" "$(subst /,\\,$(OBJDIR))" 1>nul')
_p('endif')
cpp.buildcommand(prj.language == "C")
_p('endif')
_p('')
end
--
-- Build command for a single file.
--
function cpp.buildcommand(iscfile)
function cpp.buildcommand_old(iscfile)
local flags = iif(iscfile, '$(CC) $(CFLAGS)', '$(CXX) $(CXXFLAGS)')
_p('\t$(SILENT) %s -o "$@" -MF $(@:%%.o=%%.d) -c "$<"', flags)
end

View File

@ -0,0 +1,131 @@
--
-- tests/actions/make/cpp/test_make_pch.lua
-- Validate the setup for precompiled headers in makefiles.
-- Copyright (c) 2010-2012 Jason Perkins and the Premake project
--
T.make_pch = { }
local suite = T.make_pch
local cpp = premake.make.cpp
local project = premake5.project
--
-- Setup and teardown
--
local sln, prj, cfg
function suite.setup()
sln, prj = test.createsolution()
end
local function prepare()
cfg = project.getconfig(prj, "Debug")
end
--
-- If no header has been set, nothing should be output.
--
function suite.noConfig_onNoHeaderSet()
prepare()
cpp.pchconfig(cfg)
test.isemptycapture()
end
--
-- If a header is set, but the NoPCH flag is also set, then
-- nothing should be output.
--
function suite.noConfig_onHeaderAndNoPCHFlag()
pchheader "include/myproject.h"
flags "NoPCH"
prepare()
cpp.pchconfig(cfg)
test.isemptycapture()
end
--
-- If a header is specified and the NoPCH flag is not set, then
-- the header can be used.
--
function suite.config_onPchEnabled()
pchheader "include/myproject.h"
prepare()
cpp.pchconfig(cfg)
test.capture [[
PCH = include/myproject.h
GCH = $(OBJDIR)/myproject.h.gch
CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/myproject.h
]]
end
--
-- The PCH can be specified relative the an includes search path.
--
function suite.pch_searchesIncludeDirs()
pchheader "premake.h"
includedirs { "../src/host" }
prepare()
cpp.pchconfig(cfg)
test.capture [[
PCH = ../src/host/premake.h
GCH = $(OBJDIR)/premake.h.gch
CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/premake.h
]]
end
--
-- Verify the format of the PCH rules block for a C++ file.
--
function suite.buildRules_onCpp()
pchheader "include/myproject.h"
prepare()
cpp.pchrules(cfg.project)
test.capture [[
ifneq (,$(PCH))
$(GCH): $(PCH)
@echo $(notdir $<)
ifeq (posix,$(SHELLTYPE))
-$(SILENT) cp $< $(OBJDIR)
else
$(SILENT) xcopy /D /Y /Q "$(subst /,\,$<)" "$(subst /,\,$(OBJDIR))" 1>nul
endif
$(SILENT) $(CXX) $(CXXFLAGS) -o "$@" -MF $(@:%.o=%.d) -c "$<"
endif
]]
end
--
-- Verify the format of the PCH rules block for a C file.
--
function suite.buildRules_onC()
language "C"
pchheader "include/myproject.h"
prepare()
cpp.pchrules(cfg.project)
test.capture [[
ifneq (,$(PCH))
$(GCH): $(PCH)
@echo $(notdir $<)
ifeq (posix,$(SHELLTYPE))
-$(SILENT) cp $< $(OBJDIR)
else
$(SILENT) xcopy /D /Y /Q "$(subst /,\,$<)" "$(subst /,\,$(OBJDIR))" 1>nul
endif
$(SILENT) $(CC) $(CFLAGS) -o "$@" -MF $(@:%.o=%.d) -c "$<"
endif
]]
end

View File

@ -10,22 +10,22 @@
function suite.Escapes_Spaces()
test.isequal("Program\\ Files", make.esc("Program Files"))
test.isequal([[Program\ Files]], make.esc([[Program Files]]))
end
function suite.Escapes_Backslashes()
test.isequal("Program\\\\Files", make.esc("Program\\Files"))
test.isequal([[Program\\Files]], make.esc([[Program\Files]]))
end
function suite.Escapes_Parens()
test.isequal("Debug\\(x86\\)", make.esc("Debug(x86)"))
test.isequal([[Debug\(x86\)]], make.esc([[Debug(x86)]]))
end
function suite.DoesNotEscape_ShellReplacements()
test.isequal("-L$(NVSDKCUDA_ROOT)/C/lib", make.esc("-L$(NVSDKCUDA_ROOT)/C/lib"))
test.isequal([[-L$(NVSDKCUDA_ROOT)/C/lib]], make.esc([[-L$(NVSDKCUDA_ROOT)/C/lib]]))
end
function suite.CanEscape_ShellReplacementCapturesShortest()
test.isequal("a\\(x\\)b$(ROOT)c\\(y\\)d", make.esc("a(x)b$(ROOT)c(y)d"))
test.isequal([[a\(x\)b$(ROOT)c\(y\)d]], make.esc([[a(x)b$(ROOT)c(y)d]]))
end

View File

@ -1,99 +0,0 @@
--
-- tests/actions/make/test_make_pch.lua
-- Validate the setup for precompiled headers in makefiles.
-- Copyright (c) 2010 Jason Perkins and the Premake project
--
T.make_pch = { }
local suite = T.make_pch
local _ = premake.make.cpp
--
-- Setup and teardown
--
local sln, prj, cfg
function suite.setup()
sln, prj = test.createsolution()
end
local function prepare()
premake.bake.buildconfigs()
cfg = premake.getconfig(prj, "Debug")
end
--
-- Configuration block tests
--
function suite.NoConfig_OnNoHeaderSet()
prepare()
_.pchconfig(cfg)
test.capture [[]]
end
function suite.NoConfig_OnHeaderAndNoPCHFlag()
pchheader "include/myproject.h"
flags { NoPCH }
prepare()
_.pchconfig(cfg)
test.capture [[]]
end
function suite.ConfigBlock_OnPchEnabled()
pchheader "include/myproject.h"
prepare()
_.pchconfig(cfg)
test.capture [[
PCH = include/myproject.h
GCH = $(OBJDIR)/myproject.h.gch
CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/myproject.h
]]
end
--
-- Build rule tests
--
function suite.BuildRules_OnCpp()
pchheader "include/myproject.h"
prepare()
_.pchrules(prj)
test.capture [[
ifneq (,$(PCH))
$(GCH): $(PCH)
@echo $(notdir $<)
ifeq (posix,$(SHELLTYPE))
-$(SILENT) cp $< $(OBJDIR)
else
$(SILENT) xcopy /D /Y /Q "$(subst /,\,$<)" "$(subst /,\,$(OBJDIR))" 1>nul
endif
$(SILENT) $(CXX) $(CXXFLAGS) -o "$@" -MF $(@:%.o=%.d) -c "$<"
endif
]]
end
function suite.BuildRules_OnC()
language "C"
pchheader "include/myproject.h"
prepare()
_.pchrules(prj)
test.capture [[
ifneq (,$(PCH))
$(GCH): $(PCH)
@echo $(notdir $<)
ifeq (posix,$(SHELLTYPE))
-$(SILENT) cp $< $(OBJDIR)
else
$(SILENT) xcopy /D /Y /Q "$(subst /,\,$<)" "$(subst /,\,$(OBJDIR))" 1>nul
endif
$(SILENT) $(CC) $(CFLAGS) -o "$@" -MF $(@:%.o=%.d) -c "$<"
endif
]]
end

View File

@ -151,10 +151,14 @@
dofile("actions/vstudio/vc2010/test_resource_compile.lua")
-- Makefile tests
dofile("actions/make/test_make_escaping.lua")
-- Makefile solutions
dofile("actions/make/solution/test_default_config.lua")
dofile("actions/make/solution/test_help_rule.lua")
dofile("actions/make/test_make_escaping.lua")
dofile("actions/make/test_make_pch.lua")
-- Makefile C/C++ projects
dofile("actions/make/cpp/test_make_pch.lua")
dofile("actions/make/test_make_linking.lua")
-- dofile("actions/make/test_makesettings.lua")
dofile("actions/make/test_wiidev.lua")