diff options
| author | ruki <[email protected]> | 2015-12-28 18:59:43 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2015-12-28 18:59:43 +0800 |
| commit | ad9b35fd836a38d72c39efc112300ab5d92503ba (patch) | |
| tree | 0c84be2250e27952fb6821b77fd96c3167a78513 | |
| parent | e0dab0305d1967b57b12d2deb94e4253bf7cde06 (diff) | |
add clean all
| -rwxr-xr-x | core/src/xmake/machine.c | 2 | ||||
| -rwxr-xr-x | core/src/xmake/makefile | 1 | ||||
| -rwxr-xr-x | core/src/xmake/os/emptydir.c | 79 | ||||
| -rwxr-xr-x | core/src/xmake/os/rmdir.c | 70 | ||||
| -rw-r--r-- | xmake/scripts/action/_build.lua | 4 | ||||
| -rw-r--r-- | xmake/scripts/action/_clean.lua | 5 | ||||
| -rw-r--r-- | xmake/scripts/base/clean.lua | 76 | ||||
| -rw-r--r-- | xmake/scripts/base/os.lua | 36 |
8 files changed, 239 insertions, 34 deletions
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index 5935cab50..ead646ea9 100755 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -66,6 +66,7 @@ tb_int_t xm_os_rename(lua_State* lua); tb_int_t xm_os_exists(lua_State* lua); tb_int_t xm_os_setenv(lua_State* lua); tb_int_t xm_os_getenv(lua_State* lua); +tb_int_t xm_os_emptydir(lua_State* lua); tb_int_t xm_os_strerror(lua_State* lua); // the path functions @@ -101,6 +102,7 @@ static luaL_Reg const g_os_functions[] = , { "exists", xm_os_exists } , { "setenv", xm_os_setenv } , { "getenv", xm_os_getenv } +, { "emptydir", xm_os_emptydir } , { "strerror", xm_os_strerror } , { tb_null, tb_null } }; diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile index ca2449d0b..276a1b64b 100755 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -30,6 +30,7 @@ xmake_C_FILES += \ os/exists \ os/setenv \ os/getenv \ + os/emptydir \ os/strerror \ path/relative \ path/absolute \ diff --git a/core/src/xmake/os/emptydir.c b/core/src/xmake/os/emptydir.c new file mode 100755 index 000000000..7251006f2 --- /dev/null +++ b/core/src/xmake/os/emptydir.c @@ -0,0 +1,79 @@ +/*!The Automatic Cross-platform Build Tool + * + * XMake is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * XMake is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with XMake; + * If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a> + * + * Copyright (C) 2009 - 2015, ruki All rights reserved. + * + * @author ruki + * @file emptydir.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "emptydir" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_bool_t xm_os_emptydir_walk(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv) +{ + // check + tb_bool_t* is_emptydir = (tb_bool_t*)priv; + tb_assert_and_check_return_val(path && info && is_emptydir, tb_false); + + // is emptydir? + if (info->type == TB_FILE_TYPE_DIRECTORY || info->type == TB_FILE_TYPE_FILE) + { + // not emptydir + *is_emptydir = tb_false; + + // break + return tb_false; + } + + // continue + return tb_true; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_os_emptydir(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // get the directory + tb_char_t const* dir = luaL_checkstring(lua, 1); + tb_check_return_val(dir, 0); + + // done os.emptydir(dir) + tb_bool_t is_emptydir = tb_true; + tb_directory_walk(dir, tb_false, tb_true, xm_os_emptydir_walk, &is_emptydir); + + // is emptydir? + lua_pushboolean(lua, is_emptydir); + + // ok + return 1; +} diff --git a/core/src/xmake/os/rmdir.c b/core/src/xmake/os/rmdir.c index 2daba8207..9128870f2 100755 --- a/core/src/xmake/os/rmdir.c +++ b/core/src/xmake/os/rmdir.c @@ -33,6 +33,51 @@ #include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_bool_t xm_os_rmdir_empty(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv) +{ + // check + tb_bool_t* is_emptydir = (tb_bool_t*)priv; + tb_assert_and_check_return_val(path && info && is_emptydir, tb_false); + + // is emptydir? + if (info->type == TB_FILE_TYPE_DIRECTORY || info->type == TB_FILE_TYPE_FILE) + { + // not emptydir + *is_emptydir = tb_false; + + // break + return tb_false; + } + + // continue + return tb_true; +} +static tb_bool_t xm_os_rmdir_remove(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv) +{ + // check + tb_assert_and_check_return_val(path, tb_false); + + // is directory? + if (info->type == TB_FILE_TYPE_DIRECTORY) + { + // is emptydir? + tb_bool_t is_emptydir = tb_true; + tb_directory_walk(path, tb_false, tb_true, xm_os_rmdir_empty, &is_emptydir); + + // trace + tb_trace_d("path: %s, emptydir: %u", path, is_emptydir); + + // remove empty directory + if (is_emptydir) tb_directory_remove(path); + } + + // continue + return tb_true; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ tb_int_t xm_os_rmdir(lua_State* lua) @@ -44,8 +89,29 @@ tb_int_t xm_os_rmdir(lua_State* lua) tb_char_t const* path = luaL_checkstring(lua, 1); tb_check_return_val(path, 0); - // done os.rmdir(path) - lua_pushboolean(lua, tb_directory_remove(path)); + // only remove empty directory? + tb_bool_t rmempty = lua_toboolean(lua, 2); + if (rmempty) + { + // remove all empty directories + tb_directory_walk(path, tb_true, tb_false, xm_os_rmdir_remove, tb_null); + + // remove empty root directory + tb_bool_t is_emptydir = tb_true; + tb_directory_walk(path, tb_false, tb_true, xm_os_rmdir_empty, &is_emptydir); + if (is_emptydir) tb_directory_remove(path); + + // trace + tb_trace_d("path: %s, emptydir: %u", path, is_emptydir); + + // ok? + lua_pushboolean(lua, !tb_file_info(path, tb_null)); + } + else + { + // done os.rmdir(path) + lua_pushboolean(lua, tb_directory_remove(path)); + } // ok return 1; diff --git a/xmake/scripts/action/_build.lua b/xmake/scripts/action/_build.lua index 4b4b72687..7fc7ce4ed 100644 --- a/xmake/scripts/action/_build.lua +++ b/xmake/scripts/action/_build.lua @@ -61,10 +61,10 @@ function _build.done() -- rebuild it? if options.rebuild or config.get("__rebuild") then - clean.remove(target_name) + clean.remove(target_name, "build") -- update it? elseif options.update then - clean.remove(target_name, true) + clean.remove(target_name, "targets") end -- clear rebuild mark and save configure to file diff --git a/xmake/scripts/action/_clean.lua b/xmake/scripts/action/_clean.lua index 8399f2410..677ff2470 100644 --- a/xmake/scripts/action/_clean.lua +++ b/xmake/scripts/action/_clean.lua @@ -27,6 +27,7 @@ local _clean = _clean or {} local clean = require("base/clean") local config = require("base/config") local project = require("base/project") +local utils = require("base/utils") local platform = require("platform/platform") -- need access to the given file? @@ -55,7 +56,7 @@ function _clean.done() end -- clean the current target - if not clean.remove(options.target) then + if not clean.remove(options.target, utils.ifelse(options.all, "all", "build")) then return false end @@ -89,6 +90,8 @@ function _clean.menu() , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" , " 3. The Current Directory" } , {} + , {'a', "all", "k", nil, "Clean all auto-generated files by xmake." } + , {} , {'v', "verbose", "k", nil, "Print lots of verbose information." } , {nil, "version", "k", nil, "Print the version number and exit." } , {'h', "help", "k", nil, "Print this help message and exit." } diff --git a/xmake/scripts/base/clean.lua b/xmake/scripts/base/clean.lua index 0a84407ab..9fbb3258a 100644 --- a/xmake/scripts/base/clean.lua +++ b/xmake/scripts/base/clean.lua @@ -33,8 +33,8 @@ local project = require("base/project") -- remove the given files or directories function clean._remove(filedirs) - -- check - assert(filedirs) + -- empty? + if not filedirs then return true end -- wrap it first filedirs = utils.wrap(filedirs) @@ -57,7 +57,7 @@ function clean._remove(filedirs) end -- remove the given target name -function clean._remove_target(target_name, target, target_only, buildir) +function clean._remove_target(target_name, target, mode, buildir) -- check assert(target_name and target) @@ -68,11 +68,33 @@ function clean._remove_target(target_name, target, target_only, buildir) end -- not only remove target file? - if not target_only then + if mode ~= "targets" then + -- remove the object files if not clean._remove(rule.objectfiles(target_name, target, rule.sourcefiles(target), buildir)) then return false end + + -- remove the header files + local _, dstheaders = rule.headerfiles(target) + if not clean._remove(dstheaders) then + return false + end + + -- remove the config.h file + if mode == "all" and target.config_h then + + -- translate file path + local config_h = nil + if not path.is_absolute(target.config_h) then + config_h = path.absolute(target.config_h, xmake._PROJECT_DIR) + else + config_h = path.translate(target.config_h) + end + if not clean._remove(config_h) then + return false + end + end end -- ok @@ -80,7 +102,7 @@ function clean._remove_target(target_name, target, target_only, buildir) end -- remove the given target and all dependent targets -function clean._remove_target_and_deps(target_name, target_only, buildir) +function clean._remove_target_and_deps(target_name, mode, buildir) -- the targets local targets = project.targets() @@ -91,7 +113,7 @@ function clean._remove_target_and_deps(target_name, target_only, buildir) assert(target) -- remove the target - if not clean._remove_target(target_name, target, target_only, buildir) then + if not clean._remove_target(target_name, target, mode, buildir) then return false end @@ -99,7 +121,7 @@ function clean._remove_target_and_deps(target_name, target_only, buildir) if target.deps then local deps = utils.wrap(target.deps) for _, dep in ipairs(deps) do - if not clean._remove_target_and_deps(dep, target_only, buildir) then return false end + if not clean._remove_target_and_deps(dep, mode, buildir) then return false end end end @@ -108,16 +130,22 @@ function clean._remove_target_and_deps(target_name, target_only, buildir) end -- remove the target and object files for the given target -function clean.remove(target_name, target_only) +-- +-- mode: +-- all +-- build +-- targets +-- +function clean.remove(target_name, mode) -- the build directory local buildir = config.get("buildir") - assert(buildir) + assert(buildir and mode) -- the target name if target_name and target_name ~= "all" then -- remove target - if not clean._remove_target_and_deps(target_name, target_only, buildir) then return false end + if not clean._remove_target_and_deps(target_name, mode, buildir) then return false end else -- the targets @@ -126,9 +154,35 @@ function clean.remove(target_name, target_only) -- remove targets for target_name, target in pairs(targets) do - if not clean._remove_target(target_name, target, target_only, buildir) then return false end + if not clean._remove_target(target_name, target, mode, buildir) then return false end end end + + -- remove all + if mode == "all" then + + -- remove makefile + if not clean._remove(rule.makefile()) then + return false + end + + -- remove the configure directory + if not clean._remove(config.directory()) then + return false + end + + -- remove the log file + if not clean._remove(rule.logfile()) then + return false + end + + -- remove build directory if be empty + local buildir = config.get("buildir") + if os.isdir(buildir) then + os.rm(buildir, true) + end + + end -- ok return true diff --git a/xmake/scripts/base/os.lua b/xmake/scripts/base/os.lua index 442ee20e4..b08ac3820 100644 --- a/xmake/scripts/base/os.lua +++ b/xmake/scripts/base/os.lua @@ -166,43 +166,43 @@ function os.mv(src, dst) end -- remove file or directory -function os.rm(path) +function os.rm(file_or_dir, emptydir) -- check - assert(path) + assert(file_or_dir) -- is file? - if os.isfile(path) then + if os.isfile(file_or_dir) then -- remove file - if not os.rmfile(path) then - return false, string.format("cannot remove file %s %s", path, os.strerror()) + if not os.rmfile(file_or_dir) then + return false, string.format("cannot remove file %s %s", file_or_dir, os.strerror()) end -- is directory? - elseif os.isdir(path) then + elseif os.isdir(file_or_dir) then -- remove directory - if not os.rmdir(path) then - return false, string.format("cannot remove directory %s %s", path, os.strerror()) + if not os.rmdir(file_or_dir, emptydir) then + return false, string.format("cannot remove directory %s %s", file_or_dir, os.strerror()) end -- not exists? else - return false, string.format("cannot remove file %s, not found this file %s", path, os.strerror()) + return false, string.format("cannot remove file %s, not found this file %s", file_or_dir, os.strerror()) end - + -- ok return true end -- change to directory -function os.cd(path) +function os.cd(dir) -- check - assert(path) + assert(dir) -- change to the previous directory? - if path == "-" then + if dir == "-" then -- exists the previous directory? if os._PREDIR then - path = os._PREDIR + dir = os._PREDIR os._PREDIR = nil else -- error @@ -211,14 +211,14 @@ function os.cd(path) end -- is directory? - if os.isdir(path) then + if os.isdir(dir) then -- get the current directory local current = os.curdir() -- change to directory - if not os.chdir(path) then - return false, string.format("cannot change directory %s %s", path, os.strerror()) + if not os.chdir(dir) then + return false, string.format("cannot change directory %s %s", dir, os.strerror()) end -- save the previous directory @@ -226,7 +226,7 @@ function os.cd(path) -- not exists? else - return false, string.format("cannot change directory %s, not found this directory %s", path, os.strerror()) + return false, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror()) end -- ok |
