diff options
author | Jason Perkins <starkos@industriousone.com> | 2013-07-12 18:20:57 +0400 |
---|---|---|
committer | Jason Perkins <starkos@industriousone.com> | 2013-07-12 18:20:57 +0400 |
commit | fc3d38a1670e9f549a1b60d8290a906b2b2b388e (patch) | |
tree | 4edfe3dc7e54ec9a9607319541573d2a1fff90e2 | |
parent | 17345d47a5201381c83db0e98a6e2d362738268d (diff) |
Improved handling of precompiled headers across toolsets
-rw-r--r-- | CHANGES.txt | 1 | ||||
-rw-r--r-- | src/actions/make/make_cpp.lua | 93 | ||||
-rw-r--r-- | tests/actions/make/test_make_pch.lua | 50 | ||||
-rw-r--r-- | tests/actions/make/test_wiidev.lua | 2 | ||||
-rw-r--r-- | tests/test_gmake_cpp.lua | 8 |
5 files changed, 91 insertions, 63 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 5a4c6b7..77e3bc1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -74,6 +74,7 @@ * Pull 11: Add support for Visual Studio 2012 (Oliver Schneider) * Bug 171: ImpLib used incorrectly in dependency paths * Bug 176: Target prefix breaks GCC linking +* Improved handling of precompiled headers across toolsets ------- diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua index c00b5e0..0efd321 100644 --- a/src/actions/make/make_cpp.lua +++ b/src/actions/make/make_cpp.lua @@ -1,7 +1,7 @@ -- -- make_cpp.lua -- Generate a C/C++ project makefile. --- Copyright (c) 2002-2011 Jason Perkins and the Premake project +-- Copyright (c) 2002-2013 Jason Perkins and the Premake project -- premake.make.cpp = { } @@ -109,19 +109,8 @@ -- 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), "o") - elseif (path.getextension(file) == ".rc") then - _p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file)) - _p('\t@echo $(notdir $<)') - _p('\t$(SILENT) $(RESCOMP) $< -O coff -o "$@" $(ALL_RESFLAGS)') - end - end - _p('') + -- per-file build rules + cpp.fileRules(prj) -- include the dependencies, built by GCC (with the -MMD flag) _p('-include $(OBJECTS:%%.o=%%.d)') @@ -182,15 +171,15 @@ _p(' DEFINES +=%s', make.list(cc.getdefines(cfg.defines))) _p(' INCLUDES +=%s', make.list(cc.getincludedirs(cfg.includedirs))) + -- set up precompiled headers + cpp.pchconfig(cfg) + -- CPPFLAGS, CFLAGS, CXXFLAGS, and RESFLAGS cpp.flags(cfg, cc) -- write out libraries, linker flags, and the link command cpp.linker(cfg, cc) - -- set up precompiled headers - cpp.pchconfig(cfg) - _p(' define PREBUILDCMDS') if #cfg.prebuildcommands > 0 then _p('\t@echo Running pre-build commands') @@ -243,7 +232,13 @@ -- function cpp.flags(cfg, cc) - _p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), " ")) + + if cfg.pchheader and not cfg.flags.NoPCH then + _p(' FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))') + end + + _p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE)', table.concat(cc.getcppflags(cfg), " ")) + _p(' ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions))) _p(' ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS)%s', make.list(cc.getcxxflags(cfg))) @@ -286,35 +281,47 @@ -- function cpp.pchconfig(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. - local pchheader = cfg.pchheader + + -- If there is no header, or if PCH has been disabled, I can early out + + if not cfg.pchheader or cfg.flags.NoPCH then + return + end + + -- Visual Studio requires the PCH header to be specified in the same way + -- it appears in the #include statements used in the source code; the PCH + -- source actual handles the compilation of the header. GCC compiles the + -- header file directly, and needs the file's actual file system path in + -- order to locate it. + + -- To maximize the compatibility between the two approaches, see if I can + -- locate the specified PCH header on one of the include file search paths + -- and, if so, adjust the path automatically so the user doesn't have + -- add a conditional configuration to the project script. + + local pch = cfg.pchheader for _, incdir in ipairs(cfg.includedirs) do - local testname = path.join(incdir, cfg.pchheader) + local testname = path.join(incdir, pch) if os.isfile(testname) then - pchheader = testname + pch = testname break end end - if not cfg.flags.NoPCH and cfg.pchheader then - _p(' PCH = %s', _MAKE.esc(path.getrelative(cfg.location, cfg.pchheader))) - _p(' GCH = $(OBJDIR)/%s.gch', _MAKE.esc(path.getname(cfg.pchheader))) - _p(' ALL_CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/%s', _MAKE.esc(path.getname(cfg.pchheader))) - end + _p(' PCH = %s', _MAKE.esc(path.getrelative(cfg.location, cfg.pchheader))) + _p(' GCH = $(OBJDIR)/$(notdir $(PCH)).gch', _MAKE.esc(path.getname(cfg.pchheader))) + 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", "gch") + + local cmd = iif(prj.language == "C", "$(CC) -x c-header", "$(CXX) -x c++-header") + _p('\t$(SILENT) %s $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) -o "$@" -MF "$(@:%%.gch=%%.d)" -c "$<"', cmd) + _p('endif') _p('') end @@ -324,6 +331,22 @@ -- Build command for a single file. -- + function cpp.fileRules(prj) + for _, file in ipairs(prj.files or {}) 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), "o") + _p('') + elseif (path.getextension(file) == ".rc") then + _p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file)) + _p('\t@echo $(notdir $<)') + _p('\t$(SILENT) $(RESCOMP) $< -O coff -o "$@" $(ALL_RESFLAGS)') + _p('') + end + end + end + function cpp.buildcommand(iscfile, objext) local flags = iif(iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)') _p('\t$(SILENT) %s -o "$@" -MF $(@:%%.%s=%%.d) -c "$<"', flags, objext) diff --git a/tests/actions/make/test_make_pch.lua b/tests/actions/make/test_make_pch.lua index c471e09..75d9d9d 100644 --- a/tests/actions/make/test_make_pch.lua +++ b/tests/actions/make/test_make_pch.lua @@ -7,7 +7,7 @@ T.make_pch = { } local suite = T.make_pch local _ = premake.make.cpp - + -- -- Setup and teardown @@ -17,24 +17,25 @@ function suite.setup() sln, prj = test.createsolution() end - + local function prepare() premake.bake.buildconfigs() + prj = premake.getconfig(prj) 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 } @@ -50,13 +51,12 @@ _.pchconfig(cfg) test.capture [[ PCH = include/myproject.h - GCH = $(OBJDIR)/myproject.h.gch - ALL_CPPFLAGS += -I$(OBJDIR) -include $(OBJDIR)/myproject.h + GCH = $(OBJDIR)/$(notdir $(PCH)).gch ]] end --- +-- -- Build rule tests -- @@ -68,13 +68,7 @@ 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) $(ALL_CXXFLAGS) -o "$@" -MF $(@:%.gch=%.d) -c "$<" -endif + $(SILENT) $(CXX) -x c++-header $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<" ]] end @@ -87,13 +81,23 @@ endif 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) $(ALL_CFLAGS) -o "$@" -MF $(@:%.gch=%.d) -c "$<" -endif + $(SILENT) $(CC) -x c-header $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) -o "$@" -MF "$(@:%.gch=%.d)" -c "$<" ]] end - + +-- +-- Ensure that PCH is included on all files that use it. +-- + + function suite.includesPCH_onUse() + pchheader "include/myproject.h" + files { "main.cpp" } + prepare() + _.fileRules(prj) + test.capture [[ +$(OBJDIR)/main.o: main.cpp + @echo $(notdir $<) + $(SILENT) $(CXX) $(ALL_CXXFLAGS) -o "$@" -MF $(@:%.o=%.d) -c "$<" + ]] + end + diff --git a/tests/actions/make/test_wiidev.lua b/tests/actions/make/test_wiidev.lua index f3787a0..2b276f6 100644 --- a/tests/actions/make/test_wiidev.lua +++ b/tests/actions/make/test_wiidev.lua @@ -32,7 +32,7 @@ function suite.writesCorrectFlags() cpp.flags(cfg, premake.gcc) test.capture [[ - ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -I$(LIBOGC_INC) $(MACHDEP) -MP $(DEFINES) $(INCLUDES) + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP -I$(LIBOGC_INC) $(MACHDEP) -MP $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE) ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) diff --git a/tests/test_gmake_cpp.lua b/tests/test_gmake_cpp.lua index ec895bd..2844567 100644 --- a/tests/test_gmake_cpp.lua +++ b/tests/test_gmake_cpp.lua @@ -78,7 +78,7 @@ ifeq ($(config),debug) TARGET = $(TARGETDIR)/MyProject DEFINES += INCLUDES += - ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE) ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) @@ -112,7 +112,7 @@ ifeq ($(config),debugps3) TARGET = $(TARGETDIR)/MyProject.elf DEFINES += INCLUDES += - ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE) ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) @@ -143,7 +143,7 @@ ifeq ($(config),debug64) TARGET = $(TARGETDIR)/MyProject DEFINES += INCLUDES += - ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) + ALL_CPPFLAGS += $(CPPFLAGS) -MMD -MP $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE) ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -m64 ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) @@ -175,7 +175,7 @@ ifeq ($(config),debuguniv32) TARGET = $(TARGETDIR)/libMyProject.a DEFINES += INCLUDES += - ALL_CPPFLAGS += $(CPPFLAGS) $(DEFINES) $(INCLUDES) + ALL_CPPFLAGS += $(CPPFLAGS) $(DEFINES) $(INCLUDES) $(FORCE_INCLUDE) ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH) -arch i386 -arch ppc ALL_CXXFLAGS += $(CXXFLAGS) $(ALL_CFLAGS) ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES) |