summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-08-15 11:19:15 +0800
committerGitHub <[email protected]>2022-08-15 11:19:15 +0800
commit4e4559e121c1ea1387874809fb448548dc0dba80 (patch)
treea994abe7a9836df6afe1bd201cda2dd2864b9d99
parent595a078ba33abd374cf900a07570222151caf605 (diff)
parentff971cdfeb55701078e894c380939ed7146b5638 (diff)
Merge pull request #2673 from xmake-io/generator
improve generator for cxxmodules
-rw-r--r--tests/projects/c++/modules/dependence/CMakeLists.txt43
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua10
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua253
-rw-r--r--xmake/plugins/project/make/makefile.lua14
-rw-r--r--xmake/rules/c++/modules/modules_support/clang.lua14
-rw-r--r--xmake/rules/c++/modules/modules_support/common.lua2
-rw-r--r--xmake/rules/c++/modules/modules_support/gcc.lua10
-rw-r--r--xmake/rules/c++/modules/modules_support/msvc.lua14
-rw-r--r--xmake/rules/c++/modules/xmake.lua1
9 files changed, 207 insertions, 154 deletions
diff --git a/tests/projects/c++/modules/dependence/CMakeLists.txt b/tests/projects/c++/modules/dependence/CMakeLists.txt
deleted file mode 100644
index 19eb7793a..000000000
--- a/tests/projects/c++/modules/dependence/CMakeLists.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-# this is the build file for project
-# it is autogenerated by the xmake build system.
-# do not edit by hand.
-
-# project
-cmake_minimum_required(VERSION 3.15.0)
-cmake_policy(SET CMP0091 NEW)
-project(dependence LANGUAGES CXX C)
-
-# target
-add_executable(dependence "")
-set_target_properties(dependence PROPERTIES OUTPUT_NAME "dependence")
-set_target_properties(dependence PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/macosx/x86_64/release")
-target_compile_options(dependence PRIVATE
- $<$<COMPILE_LANGUAGE:C>:-m64>
- $<$<COMPILE_LANGUAGE:CXX>:-m64>
- $<$<COMPILE_LANGUAGE:C>:-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk>
- $<$<COMPILE_LANGUAGE:CXX>:-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk>
- $<$<COMPILE_LANGUAGE:CXX>:-fmodules>
- $<$<COMPILE_LANGUAGE:CXX>:-fbuiltin-module-map>
- $<$<COMPILE_LANGUAGE:CXX>:-fimplicit-modules>
- $<$<COMPILE_LANGUAGE:CXX>:-fno-implicit-module-maps>
-)
-target_compile_features(dependence PRIVATE cxx_std_20)
-if(MSVC)
- set_property(TARGET dependence PROPERTY
- MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
-endif()
-target_link_options(dependence PRIVATE
- -m64
- -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk
-)
-target_sources(dependence PRIVATE
- src/hello_impl.cpp
- src/mod_impl.cpp
- src/main.cpp
- src/hello_impl.cpp
- src/mod_impl.cpp
- src/main.cpp
- src/mod.mpp
- src/hello.mpp
-)
-
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index 15cbcfeb9..3e00db6f6 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -111,6 +111,15 @@ function _make_arguments(jsonfile, arguments, sourcefile)
table.insert(arguments_escape, _escape_path(arg))
end
+ -- remove repeat
+ -- this is because some rules will repeatedly bind the same sourcekind, e.g. `rule("c++.build.modules.builder")`
+ local key = hash.uuid(os.args(arguments_escape) .. sourcefile)
+ local map = _g.map or {}
+ _g.map = map
+ if map[key] then
+ return
+ end
+
-- make body
jsonfile:printf(
[[%s{
@@ -121,6 +130,7 @@ function _make_arguments(jsonfile, arguments, sourcefile)
-- clear first line marks
_g.firstline = false
+ map[key] = true
end
-- make commands for target
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 09feb78e3..52acbf76f 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -20,6 +20,7 @@
-- imports
import("core.project.project")
+import("core.project.config")
import("core.tool.compiler")
import("core.base.semver")
import("core.base.hashset")
@@ -109,6 +110,67 @@ function _get_configs_from_target(target, name)
return table.unique(values)
end
+-- this sourcebatch is built?
+function _sourcebatch_is_built(sourcebatch)
+ -- we can only use rulename to filter them because sourcekind may be bound to multiple rules
+ local rulename = sourcebatch.rulename
+ if rulename == "c++.build" or rulename == "asm.build" or rulename == "cuda.build" then
+ return true
+ end
+end
+
+-- translate flag
+function _translate_flag(flag, outputdir)
+ if flag then
+ if path.instance_of(flag) then
+ flag = flag:clone():set(_get_unix_path_relative_to_cmake(flag:rawstr(), outputdir)):str()
+ elseif path.is_absolute(flag) then
+ flag = _get_unix_path_relative_to_cmake(flag, outputdir)
+ elseif flag:startswith("-fmodule-file=") then
+ flag = "-fmodule-file=" .. _get_unix_path_relative_to_cmake(flag:sub(15), outputdir)
+ elseif flag:startswith("-fmodule-mapper=") then
+ flag = "-fmodule-mapper=" .. _get_unix_path_relative_to_cmake(flag:sub(17), outputdir)
+ elseif flag:match("(.+)=(.+)") then
+ local k, v = flag:match("(.+)=(.+)")
+ if v and v:endswith(".ifc") then -- e.g. hello=xxx/hello.ifc
+ flag = k .. "=" .. _get_unix_path_relative_to_cmake(v, outputdir)
+ end
+ end
+ end
+ return flag
+end
+
+-- translate flags
+function _translate_flags(flags, outputdir)
+ if not flags then
+ return
+ end
+ local result = {}
+ for _, flag in ipairs(flags) do
+ if type(flag) == "table" and not path.instance_of(flag) then
+ for _, v in ipairs(flag) do
+ table.insert(result, _translate_flag(v, outputdir))
+ end
+ else
+ table.insert(result, _translate_flag(flag, outputdir))
+ end
+ end
+ return result
+end
+
+-- get flags from fileconfig
+function _get_flags_from_fileconfig(fileconfig, outputdir, name)
+ local flags = {}
+ table.join2(flags, fileconfig[name])
+ if fileconfig.force then
+ table.join2(flags, fileconfig.force[name])
+ end
+ flags = _translate_flags(flags, outputdir)
+ if #flags > 0 then
+ return table.concat(flags, " ")
+ end
+end
+
-- add project info
function _add_project(cmakelists, languages, outputdir)
@@ -163,8 +225,18 @@ function _add_target_phony(cmakelists, target)
cmakelists:print("")
end
+-- set compiler
+function _set_target_compiler(cmakelists, target)
+ -- use custom toolchain?
+ if config.get("toolchain") or target:get("toolchains") then
+ cmakelists:print("set(CMAKE_C_COMPILER \"%s\")", target:tool("cc"))
+ cmakelists:print("set(CMAKE_CXX_COMPILER \"%s\")", target:tool("cxx"))
+ end
+end
+
-- add target: binary
function _add_target_binary(cmakelists, target, outputdir)
+ _set_target_compiler(cmakelists, target)
cmakelists:print("add_executable(%s \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
cmakelists:print("set_target_properties(%s PROPERTIES RUNTIME_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
@@ -172,6 +244,7 @@ end
-- add target: static
function _add_target_static(cmakelists, target, outputdir)
+ _set_target_compiler(cmakelists, target)
cmakelists:print("add_library(%s STATIC \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
cmakelists:print("set_target_properties(%s PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
@@ -179,6 +252,7 @@ end
-- add target: shared
function _add_target_shared(cmakelists, target, outputdir)
+ _set_target_compiler(cmakelists, target)
cmakelists:print("add_library(%s SHARED \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
if target:is_plat("windows") then
@@ -212,13 +286,12 @@ function _add_target_sources(cmakelists, target, outputdir)
local has_cuda = false
cmakelists:print("target_sources(%s PRIVATE", target:name())
for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
- local sourcekind = sourcebatch.sourcekind
- if sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "cu" then
+ if _sourcebatch_is_built(sourcebatch) then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
cmakelists:print(" " .. _get_unix_path(sourcefile, outputdir))
end
end
- if sourcekind == "cu" then
+ if sourcebatch.sourcekind == "cu" then
has_cuda = true
end
end
@@ -391,75 +464,63 @@ function _add_target_compile_definitions(cmakelists, target)
end
-- add target compile options
-function _add_target_compile_options(cmakelists, target)
+function _add_target_compile_options(cmakelists, target, outputdir)
local cflags = _get_configs_from_target(target, "cflags")
local cxflags = _get_configs_from_target(target, "cxflags")
local cxxflags = _get_configs_from_target(target, "cxxflags")
local cuflags = _get_configs_from_target(target, "cuflags")
if #cflags > 0 or #cxflags > 0 or #cxxflags > 0 or #cuflags > 0 then
cmakelists:print("target_compile_options(%s PRIVATE", target:name())
- for _, flag in ipairs(cflags) do
+ for _, flag in ipairs(_translate_flags(cflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
end
- for _, flag in ipairs(cxflags) do
+ for _, flag in ipairs(_translate_flags(cxflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
- for _, flag in ipairs(cxxflags) do
+ for _, flag in ipairs(_translate_flags(cxxflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
- for _, flag in ipairs(cuflags) do
+ for _, flag in ipairs(_translate_flags(cuflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:CUDA>:" .. flag .. ">")
end
cmakelists:print(")")
end
-end
--- add target language standards
-function _add_target_language_standards(cmakelists, target)
- local cstds =
- {
- c89 = "90"
- , gnu89 = "90" -- TODO add cflags -std=gnu90 if supported
- , c99 = "99"
- , gnu99 = "99" -- TODO
- , c11 = "11"
- , gnu11 = "11" -- TODO
- }
- local cxxstds =
- {
- cxx98 = "98"
- , gnuxx98 = "98" -- TODO
- , cxx11 = "11"
- , gnuxx11 = "11"
- , cxx14 = "14"
- , gnuxx14 = "14"
- , cxx17 = "17"
- , gnuxx17 = "17"
- , cxx1z = "17"
- , gnuxx1z = "17"
- , cxx2a = "20"
- , gnuxx2a = "20"
- , cxxlatest = "latest"
- }
- for _, lang in ipairs(target:get("languages")) do
- local cstd = cstds[lang]
- if cstd then
- cmakelists:print("set_property(TARGET %s PROPERTY C_STANDARD %s)", target:name(), cstd)
- if cstd == "99" or cstd == "11" then
- cmakelists:print("if(MSVC)")
- cmakelists:print(" target_compile_options(%s PRIVATE $<$<COMPILE_LANGUAGE:C>:-TP>)", target:name())
- cmakelists:print("endif()")
- end
- end
- local cxxstd = cxxstds[lang]
- if cxxstd then
- if cxxstd == "latest" then
- cmakelists:print("if (MSVC)")
- cmakelists:print(" target_compile_options(%s PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>)", target:name())
- cmakelists:print("endif()")
- else
- cmakelists:print("set_property(TARGET %s PROPERTY CXX_STANDARD %s)", target:name(), cxxstd)
+ -- add cflags/cxxflags for the specific source files
+ for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
+ if _sourcebatch_is_built(sourcebatch) then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig then
+ local cxxflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cxxflags")
+ if cxxflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS \"$<$<COMPILE_LANGUAGE:CXX>:" .. cxxflags .. ">\")")
+ end
+ local cflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cflags")
+ if cflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS \"$<$<COMPILE_LANGUAGE:C>:" .. cflags .. ">\")")
+ end
+ local cxflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cxflags")
+ if cxflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS \"$<$<COMPILE_LANGUAGE:C>:" .. cxflags .. ">\")")
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS \"$<$<COMPILE_LANGUAGE:CXX>:" .. cxflags .. ">\")")
+ end
+ local cuflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cuflags")
+ if cuflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS \"$<$<COMPILE_LANGUAGE:CUDA>:" .. cuflags .. ">\")")
+ end
+ end
end
end
end
@@ -615,7 +676,7 @@ function _add_target_vs_runtime(cmakelists, target)
end
-- add target link libraries
-function _add_target_link_libraries(cmakelists, target)
+function _add_target_link_libraries(cmakelists, target, outputdir)
-- add links
local links = _get_configs_from_target(target, "links")
@@ -634,6 +695,25 @@ function _add_target_link_libraries(cmakelists, target)
end
cmakelists:print(")")
end
+
+ -- add other object files, maybe from custom rules
+ local objectfiles_set = hashset.new()
+ for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
+ if _sourcebatch_is_built(sourcebatch) then
+ for _, objectfile in ipairs(sourcebatch.objectfiles) do
+ objectfiles_set:insert(objectfile)
+ end
+ end
+ end
+ if #target:objectfiles() > objectfiles_set:size() then
+ cmakelists:print("target_link_libraries(%s PRIVATE", target:name())
+ for _, objectfile in ipairs(target:objectfiles()) do
+ if not objectfiles_set:has(objectfile) then
+ cmakelists:print(" " .. _get_unix_path_relative_to_cmake(objectfile, outputdir))
+ end
+ end
+ cmakelists:print(")")
+ end
end
-- add target link directories
@@ -699,12 +779,7 @@ function _get_command_string(cmd, outputdir)
-- @see https://github.com/xmake-io/xmake/discussions/2156
local argv = {}
for _, v in ipairs(cmd.argv) do
- if path.instance_of(v) then
- v = v:clone():set(_get_unix_path_relative_to_cmake(v:rawstr(), outputdir)):str()
- elseif path.is_absolute(v) then
- v = _get_unix_path_relative_to_cmake(v, outputdir)
- end
- table.insert(argv, v)
+ table.insert(argv, _translate_flag(v, outputdir))
end
local command = _get_unix_path_relative_to_cmake(cmd.program) .. " " .. os.args(argv)
if opt and opt.curdir then
@@ -733,8 +808,8 @@ function _get_command_string(cmd, outputdir)
end
end
--- add custom command
-function _add_target_custom_command(cmakelists, target, command, suffix)
+-- add target custom commands for batchcmds
+function _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, suffix, batchcmds)
if suffix == "before" then
-- ADD_CUSTOM_COMMAND and PRE_BUILD did not work as I expected,
-- so we need use add_dependencies and fake target to support it.
@@ -743,7 +818,12 @@ function _add_target_custom_command(cmakelists, target, command, suffix)
--
local key = target:name() .. "_" .. hash.uuid():split("-", {plain = true})[1]
cmakelists:print("add_custom_command(OUTPUT output_%s", key)
- cmakelists:print(" COMMAND %s", command)
+ for _, cmd in ipairs(batchcmds:cmds()) do
+ local command = _get_command_string(cmd, outputdir)
+ if command then
+ cmakelists:print(" COMMAND %s", command)
+ end
+ end
cmakelists:print(" VERBATIM")
cmakelists:print(")")
cmakelists:print("add_custom_target(target_%s", key)
@@ -755,7 +835,12 @@ function _add_target_custom_command(cmakelists, target, command, suffix)
if suffix == "after" then
cmakelists:print(" POST_BUILD")
end
- cmakelists:print(" COMMAND %s", command)
+ for _, cmd in ipairs(batchcmds:cmds()) do
+ local command = _get_command_string(cmd, outputdir)
+ if command then
+ cmakelists:print(" COMMAND %s", command)
+ end
+ end
cmakelists:print(" VERBATIM")
cmakelists:print(")")
end
@@ -770,12 +855,7 @@ function _add_target_custom_commands_for_target(cmakelists, target, outputdir, s
local batchcmds_ = batchcmds.new({target = target})
script(target, batchcmds_, {})
if not batchcmds_:empty() then
- for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd, outputdir)
- if command then
- _add_target_custom_command(cmakelists, target, command, suffix)
- end
- end
+ _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, suffix, batchcmds_)
end
end
end
@@ -795,12 +875,7 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
local batchcmds_ = batchcmds.new({target = target})
script(target, batchcmds_, sourcebatch, {})
if not batchcmds_:empty() then
- for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd, outputdir)
- if command then
- _add_target_custom_command(cmakelists, target, command, suffix)
- end
- end
+ _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, suffix, batchcmds_)
end
end
@@ -814,12 +889,7 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
local batchcmds_ = batchcmds.new({target = target})
script(target, batchcmds_, sourcefile, {})
if not batchcmds_:empty() then
- for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd, outputdir)
- if command then
- _add_target_custom_command(cmakelists, target, command, suffix)
- end
- end
+ _add_target_custom_commands_for_batchcmds(cmakelists, target, outputdir, suffix, batchcmds_)
end
end
end
@@ -830,8 +900,7 @@ end
function _add_target_custom_commands(cmakelists, target, outputdir)
_add_target_custom_commands_for_target(cmakelists, target, outputdir, "before")
for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
- local sourcekind = sourcebatch.sourcekind
- if sourcekind ~= "cc" and sourcekind ~= "cxx" and sourcekind ~= "as" then
+ if not _sourcebatch_is_built(sourcebatch) then
_add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir, "before")
_add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir)
_add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir, "after")
@@ -885,6 +954,10 @@ function _add_target(cmakelists, target, outputdir)
-- add target dependencies
_add_target_dependencies(cmakelists, target)
+ -- add target custom commands
+ -- we need call it first for running all rules, these rules will change some flags, e.g. c++modules
+ _add_target_custom_commands(cmakelists, target, outputdir)
+
-- add target precompilied header
_add_target_precompiled_header(cmakelists, target, outputdir)
@@ -900,11 +973,8 @@ function _add_target(cmakelists, target, outputdir)
-- add target compile definitions
_add_target_compile_definitions(cmakelists, target)
- -- add target language standards
- _add_target_language_standards(cmakelists, target)
-
-- add target compile options
- _add_target_compile_options(cmakelists, target)
+ _add_target_compile_options(cmakelists, target, outputdir)
-- add target warnings
_add_target_warnings(cmakelists, target)
@@ -922,7 +992,7 @@ function _add_target(cmakelists, target, outputdir)
_add_target_vs_runtime(cmakelists, target)
-- add target link libraries
- _add_target_link_libraries(cmakelists, target)
+ _add_target_link_libraries(cmakelists, target, outputdir)
-- add target link directories
_add_target_link_directories(cmakelists, target, outputdir)
@@ -930,9 +1000,6 @@ function _add_target(cmakelists, target, outputdir)
-- add target link options
_add_target_link_options(cmakelists, target)
- -- add target custom commands
- _add_target_custom_commands(cmakelists, target, outputdir)
-
-- add target sources
_add_target_sources(cmakelists, target, outputdir)
diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua
index 7b0ec8f60..87c3b6f55 100644
--- a/xmake/plugins/project/make/makefile.lua
+++ b/xmake/plugins/project/make/makefile.lua
@@ -192,10 +192,18 @@ end
-- make objects
function _make_objects(makefile, target, sourcekind, sourcebatch, sourceflags)
-
- -- make them
+ local handled_objects = target:data("makefile.handled_objects")
+ if not handled_objects then
+ handled_objects = {}
+ target:data_set("makefile.handled_objects", handled_objects)
+ end
for index, objectfile in ipairs(sourcebatch.objectfiles) do
- _make_object(makefile, target, sourcebatch.sourcefiles[index], objectfile, sourceflags)
+ -- remove repeat
+ -- this is because some rules will repeatedly bind the same sourcekind, e.g. `rule("c++.build.modules.builder")`
+ if not handled_objects[objectfile] then
+ _make_object(makefile, target, sourcebatch.sourcefiles[index], objectfile, sourceflags)
+ handled_objects[objectfile] = true
+ end
end
end
diff --git a/xmake/rules/c++/modules/modules_support/clang.lua b/xmake/rules/c++/modules/modules_support/clang.lua
index bd4448ae7..fb3a2d1fa 100644
--- a/xmake/rules/c++/modules/modules_support/clang.lua
+++ b/xmake/rules/c++/modules/modules_support/clang.lua
@@ -210,7 +210,9 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
-- don't build same header unit at the same time
if not common.memcache():get2(headerunit.name, "building") then
common.memcache():set2(headerunit.name, "building", true)
- local args = {modulecachepathflag .. stlcachedir, "-c", "-o", bmifile, "-x", "c++-system-header", headerunit.name}
+ local args = {
+ path(stlcachedir, function (p) return modulecachepathflag .. p end),
+ "-c", "-o", path(bmifile), "-x", "c++-system-header", headerunit.name}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
end
@@ -306,9 +308,9 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
batchcmds:mkdir(path.directory(objectfile))
- local args = { modulecachepathflag .. cachedir, "-c", "-o", bmifile}
+ local args = {path(cachedir, function (p) return modulecachepathflag .. p end), "-c", "-o", path(bmifile)}
if headerunit.type == ":quote" then
- table.join2(args, {"-I", path.directory(headerunit.path), "-x", "c++-user-header", headerunit.path})
+ table.join2(args, {"-I", path(headerunit.path):directory(), "-x", "c++-user-header", path(headerunit.path)})
elseif headerunit.type == ":angle" then
table.join2(args, {"-x", "c++-system-header", headerunit.name})
end
@@ -421,7 +423,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
-- build modules
local depmtime = 0
- local common_args = {modulecachepathflag .. cachedir}
+ local common_args = {path(cachedir, function (p) return modulecachepathflag .. p end)}
for _, objectfile in ipairs(objectfiles) do
local module = modules[objectfile]
if module then
@@ -433,7 +435,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
break
end
local bmifile = provide.bmi
- local args = { "-c", "-x", "c++-module", "--precompile", provide.sourcefile, "-o", bmifile }
+ local args = {"-c", "-x", "c++-module", "--precompile", path(provide.sourcefile), "-o", path(bmifile)}
local requiresflags
if module.requires then
requiresflags = get_requiresflags(target, module.requires)
@@ -441,7 +443,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, args))
- batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, {bmifile}, {"-c", "-o", objectfile}))
+ batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, path(bmifile), {"-c", "-o", path(objectfile)}))
batchcmds:add_depfiles(provide.sourcefile)
_add_module_to_mapper(target, name, bmifile)
depmtime = math.max(depmtime, os.mtime(bmifile))
diff --git a/xmake/rules/c++/modules/modules_support/common.lua b/xmake/rules/c++/modules/modules_support/common.lua
index 39ad17f2e..aa7c0fb59 100644
--- a/xmake/rules/c++/modules/modules_support/common.lua
+++ b/xmake/rules/c++/modules/modules_support/common.lua
@@ -88,7 +88,6 @@ end
-- patch sourcebatch
function patch_sourcebatch(target, sourcebatch)
- local cachedir = modules_cachedir(target)
sourcebatch.sourcekind = "cxx"
sourcebatch.objectfiles = {}
sourcebatch.dependfiles = {}
@@ -138,6 +137,7 @@ end
-- this target contains module files?
function contains_modules(target)
+ -- we can not use `"c++.build.modules.builder"`, because it contains sourcekind/cxx.
local target_with_modules = target:sourcebatches()["c++.build.modules"] and true or false
if not target_with_modules then
for _, dep in ipairs(target:orderdeps()) do
diff --git a/xmake/rules/c++/modules/modules_support/gcc.lua b/xmake/rules/c++/modules/modules_support/gcc.lua
index a37346bad..1405d1cfa 100644
--- a/xmake/rules/c++/modules/modules_support/gcc.lua
+++ b/xmake/rules/c++/modules/modules_support/gcc.lua
@@ -189,7 +189,7 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
for _, headerunit in ipairs(headerunits) do
local bmifile = path.join(stlcachedir, headerunit.name .. get_bmi_extension())
if not os.isfile(bmifile) then
- local args = { "-c", "-x", "c++-system-header", headerunit.name }
+ local args = {"-c", "-x", "c++-system-header", headerunit.name}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), args))
end
@@ -276,13 +276,13 @@ function generate_user_headerunits_for_batchcmds(target, batchcmds, headerunits,
local bmifile = (outputdir and path.join(outputdir, bmifilename) or bmifilename)
batchcmds:mkdir(path.directory(objectfile))
- local args = { "-c" }
+ local args = {"-c"}
local headerunit_path
if headerunit.type == ":quote" then
- table.join2(args, { "-I", path.directory(path.relative(headerunit.path, projectdir)), "-x", "c++-user-header", headerunit.name })
+ table.join2(args, {"-I", path(path.relative(headerunit.path, projectdir)):directory(), "-x", "c++-user-header", headerunit.name})
headerunit_path = path.join(".", path.relative(headerunit.path, projectdir))
elseif headerunit.type == ":angle" then
- table.join2(args, { "-x", "c++-system-header", headerunit.name })
+ table.join2(args, {"-x", "c++-system-header", headerunit.name})
-- if path is relative then its a subtarget path
headerunit_path = path.is_absolute(headerunit.path) and headerunit.path or path.join(".", headerunit.path)
end
@@ -375,7 +375,7 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
end
local bmifile = provide.bmi
- local args = {"-o", objectfile, "-c", provide.sourcefile}
+ local args = {"-o", path(objectfile), "-c", path(provide.sourcefile)}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args))
diff --git a/xmake/rules/c++/modules/modules_support/msvc.lua b/xmake/rules/c++/modules/modules_support/msvc.lua
index 4f7c8edc2..5214f12df 100644
--- a/xmake/rules/c++/modules/modules_support/msvc.lua
+++ b/xmake/rules/c++/modules/modules_support/msvc.lua
@@ -219,7 +219,12 @@ function generate_stl_headerunits_for_batchcmds(target, batchcmds, headerunits,
-- don't build same header unit at the same time
if not common.memcache():get2(headerunit.name, "building") then
common.memcache():set2(headerunit.name, "building", true)
- local args = {headernameflag .. ":angle", headerunit.name, ifcoutputflag, headerunit.name:startswith("experimental/") and path.join(stlcachedir, "experimental") or stlcachedir, "-Fo" .. objectfile}
+ local args = {
+ headernameflag .. ":angle",
+ headerunit.name,
+ ifcoutputflag,
+ path(headerunit.name:startswith("experimental/") and path.join(stlcachedir, "experimental") or stlcachedir),
+ path(objectfile, function (p) return "-Fo" .. p end)}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.headerunit.bmi %s", headerunit.name)
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, args), {envs = vcvars})
batchcmds:add_depfiles(headerunit.path)
@@ -468,7 +473,12 @@ function build_modules_for_batchcmds(target, batchcmds, objectfiles, modules, op
end
local bmifile = provide.bmi
- local args = {"-c", "-Fo" .. objectfile, interfaceflag, ifcoutputflag, bmifile, provide.sourcefile}
+ local args = {"-c",
+ path(objectfile, function (p) return "-Fo" .. p end),
+ interfaceflag,
+ ifcoutputflag,
+ path(bmifile),
+ path(provide.sourcefile)}
batchcmds:show_progress(opt.progress, "${color.build.object}generating.cxx.module.bmi %s", name)
batchcmds:mkdir(path.directory(objectfile))
batchcmds:vrunv(compinst:program(), table.join(compinst:compflags({target = target}), common_args, requiresflags or {}, args), {envs = vcvars})
diff --git a/xmake/rules/c++/modules/xmake.lua b/xmake/rules/c++/modules/xmake.lua
index 276566a27..3ef960d7a 100644
--- a/xmake/rules/c++/modules/xmake.lua
+++ b/xmake/rules/c++/modules/xmake.lua
@@ -21,7 +21,6 @@
-- define rule: c++.build.modules
rule("c++.build.modules")
set_extensions(".mpp", ".mxx", ".cppm", ".ixx")
-
add_deps("c++.build.modules.builder")
add_deps("c++.build.modules.install")