summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur LAURENT <[email protected]>2025-05-05 18:10:07 +0200
committerArthur LAURENT <[email protected]>2025-05-09 15:56:33 +0200
commit41bb46475576049e3b0dc6c008311c41d8432f62 (patch)
tree5559a7e4be1000fada433b54aefb6fc6fcd91bf5
parent5d6d36e0db45d90dfa7f0cdf2937d989de683833 (diff)
(C++ modules support) fix CMake generation
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua2
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua73
-rw-r--r--xmake/rules/c++/modules/scanner.lua26
3 files changed, 80 insertions, 21 deletions
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index b31c9bf93..538b30f83 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -311,6 +311,6 @@ function make(outputdir)
target_cmds.prepare_targets()
_add_targets(jsonfile)
jsonfile:close()
- os.setenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR", "false")
+ os.setenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR", nil)
os.cd(oldir)
end
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 41adc82a5..d0d682866 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -350,9 +350,11 @@ function _add_project(cmakelists, outputdir)
if not project_name then
for _, target in table.orderpairs(project.targets()) do
project_name = target:name()
- break
end
end
+ if _can_native_support_for_cxxmodules() then
+ cmakelists:print("set(CMAKE_CXX_SCAN_FOR_MODULES ON)")
+ end
if project_name then
local project_info = ""
local project_version = project.version()
@@ -366,9 +368,6 @@ function _add_project(cmakelists, outputdir)
cmakelists:print("project(%s%s)", project_name, project_info)
end
end
- if _can_native_support_for_cxxmodules() then
- cmakelists:print("set(CMAKE_CXX_SCAN_FOR_MODULES ON)")
- end
cmakelists:print("")
end
@@ -453,25 +452,81 @@ function _add_target_dependencies(cmakelists, target)
end
end
+function _print_target_sources(cmakelists, target, files, visibility, opt)
+ opt = opt or {}
+ local has_fileset_support = _get_cmake_version():ge("2.23")
+ local fileset = ""
+ if has_fileset_support and opt.set then
+ fileset = "FILE_SET " .. opt.set .. " FILES"
+ end
+
+ cmakelists:print("target_sources(%s %s %s", target:name(), visibility, fileset)
+ for _, file in ipairs(files) do
+ cmakelists:print(" " .. file)
+ end
+ cmakelists:print(")")
+end
+
-- add target sources
function _add_target_sources(cmakelists, target, outputdir)
local has_cuda = false
- cmakelists:print("target_sources(%s PRIVATE", target:name())
local sourcebatches = target:sourcebatches()
for name, sourcebatch in table.orderpairs(sourcebatches) do
+ local public_sources
+ local private_sources
if _sourcebatch_is_built(sourcebatch) then
+ local module_sourcebatch = false
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- cmakelists:print(" " .. _get_relative_unix_path(sourcefile, outputdir))
+ if _has_cxxmodules_sources() and name == "c++.build.modules" then
+ module_sourcebatch = true
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig and fileconfig.public then
+ public_sources = public_sources or {}
+ table.insert(public_sources, _get_relative_unix_path(sourcefile, outputdir))
+ else
+ private_sources = private_sources or {}
+ table.insert(private_sources, _get_relative_unix_path(sourcefile, outputdir))
+ end
+ else
+ private_sources = private_sources or {}
+ table.insert(private_sources, _get_relative_unix_path(sourcefile, outputdir))
+ end
+ end
+ if public_sources then
+ cmakelists:print(format("# public sourcefiles from sourcebatch %s for target %s", name, target:fullname()))
+ _print_target_sources(cmakelists, target, public_sources, "PUBLIC", {set = module_sourcebatch and "CXX_MODULES"})
+ end
+ if private_sources then
+ cmakelists:print(format("# private sourcefiles from sourcebatch %s for target %s", name, target:fullname()))
+ _print_target_sources(cmakelists, target, private_sources, "PRIVATE", {set = module_sourcebatch and "CXX_MODULES"})
end
end
if sourcebatch.sourcekind == "cu" then
has_cuda = true
end
end
- for _, headerfile in ipairs(target:headerfiles()) do
- cmakelists:print(" " .. _get_relative_unix_path(headerfile, outputdir))
+ if target:headerfiles() then
+ local public_headers
+ local private_headers
+ for _, headerfile in ipairs(target:headerfiles()) do
+ local fileconfig = target:fileconfig(headerfile)
+ if fileconfig and fileconfig.public then
+ public_headers = public_headers or {}
+ table.insert(public_headers, _get_relative_unix_path(headerfile, outputdir))
+ else
+ private_headers = private_headers or {}
+ table.insert(private_headers, _get_relative_unix_path(headerfile, outputdir))
+ end
+ end
+ if public_headers then
+ cmakelists:print(format("# public headers for target %s", target:fullname()))
+ _print_target_sources(cmakelists, target, public_headers, "PUBLIC", {set = "HEADERS"})
+ end
+ if private_headers then
+ cmakelists:print(format("# private headers for target %s", target:fullname()))
+ _print_target_sources(cmakelists, target, private_headers, "PRIVATE", {set = "HEADERS"})
+ end
end
- cmakelists:print(")")
if has_cuda then
cmakelists:print("set_target_properties(%s PROPERTIES CUDA_SEPARABLE_COMPILATION ON)", target:name())
local devlink = target:policy("build.cuda.devlink") or target:values("cuda.build.devlink")
diff --git a/xmake/rules/c++/modules/scanner.lua b/xmake/rules/c++/modules/scanner.lua
index d42c2d93e..da15e9177 100644
--- a/xmake/rules/c++/modules/scanner.lua
+++ b/xmake/rules/c++/modules/scanner.lua
@@ -766,21 +766,25 @@ function get_modules(target)
end
function after_scan(target)
- local sourcebatch_scanner = target:sourcebatches()["c++.build.modules.scanner"]
- local sourcebatch_builder = target:sourcebatches()["c++.build.modules.builder"]
- if target:data("cxx.has_modules") and not target:is_moduleonly() then
- local _, _, objectfiles = sort_modules_by_dependencies(target, get_modules(target), {jobgraph = target:policy("build.jobgraph")})
- sourcebatch_scanner.objectfiles = objectfiles
- sourcebatch_builder.objectfiles = objectfiles
- elseif sourcebatch_scanner then
- -- avoid duplicate linking of object files of non-module programs
- sourcebatch_scanner.objectfiles = {}
- sourcebatch_builder.objectfiles = {}
+ local compile_commands = os.getenv("XMAKE_IN_PROJECT_GENERATOR") and os.getenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR")
+ if not os.getenv("XMAKE_IN_PROJECT_GENERATOR") or compile_commands then
+ local sourcebatch_scanner = target:sourcebatches()["c++.build.modules.scanner"]
+ local sourcebatch_builder = target:sourcebatches()["c++.build.modules.builder"]
+ if target:data("cxx.has_modules") and not target:is_moduleonly() then
+ local _, _, objectfiles = sort_modules_by_dependencies(target, get_modules(target), {jobgraph = target:policy("build.jobgraph")})
+ sourcebatch_scanner.objectfiles = objectfiles
+ sourcebatch_builder.objectfiles = objectfiles
+ elseif sourcebatch_scanner then
+ -- avoid duplicate linking of object files of non-module programs
+ sourcebatch_scanner.objectfiles = {}
+ sourcebatch_builder.objectfiles = {}
+ end
end
end
function main(target, jobgraph, sourcebatch)
- if target:data("cxx.has_modules") then
+ local compile_commands = os.getenv("XMAKE_IN_PROJECT_GENERATOR") and os.getenv("XMAKE_IN_COMPILE_COMMANDS_PROJECT_GENERATOR")
+ if target:data("cxx.has_modules") and (not os.getenv("XMAKE_IN_PROJECT_GENERATOR") or compile_commands) then
_patch_sourcebatch(target, sourcebatch)
_schedule_module_dependencies_scan(target, jobgraph, sourcebatch)
end