summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-08-04 15:37:44 +0800
committerruki <[email protected]>2017-08-04 15:37:44 +0800
commitfada840909bf5e61e3d5c8bed84722166f5adda0 (patch)
tree2872417ab3ef455ae7fa746b8188ea1df83f1596
parentb9f40db69152c3458b2a0dcd1b99eb094e578a0d (diff)
improve precompiled header
-rw-r--r--tests/projects/precompiled_header_c++/src/header.cpp2
-rw-r--r--tests/projects/precompiled_header_c++/src/header.h2
-rw-r--r--tests/projects/precompiled_header_c++/src/test.c4
-rw-r--r--tests/projects/precompiled_header_c++/xmake.lua4
-rw-r--r--tests/projects/precompiled_header_c/src/header.c2
-rw-r--r--tests/projects/precompiled_header_c/src/test.cpp4
-rw-r--r--tests/projects/precompiled_header_c/xmake.lua4
-rw-r--r--xmake/actions/build/kinds/object.lua49
-rw-r--r--xmake/actions/clean/main.lua5
-rw-r--r--xmake/core/project/target.lua78
-rw-r--r--xmake/core/tool/builder.lua6
-rw-r--r--xmake/languages/c++/api.lua3
-rw-r--r--xmake/languages/c++/xmake.lua3
-rw-r--r--xmake/languages/objc++/api.lua3
-rw-r--r--xmake/languages/objc++/xmake.lua3
-rw-r--r--xmake/modules/core/tools/cl.lua78
-rw-r--r--xmake/modules/core/tools/gcc.lua30
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua3
-rw-r--r--xmake/plugins/project/makefile/makefile.lua3
-rw-r--r--xmake/plugins/project/vstudio/impl/vs200x.lua3
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua15
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua95
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua23
23 files changed, 204 insertions, 218 deletions
diff --git a/tests/projects/precompiled_header_c++/src/header.cpp b/tests/projects/precompiled_header_c++/src/header.cpp
deleted file mode 100644
index 79395fab8..000000000
--- a/tests/projects/precompiled_header_c++/src/header.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "header.h"
-
diff --git a/tests/projects/precompiled_header_c++/src/header.h b/tests/projects/precompiled_header_c++/src/header.h
index 39e07b7ce..d62b78383 100644
--- a/tests/projects/precompiled_header_c++/src/header.h
+++ b/tests/projects/precompiled_header_c++/src/header.h
@@ -8,7 +8,7 @@
#include <map>
#include <memory>
#include <set>
-#include <thread>
+//#include <thread>
#include <utility>
#include <vector>
diff --git a/tests/projects/precompiled_header_c++/src/test.c b/tests/projects/precompiled_header_c++/src/test.c
new file mode 100644
index 000000000..7f0aa2bf4
--- /dev/null
+++ b/tests/projects/precompiled_header_c++/src/test.c
@@ -0,0 +1,4 @@
+
+void test_c(void)
+{
+}
diff --git a/tests/projects/precompiled_header_c++/xmake.lua b/tests/projects/precompiled_header_c++/xmake.lua
index 6ad93c1e1..685eca1cd 100644
--- a/tests/projects/precompiled_header_c++/xmake.lua
+++ b/tests/projects/precompiled_header_c++/xmake.lua
@@ -8,8 +8,8 @@ target("main")
set_languages("cxx11")
-- set precompiled header
- set_precompiled_header("src/header.h", "src/header.cpp")
+ set_pcxxheader("src/header.h")
-- add files
- add_files("src/*.cpp|header.cpp")
+ add_files("src/*.cpp", "src/*.c")
diff --git a/tests/projects/precompiled_header_c/src/header.c b/tests/projects/precompiled_header_c/src/header.c
deleted file mode 100644
index 79395fab8..000000000
--- a/tests/projects/precompiled_header_c/src/header.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "header.h"
-
diff --git a/tests/projects/precompiled_header_c/src/test.cpp b/tests/projects/precompiled_header_c/src/test.cpp
new file mode 100644
index 000000000..1cedddad9
--- /dev/null
+++ b/tests/projects/precompiled_header_c/src/test.cpp
@@ -0,0 +1,4 @@
+int test_cpp()
+{
+ return 0;
+}
diff --git a/tests/projects/precompiled_header_c/xmake.lua b/tests/projects/precompiled_header_c/xmake.lua
index 6d36c0f16..3fd1905b0 100644
--- a/tests/projects/precompiled_header_c/xmake.lua
+++ b/tests/projects/precompiled_header_c/xmake.lua
@@ -5,8 +5,8 @@ target("main")
set_kind("binary")
-- set precompiled header
- set_precompiled_header("src/header.h", "src/header.c")
+ set_pcheader("src/header.h")
-- add files
- add_files("src/*.c|header.c")
+ add_files("src/*.c", "src/*.cpp")
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index 0263fd982..bd479a879 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -181,7 +181,7 @@ function _build_object(target, buildinfo, index, sourcebatch, ccache)
assert(compiler_instance:compile(sourcefile, objectfile, {depinfo = depinfo, target = target}))
-- save sources to the dependent info
- depinfo.sources = {sourcefile, target:pcsourcefile()}
+ depinfo.sources = table.join(sourcefile, target:pcheaderfile("cxx") or {}, target:pcheaderfile("c"))
-- save program to the dependent info
depinfo.program = compiler_instance:program()
@@ -252,36 +252,29 @@ function _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs,
_g.sourceindex = _g.sourceindex + #sourcebatch.sourcefiles
end
--- build precompiled header (only for c/c++)
-function _build_precompiled_header(target, buildinfo)
+-- build precompiled header files (only for c/c++)
+function _build_pcheaderfiles(target, buildinfo)
- -- get the precompiled header
- local precompiled_header, precompiled_source = target:pcsourcefile()
- if not precompiled_header then
- return
- end
+ -- for c/c++
+ for _, langkind in ipairs({"c", "cxx"}) do
- -- init sourcekinds
- local sourcekinds = {[".h"] = "cc", [".hpp"] = "cxx", [".inl"] = "cxx"}
+ -- get the precompiled header
+ local pcheaderfile = target:pcheaderfile(langkind)
+ if pcheaderfile then
- -- init sourcefile, objectfile and incdepfile
- local sourcefile = precompiled_header
- local objectfile = target:pcheaderfile()
- local incdepfile = objectfile .. ".d"
+ -- init sourcefile, objectfile and incdepfile
+ local sourcefile = pcheaderfile
+ local objectfile = target:pcoutputfile(langkind)
+ local incdepfile = objectfile .. ".d"
+ local sourcekind = language.langkinds()[langkind]
- -- init sourcekind
- local sourcekind = nil
- if precompiled_source then
- sourcekind = language.sourcekind_of(precompiled_source)
- else
- sourcekind = sourcekinds[path.extension(precompiled_header)] or "cc"
- end
+ -- init source batch
+ local sourcebatch = {sourcekind = sourcekind, sourcefiles = {sourcefile}, objectfiles = {objectfile}, incdepfiles = {incdepfile}}
- -- init source batch
- local sourcebatch = {sourcekind = sourcekind, sourcefiles = {sourcefile}, objectfiles = {objectfile}, incdepfiles = {incdepfile}}
-
- -- build this precompiled header
- _build_object(target, buildinfo, 1, sourcebatch, false)
+ -- build this precompiled header
+ _build_object(target, buildinfo, 1, sourcebatch, false)
+ end
+ end
end
-- build objects for the given target
@@ -300,8 +293,8 @@ function build(target, buildinfo)
ccache = find_ccache()
end
- -- build precompiled header
- _build_precompiled_header(target, buildinfo)
+ -- build precompiled headers
+ _build_pcheaderfiles(target, buildinfo)
-- build source batches
for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index 50dec8ad1..e11a35574 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -68,8 +68,9 @@ function _on_clean_target(target)
-- remove the symbol file
_remove(target:symbolfile())
- -- remove the precompiled header file
- _remove(target:pcheaderfile())
+ -- remove the c/c++ precompiled header file
+ _remove(target:pcoutputfile("c"))
+ _remove(target:pcoutputfile("cxx"))
-- remove the object files
_remove(target:objectfiles())
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 54bc7b62d..8f66e37d8 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -726,72 +726,50 @@ function target:configheader(outputdir)
return configheader, outputheader
end
--- get the precompiled source file (.[h|hpp|inl], .[c|cpp])
-function target:pcsourcefile()
-
- -- get it from the cache first
- if self._PCSOURCEFILE then
- return unpack(self._PCSOURCEFILE)
- end
-
- -- get the precompiled header and source file
- local headerfile = nil
- local sourcefile = nil
- for _, file in ipairs(table.wrap(self:get("precompiled_header"))) do
- local extension = path.extension(file)
- if not headerfile and (extension:startswith(".h") or extension == ".inl") then
- headerfile = file
- else
- sourcefile = file
- end
- if headerfile and sourcefile then
- break
- end
- end
-
- -- save to cache
- self._PCSOURCEFILE = {headerfile, sourcefile}
-
- -- ok?
- return headerfile, sourcefile
+-- get the precompiled header file (xxx.[h|hpp|inl])
+--
+-- @param langkind c/cxx
+--
+function target:pcheaderfile(langkind)
+ return self:get("p" .. langkind .. "header")
end
--- get the precompiled header file (xxx.h.pch)
-function target:pcheaderfile()
+-- get the output of precompiled header file (xxx.h.pch)
+--
+-- @param langkind c/cxx
+--
+function target:pcoutputfile(langkind)
- -- get the precompiled header file in the object directory
- local precompiled_header = self:pcsourcefile()
- if precompiled_header then
+ -- init cache
+ self._PCOUTPUTFILES = self._PCOUTPUTFILES or {}
- -- get it from the cache first
- if self._PCHEADERFILE then
- return self._PCHEADERFILE
- end
+ -- get it from the cache first
+ local pcoutputfile = self._PCOUTPUTFILES[langkind]
+ if pcoutputfile then
+ return pcoutputfile
+ end
- -- init sourcekinds
- local sourcekinds = {[".h"] = "cc", [".hpp"] = "cxx", [".inl"] = "cxx"}
-
- -- get source kind
- local sourcekind = sourcekinds[path.extension(precompiled_header)] or "cc"
+ -- get the precompiled header file in the object directory
+ local pcheaderfile = self:pcheaderfile(langkind)
+ if pcheaderfile then
-- load tool instance
- local toolinstance = tool.load(sourcekind)
+ local toolinstance = tool.load(language.langkinds()[langkind])
- -- make precompiled header file
+ -- make precompiled output file
--
-- @note gcc has not -include-pch option to set the pch file path
--
- local pcheaderfile = nil
if toolinstance and toolinstance:name() == "gcc" then
- pcheaderfile = precompiled_header .. ".gch"
+ pcoutputfile = pcheaderfile .. ".gch"
else
- local headerdir = path.directory(precompiled_header):gsub("%.%.", "__")
- pcheaderfile = string.format("%s/%s/%s/%s", self:objectdir(), self:name(), headerdir, path.filename(precompiled_header) .. ".pch")
+ local headerdir = path.directory(pcheaderfile):gsub("%.%.", "__")
+ pcoutputfile = string.format("%s/%s/%s/%s", self:objectdir(), self:name(), headerdir, path.filename(pcheaderfile) .. ".pch")
end
-- save to cache
- self._PCHEADERFILE = pcheaderfile
- return pcheaderfile
+ self._PCOUTPUTFILES[langkind] = pcoutputfile
+ return pcoutputfile
end
end
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
index 23db1044c..8d0fdabf0 100644
--- a/xmake/core/tool/builder.lua
+++ b/xmake/core/tool/builder.lua
@@ -40,22 +40,16 @@ local platform = require("platform/platform")
-- get the tool of builder
function builder:_tool()
-
- -- get it
return self._TOOL
end
-- get the name flags
function builder:_nameflags()
-
- -- get it
return self._NAMEFLAGS
end
-- get the target kind
function builder:_targetkind()
-
- -- get it
return self._TARGETKIND
end
diff --git a/xmake/languages/c++/api.lua b/xmake/languages/c++/api.lua
index 78f89ac6f..2258cfad7 100644
--- a/xmake/languages/c++/api.lua
+++ b/xmake/languages/c++/api.lua
@@ -208,7 +208,8 @@ function apis()
"target.set_headerdir"
, "target.set_config_h" -- deprecated
, "target.set_config_header"
- , "target.set_precompiled_header"
+ , "target.set_pcheader"
+ , "target.set_pcxxheader"
-- target.add_xxx
, "target.add_headers"
, "target.add_linkdirs"
diff --git a/xmake/languages/c++/xmake.lua b/xmake/languages/c++/xmake.lua
index e39dce940..e5add6b6e 100644
--- a/xmake/languages/c++/xmake.lua
+++ b/xmake/languages/c++/xmake.lua
@@ -67,7 +67,8 @@ language("c++")
, "target.undefines"
, "target.frameworkdirs"
, "target.frameworks"
- , "target.precompiled_header"
+ , "target.pcheader"
+ , "target.pcxxheader"
, "option.symbols"
, "option.warnings"
, "option.optimize:check"
diff --git a/xmake/languages/objc++/api.lua b/xmake/languages/objc++/api.lua
index 63e311c33..f09b99119 100644
--- a/xmake/languages/objc++/api.lua
+++ b/xmake/languages/objc++/api.lua
@@ -71,7 +71,8 @@ function apis()
"target.set_headerdir"
, "target.set_config_h" -- deprecated
, "target.set_config_header"
- , "target.set_precompiled_header"
+ , "target.set_pcheader"
+ , "target.set_pcxxheader"
-- target.add_xxx
, "target.add_headers"
, "target.add_linkdirs"
diff --git a/xmake/languages/objc++/xmake.lua b/xmake/languages/objc++/xmake.lua
index 768d8d400..009a662e4 100644
--- a/xmake/languages/objc++/xmake.lua
+++ b/xmake/languages/objc++/xmake.lua
@@ -67,7 +67,8 @@ language("objc++")
, "target.undefines"
, "target.frameworkdirs"
, "target.frameworks"
- , "target.precompiled_header"
+ , "target.pcheader"
+ , "target.pcxxheader"
, "option.symbols"
, "option.warnings"
, "option.optimize:check"
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index d02982d12..bf5bc786f 100644
--- a/xmake/modules/core/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -202,41 +202,37 @@ function nf_includedir(self, dir)
return "-I" .. dir
end
--- make the precompiled header flag
-function nf_precompiled_header(self, headerfile, target)
+-- make the c precompiled header flag
+function nf_pcheader(self, pcheaderfile, target)
- -- cache precompiled source file
- local _, sourcefile = target:pcsourcefile()
- if sourcefile then
+ -- for c source file
+ if self:kind() == "cc" then
- -- parse headerfile from sourcefile
- if os.isfile(sourcefile) then
- local sourcedata = io.readfile(sourcefile)
- if sourcedata then
- local includefile = sourcedata:match("#include%s+[<\"](.+)[>\"]")
- if includefile then
- headerfile = includefile
- end
- end
+ -- patch objectfile
+ local objectfiles = target:objectfiles()
+ if objectfiles then
+ table.insert(objectfiles, target:pcoutputfile("c") .. ".obj")
end
- -- cache sourcefile
- _g._PCHSOURCEFILES = _g._PCHSOURCEFILES or {}
- _g._PCHSOURCEFILES[target:pcheaderfile()] = sourcefile
- else
- headerfile = path.filename(headerfile)
+ -- make flag
+ return "-Yu" .. path.filename(pcheaderfile) .. " -Fp" .. target:pcoutputfile("c")
end
+end
- -- patch objectfile
- local objectfiles = target:objectfiles()
- if objectfiles then
- table.insert(objectfiles, target:pcheaderfile() .. ".obj")
- end
+-- make the c++ precompiled header flag
+function nf_pcxxheader(self, pcheaderfile, target)
- -- make flag
- local extension = path.extension(headerfile)
- if (extension:startswith(".h") or extension == ".inl") then
- return "-Yu" .. headerfile .. " -Fp" .. target:pcheaderfile()
+ -- for c++ source file
+ if self:kind() == "cxx" then
+
+ -- patch objectfile
+ local objectfiles = target:objectfiles()
+ if objectfiles then
+ table.insert(objectfiles, target:pcoutputfile("cxx") .. ".obj")
+ end
+
+ -- make flag
+ return "-Yu" .. path.filename(pcheaderfile) .. " -Fp" .. target:pcoutputfile("cxx")
end
end
@@ -268,7 +264,7 @@ function _include_deps(self, outdata)
end
-- make the complie arguments list for the precompiled header
-function _compargv1_pch(self, headerfile, objectfile, flags)
+function _compargv1_pch(self, pcheaderfile, pcoutputfile, flags)
-- remove "-Yuxxx.h" and "-Fpxxx.pch"
local pchflags = {}
@@ -278,27 +274,15 @@ function _compargv1_pch(self, headerfile, objectfile, flags)
end
end
- -- get pcheaderfile
- local pcheaderfile = objectfile
-
- -- get sourcefile from the *.pch file
- local sourcefile = nil
- if _g._PCHSOURCEFILES then
- sourcefile = _g._PCHSOURCEFILES[pcheaderfile]
- end
-
- -- make it if no sourcefile
- if not sourcefile then
- sourcefile = os.tmpfile() .. language.extension_of(self:kind())
- io.writefile(sourcefile, format("#include \"%s\"", path.filename(headerfile)))
- table.insert(pchflags, "-I" .. path.directory(headerfile))
+ -- compile as c/c++ source file
+ if self:kind() == "cc" then
+ table.insert(pchflags, "-TC")
+ elseif self:kind() == "cxx" then
+ table.insert(pchflags, "-TP")
end
- -- make objectfile
- objectfile = pcheaderfile .. ".obj"
-
-- make complie arguments list
- return self:program(), table.join("-c", "-Yc", pchflags, "-Fp" .. pcheaderfile, "-Fo" .. objectfile, sourcefile)
+ return self:program(), table.join("-c", "-Yc", pchflags, "-Fp" .. pcoutputfile, "-Fo" .. pcoutputfile .. ".obj", pcheaderfile)
end
-- make the complie arguments list
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index b8f34942f..96413b718 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -250,14 +250,24 @@ function nf_frameworkdir(self, frameworkdir)
return "-F " .. frameworkdir
end
--- make the precompiled header flag
-function nf_precompiled_header(self, headerfile, target)
- local extension = path.extension(headerfile)
- if (extension:startswith(".h") or extension == ".inl") then
+-- make the c precompiled header flag
+function nf_pcheader(self, pcheaderfile, target)
+ if self:kind() == "cc" then
+ if self:name() == "clang" then
+ return "-include " .. pcheaderfile .. " -include-pch " .. target:pcoutputfile("c")
+ else
+ return "-include " .. pcheaderfile
+ end
+ end
+end
+
+-- make the c++ precompiled header flag
+function nf_pcxxheader(self, pcheaderfile, target)
+ if self:kind() == "cxx" then
if self:name() == "clang" then
- return "-include " .. headerfile .. " -include-pch " .. target:pcheaderfile()
+ return "-include " .. pcheaderfile .. " -include-pch " .. target:pcoutputfile("cxx")
else
- return "-include " .. headerfile
+ return "-include " .. pcheaderfile
end
end
end
@@ -314,10 +324,10 @@ function _include_deps(self, sourcefile, flags)
end
-- make the complie arguments list for the precompiled header
-function _compargv1_pch(self, headerfile, objectfile, flags)
+function _compargv1_pch(self, pcheaderfile, pcoutputfile, flags)
-- init key and cache
- local key = headerfile .. tostring(flags)
+ local key = pcheaderfile .. tostring(flags)
_g._PCHFLAGS = _g._PCHFLAGS or {}
-- remove "-include xxx.h" and "-include-pch xxx.pch"
@@ -333,7 +343,7 @@ function _compargv1_pch(self, headerfile, objectfile, flags)
end
-- compile header.h as c++?
- if self:kind() == "cxx" and headerfile:endswith(".h") then
+ if self:kind() == "cxx" then
table.insert(pchflags, "-x")
table.insert(pchflags, "c++-header")
end
@@ -342,7 +352,7 @@ function _compargv1_pch(self, headerfile, objectfile, flags)
_g._PCHFLAGS[key] = pchflags
-- make complie arguments list
- return self:program(), table.join("-c", pchflags, "-o", objectfile, headerfile)
+ return self:program(), table.join("-c", pchflags, "-o", pcoutputfile, pcheaderfile)
end
-- make the complie arguments list
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index fad5549bb..3e3e3ab4b 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -80,7 +80,8 @@ function _make_target(jsonfile, target)
-- TODO
-- disable precompiled header first
- target:set("precompiled_header", nil)
+ target:set("pcheader", nil)
+ target:set("pcxxheader", nil)
-- build source batches
for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
diff --git a/xmake/plugins/project/makefile/makefile.lua b/xmake/plugins/project/makefile/makefile.lua
index f0326e6e2..811c9e98f 100644
--- a/xmake/plugins/project/makefile/makefile.lua
+++ b/xmake/plugins/project/makefile/makefile.lua
@@ -351,7 +351,8 @@ function _make_all(makefile)
-- TODO
-- disable precompiled header first
for _, target in pairs(project.targets()) do
- target:set("precompiled_header", nil)
+ target:set("pcheader", nil)
+ target:set("pcxxheader", nil)
end
-- make variables for target flags
diff --git a/xmake/plugins/project/vstudio/impl/vs200x.lua b/xmake/plugins/project/vstudio/impl/vs200x.lua
index 6a14613d7..10207467b 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x.lua
@@ -42,7 +42,8 @@ function make(outputdir, vsinfo)
-- TODO
-- disable precompiled header first
for _, target in pairs(project.targets()) do
- target:set("precompiled_header", nil)
+ target:set("pcheader", nil)
+ target:set("pcxxheader", nil)
end
-- make vsprojs
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index 7b470e94e..bf638d031 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -47,9 +47,11 @@ function _make_targetinfo(mode, arch, target)
targetinfo.sdkver = (vcvarsall[arch] or {}).sdkver
end
- -- save precompiled header file (.pch)
- targetinfo.pcheaderfile = target:pcheaderfile()
- target:set("precompiled_header", nil)
+ -- save c/c++ precompiled output file (.pch)
+ targetinfo.pcoutputfile = target:pcoutputfile("c")
+ targetinfo.pcxxoutputfile = target:pcoutputfile("cxx")
+ target:set("pcheader", nil)
+ target:set("pcxxheader", nil)
-- save symbols
targetinfo.symbols = target:get("symbols")
@@ -197,10 +199,9 @@ function make(outputdir, vsinfo)
targets[targetname] = targets[targetname] or {}
local _target = targets[targetname]
- -- save precompiled header and source
- local precompiled_header, precompiled_source = target:pcsourcefile()
- _target.pcheader = precompiled_header -- header.h
- _target.pcsourcefile = precompiled_source -- header.cpp
+ -- save c/c++ precompiled header
+ _target.pcheader = target:pcheaderfile("c") -- header.h
+ _target.pcxxheader = target:pcheaderfile("cxx") -- header.[hpp|inl]
-- init target info
_target.name = targetname
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
index d302b1bf4..7abe20a54 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
@@ -24,6 +24,7 @@
-- imports
import("core.project.config")
+import("core.language.language")
import("vsfile")
-- make compiling flags
@@ -376,26 +377,16 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo, vcxprojdir)
vcxprojfile:print("<ProgramDatabaseFile>%s</ProgramDatabaseFile>", path.relative(path.absolute(symbolfile), vcxprojdir))
end
- -- use precompiled header
- if target.pcheader then
+ -- use c or c++ precompiled header
+ local pcheader = target.pcxxheader or target.pcheader
+ if pcheader then
- -- get precompiled header file
- local pcheader = path.filename(target.pcheader)
- if target.pcsourcefile and os.isfile(target.pcsourcefile) then
- local sourcedata = io.readfile(target.pcsourcefile)
- if sourcedata then
- local includefile = sourcedata:match("#include%s+[<\"](.+)[>\"]")
- if includefile then
- pcheader = includefile
- end
- end
- end
-
-- make precompiled header and outputfile
vcxprojfile:print("<PrecompiledHeader>Use</PrecompiledHeader>")
- vcxprojfile:print("<PrecompiledHeaderFile>%s</PrecompiledHeaderFile>", pcheader)
- if targetinfo.pcheaderfile then
- vcxprojfile:print("<PrecompiledHeaderOutputFile>%s</PrecompiledHeaderOutputFile>", path.relative(path.absolute(targetinfo.pcheaderfile), vcxprojdir))
+ vcxprojfile:print("<PrecompiledHeaderFile>%s</PrecompiledHeaderFile>", path.filename(pcheader))
+ local pcoutputfile = targetinfo.pcxxoutputfile or targetinfo.pcoutputfile
+ if pcoutputfile then
+ vcxprojfile:print("<PrecompiledHeaderOutputFile>%s</PrecompiledHeaderOutputFile>", path.relative(path.absolute(pcoutputfile), vcxprojdir))
end
end
@@ -476,7 +467,7 @@ function _make_header_file(vcxprojfile, includefile, vcxprojdir)
end
-- make source file for all modes
-function _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir)
+function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
-- get object file and source kind
local sourcekind = nil
@@ -542,10 +533,20 @@ function _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, v
end
end
+ -- disable the precompiled header if sourcekind ~= headerkind
+ local pcheader = target.pcxxheader or target.pcheader
+ local pcheader_disable = false
+ if pcheader and language.sourcekind_of(sourcefile) ~= ifelse(target.pcxxheader, "cxx", "cc") then
+ pcheader_disable = true
+ end
+
-- all modes and archs exist?
if count == #vsinfo.modes then
if #key > 0 then
vcxprojfile:print("<%s>%s</%s>", itemname, iteminfo.value(key), itemname)
+ if pcheader_disable then
+ vcxprojfile:print("<PrecompiledHeader>NotUsing</PrecompiledHeader>")
+ end
end
else
for cond, _ in pairs(mergeinfos) do
@@ -553,11 +554,17 @@ function _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, v
-- for mode | arch
if #key > 0 then
vcxprojfile:print("<%s Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s\'\">%s</%s>", itemname, cond, iteminfo.value(key), itemname)
+ if pcheader_disable then
+ vcxprojfile:print("<PrecompiledHeader Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s\'\">NotUsing</PrecompiledHeader>", cond)
+ end
end
else
-- only for mode
if #key > 0 then
vcxprojfile:print("<%s Condition=\"\'%$(Configuration)\'==\'%s\'\">%s</%s>", itemname, cond, iteminfo.value(key), itemname)
+ if pcheader_disable then
+ vcxprojfile:print("<PrecompiledHeader Condition=\"\'%$(Configuration)\'==\'%s\'\">NotUsing</PrecompiledHeader>", cond)
+ end
end
end
end
@@ -571,7 +578,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, v
end
-- make source file for specific modes
-function _make_source_file_forspec(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir)
+function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
-- add source file
sourcefile = path.relative(path.absolute(sourcefile), vcxprojdir)
@@ -590,6 +597,12 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, sourcefile, sourceinfo,
-- for *.c/cpp files
else
+
+ -- disable the precompiled header if sourcekind ~= headerkind
+ local pcheader = target.pcxxheader or target.pcheader
+ if pcheader and language.sourcekind_of(sourcefile) ~= ifelse(target.pcxxheader, "cxx", "cc") then
+ vcxprojfile:print("<PrecompiledHeader>NotUsing</PrecompiledHeader>")
+ end
vcxprojfile:print("<ObjectFileName>%s</ObjectFileName>", objectfile)
vcxprojfile:print("<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>", os.args(info.flags))
end
@@ -600,18 +613,31 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, sourcefile, sourceinfo,
end
-- make source file for precompiled header
-function _make_source_file_forpch(vcxprojfile, vsinfo, pcsourcefile, targetinfo, vcxprojdir)
+function _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
-- add precompiled source file
- local sourcefile = path.relative(path.absolute(pcsourcefile), vcxprojdir)
- vcxprojfile:enter("<ClCompile Include=\"%s\">", sourcefile)
- vcxprojfile:print("<PrecompiledHeader>Create</PrecompiledHeader>")
- vcxprojfile:print("<AdditionalOptions> %%(AdditionalOptions)</AdditionalOptions>")
- for _, info in ipairs(targetinfo) do
- local objectfile = path.relative(path.absolute(info.pcheaderfile .. ".obj"), vcxprojdir)
- vcxprojfile:print("<ObjectFileName Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">%s</ObjectFileName>", info.mode, info.arch, objectfile)
- end
- vcxprojfile:leave("</ClCompile>")
+ local pcheader = target.pcxxheader or target.pcheader
+ if pcheader then
+ local sourcefile = path.relative(path.absolute(pcheader), vcxprojdir)
+ vcxprojfile:enter("<ClCompile Include=\"%s\">", sourcefile)
+ vcxprojfile:print("<PrecompiledHeader>Create</PrecompiledHeader>")
+ vcxprojfile:print("<PrecompiledHeaderFile></PrecompiledHeaderFile>")
+ vcxprojfile:print("<AdditionalOptions> %%(AdditionalOptions)</AdditionalOptions>")
+ for _, info in ipairs(target.info) do
+
+ -- compile as c/c++
+ local compileas = ifelse(target.pcxxheader, "CompileAsCpp", "CompileAsC")
+ vcxprojfile:print("<CompileAs Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">%s</CompileAs>", info.mode, info.arch, compileas)
+
+ -- add object file
+ local pcoutputfile = info.pcxxoutputfile or info.pcoutputfile
+ if pcoutputfile then
+ local objectfile = path.relative(path.absolute(pcoutputfile .. ".obj"), vcxprojdir)
+ vcxprojfile:print("<ObjectFileName Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">%s</ObjectFileName>", info.mode, info.arch, objectfile)
+ end
+ end
+ vcxprojfile:leave("</ClCompile>")
+ end
end
-- make source files
@@ -639,16 +665,14 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
-- make source files
for sourcefile, sourceinfo in pairs(sourceinfos) do
if #sourceinfo == #target.info then
- _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir)
+ _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
else
- _make_source_file_forspec(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir)
+ _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sourceinfo, vcxprojdir)
end
end
-- make precompiled source file
- if target.pcsourcefile then
- _make_source_file_forpch(vcxprojfile, vsinfo, target.pcsourcefile, target.info, vcxprojdir)
- end
+ _make_source_file_forpch(vcxprojfile, vsinfo, target, vcxprojdir)
vcxprojfile:leave("</ItemGroup>")
@@ -657,9 +681,6 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir)
for _, includefile in ipairs(target.headerfiles) do
_make_header_file(vcxprojfile, includefile, vcxprojdir)
end
- if target.pcheader then
- _make_header_file(vcxprojfile, target.pcheader, vcxprojdir)
- end
vcxprojfile:leave("</ItemGroup>")
end
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua
index c2432b4df..f15fa9c5f 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua
@@ -98,13 +98,14 @@ function _make_sources(filtersfile, vsinfo, target, vcxprojdir)
filtersfile:print("<Filter>%s</Filter>", filter)
filtersfile:leave("</%s>", ifelse(as, "CustomBuild", "ClCompile"))
end
- end
- if target.pcsourcefile then
- local filter = _make_filter(target.pcsourcefile, target, vcxprojdir)
- if filter then
- filtersfile:enter("<ClCompile Include=\"%s\">", path.relative(path.absolute(target.pcsourcefile), vcxprojdir))
- filtersfile:print("<Filter>%s</Filter>", filter)
- filtersfile:leave("</ClCompile>")
+ local pcheader = target.pcxxheader or target.pcheader
+ if pcheader then
+ local filter = _make_filter(pcheader, target, vcxprojdir)
+ if filter then
+ filtersfile:enter("<ClCompile Include=\"%s\">", path.relative(path.absolute(pcheader), vcxprojdir))
+ filtersfile:print("<Filter>%s</Filter>", filter)
+ filtersfile:leave("</ClCompile>")
+ end
end
end
filtersfile:leave("</ItemGroup>")
@@ -123,14 +124,6 @@ function _make_headers(filtersfile, vsinfo, target, vcxprojdir)
filtersfile:leave("</ClInclude>")
end
end
- if target.pcheader then
- local filter = _make_filter(target.pcheader, target, vcxprojdir)
- if filter then
- filtersfile:enter("<ClInclude Include=\"%s\">", path.relative(path.absolute(target.pcheader), vcxprojdir))
- filtersfile:print("<Filter>%s</Filter>", filter)
- filtersfile:leave("</ClInclude>")
- end
- end
filtersfile:leave("</ItemGroup>")
end