summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-10-12 22:51:27 +0800
committerGitHub <[email protected]>2021-10-12 22:51:27 +0800
commit1666e13096f40ce0cd6b1563a5bac4cc1dac5ccb (patch)
tree3e0a1ac46103ed13b8e50a4394c166a71564cade
parent2829b6248dc66799d1f21407bbe2ac1ddfec9d5c (diff)
parent6d94f1182d93b04f854f90599e3878fd5826939e (diff)
Merge pull request #1740 from xmake-io/modules
Improve C++20 modules for clang/gcc/msvc
-rw-r--r--tests/projects/c++/modules/class/src/hello.mpp3
-rw-r--r--tests/projects/c++/modules/class/src/hello_impl.cpp7
-rw-r--r--tests/projects/c++/modules/dependence/src/hello.mpp13
-rw-r--r--tests/projects/c++/modules/dependence/src/hello_impl.cpp6
-rw-r--r--tests/projects/c++/modules/hello/src/hello.mpp7
-rw-r--r--tests/projects/c++/modules/impl_unit/src/hello_impl.cpp4
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/hello.mpp6
-rw-r--r--tests/projects/c++/modules/inline_and_template/src/say.mpp6
-rw-r--r--xmake/rules/c++/modules/build_modulefiles.lua122
9 files changed, 93 insertions, 81 deletions
diff --git a/tests/projects/c++/modules/class/src/hello.mpp b/tests/projects/c++/modules/class/src/hello.mpp
index 9e4ecd960..268964aa3 100644
--- a/tests/projects/c++/modules/class/src/hello.mpp
+++ b/tests/projects/c++/modules/class/src/hello.mpp
@@ -5,8 +5,7 @@ export namespace hello {
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
index 6d0008fbb..5dd555a7a 100644
--- a/tests/projects/c++/modules/class/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/class/src/hello_impl.cpp
@@ -1,14 +1,13 @@
-module hello;
-
+module;
#include <iostream>
-using namespace std;
+module hello;
+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/dependence/src/hello.mpp b/tests/projects/c++/modules/dependence/src/hello.mpp
index 3f803afaf..abac9fcb0 100644
--- a/tests/projects/c++/modules/dependence/src/hello.mpp
+++ b/tests/projects/c++/modules/dependence/src/hello.mpp
@@ -1,27 +1,14 @@
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
-*/ \ No newline at end of file
diff --git a/tests/projects/c++/modules/dependence/src/hello_impl.cpp b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
index 5dbc009f4..064afebad 100644
--- a/tests/projects/c++/modules/dependence/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/dependence/src/hello_impl.cpp
@@ -1,6 +1,7 @@
-module hello;
-
+module;
#include <iostream>
+
+module hello;
import mod;
void inner() {
@@ -13,7 +14,6 @@ namespace hello {
void say_hello() { ::inner(); }
say::say(int data) : data_{data} {
-
}
void say::hello() {
diff --git a/tests/projects/c++/modules/hello/src/hello.mpp b/tests/projects/c++/modules/hello/src/hello.mpp
index 9bbd036f0..124bd72bc 100644
--- a/tests/projects/c++/modules/hello/src/hello.mpp
+++ b/tests/projects/c++/modules/hello/src/hello.mpp
@@ -1,11 +1,10 @@
-export module hello;
-
+module;
#include <cstdio>
-using namespace std;
+export module hello;
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/impl_unit/src/hello_impl.cpp b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
index 9cee17cfd..eccfed5d3 100644
--- a/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
+++ b/tests/projects/c++/modules/impl_unit/src/hello_impl.cpp
@@ -1,7 +1,7 @@
-module hello;
-
+module;
#include <iostream>
+module hello;
using namespace std;
namespace hello {
diff --git a/tests/projects/c++/modules/inline_and_template/src/hello.mpp b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
index c36d54783..94d40ddaa 100644
--- a/tests/projects/c++/modules/inline_and_template/src/hello.mpp
+++ b/tests/projects/c++/modules/inline_and_template/src/hello.mpp
@@ -1,9 +1,9 @@
-export module hello;
-
+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/say.mpp b/tests/projects/c++/modules/inline_and_template/src/say.mpp
index b4d05a5f4..ab3290cf9 100644
--- a/tests/projects/c++/modules/inline_and_template/src/say.mpp
+++ b/tests/projects/c++/modules/inline_and_template/src/say.mpp
@@ -1,11 +1,11 @@
-export module say;
-
+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/xmake/rules/c++/modules/build_modulefiles.lua b/xmake/rules/c++/modules/build_modulefiles.lua
index 4e26f1eca..a41ab2f39 100644
--- a/xmake/rules/c++/modules/build_modulefiles.lua
+++ b/xmake/rules/c++/modules/build_modulefiles.lua
@@ -24,6 +24,19 @@ import("core.tool.compiler")
-- build module files using clang
function _build_modulefiles_clang(target, sourcebatch, opt)
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules") then
+ modulesflag = "-fmodules"
+ elseif compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(clang): does not support c++ module!")
+
+ -- the module cache directory
+ local cachedir = path.join(target:autogendir(), "rules", "modules", "cache")
+
-- attempt to compile the module files as cxx
sourcebatch.sourcekind = "cxx"
sourcebatch.objectfiles = sourcebatch.objectfiles or {}
@@ -35,7 +48,8 @@ function _build_modulefiles_clang(target, sourcebatch, opt)
end
-- compile module files to *.pcm
- opt = table.join(opt, {configs = {force = {cxxflags = {opt.modulesflag, "--precompile", "-x c++-module"}}}})
+ opt = table.join(opt, {configs = {force = {cxxflags = {modulesflag,
+ "--precompile", "-x c++-module", "-fmodules-cache-path=" .. cachedir}}}})
import("private.action.build.object").build(target, sourcebatch, opt)
-- compile *.pcm to object files
@@ -48,52 +62,84 @@ function _build_modulefiles_clang(target, sourcebatch, opt)
sourcebatch.dependfiles[idx] = target:dependfile(objectfile)
table.insert(modulefiles, modulefile)
end
- opt.configs = {cxxflags = {opt.modulesflag}}
+ opt.configs = {cxxflags = {modulesflag, "-fmodules-cache-path=" .. cachedir}}
opt.quiet = true
import("private.action.build.object").build(target, sourcebatch, opt)
-- add module files
- target:add("cxxflags", opt.modulesflag)
+ target:add("cxxflags", opt.modulesflag, "-fmodules-cache-path=" .. cachedir)
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)
- --[[
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("-fmodules-ts") then
+ modulesflag = "-fmodules-ts"
+ end
+ assert(modulesflag, "compiler(gcc): does not support c++ module!")
+
-- 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", "-fmodule-output=" .. modulefile, "-x c++"}
- import("private.action.build.object").build(target, singlebatch, opt)
- table.insert(modulefiles, modulefile)
table.insert(sourcebatch.objectfiles, objectfile)
- table.insert(sourcebatch.dependfiles, dependfile)
+ table.insert(sourcebatch.dependfiles, target:dependfile(objectfile))
end
+ -- compile module files to object files
+ opt = table.join(opt, {configs = {force = {cxxflags = {modulesflag, "-x c++"}}}})
+ import("private.action.build.object").build(target, sourcebatch, opt)
+
-- add module files
- for _, modulefile in ipairs(modulefiles) do
- target:add("cxxflags", "-fmodules", "-fmodule-file=" .. modulefile)
- end]]
- raise("compiler(gcc): not implemented for c++ module!")
+ target:add("cxxflags", modulesflag)
end
-- build module files using msvc
function _build_modulefiles_msvc(target, sourcebatch, opt)
+ -- get modules flag
+ local modulesflag
+ local compinst = compiler.load("cxx", {target = target})
+ if compinst:has_flags("/experimental:module") then
+ modulesflag = "/experimental:module"
+ end
+ assert(modulesflag, "compiler(msvc): does not support c++ module!")
+
+ -- get output flag
+ local outputflag
+ if compinst:has_flags("/ifcOutput") then
+ outputflag = "/ifcOutput"
+ elseif compinst:has_flags("/module:output") then
+ outputflag = "/module:output"
+ end
+ assert(outputflag, "compiler(msvc): does not support c++ module!")
+
+ -- get interface flag
+ local interfaceflag
+ if compinst:has_flags("/interface") then
+ interfaceflag = "/interface"
+ elseif compinst:has_flags("/module:interface") then
+ interfaceflag = "/module:interface"
+ end
+ assert(interfaceflag, "compiler(msvc): does not support c++ module!")
+
+ -- get reference flag
+ local referenceflag
+ if compinst:has_flags("/reference") then
+ referenceflag = "/reference"
+ elseif compinst:has_flags("/module:interface") then
+ referenceflag = "/module:reference"
+ end
+ assert(referenceflag, "compiler(msvc): does not support c++ module!")
+
-- attempt to compile the module files as cxx
local modulefiles = {}
opt = table.join(opt, {configs = {}})
@@ -107,7 +153,7 @@ function _build_modulefiles_msvc(target, sourcebatch, opt)
-- 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"}
+ opt.configs.cxxflags = {modulesflag, interfaceflag, outputflag .. " " .. os.args(modulefile), "/TP"}
import("private.action.build.object").build(target, singlebatch, opt)
table.insert(modulefiles, modulefile)
table.insert(sourcebatch.objectfiles, objectfile)
@@ -116,38 +162,20 @@ function _build_modulefiles_msvc(target, sourcebatch, opt)
-- add module files
for _, modulefile in ipairs(modulefiles) do
- target:add("cxxflags", "/experimental:module /module:reference " .. os.args(modulefile))
+ target:add("cxxflags", modulesflag, referenceflag .. " " .. os.args(modulefile))
end
end
-- build module files
function main(target, sourcebatch, opt)
-
- -- do compile
- local modulesflag = nil
local _, toolname = target:tool("cxx")
- local compinst = compiler.load("cxx")
- if toolname:find("clang", 1, true) or toolname:find("gcc", 1, true) then
- if compinst:has_flags("-fmodules") then
- modulesflag = "-fmodules"
- elseif compinst:has_flags("-fmodules-ts") then
- modulesflag = "-fmodules-ts"
- end
+ if toolname:find("clang", 1, true) then
+ _build_modulefiles_clang(target, sourcebatch, opt)
+ elseif toolname:find("gcc", 1, true) then
+ _build_modulefiles_gcc(target, sourcebatch, opt)
elseif toolname == "cl" then
- if compinst:has_flags("/experimental:module") then
- modulesflag = "/experimental:module"
- end
- end
- if modulesflag then
- opt.modulesflag = modulesflag
- if toolname:find("clang", 1, true) then
- _build_modulefiles_clang(target, sourcebatch, opt)
- elseif toolname:find("gcc", 1, true) then
- _build_modulefiles_gcc(target, sourcebatch, opt)
- elseif toolname == "cl" then
- _build_modulefiles_msvc(target, sourcebatch, opt)
- else
- raise("compiler(%s): does not support c++ module!", toolname)
- end
+ _build_modulefiles_msvc(target, sourcebatch, opt)
+ else
+ raise("compiler(%s): does not support c++ module!", toolname)
end
end