summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-07-04 20:44:59 +0800
committerruki <[email protected]>2017-07-04 20:44:59 +0800
commitb753a04049557b83e19e3a1f555c4a01b549ac2f (patch)
tree5a149597a6cd3e1022dda01581f776b400d37f91
parent4e87aeb64724f77a5d78907bdb4707a255715622 (diff)
parent09eb1c7424d281e454cfffda6a65718a9e284cd8 (diff)
merge from dev
-rw-r--r--.travis.yml4
-rw-r--r--CHANGELOG.md16
-rw-r--r--core/src/xmake/machine.c4
-rw-r--r--core/src/xmake/makefile1
-rw-r--r--core/src/xmake/process/waitlist.c2
-rw-r--r--core/src/xmake/string/endswith.c6
-rw-r--r--core/src/xmake/string/startswith.c2
-rw-r--r--core/src/xmake/string/strcmp.c57
-rw-r--r--scripts/installer.nsi11
-rw-r--r--tests/build.lua3
-rwxr-xr-xtests/modules/lib/detect/test.lua14
-rw-r--r--tests/modules/string/test.lua5
-rw-r--r--xmake/actions/build/kinds/binary.lua11
-rw-r--r--xmake/actions/build/kinds/object.lua44
-rw-r--r--xmake/actions/build/kinds/shared.lua11
-rw-r--r--xmake/actions/build/kinds/static.lua11
-rw-r--r--xmake/actions/build/main.lua3
-rw-r--r--xmake/actions/config/main.lua12
-rw-r--r--xmake/core/_xmake_main.lua5
-rw-r--r--xmake/core/base/filter.lua15
-rw-r--r--xmake/core/base/interpreter.lua2
-rw-r--r--xmake/core/base/option.lua2
-rw-r--r--xmake/core/base/os.lua64
-rw-r--r--xmake/core/base/process.lua104
-rw-r--r--xmake/core/base/string.lua7
-rw-r--r--xmake/core/base/table.lua3
-rw-r--r--xmake/core/language/language.lua12
-rw-r--r--xmake/core/platform/platform.lua10
-rw-r--r--xmake/core/project/option.lua521
-rw-r--r--xmake/core/project/project.lua58
-rw-r--r--xmake/core/project/target.lua56
-rw-r--r--xmake/core/project/template.lua8
-rw-r--r--xmake/core/sandbox/modules/import.lua75
-rw-r--r--xmake/core/sandbox/modules/import/core/platform/platform.lua10
-rw-r--r--xmake/core/sandbox/modules/import/core/project/cache.lua4
-rw-r--r--xmake/core/sandbox/modules/import/core/project/history.lua4
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua42
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/compiler.lua35
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/linker.lua20
-rw-r--r--xmake/core/sandbox/modules/import/core/tool/tool.lua49
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/cache.lua (renamed from xmake/core/sandbox/modules/import/lib/detect/clear_cache.lua)58
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_directory.lua106
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_file.lua25
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_library.lua56
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_package.lua130
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_path.lua39
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua37
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_programver.lua10
-rw-r--r--xmake/core/sandbox/modules/inherit.lua10
-rw-r--r--xmake/core/sandbox/modules/interpreter/os.lua26
-rw-r--r--xmake/core/sandbox/modules/os.lua59
-rw-r--r--xmake/core/sandbox/modules/string.lua12
-rw-r--r--xmake/core/sandbox/modules/utils.lua3
-rw-r--r--xmake/core/sandbox/sandbox.lua47
-rw-r--r--xmake/core/tool/builder.lua76
-rw-r--r--xmake/core/tool/compiler.lua114
-rw-r--r--xmake/core/tool/extractor.lua10
-rw-r--r--xmake/core/tool/linker.lua90
-rw-r--r--xmake/core/tool/tool.lua288
-rw-r--r--xmake/languages/c++/api.lua71
-rw-r--r--xmake/modules/core/tools/ar.lua (renamed from xmake/tools/ar.lua)53
-rw-r--r--xmake/modules/core/tools/cl.lua (renamed from xmake/tools/cl.lua)83
-rw-r--r--xmake/modules/core/tools/clang.lua (renamed from xmake/tools/clang.lua)7
-rw-r--r--xmake/modules/core/tools/clangxx.lua (renamed from xmake/tools/clang++.lua)7
-rw-r--r--xmake/modules/core/tools/dmd.lua (renamed from xmake/tools/dmd.lua)95
-rw-r--r--xmake/modules/core/tools/gcc.lua (renamed from xmake/tools/gcc.lua)136
-rw-r--r--xmake/modules/core/tools/gccgo.lua (renamed from xmake/core/sandbox/modules/import/core/project/option.lua)18
-rw-r--r--xmake/modules/core/tools/gdc.lua (renamed from xmake/tools/gdc.lua)6
-rw-r--r--xmake/modules/core/tools/go.lua (renamed from xmake/tools/go.lua)64
-rw-r--r--xmake/modules/core/tools/gxx.lua (renamed from xmake/tools/g++.lua)7
-rw-r--r--xmake/modules/core/tools/ldc.lua (renamed from xmake/tools/ldc.lua)4
-rw-r--r--xmake/modules/core/tools/lib.lua (renamed from xmake/tools/lib.lua)37
-rw-r--r--xmake/modules/core/tools/link.lua (renamed from xmake/tools/link.lua)65
-rw-r--r--xmake/modules/core/tools/ml.lua (renamed from xmake/tools/ml.lua)61
-rw-r--r--xmake/modules/core/tools/ml64.lua28
-rw-r--r--xmake/modules/core/tools/rc.lua (renamed from xmake/tools/rc.lua)59
-rw-r--r--xmake/modules/core/tools/rustc.lua (renamed from xmake/tools/rustc.lua)58
-rw-r--r--xmake/modules/core/tools/swiftc.lua (renamed from xmake/tools/swiftc.lua)81
-rw-r--r--xmake/modules/detect/packages/find_openssl.lua74
-rw-r--r--xmake/modules/detect/packages/find_zlib.lua81
-rw-r--r--xmake/modules/detect/sdks/find_cross_toolchains.lua (renamed from xmake/modules/detect/sdk/find_cross_toolchains.lua)0
-rw-r--r--xmake/modules/detect/sdks/find_ndk_sdkvers.lua (renamed from xmake/modules/detect/sdk/find_ndk_sdkvers.lua)0
-rw-r--r--xmake/modules/detect/sdks/find_ndk_toolchains.lua (renamed from xmake/modules/detect/sdk/find_ndk_toolchains.lua)0
-rw-r--r--xmake/modules/detect/sdks/find_vstudio.lua (renamed from xmake/modules/detect/sdk/find_vstudio.lua)6
-rw-r--r--xmake/modules/detect/sdks/find_xcode_dir.lua (renamed from xmake/modules/detect/sdk/find_xcode_dir.lua)4
-rw-r--r--xmake/modules/detect/sdks/find_xcode_sdkvers.lua (renamed from xmake/modules/detect/sdk/find_xcode_sdkvers.lua)2
-rw-r--r--xmake/modules/detect/tools/ar/has_flag.lua84
-rw-r--r--xmake/modules/detect/tools/cl/has_flag.lua98
-rw-r--r--xmake/modules/detect/tools/clang/has_flag.lua (renamed from xmake/modules/detect/package/find_openssl.lua)14
-rw-r--r--xmake/modules/detect/tools/clangxx/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/dmd/has_flag.lua118
-rw-r--r--xmake/modules/detect/tools/find_7z.lua (renamed from xmake/modules/detect/tool/find_7z.lua)5
-rw-r--r--xmake/modules/detect/tools/find_ar.lua70
-rw-r--r--xmake/modules/detect/tools/find_brew.lua58
-rw-r--r--xmake/modules/detect/tools/find_ccache.lua (renamed from xmake/modules/detect/tool/find_ccache.lua)5
-rw-r--r--xmake/modules/detect/tools/find_cl.lua59
-rw-r--r--xmake/modules/detect/tools/find_clang.lua58
-rw-r--r--xmake/modules/detect/tools/find_clangxx.lua58
-rw-r--r--xmake/modules/detect/tools/find_curl.lua (renamed from xmake/modules/detect/tool/find_curl.lua)5
-rw-r--r--xmake/modules/detect/tools/find_dmd.lua57
-rw-r--r--xmake/modules/detect/tools/find_doxygen.lua (renamed from xmake/modules/detect/tool/find_doxygen.lua)5
-rw-r--r--xmake/modules/detect/tools/find_gcc.lua58
-rw-r--r--xmake/modules/detect/tools/find_gccgo.lua57
-rw-r--r--xmake/modules/detect/tools/find_gdb.lua (renamed from xmake/modules/detect/tool/find_gdb.lua)2
-rw-r--r--xmake/modules/detect/tools/find_gdc.lua57
-rw-r--r--xmake/modules/detect/tools/find_git.lua (renamed from xmake/modules/detect/tool/find_git.lua)5
-rw-r--r--xmake/modules/detect/tools/find_go.lua57
-rw-r--r--xmake/modules/detect/tools/find_gxx.lua58
-rw-r--r--xmake/modules/detect/tools/find_gzip.lua (renamed from xmake/modules/detect/tool/find_gzip.lua)5
-rw-r--r--xmake/modules/detect/tools/find_ldc2.lua57
-rw-r--r--xmake/modules/detect/tools/find_lib.lua77
-rw-r--r--xmake/modules/detect/tools/find_link.lua78
-rw-r--r--xmake/modules/detect/tools/find_lipo.lua (renamed from xmake/modules/detect/tool/find_lipo.lua)5
-rw-r--r--xmake/modules/detect/tools/find_lldb.lua (renamed from xmake/modules/detect/tool/find_lldb.lua)2
-rw-r--r--xmake/modules/detect/tools/find_ml.lua59
-rw-r--r--xmake/modules/detect/tools/find_ml64.lua59
-rw-r--r--xmake/modules/detect/tools/find_ollydbg.lua (renamed from xmake/modules/detect/tool/find_ollydbg.lua)0
-rw-r--r--xmake/modules/detect/tools/find_pkg_config.lua (renamed from xmake/modules/detect/tool/find_pkg_config.lua)0
-rw-r--r--xmake/modules/detect/tools/find_rc.lua58
-rw-r--r--xmake/modules/detect/tools/find_rustc.lua (renamed from xmake/tools/gccgo.lua)53
-rw-r--r--xmake/modules/detect/tools/find_sudo.lua (renamed from xmake/modules/detect/tool/find_sudo.lua)5
-rw-r--r--xmake/modules/detect/tools/find_swiftc.lua58
-rw-r--r--xmake/modules/detect/tools/find_tar.lua (renamed from xmake/modules/detect/tool/find_tar.lua)5
-rw-r--r--xmake/modules/detect/tools/find_unzip.lua (renamed from xmake/modules/detect/tool/find_unzip.lua)5
-rw-r--r--xmake/modules/detect/tools/find_vsjitdebugger.lua (renamed from xmake/modules/detect/tool/find_vsjitdebugger.lua)0
-rw-r--r--xmake/modules/detect/tools/find_wget.lua (renamed from xmake/modules/detect/tool/find_wget.lua)5
-rw-r--r--xmake/modules/detect/tools/find_windbg.lua (renamed from xmake/modules/detect/tool/find_windbg.lua)0
-rw-r--r--xmake/modules/detect/tools/find_x64dbg.lua (renamed from xmake/modules/detect/tool/find_x64dbg.lua)0
-rw-r--r--xmake/modules/detect/tools/find_zip.lua (renamed from xmake/modules/detect/tool/find_zip.lua)5
-rw-r--r--xmake/modules/detect/tools/gcc/has_flag.lua119
-rw-r--r--xmake/modules/detect/tools/gccgo/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/gdc/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/gxx/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/ldc/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/link/has_flag.lua116
-rw-r--r--xmake/modules/detect/tools/ml/has_flag.lua98
-rw-r--r--xmake/modules/detect/tools/ml64/has_flag.lua27
-rw-r--r--xmake/modules/detect/tools/rustc/has_flag.lua98
-rw-r--r--xmake/modules/devel/debugger/run.lua22
-rw-r--r--xmake/modules/devel/git/checkout.lua2
-rw-r--r--xmake/modules/devel/git/clean.lua2
-rw-r--r--xmake/modules/devel/git/clone.lua2
-rw-r--r--xmake/modules/devel/git/ls_remote.lua2
-rw-r--r--xmake/modules/devel/git/pull.lua2
-rw-r--r--xmake/modules/lib/detect/find_tool.lua94
-rw-r--r--xmake/modules/lib/detect/find_toolname.lua107
-rw-r--r--xmake/modules/lib/detect/has_cxsnippets.lua227
-rw-r--r--xmake/modules/lib/detect/has_flags.lua115
-rw-r--r--xmake/modules/lib/detect/pkg_config.lua183
-rw-r--r--xmake/modules/net/http/download.lua4
-rw-r--r--xmake/modules/privilege/sudo.lua54
-rw-r--r--xmake/modules/utils/archive/extract.lua8
-rw-r--r--xmake/platforms/android/check.lua4
-rw-r--r--xmake/platforms/checker.lua86
-rw-r--r--xmake/platforms/iphoneos/check.lua16
-rw-r--r--xmake/platforms/linux/check.lua118
-rw-r--r--xmake/platforms/macosx/check.lua99
-rw-r--r--xmake/platforms/mingw/check.lua22
-rw-r--r--xmake/platforms/watchos/check.lua16
-rw-r--r--xmake/platforms/windows/check.lua78
-rw-r--r--xmake/plugins/app2ipa/main.lua2
-rw-r--r--xmake/plugins/doxygen/main.lua2
-rw-r--r--xmake/plugins/lua/scripts/lipo.lua2
-rw-r--r--xmake/plugins/macro/main.lua4
-rw-r--r--xmake/plugins/project/makefile/makefile.lua52
-rw-r--r--xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua4
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua81
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua95
-rwxr-xr-xxmake/scripts/gas-preprocessor.pl (renamed from xmake/tools/utils/gas-preprocessor.pl)2
169 files changed, 4897 insertions, 2353 deletions
diff --git a/.travis.yml b/.travis.yml
index e7e12f2b2..ae11d601d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,8 +23,8 @@ script:
- scripts/get.sh __local__
- source ~/.xmake/profile
- xmake lua versioninfo
- - xmake f -m coverage -P core
- - xmake -P core
+ - xmake f -m coverage -P core
+ - xmake -v -P core
- export XMAKE_PROGRAM_DIR=$PWD/xmake
- core/build/xmake lua versioninfo
- echo "require('luacov.runner').init({['statsfile']='$PWD/luacov.stats.out',['reportfile']='$PWD/luacov.report.out'})" > tmp
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0c14cc6d6..11327afc0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,10 +6,12 @@
* [#83](https://github.com/tboox/xmake/issues/83): Add `add_csnippet` and `add_cxxsnippet` into `option` for detecting some compiler features.
* [#83](https://github.com/tboox/xmake/issues/83): Add user extension modules to detect program, libraries and files.
-* Add `find_program`, `find_file` and `find_library` module interfaces.
+* Add `find_program`, `find_file`, `find_library`, `find_tool` and `find_package` module interfaces.
* Add `net.*` and `devel.*` extension modules
* Add `val()` api to get the value of builtin-variable, .e.g `val("host")`, `val("env PATH")`, `val("shell echo hello")` and `val("reg HKEY_LOCAL_MACHINE\\XX;Value")`
* Support to compile the microsoft resource file (.rc)
+* Add `has_flags` module interfaces.
+* Add `option.on_check`, `option.after_check` and `option.before_check` api
### Changes
@@ -23,12 +25,16 @@
* Improve `xxx_script` in `xmake.lua` to support pattern match, .e.g `on_build("iphoneos|arm*", function (target) end)`
* improve builtin-variables to support to get the value envirnoment and registry
* Improve to detect vstudio sdk and cross toolchains envirnoment
+* [#71](https://github.com/tboox/xmake/issues/71): Improve to detect compiler and linker from env vars
+* Improve the option detection (cache and multi-jobs) and increase 70% speed
+* [#129](https://github.com/tboox/xmake/issues/129): Check link deps and cache the target file
### Bugs fixed
* Fix `try-catch-finally`
* Fix interpreter bug when parsing multi-level subdirs
* [#115](https://github.com/tboox/xmake/pull/115): Fix the path problem of the install script `get.sh`
+* Fix cache bug for import()
## v2.1.4
@@ -304,10 +310,12 @@
* [#83](https://github.com/tboox/xmake/issues/83): 添加 `add_csnippet`,`add_cxxsnippet`到`option`来检测一些编译器特性
* [#83](https://github.com/tboox/xmake/issues/83): 添加用户扩展模块去探测程序,库文件以及其他主机环境
-* 添加`find_program`, `find_file` 和 `find_library` 等模块接口
+* 添加`find_program`, `find_file`, `find_library`, `find_tool`和`find_package` 等模块接口
* 添加`net.*`和`devel.*`扩展模块
* 添加`val()`接口去获取内置变量,例如:`val("host")`, `val("env PATH")`, `val("shell echo hello")` and `val("reg HKEY_LOCAL_MACHINE\\XX;Value")`
* 增加对微软.rc资源文件的编译支持,当在windows上编译时,可以增加资源文件了
+* 增加`has_flags`模块接口
+* 添加`option.on_check`, `option.after_check` 和 `option.before_check` 接口
### 改进
@@ -321,12 +329,16 @@
* 改进`xxx_script`工程描述api,支持多平台模式选择, 例如:`on_build("iphoneos|arm*", function (target) end)`
* 改进内置变量,支持环境变量和注册表数据的获取
* 改进vstudio环境和交叉工具链的探测
+* [#71](https://github.com/tboox/xmake/issues/71): 改进从环境变量中探测链接器和编译器
+* 改进option选项检测,通过多任务检测,提升70%的检测速度
+* [#129](https://github.com/tboox/xmake/issues/129): 检测链接依赖,如果源文件没有改变,就不必重新链接目标文件了
### Bugs修复
* 修复`try-catch-finally`
* 修复解释器bug,解决当加载多级子目录时,根域属性设置不对
* [#115](https://github.com/tboox/xmake/pull/115): 修复安装脚本`get.sh`的路径问题
+* 修复`import()`导入接口的缓存问题
## v2.1.4
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index e1638e1ab..7f1acfbd0 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -99,7 +99,6 @@ tb_int_t xm_winreg_query(lua_State* lua);
#endif
// the string functions
-tb_int_t xm_string_strcmp(lua_State* lua);
tb_int_t xm_string_endswith(lua_State* lua);
tb_int_t xm_string_startswith(lua_State* lua);
@@ -172,8 +171,7 @@ static luaL_Reg const g_path_functions[] =
// the string functions
static luaL_Reg const g_string_functions[] =
{
- { "strcmp", xm_string_strcmp }
-, { "endswith", xm_string_endswith }
+ { "endswith", xm_string_endswith }
, { "startswith", xm_string_startswith }
, { tb_null, tb_null }
};
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index efc32d94d..e9f5badce 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -45,7 +45,6 @@ xmake_C_FILES += \
path/translate \
path/is_absolute \
winreg/query \
- string/strcmp \
string/endswith \
string/startswith \
process/open \
diff --git a/core/src/xmake/process/waitlist.c b/core/src/xmake/process/waitlist.c
index 3e5d20aa0..b577c87f4 100644
--- a/core/src/xmake/process/waitlist.c
+++ b/core/src/xmake/process/waitlist.c
@@ -71,7 +71,7 @@ tb_int_t xm_process_waitlist(lua_State* lua)
if (count <= 0 || count > 64)
{
// error
- lua_pushfstring(lua, "invalid process count(%ld) for process.waitlist", count);
+ lua_pushfstring(lua, "invalid process count(%d) for process.waitlist", count);
lua_error(lua);
return 0;
}
diff --git a/core/src/xmake/string/endswith.c b/core/src/xmake/string/endswith.c
index 241e59254..8de61e2bb 100644
--- a/core/src/xmake/string/endswith.c
+++ b/core/src/xmake/string/endswith.c
@@ -49,9 +49,9 @@ tb_int_t xm_string_endswith(lua_State* lua)
tb_char_t const* suffix = luaL_checklstring(lua, 2, &suffix_size);
tb_check_return_val(string && suffix, 0);
- // done string:endswith(suffix)
- if (string_size >= suffix_size)
- lua_pushboolean(lua, !tb_strcmp(string + string_size - suffix_size, suffix));
+ // string:endswith(suffix)?
+ lua_pushboolean(lua, string_size >= suffix_size && !tb_strcmp(string + string_size - suffix_size, suffix));
+
// ok
return 1;
diff --git a/core/src/xmake/string/startswith.c b/core/src/xmake/string/startswith.c
index 84766e5ca..de039dede 100644
--- a/core/src/xmake/string/startswith.c
+++ b/core/src/xmake/string/startswith.c
@@ -48,7 +48,7 @@ tb_int_t xm_string_startswith(lua_State* lua)
tb_char_t const* prefix = luaL_checklstring(lua, 2, &prefix_size);
tb_check_return_val(string && prefix, 0);
- // done string:startswith(prefix)
+ // string:startswith(prefix)?
lua_pushboolean(lua, !tb_strncmp(string, prefix, (tb_size_t)prefix_size));
// ok
diff --git a/core/src/xmake/string/strcmp.c b/core/src/xmake/string/strcmp.c
deleted file mode 100644
index 2ad06f27d..000000000
--- a/core/src/xmake/string/strcmp.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*!The Make-like 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 strcmp.c
- *
- */
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * trace
- */
-#define TB_TRACE_MODULE_NAME "strcmp"
-#define TB_TRACE_MODULE_DEBUG (0)
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * includes
- */
-#include "prefix.h"
-
-/* //////////////////////////////////////////////////////////////////////////////////////
- * implementation
- */
-
-// string:strcmp(s1, s2)
-tb_int_t xm_string_strcmp(lua_State* lua)
-{
- // check
- tb_assert_and_check_return_val(lua, 0);
-
- // get the strings
- tb_char_t const* s1 = luaL_checkstring(lua, 1);
- tb_char_t const* s2 = luaL_checkstring(lua, 2);
- tb_check_return_val(s1 && s2, 0);
-
- // compare them
- lua_pushinteger(lua, tb_strcmp(s1, s2));
-
- // ok
- return 1;
-}
diff --git a/scripts/installer.nsi b/scripts/installer.nsi
index e2deebfc0..f4dd014b5 100644
--- a/scripts/installer.nsi
+++ b/scripts/installer.nsi
@@ -44,6 +44,13 @@ RequestExecutionLevel admin
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
+
+;--------------------------------
+; Finish Pages
+
+!define MUI_FINISHPAGE_LINK "Donate $$5"
+!define MUI_FINISHPAGE_LINK_LOCATION "http://xmake.io/pages/donation.html#donate"
+!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Languages
@@ -53,13 +60,13 @@ RequestExecutionLevel admin
;--------------------------------
; Version Information
-VIProductVersion "2.1.4.0402"
+VIProductVersion "2.1.5.0630"
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "XMake"
VIAddVersionKey /LANG=${LANG_ENGLISH} "Comments" "website: http://www.xmake.io"
VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "The TBOOX Open Source Group"
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright 2015-2017 tboox.org"
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "The Make-like Build Utility based on Lua"
-VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "2.1.4"
+VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "2.1.5"
;--------------------------------
diff --git a/tests/build.lua b/tests/build.lua
index 226fddacf..fa8b59e2a 100644
--- a/tests/build.lua
+++ b/tests/build.lua
@@ -4,6 +4,9 @@ import("privilege.sudo")
-- main entry
function main(argv)
+ -- check global config
+ os.exec("xmake g -c")
+
-- generic?
os.exec("xmake m -b")
os.exec("xmake f -c")
diff --git a/tests/modules/lib/detect/test.lua b/tests/modules/lib/detect/test.lua
new file mode 100755
index 000000000..c44084ddc
--- /dev/null
+++ b/tests/modules/lib/detect/test.lua
@@ -0,0 +1,14 @@
+import("lib.detect.find_toolname")
+
+function main()
+ assert(find_toolname("xcrun -sdk macosx clang") == "clang")
+ assert(find_toolname("xcrun -sdk macosx clang++") == "clangxx")
+ assert(find_toolname("/usr/bin/arm-linux-gcc") == "gcc")
+ assert(find_toolname("/usr/bin/arm-linux-g++") == "gxx")
+ assert(find_toolname("/usr/bin/arm-linux-ar") == "ar")
+ assert(find_toolname("link.exe -lib") == "link")
+ assert(find_toolname("arm-android-clang++") == "clangxx")
+ assert(find_toolname("pkg-config") == "pkg_config")
+ assert(find_toolname("gcc-5") == "gcc")
+end
+
diff --git a/tests/modules/string/test.lua b/tests/modules/string/test.lua
index b2e7a23c7..98c76661f 100644
--- a/tests/modules/string/test.lua
+++ b/tests/modules/string/test.lua
@@ -1,4 +1,5 @@
function main()
- assert(string.less("awd","dwa"))
- assert(not string.less("dwa","awd"))
+ assert(not ("rc"):endswith("xcadas"))
+ assert(("aaaccc"):endswith("ccc"))
+ assert(("aaaccc"):startswith("aaa"))
end
diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua
index b7dd5f512..52baad2a3 100644
--- a/xmake/actions/build/kinds/binary.lua
+++ b/xmake/actions/build/kinds/binary.lua
@@ -34,6 +34,11 @@ function _build_from_objects(target, buildinfo)
-- build objects
object.build(target, buildinfo)
+ -- the object files are not modified?
+ if not buildinfo.objects_modified then
+ return
+ end
+
-- expand object files with *.o/obj
local objectfiles = {}
for _, objectfile in ipairs(target:objectfiles()) do
@@ -67,7 +72,7 @@ function _build_from_objects(target, buildinfo)
end
-- link it
- linker.link(objectfiles, targetfile, target)
+ linker.link(target:get("kind"), target:sourcekinds(), objectfiles, targetfile, {target = target})
end
-- build target from sources
@@ -89,11 +94,11 @@ function _build_from_sources(target, buildinfo, sourcebatch, sourcekind)
-- trace verbose info
if verbose then
- print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, target, sourcekind))
+ print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}))
end
-- build it
- compiler.build(sourcebatch.sourcefiles, targetfile, target, sourcekind)
+ compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})
end
-- build binary target
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index aa738108d..513cb2b9e 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -24,11 +24,10 @@
-- imports
import("core.base.option")
-import("core.tool.tool")
import("core.tool.compiler")
import("core.tool.extractor")
import("core.project.config")
-import("detect.tool.find_ccache")
+import("detect.tools.find_ccache")
-- build the object from the *.[o|obj] source file
function _build_from_object(target, sourcefile, objectfile, percent)
@@ -75,7 +74,7 @@ function _build_from_static(target, sourcefile, objectfile, percent)
end
-- build object
-function _build_object(target, buildinfo, index, sourcebatch)
+function _build_object(target, buildinfo, index, sourcebatch, ccache)
-- get the object and source with the given index
local sourcefile = sourcebatch.sourcefiles[index]
@@ -141,15 +140,12 @@ function _build_object(target, buildinfo, index, sourcebatch)
return
end
+ -- the object files are modified
+ buildinfo.objects_modified = true
+
-- is verbose?
local verbose = option.get("verbose")
- -- get ccache
- local ccache = nil
- if config.get("ccache") then
- ccache = find_ccache()
- end
-
-- trace percent info
if verbose then
cprint("${green}[%02d%%]:${dim} %scompiling.$(mode) %s", percent, ifelse(ccache, "ccache ", ""), sourcefile)
@@ -159,15 +155,15 @@ function _build_object(target, buildinfo, index, sourcebatch)
-- trace verbose info
if verbose then
- print(compiler.compcmd(sourcefile, objectfile, target))
+ print(compiler.compcmd(sourcefile, objectfile, {target = target}))
end
-- complie it
- compiler.compile(sourcefile, objectfile, incdepfile, target)
+ compiler.compile(sourcefile, objectfile, {incdepfiles = incdepfile, target = target})
end
-- build each objects from the given source batch
-function _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs)
+function _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs, ccache)
-- run build jobs for each source file
local curdir = os.curdir()
@@ -177,7 +173,7 @@ function _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs)
os.cd(curdir)
-- build object
- _build_object(target, buildinfo, index, sourcebatch)
+ _build_object(target, buildinfo, index, sourcebatch, ccache)
end, #sourcebatch.sourcefiles, jobs)
@@ -186,7 +182,7 @@ function _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs)
end
-- compile source files to single object at the same time
-function _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs)
+function _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs, ccache)
-- is verbose?
local verbose = option.get("verbose")
@@ -196,12 +192,6 @@ function _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs)
local objectfiles = sourcebatch.objectfiles
local incdepfiles = sourcebatch.incdepfiles
- -- get ccache
- local ccache = nil
- if config.get("ccache") then
- ccache = find_ccache()
- end
-
-- trace percent info
for index, sourcefile in ipairs(sourcefiles) do
@@ -218,11 +208,11 @@ function _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs)
-- trace verbose info
if verbose then
- print(compiler.compcmd(sourcefiles, objectfiles, target, sourcekind))
+ print(compiler.compcmd(sourcefiles, objectfiles, {target = target, sourcekind = sourcekind}))
end
-- complie them
- compiler.compile(sourcefiles, objectfiles, incdepfiles, target, sourcekind)
+ compiler.compile(sourcefiles, objectfiles, {incdepfiles = incdepfiles, target = target, sourcekind = sourcekind})
-- update object index
_g.sourceindex = _g.sourceindex + #sourcebatch.sourcefiles
@@ -238,6 +228,12 @@ function build(target, buildinfo)
-- get the max job count
local jobs = tonumber(option.get("jobs") or "4")
+ -- get ccache
+ local ccache = nil
+ if config.get("ccache") then
+ ccache = find_ccache()
+ end
+
-- build source batches
for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
@@ -245,12 +241,12 @@ function build(target, buildinfo)
if type(sourcebatch.objectfiles) == "string" then
-- build single object
- _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs)
+ _build_single_object(target, buildinfo, sourcekind, sourcebatch, jobs, ccache)
else
-- build each objects
- _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs)
+ _build_each_objects(target, buildinfo, sourcekind, sourcebatch, jobs, ccache)
end
end
end
diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua
index ab2cd40b0..d4fa90257 100644
--- a/xmake/actions/build/kinds/shared.lua
+++ b/xmake/actions/build/kinds/shared.lua
@@ -34,6 +34,11 @@ function _build_from_objects(target, buildinfo)
-- build objects
object.build(target, buildinfo)
+ -- the object files are not modified?
+ if not buildinfo.objects_modified then
+ return
+ end
+
-- make headers
local srcheaders, dstheaders = target:headerfiles()
if srcheaders and dstheaders then
@@ -80,7 +85,7 @@ function _build_from_objects(target, buildinfo)
end
-- link it
- linker.link(objectfiles, targetfile, target)
+ linker.link(target:get("kind"), target:sourcekinds(), objectfiles, targetfile, {target = target})
end
-- build target from sources
@@ -102,11 +107,11 @@ function _build_from_sources(target, buildinfo, sourcebatch, sourcekind)
-- trace verbose info
if verbose then
- print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, target, sourcekind))
+ print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}))
end
-- build it
- compiler.build(sourcebatch.sourcefiles, targetfile, target, sourcekind)
+ compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})
end
-- build shared target
diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua
index 6dcacbd30..9b73742a3 100644
--- a/xmake/actions/build/kinds/static.lua
+++ b/xmake/actions/build/kinds/static.lua
@@ -34,6 +34,11 @@ function _build_from_objects(target, buildinfo)
-- build objects
object.build(target, buildinfo)
+ -- the object files are not modified?
+ if not buildinfo.objects_modified then
+ return
+ end
+
-- make headers
local srcheaders, dstheaders = target:headerfiles()
if srcheaders and dstheaders then
@@ -80,7 +85,7 @@ function _build_from_objects(target, buildinfo)
end
-- link it
- linker.link(objectfiles, targetfile, target)
+ linker.link(target:get("kind"), target:sourcekinds(), objectfiles, targetfile, {target = target})
end
-- build target from sources
@@ -102,11 +107,11 @@ function _build_from_sources(target, buildinfo, sourcebatch, sourcekind)
-- trace verbose info
if verbose then
- print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, target, sourcekind))
+ print(compiler.buildcmd(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind}))
end
-- build it
- compiler.build(sourcebatch.sourcefiles, targetfile, target, sourcekind)
+ compiler.build(sourcebatch.sourcefiles, targetfile, {target = target, sourcekind = sourcekind})
end
-- build static target
diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua
index 18df4afb9..95ea22206 100644
--- a/xmake/actions/build/main.lua
+++ b/xmake/actions/build/main.lua
@@ -27,9 +27,8 @@ import("core.base.option")
import("core.project.task")
import("core.project.config")
import("core.project.project")
-import("core.project.cache")
+import("core.project.cache", {nocache = true})
import("core.platform.platform")
-import("core.tool.tool")
import("builder")
-- main
diff --git a/xmake/actions/config/main.lua b/xmake/actions/config/main.lua
index 2f5edceba..07588378c 100644
--- a/xmake/actions/config/main.lua
+++ b/xmake/actions/config/main.lua
@@ -28,8 +28,8 @@ import("core.project.config")
import("core.project.global")
import("core.project.project")
import("core.platform.platform")
-import("core.project.cache")
-import("lib.detect.clear_cache")
+import("core.project.cache", {nocache = true})
+import("lib.detect.cache", {alias = "detectcache"})
import("scanner")
import("configheader")
@@ -234,7 +234,7 @@ function main()
cache.set("rebuild", true)
-- clear detect cache
- clear_cache()
+ detectcache.clear()
end
-- merge the cached configure
@@ -277,10 +277,8 @@ function main()
configheader.make()
end
- -- trace
- if recheck or option.get("verbose") then
-
- -- dump it
+ -- dump config
+ if option.get("verbose") then
config.dump()
end
diff --git a/xmake/core/_xmake_main.lua b/xmake/core/_xmake_main.lua
index 39bb5f225..58af78d66 100644
--- a/xmake/core/_xmake_main.lua
+++ b/xmake/core/_xmake_main.lua
@@ -33,13 +33,10 @@ xmake._VERSION_SHORT = _VERSION_SHORT
xmake._PROGRAM_DIR = _PROGRAM_DIR
xmake._PROGRAM_FILE = _PROGRAM_FILE
xmake._PROJECT_DIR = _PROJECT_DIR
-xmake._CORE_DIR = _PROGRAM_DIR .. "/core"
-xmake._TOOLS_DIR = _PROGRAM_DIR .. "/tools"
-xmake._TEMPLATES_DIR = _PROGRAM_DIR .. "/templates"
xmake._PROJECT_FILE = "xmake.lua"
-- init package path
-package.path = xmake._CORE_DIR .. "/?.lua;" .. package.path
+package.path = xmake._PROGRAM_DIR .. "/core/?.lua;" .. package.path
-- load modules
local main = require("main")
diff --git a/xmake/core/base/filter.lua b/xmake/core/base/filter.lua
index f9744bf61..9dd146ac6 100644
--- a/xmake/core/base/filter.lua
+++ b/xmake/core/base/filter.lua
@@ -31,6 +31,10 @@ local table = require("base/table")
local utils = require("base/utils")
local string = require("base/string")
+-- globals
+local escape_table1 = {["$"] = "\001", ["("] = "\002", [")"] = "\003", ["%"] = "\004"}
+local escape_table2 = {["\001"] = "$", ["\002"] = "(", ["\003"] = ")", ["\004"] = "%"}
+
-- new filter instance
function filter.new()
@@ -155,10 +159,19 @@ function filter:handle(value)
-- check
assert(type(value) == "string")
+ -- escape "%$", "%(", "%)", "%%" to "\001", "\002", "\003", "\004"
+ value = value:gsub("%%([%$%(%)%%])", function (ch) return escape_table1[ch] end)
+
-- filter the builtin variables
return (value:gsub("%$%((.-)%)", function (variable)
+
+ -- escape "%$", "%(", "%)", "%%" to "$", "(", ")", "%"
+ variable = variable:gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end)
+
+ -- get variable value
return self:get(variable) or ""
- end))
+
+ end):gsub("[\001\002\003\004]", function (ch) return escape_table2[ch] end))
end
-- return module: filter
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index 5c51b35e4..c23fa8457 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -700,7 +700,7 @@ function interpreter.new()
instance:api_register(nil, "set_xmakever", interpreter.api_builtin_set_xmakever)
-- load builtin module files
- local builtin_module_files = os.match(path.join(xmake._CORE_DIR, "sandbox/modules/interpreter/*.lua"))
+ local builtin_module_files = os.match(path.join(os.programdir(), "core/sandbox/modules/interpreter/*.lua"))
if builtin_module_files then
for _, builtin_module_file in ipairs(builtin_module_files) do
diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua
index a2388c91e..e780656d4 100644
--- a/xmake/core/base/option.lua
+++ b/xmake/core/base/option.lua
@@ -479,7 +479,7 @@ function option.init(menu)
end
-- init the default value
- for _, o in ipairs(option._taskmenu().options) do
+ for _, o in ipairs(table.wrap(option._taskmenu().options)) do
-- the long name
local longname = option._longname(o[2])
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 5c7ca78e2..6616c2849 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -442,7 +442,7 @@ function os.tmpfile()
return path.join(os.tmpdir(), "_" .. (os.uuid():gsub("-", "")))
end
--- run shell
+-- run command
function os.run(cmd)
-- parse arguments
@@ -455,23 +455,23 @@ function os.run(cmd)
return os.runv(argv[1], table.slice(argv, 2))
end
--- run shell with arguments list
-function os.runv(shellname, argv)
+-- run command with arguments list
+function os.runv(program, argv)
-- make temporary log file
local log = os.tmpfile()
-- execute it
- local ok = os.execv(shellname, argv, log, log)
+ local ok = os.execv(program, argv, log, log)
if ok ~= 0 then
-- make errors
local errors = io.readfile(log)
if not errors or #errors == 0 then
if argv ~= nil then
- errors = string.format("runv(%s %s) failed(%d)!", shellname, table.concat(argv, ' '), ok)
+ errors = string.format("runv(%s %s) failed(%d)!", program, table.concat(argv, ' '), ok)
else
- errors = string.format("runv(%s) failed(%d)!", shellname, ok)
+ errors = string.format("runv(%s) failed(%d)!", program, ok)
end
end
@@ -489,7 +489,7 @@ function os.runv(shellname, argv)
return true
end
--- execute shell
+-- execute command
function os.exec(cmd, outfile, errfile)
-- parse arguments
@@ -502,12 +502,31 @@ function os.exec(cmd, outfile, errfile)
return os.execv(argv[1], table.slice(argv, 2), outfile, errfile)
end
--- execute shell with arguments list
-function os.execv(shellname, argv, outfile, errfile)
+-- execute command with arguments list
+--
+-- program: "clang", "xcrun -sdk macosx clang", "~/dir/test\ xxx/clang"
+-- filename: "clang", "xcrun"", "~/dir/test\ xxx/clang"
+--
+function os.execv(program, argv, outfile, errfile)
+
+ -- init arguments
+ local args = os.argw(argv)
+
+ -- is not executable program file?
+ local filename = program
+ if not os.isexec(program) then
+
+ -- parse the filename and arguments, .e.g "xcrun -sdk macosx clang"
+ local splitinfo = program:split("%s")
+ filename = splitinfo[1]
+ if #splitinfo > 1 then
+ args = table.join(table.slice(splitinfo, 2), args)
+ end
+ end
-- open command
local ok = -1
- local proc = process.openv(shellname, os.argw(argv), outfile, errfile)
+ local proc = process.openv(filename, args, outfile, errfile)
if proc ~= nil then
-- wait process
@@ -546,7 +565,7 @@ function os.execv(shellname, argv, outfile, errfile)
return ok
end
--- run shell and return output and error data
+-- run command and return output and error data
function os.iorun(cmd)
-- parse arguments
@@ -559,15 +578,15 @@ function os.iorun(cmd)
return os.iorunv(argv[1], table.slice(argv, 2))
end
--- run shell with arguments and return output and error data
-function os.iorunv(shellname, argv)
+-- run command with arguments and return output and error data
+function os.iorunv(program, argv)
-- make temporary output and error file
local outfile = os.tmpfile()
local errfile = os.tmpfile()
-- run command
- local ok = os.execv(shellname, argv, outfile, errfile)
+ local ok = os.execv(program, argv, outfile, errfile)
-- get output and error data
local outdata = io.readfile(outfile)
@@ -595,7 +614,7 @@ function os.raise(msg, ...)
end
end
--- is executable program?
+-- is executable program file?
function os.isexec(filepath)
-- check
@@ -677,23 +696,28 @@ function os.addenv(name, ...)
-- append values
return os.setenv(name, table.concat({...}, seperator) .. seperator .. (os.getenv(name) or ""))
-
end
-- get the program directory
function os.programdir()
-
- -- get it
return xmake._PROGRAM_DIR
end
-- get the program file
function os.programfile()
-
- -- get it
return xmake._PROGRAM_FILE
end
+-- get the project directory
+function os.projectdir()
+ return xmake._PROJECT_DIR
+end
+
+-- get the project file
+function os.projectfile()
+ return xmake._PROJECT_FILE
+end
+
-- get version info
function os.versioninfo()
diff --git a/xmake/core/base/process.lua b/xmake/core/base/process.lua
index 8cf96b2ea..76af563b4 100644
--- a/xmake/core/base/process.lua
+++ b/xmake/core/base/process.lua
@@ -101,53 +101,51 @@ function process.runjobs(jobfunc, total, comax, timeout, timer)
-- wait processes
local tasks_finished = {}
local procs_count = #procs
+ local procs_infos = nil
if procs_count > 0 then
-
- -- wait them
- local count, procinfos = process.waitlist(procs, utils.ifelse(procs_count < comax and index <= total, 0, timeout))
+ local count = -1
+ count, procs_infos = process.waitlist(procs, utils.ifelse(#tasks < comax and index <= total, 0, timeout))
if count < 0 then
return false, string.format("wait processes(%d) failed(%d)", #procs, count)
end
+ end
- -- timer is triggered? call timer
- if timer and os.mclock() - time > timeout then
- timer(indices)
- time = os.mclock()
- end
-
- -- wait ok
- for _, procinfo in ipairs(procinfos) do
-
- -- the process info
- local proc = procinfo[1]
- local procid = procinfo[2]
- local status = procinfo[3]
-
- -- check
- assert(procs[procid] == proc)
-
- -- resume this task
- local job_task = tasks[procid]
- local ok, job_proc_or_errors = coroutine.resume(job_task, 1, status)
- if not ok then
- return false, job_proc_or_errors
- end
+ -- timer is triggered? call timer
+ if timer and os.mclock() - time > timeout then
+ timer(indices)
+ time = os.mclock()
+ end
- -- the other process is pending for this task?
- if coroutine.status(job_task) ~= "dead" then
+ -- append fake procs_infos for coroutine.yield()
+ procs_infos = procs_infos or {}
+ for taskid = #procs + 1, #tasks do
+ table.insert(procs_infos, {nil, taskid, 0})
+ end
- -- check
- assert(job_proc_or_errors)
+ -- wait ok
+ for _, procinfo in ipairs(procs_infos) do
+
+ -- the process info
+ local proc = procinfo[1]
+ local taskid = procinfo[2]
+ local status = procinfo[3]
- -- update the pending process
- procs[procid] = job_proc_or_errors
+ -- check
+ assert(procs[taskid] == proc)
- -- this task has been finised?
- else
+ -- resume this task
+ local job_task = tasks[taskid]
+ local ok, job_proc_or_errors = coroutine.resume(job_task, 1, status)
+ if not ok then
+ return false, job_proc_or_errors
+ end
- -- mark this task as finised
- tasks_finished[procid] = true
- end
+ -- the other process is pending for this task?
+ if coroutine.status(job_task) ~= "dead" then
+ procs[taskid] = job_proc_or_errors
+ else
+ -- mark this task as finished?
+ tasks_finished[taskid] = true
end
end
@@ -156,18 +154,26 @@ function process.runjobs(jobfunc, total, comax, timeout, timer)
local procs_pending = {}
local indices_pending = {}
for taskid, job_task in ipairs(tasks) do
- if not tasks_finished[taskid] then
+ if not tasks_finished[taskid] and procs[taskid] ~= nil then -- for coroutine.yield(proc) in os.execv
table.insert(tasks_pending, job_task)
table.insert(procs_pending, procs[taskid])
table.insert(indices_pending, indices[taskid])
end
end
+ for taskid, job_task in ipairs(tasks) do
+ if not tasks_finished[taskid] and procs[taskid] == nil then -- for coroutine.yield()
+ table.insert(tasks_pending, job_task)
+ table.insert(indices_pending, indices[taskid])
+ end
+ end
tasks = tasks_pending
procs = procs_pending
indices = indices_pending
-- produce tasks
- while #tasks < comax and index <= total do
+ tasks_pending = {}
+ indices_pending = {}
+ while (#tasks + #tasks_pending) < comax and index <= total do
-- new task
local job_task = coroutine.create(jobfunc)
@@ -180,20 +186,24 @@ function process.runjobs(jobfunc, total, comax, timeout, timer)
-- add pending tasks
if coroutine.status(job_task) ~= "dead" then
-
- -- check
- assert(job_proc_or_errors)
-
- -- put task and proc to the pendings tasks
- table.insert(tasks, job_task)
- table.insert(procs, job_proc_or_errors)
- table.insert(indices, index)
+ if job_proc_or_errors ~= nil then -- for coroutine.yield(proc) in os.execv
+ table.insert(tasks, job_task)
+ table.insert(procs, job_proc_or_errors)
+ table.insert(indices, index)
+ else
+ table.insert(tasks_pending, job_task)
+ table.insert(indices_pending, index)
+ end
end
-- next index
index = index + 1
end
+ -- append pending tasks without process
+ table.join2(tasks, tasks_pending)
+ table.join2(indices, indices_pending)
+
until #tasks == 0
-- ok
diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua
index f54f7b1a3..97945851e 100644
--- a/xmake/core/base/string.lua
+++ b/xmake/core/base/string.lua
@@ -131,13 +131,6 @@ function string.join(items, sep)
return str
end
--- less than
-function string:less(other)
-
- -- < ?
- return string.strcmp(self, other) < 0
-end
-
-- try to format
function string.tryformat(format, ...)
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index 7e8438b8d..023166f69 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -315,9 +315,6 @@ end
-- remove repeat from the given array
function table.unique(array)
- -- check
- assert(array)
-
-- remove repeat
if type(array) == "table" then
diff --git a/xmake/core/language/language.lua b/xmake/core/language/language.lua
index c860b1a2a..dbe66b6b8 100644
--- a/xmake/core/language/language.lua
+++ b/xmake/core/language/language.lua
@@ -82,15 +82,11 @@ end
-- get the language menu
function _instance:menu()
-
- -- get it
return self._INFO.menu
end
-- get the language name
function _instance:name()
-
- -- get it
return self._NAME
end
@@ -119,15 +115,11 @@ end
-- get the source kinds
function _instance:sourcekinds()
-
- -- get it
return self._INFO.sourcekinds
end
-- get the source flags
function _instance:sourceflags()
-
- -- get it
return self._INFO.sourceflags
end
@@ -137,8 +129,6 @@ end
-- {binary = "ld", static = "ar", shared = "sh"}
--
function _instance:targetkinds()
-
- -- get it
return self._INFO.targetkinds
end
@@ -658,7 +648,7 @@ function language.targetkinds()
-- merge all for each language
local targetkinds = {}
for name, instance in pairs(languages) do
- for targetkind, linkerkind in pairs(instance:targetkinds()) do
+ for targetkind, linkerkind in pairs(table.wrap(instance:targetkinds())) do
targetkinds[targetkind] = targetkinds[targetkind] or {}
table.insert(targetkinds[targetkind], linkerkind)
end
diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua
index 76ff5ff93..26852b60e 100644
--- a/xmake/core/platform/platform.lua
+++ b/xmake/core/platform/platform.lua
@@ -241,13 +241,13 @@ end
--
function platform.tool(toolkind)
- -- attempt to get it from config first
- local toolpath = config.get(toolkind)
- if toolpath ~= nil then
- return toolpath
+ -- attempt to get program from config first
+ local program = config.get(toolkind)
+ if program then
+ return program
else
- -- check the tool path
+ -- check it first
local check = platform.get("check")
if check then
check("config", toolkind)
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index 72cc0d750..501f9ce69 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -26,18 +26,19 @@
local option = option or {}
-- load modules
-local io = require("base/io")
-local os = require("base/os")
-local path = require("base/path")
-local table = require("base/table")
-local utils = require("base/utils")
-local option_ = require("base/option")
-local config = require("project/config")
-local cache = require("project/cache")
-local linker = require("tool/linker")
-local compiler = require("tool/compiler")
-local sandbox = require("sandbox/sandbox")
-local language = require("language/language")
+local io = require("base/io")
+local os = require("base/os")
+local path = require("base/path")
+local table = require("base/table")
+local utils = require("base/utils")
+local option_ = require("base/option")
+local config = require("project/config")
+local cache = require("project/cache")
+local linker = require("tool/linker")
+local compiler = require("tool/compiler")
+local sandbox = require("sandbox/sandbox")
+local language = require("language/language")
+local import = require("sandbox/modules/import")
-- get cache
function option._cache()
@@ -54,370 +55,92 @@ function option._cache()
return option._CACHE
end
--- check link
-function option:_check_link(sourcefile, objectfile, targetfile)
+-- check option for c/c++
+function option:_cx_check()
- -- check
- assert(sourcefile and objectfile and targetfile)
-
- -- update source kinds
- self._SOURCEKINDS = language.sourcekind_of(sourcefile)
-
- -- load the linker instance
- local instance = linker.load("binary", self._SOURCEKINDS)
- if not instance then
- return false
- end
-
- -- attempt to link it
- return instance:link(objectfile, targetfile, self)
-end
-
--- check include
-function option:_check_include(include, srcpath, objpath)
-
- -- check
- assert(srcpath and objpath)
-
- -- open the checking source file
- local srcfile = io.open(srcpath, "w")
- if not srcfile then
- return false
- end
-
- -- make include
- if include then
- srcfile:print("#include <%s>\n", include)
- end
-
- -- make the main function header
- srcfile:print("int main(int argc, char** argv)")
- srcfile:print("{")
- srcfile:print(" return 0;")
- srcfile:print("}")
-
- -- exit this file
- srcfile:close()
-
- -- load the compiler instance
- local instance = compiler.load(language.sourcekind_of(srcpath))
- if not instance then
- return false
- end
-
- -- attempt to compile it
- return instance:compile(srcpath, objpath, nil, self)
-end
-
--- check function
-function option:_check_function(checkcode, srcpath, objpath)
-
- -- check
- assert(checkcode)
-
- -- open the checking source file
- local srcfile = io.open(srcpath, "w")
- if not srcfile then
- return false
- end
-
- -- get source kind
- local sourcekind = language.sourcekind_of(srcpath)
-
- -- load the compiler instance
- local instance = compiler.load(sourcekind)
- if not instance then
- return false
- end
-
- -- make includes
- local includes = nil
- if sourcekind == "cc" then includes = self:get("cincludes")
- elseif sourcekind == "cxx" then includes = self:get("cxxincludes")
- end
- if includes then
- for _, include in ipairs(table.wrap(includes)) do
- srcfile:print("#include <%s>", include)
- end
- srcfile:print("")
- end
-
- -- make the main function header
- srcfile:print("int main(int argc, char** argv)")
- srcfile:print("{")
-
- -- make check code
- srcfile:print(" %s;", checkcode)
-
- -- make the main function tailer
- srcfile:print(" return 0;")
- srcfile:print("}")
-
- -- exit this file
- srcfile:close()
-
- -- attempt to compile it
- return instance:compile(srcpath, objpath, nil, self)
-end
-
--- check type
-function option:_check_type(typename, srcpath, objpath)
+ -- import has_cxsnippets()
+ self._has_cxsnippets = self._has_cxsnippets or import("lib.detect.has_cxsnippets")
- -- check
- assert(typename)
-
- -- open the checking source file
- local srcfile = io.open(srcpath, "w")
- if not srcfile then
- return false
- end
-
- -- get source kind
- local sourcekind = language.sourcekind_of(srcpath)
-
- -- load the compiler instance
- local instance = compiler.load(sourcekind)
- if not instance then
- return false
- end
-
- -- make includes
- local includes = nil
- if sourcekind == "cc" then includes = self:get("cincludes")
- elseif sourcekind == "cxx" then includes = self:get("cxxincludes")
- end
- if includes then
- for _, include in ipairs(table.wrap(includes)) do
- srcfile:print("#include <%s>", include)
- end
- srcfile:print("")
- end
-
- -- make the main function header
- srcfile:print("int main(int argc, char** argv)")
- srcfile:print("{")
-
- -- make interfaces
- srcfile:print(" typedef %s __type_xxx;", typename)
-
- -- make the main function tailer
- srcfile:print(" return 0;")
- srcfile:print("}")
-
- -- exit this file
- srcfile:close()
-
- -- attempt to compile it
- return instance:compile(srcpath, objpath, nil, self)
-end
-
--- check snippet
-function option:_check_snippet(snippet, srcpath, objpath)
-
- -- check
- assert(snippet)
+ -- check for c and c++
+ for _, kind in ipairs({"c", "cxx"}) do
- -- get source kind
- local sourcekind = language.sourcekind_of(srcpath)
+ -- get conditions
+ local snippets = self:get(kind .. "snippet")
+ local types = self:get(kind .. "types")
+ local funcs = self:get(kind .. "funcs")
+ local links = self:get(kind .. "links")
+ local includes = self:get(kind .. "includes")
- -- load the compiler instance
- local instance = compiler.load(sourcekind)
- if not instance then
- return false
- end
-
- -- write snippet to source file
- if not io.writefile(srcpath, snippet) then
- return false
- end
-
- -- attempt to compile it
- return instance:compile(srcpath, objpath, nil, self)
-end
-
--- check option for checking links
-function option:_check_links(cfile, objectfile, targetfile)
-
- -- get links
- local links = self:get("links")
- if not links then
- return true
- end
-
- -- the links string
- local links_str = table.concat(table.wrap(links), ", ")
-
- -- this links has been checked?
- option._CHECKED_LINKS = option._CHECKED_LINKS or {}
- if option._CHECKED_LINKS[links_str] then
- return true
- end
-
- -- only for compile a object file
- local ok, errors = self:_check_include(nil, cfile, objectfile)
-
- -- check link
- if ok then ok, errors = self:_check_link(cfile, objectfile, targetfile) end
-
- -- trace
- utils.cprint("checking for the links %s ... %s", links_str, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
- end
-
- -- cache the result
- option._CHECKED_LINKS[links_str] = ok
-
- -- ok?
- return ok
-end
+ -- need check it?
+ if snippets or types or funcs or links or includes then
--- check option for checking includes
-function option:_check_includes(kind, file, objectfile)
+ -- init source kind
+ local sourcekind = kind
+ if kind == "c" then
+ sourcekind = "cc"
+ end
- -- done
- for _, include in ipairs(table.wrap(self:get(kind .. "includes"))) do
-
- -- this include has been checked?
- option._CHECKED_INCLUDES = option._CHECKED_INCLUDES or {}
- if option._CHECKED_INCLUDES[include] then return true end
-
- -- check include
- local ok, errors = self:_check_include(include, file, objectfile)
+ -- check it
+ local ok, results_or_errors = sandbox.load(self._has_cxsnippets, snippets, {target = self, sourcekind = sourcekind, types = types, funcs = funcs, includes = includes})
+ if not ok then
+ return false, results_or_errors
+ end
- -- trace
- utils.cprint("checking for the %s include %s ... %s", kind, include, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
+ -- not pass?
+ if not results_or_errors then
+ return false
+ end
end
-
- -- cache the result
- option._CHECKED_INCLUDES[include] = ok
-
- -- failed
- if not ok then return false end
end
-- ok
return true
end
--- check option for checking functions
-function option:_check_functions(kind, file, objectfile, targetfile)
-
- -- done
- for _, checkinfo in ipairs(table.wrap(self:get(kind .. "funcs"))) do
-
- -- parse the check code
- local checkname, checkcode = option.checkinfo(checkinfo)
- assert(checkname and checkcode)
+-- on check
+function option:_on_check()
- -- check function
- local ok, errors = self:_check_function(checkcode, file, objectfile)
+ -- get check script
+ local check = self:get("check")
+ if check then
- -- check link
- if ok and self:get("links") then ok, errors = self:_check_link(file, objectfile, targetfile) end
-
- -- trace
- utils.cprint("checking for the %s function %s ... %s", kind, checkname, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
+ -- check it
+ local ok, results_or_errors = sandbox.load(check, self)
+ if not ok then
+ return false, results_or_errors
+ else
+ return results_or_errors
end
-
- -- failed
- if not ok then return false end
end
-
- -- ok
- return true
end
--- check option for checking types
-function option:_check_types(kind, file, objectfile, targetfile)
-
- -- done
- for _, t in ipairs(table.wrap(self:get(kind .. "types"))) do
-
- -- check type
- local ok, errors = self:_check_type(t, file, objectfile)
+-- check option
+function option:_check()
- -- trace
- utils.cprint("checking for the %s type %s ... %s", kind, t, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
+ -- check it
+ local ok = nil
+ local errors = nil
+ for _, check in ipairs({self._on_check, self._cx_check}) do
+ ok, errors = check(self)
+ if ok ~= nil then
+ break
end
-
- -- failed
- if not ok then return false end
end
- -- ok
- return true
-end
-
--- check option for checking snippets
-function option:_check_snippets(kind, file, objectfile, targetfile)
-
- -- done
- for name, snippet in pairs(table.wrap(self:get(kind .. "snippet"))) do
-
- -- check snippet
- local ok, errors = self:_check_snippet(snippet, file, objectfile)
-
- -- trace
- utils.cprint("checking for the %s snippet %s ... %s", kind, name, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok and option_.get("verbose") then
- utils.cprint("${red}" .. (errors or ""))
- end
-
- -- failed
- if not ok then return false end
+ -- get name
+ local name = self:name()
+ if name:startswith("__") then
+ name = name:sub(3)
end
- -- ok
- return true
-end
-
--- check option
-function option:_check_condition()
-
- -- the files
- local cfile = os.tmpfile() .. ".c"
- local cxxfile = os.tmpfile() .. ".cpp"
- local objectfile = os.tmpfile() .. ".obj"
- local targetfile = os.tmpfile() .. ".bin"
-
- -- check links
- if not self:_check_links(cfile, objectfile, targetfile) then return false end
-
- -- check types
- if not self:_check_types("c", cfile, objectfile, targetfile) then return false end
- if not self:_check_types("cxx", cxxfile, objectfile, targetfile) then return false end
-
- -- check csnippets
- if not self:_check_snippets("c", cfile, objectfile, targetfile) then return false end
- if not self:_check_snippets("cxx", cxxfile, objectfile, targetfile) then return false end
-
- -- check includes and functions
- if self:get("cincludes") or self:get("cxxincludes") then
-
- -- check includes
- if not self:_check_includes("c", cfile, objectfile) then return false end
- if not self:_check_includes("cxx", cxxfile, objectfile) then return false end
-
- -- check functions
- if not self:_check_functions("c", cfile, objectfile, targetfile) then return false end
- if not self:_check_functions("cxx", cxxfile, objectfile, targetfile) then return false end
+ -- trace
+ utils.cprint("checking for the %s ... %s", name, utils.ifelse(ok, "${green}ok", "${red}no"))
+ if not ok and errors then
+ os.raise(errors)
end
- -- remove files
- os.rm(cfile)
- os.rm(cxxfile)
- os.rm(objectfile)
- os.rm(targetfile)
-
- -- ok
- return true
+ -- ok?
+ return ok
end
-- attempt to check option
@@ -437,6 +160,13 @@ function option:check(force)
default = self:get("enable")
end
+ -- before and after check
+ local check_before = self:get("check_before")
+ local check_after = self:get("check_after")
+ if check_before then
+ check_before(self)
+ end
+
-- need check? (only force to check the automatical option without the default value)
if config.get(name) == nil or (default == nil and force) then
@@ -450,7 +180,7 @@ function option:check(force)
self:save()
-- check option as boolean switch automatically if the default value not exists
- elseif default == nil and self:_check_condition() then
+ elseif default == nil and self:_check() then
-- enable this option
config.set(name, true)
@@ -473,17 +203,57 @@ function option:check(force)
self:save()
end
+ -- after check
+ if check_after then
+ check_after(self)
+ end
+
-- checked
self._CHECKED = true
end
+-- this option is enabled?
+function option:enabled()
+ return config.get(self:name())
+end
+
+-- dump this option
+function option:dump()
+ table.dump(self._INFO)
+end
+
-- get the option info
function option:get(infoname)
-
- -- get it
return self._INFO[infoname]
end
+-- set the value to the option info
+function option:set(name_or_info, ...)
+ if type(name_or_info) == "string" then
+ local args = ...
+ if args ~= nil then
+ self._INFO[name_or_info] = table.unique(table.join(...))
+ else
+ self._INFO[name_or_info] = nil
+ end
+ elseif type(name_or_info) == "table" and #name_or_info == 0 then
+ for name, info in pairs(name_or_info) do
+ self:set(name, info)
+ end
+ end
+end
+
+-- add the value to the option info
+function option:add(name_or_info, ...)
+ if type(name_or_info) == "string" then
+ self._INFO[name_or_info] = table.unique(table.join2(table.wrap(self._INFO[name_or_info]), ...))
+ elseif type(name_or_info) == "table" and #name_or_info == 0 then
+ for name, info in pairs(name_or_info) do
+ self:add(name, info)
+ end
+ end
+end
+
-- get option deps
function option:deps()
-- TODO in the future
@@ -493,22 +263,23 @@ end
-- save the option info to the cache
function option:save()
- -- save it
+ -- clear scripts for caching to file
+ self:set("check", nil)
+ self:set("check_after", nil)
+ self:set("check_before", nil)
+
+ -- save this option to cache
option._cache():set(self:name(), self._INFO)
option._cache():flush()
end
-- clear the option info for cache
function option:clear()
-
- -- clear it
option._cache():set(self:name(), nil)
end
-- get the option name
function option:name()
-
- -- get it
return self._NAME
end
@@ -533,43 +304,5 @@ function option.load(name)
return instance
end
--- get the kinds of sourcefiles
-function option:sourcekinds()
-
- -- cached? return it directly
- if self._SOURCEKINDS then
- return self._SOURCEKINDS
- end
-
- -- ok?
- return {"cc", "cxx"}
-end
-
--- get function name and check code
---
--- sigsetjmp
--- sigsetjmp((void*)0, 0)
--- sigsetjmp{sigsetjmp((void*)0, 0);}
--- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
---
-function option.checkinfo(checkinfo)
-
- -- parse name and code
- local name, code = string.match(checkinfo, "(.+){(.+)}")
- if code == nil then
- local pos = checkinfo:find("%(")
- if pos then
- name = checkinfo:sub(1, pos - 1)
- code = checkinfo
- else
- name = checkinfo
- code = string.format("volatile void* p%s = (void*)&%s;", name, name)
- end
- end
-
- -- ok
- return name:trim(), code
-end
-
-- return module
return option
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 649d41141..4368a7220 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -31,6 +31,7 @@ local io = require("base/io")
local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
+local process = require("base/process")
local deprecated = require("base/deprecated")
local interpreter = require("base/interpreter")
local target = require("project/target")
@@ -40,7 +41,6 @@ local option = require("project/option")
local package = require("project/package")
local deprecated_project = require("project/deprecated/project")
local platform = require("platform/platform")
-local environment = require("platform/environment")
local language = require("language/language")
local sandbox_os = require("sandbox/modules/os")
@@ -265,6 +265,12 @@ function project._interpreter()
, "target.after_package"
, "target.after_install"
, "target.after_uninstall"
+ -- option.before_xxx
+ , "option.before_check"
+ -- option.on_xxx
+ , "option.on_check"
+ -- option.after_xxx
+ , "option.after_check"
-- target.on_xxx
, "task.on_run"
}
@@ -358,52 +364,12 @@ end
-- get the project file
function project.file()
-
- -- get it
- return xmake._PROJECT_FILE
+ return os.projectfile()
end
-- get the project directory
function project.directory()
-
- -- get it
- return xmake._PROJECT_DIR
-end
-
--- check the project
-function project.check(force)
-
- -- enter the project directory
- local ok, errors = os.cd(project.directory())
- if not ok then
- return false, errors
- end
-
- -- load the options from the the project file
- local options, errors = project.options(true)
- if not options then
- return false, errors
- end
-
- -- enter toolchains environment
- environment.enter("toolchains")
-
- -- check all options
- for _, opt in pairs(options) do
- opt:check(force)
- end
-
- -- leave toolchains environment
- environment.leave("toolchains")
-
- -- leave the project directory
- ok, errors = os.cd("-")
- if not ok then
- return false, errors
- end
-
- -- ok
- return true
+ return os.projectdir()
end
-- get the project info from the given name
@@ -521,7 +487,7 @@ function project.options(enable_filter)
instance._INFO = optioninfo
-- save it
- options[optionname] = instance
+ table.insert(options,instance)
end
-- ok?
@@ -579,7 +545,7 @@ function project.menu()
-- arrange options by category
local options_by_category = {}
- for name, opt in pairs(options) do
+ for _, opt in ipairs(options) do
-- make the category
local category = "default"
@@ -587,7 +553,7 @@ function project.menu()
options_by_category[category] = options_by_category[category] or {}
-- append option to the current category
- options_by_category[category][name] = opt
+ options_by_category[category][opt:name()] = opt
end
-- make menu by category
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index bfb986123..ebc778c3a 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -66,26 +66,49 @@ function target.new(name, info)
end
-- get the target info
-function target:get(infoname)
+function target:get(name)
+ return self._INFO[name]
+end
- -- check
- assert(self and self._INFO and infoname)
+-- set the value to the target info
+function target:set(name_or_info, ...)
+ if type(name_or_info) == "string" then
+ local args = ...
+ if args ~= nil then
+ self._INFO[name_or_info] = table.unique(table.join(...))
+ else
+ self._INFO[name_or_info] = nil
+ end
+ elseif type(name_or_info) == "table" and #name_or_info == 0 then
+ for name, info in pairs(name_or_info) do
+ self:set(name, info)
+ end
+ end
+end
- -- get it
- return self._INFO[infoname]
+-- add the value to the target info
+function target:add(name_or_info, ...)
+ if type(name_or_info) == "string" then
+ self._INFO[name_or_info] = table.unique(table.join2(table.wrap(self._INFO[name_or_info]), ...))
+ elseif type(name_or_info) == "table" and #name_or_info == 0 then
+ for name, info in pairs(name_or_info) do
+ self:add(name, info)
+ end
+ end
+end
+
+-- dump this target
+function target:dump()
+ table.dump(self._INFO)
end
-- get the target name
function target:name()
-
- -- get it
return self._NAME
end
-- get the base name of target file
function target:basename()
-
- -- get it
return self:get("basename")
end
@@ -114,14 +137,14 @@ end
function target:linkcmd(objectfiles)
-- make command
- return self:linker():linkcmd(objectfiles or self:objectfiles(), self:targetfile(), self)
+ return self:linker():linkcmd(objectfiles or self:objectfiles(), self:targetfile(), {target = self})
end
-- make link flags for the given target
function target:linkflags()
-- make flags
- return self:linker():linkflags(self)
+ return self:linker():linkflags({target = self})
end
-- get target deps
@@ -362,10 +385,6 @@ function target:objectfile(sourcefile)
local objectdir = self:objectdir()
assert(objectdir and type(objectdir) == "string")
- -- make object file
- -- full file name(not base) to avoid name-clash of object file
- local objectfile = string.format("%s/%s/%s/%s", objectdir, self:name(), path.directory(sourcefile), target.filename(path.filename(sourcefile), "object"))
-
-- translate path
--
-- .e.g
@@ -378,10 +397,11 @@ function target:objectfile(sourcefile)
--
-- we need replace '..' to '__' in this case
--
- objectfile = (path.translate(objectfile):gsub("%.%.", "__"))
+ local sourcedir = path.directory(sourcefile):gsub("%.%.", "__")
- -- ok?
- return objectfile
+ -- make object file
+ -- full file name(not base) to avoid name-clash of object file
+ return string.format("%s/%s/%s/%s", objectdir, self:name(), sourcedir, target.filename(path.filename(sourcefile), "object"))
end
-- get the object files
diff --git a/xmake/core/project/template.lua b/xmake/core/project/template.lua
index a306bf622..cbc1551a8 100644
--- a/xmake/core/project/template.lua
+++ b/xmake/core/project/template.lua
@@ -90,7 +90,7 @@ function template._replace(macros, macrofiles)
-- make all files
local files = {}
for _, macrofile in ipairs(table.wrap(macrofiles)) do
- local matchfiles = os.match(macrofile)
+ local matchfiles = os.files(macrofile)
if matchfiles then
table.join2(files, matchfiles)
end
@@ -114,7 +114,7 @@ function template.languages()
local list = {}
-- get the language list
- local languages = os.match(xmake._TEMPLATES_DIR .. "/*", true)
+ local languages = os.dirs(path.join(os.programdir(), "templates", "*"))
if languages then
for _, v in ipairs(languages) do
table.insert(list, path.basename(v))
@@ -137,7 +137,7 @@ function template.templates(language)
-- load all templates
local templates = {}
- local templatefiles = os.match(string.format("%s/%s/**/template.lua", xmake._TEMPLATES_DIR, language))
+ local templatefiles = os.files(path.join(os.programdir(), "templates", language, "**", "template.lua"))
if templatefiles then
-- load template
@@ -159,7 +159,7 @@ function template.templates(language)
end
-- sort templates
- table.sort(templates, function(a, b) return a.description:less(b.description) end)
+ table.sort(templates, function(a, b) return a.description < b.description end)
-- ok?
return templates
diff --git a/xmake/core/sandbox/modules/import.lua b/xmake/core/sandbox/modules/import.lua
index 885378750..5317efa6e 100644
--- a/xmake/core/sandbox/modules/import.lua
+++ b/xmake/core/sandbox/modules/import.lua
@@ -103,7 +103,7 @@ function sandbox_import._loadfile(filepath, instance)
if not result then
return nil, errors
end
-
+
-- ok
return result, instance:script()
end
@@ -128,19 +128,16 @@ function sandbox_import._find(dir, name)
name = sandbox_import._modulepath(name)
assert(name)
- -- load the single module?
- local module = nil
- if os.isfile(path.join(dir, name .. ".lua")) then
- return true
+ -- get module key
+ local key = path.join(dir, name)
- -- load modules
- elseif os.isdir(path.join(dir, name)) then
- return true
+ -- the single module?
+ if os.isfile(key .. ".lua") then
+ return path.absolute(key)
+ -- modules?
+ elseif os.isdir(key) then
+ return path.absolute(key)
end
-
- -- not found
- return false
-
end
-- load module
@@ -240,6 +237,11 @@ end
-- import module
--
+-- @param name the module name, .e.g core.platform
+-- @param args the arguments, .e.g {alias = "", rootdir = "", inherit = false, anonymous = false, nocache = false}
+--
+-- @return the module instance
+--
-- .e.g
--
-- import("core.platform")
@@ -260,7 +262,7 @@ end
-- => inherit the all interfaces of core.platform to the current scope
--
-- local test = import("test", {rootdir = "/tmp/xxx", anonymous = true})
--- => only return imported module and do not cache it
+-- => only return imported module
--
-- @note the polymiorphism is not supported for import.inherit mode now.
--
@@ -272,6 +274,10 @@ function sandbox_import.import(name, args)
-- the arguments
args = args or {}
+ -- init module cache
+ sandbox_import._MODULES = sandbox_import._MODULES or {}
+ local modules = sandbox_import._MODULES
+
-- get the parent scope
local scope_parent = getfenv(2)
assert(scope_parent)
@@ -285,12 +291,6 @@ function sandbox_import.import(name, args)
-- the imported name
local imported_name = args.alias or modulename
- -- this module has been imported?
- local module = rawget(scope_parent, imported_name)
- if module ~= nil then
- return module
- end
-
-- get the current sandbox instance
local instance = sandbox.instance()
assert(instance)
@@ -300,7 +300,7 @@ function sandbox_import.import(name, args)
assert(rootdir)
-- the sandbox modules directory
- local modules_sandbox_dir = path.join(xmake._CORE_DIR, "sandbox/modules/import")
+ local modules_sandbox_dir = path.join(os.programdir(), "core/sandbox/modules/import")
-- the extension modules directory
local modules_extension_dir = path.join(os.programdir(), "modules")
@@ -311,18 +311,39 @@ function sandbox_import.import(name, args)
-- init module directories
local modules_directories =
{
- rootdir -- load module from the given root directory first
- , path.join(global.directory(), "modules") -- load module from the user global modules directory
- , path.join(xmake._PROGRAM_DIR, "modules") -- load module from the extension modules directory
- , path.join(xmake._CORE_DIR, "sandbox/modules/import") -- load module from the sandbox core modules directory
+ rootdir -- load module from the given root directory first
+ , path.join(global.directory(), "modules") -- load module from the user global modules directory
+ , path.join(os.programdir(), "modules") -- load module from the extension modules directory
+ , path.join(os.programdir(), "core/sandbox/modules/import") -- load module from the sandbox core modules directory
}
-- load module
- local module = nil
local errors = nil
+ local module = nil
+ local modulekey = nil
for idx, moduledir in ipairs(modules_directories) do
- if sandbox_import._find(moduledir, name) then
- module, errors = sandbox_import._load(moduledir, name, utils.ifelse(idx < #modules_directories, instance, nil)) -- last modules need not fork sandbox
+
+ -- find module and key
+ modulekey = sandbox_import._find(moduledir, name)
+ if modulekey then
+
+ -- load it from cache first
+ local moduleinfo = modules[modulekey]
+ if moduleinfo and not args.nocache and not args.inherit then
+ module = moduleinfo[1]
+ errors = moduleinfo[2]
+ else
+ -- load it from the script file
+ module, errors = sandbox_import._load(moduledir, name, utils.ifelse(idx < #modules_directories, instance, nil)) -- last modules need not fork sandbox
+
+ -- cache this module
+ if not args.nocache then
+ modules[modulekey] = {module, errors}
+ end
+ end
+
+ -- end
+ break
end
end
diff --git a/xmake/core/sandbox/modules/import/core/platform/platform.lua b/xmake/core/sandbox/modules/import/core/platform/platform.lua
index 2dee562f1..e4175aaaa 100644
--- a/xmake/core/sandbox/modules/import/core/platform/platform.lua
+++ b/xmake/core/sandbox/modules/import/core/platform/platform.lua
@@ -63,10 +63,16 @@ end
-- get the current platform configure
function sandbox_core_platform.get(name, plat)
-
- -- get the given platform configure
return platform.get(name, plat)
end
+-- get the platform tool from the kind
+--
+-- .e.g cc, cxx, mm, mxx, as, ar, ld, sh, ..
+--
+function sandbox_core_platform.tool(toolkind)
+ return platform.tool(toolkind)
+end
+
-- return module
return sandbox_core_platform
diff --git a/xmake/core/sandbox/modules/import/core/project/cache.lua b/xmake/core/sandbox/modules/import/core/project/cache.lua
index 4d2879c09..066ae4d03 100644
--- a/xmake/core/sandbox/modules/import/core/project/cache.lua
+++ b/xmake/core/sandbox/modules/import/core/project/cache.lua
@@ -22,8 +22,8 @@
-- @file cache.lua
--
--- define module, @note cannot be cached, a new instance in each sandbox module
-local sandbox_core_project_cache = {}
+-- define module
+local sandbox_core_project_cache = sandbox_core_project_cache or {}
-- load modules
local cache = require("project/cache")
diff --git a/xmake/core/sandbox/modules/import/core/project/history.lua b/xmake/core/sandbox/modules/import/core/project/history.lua
index c19607f88..b205afdf9 100644
--- a/xmake/core/sandbox/modules/import/core/project/history.lua
+++ b/xmake/core/sandbox/modules/import/core/project/history.lua
@@ -22,8 +22,8 @@
-- @file history.lua
--
--- define module, @note cannot be cached, a new instance in each sandbox module
-local sandbox_core_project_history = {}
+-- define module
+local sandbox_core_project_history = sandbox_core_project_history or {}
-- load modules
local os = require("base/os")
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index 2b5643e90..164d79fe0 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -26,10 +26,12 @@
local sandbox_core_project = sandbox_core_project or {}
-- load modules
-local table = require("base/table")
-local config = require("project/config")
-local project = require("project/project")
-local raise = require("sandbox/modules/raise")
+local table = require("base/table")
+local config = require("project/config")
+local project = require("project/project")
+local sandbox = require("sandbox/sandbox")
+local raise = require("sandbox/modules/raise")
+local environment = require("platform/environment")
-- load project
function sandbox_core_project.load()
@@ -44,8 +46,36 @@ end
-- check project options
function sandbox_core_project.check(force)
- -- check it
- local ok, errors = project.check(force)
+ -- enter the project directory
+ local ok, errors = os.cd(project.directory())
+ if not ok then
+ raise(errors)
+ end
+
+ -- load the options from the the project file
+ local options, errors = project.options(true)
+ if not options then
+ raise(errors)
+ end
+
+ -- get sandbox instance
+ local instance = sandbox.instance()
+ assert(instance)
+
+ -- enter toolchains environment
+ environment.enter("toolchains")
+
+ -- check all options
+ ok, errors = process.runjobs(instance:fork(function (index) options[index]:check(force) end):script(), #options, 4)
+ if not ok then
+ raise(errors)
+ end
+
+ -- leave toolchains environment
+ environment.leave("toolchains")
+
+ -- leave the project directory
+ ok, errors = os.cd("-")
if not ok then
raise(errors)
end
diff --git a/xmake/core/sandbox/modules/import/core/tool/compiler.lua b/xmake/core/sandbox/modules/import/core/tool/compiler.lua
index fb753aed3..a6ebc45f6 100644
--- a/xmake/core/sandbox/modules/import/core/tool/compiler.lua
+++ b/xmake/core/sandbox/modules/import/core/tool/compiler.lua
@@ -46,9 +46,13 @@ function sandbox_core_tool_compiler.feature(sourcekind, name)
end
-- make command for compiling source file
-function sandbox_core_tool_compiler.compcmd(sourcefiles, objectfile, target, sourcekind)
+function sandbox_core_tool_compiler.compcmd(sourcefiles, objectfile, opt)
+
+ -- init options
+ opt = opt or {}
-- get source kind if only one source file
+ local sourcekind = opt.sourcekind
if not sourcekind and type(sourcefiles) == "string" then
sourcekind = language.sourcekind_of(sourcefiles)
end
@@ -58,15 +62,19 @@ function sandbox_core_tool_compiler.compcmd(sourcefiles, objectfile, target, sou
if not instance then
raise(errors)
end
-
+
-- make command
- return instance:compcmd(sourcefiles, objectfile, target)
+ return instance:compcmd(sourcefiles, objectfile, opt)
end
-- compile source files
-function sandbox_core_tool_compiler.compile(sourcefiles, objectfile, incdepfile, target, sourcekind)
+function sandbox_core_tool_compiler.compile(sourcefiles, objectfile, opt)
+
+ -- init options
+ opt = opt or {}
-- get source kind if only one source file
+ local sourcekind = opt.sourcekind
if not sourcekind and type(sourcefiles) == "string" then
sourcekind = language.sourcekind_of(sourcefiles)
end
@@ -78,16 +86,17 @@ function sandbox_core_tool_compiler.compile(sourcefiles, objectfile, incdepfile,
end
-- compile it
- local ok, errors = instance:compile(sourcefiles, objectfile, incdepfile, target)
+ local ok, errors = instance:compile(sourcefiles, objectfile, opt)
if not ok then
raise(errors)
end
end
--- make compiling flags for the given target
-function sandbox_core_tool_compiler.compflags(sourcefiles, target, sourcekind)
+-- make compiling flags
+function sandbox_core_tool_compiler.compflags(sourcefiles, opt)
-- get source kind if only one source file
+ local sourcekind = opt.sourcekind
if not sourcekind and type(sourcefiles) == "string" then
sourcekind = language.sourcekind_of(sourcefiles)
end
@@ -99,13 +108,14 @@ function sandbox_core_tool_compiler.compflags(sourcefiles, target, sourcekind)
end
-- make flags
- return instance:compflags(target)
+ return instance:compflags(opt)
end
-- make command for building source file
-function sandbox_core_tool_compiler.buildcmd(sourcefiles, targetfile, target, sourcekind)
+function sandbox_core_tool_compiler.buildcmd(sourcefiles, targetfile, opt)
-- get source kind if only one source file
+ local sourcekind = opt.sourcekind
if not sourcekind and type(sourcefiles) == "string" then
sourcekind = language.sourcekind_of(sourcefiles)
end
@@ -117,13 +127,14 @@ function sandbox_core_tool_compiler.buildcmd(sourcefiles, targetfile, target, so
end
-- make command
- return instance:buildcmd(sourcefiles, target:targetkind(), targetfile, target)
+ return instance:buildcmd(sourcefiles, targetfile, opt)
end
-- build source files
-function sandbox_core_tool_compiler.build(sourcefiles, targetfile, target, sourcekind)
+function sandbox_core_tool_compiler.build(sourcefiles, targetfile, opt)
-- get source kind if only one source file
+ local sourcekind = opt.sourcekind
if not sourcekind and type(sourcefiles) == "string" then
sourcekind = language.sourcekind_of(sourcefiles)
end
@@ -135,7 +146,7 @@ function sandbox_core_tool_compiler.build(sourcefiles, targetfile, target, sourc
end
-- build it
- local ok, errors = instance:build(sourcefiles, target:targetkind(), targetfile, target)
+ local ok, errors = instance:build(sourcefiles, targetfile, opt)
if not ok then
raise(errors)
end
diff --git a/xmake/core/sandbox/modules/import/core/tool/linker.lua b/xmake/core/sandbox/modules/import/core/tool/linker.lua
index b785f2c50..7b95d8b7c 100644
--- a/xmake/core/sandbox/modules/import/core/tool/linker.lua
+++ b/xmake/core/sandbox/modules/import/core/tool/linker.lua
@@ -31,42 +31,42 @@ local linker = require("tool/linker")
local raise = require("sandbox/modules/raise")
-- make command for linking target file
-function sandbox_core_tool_linker.linkcmd(objectfiles, targetfile, target)
+function sandbox_core_tool_linker.linkcmd(targetkind, sourcekinds, objectfiles, targetfile, opt)
-- get the linker instance
- local instance, errors = linker.load(target:get("kind"), target:sourcekinds())
+ local instance, errors = linker.load(targetkind, sourcekinds)
if not instance then
raise(errors)
end
-- make command
- return instance:linkcmd(objectfiles, targetfile, target)
+ return instance:linkcmd(objectfiles, targetfile, opt)
end
-- make link flags for the given target
-function sandbox_core_tool_linker.linkflags(target)
-
+function sandbox_core_tool_linker.linkflags(targetkind, sourcekinds, opt)
+
-- get the linker instance
- local instance, errors = linker.load(target:get("kind"), target:sourcekinds())
+ local instance, errors = linker.load(targetkind, sourcekinds)
if not instance then
raise(errors)
end
-- make flags
- return instance:linkflags(target)
+ return instance:linkflags(opt)
end
-- link target file
-function sandbox_core_tool_linker.link(objectfiles, targetfile, target)
+function sandbox_core_tool_linker.link(targetkind, sourcekinds, objectfiles, targetfile, opt)
-- get the linker instance
- local instance, errors = linker.load(target:get("kind"), target:sourcekinds())
+ local instance, errors = linker.load(targetkind, sourcekinds)
if not instance then
raise(errors)
end
-- link it
- local ok, errors = instance:link(objectfiles, targetfile, target)
+ local ok, errors = instance:link(objectfiles, targetfile, opt)
if not ok then
raise(errors)
end
diff --git a/xmake/core/sandbox/modules/import/core/tool/tool.lua b/xmake/core/sandbox/modules/import/core/tool/tool.lua
deleted file mode 100644
index 9fbc68ced..000000000
--- a/xmake/core/sandbox/modules/import/core/tool/tool.lua
+++ /dev/null
@@ -1,49 +0,0 @@
---!The Make-like 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 tool.lua
---
-
--- define module
-local sandbox_core_tool = sandbox_core_tool or {}
-
--- load modules
-local tool = require("tool/tool")
-local config = require("project/config")
-local platform = require("platform/platform")
-local raise = require("sandbox/modules/raise")
-
--- get the tool shell name
-function sandbox_core_tool.shellname(name)
-
- -- get it
- return platform.tool(name)
-end
-
--- check the tool and return the absolute path if exists
-function sandbox_core_tool.check(shellname, dirs, check)
-
- -- check it
- return tool.check(shellname, dirs, check)
-end
-
--- return module
-return sandbox_core_tool
diff --git a/xmake/core/sandbox/modules/import/lib/detect/clear_cache.lua b/xmake/core/sandbox/modules/import/lib/detect/cache.lua
index 81cca369e..82d9c60bc 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/clear_cache.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/cache.lua
@@ -19,11 +19,11 @@
-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
--
-- @author ruki
--- @file clear_cache.lua
+-- @file cache.lua
--
-- define module
-local sandbox_lib_detect_clear_cache = sandbox_lib_detect_clear_cache or {}
+local sandbox_lib_detect_cache = sandbox_lib_detect_cache or {}
-- load modules
local os = require("base/os")
@@ -36,15 +36,61 @@ local project = require("project/project")
local sandbox = require("sandbox/sandbox")
local raise = require("sandbox/modules/raise")
--- clear detect cache
+-- get detect cache instance
+function sandbox_lib_detect_cache._instance()
+
+ -- get it
+ local detectcache = sandbox_lib_detect_cache._INSTANCE or cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect"))
+ sandbox_lib_detect_cache._INSTANCE = detectcache
+
+ -- ok?
+ return detectcache
+end
+
+-- load detect cache
--
-- @param name the cache name. .e.g find_program, find_programver, ..
--
-function sandbox_lib_detect_clear_cache.main(name)
+function sandbox_lib_detect_cache.load(name)
-- get detect cache
- local detectcache = cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect"))
+ local detectcache = sandbox_lib_detect_cache._instance()
+ -- attempt to get result from cache first
+ local cacheinfo = detectcache:get(name)
+ if cacheinfo == nil then
+ cacheinfo = {}
+ detectcache:set(name, cacheinfo)
+ end
+
+ -- ok?
+ return cacheinfo
+end
+
+-- save detect cache
+--
+-- @param name the cache name. .e.g find_program, find_programver, ..
+-- @param info the cache info
+--
+function sandbox_lib_detect_cache.save(name, info)
+
+ -- get detect cache
+ local detectcache = sandbox_lib_detect_cache._instance()
+
+ -- save cache info
+ detectcache:set(name, info)
+ detectcache:flush()
+end
+
+-- clear detect cache
+--
+-- @param name the cache name. .e.g find_program, find_programver, ..
+--
+function sandbox_lib_detect_cache.clear(name)
+
+ -- get detect cache
+ local detectcache = sandbox_lib_detect_cache._instance()
+
-- clear cache info
if name then
detectcache:set(name, {})
@@ -55,4 +101,4 @@ function sandbox_lib_detect_clear_cache.main(name)
end
-- return module
-return sandbox_lib_detect_clear_cache
+return sandbox_lib_detect_cache
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_directory.lua b/xmake/core/sandbox/modules/import/lib/detect/find_directory.lua
new file mode 100644
index 000000000..e4c6c00d4
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_directory.lua
@@ -0,0 +1,106 @@
+--!The Make-like 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 find_directory.lua
+--
+
+-- define module
+local sandbox_lib_detect_find_directory = sandbox_lib_detect_find_directory or {}
+
+-- load modules
+local os = require("base/os")
+local path = require("base/path")
+local utils = require("base/utils")
+local table = require("base/table")
+local raise = require("sandbox/modules/raise")
+local vformat = require("sandbox/modules/vformat")
+
+-- find directory
+--
+-- @param name the directory name
+-- @param pathes the search pathes (.e.g dirs, pathes, winreg pathes)
+-- @param opt the options, .e.g {suffixes = {"/aa", "/bb"}}
+--
+-- @return the directory path
+--
+-- @code
+--
+-- local dir = find_directory("bin", { "/usr", "/usr/local"})
+-- local dir = find_directory("xxx/test", { "/usr/include", "/usr/local/include/**"})
+-- local dir = find_directory("xxx/test", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"})
+-- local dir = find_directory("xxx/test/dir*", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"):match("\"(.-)\"") end})
+--
+-- @endcode
+--
+function sandbox_lib_detect_find_directory.main(name, pathes, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- init pathes
+ pathes = table.wrap(pathes)
+
+ -- append suffixes to pathes
+ local suffixes = table.wrap(opt.suffixes)
+ if #suffixes > 0 then
+ local pathes_new = {}
+ for _, parent in ipairs(pathes) do
+ for _, suffix in ipairs(suffixes) do
+ table.insert(pathes_new, path.join(parent, suffix))
+ end
+ end
+ pathes = pathes_new
+ end
+
+ -- find file
+ local result = nil
+ for _, _path in ipairs(pathes) do
+
+ -- format path for builtin variables
+ if type(_path) == "function" then
+ local ok, results = sandbox.load(_path)
+ if ok then
+ _path = results or ""
+ else
+ raise(results)
+ end
+ else
+ _path = vformat(_path)
+ end
+
+ -- directory exists?
+ for _, dir in ipairs(os.dirs(path.join(_path, name))) do
+ result = dir
+ break
+ end
+
+ -- found?
+ if result then
+ break
+ end
+ end
+
+ -- ok?
+ return result
+end
+
+-- return module
+return sandbox_lib_detect_find_directory
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_file.lua b/xmake/core/sandbox/modules/import/lib/detect/find_file.lua
index ae61faa40..e647f1869 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_file.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_file.lua
@@ -36,7 +36,8 @@ local vformat = require("sandbox/modules/vformat")
-- find file
--
-- @param name the file name
--- @param pathes the program pathes (.e.g dirs, pathes, winreg pathes)
+-- @param pathes the search pathes (.e.g dirs, pathes, winreg pathes)
+-- @param opt the options, .e.g {suffixes = {"/aa", "/bb"}}
--
-- @return the file path
--
@@ -49,11 +50,29 @@ local vformat = require("sandbox/modules/vformat")
--
-- @endcode
--
-function sandbox_lib_detect_find_file.main(name, pathes)
+function sandbox_lib_detect_find_file.main(name, pathes, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- init pathes
+ pathes = table.wrap(pathes)
+
+ -- append suffixes to pathes
+ local suffixes = table.wrap(opt.suffixes)
+ if #suffixes > 0 then
+ local pathes_new = {}
+ for _, parent in ipairs(pathes) do
+ for _, suffix in ipairs(suffixes) do
+ table.insert(pathes_new, path.join(parent, suffix))
+ end
+ end
+ pathes = pathes_new
+ end
-- find file
local result = nil
- for _, _path in ipairs(table.wrap(pathes)) do
+ for _, _path in ipairs(pathes) do
-- format path for builtin variables
if type(_path) == "function" then
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
index 4b386f947..fbf3cf3c6 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua
@@ -31,13 +31,9 @@ local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
local target = require("project/target")
-local config = require("project/config")
local raise = require("sandbox/modules/raise")
local import = require("sandbox/modules/import")
-
--- import sandbox modules
-import("lib.detect.find_file")
-import("detect.tool.find_pkg_config")
+local find_file = import("lib.detect.find_file")
-- get link name from the file name
function sandbox_lib_detect_find_library._link(filename)
@@ -57,64 +53,30 @@ end
-- find library
--
-- @param names the library names
--- @param pathes the library pathes
--- @param kinds the library kinds, .e.g {"static", "shared"}
+-- @param pathes the search pathes
+-- @param opt the options, .e.g {kind = "static/shared", suffixes = {"/aa", "/bb"}}
--
-- @return {kind = "static", link = "crypto", linkdir = "/usr/local/lib", filename = "libcrypto.a"}
--
-- @code
--
--- local library = find_library("crypto")
-- local library = find_library({"crypto", "cryp*"}, {"/usr/lib", "/usr/local/lib"})
+-- local library = find_library(crypto, {"/usr/lib", "/usr/local/lib"}, {kind = "static"})
--
-- @endcode
--
-function sandbox_lib_detect_find_library.main(names, paths, kinds)
+function sandbox_lib_detect_find_library.main(names, pathes, opt)
- -- init pathes
- pathes = table.wrap(pathes)
+ -- init options
+ opt = opt or {}
-- init kinds
- kinds = kinds or {"static", "shared"}
-
- -- get current platform
- local plat = config.get("plat") or os.host()
-
- -- get current architecture
- local arch = config.get("arch") or os.arch()
-
- -- attempt to add search pathes from pkg-config
- local pkg_config = find_pkg_config()
- if pkg_config then
- for _, name in ipairs(table.wrap(names)) do
-
- -- attempt to get -L/xxx/dir
- local ok, libs_only_L = os.iorunv(pkg_config, {"--libs-only-L", name})
- if not ok and not name:startswith("lib") then
- ok, libs_only_L = os.iorunv(pkg_config, {"--libs-only-L", "lib" .. name})
- end
-
- -- add linkdir to pathes
- if libs_only_L then
- local linkdir = (libs_only_L:match("%-L(.+)") or ""):trim()
- if os.isdir(linkdir) then
- table.insert(pathes, linkdir)
- break
- end
- end
- end
- end
-
- -- add default search pathes on pc host
- if plat == "macosx" or (plat == "linux" and arch == os.arch()) then
- table.insert(pathes, "/usr/local/lib")
- table.insert(pathes, "/usr/lib")
- end
+ kinds = opt.kind or {"static", "shared"}
-- find library file from the given pathes
for _, name in ipairs(table.wrap(names)) do
for _, kind in ipairs(table.wrap(kinds)) do
- local filepath = find_file(target.filename(name, kind), pathes)
+ local filepath = find_file(target.filename(name, kind), pathes, opt)
if filepath then
local filename = path.filename(filepath)
return {kind = kind, filename = filename, linkdir = path.directory(filepath), link = sandbox_lib_detect_find_library._link(filename)}
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_package.lua b/xmake/core/sandbox/modules/import/lib/detect/find_package.lua
index a225945b7..626f652cd 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_package.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_package.lua
@@ -31,10 +31,18 @@ local path = require("base/path")
local utils = require("base/utils")
local table = require("base/table")
local option = require("base/option")
-local cache = require("project/cache")
+local config = require("project/config")
local project = require("project/project")
local raise = require("sandbox/modules/raise")
local import = require("sandbox/modules/import")
+local cache = require("sandbox/modules/import/lib/detect/cache")
+local pkg_config = import("lib.detect.pkg_config")
+
+-- find package from project package directories
+function sandbox_lib_detect_find_package._find_from_project_packagedirs(name, opt)
+
+ -- TODO
+end
-- find package from repositories
function sandbox_lib_detect_find_package._find_from_repositories(name, opt)
@@ -42,21 +50,75 @@ function sandbox_lib_detect_find_package._find_from_repositories(name, opt)
-- TODO in repo branch
end
--- find package from modules (detect.package.find_xxx)
+-- find package from modules (detect.packages.find_xxx)
function sandbox_lib_detect_find_package._find_from_modules(name, opt)
- -- "detect.package.find_xxx" exists?
- if os.isfile(path.join(os.programdir(), "modules", "detect", "package", "find_" .. name .. ".lua")) then
- local find_package = import("detect.package.find_" .. name, {anonymous = true})
+ -- "detect.packages.find_xxx" exists?
+ if os.isfile(path.join(os.programdir(), "modules", "detect", "packages", "find_" .. name .. ".lua")) then
+ local find_package = import("detect.packages.find_" .. name)
if find_package then
return find_package(opt)
end
end
end
--- find package from system
-function sandbox_lib_detect_find_package._find_from_system(name, opt)
- -- TODO
+-- find package from pkg-config
+function sandbox_lib_detect_find_package._find_from_pkg_config(name, opt)
+ return pkg_config.find(name, opt)
+end
+
+-- find package from system directories
+function sandbox_lib_detect_find_package._find_from_systemdirs(name, opt)
+
+ -- cannot get the version of package
+ if opt.version then
+ return
+ end
+
+ -- add default search pathes on pc host
+ local pathes = {}
+ if opt.plat == "linux" or opt.plat == "macosx" then
+ table.insert(pathes, "/usr/local/lib")
+ table.insert(pathes, "/usr/lib")
+ table.insert(pathes, "/opt/local/lib")
+ table.insert(pathes, "/opt/lib")
+ if opt.plat == "linux" and opt.arch == "x86_64" then
+ table.insert(pathes, "/usr/local/lib/x86_64-linux-gnu")
+ table.insert(pathes, "/usr/lib/x86_64-linux-gnu")
+ end
+ end
+
+ -- attempt to get links from pkg-config
+ local pkginfo = nil
+ local links = opt.links
+ if not links then
+ pkginfo = pkg_config.info(name)
+ if pkginfo then
+ links = pkginfo.links
+ end
+ end
+
+ -- import find_library
+ local find_library = import("lib.detect.find_library")
+
+ -- find library
+ local result = nil
+ for _, link in ipairs(table.wrap(links)) do
+ local libinfo = find_library(link, pathes)
+ if libinfo then
+ result = result or {}
+ result.links = table.join(result.links or {}, libinfo.link)
+ result.linkdirs = table.join(result.linkdirs or {}, libinfo.linkdir)
+ end
+ end
+
+ -- not found? only add links
+ if not result and pkginfo and pkginfo.links then
+ result = {links = pkginfo.links}
+ end
+
+ -- ok
+ return result
end
-- find package
@@ -65,42 +127,65 @@ function sandbox_lib_detect_find_package._find(name, opt)
-- init find scripts
local findscripts =
{
- sandbox_lib_detect_find_package._find_from_repositories
+ sandbox_lib_detect_find_package._find_from_project_packagedirs
+ , sandbox_lib_detect_find_package._find_from_repositories
, sandbox_lib_detect_find_package._find_from_modules
- , sandbox_lib_detect_find_package._find_from_system
}
+ -- find package from the current host platform
+ if opt.plat == os.host() and opt.arch == os.arch() then
+ table.insert(findscripts, sandbox_lib_detect_find_package._find_from_pkg_config)
+ table.insert(findscripts, sandbox_lib_detect_find_package._find_from_systemdirs)
+ end
+
-- find it
+ local result = nil
for _, find in ipairs(findscripts) do
- local package = find(name, opt)
- if package then
- return package
+ result = find(name, opt)
+ if result then
+ break
end
end
+
+ -- remove repeat
+ if result then
+ result.linkdirs = table.unique(result.linkdirs)
+ result.includedirs = table.unique(result.includedirs)
+ end
+
+ -- ok?
+ return result
end
-- find package
--
-- @param name the package name
--- @param opt the package options. e.g. {version = ">1.0.1", pathes = {"/usr/lib"}}
+-- @param opt the package options. e.g. {plat = "iphoneos", arch = "arm64", version = "1.0.1", pathes = {"/usr/lib"}, links = {"ssl"}, includes = {"ssl.h"}}
--
--- @return {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}, version = "1.0.2"}
+-- @return {links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}}
--
-- @code
--
-- local package = find_package("openssl")
--- local package = find_package("openssl", {version = ">1.0.1"})
--- local package = find_package("openssl", {pathes = {"/usr/lib", "/usr/local/lib", "/usr/local/include"}, version = ">1.0.1"})
+-- local package = find_package("openssl", {version = "1.0.1"})
+-- local package = find_package("openssl", {plat = "iphoneos"})
+-- local package = find_package("openssl", {pathes = {"/usr/lib", "/usr/local/lib", "/usr/local/include"}, version = "1.0.1"})
+-- local package = find_package("openssl", {pathes = {"/usr/lib", "/usr/local/lib", "/usr/local/include"}, links = {"ssl", "crypto"}, includes = {"ssl.h"}})
--
-- @endcode
--
function sandbox_lib_detect_find_package.main(name, opt)
- -- get detect cache
- local detectcache = cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect"))
-
+ -- init options
+ opt = opt or {}
+ opt.plat = opt.plat or config.get("plat") or os.host()
+ opt.arch = opt.arch or config.get("arch") or os.arch()
+
+ -- init cache key
+ local key = "find_package_" .. opt.plat .. "_" .. opt.arch
+
-- attempt to get result from cache first
- local cacheinfo = detectcache:get("find_package") or {}
+ local cacheinfo = cache.load(key)
local result = cacheinfo[name]
if result ~= nil then
return utils.ifelse(result, result, nil)
@@ -113,8 +198,7 @@ function sandbox_lib_detect_find_package.main(name, opt)
cacheinfo[name] = utils.ifelse(result, result, false)
-- save cache info
- detectcache:set("find_program", cacheinfo)
- detectcache:flush()
+ cache.save(key, cacheinfo)
-- trace
if option.get("verbose") then
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_path.lua b/xmake/core/sandbox/modules/import/lib/detect/find_path.lua
index 2b94b33fc..bb5a7d280 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_path.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_path.lua
@@ -35,24 +35,45 @@ local vformat = require("sandbox/modules/vformat")
-- find path
--
-- @param name the path name
--- @param pathes the program pathes (.e.g dirs, pathes, winreg pathes)
+-- @param pathes the search pathes (.e.g dirs, pathes, winreg pathes)
+-- @param opt the options, .e.g {suffixes = {"/aa", "/bb"}}
--
-- @return the path
--
-- @code
--
-- local p = find_path("include/test.h", { "/usr", "/usr/local"})
+-- -> /usr/local ("/usr/local/include/test.h")
+--
-- local p = find_path("include/*.h", { "/usr", "/usr/local/**"})
-- local p = find_path("lib/xxx", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"})
-- local p = find_path("lib/xxx", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"):match("\"(.-)\"") end})
--
-- @endcode
--
-function sandbox_lib_detect_find_path.main(name, pathes)
+function sandbox_lib_detect_find_path.main(name, pathes, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- init pathes
+ pathes = table.wrap(pathes)
+
+ -- append suffixes to pathes
+ local suffixes = table.wrap(opt.suffixes)
+ if #suffixes > 0 then
+ local pathes_new = {}
+ for _, parent in ipairs(pathes) do
+ for _, suffix in ipairs(suffixes) do
+ table.insert(pathes_new, path.join(parent, suffix))
+ end
+ end
+ pathes = pathes_new
+ end
-- find file
local result = nil
- for _, _path in ipairs(table.wrap(pathes)) do
+ for _, _path in ipairs(pathes) do
-- format path for builtin variables
if type(_path) == "function" then
@@ -66,17 +87,9 @@ function sandbox_lib_detect_find_path.main(name, pathes)
_path = vformat(_path)
end
- -- get file path
- local filepath = nil
- if os.isfile(_path) then
- filepath = _path
- else
- filepath = path.join(_path, name)
- end
-
-- path exists?
- for _, p in ipairs(os.filedirs(filepath)) do
- result = p
+ for _, p in ipairs(os.filedirs(path.join(_path, name))) do
+ result = _path
break
end
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
index a14b67648..e38a3414c 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
@@ -31,11 +31,14 @@ local path = require("base/path")
local table = require("base/table")
local utils = require("base/utils")
local option = require("base/option")
-local cache = require("project/cache")
local project = require("project/project")
local sandbox = require("sandbox/sandbox")
local raise = require("sandbox/modules/raise")
local vformat = require("sandbox/modules/vformat")
+local cache = require("sandbox/modules/import/lib/detect/cache")
+
+-- globals
+local checking = nil
-- check program
function sandbox_lib_detect_find_program._check(program, check)
@@ -123,7 +126,7 @@ end
-- find program
--
-- @param name the program name
--- @param pathes the program pathes (.e.g dirs, pathes, winreg pathes)
+-- @param pathes the program pathes (.e.g dirs, pathes, winreg pathes, script pathes)
-- @param check the check script or command
--
-- @return the program name or path
@@ -131,21 +134,26 @@ end
-- @code
--
-- local program = find_program("ccache")
--- local program = find_program("ccache", { "/usr/bin", "/usr/local/bin"})
--- local program = find_program("ccache", { "/usr/bin", "/usr/local/bin"}, "--help") -- simple check command: ccache --help
--- local program = find_program("ccache", { "/usr/bin", "/usr/local/bin"}, function (program) os.run("%s -h", program) end)
--- local program = find_program("ccache", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"})
--- local program = find_program("ccache", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger"):match("\"(.-)\"") end})
+-- local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"})
+-- local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, "--help") -- simple check command: ccache --help
+-- local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, function (program) os.run("%s -h", program) end)
+-- local program = find_program("ccache", {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"})
+-- local program = find_program("ccache", {"$(env PATH)", function () return "/usr/local/bin" end})
--
-- @endcode
--
function sandbox_lib_detect_find_program.main(name, pathes, check)
- -- get detect cache
- local detectcache = cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect"))
-
+ -- @note avoid detect the same program in the same time leading to deadlock if running in the coroutine (.e.g ccache)
+ local coroutine_running = coroutine.running()
+ if coroutine_running then
+ while checking ~= nil and checking == name do
+ coroutine.yield()
+ end
+ end
+
-- attempt to get result from cache first
- local cacheinfo = detectcache:get("find_program") or {}
+ local cacheinfo = cache.load("find_program")
local result = cacheinfo[name]
if result ~= nil then
return utils.ifelse(result, result, nil)
@@ -153,18 +161,19 @@ function sandbox_lib_detect_find_program.main(name, pathes, check)
-- add default search pathes
if os.host() ~= "windows" then
- pathes = table.join(table.wrap(pathes), "/usr/local/lib", "/usr/lib")
+ pathes = table.join(table.wrap(pathes), "/usr/local/bin", "/usr/bin")
end
-- find executable program
+ checking = utils.ifelse(coroutine_running, name, nil)
result = sandbox_lib_detect_find_program._find(name, pathes, check)
+ checking = nil
-- cache result
cacheinfo[name] = utils.ifelse(result, result, false)
-- save cache info
- detectcache:set("find_program", cacheinfo)
- detectcache:flush()
+ cache.save("find_program", cacheinfo)
-- trace
if option.get("verbose") then
diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_programver.lua b/xmake/core/sandbox/modules/import/lib/detect/find_programver.lua
index 50eb72cef..b54b03899 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_programver.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_programver.lua
@@ -31,10 +31,10 @@ local path = require("base/path")
local table = require("base/table")
local utils = require("base/utils")
local option = require("base/option")
-local cache = require("project/cache")
local project = require("project/project")
local sandbox = require("sandbox/sandbox")
local raise = require("sandbox/modules/raise")
+local cache = require("sandbox/modules/import/lib/detect/cache")
-- find program version
--
@@ -54,11 +54,8 @@ local raise = require("sandbox/modules/raise")
--
function sandbox_lib_detect_find_programver.main(program, command, parse)
- -- get detect cache
- local detectcache = cache(utils.ifelse(os.isfile(project.file()), "local.detect", "memory.detect"))
-
-- attempt to get result from cache first
- local cacheinfo = detectcache:get("find_programver") or {}
+ local cacheinfo = cache.load("find_programver")
local result = cacheinfo[program]
if result ~= nil then
return utils.ifelse(result, result, nil)
@@ -93,8 +90,7 @@ function sandbox_lib_detect_find_programver.main(program, command, parse)
cacheinfo[program] = utils.ifelse(result, result, false)
-- save cache info
- detectcache:set("find_program", cacheinfo)
- detectcache:flush()
+ cache.save("find_programver", cacheinfo)
-- ok?
return result
diff --git a/xmake/core/sandbox/modules/inherit.lua b/xmake/core/sandbox/modules/inherit.lua
index cf22abcec..2ec1e2e29 100644
--- a/xmake/core/sandbox/modules/inherit.lua
+++ b/xmake/core/sandbox/modules/inherit.lua
@@ -30,10 +30,16 @@ local import = require("sandbox/modules/import")
-- we can access all super interfaces by _super
--
-- @note the polymiorphism is not supported for import.inherit mode now.
-function sandbox_inherit(name)
+function sandbox_inherit(name, args)
+
+ -- init args
+ args = args or {}
+
+ -- mark as inherit
+ args.inherit = true
-- import and inherit it
- return import(name, {inherit = true})
+ return import(name, args)
end
-- load module
diff --git a/xmake/core/sandbox/modules/interpreter/os.lua b/xmake/core/sandbox/modules/interpreter/os.lua
index b11e6bcb4..b956726eb 100644
--- a/xmake/core/sandbox/modules/interpreter/os.lua
+++ b/xmake/core/sandbox/modules/interpreter/os.lua
@@ -30,17 +30,21 @@ local string = require("base/string")
local sandbox_os = sandbox_os or {}
-- export some readonly interfaces
-sandbox_os.date = os.date
-sandbox_os.time = os.time
-sandbox_os.mtime = os.mtime
-sandbox_os.mclock = os.mclock
-sandbox_os.getenv = os.getenv
-sandbox_os.isdir = os.isdir
-sandbox_os.isfile = os.isfile
-sandbox_os.exists = os.exists
-sandbox_os.curdir = os.curdir
-sandbox_os.tmpdir = os.tmpdir
-sandbox_os.uuid = os.uuid
+sandbox_os.date = os.date
+sandbox_os.time = os.time
+sandbox_os.mtime = os.mtime
+sandbox_os.mclock = os.mclock
+sandbox_os.getenv = os.getenv
+sandbox_os.isdir = os.isdir
+sandbox_os.isfile = os.isfile
+sandbox_os.exists = os.exists
+sandbox_os.curdir = os.curdir
+sandbox_os.tmpdir = os.tmpdir
+sandbox_os.programdir = os.programdir
+sandbox_os.programfile = os.programfile
+sandbox_os.projectdir = os.projectdir
+sandbox_os.projectfile = os.projectfile
+sandbox_os.uuid = os.uuid
-- match files
function sandbox_os.files(pattern, ...)
diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua
index 90312ae2a..7f53818e4 100644
--- a/xmake/core/sandbox/modules/os.lua
+++ b/xmake/core/sandbox/modules/os.lua
@@ -48,6 +48,8 @@ sandbox_os.nuldev = os.nuldev
sandbox_os.emptydir = os.emptydir
sandbox_os.programdir = os.programdir
sandbox_os.programfile = os.programfile
+sandbox_os.projectdir = os.projectdir
+sandbox_os.projectfile = os.projectfile
sandbox_os.versioninfo = os.versioninfo
-- copy file or directory
@@ -224,13 +226,6 @@ function sandbox_os.tmpfile()
return tmpfile
end
--- get the tools directory
-function sandbox_os.toolsdir()
-
- -- get it
- return xmake._TOOLS_DIR
-end
-
-- get the script directory
function sandbox_os.scriptdir()
@@ -246,7 +241,7 @@ function sandbox_os.scriptdir()
return rootdir
end
--- quietly run shell
+-- quietly run command
function sandbox_os.run(cmd, ...)
-- make command
@@ -259,20 +254,20 @@ function sandbox_os.run(cmd, ...)
end
end
--- quietly run shell with arguments list
-function sandbox_os.runv(shellname, argv)
+-- quietly run command with arguments list
+function sandbox_os.runv(program, argv)
- -- make shellname
- shellname = vformat(shellname)
+ -- make program
+ program = vformat(program)
-- run it
- local ok, errors = os.runv(shellname, argv)
+ local ok, errors = os.runv(program, argv)
if not ok then
os.raise(errors)
end
end
--- quietly run shell and echo verbose info if [-v|--verbose] option is enabled
+-- quietly run command and echo verbose info if [-v|--verbose] option is enabled
function sandbox_os.vrun(cmd, ...)
-- echo command
@@ -284,19 +279,19 @@ function sandbox_os.vrun(cmd, ...)
utils.ifelse(option.get("verbose"), sandbox_os.exec, sandbox_os.run)(cmd, ...)
end
--- quietly run shell with arguments list and echo verbose info if [-v|--verbose] option is enabled
-function sandbox_os.vrunv(shellname, argv)
+-- quietly run command with arguments list and echo verbose info if [-v|--verbose] option is enabled
+function sandbox_os.vrunv(program, argv)
-- echo command
if option.get("verbose") then
- print(vformat(shellname), table.concat(argv, " "))
+ print(vformat(program), table.concat(argv, " "))
end
-- run it
- utils.ifelse(option.get("verbose"), sandbox_os.execv, sandbox_os.runv)(shellname, argv)
+ utils.ifelse(option.get("verbose"), sandbox_os.execv, sandbox_os.runv)(program, argv)
end
--- run shell and return output and error data
+-- run command and return output and error data
function sandbox_os.iorun(cmd, ...)
-- make command
@@ -312,14 +307,14 @@ function sandbox_os.iorun(cmd, ...)
return outdata, errdata
end
--- run shell and return output and error data
-function sandbox_os.iorunv(shellname, argv)
+-- run command and return output and error data
+function sandbox_os.iorunv(program, argv)
- -- make shellname
- shellname = vformat(shellname)
+ -- make program
+ program = vformat(program)
-- run it
- local ok, outdata, errdata = os.iorunv(shellname, argv)
+ local ok, outdata, errdata = os.iorunv(program, argv)
if not ok then
os.raise(errdata)
end
@@ -328,7 +323,7 @@ function sandbox_os.iorunv(shellname, argv)
return outdata, errdata
end
--- execute shell
+-- execute command
function sandbox_os.exec(cmd, ...)
-- make command
@@ -341,19 +336,19 @@ function sandbox_os.exec(cmd, ...)
end
end
--- execute shell with arguments list
-function sandbox_os.execv(shellname, argv)
+-- execute command with arguments list
+function sandbox_os.execv(program, argv)
- -- make shellname
- shellname = vformat(shellname)
+ -- make program
+ program = vformat(program)
-- run it
- local ok = os.execv(shellname, argv)
+ local ok = os.execv(program, argv)
if ok ~= 0 then
if argv ~= nil then
- os.raise("execv(%s %s) failed(%d)!", shellname, table.concat(argv, ' '), ok)
+ os.raise("execv(%s %s) failed(%d)!", program, table.concat(argv, ' '), ok)
else
- os.raise("execv(%s) failed(%d)!", shellname, ok)
+ os.raise("execv(%s) failed(%d)!", program, ok)
end
end
end
diff --git a/xmake/core/sandbox/modules/string.lua b/xmake/core/sandbox/modules/string.lua
index 3079c6e23..2506ae35e 100644
--- a/xmake/core/sandbox/modules/string.lua
+++ b/xmake/core/sandbox/modules/string.lua
@@ -23,6 +23,7 @@
--
-- load modules
+local utils = require("base/utils")
local string = require("base/string")
local sandbox = require("sandbox/sandbox")
@@ -46,12 +47,14 @@ function sandbox_string.vformat(format, ...)
local instance = sandbox.instance()
assert(instance)
- -- ignore %$(...)
- format = format:gsub("%%%$", "__$__")
-
-- format string if exists arguments
local result = format
if #{...} > 0 then
+
+ -- escape "%$", "%(", "%)", "%%" to '$', '(', ')', '%%'
+ format = format:gsub("%%([%$%(%)%%])", function (ch) return utils.ifelse(ch ~= "%", "%%" .. ch, "%%%%") end)
+
+ -- try to format it
result = string.format(format, ...)
end
assert(result)
@@ -62,9 +65,6 @@ function sandbox_string.vformat(format, ...)
result = filter:handle(result)
end
- -- escape to $(...)
- result = result:gsub("__%$__", "$")
-
-- ok?
return result
end
diff --git a/xmake/core/sandbox/modules/utils.lua b/xmake/core/sandbox/modules/utils.lua
index 80a21aef8..f72da0423 100644
--- a/xmake/core/sandbox/modules/utils.lua
+++ b/xmake/core/sandbox/modules/utils.lua
@@ -76,7 +76,8 @@ function sandbox_utils.print(format, ...)
end,
catch
{
- function ()
+ function (errors)
+ print(errors)
-- print multi-variables with raw lua action
sandbox_utils._print(format, unpack(args))
end
diff --git a/xmake/core/sandbox/sandbox.lua b/xmake/core/sandbox/sandbox.lua
index 77b7003e2..a706e6da2 100644
--- a/xmake/core/sandbox/sandbox.lua
+++ b/xmake/core/sandbox/sandbox.lua
@@ -107,7 +107,7 @@ function sandbox._new()
table.inherit2(instance, sandbox)
-- load builtin module files
- local builtin_module_files = os.match(path.join(xmake._CORE_DIR, "sandbox/modules/*.lua"))
+ local builtin_module_files = os.match(path.join(os.programdir(), "core/sandbox/modules/*.lua"))
if builtin_module_files then
for _, builtin_module_file in ipairs(builtin_module_files) do
@@ -134,19 +134,8 @@ function sandbox._new()
end
end
- -- save instance
- setmetatable(instance._PUBLIC, { __index = function (tbl, key)
- if type(key) == "string" and key == "_SANDBOX" and rawget(tbl, "_SANDBOX_READABLE") then
- return instance
- end
- return rawget(tbl, key)
- end
- , __newindex = function (tbl, key, val)
- if type(key) == "string" and (key == "_SANDBOX" or key == "_SANDBOX_READABLE") then
- return
- end
- rawset(tbl, key, val)
- end})
+ -- bind instance to the public script envirnoment
+ instance:bind(instance._PUBLIC)
-- ok?
return instance
@@ -192,7 +181,34 @@ function sandbox.load(script, ...)
return xpcall(script, sandbox._traceback, ...)
end
--- fork a new sandbox from the given sandbox
+-- bind self instance to the given script or envirnoment
+function sandbox:bind(script_or_env)
+
+ -- get envirnoment
+ local env = script_or_env
+ if type(script_or_env) == "function" then
+ env = getfenv(script_or_env)
+ end
+
+ -- bind instance to the script envirnoment
+ setmetatable(env, { __index = function (tbl, key)
+ if type(key) == "string" and key == "_SANDBOX" and rawget(tbl, "_SANDBOX_READABLE") then
+ return self
+ end
+ return rawget(tbl, key)
+ end
+ , __newindex = function (tbl, key, val)
+ if type(key) == "string" and (key == "_SANDBOX" or key == "_SANDBOX_READABLE") then
+ return
+ end
+ rawset(tbl, key, val)
+ end})
+
+ -- ok
+ return script_or_env
+end
+
+-- fork a new sandbox from the self sandbox
function sandbox:fork(script, rootdir)
-- invalid script?
@@ -254,7 +270,6 @@ function sandbox:import()
-- ok
return module
-
end
-- get script from the given sandbox
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
index 43bed8bfa..9143fcbee 100644
--- a/xmake/core/tool/builder.lua
+++ b/xmake/core/tool/builder.lua
@@ -76,8 +76,8 @@ function builder:_mapflag(flag, mapflags)
end
end
- -- check it
- if self:check(flag) then
+ -- has this flag?
+ if self:has_flags(flag) then
return flag
end
end
@@ -103,9 +103,9 @@ function builder:_mapflags(flags)
else
- -- check flags
+ -- has flags?
for _, flag in pairs(flags) do
- if self:check(flag) then
+ if self:has_flags(flag) then
table.insert(results, flag)
end
end
@@ -194,6 +194,13 @@ function builder:_addflags_from_targetdeps(results, target, flagname)
end
end
+-- add flags from the argument option
+function builder:_addflags_from_argument(flags, args)
+ for _, flagkind in ipairs(self:_flagkinds()) do
+ table.join2(flags, self:_mapflags(args[flagkind]))
+ end
+end
+
-- add flags (named) from the language
function builder:_addflags_from_language(flags, target)
@@ -261,8 +268,8 @@ function builder:_addflags_from_language(flags, target)
for _, flagvalue in ipairs(table.wrap(getter(flagname))) do
-- map and check flag
- local flag = mapper(flagvalue, target, self:_targetkind())
- if flag and flag ~= "" and (not checkstate or self:check(flag)) then
+ local flag = mapper(self:_tool(), flagvalue, target, self:_targetkind())
+ if flag and flag ~= "" and (not checkstate or self:has_flags(flag)) then
table.join2(flags, flag)
end
end
@@ -270,11 +277,29 @@ function builder:_addflags_from_language(flags, target)
end
end
+-- get tool name
+function builder:name()
+ return self:_tool():name()
+end
+
+-- get tool kind
+function builder:kind()
+ return self:_tool():kind()
+end
+
+-- get tool program
+function builder:program()
+ return self:_tool():program()
+end
+
-- get properties of the tool
function builder:get(name)
+ return self:_tool():get(name)
+end
- -- get it
- return self:_tool().get(name)
+-- has flags?
+function builder:has_flags(flags)
+ return self:_tool():has_flags(flags)
end
-- get the format of the given target kind
@@ -297,40 +322,5 @@ function builder:feature(name)
end
end
--- check the given flags
-function builder:check(flags)
-
- -- the builder tool
- local ctool = self:_tool()
-
- -- no check?
- if not ctool.check then
- return true
- end
-
- -- have been checked? return it directly
- self._CHECKED = self._CHECKED or {}
- if self._CHECKED[flags] ~= nil then
- return self._CHECKED[flags]
- end
-
- -- check it
- local ok, errors = sandbox.load(ctool.check, flags)
-
- -- trace
- if option.get("verbose") then
- utils.cprint("checking for the flags %s ... %s", flags, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok then
- utils.cprint("${red}" .. errors or "")
- end
- end
-
- -- save the checked result
- self._CHECKED[flags] = ok
-
- -- ok?
- return ok
-end
-
-- return module
return builder
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index a550564da..622ed946b 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -50,7 +50,7 @@ end
function compiler:_addflags_from_platform(flags, targetkind)
-- add flags
- local toolkind = self:get("kind")
+ local toolkind = self:kind()
for _, flagkind in ipairs(self:_flagkinds()) do
-- add flags for platform
@@ -124,67 +124,119 @@ function compiler.load(sourcekind)
return instance
end
--- build the source files
-function compiler:build(sourcefiles, targetkind, targetfile, target)
+-- build the source files (compile and link)
+function compiler:build(sourcefiles, targetfile, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- make flags
+ local flags = self:compflags(opt)
+ if opt.target then
+ flags = flags .. " " .. (opt.target:linkflags())
+ end
+
+ -- get target kind
+ local targetkind = opt.targetkind
+ if not targetkind and opt.target then
+ targetkind = opt.target:get("kind")
+ end
-- get it
- return sandbox.load(self:_tool().build, sourcefiles, targetkind, targetfile, (self:compflags(target)) .. " " .. (target:linkflags()))
+ return sandbox.load(self:_tool().build, self:_tool(), sourcefiles, targetkind or "binary", targetfile, flags)
end
--- get the build command
-function compiler:buildcmd(sourcefiles, targetkind, targetfile, target)
+-- get the build command (compile and link)
+function compiler:buildcmd(sourcefiles, targetfile, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- make flags
+ local flags = self:compflags(opt)
+ if opt.target then
+ flags = flags .. " " .. (opt.target:linkflags())
+ end
+
+ -- get target kind
+ local targetkind = opt.targetkind
+ if not targetkind and opt.target then
+ targetkind = opt.target:get("kind")
+ end
-- get it
- return self:_tool().buildcmd(sourcefiles, targetkind, targetfile, (self:compflags(target) .. " " .. (target:linkflags())))
+ return self:_tool():buildcmd(sourcefiles, targetkind or "binary", targetfile, flags)
end
-- compile the source files
-function compiler:compile(sourcefiles, objectfile, incdepfile, target)
+function compiler:compile(sourcefiles, objectfile, opt)
+
+ -- init options
+ opt = opt or {}
-- compile it
- return sandbox.load(self:_tool().compile, sourcefiles, objectfile, incdepfile, (self:compflags(target)))
+ return sandbox.load(self:_tool().compile, self:_tool(), sourcefiles, objectfile, opt.incdepfiles, (self:compflags(opt)))
end
-- get the compile command
-function compiler:compcmd(sourcefiles, objectfile, target)
-
- -- get it
- return self:_tool().compcmd(sourcefiles, objectfile, (self:compflags(target)))
+function compiler:compcmd(sourcefiles, objectfile, opt)
+ return self:_tool():compcmd(sourcefiles, objectfile, (self:compflags(opt)))
end
-- get the compling flags
-function compiler:compflags(target)
+function compiler:compflags(opt)
- -- no target?
- if not target then
- return "", {}
- end
+ -- init options
+ opt = opt or {}
+
+ -- get target
+ local target = opt.target
-- get the target key
- local key = tostring(target)
+ local key = nil
+ if target then
+ key = tostring(target)
+ end
-- get it directly from cache dirst
- self._FLAGS = self._FLAGS or {}
- local flags_cached = self._FLAGS[key]
- if flags_cached then
- return flags_cached[1], flags_cached[2]
+ if key then
+ self._FLAGS = self._FLAGS or {}
+ local flags_cached = self._FLAGS[key]
+ if flags_cached then
+ return flags_cached[1], flags_cached[2]
+ end
+ end
+
+ -- get target kind
+ local targetkind = opt.targetkind
+ if not targetkind and target then
+ targetkind = target:get("kind")
end
-- add flags from the configure
local flags = {}
self:_addflags_from_config(flags)
- -- add flags from the target
- self:_addflags_from_target(flags, target)
-
+ -- add flags for the target
+ if target then
+ self:_addflags_from_target(flags, target)
+ end
+
-- add flags (named) from language
- self:_addflags_from_language(flags, target)
+ if target then
+ self:_addflags_from_language(flags, target)
+ end
+
+ -- add flags for the argument
+ self:_addflags_from_argument(flags, opt)
-- add flags from the platform
- self:_addflags_from_platform(flags, target:get("kind"))
+ if target then
+ self:_addflags_from_platform(flags, targetkind)
+ end
-- add flags from the compiler
- self:_addflags_from_compiler(flags, target:get("kind"))
+ self:_addflags_from_compiler(flags, targetkind)
-- remove repeat
flags = table.unique(flags)
@@ -193,7 +245,9 @@ function compiler:compflags(target)
local flags_str = table.concat(flags, " "):trim()
-- save flags
- self._FLAGS[key] = {flags_str, flags}
+ if key then
+ self._FLAGS[key] = {flags_str, flags}
+ end
-- get it
return flags_str, flags
diff --git a/xmake/core/tool/extractor.lua b/xmake/core/tool/extractor.lua
index 1149e31aa..480005c68 100644
--- a/xmake/core/tool/extractor.lua
+++ b/xmake/core/tool/extractor.lua
@@ -38,8 +38,6 @@ local tool = require("tool/tool")
-- get the current tool
function extractor:_tool()
-
- -- get it
return self._TOOL
end
@@ -72,16 +70,12 @@ end
-- get properties of the tool
function extractor:get(name)
-
- -- get it
- return self:_tool().get(name)
+ return self:_tool():get(name)
end
-- extract the library file
function extractor:extract(libraryfile, objectdir)
-
- -- extract it
- return sandbox.load(self:_tool().extract, libraryfile, objectdir)
+ return sandbox.load(self:_tool().extract, self:_tool(), libraryfile, objectdir)
end
-- return module
diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua
index 0ddf3165b..e1d091edb 100644
--- a/xmake/core/tool/linker.lua
+++ b/xmake/core/tool/linker.lua
@@ -44,25 +44,27 @@ local compiler = require("tool/compiler")
function linker:_addflags_from_platform(flags, targetkind)
-- add flags
- local toolkind = self:get("kind")
+ local toolkind = self:kind()
for _, flagkind in ipairs(self:_flagkinds()) do
-- attempt to add special lanugage flags first, .e.g gc-ldflags, dc-arflags
table.join2(flags, platform.get(toolkind .. 'flags') or platform.get(flagkind))
-- attempt to add special lanugage flags first for target kind, .e.g gc-ldflags, dc-arflags
- local targetflags = platform.get(targetkind) or {}
- table.join2(flags, targetflags[toolkind .. 'flags'] or targetflags[flagkind])
+ if targetkind then
+ local targetflags = platform.get(targetkind) or {}
+ table.join2(flags, targetflags[toolkind .. 'flags'] or targetflags[flagkind])
+ end
end
end
-- add flags from the compiler
-function linker:_addflags_from_compiler(flags, targetkind, sourcekinds)
+function linker:_addflags_from_compiler(flags, targetkind)
-- make flags
local flags_of_compiler = {}
- local toolkind = self:get("kind")
- for _, sourcekind in ipairs(table.wrap(sourcekinds)) do
+ local toolkind = self:kind()
+ for _, sourcekind in ipairs(self._SOURCEKINDS) do
-- load compiler
local instance, errors = compiler.load(sourcekind)
@@ -87,7 +89,7 @@ end
function linker:_addflags_from_linker(flags)
-- add flags
- local toolkind = self:get("kind")
+ local toolkind = self:kind()
for _, flagkind in ipairs(self:_flagkinds()) do
-- attempt to add special lanugage flags first, .e.g gc-ldflags, dc-arflags
@@ -162,6 +164,9 @@ function linker.load(targetkind, sourcekinds)
-- init target kind
instance._TARGETKIND = targetkind
+ -- init source kinds
+ instance._SOURCEKINDS = sourcekinds
+
-- init flag kinds
instance._FLAGKINDS = {linkerinfo.linkerflag}
@@ -173,52 +178,71 @@ function linker.load(targetkind, sourcekinds)
end
-- link the target file
-function linker:link(objectfiles, targetfile, target)
-
- -- link it
- return sandbox.load(self:_tool().link, table.concat(table.wrap(objectfiles), " "), self:_targetkind(), targetfile, (self:linkflags(target)))
+function linker:link(objectfiles, targetfile, opt)
+ return sandbox.load(self:_tool().link, self:_tool(), table.concat(table.wrap(objectfiles), " "), self:_targetkind(), targetfile, (self:linkflags(opt)))
end
-- get the link command
-function linker:linkcmd(objectfiles, targetfile, target)
-
- -- get it
- return self:_tool().linkcmd(table.concat(table.wrap(objectfiles), " "), self:_targetkind(), targetfile, (self:linkflags(target)))
+function linker:linkcmd(objectfiles, targetfile, opt)
+ return self:_tool():linkcmd(table.concat(table.wrap(objectfiles), " "), self:_targetkind(), targetfile, (self:linkflags(opt)))
end
-- get the link flags
-function linker:linkflags(target)
+function linker:linkflags(opt)
- -- no target?
- if not target then
- return "", {}
- end
+ -- init options
+ opt = opt or {}
+
+ -- get target
+ local target = opt.target
-- get the target key
- local key = tostring(target)
+ local key = nil
+ if target then
+ key = tostring(target)
+ end
-- get it directly from cache dirst
- self._FLAGS = self._FLAGS or {}
- local flags_cached = self._FLAGS[key]
- if flags_cached then
- return flags_cached[1], flags_cached[2]
+ if key then
+ self._FLAGS = self._FLAGS or {}
+ local flags_cached = self._FLAGS[key]
+ if flags_cached then
+ return flags_cached[1], flags_cached[2]
+ end
+ end
+
+ -- get target kind
+ local targetkind = opt.targetkind
+ if not targetkind and target then
+ targetkind = target:get("kind")
end
-- add flags from the configure
local flags = {}
self:_addflags_from_config(flags)
- -- add flags from the target
- self:_addflags_from_target(flags, target)
-
+ -- add flags for the target
+ if target then
+ self:_addflags_from_target(flags, target)
+ end
+
-- add flags (named) from language
- self:_addflags_from_language(flags, target)
+ if target then
+ self:_addflags_from_language(flags, target)
+ end
+
+ -- add flags for the argument
+ self:_addflags_from_argument(flags, opt)
-- add flags from the platform
- self:_addflags_from_platform(flags, target:get("kind"))
+ if target then
+ self:_addflags_from_platform(flags, targetkind)
+ end
-- add flags from the compiler
- self:_addflags_from_compiler(flags, target:get("kind"), target:sourcekinds())
+ if target then
+ self:_addflags_from_compiler(flags, targetkind)
+ end
-- add flags from the linker
self:_addflags_from_linker(flags)
@@ -230,7 +254,9 @@ function linker:linkflags(target)
local flags_str = table.concat(flags, " "):trim()
-- save flags
- self._FLAGS[key] = {flags_str, flags}
+ if key then
+ self._FLAGS[key] = {flags_str, flags}
+ end
-- get it
return flags_str, flags
diff --git a/xmake/core/tool/tool.lua b/xmake/core/tool/tool.lua
index 7b139b12b..67c95cc24 100644
--- a/xmake/core/tool/tool.lua
+++ b/xmake/core/tool/tool.lua
@@ -13,7 +13,7 @@
-- 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
+-- See the License for the specific tool governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
@@ -24,202 +24,75 @@
-- define module
local tool = tool or {}
+local _instance = _instance or {}
-- load modules
-local os = require("base/os")
-local path = require("base/path")
-local utils = require("base/utils")
-local table = require("base/table")
-local string = require("base/string")
-local filter = require("base/filter")
-local config = require("project/config")
-local global = require("project/global")
-local sandbox = require("sandbox/sandbox")
-local platform = require("platform/platform")
+local os = require("base/os")
+local path = require("base/path")
+local utils = require("base/utils")
+local table = require("base/table")
+local string = require("base/string")
+local sandbox = require("sandbox/sandbox")
+local platform = require("platform/platform")
+local import = require("sandbox/modules/import")
--- the directories of tools
-function tool._directories(name)
-
- -- the directories
- return { path.join(config.directory(), "tools")
- , path.join(global.directory(), "tools")
- , path.join(xmake._PROGRAM_DIR, "tools")
- }
-end
-
--- match the tool name
-function tool._match(name, toolname)
-
- -- match full? ok
- if name == toolname then return 100 end
-
- -- match the last word? ok
- if name:find(toolname .. "$") then return 80 end
-
- -- contains it? ok
- if name:find(toolname, 1, true) then return 30 end
-
- -- not matched
- return 0
-end
-
--- find tool from the given root directory and name
-function tool._find(root, name)
-
- -- attempt to get it directly first
- local filepath = string.format("%s/%s.lua", root, name)
- if os.isfile(filepath) then
- return filepath
- end
-
- -- make the lower name
- name = name:lower()
-
- -- remove arguments: -xxx or --xxx
- name = (name:gsub("%s%-+%w+", " "))
-
- -- get the last name by ' ': xxx xxx toolname
- local names = name:split("%s")
- if #names > 0 then
- name = names[#names]
- end
-
- -- get the last name by '-': xxx-xxx-toolname
- local names = name:split("%-")
- if #names > 0 then
- name = names[#names]
- end
-
- -- remove suffix: ".xxx"
- name = (name:gsub("%.%w+", ""))
-
- -- get all tool files
- local file_ok = nil
- local score_maxn = 0
- local files = os.match(string.format("%s/*.lua", root))
- for _, file in ipairs(files) do
-
- -- the tool name
- local toolname = path.basename(file)
-
- -- found it?
- if toolname and toolname ~= "tool" then
-
- -- match score
- local score = tool._match(name, toolname:lower())
-
- -- ok?
- if score >= 100 then return file end
-
- -- select the file with the max score
- if score > score_maxn then
- file_ok = file
- score_maxn = score
- end
- end
- end
-
- -- ok?
- return file_ok
-end
-
--- load the given tool from the given shell name
-function tool._load(shellname, kind)
-
- -- calculate the cache key
- local key = shellname .. (kind or "")
-
- -- get it directly from cache dirst
- tool._TOOLS = tool._TOOLS or {}
- if tool._TOOLS[key] then
- return tool._TOOLS[key]
- end
-
- -- find the tool script path
- local toolpath = nil
- local toolname = path.filename(shellname)
- for _, dir in ipairs(tool._directories()) do
-
- -- find this directory
- toolpath = tool._find(dir, toolname)
- if toolpath then
- break
- end
+-- new an instance
+function _instance.new(kind, name, program)
+ -- import "core.tools.xxx"
+ local toolclass = nil
+ if os.isfile(path.join(os.programdir(), "modules", "core", "tools", name .. ".lua")) then
+ toolclass = import("core.tools." .. name)
end
- -- not exists?
- if not toolpath or not os.isfile(toolpath) then
- return nil, string.format("%s not found!", shellname)
+ -- not found?
+ if not toolclass then
+ return nil, string.format("cannot import \"core.tool.%s\" module!", name)
end
- -- load script
- local script, errors = loadfile(toolpath)
- if script then
+ -- new an instance
+ local instance = table.inherit(_instance, toolclass)
- -- make sandbox instance with the given script
- local instance, errors = sandbox.new(script, nil, path.directory(toolpath))
- if not instance then
- return nil, errors
- end
+ -- save name, kind and program
+ instance._NAME = name
+ instance._KIND = kind
+ instance._PROGRAM = program
- -- import the tool module
- local module, errors = instance:import()
- if not module then
+ -- init instance
+ if instance.init then
+ local ok, errors = sandbox.load(instance.init, instance)
+ if not ok then
return nil, errors
end
-
- -- init the tool module
- if module.init then
- module.init(shellname, kind)
- end
-
- -- save tool to the cache
- tool._TOOLS[key] = module
-
- -- ok?
- return module
end
- -- failed
- return nil, errors
+ -- ok
+ return instance
end
--- check the shellname
-function tool._check(shellname, check)
-
- -- uses the passed checker
- if check ~= nil then
+-- get the tool name
+function _instance:name()
+ return self._NAME
+end
- -- check it
- local ok, errors = sandbox.load(check, shellname)
- if not ok then
- utils.verror(errors)
- end
+-- get the tool kind
+function _instance:kind()
+ return self._KIND
+end
- -- ok?
- return ok
- end
-
- -- load the tool module
- local module, errors = tool._load(shellname)
- if not module then
- utils.verror(errors)
- end
+-- get the tool program
+function _instance:program()
+ return self._PROGRAM
+end
- -- no checker? attempt to run it directly
- if not module or not module.check then
- return 0 == os.exec(shellname, os.nuldev(), os.nuldev())
- end
+-- has the given flag?
+function _instance:has_flags(flag)
- -- check it
- local ok, errors = sandbox.load(module.check)
- if not ok then
- utils.verror(errors)
- end
+ -- import has_flags()
+ self._has_flags = self._has_flags or import("lib.detect.has_flags")
- -- ok?
- return ok
+ -- has flags?
+ return self._has_flags(self:name(), flag, {program = self:program()})
end
-- load the given tool from the given kind
@@ -230,51 +103,44 @@ end
--
function tool.load(kind)
- -- get the shell name
- local shellname = platform.tool(kind)
- if not shellname then
+ -- get it directly from cache dirst
+ tool._TOOLS = tool._TOOLS or {}
+ if tool._TOOLS[kind] then
+ return tool._TOOLS[kind]
+ end
+
+ -- get the tool program
+ local program = platform.tool(kind)
+ if not program then
return nil, string.format("cannot get tool for %s", kind)
end
-
- -- load it
- return tool._load(shellname, kind)
-end
--- check the tool and return the absolute path if exists
-function tool.check(shellname, dirs, check)
+ -- import find_toolname()
+ tool._find_toolname = tool._find_toolname or import("lib.detect.find_toolname")
- -- check
- assert(shellname)
+ -- get the tool name from the program
+ local ok, name_or_errors = sandbox.load(tool._find_toolname, program)
+ if not ok then
+ return nil, name_or_errors
+ end
- -- attempt to get result from cache first
- tool._CHECKINFO = tool._CHECKINFO or {}
- local result = tool._CHECKINFO[shellname]
- if result then
- return result
+ -- get name
+ local name = name_or_errors
+ if not name then
+ return nil, string.format("cannot find tool name for %s", program)
end
- -- attempt to check it directly
- if tool._check(shellname, check) then
- tool._CHECKINFO[shellname] = shellname
- return shellname
+ -- new an instance
+ local instance, errors = _instance.new(kind, name, program)
+ if not instance then
+ return nil, errors
end
- -- attempt to check it from the given directories
- if not path.is_absolute(shellname) then
- for _, dir in ipairs(table.wrap(dirs)) do
+ -- save instance to the cache
+ tool._TOOLS[kind] = instance
- -- the tool path
- local toolpath = path.join(dir, shellname)
- if os.isexec(toolpath) then
-
- -- check it
- if tool._check(toolpath, check) then
- tool._CHECKINFO[shellname] = toolpath
- return toolpath
- end
- end
- end
- end
+ -- ok
+ return instance
end
-- return module
diff --git a/xmake/languages/c++/api.lua b/xmake/languages/c++/api.lua
index 8937ddf74..d116fdeac 100644
--- a/xmake/languages/c++/api.lua
+++ b/xmake/languages/c++/api.lua
@@ -22,34 +22,57 @@
-- @file api.lua
--
--- imports
-import("core.project.option")
+-- get function name and function info
+--
+-- sigsetjmp
+-- sigsetjmp((void*)0, 0)
+-- sigsetjmp{sigsetjmp((void*)0, 0);}
+-- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
+--
+function _funcinfo(func)
+
+ -- parse name and code
+ local name, code = string.match(func, "(.+){(.+)}")
+ if code == nil then
+ local pos = func:find("%(")
+ if pos then
+ name = func:sub(1, pos - 1)
+ code = func
+ else
+ name = func
+ code = string.format("volatile void* p%s = (void*)&%s;", name, name)
+ end
+ end
+
+ -- ok
+ return name:trim(), code
+end
-- add c function
-function _api_add_cfunc(interp, module, alias, links, includes, checkinfo)
+function _api_add_cfunc(interp, module, alias, links, includes, func)
- -- parse the check code
- local checkname, checkcode = option.checkinfo(checkinfo)
+ -- parse the function info
+ local funcname, funccode = _funcinfo(func)
-- make the option name
local name = nil
if module ~= nil then
- name = format("__%s_%s", module, checkname)
+ name = format("__%s_%s", module, funcname)
else
- name = format("__%s", checkname)
+ name = format("__%s", funcname)
end
-- uses the alias name
if alias ~= nil then
- checkname = alias
+ funcname = alias
end
-- make the option define
local define = nil
if module ~= nil then
- define = format("$(prefix)_%s_HAVE_%s", module:upper(), checkname:upper())
+ define = format("$(prefix)_%s_HAVE_%s", module:upper(), funcname:upper())
else
- define = format("$(prefix)_HAVE_%s", checkname:upper())
+ define = format("$(prefix)_HAVE_%s", funcname:upper())
end
-- save the current scope
@@ -58,7 +81,7 @@ function _api_add_cfunc(interp, module, alias, links, includes, checkinfo)
-- check option
interp:api_call("option", name)
interp:api_call("set_category", "cfuncs")
- interp:api_call("add_cfuncs", checkinfo)
+ interp:api_call("add_cfuncs", func)
if links then interp:api_call("add_links", links) end
if includes then interp:api_call("add_cincludes", includes) end
interp:api_call("add_defines_h_if_ok", define)
@@ -74,36 +97,36 @@ end
function _api_add_cfuncs(interp, module, links, includes, ...)
-- done
- for _, checkinfo in ipairs({...}) do
- _api_add_cfunc(interp, module, nil, links, includes, checkinfo)
+ for _, func in ipairs({...}) do
+ _api_add_cfunc(interp, module, nil, links, includes, func)
end
end
-- add c++ function
-function _api_add_cxxfunc(interp, module, alias, links, includes, checkinfo)
+function _api_add_cxxfunc(interp, module, alias, links, includes, func)
- -- parse the check code
- local checkname, checkcode = option.checkinfo(checkinfo)
+ -- parse the function info
+ local funcname, funccode = _funcinfo(func)
-- make the option name
local name = nil
if module ~= nil then
- name = format("__%s_%s", module, checkname)
+ name = format("__%s_%s", module, funcname)
else
- name = format("__%s", checkname)
+ name = format("__%s", funcname)
end
-- uses the alias name
if alias ~= nil then
- checkname = alias
+ funcname = alias
end
-- make the option define
local define = nil
if module ~= nil then
- define = format("$(prefix)_%s_HAVE_%s", module:upper(), checkname:upper())
+ define = format("$(prefix)_%s_HAVE_%s", module:upper(), funcname:upper())
else
- define = format("$(prefix)_HAVE_%s", checkname:upper())
+ define = format("$(prefix)_HAVE_%s", funcname:upper())
end
-- save the current scope
@@ -112,7 +135,7 @@ function _api_add_cxxfunc(interp, module, alias, links, includes, checkinfo)
-- check option
interp:api_call("option", name)
interp:api_call("set_category", "cxxfuncs")
- interp:api_call("add_cxxfuncs", checkinfo)
+ interp:api_call("add_cxxfuncs", func)
if links then interp:api_call("add_links", links) end
if includes then interp:api_call("add_cxxincludes", includes) end
interp:api_call("add_defines_h_if_ok", define)
@@ -128,8 +151,8 @@ end
function _api_add_cxxfuncs(interp, module, links, includes, ...)
-- done
- for _, checkinfo in ipairs({...}) do
- _api_add_cxxfunc(interp, module, nil, links, includes, checkinfo)
+ for _, func in ipairs({...}) do
+ _api_add_cxxfunc(interp, module, nil, links, includes, func)
end
end
diff --git a/xmake/tools/ar.lua b/xmake/modules/core/tools/ar.lua
index e870aa866..9d7ddabeb 100644
--- a/xmake/tools/ar.lua
+++ b/xmake/modules/core/tools/ar.lua
@@ -26,28 +26,21 @@
import("core.tool.compiler")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "ar"
-
- -- save the tool kind
- _g.kind = kind or "ar"
-
-- init arflags
_g.arflags = { "-cr" }
-
end
-- get the property
-function get(name)
+function get(self, name)
-- get it
return _g[name]
end
-- make the strip flag
-function strip(level)
+function strip(self, level)
-- the maps
local maps =
@@ -61,17 +54,17 @@ function strip(level)
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
-- check
assert(targetkind == "static")
-- make it
- return format("%s %s %s %s", _g.shellname, flags, targetfile, objectfiles)
+ return format("%s %s %s %s", self:program(), flags, targetfile, objectfiles)
end
-- link the library file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- check
assert(targetkind == "static", "the target kind: %s is not support for ar", targetkind)
@@ -80,11 +73,11 @@ function link(objectfiles, targetkind, targetfile, flags)
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
-- extract the static library to object directory
-function extract(libraryfile, objectdir)
+function extract(self, libraryfile, objectdir)
-- make the object directory first
os.mkdir(objectdir)
@@ -96,11 +89,11 @@ function extract(libraryfile, objectdir)
local olddir = os.cd(objectdir)
-- extract it
- os.run("%s -x %s", _g.shellname, libraryfile)
+ os.run("%s -x %s", self:program(), libraryfile)
-- check repeat object name
local repeats = {}
- local objectfiles = os.iorun("%s -t %s", _g.shellname, libraryfile)
+ local objectfiles = os.iorun("%s -t %s", self:program(), libraryfile)
for _, objectfile in ipairs(objectfiles:split('\n')) do
if repeats[objectfile] then
raise("object name(%s) conflicts in library: %s", objectfile, libraryfile)
@@ -112,29 +105,3 @@ function extract(libraryfile, objectdir)
os.cd(olddir)
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local libraryfile = os.tmpfile() .. ".a"
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".c"
- io.writefile(sourcefile, "int test(void)\n{return 0;}")
-
- -- make flags
- local arflags = table.concat(_g.arflags, " ")
- if flags then
- arflags = arflags .. " " .. flags
- end
-
- -- compile it
- compiler.compile(sourcefile, objectfile)
-
- -- check it
- link(objectfile, "static", libraryfile, arflags)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
- os.rm(libraryfile)
-end
diff --git a/xmake/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index 7781d619d..b55948ecd 100644
--- a/xmake/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -26,14 +26,8 @@
import("core.project.project")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "cl.exe"
-
- -- save kind
- _g.kind = kind
-
-- init cxflags
_g.cxflags = { "-nologo", "-Gd", "-MP4", "-D_MBCS", "-D_CRT_SECURE_NO_WARNINGS"}
@@ -92,35 +86,21 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
+function get(self, name)
-- get it
return _g[name]
end
-- make the symbol flag
-function nf_symbol(level, target)
-
- -- check -FS flags
- if _g._FS == nil then
- local ok = try
- {
- function ()
- check("-ZI -FS -Fd" .. os.tmpfile() .. ".pdb")
- return true
- end
- }
- if ok then
- _g._FS = true
- end
- end
+function nf_symbol(self, level, target)
-- debug? generate *.pdb file
local flags = ""
if level == "debug" then
if target and target.symbolfile then
flags = "-ZI -Fd" .. target:symbolfile()
- if _g._FS then
+ if self:has_flags("-ZI -FS -Fd" .. os.tmpfile() .. ".pdb") then
flags = "-FS " .. flags
end
else
@@ -133,7 +113,7 @@ function nf_symbol(level, target)
end
-- make the warning flag
-function nf_warning(level)
+function nf_warning(self, level)
-- the maps
local maps =
@@ -150,7 +130,7 @@ function nf_warning(level)
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -168,7 +148,7 @@ function nf_optimize(level)
end
-- make the vector extension flag
-function nf_vectorext(extension)
+function nf_vectorext(self, extension)
-- the maps
local maps =
@@ -184,7 +164,7 @@ function nf_vectorext(extension)
end
-- make the language flag
-function nf_language(stdname)
+function nf_language(self, stdname)
-- the stdc maps
local cmaps =
@@ -198,7 +178,7 @@ function nf_language(stdname)
-- select maps
local maps = cmaps
- if _g.kind == "cxx" or _g.kind == "mxx" then
+ if self:kind() == "cxx" or self:kind() == "mxx" then
maps = {}
end
@@ -207,35 +187,27 @@ function nf_language(stdname)
end
-- make the define flag
-function nf_define(macro)
-
- -- make it
+function nf_define(self, macro)
return "-D" .. macro:gsub("\"", "\\\"")
end
-- make the undefine flag
-function nf_undefine(macro)
-
- -- make it
+function nf_undefine(self, macro)
return "-U" .. macro
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I" .. dir
end
-- make the complie command
-function _compcmd1(sourcefile, objectfile, flags)
-
- -- make it
- return format("%s -c %s -Fo%s %s", _g.shellname, flags, objectfile, sourcefile)
+function _compcmd1(self, sourcefile, objectfile, flags)
+ return format("%s -c %s -Fo%s %s", self:program(), flags, objectfile, sourcefile)
end
-- complie the source file
-function _compile1(sourcefile, objectfile, incdepfile, flags)
+function _compile1(self, sourcefile, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
@@ -249,7 +221,7 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
local outdata = try
{
function ()
- return os.iorun(_compcmd1(sourcefile, objectfile, flags))
+ return os.iorun(_compcmd1(self, sourcefile, objectfile, flags))
end,
catch
@@ -299,38 +271,23 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
+function compcmd(self, sourcefiles, objectfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- return _compcmd1(sourcefiles, objectfile, flags)
+ return _compcmd1(self, sourcefiles, objectfile, flags)
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- _compile1(sourcefiles, objectfile, incdepfile, flags)
+ _compile1(self, sourcefiles, objectfile, incdepfile, flags)
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".obj"
- local sourcefile = os.tmpfile() .. ".c"
- io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
-
- -- check it
- os.run("%s -c %s -Fo%s %s", _g.shellname, ifelse(flags, flags, ""), objectfile, sourcefile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
-end
diff --git a/xmake/tools/clang.lua b/xmake/modules/core/tools/clang.lua
index eb7c4b058..f391b101e 100644
--- a/xmake/tools/clang.lua
+++ b/xmake/modules/core/tools/clang.lua
@@ -26,10 +26,10 @@
inherit("gcc")
-- init it
-function init(shellname, kind)
+function init(self)
-- init super
- _super.init(shellname or "clang", kind)
+ _super.init(self)
-- init shflags
_super._g.shflags = { "-dynamiclib", "-fPIC" }
@@ -42,11 +42,10 @@ function init(shellname, kind)
-- init flags map
_super._g.mapflags["-s"] = "-Wl,-S"
_super._g.mapflags["-S"] = "-Wl,-S"
-
end
-- make the strip flag
-function nf_strip(level)
+function nf_strip(self, level)
-- the maps
local maps =
diff --git a/xmake/tools/clang++.lua b/xmake/modules/core/tools/clangxx.lua
index b9545995d..3e31ac92e 100644
--- a/xmake/tools/clang++.lua
+++ b/xmake/modules/core/tools/clangxx.lua
@@ -25,11 +25,4 @@
-- inherit clang
inherit("clang")
--- init it
-function init(shellname, kind)
-
- -- init super
- _super.init(shellname or "clang++", kind)
-
-end
diff --git a/xmake/tools/dmd.lua b/xmake/modules/core/tools/dmd.lua
index bd6b67379..02178577e 100644
--- a/xmake/tools/dmd.lua
+++ b/xmake/modules/core/tools/dmd.lua
@@ -23,20 +23,13 @@
--
-- imports
-import("core.tool.tool")
import("core.base.option")
import("core.project.config")
import("core.project.project")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "dmd"
-
- -- save the kind
- _g.kind = kind
-
-- init arflags
_g.arflags = { "-lib" }
@@ -55,14 +48,12 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -80,7 +71,7 @@ function nf_optimize(level)
end
-- make the strip flag
-function nf_strip(level)
+function nf_strip(self, level)
-- the maps
local maps =
@@ -94,7 +85,7 @@ function nf_strip(level)
end
-- make the symbol flag
-function nf_symbol(level)
+function nf_symbol(self, level)
-- the maps
local maps =
@@ -108,7 +99,7 @@ function nf_symbol(level)
end
-- make the warning flag
-function nf_warning(level)
+function nf_warning(self, level)
-- the maps
local maps =
@@ -125,7 +116,7 @@ function nf_warning(level)
end
-- make the vector extension flag
-function nf_vectorext(extension)
+function nf_vectorext(self, extension)
-- the maps
local maps =
@@ -139,101 +130,55 @@ function nf_vectorext(extension)
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I" .. dir
end
-- make the link flag
-function nf_link(lib)
-
- -- make it
+function nf_link(self, lib)
return "-L-l" .. lib
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-L-L" .. dir
end
-- make the rpathdir flag
-function nf_rpathdir(dir)
-
- -- check this flag
+function nf_rpathdir(self, dir)
local flag = "-L-rpath=" .. dir
- if _g._RPATH == nil then
- _g._RPATH = try
- {
- function ()
- check(flag, true)
- return true
- end
- }
- end
-
- -- ok?
- if _g._RPATH then
+ if self:has_flags(flag) then
return flag
end
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
-
- -- make it
- return format("%s %s -of%s %s", _g.shellname, flags, targetfile, objectfiles)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
+ return format("%s %s -of%s %s", self:program(), flags, targetfile, objectfiles)
end
-- link the target file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
-
- -- make it
- return format("%s -c %s -of%s %s", _g.shellname, flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
+function compcmd(self, sourcefiles, objectfile, flags)
+ return format("%s -c %s -of%s %s", self:program(), flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
- os.run(compcmd(sourcefiles, objectfile, flags))
+ os.run(compcmd(self, sourcefiles, objectfile, flags))
end
--- check the given flags
-function check(flags, trylink)
-
- -- make an stub source file
- local binaryfile = os.tmpfile() .. ".b"
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".d"
-
- -- make stub code
- io.writefile(sourcefile, "void main() {\n}")
-
- -- check it, need check compflags and linkflags
- if trylink then
- os.run("%s %s -of%s %s", _g.shellname, ifelse(flags, flags, ""), binaryfile, sourcefile)
- else
- os.run("%s -c %s -of%s %s", _g.shellname, ifelse(flags, flags, ""), binaryfile, sourcefile)
- end
-
- -- remove files
- os.tryrm(binaryfile)
- os.tryrm(objectfile)
- os.tryrm(sourcefile)
-end
diff --git a/xmake/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 94bc201ed..4071ba100 100644
--- a/xmake/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -23,20 +23,13 @@
--
-- imports
-import("core.tool.tool")
import("core.base.option")
import("core.project.config")
import("core.project.project")
-import("detect.tool.find_ccache")
+import("detect.tools.find_ccache")
-- init it
-function init(shellname, kind)
-
- -- save the shell name
- _g.shellname = shellname or "gcc"
-
- -- save the kind
- _g.kind = kind
+function init(self)
-- init mxflags
_g.mxflags = { "-fmessage-length=0"
@@ -50,8 +43,15 @@ function init(shellname, kind)
_g.shflags = { "-shared", "-fPIC" }
-- init cxflags for the kind: shared
- _g.shared = {}
- _g.shared.cxflags = {"-fPIC"}
+ _g.shared = {}
+ _g.shared.cxflags = {"-fPIC"}
+
+ -- suppress warning for clang (gcc -> clang on macosx)
+ if self:has_flags("-Qunused-arguments") then
+ _g.cxflags = {"-Qunused-arguments"}
+ _g.mxflags = {"-Qunused-arguments"}
+ _g.asflags = {"-Qunused-arguments"}
+ end
-- init flags map
_g.mapflags =
@@ -75,14 +75,14 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
+function get(self, name)
-- get it
return _g[name]
end
-- make the strip flag
-function nf_strip(level)
+function nf_strip(self, level)
-- the maps
local maps =
@@ -96,7 +96,7 @@ function nf_strip(level)
end
-- make the symbol flag
-function nf_symbol(level)
+function nf_symbol(self, level)
-- the maps
local maps =
@@ -110,7 +110,7 @@ function nf_symbol(level)
end
-- make the warning flag
-function nf_warning(level)
+function nf_warning(self, level)
-- the maps
local maps =
@@ -127,7 +127,7 @@ function nf_warning(level)
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -145,7 +145,7 @@ function nf_optimize(level)
end
-- make the vector extension flag
-function nf_vectorext(extension)
+function nf_vectorext(self, extension)
-- the maps
local maps =
@@ -165,7 +165,7 @@ function nf_vectorext(extension)
end
-- make the language flag
-function nf_language(stdname)
+function nf_language(self, stdname)
-- the stdc maps
local cmaps =
@@ -197,9 +197,9 @@ function nf_language(stdname)
-- select maps
local maps = cmaps
- if _g.kind == "cxx" or _g.kind == "mxx" then
+ if self:kind() == "cxx" or self:kind() == "mxx" then
maps = cxxmaps
- elseif _g.kind == "sc" then
+ elseif self:kind() == "sc" then
maps = {}
end
@@ -208,87 +208,59 @@ function nf_language(stdname)
end
-- make the define flag
-function nf_define(macro)
-
- -- make it
+function nf_define(self, macro)
return "-D" .. macro:gsub("\"", "\\\"")
end
-- make the undefine flag
-function nf_undefine(macro)
-
- -- make it
+function nf_undefine(self, macro)
return "-U" .. macro
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I" .. dir
end
-- make the link flag
-function nf_link(lib)
-
- -- make it
+function nf_link(self, lib)
return "-l" .. lib
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-L" .. dir
end
-- make the rpathdir flag
-function nf_rpathdir(dir)
-
- -- check this flag
- local flag = "-Wl,-rpath=" .. dir
- if _g._RPATH == nil then
- _g._RPATH = try
- {
- function ()
- check(flag, true)
- return true
- end
- }
- end
-
- -- ok?
- if _g._RPATH then
+function nf_rpathdir(self, dir)
+ if self:has_flags("-Wl,-rpath=" .. dir) then
return flag
end
end
-- make the framework flag
-function nf_framework(framework)
-
- -- make it
+function nf_framework(self, framework)
return "-framework " .. framework
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
-
- -- make it
- return format("%s -o %s %s %s", _g.shellname, targetfile, objectfiles, flags)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
+ return format("%s -o %s %s %s", self:program(), targetfile, objectfiles, flags)
end
-- link the target file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
-- make the complie command
-function _compcmd1(sourcefile, objectfile, flags)
+function _compcmd1(self, sourcefile, objectfile, flags)
-- get ccache
local ccache = nil
@@ -297,7 +269,7 @@ function _compcmd1(sourcefile, objectfile, flags)
end
-- make it
- local command = format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile)
+ local command = format("%s -c %s -o %s %s", self:program(), flags, objectfile, sourcefile)
if ccache then
command = ccache:append(command, " ")
end
@@ -307,7 +279,7 @@ function _compcmd1(sourcefile, objectfile, flags)
end
-- complie the source file
-function _compile1(sourcefile, objectfile, incdepfile, flags)
+function _compile1(self, sourcefile, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
@@ -316,7 +288,7 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
try
{
function ()
- local outdata, errdata = os.iorun(_compcmd1(sourcefile, objectfile, flags))
+ local outdata, errdata = os.iorun(_compcmd1(self, sourcefile, objectfile, flags))
return (outdata or "") .. (errdata or "")
end,
catch
@@ -340,13 +312,13 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
}
-- generate includes file
- if incdepfile and _g.kind ~= "as" then
+ if incdepfile and self:kind() ~= "as" then
-- the temporary file
local tmpfile = os.tmpfile()
-- generate it
- os.run("%s -c -MM %s -o %s %s", _g.shellname, flags or "", tmpfile, sourcefile)
+ os.run("%s -c -MM %s -o %s %s", self:program(), flags or "", tmpfile, sourcefile)
-- translate it
local results = {}
@@ -368,46 +340,22 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
+function compcmd(self, sourcefiles, objectfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- return _compcmd1(sourcefiles, objectfile, flags)
+ return _compcmd1(self, sourcefiles, objectfile, flags)
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- _compile1(sourcefiles, objectfile, incdepfile, flags)
-end
-
--- check the given flags
-function check(flags, trylink)
-
- -- make an stub source file
- local binaryfile = os.tmpfile() .. ".b"
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".c" .. ifelse(_g.kind == "cxx", "pp", "")
-
- -- make stub code
- io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
-
- -- check it, need check compflags and linkflags
- if trylink then
- os.run("%s %s -o %s %s", _g.shellname, ifelse(flags, flags, ""), binaryfile, sourcefile)
- else
- os.run("%s -c %s -o %s %s", _g.shellname, ifelse(flags, flags, ""), binaryfile, sourcefile)
- end
-
- -- remove files
- os.tryrm(binaryfile)
- os.tryrm(objectfile)
- os.tryrm(sourcefile)
+ _compile1(self, sourcefiles, objectfile, incdepfile, flags)
end
diff --git a/xmake/core/sandbox/modules/import/core/project/option.lua b/xmake/modules/core/tools/gccgo.lua
index be9cb810f..41f941cf4 100644
--- a/xmake/core/sandbox/modules/import/core/project/option.lua
+++ b/xmake/modules/core/tools/gccgo.lua
@@ -19,22 +19,10 @@
-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
--
-- @author ruki
--- @file option.lua
+-- @file gccgo.lua
--
--- define module
-local sandbox_core_project_option = sandbox_core_project_option or {}
+-- inherit gcc
+inherit("gcc")
--- load modules
-local option = require("project/option")
-local raise = require("sandbox/modules/raise")
--- parse checkinfo
-function sandbox_core_project_option.checkinfo(checkinfo)
-
- -- parse it
- return option.checkinfo(checkinfo)
-end
-
--- return module
-return sandbox_core_project_option
diff --git a/xmake/tools/gdc.lua b/xmake/modules/core/tools/gdc.lua
index 64b36c2b9..3682de49e 100644
--- a/xmake/tools/gdc.lua
+++ b/xmake/modules/core/tools/gdc.lua
@@ -25,11 +25,5 @@
-- inherit dmd
inherit("dmd")
--- init it
-function init(shellname, kind)
-
- -- init super
- _super.init(shellname or "gdc", kind)
-end
diff --git a/xmake/tools/go.lua b/xmake/modules/core/tools/go.lua
index 472ff84ff..a3b49c8c4 100644
--- a/xmake/tools/go.lua
+++ b/xmake/modules/core/tools/go.lua
@@ -23,20 +23,13 @@
--
-- imports
-import("core.tool.tool")
import("core.base.option")
import("core.project.config")
import("core.project.project")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "go"
-
- -- save the kind
- _g.kind = kind
-
-- init arflags
_g.arflags = { "grc" }
@@ -52,14 +45,12 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -77,7 +68,7 @@ function nf_optimize(level)
end
-- make the symbol flag
-function nf_symbol(level, target, mapkind)
+function nf_symbol(self, level, target, mapkind)
-- only for compiler
if mapkind ~= "object" then
@@ -96,7 +87,7 @@ function nf_symbol(level, target, mapkind)
end
-- make the strip flag
-function nf_strip(level)
+function nf_strip(self, level)
-- the maps
local maps =
@@ -110,71 +101,48 @@ function nf_strip(level)
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I " .. dir
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-L " .. dir
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
-- make it
if targetkind == "static" then
- return format("%s tool pack %s %s %s", _g.shellname, flags, targetfile, objectfiles)
+ return format("%s tool pack %s %s %s", self:program(), flags, targetfile, objectfiles)
else
- return format("%s tool link %s -o %s %s", _g.shellname, flags, targetfile, objectfiles)
+ return format("%s tool link %s -o %s %s", self:program(), flags, targetfile, objectfiles)
end
end
-- link the target file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
-
- -- make it
- return format("%s tool compile %s -o %s %s", _g.shellname, flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
+function compcmd(self, sourcefiles, objectfile, flags)
+ return format("%s tool compile %s -o %s %s", self:program(), flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
- os.run(compcmd(sourcefiles, objectfile, flags))
+ os.run(compcmd(self, sourcefiles, objectfile, flags))
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".go"
-
- -- make stub code
- io.writefile(sourcefile, "package main\nfunc main() {\n}")
-
- -- check it
- os.run("%s tool compile %s -o %s %s", _g.shellname, ifelse(flags, flags, ""), objectfile, sourcefile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
-end
diff --git a/xmake/tools/g++.lua b/xmake/modules/core/tools/gxx.lua
index f37bdb05a..2c73c5473 100644
--- a/xmake/tools/g++.lua
+++ b/xmake/modules/core/tools/gxx.lua
@@ -25,11 +25,4 @@
-- inherit gcc
inherit("gcc")
--- init it
-function init(shellname, kind)
-
- -- init super
- _super.init(shellname or "g++", kind)
-
-end
diff --git a/xmake/tools/ldc.lua b/xmake/modules/core/tools/ldc.lua
index 531d319be..b36fd446e 100644
--- a/xmake/tools/ldc.lua
+++ b/xmake/modules/core/tools/ldc.lua
@@ -26,10 +26,10 @@
inherit("dmd")
-- init it
-function init(shellname, kind)
+function init(self)
-- init super
- _super.init(shellname or "ldc", kind)
+ _super.init(self)
-- init shflags
_super._g.shflags = { "-shared" }
diff --git a/xmake/tools/lib.lua b/xmake/modules/core/tools/lib.lua
index 7b0a851e8..a193b8788 100644
--- a/xmake/tools/lib.lua
+++ b/xmake/modules/core/tools/lib.lua
@@ -22,31 +22,21 @@
-- @file lib.lua
--
--- init it
-function init(shellname, kind)
-
- -- save the shell name
- _g.shellname = shellname or "lib.exe"
-
- -- save the tool kind
- _g.kind = kind
-end
-
-- get the property
-function get(name)
+function get(self, name)
-- get it
return _g[name]
end
-- extract the static library to object directory
-function extract(libraryfile, objectdir)
+function extract(self, libraryfile, objectdir)
-- make the object directory first
os.mkdir(objectdir)
-- list object files
- local objectfiles = os.iorun("%s -nologo -list %s", _g.shellname, libraryfile)
+ local objectfiles = os.iorun("%s -nologo -list %s", self:program(), libraryfile)
-- extrace all object files
for _, objectfile in ipairs(objectfiles:split('\n')) do
@@ -68,28 +58,9 @@ function extract(libraryfile, objectdir)
end
-- extract it
- os.run("%s -nologo -extract:%s -out:%s %s", _g.shellname, objectfile, outputfile, libraryfile)
+ os.run("%s -nologo -extract:%s -out:%s %s", self:program(), objectfile, outputfile, libraryfile)
end
end
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local libfile = os.tmpfile() .. ".lib"
- local objfile = os.tmpfile() .. ".obj"
- local srcfile = os.tmpfile() .. ".c"
- io.writefile(srcfile, "int test(void)\n{return 0;}")
-
- -- check it
- os.run("cl -c -Fo%s %s", objfile, srcfile)
- os.run("link -lib -out:%s %s", libfile, objfile)
- os.run("%s %s -list %s", _g.shellname, ifelse(flags, flags, ""), libfile)
-
- -- remove files
- os.rm(objfile)
- os.rm(srcfile)
- os.rm(libfile)
-end
diff --git a/xmake/tools/link.lua b/xmake/modules/core/tools/link.lua
index aa99377fb..f41a093d4 100644
--- a/xmake/tools/link.lua
+++ b/xmake/modules/core/tools/link.lua
@@ -26,14 +26,8 @@
import("core.project.config")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "link.exe"
-
- -- save the tool kind
- _g.kind = kind
-
-- the architecture
local arch = config.get("arch")
@@ -68,18 +62,17 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the symbol flag
-function nf_symbol(level, target)
+function nf_symbol(self, level, target)
-- debug? generate *.pdb file
local flags = ""
- if level == "debug" then
+ local targetkind = target:get("kind")
+ if level == "debug" and (targetkind == "binary" or targetkind == "shared") then
if target and target.symbolfile then
flags = "-debug -pdb:" .. target:symbolfile()
else
@@ -92,30 +85,26 @@ function nf_symbol(level, target)
end
-- make the link flag
-function nf_link(lib)
-
- -- make it
+function nf_link(self, lib)
return lib .. ".lib"
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-libpath:" .. dir
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
-- make it
- local cmd = format("%s %s -out:%s %s", _g.shellname, flags, targetfile, objectfiles)
+ local cmd = format("%s %s -out:%s %s", self:program(), flags, targetfile, objectfiles)
-- too long?
if #cmd > 4096 then
local argfile = targetfile .. ".arg"
io.printf(argfile, "%s -out:%s %s", flags, targetfile, objectfiles)
- cmd = format("%s @%s", _g.shellname, argfile)
+ cmd = format("%s @%s", self:program(), argfile)
end
-- ok?
@@ -123,42 +112,12 @@ function linkcmd(objectfiles, targetkind, targetfile, flags)
end
-- link the target file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
-end
-
--- check the given flags
-function check(flags)
-
- -- -def:"xxx.def"? pass directly
- if flags and flags:lower():find("def:") then
- return
- end
-
- -- make an stub source file
- local binaryfile = os.tmpfile() .. ".exe"
- local objectfile = os.tmpfile() .. ".obj"
- local sourcefile = os.tmpfile() .. ".c"
-
- -- main entry
- if flags and flags:lower():find("subsystem:windows") then
- io.writefile(sourcefile, "int WinMain(void* instance, void* previnst, char** argv, int argc)\n{return 0;}")
- else
- io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
- end
-
- -- check it
- os.run("cl -c -Fo%s %s", objectfile, sourcefile)
- os.run("%s %s -out:%s %s", _g.shellname, ifelse(flags, flags, ""), binaryfile, objectfile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
- os.rm(binaryfile)
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
diff --git a/xmake/tools/ml.lua b/xmake/modules/core/tools/ml.lua
index d8ddaee29..74a8fc364 100644
--- a/xmake/tools/ml.lua
+++ b/xmake/modules/core/tools/ml.lua
@@ -23,16 +23,10 @@
--
-- init it
-function init(shellname, kind)
+function init(self)
- -- save name
- _g.shellname = shellname or "ml.exe"
-
- -- save kind
- _g.kind = kind
-
-- init asflags
- if _g.shellname:find("64") then
+ if self:program():find("64") then
_g.asflags = { "-nologo"}
else
_g.asflags = { "-nologo", "-Gd"}
@@ -66,14 +60,12 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the warning flag
-function nf_warning(level)
+function nf_warning(self, level)
-- the maps
local maps =
@@ -90,75 +82,52 @@ function nf_warning(level)
end
-- make the define flag
-function nf_define(macro)
-
- -- make it
+function nf_define(self, macro)
return "-D" .. macro:gsub("\"", "\\\"")
end
-- make the undefine flag
-function nf_undefine(macro)
-
- -- make it
+function nf_undefine(self, macro)
return "-U" .. macro
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I" .. dir
end
-- make the complie command
-function _compcmd1(sourcefile, objectfile, flags)
-
- -- make it
- return format("%s -c %s -Fo%s %s", _g.shellname, flags, objectfile, sourcefile)
+function _compcmd1(self, sourcefile, objectfile, flags)
+ return format("%s -c %s -Fo%s %s", self:program(), flags, objectfile, sourcefile)
end
-- complie the source file
-function _compile1(sourcefile, objectfile, incdepfile, flags)
+function _compile1(self, sourcefile, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
- os.run(_compcmd1(sourcefile, objectfile, flags))
+ os.run(_compcmd1(self, sourcefile, objectfile, flags))
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
+function compcmd(self, sourcefiles, objectfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- return _compcmd1(sourcefiles, objectfile, flags)
+ return _compcmd1(self, sourcefiles, objectfile, flags)
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- _compile1(sourcefiles, objectfile, incdepfile, flags)
-end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".obj"
- local sourcefile = os.tmpfile() .. ".asm"
- io.writefile(sourcefile, "end")
-
- -- check it
- os.run("%s -c %s -Fo%s %s", _g.shellname, ifelse(flags, flags, ""), objectfile, sourcefile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
+ _compile1(self, sourcefiles, objectfile, incdepfile, flags)
end
diff --git a/xmake/modules/core/tools/ml64.lua b/xmake/modules/core/tools/ml64.lua
new file mode 100644
index 000000000..899ba9972
--- /dev/null
+++ b/xmake/modules/core/tools/ml64.lua
@@ -0,0 +1,28 @@
+--!The Make-like 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 ml64.lua
+--
+
+-- inherit ml
+inherit("ml")
+
+
diff --git a/xmake/tools/rc.lua b/xmake/modules/core/tools/rc.lua
index eb2d5fa05..a76d7493d 100644
--- a/xmake/tools/rc.lua
+++ b/xmake/modules/core/tools/rc.lua
@@ -27,58 +27,42 @@ import("core.base.option")
import("core.project.project")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "rc.exe"
-
- -- save kind
- _g.kind = kind
-
-- init features
_g.features =
{
- ["object:sources"] = false
+ ["object:sources"] = false
}
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the define flag
-function nf_define(macro)
-
- -- make it
+function nf_define(self, macro)
return "-d" .. macro:gsub("\"", "\\\"")
end
-- make the undefine flag
-function nf_undefine(macro)
-
- -- make it
+function nf_undefine(self, macro)
return "-u" .. macro
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-I" .. dir
end
-- make the complie command
-function _compcmd1(sourcefile, objectfile, flags)
-
- -- make it
- return format("%s %s -Fo%s %s", _g.shellname, flags, objectfile, sourcefile)
+function _compcmd1(self, sourcefile, objectfile, flags)
+ return format("%s %s -Fo%s %s", self:program(), flags, objectfile, sourcefile)
end
-- complie the source file
-function _compile1(sourcefile, objectfile, incdepfile, flags)
+function _compile1(self, sourcefile, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
@@ -87,7 +71,7 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
try
{
function ()
- local outdata, errdata = os.iorun(_compcmd1(sourcefile, objectfile, flags))
+ local outdata, errdata = os.iorun(_compcmd1(self, sourcefile, objectfile, flags))
return (outdata or "") .. (errdata or "")
end,
catch
@@ -112,38 +96,23 @@ function _compile1(sourcefile, objectfile, incdepfile, flags)
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
+function compcmd(self, sourcefiles, objectfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- return _compcmd1(sourcefiles, objectfile, flags)
+ return _compcmd1(self, sourcefiles, objectfile, flags)
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- _compile1(sourcefiles, objectfile, incdepfile, flags)
+ _compile1(self, sourcefiles, objectfile, incdepfile, flags)
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".res"
- local sourcefile = os.tmpfile() .. ".rc"
- io.writefile(sourcefile, "#define RESID 1")
-
- -- check it
- os.run("%s -fo%s %s", _g.shellname, objectfile, sourcefile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
-end
diff --git a/xmake/tools/rustc.lua b/xmake/modules/core/tools/rustc.lua
index 44e117d3f..e480624d9 100644
--- a/xmake/tools/rustc.lua
+++ b/xmake/modules/core/tools/rustc.lua
@@ -23,20 +23,13 @@
--
-- imports
-import("core.tool.tool")
import("core.base.option")
import("core.project.config")
import("core.project.project")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "rustc"
-
- -- save the kind
- _g.kind = kind
-
-- init arflags
_g.arflags = { "--crate-type=lib" }
@@ -61,14 +54,12 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -86,7 +77,7 @@ function nf_optimize(level)
end
-- make the symbol flag
-function nf_symbol(level)
+function nf_symbol(self, level)
-- the maps
local maps =
@@ -100,60 +91,37 @@ function nf_symbol(level)
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-L " .. dir
end
-- make the build command
-function buildcmd(sourcefiles, targetkind, targetfile, flags)
-
- -- make it
- return format("%s %s -o %s %s", _g.shellname, flags, targetfile, table.concat(sourcefiles, " "))
+function buildcmd(self, sourcefiles, targetkind, targetfile, flags)
+ return format("%s %s -o %s %s", self:program(), flags, targetfile, table.concat(sourcefiles, " "))
end
-- build the target file
-function build(sourcefiles, targetkind, targetfile, flags)
+function build(self, sourcefiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- build it
- os.run(buildcmd(sourcefiles, targetkind, targetfile, flags))
+ os.run(buildcmd(self, sourcefiles, targetkind, targetfile, flags))
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
-
- -- make it
- return format("%s --emit obj %s -o %s %s", _g.shellname, flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
+function compcmd(self, sourcefiles, objectfile, flags)
+ return format("%s --emit obj %s -o %s %s", self:program(), flags, objectfile, table.concat(table.wrap(sourcefiles), " "))
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
- os.run(compcmd(sourcefiles, objectfile, flags))
+ os.run(compcmd(self, sourcefiles, objectfile, flags))
end
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".rs"
-
- -- make stub code
- io.writefile(sourcefile, "fn main() {\n}")
-
- -- check it
- os.run("%s --emit obj %s -o %s %s", _g.shellname, ifelse(flags, flags, ""), objectfile, sourcefile)
-
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
-end
diff --git a/xmake/tools/swiftc.lua b/xmake/modules/core/tools/swiftc.lua
index 8a52125e4..e1c18934e 100644
--- a/xmake/tools/swiftc.lua
+++ b/xmake/modules/core/tools/swiftc.lua
@@ -23,19 +23,12 @@
--
-- imports
-import("core.tool.tool")
import("core.project.config")
-import("detect.tool.find_ccache")
+import("detect.tools.find_ccache")
-- init it
-function init(shellname, kind)
+function init(self)
- -- save the shell name
- _g.shellname = shellname or "swiftc"
-
- -- init kind
- _g.kind = kind
-
-- init flags map
_g.mapflags =
{
@@ -71,14 +64,12 @@ function init(shellname, kind)
end
-- get the property
-function get(name)
-
- -- get it
+function get(self, name)
return _g[name]
end
-- make the strip flag
-function nf_strip(level)
+function nf_strip(self, level)
-- the maps
local maps =
@@ -92,7 +83,7 @@ function nf_strip(level)
end
-- make the symbol flag
-function nf_symbol(level)
+function nf_symbol(self, level)
-- the maps
local maps =
@@ -105,7 +96,7 @@ function nf_symbol(level)
end
-- make the warning flag
-function nf_warning(level)
+function nf_warning(self, level)
-- the maps
local maps =
@@ -122,7 +113,7 @@ function nf_warning(level)
end
-- make the optimize flag
-function nf_optimize(level)
+function nf_optimize(self, level)
-- the maps
local maps =
@@ -140,7 +131,7 @@ function nf_optimize(level)
end
-- make the vector extension flag
-function nf_vectorext(extension)
+function nf_vectorext(self, extension)
-- the maps
local maps =
@@ -160,66 +151,52 @@ function nf_vectorext(extension)
end
-- make the includedir flag
-function nf_includedir(dir)
-
- -- make it
+function nf_includedir(self, dir)
return "-Xcc -I" .. dir
end
-- make the define flag
-function nf_define(macro)
-
- -- make it
+function nf_define(self, macro)
return "-Xcc -D" .. macro:gsub("\"", "\\\"")
end
-- make the undefine flag
-function nf_undefine(macro)
-
- -- make it
+function nf_undefine(self, macro)
return "-Xcc -U" .. macro
end
-- make the framework flag
-function nf_framework(framework)
-
- -- make it
+function nf_framework(self, framework)
return "-framework" .. framework
end
-- make the link flag
-function nf_link(lib)
-
- -- make it
+function nf_link(self, lib)
return "-l" .. lib
end
-- make the linkdir flag
-function nf_linkdir(dir)
-
- -- make it
+function nf_linkdir(self, dir)
return "-L" .. dir
end
-- make the link command
-function linkcmd(objectfiles, targetkind, targetfile, flags)
-
- -- make it
- return format("%s -o %s %s %s", _g.shellname, targetfile, objectfiles, flags)
+function linkcmd(self, objectfiles, targetkind, targetfile, flags)
+ return format("%s -o %s %s %s", self:program(), targetfile, objectfiles, flags)
end
-- link the target file
-function link(objectfiles, targetkind, targetfile, flags)
+function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
-- link it
- os.run(linkcmd(objectfiles, targetkind, targetfile, flags))
+ os.run(linkcmd(self, objectfiles, targetkind, targetfile, flags))
end
-- make the compile command
-function _compcmd1(sourcefile, objectfile, flags)
+function _compcmd1(self, sourcefile, objectfile, flags)
-- get ccache
local ccache = nil
@@ -228,7 +205,7 @@ function _compcmd1(sourcefile, objectfile, flags)
end
-- make it
- local command = format("%s -c %s -o %s %s", _g.shellname, flags, objectfile, sourcefile)
+ local command = format("%s -c %s -o %s %s", self:program(), flags, objectfile, sourcefile)
if ccache then
command = ccache:append(command, " ")
end
@@ -238,38 +215,32 @@ function _compcmd1(sourcefile, objectfile, flags)
end
-- complie the source file
-function _compile1(sourcefile, objectfile, incdepfile, flags)
+function _compile1(self, sourcefile, objectfile, incdepfile, flags)
-- ensure the object directory
os.mkdir(path.directory(objectfile))
-- compile it
- os.run(_compcmd1(sourcefile, objectfile, flags))
+ os.run(_compcmd1(self, sourcefile, objectfile, flags))
end
-- make the complie command
-function compcmd(sourcefiles, objectfile, flags)
+function compcmd(self, sourcefiles, objectfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- return _compcmd1(sourcefiles, objectfile, flags)
+ return _compcmd1(self, sourcefiles, objectfile, flags)
end
-- complie the source file
-function compile(sourcefiles, objectfile, incdepfile, flags)
+function compile(self, sourcefiles, objectfile, incdepfile, flags)
-- only support single source file now
assert(type(sourcefiles) ~= "table", "'object:sources' not support!")
-- for only single source file
- _compile1(sourcefiles, objectfile, incdepfile, flags)
+ _compile1(self, sourcefiles, objectfile, incdepfile, flags)
end
--- check the given flags
-function check(flags)
-
- -- check it
- os.run("%s -h", _g.shellname)
-end
diff --git a/xmake/modules/detect/packages/find_openssl.lua b/xmake/modules/detect/packages/find_openssl.lua
new file mode 100644
index 000000000..9efe76370
--- /dev/null
+++ b/xmake/modules/detect/packages/find_openssl.lua
@@ -0,0 +1,74 @@
+--!The Make-like 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 find_openssl.lua
+--
+
+-- imports
+import("lib.detect.find_path")
+import("lib.detect.find_library")
+
+-- find openssl
+--
+-- @param opt the package options. e.g. see the options of find_package()
+--
+-- @return see the return value of find_package()
+--
+function main(opt)
+
+ -- for windows platform
+ --
+ -- http://www.slproweb.com/products/Win32OpenSSL.html
+ --
+ if opt.plat == "windows" then
+
+ -- init bits
+ local bits = ifelse(opt.arch == "x64", "64", "32")
+
+ -- init search pathes
+ local pathes = {"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL %(" .. bits .. "-bit%)_is1;Inno Setup: App Path)",
+ "$(env PROGRAMFILES)/OpenSSL",
+ "$(env PROGRAMFILES)/OpenSSL-Win" .. bits,
+ "C:/OpenSSL",
+ "C:/OpenSSL-Win" .. bits}
+
+ -- find library
+ local result = {links = {}, linkdirs = {}, includedirs = {}}
+ for _, name in ipairs({"libssl", "libcrypto"}) do
+ local linkinfo = find_library(name, pathes, {suffixes = "lib"})
+ if linkinfo then
+ table.insert(result.links, linkinfo.link)
+ table.insert(result.linkdirs, linkinfo.linkdir)
+ end
+ end
+
+ -- not found?
+ if #result.links ~= 2 then
+ return
+ end
+
+ -- find include
+ table.insert(result.includedirs, find_path("openssl/ssl.h", pathes, {suffixes = "include"}))
+
+ -- ok
+ return result
+ end
+end
diff --git a/xmake/modules/detect/packages/find_zlib.lua b/xmake/modules/detect/packages/find_zlib.lua
new file mode 100644
index 000000000..49cc3e83a
--- /dev/null
+++ b/xmake/modules/detect/packages/find_zlib.lua
@@ -0,0 +1,81 @@
+--!The Make-like 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 find_zlib.lua
+--
+
+-- imports
+import("lib.detect.find_path")
+import("lib.detect.find_library")
+
+-- find zlib
+--
+-- @param opt the package options. e.g. see the options of find_package()
+--
+-- @return see the return value of find_package()
+--
+function main(opt)
+
+ -- for windows platform
+ --
+ -- http://gnuwin32.sourceforge.net/packages/zlib.html
+ --
+ if opt.plat == "windows" then
+
+ -- init search pathes
+ local pathes = {"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath)",
+ "$(env PROGRAMFILES)/GnuWin32",
+ "$(env PROGRAMFILES)/zlib"}
+
+ -- find library
+ local result = {links = {}, linkdirs = {}, includedirs = {}}
+ local linkinfo = find_library("zlib", pathes, {suffixes = "lib"})
+ if not linkinfo then
+ return
+ end
+
+ -- save link and directory
+ table.insert(result.links, linkinfo.link)
+ table.insert(result.linkdirs, linkinfo.linkdir)
+
+ -- find include
+ local includedir = find_path("zlib.h", pathes, {suffixes = "include"})
+ if includedir then
+
+ -- save include directory
+ table.insert(result.includedirs, includedir)
+
+ -- match version
+ if opt.version then
+ local zlib_h = io.readfile(path.join(includedir, "zlib.h"))
+ if zlib_h then
+ local version = zlib_h:match("#define ZLIB_VERSION \"(%d+%.?%d+%.?%d+)\"")
+ if version ~= opt.version then
+ return
+ end
+ end
+ end
+ end
+
+ -- ok
+ return result
+ end
+end
diff --git a/xmake/modules/detect/sdk/find_cross_toolchains.lua b/xmake/modules/detect/sdks/find_cross_toolchains.lua
index 0e989d6e7..0e989d6e7 100644
--- a/xmake/modules/detect/sdk/find_cross_toolchains.lua
+++ b/xmake/modules/detect/sdks/find_cross_toolchains.lua
diff --git a/xmake/modules/detect/sdk/find_ndk_sdkvers.lua b/xmake/modules/detect/sdks/find_ndk_sdkvers.lua
index 16ad5eca7..16ad5eca7 100644
--- a/xmake/modules/detect/sdk/find_ndk_sdkvers.lua
+++ b/xmake/modules/detect/sdks/find_ndk_sdkvers.lua
diff --git a/xmake/modules/detect/sdk/find_ndk_toolchains.lua b/xmake/modules/detect/sdks/find_ndk_toolchains.lua
index f7d5b7430..f7d5b7430 100644
--- a/xmake/modules/detect/sdk/find_ndk_toolchains.lua
+++ b/xmake/modules/detect/sdks/find_ndk_toolchains.lua
diff --git a/xmake/modules/detect/sdk/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua
index 1a06d1e90..fb09d915d 100644
--- a/xmake/modules/detect/sdk/find_vstudio.lua
+++ b/xmake/modules/detect/sdks/find_vstudio.lua
@@ -64,6 +64,12 @@ function _load_vcvarsall(vcvarsall, arch)
end
end
+ -- get sdk version
+ local include = variables["include"]
+ if include then
+ variables["sdkver"] = include:match("Windows Kits\\%d+\\include\\(%d+%.%d+%.%d+%.%d+)\\")
+ end
+
-- ok
return variables
end
diff --git a/xmake/modules/detect/sdk/find_xcode_dir.lua b/xmake/modules/detect/sdks/find_xcode_dir.lua
index 65e5b4f31..728ba1245 100644
--- a/xmake/modules/detect/sdk/find_xcode_dir.lua
+++ b/xmake/modules/detect/sdks/find_xcode_dir.lua
@@ -23,7 +23,7 @@
--
-- imports
-import("lib.detect.find_path")
+import("lib.detect.find_directory")
-- find xcode directory
--
@@ -36,5 +36,5 @@ import("lib.detect.find_path")
-- @endcode
--
function main()
- return find_path("Xcode.app", {"/Applications"}) or find_path("Xcode*.app", {"/Applications"})
+ return find_directory("Xcode.app", {"/Applications"}) or find_directory("Xcode*.app", {"/Applications"})
end
diff --git a/xmake/modules/detect/sdk/find_xcode_sdkvers.lua b/xmake/modules/detect/sdks/find_xcode_sdkvers.lua
index fb479208c..a8ef1a816 100644
--- a/xmake/modules/detect/sdk/find_xcode_sdkvers.lua
+++ b/xmake/modules/detect/sdks/find_xcode_sdkvers.lua
@@ -24,7 +24,7 @@
-- imports
import("core.project.config")
-import("detect.sdk.find_xcode_dir")
+import("detect.sdks.find_xcode_dir")
-- find xcode sdk versions for the given platform
--
diff --git a/xmake/modules/detect/tools/ar/has_flag.lua b/xmake/modules/detect/tools/ar/has_flag.lua
new file mode 100644
index 000000000..5358e3e0a
--- /dev/null
+++ b/xmake/modules/detect/tools/ar/has_flag.lua
@@ -0,0 +1,84 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt)
+
+ -- make cache key
+ local key = "detect.tools.ar.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = nil
+ try
+ {
+ function () os.runv(opt.program, {"--help"}) end,
+ catch
+ {
+ function (errors) arglist = errors end
+ }
+ }
+ if arglist then
+ local found = false
+ for arg in arglist:gmatch("%-r %[%-(%a+)%]") do
+ arg:gsub("%a", function (ch) flags["-" .. ch] = true; flags["-r" .. ch] = true; flags["-" .. ch .. "r"] = true end)
+ found = true
+ end
+ if found then
+ flags["-r"] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag]
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+ return _check_from_arglist(flag, opt)
+end
+
diff --git a/xmake/modules/detect/tools/cl/has_flag.lua b/xmake/modules/detect/tools/cl/has_flag.lua
new file mode 100644
index 000000000..1f6e370e3
--- /dev/null
+++ b/xmake/modules/detect/tools/cl/has_flag.lua
@@ -0,0 +1,98 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt)
+
+ -- make cache key
+ local key = "detect.tools.cl.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = os.iorunv(opt.program, {"-?"})
+ if arglist then
+ for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do
+ flags[arg:gsub("/", "-")] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag:gsub("/", "-")]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "cl_has_flag.c")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
+ end
+
+ -- check it
+ return try { function ()
+ local _, errors = os.iorunv(opt.program, {"-c", "-nologo", flag, "-Fo" .. os.nuldev(), sourcefile})
+ if errors and #errors:trim() > 0 then
+ return false
+ end
+ return true
+ end
+ }
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt)
+end
+
diff --git a/xmake/modules/detect/package/find_openssl.lua b/xmake/modules/detect/tools/clang/has_flag.lua
index fb1af8c6a..0cb83600e 100644
--- a/xmake/modules/detect/package/find_openssl.lua
+++ b/xmake/modules/detect/tools/clang/has_flag.lua
@@ -19,19 +19,9 @@
-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
--
-- @author ruki
--- @file find_openssl.lua
+-- @file has_flag.lua
--
-- imports
-import("lib.detect.find_file")
-import("lib.detect.find_library")
+inherit("detect.tools.gcc.has_flag")
--- find openssl
---
--- @param opt the package options. e.g. see the options of find_package()
---
--- @return see the return value of find_package()
---
-function main(opt)
- -- TODO
-end
diff --git a/xmake/modules/detect/tools/clangxx/has_flag.lua b/xmake/modules/detect/tools/clangxx/has_flag.lua
new file mode 100644
index 000000000..0cb83600e
--- /dev/null
+++ b/xmake/modules/detect/tools/clangxx/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.gcc.has_flag")
+
diff --git a/xmake/modules/detect/tools/dmd/has_flag.lua b/xmake/modules/detect/tools/dmd/has_flag.lua
new file mode 100644
index 000000000..719551523
--- /dev/null
+++ b/xmake/modules/detect/tools/dmd/has_flag.lua
@@ -0,0 +1,118 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- is linker?
+function _islinker(flag, opt)
+
+ -- the flag is "-L=<arg>" or "-L<arg>"?
+ if flag:startswith("-L=") or flag:startswith("-L-") then
+ return true
+ end
+
+ -- the tool kind is ld or sh?
+ local toolkind = opt.toolkind or ""
+ return toolkind == "ld" or toolkind == "sh" or toolkind:endswith("-ld") or toolkind:endswith("-sh")
+end
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt, islinker)
+
+ -- only for compiler
+ if islinker then
+ return
+ end
+
+ -- make cache key
+ local key = "detect.tools.dmd.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = os.iorunv(opt.program, {"--help"})
+ if arglist then
+ for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
+ flags[arg] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt, islinker)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "dmd_has_flag.d")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "void main() {\n}")
+ end
+
+ -- init argv
+ local argv = {flag, "-of" .. os.nuldev(), sourcefile}
+ if not islinker then
+ table.insert(argv, 1, "-c")
+ end
+
+ -- check it
+ return try { function () os.runv(opt.program, argv); return true end }
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- is linker?
+ local islinker = _islinker(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt, islinker) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt, islinker)
+end
+
diff --git a/xmake/modules/detect/tool/find_7z.lua b/xmake/modules/detect/tools/find_7z.lua
index 58a4ea24e..bc5c3d340 100644
--- a/xmake/modules/detect/tool/find_7z.lua
+++ b/xmake/modules/detect/tools/find_7z.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("7z", {}, "--help")
+ local program = find_program(opt.program or "7z", opt.pathes, opt.check or "--help")
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_ar.lua b/xmake/modules/detect/tools/find_ar.lua
new file mode 100644
index 000000000..6bbf840c5
--- /dev/null
+++ b/xmake/modules/detect/tools/find_ar.lua
@@ -0,0 +1,70 @@
+--!The Make-like 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 find_ar.lua
+--
+
+-- imports
+import("core.tool.compiler")
+import("lib.detect.find_program")
+
+-- check
+function _check(program)
+
+ -- make an stub source file
+ local libraryfile = os.tmpfile() .. ".a"
+ local objectfile = os.tmpfile() .. ".o"
+ local sourcefile = os.tmpfile() .. ".c"
+ io.writefile(sourcefile, "int test(void)\n{return 0;}")
+
+ -- compile it
+ compiler.compile(sourcefile, objectfile)
+
+ -- archive it
+ os.runv(program, {"-cr", libraryfile, objectfile})
+
+ -- remove files
+ os.rm(objectfile)
+ os.rm(sourcefile)
+ os.rm(libraryfile)
+end
+
+-- find ar
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local ar = find_ar()
+-- local ar, version = find_ar({program = "xcrun -sdk macosx g++", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ return find_program(opt.program or "ar", opt.pathes, opt.check or _check)
+end
diff --git a/xmake/modules/detect/tools/find_brew.lua b/xmake/modules/detect/tools/find_brew.lua
new file mode 100644
index 000000000..e4c07403f
--- /dev/null
+++ b/xmake/modules/detect/tools/find_brew.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_brew.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find brew
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local brew = find_brew()
+-- local brew, version = find_brew({version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "brew", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_ccache.lua b/xmake/modules/detect/tools/find_ccache.lua
index faf45da53..9e4fe4aa6 100644
--- a/xmake/modules/detect/tool/find_ccache.lua
+++ b/xmake/modules/detect/tools/find_ccache.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("ccache")
+ local program = find_program(opt.program or "ccache", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_cl.lua b/xmake/modules/detect/tools/find_cl.lua
new file mode 100644
index 000000000..3ab7cf5c1
--- /dev/null
+++ b/xmake/modules/detect/tools/find_cl.lua
@@ -0,0 +1,59 @@
+--!The Make-like 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 find_cl.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find cl
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local cl = find_cl()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "cl.exe", opt.pathes, opt.check or function (program) os.run(program) end)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, function () local _, info = os.iorun(program); return info end,
+ function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tools/find_clang.lua b/xmake/modules/detect/tools/find_clang.lua
new file mode 100644
index 000000000..5e1dc95d4
--- /dev/null
+++ b/xmake/modules/detect/tools/find_clang.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_clang.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find clang
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local clang = find_clang()
+-- local clang, version = find_clang({program = "xcrun -sdk macosx clang", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "clang", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_clangxx.lua b/xmake/modules/detect/tools/find_clangxx.lua
new file mode 100644
index 000000000..77e80304f
--- /dev/null
+++ b/xmake/modules/detect/tools/find_clangxx.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_clangxx.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find clang++
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local clangxx = find_clangxx()
+-- local clangxx, version = find_clangxx({program = "xcrun -sdk macosx clang++", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "clang++", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_curl.lua b/xmake/modules/detect/tools/find_curl.lua
index 3b49247ef..a5ba49e20 100644
--- a/xmake/modules/detect/tool/find_curl.lua
+++ b/xmake/modules/detect/tools/find_curl.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("curl")
+ local program = find_program(opt.program or "curl", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_dmd.lua b/xmake/modules/detect/tools/find_dmd.lua
new file mode 100644
index 000000000..f244c0ad0
--- /dev/null
+++ b/xmake/modules/detect/tools/find_dmd.lua
@@ -0,0 +1,57 @@
+--!The Make-like 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 find_dmd.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find dmd
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local dmd = find_dmd()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "dmd", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "--version", function (output) return output:match("v(%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_doxygen.lua b/xmake/modules/detect/tools/find_doxygen.lua
index 3b3a6bee4..5824c574c 100644
--- a/xmake/modules/detect/tool/find_doxygen.lua
+++ b/xmake/modules/detect/tools/find_doxygen.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("doxygen", { "/usr/bin", "/usr/local/bin"})
+ local program = find_program(opt.program or "doxygen", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_gcc.lua b/xmake/modules/detect/tools/find_gcc.lua
new file mode 100644
index 000000000..d7cbce7d2
--- /dev/null
+++ b/xmake/modules/detect/tools/find_gcc.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_gcc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find gcc
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local gcc = find_gcc()
+-- local gcc, version = find_gcc({program = "xcrun -sdk macosx gcc", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "gcc", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_gccgo.lua b/xmake/modules/detect/tools/find_gccgo.lua
new file mode 100644
index 000000000..a12be3067
--- /dev/null
+++ b/xmake/modules/detect/tools/find_gccgo.lua
@@ -0,0 +1,57 @@
+--!The Make-like 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 find_gogccgo.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find gccgo
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local gccgo = find_gccgo()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "gccgo", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "--version", function (output) return output:match("%s(%d+%.?%d+%.?%d+)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_gdb.lua b/xmake/modules/detect/tools/find_gdb.lua
index ff206288c..3e698022a 100644
--- a/xmake/modules/detect/tool/find_gdb.lua
+++ b/xmake/modules/detect/tools/find_gdb.lua
@@ -46,7 +46,7 @@ function main(opt)
opt = opt or {}
-- find program
- local program = find_program(opt.program or "gdb")
+ local program = find_program(opt.program or "gdb", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_gdc.lua b/xmake/modules/detect/tools/find_gdc.lua
new file mode 100644
index 000000000..a2b2b4c9a
--- /dev/null
+++ b/xmake/modules/detect/tools/find_gdc.lua
@@ -0,0 +1,57 @@
+--!The Make-like 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 find_gdc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find gdc
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local gdc = find_gdc()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "gdc", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "--version", function (output) return output:match("%s(%d+%.?%d+%.?%d+)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_git.lua b/xmake/modules/detect/tools/find_git.lua
index 12f08978d..b21455b0c 100644
--- a/xmake/modules/detect/tool/find_git.lua
+++ b/xmake/modules/detect/tools/find_git.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("git")
+ local program = find_program(opt.program or "git", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_go.lua b/xmake/modules/detect/tools/find_go.lua
new file mode 100644
index 000000000..0b1b9103e
--- /dev/null
+++ b/xmake/modules/detect/tools/find_go.lua
@@ -0,0 +1,57 @@
+--!The Make-like 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 find_go.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find go
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local go = find_go()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "go", opt.pathes, opt.check or "version")
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "version")
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_gxx.lua b/xmake/modules/detect/tools/find_gxx.lua
new file mode 100644
index 000000000..5ab35fa44
--- /dev/null
+++ b/xmake/modules/detect/tools/find_gxx.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_gxx.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find g++
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local gxx = find_gxx()
+-- local gxx, version = find_gxx({program = "xcrun -sdk macosx g++", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "g++", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_gzip.lua b/xmake/modules/detect/tools/find_gzip.lua
index d1b286bba..95d364971 100644
--- a/xmake/modules/detect/tool/find_gzip.lua
+++ b/xmake/modules/detect/tools/find_gzip.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("gzip")
+ local program = find_program(opt.program or "gzip", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_ldc2.lua b/xmake/modules/detect/tools/find_ldc2.lua
new file mode 100644
index 000000000..8b2f42c5d
--- /dev/null
+++ b/xmake/modules/detect/tools/find_ldc2.lua
@@ -0,0 +1,57 @@
+--!The Make-like 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 find_ldc2.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find ldc2
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local ldc2 = find_ldc2()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "ldc2", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "--version", function (output) return output:match("%((%d+%.?%d*%.?%d*.-)%)") end)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tools/find_lib.lua b/xmake/modules/detect/tools/find_lib.lua
new file mode 100644
index 000000000..107c33cbb
--- /dev/null
+++ b/xmake/modules/detect/tools/find_lib.lua
@@ -0,0 +1,77 @@
+--!The Make-like 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 find_lib.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find lib
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local lib = find_lib()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local verinfo = nil
+ local program = find_program(opt.program or "lib.exe", opt.pathes, opt.check or function (program)
+
+ -- make an stub source file
+ local libraryfile = os.tmpfile() .. ".lib"
+ local objectfile = os.tmpfile() .. ".obj"
+ local sourcefile = os.tmpfile() .. ".c"
+ io.writefile(sourcefile, "int test(void)\n{return 0;}")
+
+ -- check it
+ os.run("cl -c -Fo%s %s", objectfile, sourcefile)
+ os.run("link -lib -out:%s %s", libraryfile, objectfile)
+ verinfo = os.iorun("%s -list %s", program, libraryfile)
+
+ -- remove files
+ os.rm(objectfile)
+ os.rm(sourcefile)
+ os.rm(libraryfile)
+ end)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, function () return verinfo end,
+ function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tools/find_link.lua b/xmake/modules/detect/tools/find_link.lua
new file mode 100644
index 000000000..d30fe6fbe
--- /dev/null
+++ b/xmake/modules/detect/tools/find_link.lua
@@ -0,0 +1,78 @@
+--!The Make-like 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 find_link.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find link
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local link = find_link()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local verinfo = nil
+ local program = find_program(opt.program or "link.exe", opt.pathes, opt.check or function (program)
+
+ -- make an stub source file
+ local binaryfile = os.tmpfile() .. ".exe"
+ local objectfile = os.tmpfile() .. ".obj"
+ local sourcefile = os.tmpfile() .. ".c"
+
+ -- main entry
+ io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
+
+ -- check it
+ os.run("cl -c -Fo%s %s", objectfile, sourcefile)
+ verinfo = os.iorun("%s -out:%s %s", program, binaryfile, objectfile)
+
+ -- remove files
+ os.rm(objectfile)
+ os.rm(sourcefile)
+ os.rm(binaryfile)
+ end)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, function () return verinfo end,
+ function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tool/find_lipo.lua b/xmake/modules/detect/tools/find_lipo.lua
index 621bb80d5..27be94c1f 100644
--- a/xmake/modules/detect/tool/find_lipo.lua
+++ b/xmake/modules/detect/tools/find_lipo.lua
@@ -40,6 +40,9 @@ import("lib.detect.find_programver")
--
function main(opt)
+ -- init options
+ opt = opt or {}
+
-- find program
- return find_program("lipo", {}, function (program) os.run("%s -info %s", program, os.programfile()) end)
+ return find_program(opt.program or "lipo", opt.pathes, opt.check or function (program) os.run("%s -info %s", program, os.programfile()) end)
end
diff --git a/xmake/modules/detect/tool/find_lldb.lua b/xmake/modules/detect/tools/find_lldb.lua
index 3c15c2fb1..8a6e86341 100644
--- a/xmake/modules/detect/tool/find_lldb.lua
+++ b/xmake/modules/detect/tools/find_lldb.lua
@@ -46,7 +46,7 @@ function main(opt)
opt = opt or {}
-- find program
- local program = find_program(opt.program or "lldb")
+ local program = find_program(opt.program or "lldb", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_ml.lua b/xmake/modules/detect/tools/find_ml.lua
new file mode 100644
index 000000000..da3f026ac
--- /dev/null
+++ b/xmake/modules/detect/tools/find_ml.lua
@@ -0,0 +1,59 @@
+--!The Make-like 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 find_ml.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find ml
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local ml = find_ml()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "ml.exe", opt.pathes, opt.check or function (program) os.run(program) end)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, function () local _, info = os.iorun(program); return info end,
+ function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tools/find_ml64.lua b/xmake/modules/detect/tools/find_ml64.lua
new file mode 100644
index 000000000..d2377c19e
--- /dev/null
+++ b/xmake/modules/detect/tools/find_ml64.lua
@@ -0,0 +1,59 @@
+--!The Make-like 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 find_ml64.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find ml64
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local ml64 = find_ml64()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "ml64.exe", opt.pathes, opt.check or function (program) os.run(program) end)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, function () local _, info = os.iorun(program); return info end,
+ function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/modules/detect/tool/find_ollydbg.lua b/xmake/modules/detect/tools/find_ollydbg.lua
index 636f52932..636f52932 100644
--- a/xmake/modules/detect/tool/find_ollydbg.lua
+++ b/xmake/modules/detect/tools/find_ollydbg.lua
diff --git a/xmake/modules/detect/tool/find_pkg_config.lua b/xmake/modules/detect/tools/find_pkg_config.lua
index 8bbad9f3f..8bbad9f3f 100644
--- a/xmake/modules/detect/tool/find_pkg_config.lua
+++ b/xmake/modules/detect/tools/find_pkg_config.lua
diff --git a/xmake/modules/detect/tools/find_rc.lua b/xmake/modules/detect/tools/find_rc.lua
new file mode 100644
index 000000000..cbd24e82a
--- /dev/null
+++ b/xmake/modules/detect/tools/find_rc.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_rc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find rc
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local rc = find_rc()
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "rc.exe", opt.pathes, "-?")
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program, "-?", function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end)
+ end
+
+ -- ok?
+ return program, version
+end
+
diff --git a/xmake/tools/gccgo.lua b/xmake/modules/detect/tools/find_rustc.lua
index 1254130d4..d01380d72 100644
--- a/xmake/tools/gccgo.lua
+++ b/xmake/modules/detect/tools/find_rustc.lua
@@ -19,34 +19,39 @@
-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
--
-- @author ruki
--- @file gccgo.lua
+-- @file find_rustc.lua
--
--- inherit gcc
-inherit("gcc")
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
--- init it
-function init(shellname, kind)
-
- -- init super
- _super.init(shellname or "gccgo", kind)
-end
-
--- check the given flags
-function check(flags)
-
- -- make an stub source file
- local objectfile = os.tmpfile() .. ".o"
- local sourcefile = os.tmpfile() .. ".go"
+-- find rustc
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local rustc = find_rustc()
+--
+-- @endcode
+--
+function main(opt)
- -- make stub code
- io.writefile(sourcefile, "package main\nfunc main() {\n}")
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "rustc", opt.pathes, opt.check)
- -- check it
- os.run("%s -c %s -o %s %s", _super._g.shellname, ifelse(flags, flags, ""), objectfile, sourcefile)
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
- -- remove files
- os.rm(objectfile)
- os.rm(sourcefile)
+ -- ok?
+ return program, version
end
-
diff --git a/xmake/modules/detect/tool/find_sudo.lua b/xmake/modules/detect/tools/find_sudo.lua
index 3d0082b17..3306f2fd3 100644
--- a/xmake/modules/detect/tool/find_sudo.lua
+++ b/xmake/modules/detect/tools/find_sudo.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("sudo", {}, "-h")
+ local program = find_program(opt.program or "sudo", opt.pathes, opt.check or "-h")
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/find_swiftc.lua b/xmake/modules/detect/tools/find_swiftc.lua
new file mode 100644
index 000000000..cf9373739
--- /dev/null
+++ b/xmake/modules/detect/tools/find_swiftc.lua
@@ -0,0 +1,58 @@
+--!The Make-like 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 find_swiftc.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+
+-- find swiftc
+--
+-- @param opt the argument options, .e.g {version = true}
+--
+-- @return program, version
+--
+-- @code
+--
+-- local swiftc = find_swiftc()
+-- local swiftc, version = find_swiftc({program = "xcrun -sdk macosx swiftc", version = true})
+--
+-- @endcode
+--
+function main(opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find program
+ local program = find_program(opt.program or "swiftc", opt.pathes, opt.check)
+
+ -- find program version
+ local version = nil
+ if program and opt and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return program, version
+end
diff --git a/xmake/modules/detect/tool/find_tar.lua b/xmake/modules/detect/tools/find_tar.lua
index e091d3204..f37843171 100644
--- a/xmake/modules/detect/tool/find_tar.lua
+++ b/xmake/modules/detect/tools/find_tar.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("tar")
+ local program = find_program(opt.program or "tar", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tool/find_unzip.lua b/xmake/modules/detect/tools/find_unzip.lua
index 19c30f517..c3533cd54 100644
--- a/xmake/modules/detect/tool/find_unzip.lua
+++ b/xmake/modules/detect/tools/find_unzip.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("unzip", {}, "-v")
+ local program = find_program(opt.program or "unzip", opt.pathes, opt.check or "-v")
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tool/find_vsjitdebugger.lua b/xmake/modules/detect/tools/find_vsjitdebugger.lua
index 879fd0a5d..879fd0a5d 100644
--- a/xmake/modules/detect/tool/find_vsjitdebugger.lua
+++ b/xmake/modules/detect/tools/find_vsjitdebugger.lua
diff --git a/xmake/modules/detect/tool/find_wget.lua b/xmake/modules/detect/tools/find_wget.lua
index 59a9c7d63..5f8dd7594 100644
--- a/xmake/modules/detect/tool/find_wget.lua
+++ b/xmake/modules/detect/tools/find_wget.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("wget")
+ local program = find_program(opt.program or "wget", opt.pathes, opt.check)
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tool/find_windbg.lua b/xmake/modules/detect/tools/find_windbg.lua
index 323855d79..323855d79 100644
--- a/xmake/modules/detect/tool/find_windbg.lua
+++ b/xmake/modules/detect/tools/find_windbg.lua
diff --git a/xmake/modules/detect/tool/find_x64dbg.lua b/xmake/modules/detect/tools/find_x64dbg.lua
index 431fea112..431fea112 100644
--- a/xmake/modules/detect/tool/find_x64dbg.lua
+++ b/xmake/modules/detect/tools/find_x64dbg.lua
diff --git a/xmake/modules/detect/tool/find_zip.lua b/xmake/modules/detect/tools/find_zip.lua
index b424d6e99..71405d3ff 100644
--- a/xmake/modules/detect/tool/find_zip.lua
+++ b/xmake/modules/detect/tools/find_zip.lua
@@ -40,9 +40,12 @@ import("lib.detect.find_programver")
-- @endcode
--
function main(opt)
+
+ -- init options
+ opt = opt or {}
-- find program
- local program = find_program("zip", {}, "-v")
+ local program = find_program(opt.program or "zip", opt.pathes, opt.check or "-v")
-- find program version
local version = nil
diff --git a/xmake/modules/detect/tools/gcc/has_flag.lua b/xmake/modules/detect/tools/gcc/has_flag.lua
new file mode 100644
index 000000000..396c460e4
--- /dev/null
+++ b/xmake/modules/detect/tools/gcc/has_flag.lua
@@ -0,0 +1,119 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- is linker?
+function _islinker(flag, opt)
+
+ -- the flag is "-Wl,<arg>" or "-Xlinker <arg>"?
+ if flag:startswith("-Wl,") or flag:startswith("-Xlinker ") then
+ return true
+ end
+
+ -- the tool kind is ld or sh?
+ local toolkind = opt.toolkind or ""
+ return toolkind == "ld" or toolkind == "sh" or toolkind:endswith("-ld") or toolkind:endswith("-sh")
+end
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt, islinker)
+
+ -- only for compiler
+ if islinker then
+ return
+ end
+
+ -- make cache key
+ local key = "detect.tools.gcc.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = os.iorunv(opt.program, {"--help"})
+ if arglist then
+ for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
+ flags[arg] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt, islinker)
+
+ -- check flag for linker
+ if islinker then
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "gcc_has_flag.c")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
+ end
+
+ -- check it
+ return try { function () os.runv(opt.program, {flag, "-o", os.nuldev(), sourcefile}); return true end }
+ end
+
+ -- check flag for compiler
+ return try { function () os.runv(opt.program, {flag, "-S", "-o", os.nuldev(), "-xc", os.nuldev()}); return true end }
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- is linker?
+ local islinker = _islinker(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt, islinker) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt, islinker)
+end
+
diff --git a/xmake/modules/detect/tools/gccgo/has_flag.lua b/xmake/modules/detect/tools/gccgo/has_flag.lua
new file mode 100644
index 000000000..0cb83600e
--- /dev/null
+++ b/xmake/modules/detect/tools/gccgo/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.gcc.has_flag")
+
diff --git a/xmake/modules/detect/tools/gdc/has_flag.lua b/xmake/modules/detect/tools/gdc/has_flag.lua
new file mode 100644
index 000000000..617355673
--- /dev/null
+++ b/xmake/modules/detect/tools/gdc/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.dmd.has_flag")
+
diff --git a/xmake/modules/detect/tools/gxx/has_flag.lua b/xmake/modules/detect/tools/gxx/has_flag.lua
new file mode 100644
index 000000000..0cb83600e
--- /dev/null
+++ b/xmake/modules/detect/tools/gxx/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.gcc.has_flag")
+
diff --git a/xmake/modules/detect/tools/ldc/has_flag.lua b/xmake/modules/detect/tools/ldc/has_flag.lua
new file mode 100644
index 000000000..617355673
--- /dev/null
+++ b/xmake/modules/detect/tools/ldc/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.dmd.has_flag")
+
diff --git a/xmake/modules/detect/tools/link/has_flag.lua b/xmake/modules/detect/tools/link/has_flag.lua
new file mode 100644
index 000000000..008f28912
--- /dev/null
+++ b/xmake/modules/detect/tools/link/has_flag.lua
@@ -0,0 +1,116 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt)
+
+ -- make cache key
+ local key = "detect.tools.link.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = nil
+ try
+ {
+ function () os.runv(opt.program, {"-?"}) end,
+ catch
+ {
+ function (errors) arglist = errors end
+ }
+ }
+ if arglist then
+ for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do
+ flags[arg:gsub("/", "-"):lower()] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag:gsub("/", "-"):lower()]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt)
+
+ -- make an stub source file
+ local winmain = flag:lower():find("subsystem:windows")
+ local sourcefile = path.join(os.tmpdir(), "detect", ifelse(winmain, "winmain_", "") .. "link_has_flag.c")
+ if not os.isfile(sourcefile) then
+ if winmain then
+ io.writefile(sourcefile, "int WinMain(void* instance, void* previnst, char** argv, int argc)\n{return 0;}")
+ else
+ io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}")
+ end
+ end
+
+ -- compile the source file
+ local objectfile = os.tmpfile() .. ".obj"
+ local binaryfile = os.tmpfile() .. ".exe"
+ os.iorunv("cl", {"-c", "-nologo", "-Fo" .. objectfile, sourcefile})
+
+ -- try link it
+ local ok = try { function () os.execv(opt.program, {flag, "-nologo", "-out:" .. binaryfile, objectfile}); return true end }
+
+ -- remove files
+ os.tryrm(objectfile)
+ os.tryrm(binaryfile)
+
+ -- ok?
+ return ok
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt)
+end
+
diff --git a/xmake/modules/detect/tools/ml/has_flag.lua b/xmake/modules/detect/tools/ml/has_flag.lua
new file mode 100644
index 000000000..f41561953
--- /dev/null
+++ b/xmake/modules/detect/tools/ml/has_flag.lua
@@ -0,0 +1,98 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt)
+
+ -- make cache key
+ local key = "detect.tools.ml.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = os.iorunv(opt.program, {"-?"})
+ if arglist then
+ for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do
+ flags[arg:gsub("/", "-")] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag:gsub("/", "-")]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "ml_has_flag.asm")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, ".code\nend")
+ end
+
+ -- check it
+ return try { function ()
+ local _, errors = os.iorunv(opt.program, {"-c", "-nologo", flag, "-Fo" .. os.nuldev(), sourcefile})
+ if errors and #errors:trim() > 0 then
+ return false
+ end
+ return true
+ end
+ }
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt)
+end
+
diff --git a/xmake/modules/detect/tools/ml64/has_flag.lua b/xmake/modules/detect/tools/ml64/has_flag.lua
new file mode 100644
index 000000000..c0086f0e7
--- /dev/null
+++ b/xmake/modules/detect/tools/ml64/has_flag.lua
@@ -0,0 +1,27 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+inherit("detect.tools.ml.has_flag")
+
diff --git a/xmake/modules/detect/tools/rustc/has_flag.lua b/xmake/modules/detect/tools/rustc/has_flag.lua
new file mode 100644
index 000000000..e5766bba8
--- /dev/null
+++ b/xmake/modules/detect/tools/rustc/has_flag.lua
@@ -0,0 +1,98 @@
+--!The Make-like 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 has_flag.lua
+--
+
+-- imports
+import("lib.detect.cache")
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flag, opt)
+
+ -- make cache key
+ local key = "detect.tools.rustc.has_flag"
+
+ -- make flags key
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+
+ -- load cache
+ local cacheinfo = cache.load(key)
+
+ -- get all flags from argument list
+ local flags = cacheinfo[flagskey]
+ if not flags then
+
+ -- get argument list
+ flags = {}
+ local arglist = os.iorunv(opt.program, {"--help"})
+ if arglist then
+ for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
+ flags[arg] = true
+ end
+ end
+
+ -- save cache
+ cacheinfo[flagskey] = flags
+ cache.save(key, cacheinfo)
+ end
+
+ -- ok?
+ return flags[flag]
+end
+
+-- try running to check flag
+function _check_try_running(flag, opt)
+
+ -- make an stub source file
+ local sourcefile = path.join(os.tmpdir(), "detect", "rustc_has_flag.rs")
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, "fn main() {\n}")
+ end
+
+ -- check it
+ local objectfile = os.tmpfile() .. ".o"
+ local ok = try { function () os.runv(opt.program, {"--emit", "obj", flag, "-o", objectfile, sourcefile}); return true end }
+
+ -- remove files
+ os.tryrm(objectfile)
+
+ -- ok?
+ return ok
+end
+
+-- has_flag(flag)?
+--
+-- @param opt the argument options, .e.g {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flag, opt)
+
+ -- attempt to check it from the argument list
+ if _check_from_arglist(flag, opt) then
+ return true
+ end
+
+ -- try running to check it
+ return _check_try_running(flag, opt)
+end
+
diff --git a/xmake/modules/devel/debugger/run.lua b/xmake/modules/devel/debugger/run.lua
index a94f7852f..1b71caafe 100644
--- a/xmake/modules/devel/debugger/run.lua
+++ b/xmake/modules/devel/debugger/run.lua
@@ -25,12 +25,12 @@
-- imports
import("core.base.option")
import("core.project.config")
-import("detect.tool.find_gdb")
-import("detect.tool.find_lldb")
-import("detect.tool.find_windbg")
-import("detect.tool.find_x64dbg")
-import("detect.tool.find_ollydbg")
-import("detect.tool.find_vsjitdebugger")
+import("detect.tools.find_gdb")
+import("detect.tools.find_lldb")
+import("detect.tools.find_windbg")
+import("detect.tools.find_x64dbg")
+import("detect.tools.find_ollydbg")
+import("detect.tools.find_vsjitdebugger")
-- run gdb
function _run_gdb(program, argv)
@@ -62,18 +62,18 @@ function _run_lldb(program, argv)
return false
end
- -- attempt to split shellname, .e.g xcrun -sdk macosx lldb
- local shellnames = lldb:split("%s")
+ -- attempt to split name, .e.g xcrun -sdk macosx lldb
+ local names = lldb:split("%s")
-- patch arguments
argv = argv or {}
table.insert(argv, 1, program)
- for i = #shellnames, 2, -1 do
- table.insert(argv, 1, shellnames[i])
+ for i = #names, 2, -1 do
+ table.insert(argv, 1, names[i])
end
-- run it
- os.execv(shellnames[1], argv)
+ os.execv(names[1], argv)
-- ok
return true
diff --git a/xmake/modules/devel/git/checkout.lua b/xmake/modules/devel/git/checkout.lua
index a69801711..02f6c657e 100644
--- a/xmake/modules/devel/git/checkout.lua
+++ b/xmake/modules/devel/git/checkout.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_git")
+import("detect.tools.find_git")
-- checkout to given branch, tag or commit
--
diff --git a/xmake/modules/devel/git/clean.lua b/xmake/modules/devel/git/clean.lua
index dcc94c805..d6eff80bd 100644
--- a/xmake/modules/devel/git/clean.lua
+++ b/xmake/modules/devel/git/clean.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_git")
+import("detect.tools.find_git")
-- clean files
--
diff --git a/xmake/modules/devel/git/clone.lua b/xmake/modules/devel/git/clone.lua
index c717065b8..9e17a69b0 100644
--- a/xmake/modules/devel/git/clone.lua
+++ b/xmake/modules/devel/git/clone.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_git")
+import("detect.tools.find_git")
-- clone url
--
diff --git a/xmake/modules/devel/git/ls_remote.lua b/xmake/modules/devel/git/ls_remote.lua
index 6ffb77d10..1f41c6e84 100644
--- a/xmake/modules/devel/git/ls_remote.lua
+++ b/xmake/modules/devel/git/ls_remote.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_git")
+import("detect.tools.find_git")
-- ls_remote to given branch, tag or commit
--
diff --git a/xmake/modules/devel/git/pull.lua b/xmake/modules/devel/git/pull.lua
index 5874ae460..504d64ebd 100644
--- a/xmake/modules/devel/git/pull.lua
+++ b/xmake/modules/devel/git/pull.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_git")
+import("detect.tools.find_git")
-- pull remote commits
--
diff --git a/xmake/modules/lib/detect/find_tool.lua b/xmake/modules/lib/detect/find_tool.lua
new file mode 100644
index 000000000..3cc07b071
--- /dev/null
+++ b/xmake/modules/lib/detect/find_tool.lua
@@ -0,0 +1,94 @@
+--!The Make-like 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 find_tool.lua
+--
+
+-- imports
+import("lib.detect.find_program")
+import("lib.detect.find_programver")
+import("lib.detect.find_toolname")
+
+-- find tool from modules
+function _find_from_modules(name, opt)
+
+ -- "detect.tools.find_xxx" exists?
+ if os.isfile(path.join(os.programdir(), "modules", "detect", "tools", "find_" .. name .. ".lua")) then
+ local find_tool = import("detect.tools.find_" .. name)
+ if find_tool then
+ local program, version = find_tool(opt)
+ return {name = name, program = program, version = version}
+ end
+ end
+end
+
+-- find tool
+--
+-- @param name the tool name
+-- @param opt the options, .e.g {program = "xcrun -sdk macosx clang", pathes = {"/usr/bin"}, check = function (tool) os.run("%s -h", tool) end, version = true}
+--
+-- @return {name = "", program = "", version = ""}
+--
+-- @code
+--
+-- local tool = find_tool("clang")
+-- local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"})
+-- local tool = find_tool("clang", {pathes = {"/usr/bin", "/usr/local/bin"}})
+-- local tool = find_tool("clang", {check= "--help"}) -- simple check command: ccache --help
+-- local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end})
+-- local tool = find_tool("clang", {pathes = {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}})
+-- local tool = find_tool("clang", {pathes = {"$(env PATH)", function () return "/usr/bin"end}})
+-- local tool = find_tool("ccache", {version = true})
+--
+-- @endcode
+--
+function main(name, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- find tool name
+ local toolname = find_toolname(name or opt.program)
+ if not toolname then
+ return
+ end
+
+ -- init program
+ opt.program = opt.program or name
+
+ -- attempt to find tool from modules first
+ local tool = _find_from_modules(toolname, opt)
+ if tool then
+ return tool
+ end
+
+ -- find tool
+ local program = find_program(opt.program, opt.pathes, opt.check)
+
+ -- find tool version
+ local version = nil
+ if program and opt.version then
+ version = find_programver(program)
+ end
+
+ -- ok?
+ return {name = toolname, program = program, version = version}
+end
diff --git a/xmake/modules/lib/detect/find_toolname.lua b/xmake/modules/lib/detect/find_toolname.lua
new file mode 100644
index 000000000..ce3b4f1f1
--- /dev/null
+++ b/xmake/modules/lib/detect/find_toolname.lua
@@ -0,0 +1,107 @@
+--!The Make-like 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 find_toolname.lua
+--
+
+-- find tool name from the given program
+function _find(program)
+
+ -- get tool directory
+ local tooldir = path.join(os.programdir(), "modules", "detect", "tools")
+
+ -- attempt to find it directly first
+ if os.isfile(path.join(tooldir, "find_" .. program .. ".lua")) then
+ return program
+ end
+
+ -- get file name first
+ name = path.filename(program):lower()
+
+ -- remove arguments: " -xxx" or " --xxx"
+ name = name:gsub("%s%-+%w+", " ")
+
+ -- get the last name by ' ': xxx xxx toolname
+ local names = name:split("%s")
+ if #names > 0 then
+ name = names[#names]
+ end
+
+ -- remove suffix: ".xxx"
+ name = name:gsub("%.%w+", "")
+
+ -- find_toolname.lua exists? found
+ local toolname = name:gsub("[%+%-]", function (ch) return ifelse(ch == "+", "x", "_") end)
+ if os.isfile(path.join(tooldir, "find_" .. toolname .. ".lua")) then
+ return toolname
+ end
+
+ -- get the last valid name: xxx-xxx-toolname-5
+ local partnames = {}
+ for partname in name:gmatch("([%a%+]+)") do
+ table.insert(partnames, partname)
+ end
+ if #partnames > 0 then
+ name = partnames[#partnames]
+ end
+
+ -- find_toolname.lua exists? found
+ toolname = name:gsub("%+", "x")
+ if os.isfile(path.join(tooldir, "find_" .. toolname .. ".lua")) then
+ return toolname
+ end
+end
+
+-- find tool name
+--
+-- .e.g
+-- "xcrun -sdk macosx clang": clang
+-- "/usr/bin/arm-linux-gcc": gcc
+-- "link.exe -lib": link
+-- "gcc-5": gcc
+-- "arm-android-clang++": clangxx
+-- "pkg-config": pkg_config
+--
+-- @param program the program path or name
+--
+-- @return the tool name
+--
+function main(program)
+
+ -- init cache
+ local toolnames = _g._TOOLNAMES or {}
+
+ -- get it from the cache first
+ local toolname = toolnames[program]
+ if toolname ~= nil then
+ return ifelse(toolname, toolname, nil)
+ end
+
+ -- find the tool name
+ toolname = _find(program)
+
+ -- save result to cache
+ toolnames[program] = ifelse(toolname, toolname, false)
+ _g._TOOLNAMES = toolnames
+
+ -- found?
+ return toolname
+end
diff --git a/xmake/modules/lib/detect/has_cxsnippets.lua b/xmake/modules/lib/detect/has_cxsnippets.lua
new file mode 100644
index 000000000..59ef12872
--- /dev/null
+++ b/xmake/modules/lib/detect/has_cxsnippets.lua
@@ -0,0 +1,227 @@
+--!The Make-like 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 has_csnippets.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.tool.linker")
+import("core.tool.compiler")
+import("core.language.language")
+
+-- get function name
+--
+-- sigsetjmp
+-- sigsetjmp((void*)0, 0)
+-- sigsetjmp{sigsetjmp((void*)0, 0);}
+-- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
+--
+function _funcname(funcinfo)
+
+ -- parse function name
+ local name = string.match(funcinfo, "(.+){.+}")
+ if name == nil then
+ local pos = funcinfo:find("%(")
+ if pos then
+ name = funcinfo:sub(1, pos - 1)
+ else
+ name = funcinfo
+ end
+ end
+
+ -- ok
+ return name:trim()
+end
+
+-- get function code
+--
+-- sigsetjmp
+-- sigsetjmp((void*)0, 0)
+-- sigsetjmp{sigsetjmp((void*)0, 0);}
+-- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
+--
+function _funccode(funcinfo)
+
+ -- parse function code
+ local code = string.match(funcinfo, ".+{(.+)}")
+ if code == nil then
+ local pos = funcinfo:find("%(")
+ if pos then
+ code = funcinfo
+ else
+ code = string.format("volatile void* p%s = (void*)&%s;", funcinfo, funcinfo)
+ end
+ end
+
+ -- ok
+ return code
+end
+
+-- make source code
+function _sourcecode(snippets, opt)
+
+ -- add includes
+ local sourcecode = ""
+ for _, include in ipairs(opt.includes) do
+ sourcecode = format("%s\n#include <%s>", sourcecode, include)
+ end
+ sourcecode = sourcecode .. "\n"
+
+ -- add types
+ for _, typename in ipairs(opt.types) do
+ sourcecode = format("%s\ntypedef %s __type_%s;", sourcecode, typename, typename:gsub("[^%a]", "_"))
+ end
+ sourcecode = sourcecode .. "\n"
+
+ -- add snippets
+ for _, snippet in ipairs(snippets) do
+ sourcecode = sourcecode .. "\n" .. snippet
+ end
+ sourcecode = sourcecode .. "\n"
+
+ -- enter main function
+ sourcecode = sourcecode .. "int main(int argc, char** argv)\n{\n"
+
+ -- add funcs
+ for _, funcinfo in ipairs(opt.funcs) do
+ sourcecode = format("%s\n %s;", sourcecode, _funccode(funcinfo))
+ end
+
+ -- leave main function
+ sourcecode = sourcecode .. "\n return 0;\n}\n"
+
+ -- done
+ return sourcecode
+end
+
+-- has the given c snippets?
+--
+-- @param snippets the snippets
+-- @param opt the argument options
+-- .e.g
+-- { verbose = false, target = [target|option], sourcekind = "[cc|cxx]"
+-- , types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}}
+--
+-- funcs:
+-- sigsetjmp
+-- sigsetjmp((void*)0, 0)
+-- sigsetjmp{sigsetjmp((void*)0, 0);}
+-- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
+--
+-- @return true or false
+--
+-- @code
+-- local ok = has_csnippets("void test() {}")
+-- local ok = has_csnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"})
+-- @endcode
+--
+function main(snippets, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- init snippets
+ snippets = snippets or {}
+
+ -- get links
+ local links = table.wrap(opt.links)
+ if opt.target then
+ table.join2(links, opt.target:get("links"))
+ end
+
+ -- get types
+ local types = table.wrap(opt.types)
+
+ -- get includes
+ local includes = table.wrap(opt.includes)
+
+ -- get funcs
+ local funcs = {}
+ for _, funcinfo in ipairs(opt.funcs) do
+ table.insert(funcs, _funcname(funcinfo))
+ end
+
+ -- make source code
+ local sourcecode = _sourcecode(snippets, opt)
+
+ -- get c/c++ extension
+ local extension = ".c"
+ if opt.sourcekind then
+ extension = table.wrap(language.sourcekinds()[opt.sourcekind])[1] or ".c"
+ end
+
+ -- make the source file
+ local sourcefile = os.tmpfile() .. extension
+ local objectfile = os.tmpfile() .. ".o"
+ local binaryfile = os.tmpfile() .. ".b"
+ io.writefile(sourcefile, sourcecode)
+
+ -- @note cannot cache result, all conditions will be changed
+ -- attempt to compile it
+ local ok = try
+ {
+ function ()
+ compiler.compile(sourcefile, objectfile, opt)
+ if #links > 0 then
+ linker.link("binary", {"cc", "cxx"}, objectfile, binaryfile, opt)
+ end
+ return true
+ end,
+ catch
+ {
+ function (errors)
+ if option.get("verbose") then
+ cprint("${red}%s", errors)
+ end
+ end
+ }
+ }
+
+ -- remove some files
+ os.tryrm(sourcefile)
+ os.tryrm(objectfile)
+ os.tryrm(binaryfile)
+
+ -- trace
+ if opt.verbose or option.get("verbose") then
+ local kind = ifelse(sourcekind == "cc", "c", "c++")
+ if #includes > 0 then
+ cprint("checking for the %s includes %s ... %s", kind, table.concat(includes, ", "), ifelse(ok, "${green}ok", "${red}no"))
+ end
+ if #types > 0 then
+ cprint("checking for the %s types %s ... %s", kind, table.concat(types, ", "), ifelse(ok, "${green}ok", "${red}no"))
+ end
+ if #funcs > 0 then
+ cprint("checking for the %s funcs %s ... %s", kind, table.concat(funcs, ", "), ifelse(ok, "${green}ok", "${red}no"))
+ end
+ if #links > 0 then
+ cprint("checking for the %s links %s ... %s", kind, table.concat(links, ", "), ifelse(ok, "${green}ok", "${red}no"))
+ end
+ for _, snippet in ipairs(snippets) do
+ cprint("checking for the %s snippet %s ... %s", kind, snippet:sub(1, 16), ifelse(ok, "${green}ok", "${red}no"))
+ end
+ end
+
+ -- ok?
+ return ok
+end
+
diff --git a/xmake/modules/lib/detect/has_flags.lua b/xmake/modules/lib/detect/has_flags.lua
new file mode 100644
index 000000000..f307fc40f
--- /dev/null
+++ b/xmake/modules/lib/detect/has_flags.lua
@@ -0,0 +1,115 @@
+--!The Make-like 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 has_flags.lua
+--
+
+-- imports
+import("core.base.option")
+import("lib.detect.find_tool")
+
+-- has this flag?
+function _has_flag(name, flag, opt)
+
+ -- find tool program and version first
+ opt.version = true
+ local tool = find_tool(name, opt)
+ if not tool then
+ return false
+ end
+
+ -- init tool
+ opt.toolname = tool.name
+ opt.program = tool.program
+ opt.programver = tool.version
+
+ -- init cache and key
+ local key = tool.program .. "_" .. (tool.version or "") .. "_" .. (opt.toolkind or "") .. "_" .. flag
+ _g._RESULTS = _g._RESULTS or {}
+ local results = _g._RESULTS
+
+ -- @note avoid detect the same program in the same time if running in the coroutine (.e.g ccache)
+ local coroutine_running = coroutine.running()
+ if coroutine_running then
+ while _g._checking ~= nil and _g._checking == key do
+ coroutine.yield()
+ end
+ end
+
+ -- get result from the cache first
+ local result = results[key]
+ if result ~= nil then
+ return result
+ end
+
+ -- detect.tools.xxx.has_flag(flag, opt)?
+ _g._checking = ifelse(coroutine_running, key, nil)
+ if os.isfile(path.join(os.programdir(), "modules", "detect", "tools", tool.name, "has_flag.lua")) then
+ local hasflag = import("detect.tools." .. tool.name .. ".has_flag")
+ if hasflag then
+ result = hasflag(flag, opt)
+ end
+ else
+ result = try { function () os.runv(tool.program, {flag}); return true end }
+ end
+ _g._checking = nil
+
+ -- trace
+ if option.get("verbose") or opt.verbose then
+ cprint("checking for the flags(%s) %s ... %s", path.filename(tool.program), flag, ifelse(result, "${green}ok", "${red}no"))
+ end
+
+ -- save result to cache
+ results[key] = ifelse(result, result, false)
+
+ -- ok?
+ return result
+end
+
+-- has the given flags for the current tool?
+--
+-- @param name the tool name
+-- @param flags the flags
+-- @param opt the argument options, .e.g {verbose = false, program = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+-- @code
+-- local ok = has_flags("clang", "-g")
+-- local ok = has_flags("clang", {"-g", "-O0"}, {program = "xcrun -sdk macosx clang"})
+-- local ok = has_flags("clang", "-g", {toolkind = "cxx"})
+-- @endcode
+--
+function main(name, flags, opt)
+
+ -- init options
+ opt = opt or {}
+
+ -- has all flags?
+ for _, flag in ipairs(flags) do
+ if not _has_flag(name, flag, opt) then
+ return false
+ end
+ end
+
+ -- ok
+ return true
+end
diff --git a/xmake/modules/lib/detect/pkg_config.lua b/xmake/modules/lib/detect/pkg_config.lua
new file mode 100644
index 000000000..322977dbd
--- /dev/null
+++ b/xmake/modules/lib/detect/pkg_config.lua
@@ -0,0 +1,183 @@
+--!The Make-like 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 pkg_config.lua
+--
+
+-- imports
+import("lib.detect.find_library")
+import("detect.tools.find_brew")
+import("detect.tools.find_pkg_config")
+
+-- get package info
+--
+-- @param name the package name
+-- @param opt the argument options, {version = true, configdirs = {"/xxxx/pkgconfig/"}}
+--
+-- @return {links = {"ssl", "crypto", "z"}, linkdirs = {""}, includedirs = {""}, version = ""}
+--
+-- @code
+--
+-- local pkginfo = pkg_config.info("openssl")
+--
+-- @endcode
+--
+function info(name, opt)
+
+ -- attempt to add search pathes from pkg-config
+ local pkg_config = find_pkg_config()
+ if not pkg_config then
+ return
+ end
+
+ -- init options and cache
+ opt = opt or {}
+ _g._INFO = _g._INFO or {}
+
+ -- get it from cache first
+ local result = _g._INFO[name]
+ if result then
+ return result
+ end
+
+ -- get pkg-config path from brew
+ local brew = find_brew()
+ local configdirs = opt.configdirs or {}
+ if brew then
+ local prefix = try { function () return os.iorunv(brew, {"--prefix", name}) end }
+ if prefix then
+ prefix = path.join(prefix:trim(), "lib", "pkgconfig")
+ if os.isdir(prefix) then
+ table.insert(configdirs, prefix)
+ end
+ end
+ end
+
+ -- add PKG_CONFIG_PATH
+ local configdirs_old = nil
+ if #configdirs > 0 then
+ configdirs_old = os.getenv("PKG_CONFIG_PATH")
+ os.addenv("PKG_CONFIG_PATH", unpack(configdirs))
+ end
+
+ -- get libs and cflags
+ local flags = try { function () return os.iorunv(pkg_config, {"--libs", "--cflags", name}) end }
+ if flags then
+
+ -- init result
+ result = {}
+ for _, flag in ipairs(flags:split('%s*')) do
+
+ -- get links
+ local link = flag:match("%-l(.*)")
+ if link then
+ result.links = result.links or {}
+ table.insert(result.links, link)
+ end
+
+ -- get linkdirs
+ local linkdirs = nil
+ local linkdir = flag:match("%-L(.*)")
+ if linkdir and os.isdir(linkdir) then
+ result.linkdirs = result.linkdirs or {}
+ table.insert(result.linkdirs, linkdir)
+ end
+
+ -- get includedirs
+ local includedirs = nil
+ local includedir = flag:match("%-I(.*)")
+ if includedir and os.isdir(includedir) then
+ result.includedirs = result.includedirs or {}
+ table.insert(result.includedirs, includedir)
+ end
+ end
+ end
+
+ -- get version
+ if opt.version then
+
+ -- get version
+ local version = try { function() return os.iorunv(pkg_config, {"--modversion", name}) end }
+ if version then
+ result = result or {}
+ result.version = version:trim()
+ end
+ end
+
+ -- restore PKG_CONFIG_PATH
+ if configdirs_old then
+ os.setenv("PKG_CONFIG_PATH", configdirs_old)
+ end
+
+ -- save result to cache
+ _g._INFO[name] = result
+
+ -- ok?
+ return result
+end
+
+-- find package
+--
+-- @param name the package name
+-- @param opt the argument options, {plat = "", arch = "", version = "1.0.1"}
+--
+-- @return {links = {"ssl", "crypto", "z"}, linkdirs = {""}, includedirs = {""}}
+--
+-- @code
+--
+-- local pkginfo = pkg_config.find("openssl")
+--
+-- @endcode
+--
+function find(name, opt)
+
+ -- get package info
+ local pkginfo = info(name, opt)
+ if not pkginfo then
+ return
+ end
+
+ -- match version?
+ opt = opt or {}
+ if opt.version and pkginfo.version ~= opt.version then
+ return
+ end
+
+ -- find library
+ local result = nil
+ for _, link in ipairs(table.wrap(pkginfo.links)) do
+ local libinfo = find_library(link, pkginfo.linkdirs)
+ if libinfo then
+ result = result or {}
+ result.links = table.join(result.links or {}, libinfo.link)
+ result.linkdirs = table.join(result.linkdirs or {}, libinfo.linkdir)
+ end
+ end
+
+ -- found?
+ if result and result.links then
+ result.linkdirs = table.unique(result.linkdirs)
+ result.includedirs = table.join(result.includedirs or {}, pkginfo.includedirs)
+ end
+
+ -- ok?
+ return result
+end
diff --git a/xmake/modules/net/http/download.lua b/xmake/modules/net/http/download.lua
index 66e211578..e5cc6c14d 100644
--- a/xmake/modules/net/http/download.lua
+++ b/xmake/modules/net/http/download.lua
@@ -24,8 +24,8 @@
-- imports
import("core.base.option")
-import("detect.tool.find_curl")
-import("detect.tool.find_wget")
+import("detect.tools.find_curl")
+import("detect.tools.find_wget")
-- download url using curl
function _curl_download(program, url, outputfile)
diff --git a/xmake/modules/privilege/sudo.lua b/xmake/modules/privilege/sudo.lua
index 4eb5f6538..0a8816098 100644
--- a/xmake/modules/privilege/sudo.lua
+++ b/xmake/modules/privilege/sudo.lua
@@ -24,9 +24,9 @@
-- imports
import("core.base.option")
-import("detect.tool.find_sudo")
+import("detect.tools.find_sudo")
--- sudo run shell with administrator permission
+-- sudo run command with administrator permission
--
-- .e.g
-- _sudo(os.run, "echo", "hello xmake!")
@@ -34,8 +34,8 @@ import("detect.tool.find_sudo")
function _sudo(runner, cmd, ...)
-- find sudo
- local program = find_sudo()
- assert(program, "sudo not found!")
+ local sudo = find_sudo()
+ assert(sudo, "sudo not found!")
-- get current path environment
local pathenv = os.getenv("PATH")
@@ -45,26 +45,26 @@ function _sudo(runner, cmd, ...)
pathenv = pathenv:gsub("\"", "\\\"")
-- run it with administrator permission and preserve parent environment
- runner(program .. " env PATH=\"" .. pathenv .. "\" " .. cmd, ...)
+ runner(sudo .. " env PATH=\"" .. pathenv .. "\" " .. cmd, ...)
else
-- run it with administrator permission
- runner(program .. " " .. cmd, ...)
+ runner(sudo .. " " .. cmd, ...)
end
end
--- sudo run shell with administrator permission and arguments list
+-- sudo run command with administrator permission and arguments list
--
-- .e.g
-- _sudov(os.runv, {"echo", "hello xmake!"})
--
-function _sudov(runner, shellname, argv)
+function _sudov(runner, program, argv)
-- find sudo
- local program = find_sudo()
- assert(program, "sudo not found!")
+ local sudo = find_sudo()
+ assert(sudo, "sudo not found!")
-- run it with administrator permission and preserve parent environment
- runner(program, table.join("env", "PATH=" .. os.getenv("PATH"), shellname, argv))
+ runner(sudo, table.join("env", "PATH=" .. os.getenv("PATH"), program, argv))
end
-- sudo run lua script with administrator permission and arguments list
@@ -94,44 +94,44 @@ function has()
return find_sudo() ~= nil
end
--- sudo run shell
+-- sudo run command
function run(cmd, ...)
return _sudo(os.run, cmd, ...)
end
--- sudo run shell with arguments list
-function runv(shellname, argv)
- return _sudov(os.run, shellname, argv)
+-- sudo run command with arguments list
+function runv(program, argv)
+ return _sudov(os.run, program, argv)
end
--- sudo quietly run shell and echo verbose info if [-v|--verbose] option is enabled
+-- sudo quietly run command and echo verbose info if [-v|--verbose] option is enabled
function vrun(cmd, ...)
return _sudo(os.vrun, cmd, ...)
end
--- sudo quietly run shell with arguments list and echo verbose info if [-v|--verbose] option is enabled
-function vrunv(shellname, argv)
- return _sudov(os.vrunv, shellname, argv)
+-- sudo quietly run command with arguments list and echo verbose info if [-v|--verbose] option is enabled
+function vrunv(program, argv)
+ return _sudov(os.vrunv, program, argv)
end
--- sudo run shell and return output and error data
+-- sudo run command and return output and error data
function iorun(cmd, ...)
return _sudo(os.iorun, cmd, ...)
end
--- sudo run shell and return output and error data
-function iorunv(shellname, argv)
- return _sudov(os.iorunv, shellname, argv)
+-- sudo run command and return output and error data
+function iorunv(program, argv)
+ return _sudov(os.iorunv, program, argv)
end
--- sudo execute shell
+-- sudo execute command
function exec(cmd, ...)
return _sudo(os.exec, cmd, ...)
end
--- sudo execute shell with arguments list
-function execv(shellname, argv)
- return _sudov(os.execv, shellname, argv)
+-- sudo execute command with arguments list
+function execv(program, argv)
+ return _sudov(os.execv, program, argv)
end
-- sudo run lua script
diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua
index e350ff636..4672c2442 100644
--- a/xmake/modules/utils/archive/extract.lua
+++ b/xmake/modules/utils/archive/extract.lua
@@ -25,10 +25,10 @@
-- imports
import("core.base.option")
import("lib.detect.find_file")
-import("detect.tool.find_7z")
-import("detect.tool.find_tar")
-import("detect.tool.find_gzip")
-import("detect.tool.find_unzip")
+import("detect.tools.find_7z")
+import("detect.tools.find_tar")
+import("detect.tools.find_gzip")
+import("detect.tools.find_unzip")
-- extract archivefile using tar
function _extract_using_tar(archivefile, outputdir, extension)
diff --git a/xmake/platforms/android/check.lua b/xmake/platforms/android/check.lua
index cb8b15e21..4d70c5001 100644
--- a/xmake/platforms/android/check.lua
+++ b/xmake/platforms/android/check.lua
@@ -24,8 +24,8 @@
-- imports
import(".checker")
-import("detect.sdk.find_ndk_sdkvers")
-import("detect.sdk.find_ndk_toolchains")
+import("detect.sdks.find_ndk_sdkvers")
+import("detect.sdks.find_ndk_toolchains")
-- check the sdk version for ndk
function _check_ndk_sdkver(config)
diff --git a/xmake/platforms/checker.lua b/xmake/platforms/checker.lua
index 870b51053..bf6e60b8c 100644
--- a/xmake/platforms/checker.lua
+++ b/xmake/platforms/checker.lua
@@ -23,92 +23,52 @@
--
-- imports
-import("core.tool.tool")
import("core.base.option")
-import("detect.sdk.find_xcode_dir")
-import("detect.sdk.find_xcode_sdkvers")
+import("detect.sdks.find_xcode_dir")
+import("detect.sdks.find_xcode_sdkvers")
+import("lib.detect.find_tool")
-- find the given tool
function _toolchain_check(config, toolkind, toolinfo)
- -- get the tool path
- local toolpath = config.get(toolkind)
- if not toolpath then
+ -- get the program
+ local program = config.get(toolkind)
+ if not program then
- -- get name
- local name = toolinfo.name
-
- -- get cross
- local cross = config.get("cross") or toolinfo.cross
-
- -- get shell name from the env if not cross-compilation
- if cross and cross:trim() == "" then
- local shellname = os.getenv(toolkind:upper():split('-')[1])
- if shellname and shellname:trim() ~= "" then
- toolpath = tool.check(shellname)
- end
+ -- get name and attempt to get `$(env XX)`
+ local name = vformat(toolinfo.name)
+ if #name == 0 then
+ return
end
- -- check it using the custom script
- if not toolpath and toolinfo.check then
-
- -- check it
- try
- {
- function ()
-
- -- check it
- toolinfo.check(cross .. name)
-
- -- ok
- toolpath = cross .. name
- end
- }
- end
+ -- get cross
+ local cross = config.get("cross") or toolinfo.cross or ""
- -- get toolchains
- local toolchains = config.get("toolchains")
- if not toolchains then
- local sdkdir = config.get("sdk")
- if sdkdir then
- toolchains = path.join(sdkdir, "bin")
+ -- attempt to check it
+ if not program then
+ local tool = find_tool(name, {program = cross .. name, pathes = config.get("toolchains"), check = toolinfo.check})
+ if tool then
+ program = tool.program
end
end
- -- attempt to check it from the given cross toolchains
- if not toolpath and toolchains then
- toolpath = tool.check(cross .. name, toolchains)
- end
-
- -- attempt to check it with cross prefix
- if not toolpath then
- toolpath = tool.check(cross .. name)
- end
-
- -- attempt to check it without cross prefix
- if not toolpath then
- toolpath = tool.check(name)
- end
-
-- check ok?
- if toolpath then
-
- -- update config
- config.set(toolkind, toolpath)
+ if program then
+ config.set(toolkind, program)
end
-- trace
if option.get("verbose") then
- if toolpath then
- cprint("checking for %s (%s) ... ${green}%s", toolinfo.description, toolkind, path.filename(toolpath))
+ if program then
+ cprint("checking for %s (%s) ... ${green}%s", toolinfo.description, toolkind, path.filename(program))
else
cprint("checking for %s (%s: ${red}%s${clear}) ... ${red}no", toolinfo.description, toolkind, name)
end
end
end
- -- get tool path
- return toolpath
+ -- ok?
+ return program
end
-- check all for the given config kind
diff --git a/xmake/platforms/iphoneos/check.lua b/xmake/platforms/iphoneos/check.lua
index b3fa9b728..a12a53801 100644
--- a/xmake/platforms/iphoneos/check.lua
+++ b/xmake/platforms/iphoneos/check.lua
@@ -25,20 +25,6 @@
-- imports
import(".checker")
--- check the as
-function _check_as(shellname)
-
- -- make an empty tmp.S
- local tmpfile = os.tmpfile() .. ".S"
- io.writefile(tmpfile, "")
-
- -- check it
- os.run("%s -arch armv7 -o %s -c %s", shellname, os.nuldev(), tmpfile)
-
- -- remove this tmp.S
- os.rm(tmpfile)
-end
-
-- get toolchains
function _toolchains(config)
@@ -82,7 +68,7 @@ function _toolchains(config)
if simulator then
checker.toolchain_insert(toolchains, "as", cross, "clang", "the assember")
else
- checker.toolchain_insert(toolchains, "as", path.join(os.toolsdir(), "utils/gas-preprocessor.pl " .. cross), "clang", "the assember", _check_as)
+ checker.toolchain_insert(toolchains, "as", path.join(os.programdir(), "scripts", "gas-preprocessor.pl " .. cross), "clang", "the assember")
end
-- save toolchains
diff --git a/xmake/platforms/linux/check.lua b/xmake/platforms/linux/check.lua
index 82e7737cc..c3751b644 100644
--- a/xmake/platforms/linux/check.lua
+++ b/xmake/platforms/linux/check.lua
@@ -23,7 +23,7 @@
--
-- imports
-import("detect.sdk.find_cross_toolchains")
+import("detect.sdks.find_cross_toolchains")
import(".checker")
-- check the architecture
@@ -63,63 +63,87 @@ function _toolchains(config)
-- init toolchains
local toolchains = {}
+ -- inset tools from environment variables if not cross-compilation
+ if #cross == 0 then
+ checker.toolchain_insert(toolchains, "cc", "", "$(env CC)", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", "", "$(env CXX)", "the linker")
+ checker.toolchain_insert(toolchains, "ld", "", "$(env LD)", "the linker")
+ checker.toolchain_insert(toolchains, "ld", "", "$(env CXX)", "the linker")
+ checker.toolchain_insert(toolchains, "ar", "", "$(env AR)", "the static library archiver")
+ checker.toolchain_insert(toolchains, "sh", "", "$(env SH)", "the shared library linker")
+ checker.toolchain_insert(toolchains, "mm", "", "$(env MM)", "the objc compiler")
+ checker.toolchain_insert(toolchains, "mxx", "", "$(env MXX)", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "as", "", "$(env AS)", "the assember")
+ end
+
-- insert c/c++ tools to toolchains
- checker.toolchain_insert(toolchains, "cc", cross, "gcc", "the c compiler")
- checker.toolchain_insert(toolchains, "cc", cross, "clang", "the c compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "gcc", "the c++ compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "clang", "the c++ compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "g++", "the c++ compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "clang++", "the c++ compiler")
- checker.toolchain_insert(toolchains, "ld", cross, "g++", "the linker")
- checker.toolchain_insert(toolchains, "ld", cross, "gcc", "the linker")
- checker.toolchain_insert(toolchains, "ld", cross, "clang++", "the linker")
- checker.toolchain_insert(toolchains, "ld", cross, "clang", "the linker")
- checker.toolchain_insert(toolchains, "ar", cross, "ar", "the static library archiver")
- checker.toolchain_insert(toolchains, "ex", cross, "ar", "the static library extractor")
- checker.toolchain_insert(toolchains, "sh", cross, "g++", "the shared library linker")
- checker.toolchain_insert(toolchains, "sh", cross, "gcc", "the shared library linker")
- checker.toolchain_insert(toolchains, "sh", cross, "clang++", "the shared library linker")
- checker.toolchain_insert(toolchains, "sh", cross, "clang", "the shared library linker")
+ checker.toolchain_insert(toolchains, "cc", cross, "gcc", "the c compiler")
+ checker.toolchain_insert(toolchains, "cc", cross, "clang", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "gcc", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "clang", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "g++", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "clang++", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "ld", cross, "g++", "the linker")
+ checker.toolchain_insert(toolchains, "ld", cross, "gcc", "the linker")
+ checker.toolchain_insert(toolchains, "ld", cross, "clang++", "the linker")
+ checker.toolchain_insert(toolchains, "ld", cross, "clang", "the linker")
+ checker.toolchain_insert(toolchains, "ar", cross, "ar", "the static library archiver")
+ checker.toolchain_insert(toolchains, "ex", cross, "ar", "the static library extractor")
+ checker.toolchain_insert(toolchains, "sh", cross, "g++", "the shared library linker")
+ checker.toolchain_insert(toolchains, "sh", cross, "gcc", "the shared library linker")
+ checker.toolchain_insert(toolchains, "sh", cross, "clang++", "the shared library linker")
+ checker.toolchain_insert(toolchains, "sh", cross, "clang", "the shared library linker")
-- insert objc/c++ tools to toolchains
- checker.toolchain_insert(toolchains, "mm", cross, "clang", "the objc compiler")
- checker.toolchain_insert(toolchains, "mm", cross, "gcc", "the objc compiler")
- checker.toolchain_insert(toolchains, "mxx", cross, "clang++", "the objc++ compiler")
- checker.toolchain_insert(toolchains, "mxx", cross, "clang", "the objc++ compiler")
- checker.toolchain_insert(toolchains, "mxx", cross, "g++", "the objc++ compiler")
- checker.toolchain_insert(toolchains, "mxx", cross, "gcc", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mm", cross, "clang", "the objc compiler")
+ checker.toolchain_insert(toolchains, "mm", cross, "gcc", "the objc compiler")
+ checker.toolchain_insert(toolchains, "mxx", cross, "clang++", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mxx", cross, "clang", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mxx", cross, "g++", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mxx", cross, "gcc", "the objc++ compiler")
-- insert asm tools to toolchains
- checker.toolchain_insert(toolchains, "as", cross, "clang", "the assember")
- checker.toolchain_insert(toolchains, "as", cross, "gcc", "the assember")
+ checker.toolchain_insert(toolchains, "as", cross, "clang", "the assember")
+ checker.toolchain_insert(toolchains, "as", cross, "gcc", "the assember")
-- insert golang tools to toolchains
- checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
- checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc", "", "$(env GC)", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "$(env GC)", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "$(env GC)", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
-- insert dlang tools to toolchains
- checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc", "", "$(env DC)", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "$(env Dc)", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "$(env DC)", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "$(env DC)", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
-- insert rust tools to toolchains
- checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
- checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
- checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
- checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
+ checker.toolchain_insert(toolchains, "rc", "", "$(env RC)", "the rust compiler")
+ checker.toolchain_insert(toolchains, "rc-ar", "", "$(env RC)", "the rust static library archiver")
+ checker.toolchain_insert(toolchains, "rc-sh", "", "$(env RC)", "the rust shared library linker")
+ checker.toolchain_insert(toolchains, "rc-ld", "", "$(env RC)", "the rust linker")
+ checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
+ checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
+ checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
+ checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
-- save toolchains
_g.TOOLCHAINS = toolchains
diff --git a/xmake/platforms/macosx/check.lua b/xmake/platforms/macosx/check.lua
index 56d4e48c6..833087684 100644
--- a/xmake/platforms/macosx/check.lua
+++ b/xmake/platforms/macosx/check.lua
@@ -37,56 +37,79 @@ function _toolchains(config)
local toolchains = {}
-- insert c/c++ tools to toolchains
- checker.toolchain_insert(toolchains, "cc", "xcrun -sdk macosx ", "clang", "the c compiler")
- checker.toolchain_insert(toolchains, "cxx", "xcrun -sdk macosx ", "clang", "the c++ compiler")
- checker.toolchain_insert(toolchains, "cxx", "xcrun -sdk macosx ", "clang++", "the c++ compiler")
- checker.toolchain_insert(toolchains, "ld", "xcrun -sdk macosx ", "clang++", "the linker")
- checker.toolchain_insert(toolchains, "ld", "xcrun -sdk macosx ", "clang", "the linker")
- checker.toolchain_insert(toolchains, "ar", "xcrun -sdk macosx ", "ar", "the static library archiver")
- checker.toolchain_insert(toolchains, "ex", "xcrun -sdk macosx ", "ar", "the static library extractor")
- checker.toolchain_insert(toolchains, "sh", "xcrun -sdk macosx ", "clang++", "the shared library linker")
- checker.toolchain_insert(toolchains, "sh", "xcrun -sdk macosx ", "clang", "the shared library linker")
+ checker.toolchain_insert(toolchains, "cc", "", "$(env CC)", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", "", "$(env CXX)", "the linker")
+ checker.toolchain_insert(toolchains, "ld", "", "$(env LD)", "the linker")
+ checker.toolchain_insert(toolchains, "ld", "", "$(env CXX)", "the linker")
+ checker.toolchain_insert(toolchains, "ar", "", "$(env AR)", "the static library archiver")
+ checker.toolchain_insert(toolchains, "sh", "", "$(env SH)", "the shared library linker")
+ checker.toolchain_insert(toolchains, "cc", "xcrun -sdk macosx ", "clang", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", "xcrun -sdk macosx ", "clang", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "cxx", "xcrun -sdk macosx ", "clang++", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "ld", "xcrun -sdk macosx ", "clang++", "the linker")
+ checker.toolchain_insert(toolchains, "ld", "xcrun -sdk macosx ", "clang", "the linker")
+ checker.toolchain_insert(toolchains, "ar", "xcrun -sdk macosx ", "ar", "the static library archiver")
+ checker.toolchain_insert(toolchains, "ex", "xcrun -sdk macosx ", "ar", "the static library extractor")
+ checker.toolchain_insert(toolchains, "sh", "xcrun -sdk macosx ", "clang++", "the shared library linker")
+ checker.toolchain_insert(toolchains, "sh", "xcrun -sdk macosx ", "clang", "the shared library linker")
-- insert objc/c++ tools to toolchains
- checker.toolchain_insert(toolchains, "mm", "xcrun -sdk macosx ", "clang", "the objc compiler")
- checker.toolchain_insert(toolchains, "mxx", "xcrun -sdk macosx ", "clang++", "the objc++ compiler")
- checker.toolchain_insert(toolchains, "mxx", "xcrun -sdk macosx ", "clang", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mm", "", "$(env MM)", "the objc compiler")
+ checker.toolchain_insert(toolchains, "mxx", "", "$(env MXX)", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mm", "xcrun -sdk macosx ", "clang", "the objc compiler")
+ checker.toolchain_insert(toolchains, "mxx", "xcrun -sdk macosx ", "clang++", "the objc++ compiler")
+ checker.toolchain_insert(toolchains, "mxx", "xcrun -sdk macosx ", "clang", "the objc++ compiler")
-- insert asm tools to toolchains
- checker.toolchain_insert(toolchains, "as", "xcrun -sdk macosx ", "clang", "the assember")
+ checker.toolchain_insert(toolchains, "as", "", "$(env AS)", "the assember")
+ checker.toolchain_insert(toolchains, "as", "xcrun -sdk macosx ", "clang", "the assember")
-- insert swift tools to toolchains
- checker.toolchain_insert(toolchains, "sc", "xcrun -sdk macosx ", "swiftc", "the swift compiler")
- checker.toolchain_insert(toolchains, "sc-ld", "xcrun -sdk macosx ", "swiftc", "the swift linker")
- checker.toolchain_insert(toolchains, "sc-sh", "xcrun -sdk macosx ", "swiftc", "the swift shared library linker")
+ checker.toolchain_insert(toolchains, "sc", "", "$(env SC)", "the swift compiler")
+ checker.toolchain_insert(toolchains, "sc-ld", "", "$(env SC)", "the swift linker")
+ checker.toolchain_insert(toolchains, "sc-sh", "", "$(env SC)", "the swift shared library linker")
+ checker.toolchain_insert(toolchains, "sc", "xcrun -sdk macosx ", "swiftc", "the swift compiler")
+ checker.toolchain_insert(toolchains, "sc-ld", "xcrun -sdk macosx ", "swiftc", "the swift linker")
+ checker.toolchain_insert(toolchains, "sc-sh", "xcrun -sdk macosx ", "swiftc", "the swift shared library linker")
-- insert golang tools to toolchains
- checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
- checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc", "", "$(env GC)", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "$(env GC)", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "$(env GC)", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
-- insert dlang tools to toolchains
- checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc", "", "$(env DC)", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "$(env Dc)", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "$(env DC)", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "$(env DC)", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
-- insert rust tools to toolchains
- checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
- checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
- checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
- checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
+ checker.toolchain_insert(toolchains, "rc", "", "$(env RC)", "the rust compiler")
+ checker.toolchain_insert(toolchains, "rc-ar", "", "$(env RC)", "the rust static library archiver")
+ checker.toolchain_insert(toolchains, "rc-sh", "", "$(env RC)", "the rust shared library linker")
+ checker.toolchain_insert(toolchains, "rc-ld", "", "$(env RC)", "the rust linker")
+ checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
+ checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
+ checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
+ checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
-- save toolchains
_g.TOOLCHAINS = toolchains
diff --git a/xmake/platforms/mingw/check.lua b/xmake/platforms/mingw/check.lua
index 887aa43db..f3f8872db 100644
--- a/xmake/platforms/mingw/check.lua
+++ b/xmake/platforms/mingw/check.lua
@@ -23,7 +23,7 @@
--
-- imports
-import("detect.sdk.find_cross_toolchains")
+import("detect.sdks.find_cross_toolchains")
import(".checker")
-- get toolchains
@@ -53,16 +53,16 @@ function _toolchains(config)
-- make toolchains
local toolchains = {}
- checker.toolchain_insert(toolchains, "cc", cross, "gcc", "the c compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "g++", "the c++ compiler")
- checker.toolchain_insert(toolchains, "cxx", cross, "gcc", "the c++ compiler")
- checker.toolchain_insert(toolchains, "as", cross, "gcc", "the assember")
- checker.toolchain_insert(toolchains, "ld", cross, "g++", "the linker")
- checker.toolchain_insert(toolchains, "ld", cross, "gcc", "the linker")
- checker.toolchain_insert(toolchains, "ar", cross, "ar", "the static library archiver")
- checker.toolchain_insert(toolchains, "ex", cross, "ar", "the static library extractor")
- checker.toolchain_insert(toolchains, "sh", cross, "g++", "the shared library linker")
- checker.toolchain_insert(toolchains, "sh", cross, "gcc", "the shared library linker")
+ checker.toolchain_insert(toolchains, "cc", cross, "gcc", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "g++", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "cxx", cross, "gcc", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "as", cross, "gcc", "the assember")
+ checker.toolchain_insert(toolchains, "ld", cross, "g++", "the linker")
+ checker.toolchain_insert(toolchains, "ld", cross, "gcc", "the linker")
+ checker.toolchain_insert(toolchains, "ar", cross, "ar", "the static library archiver")
+ checker.toolchain_insert(toolchains, "ex", cross, "ar", "the static library extractor")
+ checker.toolchain_insert(toolchains, "sh", cross, "g++", "the shared library linker")
+ checker.toolchain_insert(toolchains, "sh", cross, "gcc", "the shared library linker")
-- save toolchains
_g.TOOLCHAINS = toolchains
diff --git a/xmake/platforms/watchos/check.lua b/xmake/platforms/watchos/check.lua
index c6ce73e21..60a923fa8 100644
--- a/xmake/platforms/watchos/check.lua
+++ b/xmake/platforms/watchos/check.lua
@@ -25,20 +25,6 @@
-- imports
import(".checker")
--- check the as
-function _check_as(shellname)
-
- -- make an empty tmp.S
- local tmpfile = os.tmpfile() .. ".S"
- io.writefile(tmpfile, "")
-
- -- check it
- os.run("%s -arch armv7 -o %s -c %s", shellname, os.nuldev(), tmpfile)
-
- -- remove this tmp.S
- os.rm(tmpfile)
-end
-
-- get toolchains
function _toolchains(config)
@@ -82,7 +68,7 @@ function _toolchains(config)
if simulator then
checker.toolchain_insert(toolchains, "as", cross, "clang", "the assember")
else
- checker.toolchain_insert(toolchains, "as", path.join(os.toolsdir(), "utils/gas-preprocessor.pl " .. cross), "clang", "the assember", _check_as)
+ checker.toolchain_insert(toolchains, "as", path.join(os.programdir(), "scripts", "gas-preprocessor.pl " .. cross), "clang", "the assember")
end
-- save toolchains
diff --git a/xmake/platforms/windows/check.lua b/xmake/platforms/windows/check.lua
index 8218ffd3a..7bcb96326 100644
--- a/xmake/platforms/windows/check.lua
+++ b/xmake/platforms/windows/check.lua
@@ -23,11 +23,11 @@
--
-- imports
-import("core.tool.tool")
-import("core.base.option")
-import("platforms.checker", {rootdir = os.programdir()})
+import(".checker")
import("environment")
-import("detect.sdk.find_vstudio")
+import("core.base.option")
+import("detect.sdks.find_vstudio")
+import("lib.detect.find_tool")
-- attempt to check vs environment
function _check_vsenv(config)
@@ -65,11 +65,15 @@ function _check_vsenv(config)
-- check compiler
environment.enter("toolchains")
- local toolpath = tool.check("cl.exe")
+ local program = nil
+ local tool = find_tool("cl.exe")
+ if tool then
+ program = tool.program
+ end
environment.leave("toolchains")
-- ok?
- if toolpath then
+ if program then
return vsver
end
end
@@ -119,47 +123,47 @@ function _toolchains(config)
local toolchains = {}
-- insert c/c++ tools to toolchains
- checker.toolchain_insert(toolchains, "cc", "", "cl.exe", "the c compiler")
- checker.toolchain_insert(toolchains, "cxx", "", "cl.exe", "the c++ compiler")
- checker.toolchain_insert(toolchains, "mrc", "", "rc.exe", "the resource compiler")
- checker.toolchain_insert(toolchains, "ld", "", "link.exe", "the linker")
- checker.toolchain_insert(toolchains, "ar", "", "link.exe -lib", "the static library archiver")
- checker.toolchain_insert(toolchains, "sh", "", "link.exe -dll", "the shared library linker")
- checker.toolchain_insert(toolchains, "ex", "", "lib.exe", "the static library extractor")
+ checker.toolchain_insert(toolchains, "cc", "", "cl.exe", "the c compiler")
+ checker.toolchain_insert(toolchains, "cxx", "", "cl.exe", "the c++ compiler")
+ checker.toolchain_insert(toolchains, "mrc", "", "rc.exe", "the resource compiler")
+ checker.toolchain_insert(toolchains, "ld", "", "link.exe", "the linker")
+ checker.toolchain_insert(toolchains, "ar", "", "link.exe -lib", "the static library archiver")
+ checker.toolchain_insert(toolchains, "sh", "", "link.exe -dll", "the shared library linker")
+ checker.toolchain_insert(toolchains, "ex", "", "lib.exe", "the static library extractor")
-- insert golang tools to toolchains
- checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
- checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
- checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
- checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc", "", "go", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc", "", "gccgo", "the golang compiler")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "go", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ar", "", "gccgo", "the golang static library archiver")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "go", "the golang linker")
+ checker.toolchain_insert(toolchains, "gc-ld", "", "gccgo", "the golang linker")
-- insert dlang tools to toolchains
- checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
- checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
- checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
- checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc", "", "dmd", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "ldc2", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc", "", "gdc", "the dlang compiler")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "dmd", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "ldc2", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-ar", "", "gdc", "the dlang static library archiver")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "dmd", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "ldc2", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-sh", "", "gdc", "the dlang shared library linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "dmd", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "ldc2", "the dlang linker")
+ checker.toolchain_insert(toolchains, "dc-ld", "", "gdc", "the dlang linker")
-- insert rust tools to toolchains
- checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
- checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
- checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
- checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
+ checker.toolchain_insert(toolchains, "rc", "", "rustc", "the rust compiler")
+ checker.toolchain_insert(toolchains, "rc-ar", "", "rustc", "the rust static library archiver")
+ checker.toolchain_insert(toolchains, "rc-sh", "", "rustc", "the rust shared library linker")
+ checker.toolchain_insert(toolchains, "rc-ld", "", "rustc", "the rust linker")
-- insert asm tools to toolchains
if config.get("arch"):find("64") then
- checker.toolchain_insert(toolchains, "as", "", "ml64.exe", "the assember")
+ checker.toolchain_insert(toolchains, "as", "", "ml64.exe", "the assember")
else
- checker.toolchain_insert(toolchains, "as", "", "ml.exe", "the assember")
+ checker.toolchain_insert(toolchains, "as", "", "ml.exe", "the assember")
end
-- save toolchains
diff --git a/xmake/plugins/app2ipa/main.lua b/xmake/plugins/app2ipa/main.lua
index 7fba742dc..f03657b70 100644
--- a/xmake/plugins/app2ipa/main.lua
+++ b/xmake/plugins/app2ipa/main.lua
@@ -24,7 +24,7 @@
-- imports
import("core.base.option")
-import("detect.tool.find_zip")
+import("detect.tools.find_zip")
-- main
function main()
diff --git a/xmake/plugins/doxygen/main.lua b/xmake/plugins/doxygen/main.lua
index 7129c7306..c13327959 100644
--- a/xmake/plugins/doxygen/main.lua
+++ b/xmake/plugins/doxygen/main.lua
@@ -26,7 +26,7 @@
import("core.base.option")
import("core.project.config")
import("core.project.project")
-import("detect.tool.find_doxygen")
+import("detect.tools.find_doxygen")
-- main
function main()
diff --git a/xmake/plugins/lua/scripts/lipo.lua b/xmake/plugins/lua/scripts/lipo.lua
index 8b87eb9e0..5c0ce510d 100644
--- a/xmake/plugins/lua/scripts/lipo.lua
+++ b/xmake/plugins/lua/scripts/lipo.lua
@@ -23,7 +23,7 @@
--
-- imports
-import("detect.tool.find_lipo")
+import("detect.tools.find_lipo")
-- main
--
diff --git a/xmake/plugins/macro/main.lua b/xmake/plugins/macro/main.lua
index 1fbd26207..59510fc89 100644
--- a/xmake/plugins/macro/main.lua
+++ b/xmake/plugins/macro/main.lua
@@ -24,9 +24,9 @@
-- imports
import("core.base.option")
-import("core.project.cache")
+import("core.project.cache", {nocache = true})
import("core.project.config")
-import("core.project.history")
+import("core.project.history", {nocache = true})
-- the macro directories
function _directories()
diff --git a/xmake/plugins/project/makefile/makefile.lua b/xmake/plugins/project/makefile/makefile.lua
index 2df00a4a9..e09b4edc1 100644
--- a/xmake/plugins/project/makefile/makefile.lua
+++ b/xmake/plugins/project/makefile/makefile.lua
@@ -23,11 +23,11 @@
--
-- imports
-import("core.tool.tool")
import("core.tool.compiler")
import("core.project.config")
import("core.project.project")
import("core.language.language")
+import("core.platform.platform")
-- get log makefile
function _logfile()
@@ -99,14 +99,14 @@ function _make_object(makefile, target, sourcefile, objectfile)
return _make_object_for_static(makefile, target, sourcefile, objectfile)
end
- -- get shellname name
- local shellname = tool.shellname(sourcekind)
+ -- get program
+ local program = platform.tool(sourcekind)
-- get complier flags
- local compflags = compiler.compflags(sourcefile, target, sourcekind)
+ local compflags = compiler.compflags(sourcefile, {target = target, sourcekind = sourcekind})
-- make command
- local command = compiler.compcmd(sourcefile, objectfile, target)
+ local command = compiler.compcmd(sourcefile, objectfile, {target = target})
-- replace compflags to $(XX)
local p, e = command:find(compflags, 1, true)
@@ -114,8 +114,8 @@ function _make_object(makefile, target, sourcefile, objectfile)
command = format("%s$(%s_%s)%s", command:sub(1, p - 1), target:name(), sourcekind:upper(), command:sub(e + 1))
end
- -- replace shellname to $(XX)
- p, e = command:find(shellname, 1, true)
+ -- replace program to $(XX)
+ p, e = command:find(program, 1, true)
if p then
command = format("%s$(%s)%s", command:sub(1, p - 1), sourcekind:upper(), command:sub(e + 1))
end
@@ -160,14 +160,14 @@ function _make_single_object(makefile, target, sourcekind, sourcebatch)
local objectfiles = sourcebatch.objectfiles
local incdepfiles = sourcebatch.incdepfiles
- -- get shellname name
- local shellname = tool.shellname(sourcekind)
+ -- get program
+ local program = platform.tool(sourcekind)
-- get complier flags
- local compflags = compiler.compflags(sourcefiles, target, sourcekind)
+ local compflags = compiler.compflags(sourcefiles, {target = target, sourcekind = sourcekind})
-- make command
- local command = compiler.compcmd(sourcefiles, objectfiles, target, sourcekind)
+ local command = compiler.compcmd(sourcefiles, objectfiles, {target = target, sourcekind = sourcekind})
-- replace compflags to $(XX)
local p, e = command:find(compflags, 1, true)
@@ -175,8 +175,8 @@ function _make_single_object(makefile, target, sourcekind, sourcebatch)
command = format("%s$(%s_%s)%s", command:sub(1, p - 1), target:name(), sourcekind:upper(), command:sub(e + 1))
end
- -- replace shellname to $(XX)
- p, e = command:find(shellname, 1, true)
+ -- replace program to $(XX)
+ p, e = command:find(program, 1, true)
if p then
command = format("%s$(%s)%s", command:sub(1, p - 1), sourcekind:upper(), command:sub(e + 1))
end
@@ -248,10 +248,10 @@ function _make_target(makefile, target)
makefile:print("")
-- get linker kind
- local linkerkind = target:linker():get("kind")
+ local linkerkind = target:linker():kind()
- -- get shellname
- local shellname = tool.shellname(linkerkind)
+ -- get program
+ local program = platform.tool(linkerkind)
-- get command
local command = target:linkcmd()
@@ -262,8 +262,8 @@ function _make_target(makefile, target)
command = format("%s$(%s_%s)%s", command:sub(1, p - 1), target:name(), (linkerkind:upper():gsub('%-', '_')), command:sub(e + 1))
end
- -- replace shellname to $(XX)
- p, e = command:find(shellname, 1, true)
+ -- replace program to $(XX)
+ p, e = command:find(program, 1, true)
if p then
command = format("%s$(%s)%s", command:sub(1, p - 1), (linkerkind:upper():gsub('%-', '_')), command:sub(e + 1))
end
@@ -322,9 +322,9 @@ function _make_all(makefile)
-- make variables for source kinds
for sourcekind, _ in pairs(language.sourcekinds()) do
- local shellname = tool.shellname(sourcekind)
- if shellname and shellname ~= "" then
- makefile:print("%s=%s", sourcekind:upper(), shellname)
+ local program = platform.tool(sourcekind)
+ if program and program ~= "" then
+ makefile:print("%s=%s", sourcekind:upper(), program)
end
end
makefile:print("")
@@ -335,9 +335,9 @@ function _make_all(makefile)
table.join2(linkerkinds, _linkerkinds)
end
for _, linkerkind in ipairs(table.unique(linkerkinds)) do
- local shellname = tool.shellname(linkerkind)
- if shellname and shellname ~= "" then
- makefile:print("%s=%s", (linkerkind:upper():gsub('%-', '_')), shellname)
+ local program = platform.tool(linkerkind)
+ if program and program ~= "" then
+ makefile:print("%s=%s", (linkerkind:upper():gsub('%-', '_')), program)
end
end
makefile:print("")
@@ -346,9 +346,9 @@ function _make_all(makefile)
for targetname, target in pairs(project.targets()) do
if not target:isphony() then
for sourcekind, sourcebatch in pairs(target:sourcebatches()) do
- makefile:print("%s_%s=%s", targetname, sourcekind:upper(), compiler.compflags(sourcebatch.sourcefiles, target, sourcekind))
+ makefile:print("%s_%s=%s", targetname, sourcekind:upper(), compiler.compflags(sourcebatch.sourcefiles, {target = target, sourcekind = sourcekind}))
end
- makefile:print("%s_%s=%s", targetname, target:linker():get("kind"):upper(), target:linkflags())
+ makefile:print("%s_%s=%s", targetname, target:linker():kind():upper(), target:linkflags())
end
end
makefile:print("")
diff --git a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
index 094b7a166..3fe67bf45 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
@@ -32,7 +32,7 @@ import("vsfile")
function _make_compflags(sourcefile, target, vcprojdir)
-- make the compiling flags
- local _, compflags = compiler.compflags(sourcefile, target)
+ local _, compflags = compiler.compflags(sourcefile, {target = target})
-- replace -Idir or /Idir, -Fdsymbol.pdb or /Fdsymbol.pdb
local flags = {}
@@ -74,7 +74,7 @@ end
function _make_linkflags(target, vcprojdir)
-- make the linking flags
- local _, linkflags = linker.linkflags(target)
+ local _, linkflags = linker.linkflags(target:get("kind"), target:sourcekinds(), {target = target})
-- replace -libpath:dir or /libpath:dir, -pdb:symbol.pdb or /pdb:symbol.pdb
local flags = {}
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index 29b004030..566c45470 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -32,6 +32,7 @@ import("core.tool.linker")
import("vs201x_solution")
import("vs201x_vcxproj")
import("vs201x_vcxproj_filters")
+import("actions.config.configheader", {rootdir = os.programdir()})
-- make target info
function _make_targetinfo(mode, arch, target)
@@ -39,30 +40,93 @@ function _make_targetinfo(mode, arch, target)
-- init target info
local targetinfo = { mode = mode, arch = ifelse(arch == "x86", "Win32", "x64") }
+ -- get sdk version
+ local vcvarsall = config.get("__vcvarsall")
+ if vcvarsall then
+ targetinfo.sdkver = (vcvarsall[arch] or {}).sdkver
+ end
+
-- save symbols
targetinfo.symbols = target:get("symbols")
-- save target kind
targetinfo.targetkind = target:targetkind()
+ -- save target file
+ targetinfo.targetfile = target:targetfile()
+
+ -- save symbol file
+ targetinfo.symbolfile = target:symbolfile()
+
-- save sourcebatches
targetinfo.sourcebatches = target:sourcebatches()
-- save compiler flags
targetinfo.compflags = {}
for _, sourcefile in ipairs(target:sourcefiles()) do
- local _, compflags = compiler.compflags(sourcefile, target)
+ local _, compflags = compiler.compflags(sourcefile, {target = target})
targetinfo.compflags[sourcefile] = compflags
end
-- save linker flags
- local _, linkflags = linker.linkflags(target)
+ local _, linkflags = linker.linkflags(target:get("kind"), target:sourcekinds(), {target = target})
targetinfo.linkflags = linkflags
-- ok
return targetinfo
end
+-- make target headers
+function _make_targetheaders(mode, arch, target, last)
+
+ -- only for static and shared target
+ local kind = target:get("kind")
+ if kind == "static" or kind == "shared" then
+
+ -- 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
+ os.cp(srcheader, dstheader)
+ end
+ i = i + 1
+ end
+ end
+
+ -- make config header
+ local configheader_raw = target:configheader()
+ if configheader_raw and os.isfile(configheader_raw) then
+
+ -- init the config header path for each mode and arch
+ local configheader_mode_arch = path.join(path.directory(configheader_raw), mode .. "." .. arch .. "." .. path.filename(configheader_raw))
+
+ -- init the temporary config header path
+ local configheader_tmp = path.join(path.directory(configheader_raw), "tmp." .. path.filename(configheader_raw))
+
+ -- copy the original config header first
+ os.cp(configheader_raw, configheader_mode_arch)
+
+ -- append the current config header
+ local file = io.open(configheader_tmp, "a+")
+ if file then
+ file:print("")
+ file:print("#if defined(__config_%s__) && defined(__config_%s__)", mode, arch)
+ file:print("# include \"%s.%s.%s\"", mode, arch, path.filename(configheader_raw))
+ file:print("#endif")
+ file:close()
+ end
+
+ -- override the raw config header at last
+ if last and os.isfile(configheader_tmp) then
+ os.mv(configheader_tmp, configheader_raw)
+ end
+ end
+ end
+end
+
-- make vstudio project
function make(outputdir, vsinfo)
@@ -88,8 +152,11 @@ function make(outputdir, vsinfo)
-- load targets
local targets = {}
- for _, mode in ipairs(vsinfo.modes) do
- for _, arch in ipairs({"x86", "x64"}) do
+ for mode_idx, mode in ipairs(vsinfo.modes) do
+ for arch_idx, arch in ipairs({"x86", "x64"}) do
+
+ -- trace
+ print("checking for the %s.%s ...", mode, arch)
-- reload config, project and platform
if mode ~= config.mode() or arch ~= config.arch() then
@@ -106,6 +173,9 @@ function make(outputdir, vsinfo)
-- reload project
project.load()
+
+ -- remake configheader
+ configheader.make()
end
-- ensure to enter project directory
@@ -129,6 +199,9 @@ function make(outputdir, vsinfo)
-- save all sourcefiles and headerfiles
_target.sourcefiles = table.unique(table.join(_target.sourcefiles or {}, (target:sourcefiles())))
_target.headerfiles = table.unique(table.join(_target.headerfiles or {}, (target:headerfiles())))
+
+ -- make target headers
+ _make_targetheaders(mode, arch, target, mode_idx == #vsinfo.modes and arch_idx == 2)
end
end
end
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
index 320c4813c..2972e5562 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
@@ -55,6 +55,10 @@ function _make_compflags(sourcefile, targetinfo, vcxprojdir)
table.insert(flags, flag)
end
+ -- add -D__config_$(mode)__ and -D__config_$(arch)__ for the config header
+ table.insert(flags, "-D__config_" .. targetinfo.mode .. "__")
+ table.insert(flags, "-D__config_" .. targetinfo.arch .. "__")
+
-- ok?
return flags
end
@@ -62,7 +66,7 @@ end
-- make linking flags
function _make_linkflags(targetinfo, vcxprojdir)
- -- replace -libpath:dir or /libpath:dir, -pdb:symbol.pdb or /pdb:symbol.pdb
+ -- replace -libpath:dir or /libpath:dir
local flags = {}
for _, flag in ipairs(targetinfo.linkflags) do
@@ -75,15 +79,6 @@ function _make_linkflags(targetinfo, vcxprojdir)
return "/libpath:" .. dir
end)
- -- replace -pdb:symbol.pdb or /pdb:symbol.pdb
- flag = flag:gsub("[%-|/]pdb:(.*)", function (dir)
- dir = dir:trim()
- if not path.is_absolute(dir) then
- dir = path.relative(path.absolute(dir), vcxprojdir)
- end
- return "/pdb:" .. dir
- end)
-
-- save flag
table.insert(flags, flag)
end
@@ -142,13 +137,22 @@ function _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
, vs2017 = "141"
}
- -- the sdk version
+ -- the default sdk version
local sdk_versions =
{
vs2015 = "10.0.10240.0"
, vs2017 = "10.0.14393.0"
}
+ -- get sdk version
+ local sdkver = nil
+ for _, targetinfo in ipairs(target.info) do
+ sdkver = targetinfo.sdkver
+ if sdkver then
+ break
+ end
+ end
+
-- make ProjectConfigurations
vcxprojfile:enter("<ItemGroup Label=\"ProjectConfigurations\">")
for _, targetinfo in ipairs(target.info) do
@@ -164,7 +168,7 @@ function _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
vcxprojfile:print("<ProjectGuid>{%s}</ProjectGuid>", os.uuid(targetname))
vcxprojfile:print("<RootNamespace>%s</RootNamespace>", targetname)
if vsinfo.vstudio_version >= "2015" then
- vcxprojfile:print("<WindowsTargetPlatformVersion>%s</WindowsTargetPlatformVersion>", sdk_versions["vs" .. vsinfo.vstudio_version])
+ vcxprojfile:print("<WindowsTargetPlatformVersion>%s</WindowsTargetPlatformVersion>", sdkver or sdk_versions["vs" .. vsinfo.vstudio_version])
end
vcxprojfile:leave("</PropertyGroup>")
@@ -202,6 +206,10 @@ function _make_configurations(vcxprojfile, vsinfo, target, vcxprojdir)
vcxprojfile:enter("<PropertyGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">", targetinfo.mode, targetinfo.arch)
vcxprojfile:print("<OutDir>%s\\</OutDir>", path.relative(path.absolute(config.get("buildir")), vcxprojdir))
vcxprojfile:print("<IntDir>%$(Configuration)\\</IntDir>")
+ vcxprojfile:print("<TargetName>%s</TargetName>", path.basename(targetinfo.targetfile))
+ vcxprojfile:print("<TargetExt>%s</TargetExt>", path.extension(targetinfo.targetfile))
+ vcxprojfile:print("<TargetPath>%s</TargetPath>", path.relative(path.absolute(targetinfo.targetfile), vcxprojdir))
+
if target.kind == "binary" then
vcxprojfile:print("<LinkIncremental>true</LinkIncremental>")
end
@@ -298,17 +306,36 @@ function _make_common_item(vcxprojfile, vsinfo, targetinfo, vcxprojdir)
-- enter ItemDefinitionGroup
vcxprojfile:enter("<ItemDefinitionGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">", targetinfo.mode, targetinfo.arch)
+ -- init the linker kinds
+ local linkerkinds =
+ {
+ binary = "Link"
+ , static = "Lib"
+ , shared = "Link"
+ }
+
-- for linker?
- if targetinfo.targetkind == "binary" then
- vcxprojfile:enter("<Link>")
+ vcxprojfile:enter("<%s>", linkerkinds[targetinfo.targetkind])
- -- make linker flags
- local flags = table.concat(_make_linkflags(targetinfo, vcxprojdir), " "):trim()
+ -- make linker flags
+ local flags = table.concat(_make_linkflags(targetinfo, vcxprojdir), " "):trim()
- -- make AdditionalOptions
- vcxprojfile:print("<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>", flags)
+ -- remove "-machine:[x86|x64]"
+ flags = flags:gsub("[%-/]machine:%w+", "")
+
+ -- remove "-pdb:*.pdb"
+ flags = flags:gsub("[%-/]pdb:.+%.pdb", "")
- -- generate debug infomation?
+ -- remove "-debug"
+ flags = flags:gsub("[%-/]debug", "")
+
+ -- make AdditionalOptions
+ vcxprojfile:print("<AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>", flags)
+
+ -- generate debug infomation?
+ if linkerkinds[targetinfo.targetkind] == "Link" then
+
+ -- enable debug infomation?
local debug = false
for _, symbol in ipairs(targetinfo.symbols) do
if symbol == "debug" then
@@ -318,14 +345,25 @@ function _make_common_item(vcxprojfile, vsinfo, targetinfo, vcxprojdir)
end
vcxprojfile:print("<GenerateDebugInformation>%s</GenerateDebugInformation>", tostring(debug))
- -- make SubSystem
+ -- make *.pdb file path
+ local symbolfile = targetinfo.symbolfile
+ if symbolfile then
+ vcxprojfile:print("<ProgramDatabaseFile>%s</ProgramDatabaseFile>", path.relative(path.absolute(symbolfile), vcxprojdir))
+ end
+ end
+
+ -- make SubSystem
+ if targetinfo.targetkind == "binary" then
vcxprojfile:print("<SubSystem>Console</SubSystem>")
-
- -- make TargetMachine
- vcxprojfile:print("<TargetMachine>%s</TargetMachine>", ifelse(targetinfo.arch == "x64", "MachineX64", "MachineX86"))
+ end
+
+ -- make TargetMachine
+ vcxprojfile:print("<TargetMachine>%s</TargetMachine>", ifelse(targetinfo.arch == "x64", "MachineX64", "MachineX86"))
- vcxprojfile:leave("</Link>")
- end
+ -- make OutputFile
+ vcxprojfile:print("<OutputFile>%s</OutputFile>", path.relative(path.absolute(targetinfo.targetfile), vcxprojdir))
+
+ vcxprojfile:leave("</%s>", linkerkinds[targetinfo.targetkind])
-- for compiler?
vcxprojfile:enter("<ClCompile>")
@@ -333,8 +371,11 @@ function _make_common_item(vcxprojfile, vsinfo, targetinfo, vcxprojdir)
-- make source options
_make_source_options(vcxprojfile, targetinfo.commonflags)
- -- make ProgramDataBaseFileName (default: empty)
- vcxprojfile:print("<ProgramDataBaseFileName></ProgramDataBaseFileName>")
+ -- make *.pdb file path
+ local symbolfile = targetinfo.symbolfile
+ if symbolfile then
+ vcxprojfile:print("<ProgramDatabaseFile>%s</ProgramDatabaseFile>", path.relative(path.absolute(symbolfile), vcxprojdir))
+ end
vcxprojfile:leave("</ClCompile>")
diff --git a/xmake/tools/utils/gas-preprocessor.pl b/xmake/scripts/gas-preprocessor.pl
index 98dfe4ad9..7e0857a66 100755
--- a/xmake/tools/utils/gas-preprocessor.pl
+++ b/xmake/scripts/gas-preprocessor.pl
@@ -86,7 +86,7 @@ if (grep /\.c$/, @gcc_cmd) {
} elsif (grep /\.[sS]$/, @gcc_cmd) {
# asm file, just do C preprocessor
@preprocess_c_cmd = (@gcc_cmd, "-E");
-} elsif (grep /-(v|-version|dumpversion)/, @gcc_cmd) {
+} elsif (grep /-(v|-help|-version|dumpversion)/, @gcc_cmd) {
# pass -v/--version along, used during probing. Matching '-v' might have
# uninteded results but it doesn't matter much if gas-preprocessor or
# the compiler fails.