summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-09-12 12:32:53 +0800
committerGitHub <[email protected]>2019-09-12 12:32:53 +0800
commit961b833b032ee06ffd4f5de96a11013edb8498a7 (patch)
treea7f2378ae72fa63607267286ffd6dacd11086b89
parentc58d64d433d2a3e2c97ead29738722aa653ae88a (diff)
parentce51c2de7c11b6368ce8956329f9ebbe4ffd1b67 (diff)
Merge pull request #569 from xmake-io/cppmodules
Add c++ modules ts build rules
-rw-r--r--tests/projects/c++/modules/class/src/hello.mpp12
-rw-r--r--tests/projects/c++/modules/class/src/hello_impl.cpp16
-rw-r--r--tests/projects/c++/modules/class/src/main.cpp7
-rw-r--r--tests/projects/c++/modules/class/xmake.lua5
-rw-r--r--tests/projects/c++/modules/dependence/src/hello.mpp26
-rw-r--r--tests/projects/c++/modules/dependence/src/hello_impl.cpp23
-rw-r--r--tests/projects/c++/modules/dependence/src/main.cpp9
-rw-r--r--tests/projects/c++/modules/dependence/src/mod.mpp5
-rw-r--r--tests/projects/c++/modules/dependence/src/mod_impl.cpp8
-rw-r--r--tests/projects/c++/modules/dependence/xmake.lua6
-rw-r--r--tests/projects/c++/modules/hello/src/hello.mpp10
-rw-r--r--tests/projects/c++/modules/hello/src/main.cpp6
-rw-r--r--tests/projects/c++/modules/hello/xmake.lua5
-rw-r--r--tests/projects/c++/modules/impl_unit/src/hello.mpp10
-rw-r--r--tests/projects/c++/modules/impl_unit/src/hello_impl.cpp19
-rw-r--r--tests/projects/c++/modules/impl_unit/src/main.cpp8
-rw-r--r--tests/projects/c++/modules/impl_unit/xmake.lua5
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/foo.mpp17
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/foo_impl.cpp8
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/hello.mpp9
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/main.cpp12
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/say.mpp11
-rw-r--r--tests/projects/c++/modules/inline_and_template/xmake.lua6
-rw-r--r--tests/projects/objc++/modulemap/src/hello.h7
-rw-r--r--tests/projects/objc++/modulemap/src/hello.m10
-rw-r--r--tests/projects/objc++/modulemap/src/main.mm8
-rw-r--r--tests/projects/objc++/modulemap/src/module.modulemap4
-rw-r--r--tests/projects/objc++/modulemap/xmake.lua6
-rw-r--r--tests/projects/objc/modulemap/src/hello.h7
-rw-r--r--tests/projects/objc/modulemap/src/hello.m10
-rw-r--r--tests/projects/objc/modulemap/src/main.m8
-rw-r--r--tests/projects/objc/modulemap/src/module.modulemap4
-rw-r--r--tests/projects/objc/modulemap/xmake.lua6
-rw-r--r--tests/projects/swift/modulemap/src/hello.cpp8
-rw-r--r--tests/projects/swift/modulemap/src/hello.h14
-rw-r--r--tests/projects/swift/modulemap/src/main.swift5
-rw-r--r--tests/projects/swift/modulemap/src/module.modulemap4
-rw-r--r--tests/projects/swift/modulemap/xmake.lua4
-rw-r--r--xmake/actions/build/kinds/object.lua18
-rw-r--r--xmake/core/project/option.lua20
-rw-r--r--xmake/core/project/target.lua14
-rw-r--r--xmake/core/tool/builder.lua2
-rw-r--r--xmake/languages/c++/xmake.lua2
-rw-r--r--xmake/modules/private/action/build/object.lua16
-rw-r--r--xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua2
-rw-r--r--xmake/rules/asm/xmake.lua4
-rw-r--r--xmake/rules/c++/modules/build_modulefiles.lua138
-rw-r--r--xmake/rules/c++/modules/xmake.lua25
-rw-r--r--xmake/rules/c++/xmake.lua22
-rw-r--r--xmake/rules/dlang/xmake.lua4
-rw-r--r--xmake/rules/go/xmake.lua4
-rw-r--r--xmake/rules/objc++/xmake.lua10
-rw-r--r--xmake/rules/rust/xmake.lua4
-rw-r--r--xmake/rules/swift/xmake.lua4
-rw-r--r--xmake/rules/winsdk/xmake.lua4
55 files changed, 586 insertions, 55 deletions
diff --git a/tests/projects/c++/modules/class/src/hello.mpp b/tests/projects/c++/modules/class/src/hello.mpp
new file mode 100644
index 000000000..9e4ecd960
--- /dev/null
+++ b/tests/projects/c++/modules/class/src/hello.mpp
@@ -0,0 +1,12 @@
+export module hello;
+
+export namespace hello {
+ class say {
+ public:
+ say(int data);
+ void hello();
+
+ private:
+ int data_;
+ };
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/class/src/hello_impl.cpp b/tests/projects/c++/modules/class/src/hello_impl.cpp
new file mode 100644
index 000000000..b929c453b
--- /dev/null
+++ b/tests/projects/c++/modules/class/src/hello_impl.cpp
@@ -0,0 +1,16 @@
+// module;
+#include <iostream>
+module hello;
+
+// import std.core;
+using namespace std;
+
+namespace hello {
+ say::say(int data) : data_(data) {
+
+ }
+
+ void say::hello() {
+ cout << "hello, say class: " << data_ << endl;
+ }
+}
diff --git a/tests/projects/c++/modules/class/src/main.cpp b/tests/projects/c++/modules/class/src/main.cpp
new file mode 100644
index 000000000..6f80b6c7d
--- /dev/null
+++ b/tests/projects/c++/modules/class/src/main.cpp
@@ -0,0 +1,7 @@
+import hello;
+
+int main() {
+ hello::say s(sizeof(hello::say));
+ s.hello();
+ return 0;
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/class/xmake.lua b/tests/projects/c++/modules/class/xmake.lua
new file mode 100644
index 000000000..f0dcc3ea7
--- /dev/null
+++ b/tests/projects/c++/modules/class/xmake.lua
@@ -0,0 +1,5 @@
+target("class")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
+
+
diff --git a/tests/projects/c++/modules/dependence/src/hello.mpp b/tests/projects/c++/modules/dependence/src/hello.mpp
new file mode 100644
index 000000000..e29bd7b95
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/src/hello.mpp
@@ -0,0 +1,26 @@
+export module hello;
+
+export namespace hello {
+#ifdef _MSC_VER
+ int data__;
+#else
+ extern int data__;
+#endif
+ void say_hello();
+
+ class say {
+ public:
+ say(int data);
+ void hello();
+
+ private:
+ int data_;
+ };
+}
+
+#ifndef _MSC_VER
+export namespace {
+ void anonymous() {
+ }
+}
+#endif
diff --git a/tests/projects/c++/modules/dependence/src/hello_impl.cpp b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
new file mode 100644
index 000000000..37797c31c
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
@@ -0,0 +1,23 @@
+// module;
+#include <iostream>
+module hello;
+import mod;
+
+void inner() {
+ std::cout << "hello world! data: "
+ << mod::foo() << std::endl;
+}
+
+namespace hello {
+ int data__;
+ void say_hello() { ::inner(); }
+
+ say::say(int data) : data_{data} {
+
+ }
+
+ void say::hello() {
+ hello::data__ = data_;
+ ::inner();
+ }
+}
diff --git a/tests/projects/c++/modules/dependence/src/main.cpp b/tests/projects/c++/modules/dependence/src/main.cpp
new file mode 100644
index 000000000..93cc427a4
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/src/main.cpp
@@ -0,0 +1,9 @@
+import hello;
+
+int main() {
+ hello::data__ = 123;
+ hello::say_hello();
+ hello::say(sizeof(hello::say)).hello();
+ return 0;
+}
+
diff --git a/tests/projects/c++/modules/dependence/src/mod.mpp b/tests/projects/c++/modules/dependence/src/mod.mpp
new file mode 100644
index 000000000..ac30a31c8
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/src/mod.mpp
@@ -0,0 +1,5 @@
+export module mod;
+
+export namespace mod {
+ int foo();
+}
diff --git a/tests/projects/c++/modules/dependence/src/mod_impl.cpp b/tests/projects/c++/modules/dependence/src/mod_impl.cpp
new file mode 100644
index 000000000..1adf6570e
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/src/mod_impl.cpp
@@ -0,0 +1,8 @@
+module mod;
+import hello;
+
+namespace mod {
+ int foo() {
+ return hello::data__;
+ }
+}
diff --git a/tests/projects/c++/modules/dependence/xmake.lua b/tests/projects/c++/modules/dependence/xmake.lua
new file mode 100644
index 000000000..4a2608cd3
--- /dev/null
+++ b/tests/projects/c++/modules/dependence/xmake.lua
@@ -0,0 +1,6 @@
+target("dependence")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
+ set_languages("c++11")
+
+
diff --git a/tests/projects/c++/modules/hello/src/hello.mpp b/tests/projects/c++/modules/hello/src/hello.mpp
new file mode 100644
index 000000000..fbd7fd6ad
--- /dev/null
+++ b/tests/projects/c++/modules/hello/src/hello.mpp
@@ -0,0 +1,10 @@
+// module;
+#include <cstdio>
+export module hello;
+using namespace std;
+
+export namespace hello {
+ void say(const char* str) {
+ printf("%s\n", str);
+ }
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/hello/src/main.cpp b/tests/projects/c++/modules/hello/src/main.cpp
new file mode 100644
index 000000000..175b4d348
--- /dev/null
+++ b/tests/projects/c++/modules/hello/src/main.cpp
@@ -0,0 +1,6 @@
+import hello;
+
+int main() {
+ hello::say("hello module!");
+ return 0;
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/hello/xmake.lua b/tests/projects/c++/modules/hello/xmake.lua
new file mode 100644
index 000000000..e22047e4b
--- /dev/null
+++ b/tests/projects/c++/modules/hello/xmake.lua
@@ -0,0 +1,5 @@
+target("hello")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
+
+
diff --git a/tests/projects/c++/modules/impl_unit/src/hello.mpp b/tests/projects/c++/modules/impl_unit/src/hello.mpp
new file mode 100644
index 000000000..0b65bf24e
--- /dev/null
+++ b/tests/projects/c++/modules/impl_unit/src/hello.mpp
@@ -0,0 +1,10 @@
+export module hello;
+
+namespace hello {
+ void say_hi();
+}
+
+export namespace hello {
+ void say_hello();
+ void say_xz();
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
new file mode 100644
index 000000000..1c9968a51
--- /dev/null
+++ b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
@@ -0,0 +1,19 @@
+// module;
+#include <iostream>
+module hello;
+
+using namespace std;
+
+namespace hello {
+ void say_hi() {
+ cout << "hello hi!" << endl;
+ }
+
+ void say_hello() {
+ cout << "hello world!" << endl;
+ }
+
+ void say_xz() {
+ cout << "hello xz!" << endl;
+ }
+}
diff --git a/tests/projects/c++/modules/impl_unit/src/main.cpp b/tests/projects/c++/modules/impl_unit/src/main.cpp
new file mode 100644
index 000000000..378861561
--- /dev/null
+++ b/tests/projects/c++/modules/impl_unit/src/main.cpp
@@ -0,0 +1,8 @@
+import hello;
+
+int main() {
+ hello::say_hello();
+ hello::say_xz();
+ // hello::say_hi();
+ return 0;
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/impl_unit/xmake.lua b/tests/projects/c++/modules/impl_unit/xmake.lua
new file mode 100644
index 000000000..1ce6cb8b6
--- /dev/null
+++ b/tests/projects/c++/modules/impl_unit/xmake.lua
@@ -0,0 +1,5 @@
+target("impl_unit")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
+
+
diff --git a/tests/projects/c++/modules/inline_and_template/src/foo.mpp b/tests/projects/c++/modules/inline_and_template/src/foo.mpp
new file mode 100644
index 000000000..03e15d413
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/src/foo.mpp
@@ -0,0 +1,17 @@
+export module foo;
+
+export {
+ template <typename>
+ struct foo {
+ constexpr const char* hello(void) const {
+ return "hello typename!";
+ }
+ };
+
+ // template <>
+ // struct foo<int> {
+ // constexpr const char* hello(void) const {
+ // return "hello typename int!";
+ // }
+ // };
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/inline_and_template/src/foo_impl.cpp b/tests/projects/c++/modules/inline_and_template/src/foo_impl.cpp
new file mode 100644
index 000000000..c44ef849b
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/src/foo_impl.cpp
@@ -0,0 +1,8 @@
+module foo;
+
+template <>
+struct foo<int> {
+ constexpr const char* hello(void) const {
+ return "hello int!";
+ }
+}; \ No newline at end of file
diff --git a/tests/projects/c++/modules/inline_and_template/src/hello.mpp b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
new file mode 100644
index 000000000..1796f0b11
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
@@ -0,0 +1,9 @@
+// module;
+#include <cstdio>
+export module hello;
+
+export namespace hello {
+ inline void say_hello() {
+ std::printf("hello world!\n");
+ }
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/inline_and_template/src/main.cpp b/tests/projects/c++/modules/inline_and_template/src/main.cpp
new file mode 100644
index 000000000..a34667fbe
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/src/main.cpp
@@ -0,0 +1,12 @@
+import hello;
+import say;
+import foo;
+
+#include <iostream>
+
+int main() {
+ hello::say_hello();
+ say{}.hello<sizeof(say)>();
+ std::cout << foo<int>{}.hello() << std::endl;
+ return 0;
+} \ No newline at end of file
diff --git a/tests/projects/c++/modules/inline_and_template/src/say.mpp b/tests/projects/c++/modules/inline_and_template/src/say.mpp
new file mode 100644
index 000000000..d09e14d28
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/src/say.mpp
@@ -0,0 +1,11 @@
+// module;
+#include <cstdio>
+export module say;
+
+export class say {
+public:
+ template <int N>
+ void hello() {
+ std::printf("hello, say class: %d\n", N);
+ }
+}; \ No newline at end of file
diff --git a/tests/projects/c++/modules/inline_and_template/xmake.lua b/tests/projects/c++/modules/inline_and_template/xmake.lua
new file mode 100644
index 000000000..e22a0ef04
--- /dev/null
+++ b/tests/projects/c++/modules/inline_and_template/xmake.lua
@@ -0,0 +1,6 @@
+target("inline_and_template")
+ set_kind("binary")
+ add_files("src/*.cpp", "src/*.mpp")
+ set_languages("c++11")
+
+
diff --git a/tests/projects/objc++/modulemap/src/hello.h b/tests/projects/objc++/modulemap/src/hello.h
new file mode 100644
index 000000000..7eb60b9e6
--- /dev/null
+++ b/tests/projects/objc++/modulemap/src/hello.h
@@ -0,0 +1,7 @@
+#import <Foundation/Foundation.h>
+
+@interface Hello : NSObject
+
++ (void)say:(NSString*)s;
+
+@end
diff --git a/tests/projects/objc++/modulemap/src/hello.m b/tests/projects/objc++/modulemap/src/hello.m
new file mode 100644
index 000000000..b22f844f2
--- /dev/null
+++ b/tests/projects/objc++/modulemap/src/hello.m
@@ -0,0 +1,10 @@
+#import "hello.h"
+
+@implementation Hello
+
++ (void)say:(NSString*)s
+{
+ NSLog(@"%@\n", s);
+}
+
+@end
diff --git a/tests/projects/objc++/modulemap/src/main.mm b/tests/projects/objc++/modulemap/src/main.mm
new file mode 100644
index 000000000..5f6fd74cb
--- /dev/null
+++ b/tests/projects/objc++/modulemap/src/main.mm
@@ -0,0 +1,8 @@
+#import <Foundation/Foundation.h>
+@import Hello;
+
+int main(int argc, char** argv)
+{
+ [Hello say:@"hello"];
+ return 0;
+}
diff --git a/tests/projects/objc++/modulemap/src/module.modulemap b/tests/projects/objc++/modulemap/src/module.modulemap
new file mode 100644
index 000000000..91a9c4235
--- /dev/null
+++ b/tests/projects/objc++/modulemap/src/module.modulemap
@@ -0,0 +1,4 @@
+module Hello {
+ header "hello.h"
+ export *
+}
diff --git a/tests/projects/objc++/modulemap/xmake.lua b/tests/projects/objc++/modulemap/xmake.lua
new file mode 100644
index 000000000..a7cdbc308
--- /dev/null
+++ b/tests/projects/objc++/modulemap/xmake.lua
@@ -0,0 +1,6 @@
+target("modulemap")
+ set_kind("binary")
+ add_files("src/*.mm", "src/*.m")
+ add_mxxflags("-fmodules", "-fcxx-modules", "-fmodule-map-file=src/module.modulemap")
+
+
diff --git a/tests/projects/objc/modulemap/src/hello.h b/tests/projects/objc/modulemap/src/hello.h
new file mode 100644
index 000000000..7eb60b9e6
--- /dev/null
+++ b/tests/projects/objc/modulemap/src/hello.h
@@ -0,0 +1,7 @@
+#import <Foundation/Foundation.h>
+
+@interface Hello : NSObject
+
++ (void)say:(NSString*)s;
+
+@end
diff --git a/tests/projects/objc/modulemap/src/hello.m b/tests/projects/objc/modulemap/src/hello.m
new file mode 100644
index 000000000..b22f844f2
--- /dev/null
+++ b/tests/projects/objc/modulemap/src/hello.m
@@ -0,0 +1,10 @@
+#import "hello.h"
+
+@implementation Hello
+
++ (void)say:(NSString*)s
+{
+ NSLog(@"%@\n", s);
+}
+
+@end
diff --git a/tests/projects/objc/modulemap/src/main.m b/tests/projects/objc/modulemap/src/main.m
new file mode 100644
index 000000000..5f6fd74cb
--- /dev/null
+++ b/tests/projects/objc/modulemap/src/main.m
@@ -0,0 +1,8 @@
+#import <Foundation/Foundation.h>
+@import Hello;
+
+int main(int argc, char** argv)
+{
+ [Hello say:@"hello"];
+ return 0;
+}
diff --git a/tests/projects/objc/modulemap/src/module.modulemap b/tests/projects/objc/modulemap/src/module.modulemap
new file mode 100644
index 000000000..91a9c4235
--- /dev/null
+++ b/tests/projects/objc/modulemap/src/module.modulemap
@@ -0,0 +1,4 @@
+module Hello {
+ header "hello.h"
+ export *
+}
diff --git a/tests/projects/objc/modulemap/xmake.lua b/tests/projects/objc/modulemap/xmake.lua
new file mode 100644
index 000000000..db00678f2
--- /dev/null
+++ b/tests/projects/objc/modulemap/xmake.lua
@@ -0,0 +1,6 @@
+target("modulemap")
+ set_kind("binary")
+ add_files("src/*.m")
+ add_mflags("-fmodules", "-fmodule-map-file=src/module.modulemap")
+
+
diff --git a/tests/projects/swift/modulemap/src/hello.cpp b/tests/projects/swift/modulemap/src/hello.cpp
new file mode 100644
index 000000000..42b01afac
--- /dev/null
+++ b/tests/projects/swift/modulemap/src/hello.cpp
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include "hello.h"
+
+void say1(char const* s) {
+ printf("%s\n", s);
+}
+
+
diff --git a/tests/projects/swift/modulemap/src/hello.h b/tests/projects/swift/modulemap/src/hello.h
new file mode 100644
index 000000000..80849f5df
--- /dev/null
+++ b/tests/projects/swift/modulemap/src/hello.h
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void say1(char const* s);
+#ifdef __cplusplus
+}
+#endif
+static inline void say2(char const* s) {
+ printf("%s\n", s);
+}
+
+
diff --git a/tests/projects/swift/modulemap/src/main.swift b/tests/projects/swift/modulemap/src/main.swift
new file mode 100644
index 000000000..0cc015090
--- /dev/null
+++ b/tests/projects/swift/modulemap/src/main.swift
@@ -0,0 +1,5 @@
+import Foundation
+import hello
+
+hello.say1("hello1")
+hello.say2("hello2")
diff --git a/tests/projects/swift/modulemap/src/module.modulemap b/tests/projects/swift/modulemap/src/module.modulemap
new file mode 100644
index 000000000..69c787ee2
--- /dev/null
+++ b/tests/projects/swift/modulemap/src/module.modulemap
@@ -0,0 +1,4 @@
+module hello {
+ header "hello.h"
+ export *
+}
diff --git a/tests/projects/swift/modulemap/xmake.lua b/tests/projects/swift/modulemap/xmake.lua
new file mode 100644
index 000000000..fb329e99e
--- /dev/null
+++ b/tests/projects/swift/modulemap/xmake.lua
@@ -0,0 +1,4 @@
+target("modulemap")
+ set_kind("binary")
+ add_files("src/*.swift", "src/*.cpp")
+ add_scflags("-Xcc -fmodules", "-Xcc -fmodule-map-file=src/module.modulemap")
diff --git a/xmake/actions/build/kinds/object.lua b/xmake/actions/build/kinds/object.lua
index 8cf9bba99..2959a0114 100644
--- a/xmake/actions/build/kinds/object.lua
+++ b/xmake/actions/build/kinds/object.lua
@@ -33,9 +33,18 @@ function _build_files_with_rule(target, sourcebatch, opt, suffix)
-- get rule instance
local ruleinst = assert(project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename)
+ -- get progress
+ local progress = opt.progress
+
-- on_build_files?
local on_build_files = ruleinst:script("build_files" .. (suffix and ("_" .. suffix) or ""))
if on_build_files then
+ opt = table.copy(opt)
+ if suffix == "before" then
+ opt.progress = {start = progress.start, stop = progress.start}
+ elseif suffix == "after" then
+ opt.progress = {start = progress.stop, stop = progress.stop}
+ end
on_build_files(target, sourcebatch, opt)
else
-- get the build file script
@@ -45,9 +54,6 @@ function _build_files_with_rule(target, sourcebatch, opt, suffix)
-- get the max job count
local jobs = tonumber(option.get("jobs") or "4")
- -- get progress range
- local progress = opt.progress
-
-- run build jobs for each source file
local curdir = os.curdir()
local sourcecount = #sourcebatch.sourcefiles
@@ -56,7 +62,7 @@ function _build_files_with_rule(target, sourcebatch, opt, suffix)
-- force to set the current directory first because the other jobs maybe changed it
os.cd(curdir)
- -- calculate progress
+ -- get current progress
local progress_now = progress.start + ((index - 1) * (progress.stop - progress.start)) / sourcecount
if suffix == "before" then
progress_now = progress.start
@@ -86,6 +92,8 @@ function _build_files(target, sourcebatch, opt)
-- do before build
local before_build_files = target:script("build_files_before")
if before_build_files then
+ opt = table.copy(opt)
+ opt.progress = {start = progress.start, stop = progress.start}
before_build_files(target, sourcebatch, opt)
end
@@ -102,6 +110,8 @@ function _build_files(target, sourcebatch, opt)
-- do after build
local after_build_files = target:script("build_files_after")
if after_build_files then
+ opt = table.copy(opt)
+ opt.progress = {start = progress.stop, stop = progress.stop}
after_build_files(target, sourcebatch, opt)
end
end
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index c5a8c7322..292adacba 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -43,9 +43,10 @@ local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- new an instance
function _instance.new(name, info)
- local instance = table.inherit(_instance)
- instance._NAME = name
- instance._INFO = info
+ local instance = table.inherit(_instance)
+ instance._NAME = name
+ instance._INFO = info
+ instance._CACHEID = 1
return instance
end
@@ -181,6 +182,11 @@ function _instance:_check()
io.flush()
end
+-- invalidate the previous cache key
+function _instance:_invalidate()
+ self._CACHEID = self._CACHEID + 1
+end
+
-- attempt to check option
function _instance:check()
@@ -296,16 +302,19 @@ end
-- set the value to the option info
function _instance:set(name, ...)
self._INFO:apival_set(name, ...)
+ self:_invalidate()
end
-- add the value to the option info
function _instance:add(name, ...)
self._INFO:apival_add(name, ...)
+ self:_invalidate()
end
-- remove the value to the option info
function _instance:del(name, ...)
self._INFO:apival_del(name, ...)
+ self:_invalidate()
end
-- get the extra configuration
@@ -336,6 +345,11 @@ function _instance:name()
return self._NAME
end
+-- get the cache key
+function _instance:cachekey()
+ return string.format("%s_%d", tostring(self), self._CACHEID)
+end
+
-- get xxx_script
function _instance:script(name)
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 911d8ddbf..5584ed569 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -48,6 +48,7 @@ function _instance.new(name, info, project)
instance._NAME = name
instance._INFO = info
instance._PROJECT = project
+ instance._CACHEID = 1
return instance
end
@@ -239,6 +240,11 @@ function _instance:_visibility(opt)
return visibility
end
+-- invalidate the previous cache key
+function _instance:_invalidate()
+ self._CACHEID = self._CACHEID + 1
+end
+
-- get the target info
--
-- e.g.
@@ -298,16 +304,19 @@ end
-- set the value to the target info
function _instance:set(name, ...)
self._INFO:apival_set(name, ...)
+ self:_invalidate()
end
-- add the value to the target info
function _instance:add(name, ...)
self._INFO:apival_add(name, ...)
+ self:_invalidate()
end
-- remove the value to the target info
function _instance:del(name, ...)
self._INFO:apival_del(name, ...)
+ self:_invalidate()
end
-- get the extra configuration
@@ -387,6 +396,11 @@ function _instance:name()
return self._NAME
end
+-- get the cache key
+function _instance:cachekey()
+ return string.format("%s_%d", tostring(self), self._CACHEID)
+end
+
-- get the target version
function _instance:version()
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
index f9cd6fe3d..e618f34ce 100644
--- a/xmake/core/tool/builder.lua
+++ b/xmake/core/tool/builder.lua
@@ -307,7 +307,7 @@ function builder:_add_flags_from_target(flags, target)
local cache = self._TARGETFLAGS
-- get flags from cache first
- local key = tostring(target)
+ local key = target:cachekey()
local targetflags = cache[key]
if not targetflags then
diff --git a/xmake/languages/c++/xmake.lua b/xmake/languages/c++/xmake.lua
index 93f0eb528..97c3bdca5 100644
--- a/xmake/languages/c++/xmake.lua
+++ b/xmake/languages/c++/xmake.lua
@@ -40,7 +40,7 @@ language("c++")
set_mixingkinds("cc", "cxx", "as", "mrc")
-- add rules
- add_rules("cpp")
+ add_rules("c++")
-- on load
on_load("load")
diff --git a/xmake/modules/private/action/build/object.lua b/xmake/modules/private/action/build/object.lua
index abfb3682b..209d99bfe 100644
--- a/xmake/modules/private/action/build/object.lua
+++ b/xmake/modules/private/action/build/object.lua
@@ -38,7 +38,7 @@ function _do_build_file(target, sourcefile, opt)
local compinst = compiler.load(sourcekind, {target = target})
-- get compile flags
- local compflags = compinst:compflags({target = target, sourcefile = sourcefile})
+ local compflags = compinst:compflags({target = target, sourcefile = sourcefile, configs = opt.configs})
-- load dependent info
local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
@@ -56,11 +56,13 @@ function _do_build_file(target, sourcefile, opt)
local exists_ccache = ccache.exists()
-- trace progress info
- cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress)
- if verbose then
- cprint("${dim color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile)
- else
- cprint("${color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile)
+ if not opt.quiet then
+ cprintf("${color.build.progress}" .. theme.get("text.build.progress_format") .. ":${clear} ", progress)
+ if verbose then
+ cprint("${dim color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile)
+ else
+ cprint("${color.build.object}%scompiling.$(mode) %s", exists_ccache and "ccache " or "", sourcefile)
+ end
end
-- trace verbose info
@@ -97,7 +99,7 @@ function _build_object(target, sourcebatch, index, opt)
local progress_now = progress.start + ((index - 1) * (progress.stop - progress.start)) / #sourcebatch.sourcefiles
-- init build option
- local opt = {objectfile = objectfile, dependfile = dependfile, sourcekind = sourcekind, progress = progress_now}
+ local opt = table.join(opt, {objectfile = objectfile, dependfile = dependfile, sourcekind = sourcekind, progress = progress_now})
-- do before build
local before_build_file = target:script("build_file_before")
diff --git a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
index 149330276..24310bf7d 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x_vcproj.lua
@@ -410,7 +410,7 @@ end
function _make_cxfile(vcprojfile, vsinfo, target, sourcefile, objectfile, vcprojdir)
-- get the target key
- local key = tostring(target)
+ local key = target:cachekey()
-- make flags cache
_g.flags = _g.flags or {}
diff --git a/xmake/rules/asm/xmake.lua b/xmake/rules/asm/xmake.lua
index 3a7e85f59..9adc87ab7 100644
--- a/xmake/rules/asm/xmake.lua
+++ b/xmake/rules/asm/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: asm.build
rule("asm.build")
set_extensions(".s", ".asm")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
-- define rule: asm
rule("asm")
diff --git a/xmake/rules/c++/modules/build_modulefiles.lua b/xmake/rules/c++/modules/build_modulefiles.lua
new file mode 100644
index 000000000..08924e814
--- /dev/null
+++ b/xmake/rules/c++/modules/build_modulefiles.lua
@@ -0,0 +1,138 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed 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 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file build_modulefiles.lua
+--
+
+-- imports
+import("core.tool.compiler")
+
+-- build module files using clang
+function _build_modulefiles_clang(target, sourcebatch, opt)
+
+ -- attempt to compile the module files as cxx
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = target:objectfile(sourcefile) .. ".pcm"
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, target:dependfile(objectfile))
+ end
+
+ -- compile module files to *.pcm
+ opt = table.join(opt, {configs = {cxxflags = {"-fmodules-ts", "--precompile", "-x c++-module"}}})
+ import("private.action.build.object")(target, sourcebatch, opt)
+
+ -- compile *.pcm to object files
+ local modulefiles = {}
+ for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local modulefile = sourcebatch.objectfiles[idx]
+ local objectfile = target:objectfile(sourcefile)
+ sourcebatch.sourcefiles[idx] = modulefile
+ sourcebatch.objectfiles[idx] = objectfile
+ sourcebatch.dependfiles[idx] = target:dependfile(objectfile)
+ table.insert(modulefiles, modulefile)
+ end
+ opt.configs = {cxxflags = {"-fmodules-ts"}}
+ opt.quiet = true
+ import("private.action.build.object")(target, sourcebatch, opt)
+
+ -- add module files
+ target:add("cxxflags", "-fmodules-ts")
+ for _, modulefile in ipairs(modulefiles) do
+ target:add("cxxflags", "-fmodule-file=" .. modulefile)
+ end
+end
+
+-- TODO
+-- build module files using gcc
+function _build_modulefiles_gcc(target, sourcebatch, opt)
+
+ --[[
+ -- attempt to compile the module files as cxx
+ local modulefiles = {}
+ opt = table.join(opt, {configs = {}})
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = target:objectfile(sourcefile)
+ local dependfile = target:dependfile(objectfile)
+ local modulefile = objectfile .. ".pcm"
+
+ -- compile module file to *.pcm
+ local singlebatch = {sourcekind = "cxx", sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}}
+ opt.configs.cxxflags = {"-fmodules-ts", "-fmodule-output=" .. modulefile, "-x c++"}
+ import("private.action.build.object")(target, singlebatch, opt)
+ table.insert(modulefiles, modulefile)
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, dependfile)
+ end
+
+ -- add module files
+ for _, modulefile in ipairs(modulefiles) do
+ target:add("cxxflags", "-fmodules-ts", "-fmodule-file=" .. modulefile)
+ end]]
+ raise("compiler(gcc): not implemented for c++ module!")
+end
+
+-- build module files using msvc
+function _build_modulefiles_msvc(target, sourcebatch, opt)
+
+ -- attempt to compile the module files as cxx
+ local modulefiles = {}
+ opt = table.join(opt, {configs = {}})
+ sourcebatch.sourcekind = "cxx"
+ sourcebatch.objectfiles = sourcebatch.objectfiles or {}
+ sourcebatch.dependfiles = sourcebatch.dependfiles or {}
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = target:objectfile(sourcefile)
+ local dependfile = target:dependfile(objectfile)
+ local modulefile = objectfile .. ".pcm"
+
+ -- compile module file to *.pcm
+ local singlebatch = {sourcekind = "cxx", sourcefiles = {sourcefile}, objectfiles = {objectfile}, dependfiles = {dependfile}}
+ opt.configs.cxxflags = {"/experimental:module /module:interface /module:output " .. os.args(modulefile), "/TP"}
+ import("private.action.build.object")(target, singlebatch, opt)
+ table.insert(modulefiles, modulefile)
+ table.insert(sourcebatch.objectfiles, objectfile)
+ table.insert(sourcebatch.dependfiles, dependfile)
+ end
+
+ -- add module files
+ for _, modulefile in ipairs(modulefiles) do
+ target:add("cxxflags", "/experimental:module /module:reference " .. os.args(modulefile))
+ end
+end
+
+-- build module files
+function main(target, sourcebatch, opt)
+
+ -- do compile
+ local compinst = compiler.load("cxx")
+ if compinst:name() == "clang" and compinst:has_flags("-fmodules-ts") then
+ _build_modulefiles_clang(target, sourcebatch, opt)
+ elseif compinst:name() == "gcc" and compinst:has_flags("-fmodules-ts") then
+ _build_modulefiles_gcc(target, sourcebatch, opt)
+ elseif compinst:name() == "cl" and compinst:has_flags("/experimental:module") then
+ _build_modulefiles_msvc(target, sourcebatch, opt)
+ else
+ raise("compiler(%s): does not support c++ module!", compinst:name())
+ end
+end
+
diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua
new file mode 100644
index 000000000..29f0b28f7
--- /dev/null
+++ b/xmake/rules/c++/modules/xmake.lua
@@ -0,0 +1,25 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed 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 - 2019, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file xmake.lua
+--
+
+-- define rule: c++.build.modules
+rule("c++.build.modules")
+ set_extensions(".mpp", ".mxx", ".cppm", ".ixx")
+ before_build_files("build_modulefiles")
+
diff --git a/xmake/rules/c++/xmake.lua b/xmake/rules/c++/xmake.lua
index 1330fbfca..cb5f5b43c 100644
--- a/xmake/rules/c++/xmake.lua
+++ b/xmake/rules/c++/xmake.lua
@@ -28,24 +28,20 @@ rule("c.build.pcheader")
rule("c.build")
set_extensions(".c")
add_deps("c.build.pcheader")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
--- define rule: cpp.build.pcheader
-rule("cpp.build.pcheader")
+-- define rule: c++.build.pcheader
+rule("c++.build.pcheader")
before_build(function (target, opt)
import("private.action.build.pcheader")(target, "cxx", opt)
end)
--- define rule: cpp.build
-rule("cpp.build")
+-- define rule: c++.build
+rule("c++.build")
set_extensions(".cpp", ".cc", ".cxx")
- add_deps("cpp.build.pcheader")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ add_deps("c++.build.pcheader", "c++.build.modules")
+ on_build_files("private.action.build.object")
-- define rule: cpp
-rule("cpp")
- add_deps("cpp.build", "c.build", "utils.merge.object", "utils.merge.archive")
+rule("c++")
+ add_deps("c++.build", "c.build", "utils.merge.object", "utils.merge.archive")
diff --git a/xmake/rules/dlang/xmake.lua b/xmake/rules/dlang/xmake.lua
index 27f06c432..95615a3ec 100644
--- a/xmake/rules/dlang/xmake.lua
+++ b/xmake/rules/dlang/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: dlang.build
rule("dlang.build")
set_extensions(".d")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
-- define rule: dlang
rule("dlang")
diff --git a/xmake/rules/go/xmake.lua b/xmake/rules/go/xmake.lua
index 97d929e08..2830ce6fb 100644
--- a/xmake/rules/go/xmake.lua
+++ b/xmake/rules/go/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: go.build
rule("go.build")
set_extensions(".go")
- on_build_files(function (target, sourcebatch, opt)
- import("build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("build.object")
-- define rule: cpp
rule("go")
diff --git a/xmake/rules/objc++/xmake.lua b/xmake/rules/objc++/xmake.lua
index 986e3d1a3..7356cf36d 100644
--- a/xmake/rules/objc++/xmake.lua
+++ b/xmake/rules/objc++/xmake.lua
@@ -22,17 +22,13 @@
rule("objc.build")
set_extensions(".m")
add_deps("c.build.pcheader")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
-- define rule: objc++.build
rule("objc++.build")
set_extensions(".mm")
- add_deps("cpp.build.pcheader")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ add_deps("c++.build.pcheader")
+ on_build_files("private.action.build.object")
-- define rule: objc
rule("objc++")
diff --git a/xmake/rules/rust/xmake.lua b/xmake/rules/rust/xmake.lua
index 3d88f2c96..50ad79a89 100644
--- a/xmake/rules/rust/xmake.lua
+++ b/xmake/rules/rust/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: rust.build
rule("rust.build")
set_extensions(".rs")
- on_build(function (target, opt)
- import("build.target")(target, opt)
- end)
+ on_build("build.target")
-- define rule: cpp
rule("rust")
diff --git a/xmake/rules/swift/xmake.lua b/xmake/rules/swift/xmake.lua
index 9be96096d..04fbfbcab 100644
--- a/xmake/rules/swift/xmake.lua
+++ b/xmake/rules/swift/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: swift.build
rule("swift.build")
set_extensions(".swift")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
-- define rule: swift
rule("swift")
diff --git a/xmake/rules/winsdk/xmake.lua b/xmake/rules/winsdk/xmake.lua
index e5190fc31..81fc72650 100644
--- a/xmake/rules/winsdk/xmake.lua
+++ b/xmake/rules/winsdk/xmake.lua
@@ -21,9 +21,7 @@
-- define rule: win.sdk.resource
rule("win.sdk.resource")
set_extensions(".rc")
- on_build_files(function (target, sourcebatch, opt)
- import("private.action.build.object")(target, sourcebatch, opt)
- end)
+ on_build_files("private.action.build.object")
-- define rule: application
rule("win.sdk.application")