summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2018-12-25 00:52:14 +0800
committerruki <[email protected]>2018-12-24 23:13:27 +0800
commit5420bfcb78df27235e76157136aa695473d07758 (patch)
tree0ddaf6e18349e85b4e00c3d6bd8acf7eca5b2d84
parent42de73ec9745599c166fc97ada4faa28c5a45e55 (diff)
improve precompilied headerfile
-rw-r--r--CHANGELOG.md2
-rw-r--r--tests/projects/c++/precompiled_header/src/header.h13
-rw-r--r--tests/projects/c++/precompiled_header/src/header2.h0
-rw-r--r--tests/projects/c++/precompiled_header/src/main.cpp3
-rw-r--r--tests/projects/c++/precompiled_header/src/test3.cpp8
-rw-r--r--tests/projects/c++/precompiled_header/test3.cpp8
-rw-r--r--tests/projects/c++/precompiled_header/xmake.lua2
-rw-r--r--xmake/actions/build/kinds/object.lua2
-rw-r--r--xmake/core/project/target.lua8
-rw-r--r--xmake/modules/core/tools/gcc.lua93
10 files changed, 72 insertions, 67 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95f068ae0..ca291661e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
* Improve to switch version and debug mode for the dependent packages
* [#264](https://github.com/tboox/xmake/issues/264): Support `xmake update dev` on windows
* [#293](https://github.com/tboox/xmake/issues/293): Add `xmake f/g --mingw=xxx` configuration option and improve to find_mingw
+* [#301](https://github.com/tboox/xmake/issues/301): Improve precompiled header file
### Bugs fixed
@@ -547,6 +548,7 @@
* 针对远程依赖包,改进版本和调试模式切换
* [#264](https://github.com/tboox/xmake/issues/264): 支持在windows上更新dev/master版本,`xmake update dev`
* [#293](https://github.com/tboox/xmake/issues/293): 添加`xmake f/g --mingw=xxx` 配置选线,并且改进find_mingw检测
+* [#301](https://github.com/tboox/xmake/issues/301): 改进编译预处理头文件以及依赖头文件生成,编译速度提升30%
### Bugs修复
diff --git a/tests/projects/c++/precompiled_header/src/header.h b/tests/projects/c++/precompiled_header/src/header.h
index d62b78383..affda55ca 100644
--- a/tests/projects/c++/precompiled_header/src/header.h
+++ b/tests/projects/c++/precompiled_header/src/header.h
@@ -1,7 +1,7 @@
// header.h
#ifndef HEADER_H
#define HEADER_H
-
+
#include <algorithm>
#include <deque>
#include <iostream>
@@ -11,6 +11,17 @@
//#include <thread>
#include <utility>
#include <vector>
+#include <string>
+#include <queue>
+#include <cstdlib>
+#include <utility>
+#include <exception>
+#include <list>
+#include <stack>
+#include <complex>
+#include <fstream>
+#include <cstdio>
+#include <iomanip>
#endif
diff --git a/tests/projects/c++/precompiled_header/src/header2.h b/tests/projects/c++/precompiled_header/src/header2.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/projects/c++/precompiled_header/src/header2.h
diff --git a/tests/projects/c++/precompiled_header/src/main.cpp b/tests/projects/c++/precompiled_header/src/main.cpp
index f0408cdf8..27d41ee50 100644
--- a/tests/projects/c++/precompiled_header/src/main.cpp
+++ b/tests/projects/c++/precompiled_header/src/main.cpp
@@ -2,6 +2,7 @@
int main(int argc, char** argv)
{
- printf("hello xmake!\n");
+ std::string s("xmake");
+ printf("hello %s!\n", s.c_str());
return 0;
}
diff --git a/tests/projects/c++/precompiled_header/src/test3.cpp b/tests/projects/c++/precompiled_header/src/test3.cpp
deleted file mode 100644
index b4ce69b0f..000000000
--- a/tests/projects/c++/precompiled_header/src/test3.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-
-// main.cpp
-#include "header.h"
-
-int test3()
-{
- return 0;
-}
diff --git a/tests/projects/c++/precompiled_header/test3.cpp b/tests/projects/c++/precompiled_header/test3.cpp
new file mode 100644
index 000000000..7daf91dd7
--- /dev/null
+++ b/tests/projects/c++/precompiled_header/test3.cpp
@@ -0,0 +1,8 @@
+
+#include "src/header.h"
+#include "src/header2.h"
+
+int test3()
+{
+ return 0;
+}
diff --git a/tests/projects/c++/precompiled_header/xmake.lua b/tests/projects/c++/precompiled_header/xmake.lua
index 685eca1cd..337f7a7fe 100644
--- a/tests/projects/c++/precompiled_header/xmake.lua
+++ b/tests/projects/c++/precompiled_header/xmake.lua
@@ -11,5 +11,5 @@ target("main")
set_pcxxheader("src/header.h")
-- add files
- add_files("src/*.cpp", "src/*.c")
+ add_files("src/*.cpp", "src/*.c", "*.cpp")
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index 7a6039f70..d6b772671 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -139,7 +139,7 @@ function _do_build_file(target, sourcefile, opt)
-- update files and values to the dependent file
dependinfo.values = depvalues
- table.join2(dependinfo.files, sourcefile, target:pcheaderfile("cxx") or {}, target:pcheaderfile("c"))
+ table.join2(dependinfo.files, sourcefile, target:pcoutputfile("cxx") or {}, target:pcoutputfile("c"))
depend.save(dependinfo, dependfile)
end
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 2332fcf93..15dbd0788 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -1392,12 +1392,8 @@ function target:pcoutputfile(langkind)
--
-- @note gcc has not -include-pch option to set the pch file path
--
- if toolinstance and toolinstance:name() == "gcc" then
- pcoutputfile = pcheaderfile .. ".gch"
- else
- local headerdir = path.directory(pcheaderfile):gsub("%.%.", "__")
- pcoutputfile = string.format("%s/%s/%s/%s", self:objectdir(), self:name(), headerdir, path.filename(pcheaderfile) .. ".pch")
- end
+ pcoutputfile = self:objectfile(pcheaderfile)
+ pcoutputfile = path.join(path.directory(pcoutputfile), path.basename(pcoutputfile) .. (toolinstance and toolinstance:name() == "gcc" and ".gch" or ".pch"))
-- save to cache
self._PCOUTPUTFILES[langkind] = pcoutputfile
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 89773c85c..15a0d37bf 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -277,10 +277,11 @@ end
-- make the c precompiled header flag
function nf_pcheader(self, pcheaderfile, target)
if self:kind() == "cc" then
+ local pcoutputfile = target:pcoutputfile("c")
if self:name() == "clang" then
- return "-include " .. os.args(pcheaderfile) .. " -include-pch " .. os.args(target:pcoutputfile("c"))
+ return "-include " .. os.args(pcheaderfile) .. " -include-pch " .. os.args(pcoutputfile)
else
- return "-include " .. os.args(pcheaderfile)
+ return "-include " .. path.filename(pcheaderfile) .. " -I" .. os.args(path.directory(pcoutputfile))
end
end
end
@@ -288,10 +289,11 @@ end
-- make the c++ precompiled header flag
function nf_pcxxheader(self, pcheaderfile, target)
if self:kind() == "cxx" then
+ local pcoutputfile = target:pcoutputfile("cxx")
if self:name() == "clang" then
- return "-include " .. os.args(pcheaderfile) .. " -include-pch " .. os.args(target:pcoutputfile("cxx"))
+ return "-include " .. os.args(pcheaderfile) .. " -include-pch " .. os.args(pcoutputfile)
else
- return "-include " .. os.args(pcheaderfile)
+ return "-include " .. path.filename(pcheaderfile) .. " -I" .. os.args(path.directory(pcoutputfile))
end
end
end
@@ -326,56 +328,39 @@ function link(self, objectfiles, targetkind, targetfile, flags)
end
-- get include deps
-function _include_deps(self, sourcefile, flags)
+function _include_deps(self, outdata)
- -- support -E -MM? some old gcc does not support it at same time
- if _g._HAS_EMM == nil then
- _g._HAS_EMM = self:has_flags("-E -MM", "cxflags")
- end
- if not _g._HAS_EMM then
- return {}
- end
-
- -- the temporary file
- local tmpfile = os.tmpfile()
+ -- translate it
+ local results = {}
+ local uniques = {}
+ for _, line in ipairs(outdata:split("\n")) do
- -- uses pchflags for precompiled header
- if _g._PCHFLAGS then
- local key = sourcefile .. tostring(flags)
- local pchflags = _g._PCHFLAGS[key]
- if pchflags then
- flags = pchflags
- end
- end
+ -- get includefile, e.g. '! xxx.gch' or '... xxx.h'
+ if line:startswith("!") or line:startswith(".") then
+ local includefile = line:split("%s")[2]
+ if includefile then
- -- generate it
- os.runv(self:program(), table.join("-c", "-E", "-MM", flags or {}, "-o", tmpfile, sourcefile))
+ -- get the relative
+ includefile = path.relative(includefile, project.directory())
- -- translate it
- results = {}
- local deps = io.readfile(tmpfile)
- for includefile in string.gmatch(deps, "%s+([%w/%.%-%+_%$%.]+)") do
+ -- save it if belong to the project
+ if path.absolute(includefile):startswith(os.projectdir()) then
- -- save it if belong to the project
- if path.absolute(includefile):startswith(os.projectdir()) then
- table.insert(results, includefile)
+ -- insert it and filter repeat
+ if not uniques[includefile] then
+ table.insert(results, includefile)
+ uniques[includefile] = true
+ end
+ end
+ end
end
end
-
- -- remove the temporary file
- os.rm(tmpfile)
-
- -- ok?
return results
end
-- make the complie arguments list for the precompiled header
function _compargv1_pch(self, pcheaderfile, pcoutputfile, flags)
- -- init key and cache
- local key = pcheaderfile .. tostring(flags)
- _g._PCHFLAGS = _g._PCHFLAGS or {}
-
-- remove "-include xxx.h" and "-include-pch xxx.pch"
local pchflags = {}
local include = false
@@ -396,9 +381,6 @@ function _compargv1_pch(self, pcheaderfile, pcoutputfile, flags)
table.insert(pchflags, "c++-header")
end
- -- save pchflags to cache
- _g._PCHFLAGS[key] = pchflags
-
-- make complie arguments list
return self:program(), table.join("-c", pchflags, "-o", pcoutputfile, pcheaderfile)
end
@@ -445,11 +427,24 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags)
os.mkdir(path.directory(objectfile))
-- compile it
- try
+ local outdata = try
{
function ()
- local outdata, errdata = os.iorunv(_compargv1(self, sourcefile, objectfile, flags))
- return (outdata or "") .. (errdata or "")
+
+ -- support -H? some old gcc does not support it at same time
+ if _g._HAS_H == nil then
+ _g._HAS_H = self:has_flags("-H", "cxflags")
+ end
+
+ -- generate includes file
+ local compflags = flags
+ if dependinfo and _g._HAS_H then
+ compflags = table.join(flags, "-H")
+ end
+
+ -- do compile
+ local outs, errs = os.iorunv(_compargv1(self, sourcefile, objectfile, compflags))
+ return (outs or "") .. (errs or "")
end,
catch
{
@@ -495,9 +490,9 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags)
}
-- generate the dependent includes
- if dependinfo and self:kind() ~= "as" then
+ if dependinfo and self:kind() ~= "as" and outdata then
dependinfo.files = dependinfo.files or {}
- table.join2(dependinfo.files, _include_deps(self, sourcefile, flags))
+ table.join2(dependinfo.files, _include_deps(self, outdata))
end
end