summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2015-12-28 18:59:43 +0800
committerruki <[email protected]>2015-12-28 18:59:43 +0800
commitad9b35fd836a38d72c39efc112300ab5d92503ba (patch)
tree0c84be2250e27952fb6821b77fd96c3167a78513
parente0dab0305d1967b57b12d2deb94e4253bf7cde06 (diff)
add clean all
-rwxr-xr-xcore/src/xmake/machine.c2
-rwxr-xr-xcore/src/xmake/makefile1
-rwxr-xr-xcore/src/xmake/os/emptydir.c79
-rwxr-xr-xcore/src/xmake/os/rmdir.c70
-rw-r--r--xmake/scripts/action/_build.lua4
-rw-r--r--xmake/scripts/action/_clean.lua5
-rw-r--r--xmake/scripts/base/clean.lua76
-rw-r--r--xmake/scripts/base/os.lua36
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