diff options
| author | ruki <[email protected]> | 2016-03-20 20:44:48 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-03-20 20:44:48 +0800 |
| commit | c240d9bfda967e986237110d4706db567afd8415 (patch) | |
| tree | ca1d7c35bb4514f7be6b9e8c510049c148a7e3b5 | |
| parent | 4cf03c92577e64fd6c9bd86c01790dbd295e2530 (diff) | |
impl some interfaces for targets
| -rwxr-xr-x | xmake/actions/config/makefile.lua | 86 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 200 |
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 |
