diff options
| author | ruki <[email protected]> | 2019-09-12 12:32:53 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-09-12 12:32:53 +0800 |
| commit | 961b833b032ee06ffd4f5de96a11013edb8498a7 (patch) | |
| tree | a7f2378ae72fa63607267286ffd6dacd11086b89 | |
| parent | c58d64d433d2a3e2c97ead29738722aa653ae88a (diff) | |
| parent | ce51c2de7c11b6368ce8956329f9ebbe4ffd1b67 (diff) | |
Merge pull request #569 from xmake-io/cppmodules
Add c++ modules ts build rules
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") |
