summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-11-11 00:59:30 +0800
committerruki <[email protected]>2017-11-10 23:57:03 +0800
commit47e6e15e84968c6b0f1ebf6c939157fb027a1c4f (patch)
tree1b5399b13a73f981d1b95c531bb306f0e4a813f4
parent64875f84837a3b447d95b38ccce29bcdb57f8dd5 (diff)
build single object with rule
-rw-r--r--tests/apis/rules/xmake.lua2
-rw-r--r--xmake/actions/build/kinds/object.lua55
-rw-r--r--xmake/core/project/project.lua2
-rw-r--r--xmake/core/project/rule.lua52
-rw-r--r--xmake/core/project/target.lua60
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua10
-rw-r--r--xmake/core/sandbox/modules/import/core/project/rule.lua38
7 files changed, 193 insertions, 26 deletions
diff --git a/tests/apis/rules/xmake.lua b/tests/apis/rules/xmake.lua
index d05d0eacc..1971e20fe 100644
--- a/tests/apis/rules/xmake.lua
+++ b/tests/apis/rules/xmake.lua
@@ -10,10 +10,8 @@ rule("markdown")
rule("man")
add_imports("core.project.rule")
on_build_all(function (target, sourcefiles)
- local vars = {name = "xmake"}
for _, sourcefile in ipairs(sourcefiles) do
print("generating %s", sourcefile)
- io.gsub(sourcefile, "%[(.+)%]", function (name) return vars[name] end)
end
rule.build_all("markdown", target, sourcefiles)
end)
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index 3b4e78146..de99b1675 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -27,6 +27,7 @@ import("core.base.option")
import("core.tool.compiler")
import("core.tool.extractor")
import("core.project.config")
+import("core.project.project")
import("core.language.language")
import("detect.tools.find_ccache")
@@ -292,6 +293,50 @@ function _build_pcheaderfiles(target, buildinfo)
end
end
+-- build each objects from the given source batch with the custom rule
+function _build_each_objects_with_rule(target, buildinfo, sourcebatch, jobs, rule)
+ print("each", sourcebatch.rulename)
+end
+
+-- compile source files to single object at the same time with the custom rule
+function _build_single_object_with_rule(target, buildinfo, sourcebatch, jobs, rule)
+
+ -- the rule scripts
+ local scripts =
+ {
+ rule:script("build_all_before")
+ , rule:script("build_all")
+ , rule:script("build_all_after")
+ }
+
+ -- run the rule scripts
+ for i = 1, 3 do
+ local script = scripts[i]
+ if script ~= nil then
+ script(target, sourcebatch.sourcefiles)
+ end
+ end
+end
+
+-- build objects with the custom rule
+function _build_objects_with_rule(target, buildinfo, sourcebatch, jobs)
+
+ -- get rule
+ local rule = project.rule(sourcebatch.rulename)
+ assert(rule, "unknown rule: %s", sourcebatch.rule)
+
+ -- build all source files at once
+ if rule:get("build_all") then
+
+ -- build single object
+ _build_single_object_with_rule(target, buildinfo, sourcebatch, jobs, rule)
+ else
+
+ -- build each objects
+ _build_each_objects_with_rule(target, buildinfo, sourcebatch, jobs, rule)
+ end
+end
+
-- build objects for the given target
function build(target, buildinfo)
@@ -314,8 +359,14 @@ function build(target, buildinfo)
-- build source batches
for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
- -- compile source files to single object at the same time?
- if type(sourcebatch.objectfiles) == "string" then
+ -- compile source files using the custom rule
+ if sourcebatch.rulename then
+
+ -- build objects with the custom rule
+ _build_objects_with_rule(target, buildinfo, sourcebatch, jobs)
+
+ -- compile source files to single object at once
+ elseif type(sourcebatch.objectfiles) == "string" then
-- build single object
_build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs, ccache)
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 2dfa53d7a..26c986b03 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -619,7 +619,7 @@ function project.rules()
-- load rules
if not project._RULES then
- local rules, errors = project._load_RULES()
+ local rules, errors = project._load_rules()
if not rules then
os.raise(errors)
end
diff --git a/xmake/core/project/rule.lua b/xmake/core/project/rule.lua
index 56d47c0ca..13ab82ac0 100644
--- a/xmake/core/project/rule.lua
+++ b/xmake/core/project/rule.lua
@@ -30,6 +30,8 @@ local os = require("base/os")
local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
+local sandbox = require("sandbox/sandbox")
+local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- get rule apis
function rule.apis()
@@ -103,6 +105,56 @@ function rule:get(name)
return self._INFO[name]
end
+-- get xxx_script
+function rule:script(name, generic)
+
+ -- get script
+ local script = self:get(name)
+ local result = nil
+ if type(script) == "function" then
+ result = script
+ elseif type(script) == "table" then
+
+ -- match script for special plat and arch
+ local plat = (config.get("plat") or "")
+ local pattern = plat .. '|' .. (config.get("arch") or "")
+ for _pattern, _script in pairs(script) do
+ if not _pattern:startswith("__") and pattern:find('^' .. _pattern .. '$') then
+ result = _script
+ break
+ end
+ end
+
+ -- match script for special plat
+ if result == nil then
+ for _pattern, _script in pairs(script) do
+ if not _pattern:startswith("__") and plat:find('^' .. _pattern .. '$') then
+ result = _script
+ break
+ end
+ end
+ end
+
+ -- get generic script
+ result = result or script["__generic__"] or generic
+ end
+
+ -- only generic script
+ result = result or generic
+
+ -- imports some modules first
+ if result and result ~= generic then
+ local scope = getfenv(result)
+ if scope then
+ for _, modulename in ipairs(table.wrap(self:get("imports"))) do
+ scope[sandbox_module.name(modulename)] = sandbox_module.import(modulename, {anonymous = true})
+ end
+ end
+ end
+
+ -- ok
+ return result
+end
-- return module
return rule
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index ec243300a..3aaa71f24 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -699,8 +699,17 @@ function target:sourcebatches()
local sourcebatches = {}
for _, sourcefile in ipairs(sourcefiles) do
+ -- get file config
+ local fileconfig = self:fileconfig(sourcefile)
+
-- get source kind
- local sourcekind = language.sourcekind_of(sourcefile)
+ local sourcekind = nil
+ if fileconfig and fileconfig.rule then
+ sourcekind = "__rule_" .. fileconfig.rule
+ end
+ if not sourcekind then
+ sourcekind = language.sourcekind_of(sourcefile)
+ end
if not sourcekind then
local sourcekind_ext = sourcekinds_ext[path.extension(sourcefile):lower()]
if sourcekind_ext then
@@ -720,6 +729,11 @@ function target:sourcebatches()
-- add source kind to this batch
sourcebatch.sourcekind = sourcekind
+ -- add source rule to this batch
+ if fileconfig and fileconfig.rule then
+ sourcebatch.rulename = fileconfig.rule
+ end
+
-- add source file to this batch
table.insert(sourcebatch.sourcefiles, sourcefile)
end
@@ -727,34 +741,38 @@ function target:sourcebatches()
-- insert object files to source batches
for sourcekind, sourcebatch in pairs(sourcebatches) do
- -- this batch support to compile multiple objects at the same time?
- local instance = compiler.load(sourcekind)
- if instance and instance:buildmode("object:sources") then
+ -- skip source files with the custom rule
+ if not sourcekind:startswith("__rule_") then
- -- get the first source file
- local sourcefile = sourcebatch.sourcefiles[1]
+ -- this batch support to compile multiple objects at the same time?
+ local instance = compiler.load(sourcekind)
+ if instance and instance:buildmode("object:sources") then
- -- insert single object file for all source files
- sourcebatch.objectfiles = self:objectfile(path.join(path.directory(sourcefile), "__" .. sourcekind))
+ -- get the first source file
+ local sourcefile = sourcebatch.sourcefiles[1]
- -- insert single incdep file for all source files
- sourcebatch.incdepfiles = self:incdepfile(sourcebatch.objectfiles)
+ -- insert single object file for all source files
+ sourcebatch.objectfiles = self:objectfile(path.join(path.directory(sourcefile), "__" .. sourcekind))
- else
+ -- insert single incdep file for all source files
+ sourcebatch.incdepfiles = self:incdepfile(sourcebatch.objectfiles)
- -- insert object files for each source files
- sourcebatch.objectfiles = {}
- sourcebatch.incdepfiles = {}
- for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ else
- -- get object file from this source file
- local objectfile = self:objectfile(sourcefile)
+ -- insert object files for each source files
+ sourcebatch.objectfiles = {}
+ sourcebatch.incdepfiles = {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- -- add object file to this batch
- table.insert(sourcebatch.objectfiles, objectfile)
+ -- get object file from this source file
+ local objectfile = self:objectfile(sourcefile)
- -- add incdep file to this batch
- table.insert(sourcebatch.incdepfiles, self:incdepfile(objectfile))
+ -- add object file to this batch
+ table.insert(sourcebatch.objectfiles, objectfile)
+
+ -- add incdep file to this batch
+ table.insert(sourcebatch.incdepfiles, self:incdepfile(objectfile))
+ end
end
end
end
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index a1ee7c0fd..cf027b0b2 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -112,6 +112,16 @@ function sandbox_core_project.check()
end
end
+-- get the given rule
+function sandbox_core_project.rule(name)
+ return project.rule(name)
+end
+
+-- get the all rules
+function sandbox_core_project.rules()
+ return project.rules()
+end
+
-- get the given target
function sandbox_core_project.target(name)
return project.target(name)
diff --git a/xmake/core/sandbox/modules/import/core/project/rule.lua b/xmake/core/sandbox/modules/import/core/project/rule.lua
new file mode 100644
index 000000000..81a8db412
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/core/project/rule.lua
@@ -0,0 +1,38 @@
+--!A cross-platform 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 rule.lua
+--
+
+-- define module
+local sandbox_core_project_rule = sandbox_core_project_rule or {}
+
+-- load modules
+local rule = require("project/rule")
+local raise = require("sandbox/modules/raise")
+
+-- build all source files
+function sandbox_core_project_rule.build_all(rulename, target, sourcefiles)
+
+end
+
+-- return module
+return sandbox_core_project_rule