summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-02-22 23:20:19 +0800
committerruki <[email protected]>2020-02-22 23:20:19 +0800
commitd7343aea8fdfdba0c71bcdb3441057aefeb64a97 (patch)
tree5de89b0f8bc30e2776c56a41f2d569f55bd96080
parent4a7f397b9036a3c31cad090732d758794555e40c (diff)
impl generate build.ninja
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua5
-rwxr-xr-xxmake/plugins/project/main.lua7
-rw-r--r--xmake/plugins/project/make/makefile.lua6
-rw-r--r--xmake/plugins/project/ninja/build_ninja.lua240
-rw-r--r--xmake/plugins/project/xmake.lua5
5 files changed, 259 insertions, 4 deletions
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 0df54131c..ca54659c8 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -49,9 +49,12 @@ function _add_values_from_targetpkgs(values, target, name)
end
end
-
-- add project info
function _add_project(cmakelists)
+ cmakelists:print([[# this is the build file for project %s
+# it is autogenerated by the xmake build system.
+# do not edit by hand.
+]], project.name() or "")
cmakelists:print("# project")
cmakelists:print("cmake_minimum_required(VERSION 3.13.0)")
local project_name = project.name()
diff --git a/xmake/plugins/project/main.lua b/xmake/plugins/project/main.lua
index b24a3b47f..f7b61c82b 100755
--- a/xmake/plugins/project/main.lua
+++ b/xmake/plugins/project/main.lua
@@ -26,6 +26,7 @@ import("core.platform.environment")
import("make.makefile")
import("make.xmakefile")
import("cmake.cmakelists")
+import("ninja.build_ninja")
import("vstudio.vs")
import("vsxmake.vsxmake")
import("clang.compile_flags")
@@ -35,9 +36,13 @@ function makers()
-- the maps
return
- { makefile = makefile.make
+ {
+ make = makefile.make
+ , makefile = makefile.make
, xmakefile = xmakefile.make
+ , cmake = cmakelists.make
, cmakelists = cmakelists.make
+ , ninja = build_ninja.make
, vs2002 = vs.make(2002)
, vs2003 = vs.make(2003)
, vs2005 = vs.make(2005)
diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua
index c5b76880a..c2c44508d 100644
--- a/xmake/plugins/project/make/makefile.lua
+++ b/xmake/plugins/project/make/makefile.lua
@@ -320,6 +320,12 @@ end
-- make all
function _make_all(makefile)
+ -- make head
+ makefile:print([[# this is the build file for project %s
+# it is autogenerated by the xmake build system.
+# do not edit by hand.
+]], project.name() or "")
+
-- make variables for ccache
local ccache = find_tool("ccache")
if ccache then
diff --git a/xmake/plugins/project/ninja/build_ninja.lua b/xmake/plugins/project/ninja/build_ninja.lua
new file mode 100644
index 000000000..a1be1c69a
--- /dev/null
+++ b/xmake/plugins/project/ninja/build_ninja.lua
@@ -0,0 +1,240 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed 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-2020, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file build_ninja.lua
+--
+
+-- imports
+import("core.project.config")
+import("core.project.project")
+import("core.platform.platform")
+import("core.language.language")
+import("core.tool.linker")
+import("core.tool.compiler")
+import("lib.detect.find_tool")
+
+-- add header
+function _add_header(ninjafile)
+ ninjafile:print([[# this is the build file for project %s
+# it is autogenerated by the xmake build system.
+# do not edit by hand.
+]], project.name() or "")
+ ninjafile:print("ninja_required_version = 1.5.1")
+ ninjafile:print("")
+end
+
+-- add rules for complier (gcc)
+function _add_rules_for_compiler_gcc(ninjafile, sourcekind, program)
+ local ccache = find_tool("ccache")
+ ninjafile:print("rule %s", sourcekind)
+ ninjafile:print(" command = %s%s $ARGS -MDD -MF '$DEPFILE' -o $out -c $in", ccache and (ccache.program .. " ") or "", program)
+ ninjafile:print(" depfile = $DEPFILE")
+ ninjafile:print(" description = %scompiling.%s $in", ccache and "ccache " or "", config.mode())
+ ninjafile:print("")
+end
+
+-- add rules for complier (clang)
+function _add_rules_for_compiler_clang(ninjafile, sourcekind, program)
+ return _add_rules_for_compiler_gcc(ninjafile, sourcekind, program)
+end
+
+-- add rules for complier
+function _add_rules_for_compiler(ninjafile)
+ ninjafile:print("# rules for compiler")
+ local add_compiler_rules =
+ {
+ gcc = _add_rules_for_compiler_gcc,
+ clang = _add_rules_for_compiler_clang
+ }
+ for sourcekind, _ in pairs(language.sourcekinds()) do
+ local program, toolname = platform.tool(sourcekind)
+ if program and toolname then
+ local add_rule = add_compiler_rules[toolname]
+ if add_rule then
+ add_rule(ninjafile, sourcekind, program)
+ end
+ end
+ end
+ ninjafile:print("")
+end
+
+-- add rules for linker (gcc)
+function _add_rules_for_linker_gcc(ninjafile, linkerkind, program)
+ ninjafile:print("rule %s", linkerkind)
+ ninjafile:print(" command = %s -o $out $in $ARGS", program)
+ ninjafile:print(" description = linking.%s $in", config.mode())
+ ninjafile:print("")
+end
+
+-- add rules for linker (clang)
+function _add_rules_for_linker_clang(ninjafile, linkerkind, program)
+ return _add_rules_for_linker_gcc(ninjafile, linkerkind, program)
+end
+
+-- add rules for linker
+function _add_rules_for_linker(ninjafile)
+ ninjafile:print("# rules for linker")
+ local linkerkinds = {}
+ for _, _linkerkinds in pairs(language.targetkinds()) do
+ table.join2(linkerkinds, _linkerkinds)
+ end
+ local add_linker_rules =
+ {
+ gcc = _add_rules_for_linker_gcc,
+ gxx = _add_rules_for_linker_gcc,
+ clang = _add_rules_for_linker_clang,
+ clangxx = _add_rules_for_linker_clang
+ }
+ for _, linkerkind in ipairs(table.unique(linkerkinds)) do
+ local program, toolname = platform.tool(linkerkind)
+ if program and toolname then
+ local add_rule = add_linker_rules[toolname]
+ if add_rule then
+ add_rule(ninjafile, linkerkind, program)
+ end
+ end
+ end
+ ninjafile:print("")
+end
+
+-- add rules
+function _add_rules(ninjafile)
+
+ -- add rules for complier
+ _add_rules_for_compiler(ninjafile)
+
+ -- add rules for linker
+ _add_rules_for_linker(ninjafile)
+end
+
+-- add build rule for phony
+function _add_build_for_phony(ninjafile, target)
+ ninjafile:print("build %s: phony", target:name())
+end
+
+-- add build rule for object
+function _add_build_for_object(ninjafile, target, sourcekind, sourcefile, objectfile)
+ ninjafile:print("build %s: %s %s", objectfile, sourcekind, sourcefile)
+ ninjafile:print(" DEPFILE = %s", target:dependfile(objectfile))
+ ninjafile:print(" ARGS = %s", os.args(compiler.compflags(sourcefile, {target = target})))
+ ninjafile:print("")
+end
+
+-- add build rule for objects
+function _add_build_for_objects(ninjafile, target, sourcebatch)
+ for index, objectfile in ipairs(sourcebatch.objectfiles) do
+ _add_build_for_object(ninjafile, target, sourcebatch.sourcekind, sourcebatch.sourcefiles[index], objectfile)
+ end
+end
+
+-- add build rule for target
+function _add_build_for_target(ninjafile, target)
+
+ -- is phony target?
+ if target:isphony() then
+ return _add_build_for_phony(ninjafile, target)
+ end
+
+ -- build target
+ ninjafile:print("# build target: %s", target:name())
+ local targetfile = target:targetfile()
+ ninjafile:print("build %s: phony %s", target:name(), targetfile)
+
+ -- build target file
+ ninjafile:printf("build %s: %s", targetfile, target:linker():kind())
+ for _, dep in ipairs(target:get("deps")) do
+ ninjafile:write(" " .. project.target(dep):targetfile())
+ end
+ local objectfiles = target:objectfiles()
+ for _, objectfile in ipairs(objectfiles) do
+ ninjafile:write(" " .. objectfile)
+ end
+ ninjafile:print("")
+ ninjafile:print(" ARGS = %s", os.args(target:linkflags()))
+ ninjafile:print("")
+
+ -- build target objects
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ if sourcebatch.sourcekind then
+ _add_build_for_objects(ninjafile, target, sourcebatch)
+ end
+ end
+end
+
+-- add build rule for targets
+function _add_build_for_targets(ninjafile)
+
+ -- begin
+ ninjafile:print("# build targets\n")
+
+ -- TODO
+ -- disable precompiled header first
+ for _, target in pairs(project.targets()) do
+ target:set("pcheader", nil)
+ target:set("pcxxheader", nil)
+ end
+
+ -- build targets
+ for _, target in pairs(project.targets()) do
+ _add_build_for_target(ninjafile, target)
+ end
+
+ -- build default
+ local default = ""
+ for targetname, target in pairs(project.targets()) do
+ local isdefault = target:get("default")
+ if isdefault == nil or isdefault == true then
+ default = default .. " " .. targetname
+ end
+ end
+ ninjafile:print("build default: phony%s", default)
+
+ -- build all
+ local all = ""
+ for targetname, _ in pairs(project.targets()) do
+ all = all .. " " .. targetname
+ end
+ ninjafile:print("build all: phony%s\n", all)
+
+ -- end
+ ninjafile:print("default default\n")
+end
+
+-- make
+function make(outputdir)
+
+ -- enter project directory
+ local oldir = os.cd(os.projectdir())
+
+ -- open the build.ninja file
+ local ninjafile = io.open(path.join(outputdir, "build.ninja"), "w")
+
+ -- add header
+ _add_header(ninjafile)
+
+ -- add rules
+ _add_rules(ninjafile)
+
+ -- add build rules for targets
+ _add_build_for_targets(ninjafile)
+
+ -- close the ninjafile
+ ninjafile:close()
+
+ -- leave project directory
+ os.cd(oldir)
+end
diff --git a/xmake/plugins/project/xmake.lua b/xmake/plugins/project/xmake.lua
index f5c6c6b30..1dbaaa993 100644
--- a/xmake/plugins/project/xmake.lua
+++ b/xmake/plugins/project/xmake.lua
@@ -39,9 +39,10 @@ task("project")
, options =
{
{'k', "kind", "kv" , "makefile", "Set the project kind."
- , " - makefile"
+ , " - make"
, " - xmakefile (makefile with xmake)"
- , " - cmakelists"
+ , " - cmake"
+ , " - ninja"
, " - compile_flags"
, " - compile_commands (clang compilation database with json format)"
, " - vs (auto detect), vs2002, vs2003, vs2005, vs2008"