diff options
| author | Arthur LAURENT <[email protected]> | 2025-05-05 18:10:07 +0200 |
|---|---|---|
| committer | Arthur LAURENT <[email protected]> | 2025-05-09 15:56:33 +0200 |
| commit | 41bb46475576049e3b0dc6c008311c41d8432f62 (patch) | |
| tree | 5559a7e4be1000fada433b54aefb6fc6fcd91bf5 | |
| parent | 5d6d36e0db45d90dfa7f0cdf2937d989de683833 (diff) | |
(C++ modules support) fix CMake generation
| -rw-r--r-- | xmake/plugins/project/clang/compile_commands.lua | 2 | ||||
| -rw-r--r-- | xmake/plugins/project/cmake/cmakelists.lua | 73 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/scanner.lua | 26 |
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 |
