summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-06-18 22:39:36 +0800
committerGitHub <[email protected]>2019-06-18 22:39:36 +0800
commit96bda12356f3d69edae33a31d384d28b1ef74274 (patch)
treefe35918e6ddb0cfdaca7b5333becf9b19c007a38
parentb441b29b947c8d94c0642132383b4a7a67c189c9 (diff)
parent98d4504577b586ef2398346a0db2743081cf03a8 (diff)
Merge pull request #455 from OpportunityLiu/clang-cuda
Support clang as cuda compiler
-rw-r--r--CHANGELOG.md6
-rw-r--r--tests/modules/path/test.lua27
-rw-r--r--tests/projects/cuda/console_2/inc/lib.cuh3
-rw-r--r--tests/projects/cuda/console_2/src/lib.cu7
-rw-r--r--tests/projects/cuda/console_2/src/main.cu127
-rw-r--r--tests/projects/cuda/console_2/xmake.lua19
-rw-r--r--tests/projects/dlang/console/test.lua2
-rw-r--r--tests/projects/dlang/shared_library/test.lua2
-rw-r--r--tests/projects/dlang/static_library/test.lua2
-rw-r--r--tests/projects/go/console/test.lua2
-rw-r--r--tests/projects/go/static_library/test.lua2
-rw-r--r--tests/projects/objc++/console/test.lua2
-rw-r--r--tests/projects/objc/console/test.lua2
-rw-r--r--tests/projects/rust/console/test.lua2
-rw-r--r--tests/projects/rust/static_library/test.lua2
-rw-r--r--tests/projects/swift/console/test.lua2
-rw-r--r--tests/runner.lua20
-rw-r--r--tests/test_utils/context.lua13
-rw-r--r--tests/test_utils/test_assert.lua9
-rw-r--r--tests/test_utils/test_build.lua (renamed from tests/test_utils/build.lua)9
-rw-r--r--tests/test_utils/test_skip.lua13
-rw-r--r--xmake/core/base/path.lua63
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_file.lua36
-rw-r--r--xmake/core/sandbox/modules/import/lib/detect/find_program.lua47
-rw-r--r--xmake/languages/cuda/xmake.lua5
-rw-r--r--xmake/modules/core/tools/clang.lua23
-rw-r--r--xmake/modules/core/tools/nvcc.lua10
-rw-r--r--xmake/modules/detect/sdks/find_cuda.lua1
-rw-r--r--xmake/modules/detect/tools/find_nvcc.lua13
-rw-r--r--xmake/modules/lib/detect/find_cudadevices.lua52
-rw-r--r--xmake/platforms/linux/config.lua6
-rw-r--r--xmake/platforms/macosx/config.lua6
-rw-r--r--xmake/platforms/windows/config.lua6
-rw-r--r--xmake/rules/cuda/devlink/xmake.lua7
-rw-r--r--xmake/rules/cuda/env/xmake.lua5
-rw-r--r--xmake/rules/cuda/gencodes/xmake.lua80
36 files changed, 494 insertions, 139 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46ad3e30b..5311ccee8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### New features
+* [#455](https://github.com/xmake-io/xmake/pull/455): support clang as cuda compiler, try `xmake f --cu=clang`
* [#440](https://github.com/xmake-io/xmake/issues/440): Add `set_rundir()` and `add_runenvs()` api for target/run
* [#443](https://github.com/xmake-io/xmake/pull/443): Add tab completion support
* Add `on_link`, `before_link` and `after_link` for rule and target
@@ -12,7 +13,7 @@
### Changes
* [#430](https://github.com/xmake-io/xmake/pull/430): Add `add_cucodegens()` api to improve set codegen for cuda
-* [#432](https://github.com/xmake-io/xmake/pull/432): support deps analyze for cu file
+* [#432](https://github.com/xmake-io/xmake/pull/432): support deps analyze for cu file (for CUDA 10.1+)
* [#437](https://github.com/xmake-io/xmake/issues/437): Support explict git source for xmake update, `xmake update github:xmake-io/xmake#dev`
* [#438](https://github.com/xmake-io/xmake/pull/438): Support to only update scripts, `xmake update --scriptonly dev`
* [#433](https://github.com/xmake-io/xmake/issues/433): Improve cuda to support device-link
@@ -602,6 +603,7 @@
### 新特性
+* [#455](https://github.com/xmake-io/xmake/pull/455): 支持使用 clang 作为 cuda 编译器,`xmake f --cu=clang`
* [#440](https://github.com/xmake-io/xmake/issues/440): 为target/run添加`set_rundir()`和`add_runenvs()`接口设置
* [#443](https://github.com/xmake-io/xmake/pull/443): 添加命令行tab自动完成支持
* 为rule/target添加`on_link`,`before_link`和`after_link`阶段自定义脚本支持
@@ -610,7 +612,7 @@
### 改进
* [#430](https://github.com/xmake-io/xmake/pull/430): 添加`add_cucodegens()`api为cuda改进设置codegen
-* [#432](https://github.com/xmake-io/xmake/pull/432): 针对cuda编译支持依赖分析检测
+* [#432](https://github.com/xmake-io/xmake/pull/432): 针对cuda编译支持依赖分析检测(仅支持 CUDA 10.1+)
* [#437](https://github.com/xmake-io/xmake/issues/437): 支持指定更新源,`xmake update github:xmake-io/xmake#dev`
* [#438](https://github.com/xmake-io/xmake/pull/438): 支持仅更新脚本,`xmake update --scriptonly dev`
* [#433](https://github.com/xmake-io/xmake/issues/433): 改进cuda构建支持device-link设备代码链接
diff --git a/tests/modules/path/test.lua b/tests/modules/path/test.lua
new file mode 100644
index 000000000..4217dec16
--- /dev/null
+++ b/tests/modules/path/test.lua
@@ -0,0 +1,27 @@
+function test_splitenv_win(t)
+ if not is_host("windows") then
+ return t:skip("wrong host platform")
+ end
+ t:are_equal(path.splitenv(""), {})
+ t:are_equal(path.splitenv("a"), {'a'})
+ t:are_equal(path.splitenv("a;b"), {'a','b'})
+ t:are_equal(path.splitenv(";;a;;b;"), {'a','b'})
+ t:are_equal(path.splitenv('c:/a;c:\\b'), {'c:/a', 'c:\\b'})
+ t:are_equal(path.splitenv('"a;aa;aa;;"'), {"a;aa;aa;;"})
+ t:are_equal(path.splitenv('"a;aa;aa;;";bb;;'), {"a;aa;aa;;", 'bb'})
+ t:are_equal(path.splitenv('"a;aa;aa;;";"a;cc;aa;;";bb;"d";'), {"a;aa;aa;;","a;cc;aa;;", 'bb', 'd' })
+end
+
+function test_splitenv_unix(t)
+ if is_host("windows") then
+ return t:skip("wrong host platform")
+ end
+ t:are_equal(path.splitenv(""), {})
+ t:are_equal(path.splitenv("a"), {'a'})
+ t:are_equal(path.splitenv("a:b"), {'a','b'})
+ t:are_equal(path.splitenv("::a::b:"), {'a','b'})
+ t:are_equal(path.splitenv('a%tag:b'), {'a','b'})
+ t:are_equal(path.splitenv('a%tag:b%tag'), {'a','b'})
+ t:are_equal(path.splitenv('a%tag:b%%tag%%'), {'a','b'})
+ t:are_equal(path.splitenv('a%tag:b:%tag:'), {'a','b'})
+end \ No newline at end of file
diff --git a/tests/projects/cuda/console_2/inc/lib.cuh b/tests/projects/cuda/console_2/inc/lib.cuh
new file mode 100644
index 000000000..35255e31e
--- /dev/null
+++ b/tests/projects/cuda/console_2/inc/lib.cuh
@@ -0,0 +1,3 @@
+#pragma once
+
+__global__ void addKernel(int *c, const int *a, const int *b); \ No newline at end of file
diff --git a/tests/projects/cuda/console_2/src/lib.cu b/tests/projects/cuda/console_2/src/lib.cu
new file mode 100644
index 000000000..a5f054354
--- /dev/null
+++ b/tests/projects/cuda/console_2/src/lib.cu
@@ -0,0 +1,7 @@
+#include <lib.cuh>
+
+__global__ void addKernel(int *c, const int *a, const int *b)
+{
+ int i = threadIdx.x;
+ c[i] = a[i] + b[i];
+} \ No newline at end of file
diff --git a/tests/projects/cuda/console_2/src/main.cu b/tests/projects/cuda/console_2/src/main.cu
new file mode 100644
index 000000000..32844cd56
--- /dev/null
+++ b/tests/projects/cuda/console_2/src/main.cu
@@ -0,0 +1,127 @@
+
+#include "cuda_runtime.h"
+#include "device_launch_parameters.h"
+
+#include <stdio.h>
+#include <lib.cuh>
+
+cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);
+
+int main()
+{
+ const int arraySize = 5;
+ const int a[arraySize] = {1, 2, 3, 4, 5};
+ const int b[arraySize] = {10, 20, 30, 40, 50};
+ int c[arraySize] = {0};
+
+ // Add vectors in parallel.
+ cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize);
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "addWithCuda failed!");
+ return 1;
+ }
+
+ printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n",
+ c[0], c[1], c[2], c[3], c[4]);
+
+ // cudaDeviceReset must be called before exiting in order for profiling and
+ // tracing tools such as Nsight and Visual Profiler to show complete traces.
+ cudaStatus = cudaDeviceReset();
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaDeviceReset failed!");
+ return 1;
+ }
+
+ return 0;
+}
+
+// Helper function for using CUDA to add vectors in parallel.
+cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
+{
+ int *dev_a = 0;
+ int *dev_b = 0;
+ int *dev_c = 0;
+ cudaError_t cudaStatus;
+
+ // Choose which GPU to run on, change this on a multi-GPU system.
+ cudaStatus = cudaSetDevice(0);
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
+ goto Error;
+ }
+
+ // Allocate GPU buffers for three vectors (two input, one output) .
+ cudaStatus = cudaMalloc((void **)&dev_c, size * sizeof(int));
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMalloc failed!");
+ goto Error;
+ }
+
+ cudaStatus = cudaMalloc((void **)&dev_a, size * sizeof(int));
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMalloc failed!");
+ goto Error;
+ }
+
+ cudaStatus = cudaMalloc((void **)&dev_b, size * sizeof(int));
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMalloc failed!");
+ goto Error;
+ }
+
+ // Copy input vectors from host memory to GPU buffers.
+ cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMemcpy failed!");
+ goto Error;
+ }
+
+ cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMemcpy failed!");
+ goto Error;
+ }
+
+ // Launch a kernel on the GPU with one thread for each element.
+ addKernel<<<1, size>>>(dev_c, dev_a, dev_b);
+
+ // Check for any errors launching the kernel
+ cudaStatus = cudaGetLastError();
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
+ goto Error;
+ }
+
+ // cudaDeviceSynchronize waits for the kernel to finish, and returns
+ // any errors encountered during the launch.
+ cudaStatus = cudaDeviceSynchronize();
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
+ goto Error;
+ }
+
+ // Copy output vector from GPU buffer to host memory.
+ cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
+ if (cudaStatus != cudaSuccess)
+ {
+ fprintf(stderr, "cudaMemcpy failed!");
+ goto Error;
+ }
+
+Error:
+ cudaFree(dev_c);
+ cudaFree(dev_a);
+ cudaFree(dev_b);
+
+ return cudaStatus;
+}
diff --git a/tests/projects/cuda/console_2/xmake.lua b/tests/projects/cuda/console_2/xmake.lua
new file mode 100644
index 000000000..2c445d7e3
--- /dev/null
+++ b/tests/projects/cuda/console_2/xmake.lua
@@ -0,0 +1,19 @@
+
+-- add modes: debug and release
+add_rules("mode.debug", "mode.release")
+
+-- generate PTX code for the virtual architecture to guarantee compatibility
+add_cugencodes("compute_30")
+
+-- define target
+target("bin")
+
+ -- set kind
+ set_kind("binary")
+
+ add_cuflags("-rdc=true")
+
+ add_includedirs("inc")
+
+ -- add files
+ add_files("src/*.cu")
diff --git a/tests/projects/dlang/console/test.lua b/tests/projects/dlang/console/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/dlang/console/test.lua
+++ b/tests/projects/dlang/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/dlang/shared_library/test.lua b/tests/projects/dlang/shared_library/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/dlang/shared_library/test.lua
+++ b/tests/projects/dlang/shared_library/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/dlang/static_library/test.lua b/tests/projects/dlang/static_library/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/dlang/static_library/test.lua
+++ b/tests/projects/dlang/static_library/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/go/console/test.lua b/tests/projects/go/console/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/go/console/test.lua
+++ b/tests/projects/go/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/go/static_library/test.lua b/tests/projects/go/static_library/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/go/static_library/test.lua
+++ b/tests/projects/go/static_library/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/objc++/console/test.lua b/tests/projects/objc++/console/test.lua
index f73079781..60277b691 100644
--- a/tests/projects/objc++/console/test.lua
+++ b/tests/projects/objc++/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/objc/console/test.lua b/tests/projects/objc/console/test.lua
index f73079781..60277b691 100644
--- a/tests/projects/objc/console/test.lua
+++ b/tests/projects/objc/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/rust/console/test.lua b/tests/projects/rust/console/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/rust/console/test.lua
+++ b/tests/projects/rust/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/rust/static_library/test.lua b/tests/projects/rust/static_library/test.lua
index b423189da..c1bac30ee 100644
--- a/tests/projects/rust/static_library/test.lua
+++ b/tests/projects/rust/static_library/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build()
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/projects/swift/console/test.lua b/tests/projects/swift/console/test.lua
index f73079781..60277b691 100644
--- a/tests/projects/swift/console/test.lua
+++ b/tests/projects/swift/console/test.lua
@@ -4,5 +4,7 @@ function main(t)
-- build project
if os.host() == "macosx" then
t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
end
end
diff --git a/tests/runner.lua b/tests/runner.lua
index b4325edc2..227e66a7f 100644
--- a/tests/runner.lua
+++ b/tests/runner.lua
@@ -1,7 +1,5 @@
import("core.base.option")
-import("test_utils.test_assert")
-import("test_utils.print_error")
-import("test_utils.build", { alias = "test_build" })
+import("test_utils.context", { alias = "test_context" })
function main(script)
@@ -16,14 +14,7 @@ function main(script)
os.setenv("XMAKE_STATS", "false")
-- init test context
- local context =
- {
- filename = script
- }
- context = test_assert(context)
- function context:build(argv)
- test_build(argv)
- end
+ local context = test_context(script)
local root = path.directory(script)
@@ -50,10 +41,10 @@ function main(script)
if verbose then print(">> running %s ...", k) end
context.func = v
context.funcname = k
- try
+ local result = try
{
function ()
- v(context)
+ return v(context)
end,
catch
{
@@ -66,6 +57,9 @@ function main(script)
end
}
}
+ if context:is_skipped(result) then
+ print(">> skipped %s : %s", k, result.reason)
+ end
succeed_count = succeed_count + 1
end
end
diff --git a/tests/test_utils/context.lua b/tests/test_utils/context.lua
new file mode 100644
index 000000000..50271ac76
--- /dev/null
+++ b/tests/test_utils/context.lua
@@ -0,0 +1,13 @@
+import("test_build")
+import("test_skip")
+import("test_assert")
+
+function main(filename)
+
+ local context = { filename = filename }
+ table.join2(context, test_build())
+ table.join2(context, test_skip())
+ table.join2(context, test_assert())
+
+ return context
+end \ No newline at end of file
diff --git a/tests/test_utils/test_assert.lua b/tests/test_utils/test_assert.lua
index 4a97cb3ac..a964fcfb3 100644
--- a/tests/test_utils/test_assert.lua
+++ b/tests/test_utils/test_assert.lua
@@ -1,8 +1,8 @@
-import("print_error")
+
import("check")
-local test_assert = { print_error = print_error.main }
+local test_assert = { print_error = import("print_error", { anonymous = true }).main }
function test_assert:require(value)
if not value then
@@ -66,7 +66,6 @@ function test_assert:will_raise(func, message_pattern)
table.remove(self._will_raise_stack, 1)
end
-function main(context)
- table.join2(context, test_assert)
- return context
+function main()
+ return test_assert
end
diff --git a/tests/test_utils/build.lua b/tests/test_utils/test_build.lua
index 7725f1ddc..4625a5943 100644
--- a/tests/test_utils/build.lua
+++ b/tests/test_utils/test_build.lua
@@ -1,8 +1,9 @@
-- imports
import("privilege.sudo")
--- main entry
-function main(argv)
+local test_build = {}
+
+function test_build:build(argv)
-- check global config
os.exec("xmake g -c")
@@ -35,3 +36,7 @@ function main(argv)
end
end
end
+
+function main()
+ return test_build
+end
diff --git a/tests/test_utils/test_skip.lua b/tests/test_utils/test_skip.lua
new file mode 100644
index 000000000..c17f2c42c
--- /dev/null
+++ b/tests/test_utils/test_skip.lua
@@ -0,0 +1,13 @@
+local test_skip = { _is_skipped_tag = {true} }
+
+function test_skip:skip(reason)
+ return { is_skipped = self._is_skipped_tag, reason = reason, context = self }
+end
+
+function test_skip:is_skipped(result)
+ return result and result.context and result.context._is_skipped_tag == result.is_skipped
+end
+
+function main()
+ return test_skip
+end \ No newline at end of file
diff --git a/xmake/core/base/path.lua b/xmake/core/base/path.lua
index 489f6b702..c5ba7423b 100644
--- a/xmake/core/base/path.lua
+++ b/xmake/core/base/path.lua
@@ -27,6 +27,10 @@ local string = require("base/string")
-- get the directory of the path
function path.directory(p)
+
+ -- check
+ assert(p)
+
local i = p:find_last("[/\\]")
if i then
if i > 1 then i = i - 1 end
@@ -38,6 +42,10 @@ end
-- get the filename of the path
function path.filename(p)
+
+ -- check
+ assert(p)
+
local i = p:find_last("[/\\]")
if i then
return p:sub(i + 1)
@@ -48,6 +56,10 @@ end
-- get the basename of the path
function path.basename(p)
+
+ -- check
+ assert(p)
+
local name = path.filename(p)
local i = name:find_last(".", true)
if i then
@@ -89,6 +101,10 @@ end
-- split path by the separator
function path.split(p)
+
+ -- check
+ assert(p)
+
return p:split("/\\")
end
@@ -102,15 +118,60 @@ function path.envsep()
return xmake._HOST == "windows" and ';' or ':'
end
+-- split environment variable with `path.envsep()`,
+-- also handles more speical cases such as posix flags and windows quoted pathes
+function path.splitenv(env_path)
+
+ -- check
+ assert(env_path)
+
+ local result = {}
+ if xmake._HOST == "windows" then
+ while #env_path > 0 do
+ if env_path:startswith(path.envsep()) then
+ env_path = env_path:sub(2)
+ elseif env_path:startswith('"') then
+ -- path quoted with, can contain `;`
+ local p_end = env_path:find('"' .. path.envsep(), 2, true) or env_path:find('"$', 2) or (#env_path + 1)
+ table.insert(result, env_path:sub(2, p_end - 1))
+ env_path = env_path:sub(p_end + 1)
+ else
+ local p_end = env_path:find(path.envsep(), 2, true) or (#env_path + 1)
+ table.insert(result, env_path:sub(1, p_end - 1))
+ env_path = env_path:sub(p_end)
+ end
+ end
+ else
+ -- see https://git.kernel.org/pub/scm/utils/dash/dash.git/tree/src/exec.c?h=v0.5.9.1&id=afe0e0152e4dc12d84be3c02d6d62b0456d68580#n173
+ -- no escape sequences, so `:` and `%` is invalid in environment variable
+ for _, v in ipairs(env_path:split(path.envsep(), { plain = true })) do
+ -- flag for shells, style `<path>%<flag>`
+ local flag = v:find("%", 1, true)
+ if flag then
+ v = v:sub(1, flag - 1)
+ end
+ if #v > 0 then
+ table.insert(result, v)
+ end
+ end
+ end
+
+ return result
+end
+
-- the last character is the path seperator?
function path.islastsep(p)
+
+ -- check
+ assert(p)
+
local sep = p:sub(#p, #p)
return xmake._HOST == "windows" and (sep == '\\' or sep == '/') or (sep == '/')
end
-- convert path pattern to a lua pattern
function path.pattern(pattern)
-
+
-- translate wildcards, .e.g *, **
pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1")
pattern = pattern:gsub("%*%*", "\001")
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 1543d8bd6..2d64d6067 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_file.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_file.lua
@@ -75,31 +75,37 @@ function sandbox_lib_detect_find_file.main(name, pathes, opt)
-- format path for builtin variables
if type(_path) == "function" then
- local ok, results = sandbox.load(_path)
+ local ok, results = sandbox.load(_path)
if ok then
_path = results or ""
- else
+ else
raise(results)
end
- else
- _path = vformat(_path)
+ elseif type(_path) == "string" then
+ if _path:match("^%$%($s*env%s+%S+%s*%)$") then
+ _path = path.splitenv(vformat(_path))
+ else
+ _path = vformat(_path)
+ end
end
- -- find file with suffixes
- if #suffixes > 0 then
- for _, suffix in ipairs(suffixes) do
- local filedir = path.join(_path, suffix)
- local results = sandbox_lib_detect_find_file._find(filedir, name)
+ for _, _s_path in ipairs(table.wrap(_path)) do
+ -- find file with suffixes
+ if #suffixes > 0 then
+ for _, suffix in ipairs(suffixes) do
+ local filedir = path.join(_s_path, suffix)
+ local results = sandbox_lib_detect_find_file._find(filedir, name)
+ if results then
+ return results
+ end
+ end
+ else
+ -- find file in the given path
+ local results = sandbox_lib_detect_find_file._find(_s_path, name)
if results then
return results
end
end
- else
- -- find file in the given path
- local results = sandbox_lib_detect_find_file._find(_path, name)
- if results then
- return results
- end
end
end
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 d9cfbf484..bfc21f35c 100644
--- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
+++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua
@@ -63,7 +63,7 @@ function sandbox_lib_detect_find_program._check(program, opt)
if type(opt.check) == "string" then
ok, errors = os.runv(program, {opt.check})
else
- ok, errors = sandbox.load(opt.check, program)
+ ok, errors = sandbox.load(opt.check, program)
end
-- check failed? print verbose error info
@@ -84,29 +84,36 @@ function sandbox_lib_detect_find_program._find_from_pathes(name, pathes, opt)
-- format path for builtin variables
if type(_path) == "function" then
- local ok, results = sandbox.load(_path)
+ local ok, results = sandbox.load(_path)
if ok then
_path = results or ""
- else
+ else
raise(results)
end
- else
- _path = vformat(_path)
+ elseif type(_path) == "string" then
+ if _path:match("^%$%($s*env%s+%S+%s*%)$") then
+ _path = path.splitenv(vformat(_path))
+ else
+ _path = vformat(_path)
+ end
end
- -- get program path
- local program_path = nil
- if os.isfile(_path) then
- program_path = _path
- elseif os.isdir(_path) then
- program_path = path.join(_path, name)
- end
+ for _, _s_path in ipairs(table.wrap(_path)) do
- -- the program path
- if program_path and (os.isexec(program_path) or os.isexec(program_path:split("%s")[1])) then
- -- check it
- if sandbox_lib_detect_find_program._check(program_path, opt) then
- return program_path
+ -- get program path
+ local program_path = nil
+ if os.isfile(_s_path) then
+ program_path = _s_path
+ elseif os.isdir(_s_path) then
+ program_path = path.join(_s_path, name)
+ end
+
+ -- the program path
+ if program_path and (os.isexec(program_path) or os.isexec(program_path:split("%s")[1])) then
+ -- check it
+ if sandbox_lib_detect_find_program._check(program_path, opt) then
+ return program_path
+ end
end
end
end
@@ -119,7 +126,7 @@ function sandbox_lib_detect_find_program._find_from_packages(name, opt)
-- get the manifest file of package, .e.g ~/.xmake/packages/g/git/1.1.12/ed41d5327fad3fc06fe376b4a94f62ef/manifest.txt
local manifest_file = path.join(package.installdir(), name:sub(1, 1), name, opt.version, opt.buildhash, "manifest.txt")
if not os.isfile(manifest_file) then
- return
+ return
end
-- get install directory of this package
@@ -250,7 +257,7 @@ function sandbox_lib_detect_find_program.main(name, opt)
end
-- attempt to get result from cache first
- local cacheinfo = cache.load(cachekey)
+ local cacheinfo = cache.load(cachekey)
local result = cacheinfo[name]
if result ~= nil and not opt.force then
return utils.ifelse(result, result, nil)
@@ -258,7 +265,7 @@ function sandbox_lib_detect_find_program.main(name, opt)
-- find executable program
checking = utils.ifelse(coroutine_running, name, nil)
- result = sandbox_lib_detect_find_program._find(name, opt.pathes, opt)
+ result = sandbox_lib_detect_find_program._find(name, opt.pathes, opt)
checking = nil
-- cache result
diff --git a/xmake/languages/cuda/xmake.lua b/xmake/languages/cuda/xmake.lua
index 75b4bf5b8..0f532d4ed 100644
--- a/xmake/languages/cuda/xmake.lua
+++ b/xmake/languages/cuda/xmake.lua
@@ -140,14 +140,11 @@ language("cuda")
{category = "Cross Complation Configuration/Compiler Configuration" }
, {nil, "cu", "kv", nil, "The Cuda Compiler" }
, {nil, "cu-ccbin", "kv", nil, "The Cuda Host C++ Compiler" }
-
- , {category = "Cross Complation Configuration/Linker Configuration" }
, {nil, "cu-ld", "kv", nil, "The Cuda Linker" }
- , {nil, "cu-ar", "kv", nil, "The Cuda Static Library Archiver" }
- , {nil, "cu-sh", "kv", nil, "The Cuda Shared Library Linker" }
, {category = "Cross Complation Configuration/Compiler Flags Configuration" }
, {nil, "cuflags", "kv", nil, "The Cuda Compiler Flags" }
+ , {nil, "culdflags", "kv", nil, "The Cuda Linker Flags" }
, {category = "Cross Complation Configuration/Builtin Flags Configuration" }
, {nil, "links", "kv", nil, "The Link Libraries" }
diff --git a/xmake/modules/core/tools/clang.lua b/xmake/modules/core/tools/clang.lua
index b7291b285..a57dd924f 100644
--- a/xmake/modules/core/tools/clang.lua
+++ b/xmake/modules/core/tools/clang.lua
@@ -23,15 +23,26 @@ inherit("gcc")
-- init it
function init(self)
-
+
-- init super
_super.init(self)
+ if not is_plat("windows", "mingw") then
+ self:add("shared.cuflags", "-fPIC")
+ end
+
-- suppress warning
self:add("cxflags", "-Qunused-arguments")
+ self:add("cuflags", "-Qunused-arguments")
self:add("mxflags", "-Qunused-arguments")
self:add("asflags", "-Qunused-arguments")
+ local cuda = get_config("cuda")
+ if cuda then
+ local cuda_path = "--cuda-path=" .. os.args(path.translate(cuda))
+ self:add("cuflags", cuda_path)
+ end
+
-- init flags map
self:set("mapflags",
{
@@ -44,6 +55,16 @@ function init(self)
-- strip
, ["-s"] = "-s"
, ["-S"] = "-S"
+
+ -- rdc
+ , ["-rdc=true"] = "-fcuda-rdc"
+ , ["-rdc true"] = "-fcuda-rdc"
+ , ["--relocatable-device-code=true"] = "-fcuda-rdc"
+ , ["--relocatable-device-code true"] = "-fcuda-rdc"
+ , ["-rdc=false"] = ""
+ , ["-rdc false"] = ""
+ , ["--relocatable-device-code=false"] = ""
+ , ["--relocatable-device-code false"] = ""
})
end
diff --git a/xmake/modules/core/tools/nvcc.lua b/xmake/modules/core/tools/nvcc.lua
index 592634ac8..e72857a93 100644
--- a/xmake/modules/core/tools/nvcc.lua
+++ b/xmake/modules/core/tools/nvcc.lua
@@ -29,11 +29,17 @@ import("private.tools.nvcc.parse_deps")
-- init it
function init(self)
- -- init flags
- if not is_plat("windows") then
+ -- init cuflags
+ if not is_plat("windows", "mingw") then
self:set("shared.cuflags", "-Xcompiler -fPIC")
end
+ -- add -ccbin
+ local cu_ccbin = get_config("cu-ccbin")
+ if cu_ccbin then
+ self:add("cuflags", "-ccbin=" .. os.args(cu_ccbin))
+ end
+
-- init flags map
self:set("mapflags",
{
diff --git a/xmake/modules/detect/sdks/find_cuda.lua b/xmake/modules/detect/sdks/find_cuda.lua
index f9077a485..b7fb4911e 100644
--- a/xmake/modules/detect/sdks/find_cuda.lua
+++ b/xmake/modules/detect/sdks/find_cuda.lua
@@ -37,6 +37,7 @@ function _find_sdkdir()
else
table.insert(pathes, "/usr/local/cuda*/bin")
end
+ table.insert(pathes, "$(env PATH)")
-- attempt to find nvcc
local nvcc = find_file(os.host() == "windows" and "nvcc.exe" or "nvcc", pathes)
diff --git a/xmake/modules/detect/tools/find_nvcc.lua b/xmake/modules/detect/tools/find_nvcc.lua
index 5b00510c1..5cd11e3dc 100644
--- a/xmake/modules/detect/tools/find_nvcc.lua
+++ b/xmake/modules/detect/tools/find_nvcc.lua
@@ -43,8 +43,12 @@ function main(opt)
opt = opt or {}
opt.parse = opt.parse or "V(%d+%.?%d*%.?%d*.-)%s"
+ local program = nil
+
-- find program
- local program = find_program(opt.program or "nvcc", opt)
+ if opt.program then
+ program = find_program(opt.program, opt)
+ end
-- not found? attempt to find program from cuda toolchains
if not program then
@@ -54,9 +58,14 @@ function main(opt)
end
end
+ -- not found? attempt to find program from PATH
+ if not program then
+ program = find_program("nvcc", opt)
+ end
+
-- find program version
local version = nil
- if program and opt and opt.version then
+ if program and opt.version then
version = find_programver(program, opt)
end
diff --git a/xmake/modules/lib/detect/find_cudadevices.lua b/xmake/modules/lib/detect/find_cudadevices.lua
index aa44fe0fb..63874685d 100644
--- a/xmake/modules/lib/detect/find_cudadevices.lua
+++ b/xmake/modules/lib/detect/find_cudadevices.lua
@@ -23,6 +23,8 @@ import("core.base.option")
import("core.platform.platform")
import("core.project.config")
import("lib.detect.cache")
+import("lib.detect.find_tool")
+import("detect.sdks.find_cuda")
-- a magic string to filter output
local _PRINT_SUFFIX = "<find_cudadevices>"
@@ -30,7 +32,7 @@ local _PRINT_SUFFIX = "<find_cudadevices>"
-- filter stdout and stderr with _PRINT_SUFFIX
function _get_lines(str)
local result = {}
- for _, l in ipairs(str:split('\n')) do
+ for _, l in ipairs(str:split("\n")) do
if l:startswith(_PRINT_SUFFIX) then
table.insert(result, l:sub(#_PRINT_SUFFIX + 1))
end
@@ -55,8 +57,8 @@ function _parse_value(value)
return value:sub(2, -2)
end
- if value:startswith('(') and value:endswith(')') then
- local values = value:sub(2, -2):split(',')
+ if value:startswith("(") and value:endswith(")") then
+ local values = value:sub(2, -2):split(",")
local result = {}
for _, v in ipairs(values) do
table.insert(result, _parse_value(v:trim()))
@@ -77,7 +79,7 @@ function _parse_line(line, device)
if key and value then
key = key:trim()
value = value:trim()
- assert(not device[key], 'duplicate key: ' .. key)
+ assert(not device[key], "duplicate key: " .. key)
device[key] = _parse_value(value)
end
end
@@ -99,7 +101,7 @@ function _parse_result(lines, verbose)
end
local devId = tonumber(l:match("%s*DEVICE #(%d+)"))
if devId then
- currentDevice = { ['$id'] = devId }
+ currentDevice = { ["$id"] = devId }
table.insert(devices, currentDevice)
elseif currentDevice then
_parse_line(l, currentDevice)
@@ -111,32 +113,28 @@ end
-- find devices
function _find_devices(verbose)
-
- local nvcc = platform.tool("cu")
- if nvcc == nil then
- raise('nvcc not found')
- end
+ local nvcc = assert(find_tool("nvcc"), "nvcc not found")
if verbose then
cprint("${dim}checking for cuda devices")
end
- local sourcefile = path.join(os.programdir(), 'scripts', 'find_cudadevices.cpp')
+ local sourcefile = path.join(os.programdir(), "scripts", "find_cudadevices.cpp")
local outfile = os.tmpfile()
+ local args = { sourcefile, "-run", "-o", outfile , '-DPRINT_SUFFIX="' .. _PRINT_SUFFIX .. '"' }
+
local compile_errors = nil
- local results, errors = try
- {
+ local results, errors = try
+ {
function ()
- local archs = { i386 = "-m32", x86 = "-m32", x86_64 = "-m64", x64 = "-m64" }
- local arch = archs[config.get("arch")] or ""
- return os.iorunv(nvcc, { sourcefile, arch, '-run', '-o', outfile , '-DPRINT_SUFFIX="' .. _PRINT_SUFFIX .. '"' })
- end,
- catch
+ return os.iorunv(nvcc.program, args)
+ end,
+ catch
{
- function (errs)
- compile_errors = tostring(errs)
+ function (errs)
+ compile_errors = tostring(errs)
end
- }
+ }
}
if compile_errors then
@@ -149,13 +147,13 @@ function _find_devices(verbose)
-- clean up
os.tryrm(outfile)
- os.tryrm(outfile .. '.*')
+ os.tryrm(outfile .. ".*")
-- get results
local results_lines = _get_lines(results)
local errors_lines = _get_lines(errors)
if #errors_lines ~= 0 then
- utils.warning("failed to find cuda devices: " .. table.concat(errors_lines, '\n'))
+ utils.warning("failed to find cuda devices: " .. table.concat(errors_lines, "\n"))
return nil
end
@@ -163,7 +161,7 @@ function _find_devices(verbose)
local devices = _parse_result(results_lines, option.get("diagnosis"))
if verbose then
for _, v in ipairs(devices) do
- cprint("${dim}> found device #%d: ${green bright}%s${reset dim} with compute ${bright}%d.%d${reset dim} capability", v['$id'], v.name, v.major, v.minor)
+ cprint("${dim}> found device #%d: ${green bright}%s${reset dim} with compute ${bright}%d.%d${reset dim} capability", v["$id"], v.name, v.major, v.minor)
end
end
return devices
@@ -244,10 +242,10 @@ function _order_by_flops(devices)
else
sm_per_multiproc = ngpu_arch_cores_per_sm[dev.major * 10 + dev.minor] or 64;
end
- dev['$flops'] = dev.multiProcessorCount * sm_per_multiproc * dev.clockRate
+ dev["$flops"] = dev.multiProcessorCount * sm_per_multiproc * dev.clockRate
end
- table.sort(devices, function (a,b) return a['$flops'] > b['$flops'] end)
+ table.sort(devices, function (a,b) return a["$flops"] > b["$flops"] end)
return devices
end
@@ -256,7 +254,7 @@ end
-- @param opt the options
-- e.g. { verbose = false, force = false, cachekey = "xxxx", min_sm_arch = 35, skip_compute_mode_prohibited = false, order_by_flops = true }
--
--- @return { { ['$id'] = 0, name = "GeForce GTX 960M", major = 5, minor = 0, ... }, ... }
+-- @return { { ["$id"] = 0, name = "GeForce GTX 960M", major = 5, minor = 0, ... }, ... }
-- for all keys, see https://docs.nvidia.com/cuda/cuda-runtime-api/structcudaDeviceProp.html#structcudaDeviceProp
-- keys might be differ as your cuda version varies
--
diff --git a/xmake/platforms/linux/config.lua b/xmake/platforms/linux/config.lua
index ebccfc985..c86144804 100644
--- a/xmake/platforms/linux/config.lua
+++ b/xmake/platforms/linux/config.lua
@@ -77,14 +77,13 @@ function _toolchains()
local rc_ar = toolchain("the rust static library archiver")
local cu = toolchain("the cuda compiler")
local cu_ld = toolchain("the cuda linker")
- local cu_sh = toolchain("the cuda shared library linker")
local cu_ccbin = toolchain("the cuda host c++ compiler")
local toolchains = {cc = cc, cxx = cxx, as = as, ld = ld, sh = sh, ar = ar, ex = ex,
mm = mm, mxx = mxx,
gc = gc, ["gc-ld"] = gc_ld, ["gc-ar"] = gc_ar,
dc = dc, ["dc-ld"] = dc_ld, ["dc-sh"] = dc_sh, ["dc-ar"] = dc_ar,
rc = rc, ["rc-ld"] = rc_ld, ["rc-sh"] = rc_sh, ["rc-ar"] = rc_ar,
- cu = cu, ["cu-ld"] = cu_ld, ["cu-sh"] = cu_sh, ["cu-ccbin"] = cu_ccbin}
+ cu = cu, ["cu-ld"] = cu_ld, ["cu-ccbin"] = cu_ccbin}
-- init the c compiler
cc:add("$(env CC)", {name = "gcc", cross = cross}, {name = "clang", cross = cross})
@@ -147,9 +146,8 @@ function _toolchains()
rc_ar:add("$(env RC)", "rustc")
-- init the cuda compiler and linker
- cu:add("nvcc")
+ cu:add("nvcc", "clang++", "clang")
cu_ld:add("nvcc")
- cu_sh:add("nvcc")
if not cross or cross == "" then
cu_ccbin:add("$(env CXX)", "$(env CC)", "gcc", "clang", "g++", "clang++")
end
diff --git a/xmake/platforms/macosx/config.lua b/xmake/platforms/macosx/config.lua
index a5b1935ba..3db232687 100644
--- a/xmake/platforms/macosx/config.lua
+++ b/xmake/platforms/macosx/config.lua
@@ -59,14 +59,13 @@ function _toolchains()
local rc_ar = toolchain("the rust static library archiver")
local cu = toolchain("the cuda compiler")
local cu_ld = toolchain("the cuda linker")
- local cu_sh = toolchain("the cuda shared library linker")
local cu_ccbin = toolchain("the cuda host c++ compiler")
local toolchains = {cc = cc, cxx = cxx, as = as, ld = ld, sh = sh, ar = ar, ex = ex,
mm = mm, mxx = mxx, sc = sc, ["sc-ld"] = sc_ld, ["sc-sh"] = sc_sh,
gc = gc, ["gc-ld"] = gc_ld, ["gc-ar"] = gc_ar,
dc = dc, ["dc-ld"] = dc_ld, ["dc-sh"] = dc_sh, ["dc-ar"] = dc_ar,
rc = rc, ["rc-ld"] = rc_ld, ["rc-sh"] = rc_sh, ["rc-ar"] = rc_ar,
- cu = cu, ["cu-ld"] = cu_ld, ["cu-sh"] = cu_sh, ["cu-ccbin"] = cu_ccbin}
+ cu = cu, ["cu-ld"] = cu_ld, ["cu-ccbin"] = cu_ccbin}
-- init the c compiler
cc:add("$(env CC)", {name = "clang", cross = cross}, "clang", "gcc")
@@ -130,9 +129,8 @@ function _toolchains()
rc_ar:add("$(env RC)", "rustc")
-- init the cuda compiler and linker
- cu:add("nvcc")
+ cu:add("nvcc", "clang")
cu_ld:add("nvcc")
- cu_sh:add("nvcc")
cu_ccbin:add("$(env CXX)", "$(env CC)", "clang", "gcc")
return toolchains
diff --git a/xmake/platforms/windows/config.lua b/xmake/platforms/windows/config.lua
index c61a1ab1a..1ba24cb65 100644
--- a/xmake/platforms/windows/config.lua
+++ b/xmake/platforms/windows/config.lua
@@ -56,12 +56,11 @@ function _toolchains()
local rc_ar = toolchain("the rust static library archiver")
local cu = toolchain("the cuda compiler")
local cu_ld = toolchain("the cuda linker")
- local cu_sh = toolchain("the cuda shared library linker")
local toolchains = {cc = cc, cxx = cxx, mrc = mrc, as = as, ld = ld, sh = sh, ar = ar, ex = ex,
gc = gc, ["gc-ld"] = gc_ld, ["gc-ar"] = gc_ar,
dc = dc, ["dc-ld"] = dc_ld, ["dc-sh"] = dc_sh, ["dc-ar"] = dc_ar,
rc = rc, ["rc-ld"] = rc_ld, ["rc-sh"] = rc_sh, ["rc-ar"] = rc_ar,
- cu = cu, ["cu-ld"] = cu_ld, ["cu-sh"] = cu_sh}
+ cu = cu, ["cu-ld"] = cu_ld}
-- init the c compiler
cc:add("cl.exe")
@@ -109,9 +108,8 @@ function _toolchains()
rc_ar:add("$(env RC)", "rustc")
-- init the cuda compiler and linker
- cu:add("nvcc")
+ cu:add("nvcc", "clang")
cu_ld:add("nvcc")
- cu_sh:add("nvcc")
return toolchains
end
diff --git a/xmake/rules/cuda/devlink/xmake.lua b/xmake/rules/cuda/devlink/xmake.lua
index 0416b9abe..1cdfb2fb7 100644
--- a/xmake/rules/cuda/devlink/xmake.lua
+++ b/xmake/rules/cuda/devlink/xmake.lua
@@ -26,16 +26,17 @@ rule("cuda.devlink")
-- @see https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/
before_link(function (target, opt)
+ import("core.platform.platform")
-- disable devlink?
if target:values("cuda.devlink") == false then
- return
+ return
end
-- only for binary/shared
local targetkind = target:targetkind()
if targetkind ~= "binary" and targetkind ~= "shared" then
- return
+ return
end
-- imports
@@ -50,6 +51,8 @@ rule("cuda.devlink")
-- init culdflags
local culdflags = {"-dlink"}
+
+ -- add shared flag
if targetkind == "shared" then
table.insert(culdflags, "-shared")
end
diff --git a/xmake/rules/cuda/env/xmake.lua b/xmake/rules/cuda/env/xmake.lua
index 1acbc08ba..a78e13af1 100644
--- a/xmake/rules/cuda/env/xmake.lua
+++ b/xmake/rules/cuda/env/xmake.lua
@@ -35,11 +35,10 @@ rule("cuda.env")
target:add("culdflags", "-m64", {force = true})
end
- -- add -ccbin
+ -- add ccbin
local cu_ccbin = get_config("cu-ccbin")
if cu_ccbin then
- target:add("cuflags", "-ccbin", os.args(cu_ccbin), {force = true})
- target:add("culdflags", "-ccbin", os.args(cu_ccbin), {force = true})
+ target:add("culdflags", "-ccbin=" .. os.args(cu_ccbin), {force = true})
end
-- add links
diff --git a/xmake/rules/cuda/gencodes/xmake.lua b/xmake/rules/cuda/gencodes/xmake.lua
index 9fcdbcd3a..cecf83694 100644
--- a/xmake/rules/cuda/gencodes/xmake.lua
+++ b/xmake/rules/cuda/gencodes/xmake.lua
@@ -36,6 +36,9 @@ rule("cuda.gencodes")
--
before_load(function (target)
+ import("core.platform.platform")
+ import("lib.detect.find_cudadevices")
+
local function set (list)
local result = {}
for _, l in ipairs(list) do result[l] = true end
@@ -43,17 +46,15 @@ rule("cuda.gencodes")
end
-- sm_20 and compute_20 is supported until CUDA 8
- local knownVArchs = set { 20, 30, 32, 35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, }
- local knownRArchs = set { 20, 30, 32, 35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, }
+ local known_v_archs = set { 20, 30, 32, 35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, }
+ local known_r_archs = set { 20, 30, 32, 35, 37, 50, 52, 53, 60, 61, 62, 70, 72, 75, }
local function nf_cugencode(archs)
-
if type(archs) ~= 'string' then
return nil
end
archs = archs:trim():lower()
if archs == 'native' then
- import("lib.detect.find_cudadevices")
local device = find_cudadevices({ skip_compute_mode_prohibited = true, order_by_flops = true })[1]
if device then
return nf_cugencode('sm_' .. device.major .. device.minor)
@@ -61,10 +62,10 @@ rule("cuda.gencodes")
return nil
end
- local vArch = nil
- local rArchs = {}
+ local v_arch = nil
+ local r_archs = {}
- local function parse_arch(value, prefix, knowList)
+ local function parse_arch(value, prefix, know_list)
if not value:startswith(prefix) then
return nil
end
@@ -72,8 +73,8 @@ rule("cuda.gencodes")
if arch == nil then
raise("Unknown architecture: " .. value)
end
- if not knowList[arch] then
- if arch <= table.maxn(knowList) then
+ if not know_list[arch] then
+ if arch <= table.maxn(know_list) then
raise("Unknown architecture: " .. prefix .. "_" .. arch)
else
utils.warning("Unknown architecture: " .. prefix .. "_" .. arch)
@@ -84,37 +85,55 @@ rule("cuda.gencodes")
for _, v in ipairs(archs:split(',')) do
local arch = v:trim()
- local tempRArch = parse_arch(arch, 'sm', knownRArchs)
- if tempRArch then
- table.insert(rArchs, tempRArch)
+ local temp_r_arch = parse_arch(arch, 'sm', known_r_archs)
+ if temp_r_arch then
+ table.insert(r_archs, temp_r_arch)
end
- local tempVArch = parse_arch(arch, 'compute', knownVArchs)
- if tempVArch then
- if vArch ~= nil then
- raise("More than one virtual architecture is defined in one gpu gencode option: compute_" .. vArch .. " and compute_" .. tempVArch)
+ local temp_v_arch = parse_arch(arch, 'compute', known_v_archs)
+ if temp_v_arch then
+ if v_arch ~= nil then
+ raise("More than one virtual architecture is defined in one gpu gencode option: compute_" .. v_arch .. " and compute_" .. temp_v_arch)
end
- vArch = tempVArch
+ v_arch = temp_v_arch
end
- if not (tempRArch or tempVArch) then
+ if not (temp_r_arch or temp_v_arch) then
raise("Unknown architecture: " .. arch)
end
end
- if vArch == nil and #rArchs == 0 then
+ local result = { clang = {}, nvcc = {} }
+ if v_arch == nil and #r_archs == 0 then
return nil
end
- if #rArchs == 0 then
- return '-gencode arch=compute_' .. vArch .. ',code=compute_' .. vArch
+
+ if #r_archs == 0 then
+ return {
+ clang = '--cuda-gpu-arch=sm_' .. v_arch
+ , nvcc = '-gencode arch=compute_' .. v_arch .. ',code=compute_' .. v_arch }
+ end
+
+ if v_arch then
+ table.insert(r_archs, v_arch)
+ end
+ r_archs = table.unique(r_archs)
+ local clang_flags = {}
+ for _, r_arch in ipairs(r_archs) do
+ table.insert(clang_flags, '--cuda-gpu-arch=sm_' .. r_arch)
end
- rArchs = table.unique(rArchs)
- vArch = vArch or math.min(unpack(rArchs))
- if #rArchs == 1 then
- return '-gencode arch=compute_' .. vArch .. ',code=sm_' .. rArchs[1]
+ r_archs = table.unique(r_archs)
+ v_arch = v_arch or math.min(unpack(r_archs))
+ local nvcc_flags = nil
+ if #r_archs == 1 then
+ nvcc_flags = '-gencode arch=compute_' .. v_arch .. ',code=sm_' .. r_archs[1]
else
- return '-gencode arch=compute_' .. vArch .. ',code=[sm_' .. table.concat(rArchs, ',sm_') .. ']'
+ nvcc_flags = '-gencode arch=compute_' .. v_arch .. ',code=[sm_' .. table.concat(r_archs, ',sm_') .. ']'
end
+
+ return {
+ clang = clang_flags
+ , nvcc = nvcc_flags }
end
local cugencodes = table.wrap(target:get("cugencodes"))
@@ -124,8 +143,13 @@ rule("cuda.gencodes")
for _, v in ipairs(cugencodes) do
local flag = nf_cugencode(v)
if flag then
- target:add('cuflags', flag)
- target:add('culdflags', flag)
+ local tool, toolname = platform.tool("cu")
+ if (toolname or path.basename(tool)) == "nvcc" then
+ target:add('cuflags', flag.nvcc)
+ else
+ target:add('cuflags', flag.clang)
+ end
+ target:add('culdflags', flag.nvcc)
end
end
end)