summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-07-19 14:56:46 +0800
committerruki <[email protected]>2017-07-19 14:56:46 +0800
commitf22b46466ebed2df42379172a31107e071b99979 (patch)
treecb8dbafadd4bfc0fa85c40b2c239c1c1b0f91bf4
parent8119b93a66582b3b2f0443f5984b7a0336c30c8f (diff)
export compile_commands.json for clang tools
-rw-r--r--CHANGELOG.md2
-rw-r--r--xmake/actions/build/main.lua4
-rw-r--r--xmake/actions/clean/main.lua4
-rw-r--r--xmake/actions/config/configheader.lua4
-rw-r--r--xmake/actions/install/install.lua4
-rw-r--r--xmake/actions/package/main.lua4
-rw-r--r--xmake/actions/run/main.lua4
-rw-r--r--xmake/actions/uninstall/uninstall.lua4
-rw-r--r--xmake/core/base/interpreter.lua8
-rw-r--r--xmake/modules/core/tools/ar.lua4
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua128
-rw-r--r--xmake/plugins/project/main.lua22
-rw-r--r--xmake/plugins/project/makefile/makefile.lua4
-rw-r--r--xmake/plugins/project/vstudio/impl/vs200x.lua4
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua4
-rw-r--r--xmake/plugins/project/xmake.lua3
16 files changed, 171 insertions, 36 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba3975d98..3f1377a4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@
* Add `lib.detect.has_xxx` and `lib.detect.find_xxx` apis.
* Add `add_moduledirs` api
* Add `includes` api instead of `add_subdirs` and `add_subfiles`
+* [#133](https://github.com/tboox/xmake/issues/133): Improve the project plugin to generate `compile_commands.json` by run `xmake project -k compile_commands`
### Changes
@@ -328,6 +329,7 @@
* 添加`lib.detect.has_xxx`和`lib.detect.find_xxx`接口
* 添加`add_moduledirs`接口在工程中定义和加载扩展模块
* 添加`includes`接口替换`add_subdirs`和`add_subfiles`
+* [#133](https://github.com/tboox/xmake/issues/133): 改进工程插件,通过运行`xmake project -k compile_commands`来导出`compile_commands.json`
### 改进
diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua
index 95ea22206..eeeeb2318 100644
--- a/xmake/actions/build/main.lua
+++ b/xmake/actions/build/main.lua
@@ -61,7 +61,7 @@ function main()
cache.flush()
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- build it
try
@@ -89,7 +89,7 @@ function main()
}
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
-- trace
if rebuild then
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index 07a10d72e..f35c0e224 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -158,11 +158,11 @@ function main()
_g.finished = {}
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- clean the current target
_clean(targetname)
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/actions/config/configheader.lua b/xmake/actions/config/configheader.lua
index 1aa0aabdb..ccae5237d 100644
--- a/xmake/actions/config/configheader.lua
+++ b/xmake/actions/config/configheader.lua
@@ -133,7 +133,7 @@ function make()
local targetname = option.get("target")
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- init files
local files = {}
@@ -154,5 +154,5 @@ function make()
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/actions/install/install.lua b/xmake/actions/install/install.lua
index 31f23a667..c3c36e61c 100644
--- a/xmake/actions/install/install.lua
+++ b/xmake/actions/install/install.lua
@@ -31,7 +31,7 @@ import("core.platform.platform")
function _install_target(target)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- the target scripts
local scripts =
@@ -50,7 +50,7 @@ function _install_target(target)
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
-- install the given target and deps
diff --git a/xmake/actions/package/main.lua b/xmake/actions/package/main.lua
index 80d6ac70c..ae88d661c 100644
--- a/xmake/actions/package/main.lua
+++ b/xmake/actions/package/main.lua
@@ -142,7 +142,7 @@ end
function _package(target)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- the target scripts
local scripts =
@@ -161,7 +161,7 @@ function _package(target)
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
-- package the given target and deps
diff --git a/xmake/actions/run/main.lua b/xmake/actions/run/main.lua
index 5127e8b68..ee30b6c7c 100644
--- a/xmake/actions/run/main.lua
+++ b/xmake/actions/run/main.lua
@@ -89,7 +89,7 @@ function main()
task.run("build", {target = targetname, all = option.get("all")})
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- run the given target?
if targetname then
@@ -107,5 +107,5 @@ function main()
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/actions/uninstall/uninstall.lua b/xmake/actions/uninstall/uninstall.lua
index 3d0c6e0c7..8f468c29c 100644
--- a/xmake/actions/uninstall/uninstall.lua
+++ b/xmake/actions/uninstall/uninstall.lua
@@ -31,7 +31,7 @@ import("core.platform.platform")
function _uninstall_target(target)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- the target scripts
local scripts =
@@ -50,7 +50,7 @@ function _uninstall_target(target)
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
-- uninstall the given target and deps
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index e6d3e683a..49592e082 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -417,7 +417,7 @@ function interpreter:_api_builtin_add_subdirfiles(...)
scopes._CURRENT = nil
-- save the current directory
- local olddir = os.curdir()
+ local oldir = os.curdir()
-- enter the script directory
os.cd(path.directory(file))
@@ -429,7 +429,7 @@ function interpreter:_api_builtin_add_subdirfiles(...)
end
-- leave the script directory
- os.cd(olddir)
+ os.cd(oldir)
-- restore the previous scope kind
scopes._CURRENT_KIND = scope_kind_prev
@@ -1488,7 +1488,7 @@ function interpreter:api_builtin_includes(...)
scopes._CURRENT = nil
-- save the current directory
- local olddir = os.curdir()
+ local oldir = os.curdir()
-- enter the script directory
os.cd(path.directory(file))
@@ -1500,7 +1500,7 @@ function interpreter:api_builtin_includes(...)
end
-- leave the script directory
- os.cd(olddir)
+ os.cd(oldir)
-- restore the previous scope kind
scopes._CURRENT_KIND = scope_kind_prev
diff --git a/xmake/modules/core/tools/ar.lua b/xmake/modules/core/tools/ar.lua
index b1a8fbf92..3c020f6e8 100644
--- a/xmake/modules/core/tools/ar.lua
+++ b/xmake/modules/core/tools/ar.lua
@@ -82,7 +82,7 @@ function extract(self, libraryfile, objectdir)
libraryfile = path.absolute(libraryfile)
-- enter the object directory
- local olddir = os.cd(objectdir)
+ local oldir = os.cd(objectdir)
-- extract it
os.runv(self:program(), {"-x", libraryfile})
@@ -98,6 +98,6 @@ function extract(self, libraryfile, objectdir)
end
-- leave the object directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
new file mode 100644
index 000000000..3b3b65105
--- /dev/null
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -0,0 +1,128 @@
+--!The Make-like Build Utility based on Lua
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file compile_commands.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import("core.project.project")
+import("core.language.language")
+
+-- make the object
+function _make_object(jsonfile, target, sourcefile, objectfile)
+
+ -- get the source file kind
+ local sourcekind = language.sourcekind_of(sourcefile)
+
+ -- make the object for the *.o/obj? ignore it directly
+ if sourcekind == "obj" or sourcekind == "lib" then
+ return
+ end
+
+ -- get compile arguments
+ local arguments = table.join(compiler.compargv(sourcefile, {target = target, sourcekind = sourcekind}))
+
+ -- make body
+ jsonfile:printf(
+[[%s{
+ "directory": "%s",
+ "arguments": ["%s"],
+ "file": "%s",
+ "output": "%s"
+}]], ifelse(_g.firstline, "", ",\n"), os.projectdir(), table.concat(arguments, "\", \""), sourcefile, objectfile)
+
+ -- clear first line marks
+ _g.firstline = false
+end
+
+-- make each objects
+function _make_each_objects(jsonfile, target, sourcekind, sourcebatch)
+ for index, objectfile in ipairs(sourcebatch.objectfiles) do
+ _make_object(jsonfile, target, sourcebatch.sourcefiles[index], objectfile)
+ end
+end
+
+-- make single object
+function _make_single_object(jsonfile, target, sourcekind, sourcebatch)
+
+ -- not supported now, ignore it directly
+ for _, sourcefile in ipairs(table.wrap(sourcebatch.sourcefiles)) do
+ cprint("${bright yellow}warning: ${default yellow}ignore[%s]: %s", target:name(), sourcefile)
+ end
+end
+
+-- make target
+function _make_target(jsonfile, target)
+
+ -- build source batches
+ for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
+ if type(sourcebatch.objectfiles) == "string" then
+ _make_single_object(jsonfile, target, sourcekind, sourcebatch)
+ else
+ _make_each_objects(jsonfile, target, sourcekind, sourcebatch)
+ end
+ end
+end
+
+-- make all
+function _make_all(jsonfile)
+
+ -- make header
+ jsonfile:print("[")
+
+ -- make commands
+ _g.firstline = true
+ for _, target in pairs(project.targets()) do
+ local isdefault = target:get("default")
+ if not target:isphony() and (isdefault == nil or isdefault == true) then
+ _make_target(jsonfile, target)
+ end
+ end
+
+ -- make tailer
+ jsonfile:print("]")
+end
+
+-- generate compilation databases for clang-based tools(compile_commands.json)
+--
+-- references:
+-- - https://clang.llvm.org/docs/JSONCompilationDatabase.html
+-- - https://sarcasm.github.io/notes/dev/compilation-database.html
+-- - http://eli.thegreenplace.net/2014/05/21/compilation-databases-for-clang-based-tools
+--
+function make(outputdir)
+
+ -- enter project directory
+ local oldir = os.cd(os.projectdir())
+
+ -- open the jsonfile
+ local jsonfile = io.open(path.join(outputdir, "compile_commands.json"), "w")
+
+ -- make all
+ _make_all(jsonfile)
+
+ -- close the jsonfile
+ jsonfile:close()
+
+ -- leave project directory
+ os.cd(oldir)
+end
diff --git a/xmake/plugins/project/main.lua b/xmake/plugins/project/main.lua
index 1b4e6efe1..c949fa70f 100644
--- a/xmake/plugins/project/main.lua
+++ b/xmake/plugins/project/main.lua
@@ -36,6 +36,7 @@ import("vstudio.vs2012")
import("vstudio.vs2013")
import("vstudio.vs2015")
import("vstudio.vs2017")
+import("clang.compile_commands")
-- make project
function _make(kind)
@@ -43,16 +44,17 @@ function _make(kind)
-- the maps
local maps =
{
- makefile = makefile.make
- , vs2002 = vs2002.make
- , vs2003 = vs2003.make
- , vs2005 = vs2005.make
- , vs2008 = vs2008.make
- , vs2010 = vs2010.make
- , vs2012 = vs2012.make
- , vs2013 = vs2013.make
- , vs2015 = vs2015.make
- , vs2017 = vs2017.make
+ makefile = makefile.make
+ , vs2002 = vs2002.make
+ , vs2003 = vs2003.make
+ , vs2005 = vs2005.make
+ , vs2008 = vs2008.make
+ , vs2010 = vs2010.make
+ , vs2012 = vs2012.make
+ , vs2013 = vs2013.make
+ , vs2015 = vs2015.make
+ , vs2017 = vs2017.make
+ , compile_commands = compile_commands.make
}
assert(maps[kind], "the project kind(%s) is not supported!", kind)
diff --git a/xmake/plugins/project/makefile/makefile.lua b/xmake/plugins/project/makefile/makefile.lua
index 09b6d2e0f..d036c7240 100644
--- a/xmake/plugins/project/makefile/makefile.lua
+++ b/xmake/plugins/project/makefile/makefile.lua
@@ -387,7 +387,7 @@ end
function make(outputdir)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(os.projectdir())
-- remove the log makefile first
os.rm(_logfile())
@@ -402,5 +402,5 @@ function make(outputdir)
makefile:close()
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/plugins/project/vstudio/impl/vs200x.lua b/xmake/plugins/project/vstudio/impl/vs200x.lua
index 2f07f35a5..2c35534fe 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x.lua
@@ -31,7 +31,7 @@ import("vs200x_vcproj")
function make(outputdir, vsinfo)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- init solution directory
vsinfo.solution_dir = path.join(outputdir, "vs" .. vsinfo.vstudio_version)
@@ -47,5 +47,5 @@ function make(outputdir, vsinfo)
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index 1807e9845..12d7ae4fb 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -132,7 +132,7 @@ end
function make(outputdir, vsinfo)
-- enter project directory
- local olddir = os.cd(project.directory())
+ local oldir = os.cd(project.directory())
-- init solution directory
vsinfo.solution_dir = path.join(outputdir, "vs" .. vsinfo.vstudio_version)
@@ -224,5 +224,5 @@ function make(outputdir, vsinfo)
end
-- leave project directory
- os.cd(olddir)
+ os.cd(oldir)
end
diff --git a/xmake/plugins/project/xmake.lua b/xmake/plugins/project/xmake.lua
index 4de77ea2b..382d82411 100644
--- a/xmake/plugins/project/xmake.lua
+++ b/xmake/plugins/project/xmake.lua
@@ -44,9 +44,12 @@ task("project")
{
{'k', "kind", "kv", "makefile", "Set the project kind."
, " - makefile"
+ , " - compile_commands (clang compilation database with json format)"
, " - vs2002, vs2003, vs2005, vs2008, vs2010, vs2012, vs2013, vs2015, vs2017" }
, {'m', "modes", "kv", nil, "Set the project modes."
, " .e.g "
+ , " - xmake project -k makefile"
+ , " - xmake project -k compile_commands"
, " - xmake project -k vs2015 -m \"release,debug\"" }
, {nil, "outputdir", "v", ".", "Set the output directory." }
}