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 | 99a23c9fccb0ce71a752289ffc20aaf27e217dfa (patch) | |
tree | 4edfe3dc7e54ec9a9607319541573d2a1fff90e2 /src/actions | |
parent | e390d423462f1aa5381f09db74920931fe5e2335 (diff) |
Improved handling of precompiled headers across toolsets
Diffstat (limited to 'src/actions')
-rw-r--r-- | src/actions/make/make_cpp.lua | 93 |
1 files changed, 58 insertions, 35 deletions
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) |