summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2016-03-20 20:44:48 +0800
committerruki <[email protected]>2016-03-20 20:44:48 +0800
commitc240d9bfda967e986237110d4706db567afd8415 (patch)
treeca1d7c35bb4514f7be6b9e8c510049c148a7e3b5
parent4cf03c92577e64fd6c9bd86c01790dbd295e2530 (diff)
impl some interfaces for targets
-rwxr-xr-xxmake/actions/config/makefile.lua86
-rw-r--r--xmake/core/project/target.lua200
2 files changed, 286 insertions, 0 deletions
diff --git a/xmake/actions/config/makefile.lua b/xmake/actions/config/makefile.lua
index 5a7077126..427870784 100755
--- a/xmake/actions/config/makefile.lua
+++ b/xmake/actions/config/makefile.lua
@@ -23,9 +23,95 @@
-- imports
import("core.project.project")
+-- make the object
+function _make_object(makefile, target, srcfile, objfile)
+
+end
+
+-- make all objects of the given target
+function _make_objects(makefile, target, srcfiles, objfiles)
+
+ -- make all objects
+ local i = 1
+ for _, objfile in ipairs(objfiles) do
+
+ -- make object
+ _make_object(makefile, target, srcfiles[i], objfile)
+
+ -- next
+ i = i + 1
+ end
+
+end
+
-- make target
function _make_target(makefile, target)
+--[[ -- get the linker from the given kind
+ local l = linker.get(target.kind)
+ if not l then
+ utils.error("cannot get linker with kind: %s", target.kind)
+ return false
+ end
+]]
+
+ -- make head
+ local targetfile = target:targetfile()
+ makefile:printf("%s: %s\n", name, targetfile)
+ makefile:printf("%s:", targetfile)
+
+ -- make dependence for the dependent targets
+ for _, dep in ipairs(target:get("deps")) do
+
+ -- add dependence
+ makefile:write(" " .. project.target(dep):targetfile())
+ end
+
+ -- make dependence for objects
+ local objfiles = target:objectfiles()
+ for _, objfile in ipairs(objfiles) do
+ makefile:write(" " .. objfile)
+ end
+
+ -- make dependence end
+ makefile:print("")
+
+ -- make the command
+ local srcfiles = target:sourcefiles()
+ local cmd = ""--linker.make(l, target, srcfiles, objfiles, targetfile, makefile._LOGFILE)
+
+ -- make the verbose info
+ local verbose = cmd:encode()
+ if verbose and #verbose > 256 then
+ verbose = nil--linker.make(l, target, srcfiles, {rule.filename("*", "object")}, targetfile)
+ verbose = verbose:encode()
+ end
+
+ -- TODO: $(mode)
+ -- make body
+ makefile:print("\t@echo linking.$(mode) %s", path.filename(targetfile))
+ makefile:print("\t@xmake l $(VERBOSE) verbose \"%s\"", verbose)
+ makefile:print("\t@xmake l mkdir %s", path.directory(targetfile))
+ makefile:print("\t@%s", cmd)
+
+ -- make headers
+ local srcheaders, dstheaders = target:headerfiles()
+ if srcheaders and dstheaders then
+ local i = 1
+ for _, srcheader in ipairs(srcheaders) do
+ local dstheader = dstheaders[i]
+ if dstheader then
+ makefile:print("\t@xmake l cp %s %s", srcheader, dstheader)
+ end
+ i = i + 1
+ end
+ end
+
+ -- make tail
+ makefile:print("")
+
+ -- make objects for this target
+ _make_objects(makefile, target, srcfiles, objfiles)
end
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index a213a4b79..6b1da3215 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -24,6 +24,10 @@
local target = target or {}
-- load modules
+local os = require("base/os")
+local path = require("base/path")
+local table = require("base/table")
+local config = require("project/config")
local platform = require("platform/platform")
-- get the filename from the given name and kind
@@ -56,5 +60,201 @@ function target.name(self)
return self._NAME
end
+-- get the object file directory
+function target.objectdir(self)
+
+ -- check
+ assert(self)
+
+ -- the object directory
+ local objectdir = self:get("objectdir")
+ if not objectdir then
+
+ -- make the default object directory
+ objectdir = path.join(config.get("buildir"), ".objs")
+ end
+
+ -- ok?
+ return objectdir
+end
+
+-- get the target file
+function target.targetfile(self)
+
+ -- check
+ assert(self)
+
+ -- the target directory
+ local targetdir = self:get("targetdir") or config.get("buildir")
+ assert(targetdir and type(targetdir) == "string")
+
+ -- the target file name
+ local filename = target.filename(self:name(), self:get("kind"))
+ assert(filename)
+
+ -- make the target file path
+ return path.join(targetdir, filename)
+end
+
+-- get the source files
+function target.sourcefiles(self)
+
+ -- check
+ assert(self)
+
+ -- get files
+ local files = self:get("files")
+
+ -- no files?
+ if not files then
+ return {}
+ end
+
+ -- match files
+ local i = 1
+ local sourcefiles = {}
+ for _, file in ipairs(table.wrap(files)) do
+
+ -- normalize *.[o|obj] filename
+ file = file:gsub("([%w%*]+)%.obj|", target.filename("%1|", "object"))
+ file = file:gsub("([%w%*]+)%.obj$", target.filename("%1", "object"))
+ file = file:gsub("([%w%*]+)%.o|", target.filename("%1|", "object"))
+ file = file:gsub("([%w%*]+)%.o$", target.filename("%1", "object"))
+
+ -- normalize [lib]*.[a|lib] filename
+ file = file:gsub("([%w%*]+)%.lib|", target.filename("%1|", "static"))
+ file = file:gsub("([%w%*]+)%.lib$", target.filename("%1", "static"))
+ file = file:gsub("lib([%w%*]+)%.a|", target.filename("%1|", "static"))
+ file = file:gsub("lib([%w%*]+)%.a$", target.filename("%1", "static"))
+
+ -- match source files
+ local srcfiles = os.match(file)
+ if #srcfiles == 0 then
+ utils.warning("cannot match add_files(\"%s\")", file)
+ end
+
+ -- process source files
+ for _, srcfile in ipairs(srcfiles) do
+
+ -- convert to the relative path
+ if path.is_absolute(srcfile) then
+ srcfile = path.relative(srcfile, xmake._PROJECT_DIR)
+ end
+
+ -- save it
+ sourcefiles[i] = srcfile
+ i = i + 1
+
+ end
+ end
+
+ -- remove repeat files
+ sourcefiles = table.unique(sourcefiles)
+
+ -- ok?
+ return sourcefiles
+end
+
+-- get the object files
+function target.objectfiles(self)
+
+ -- check
+ assert(self)
+
+ -- get the object directory
+ local objectdir = self:objectdir()
+ assert(objectdir and type(objectdir) == "string")
+
+ -- get the source files
+ local sourcefiles = self:sourcefiles()
+ assert(sourcefiles)
+
+ -- make object files
+ local i = 1
+ local objectfiles = {}
+ for _, sourcefile in ipairs(sourcefiles) do
+
+ -- translate: [lib]xxx*.[a|lib] => xxx/*.[o|obj] object file
+ sourcefile = sourcefile:gsub(target.filename("([%w_]+)", "static"):gsub("%.", "%%.") .. "$", "%1/*")
+
+ -- make object file
+ local objectfile = string.format("%s/%s/%s/%s", objectdir, self:name(), path.directory(sourcefile), target.filename(path.basename(sourcefile), "object"))
+
+ -- translate path
+ --
+ -- .e.g
+ --
+ -- src/xxx.c
+ -- project/xmake.lua
+ -- build/.objs
+ --
+ -- objectfile: project/build/.objs/xxxx/../../xxx.c will be out of range for objectdir
+ --
+ -- we need replace '..' to '__' in this case
+ --
+ objectfile = (path.translate(objectfile):gsub("%.%.", "__"))
+
+ -- save it
+ objectfiles[i] = objectfile
+ i = i + 1
+
+ end
+
+ -- ok?
+ return objectfiles
+end
+
+-- get the header files
+function target.headerfiles(self)
+
+ -- check
+ assert(self)
+
+ -- no headers?
+ local headers = self:get("headers")
+ if not headers then return end
+
+ -- get the headerdir
+ local headerdir = self:get("headerdir") or config.get("buildir")
+ assert(headerdir)
+
+ -- get the source pathes and destinate pathes
+ local srcheaders = {}
+ local dstheaders = {}
+ for _, header in ipairs(table.wrap(headers)) do
+
+ -- get the root directory
+ local rootdir = header:gsub("%(.*%)", ""):gsub("|.*$", "")
+
+ -- remove '(' and ')'
+ local srcpathes = header:gsub("[%(%)]", "")
+ if srcpathes then
+
+ -- get the source pathes
+ srcpathes = os.match(srcpathes)
+ if srcpathes then
+
+ -- add the source headers
+ table.join2(srcheaders, srcpathes)
+
+ -- add the destinate headers
+ for _, srcpath in ipairs(srcpathes) do
+
+ -- the header
+ local dstheader = path.absolute(path.relative(srcpath, rootdir), headerdir)
+ assert(dstheader)
+
+ -- add it
+ table.insert(dstheaders, dstheader)
+ end
+ end
+ end
+ end
+
+ -- ok?
+ return srcheaders, dstheaders
+end
+
+
-- return module
return target