summaryrefslogtreecommitdiff
path: root/xmake/plugins
diff options
context:
space:
mode:
authorruki <[email protected]>2024-02-18 21:41:52 +0800
committerGitHub <[email protected]>2024-02-18 21:41:52 +0800
commit3c1163b36e0817dbd5b62ec1ff495dc2e830d6ac (patch)
tree16f6cb664c031d80b1841e6978fc1d8753eb6761 /xmake/plugins
parentcda48025005f9aa23bdd582e29bb0f1f1ca24d27 (diff)
parentbc1a30db6041c2c14ca79ccf0aa35b2d550e64e5 (diff)
Merge pull request #4673 from xmake-io/modules
Refactor modules support
Diffstat (limited to 'xmake/plugins')
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua13
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua27
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua49
-rw-r--r--xmake/plugins/project/vsxmake/getinfo.lua2
4 files changed, 71 insertions, 20 deletions
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 6fcf38313..4402f080f 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -68,6 +68,7 @@ end
function _escape_path(filepath)
if is_host("windows") then
filepath = filepath:gsub('\\', '/')
+ filepath = filepath:gsub(' ', '\\ ')
end
return filepath
end
@@ -323,6 +324,11 @@ function _add_target_headeronly(cmakelists, target)
cmakelists:print("add_library(%s INTERFACE)", target:name())
end
+-- add target: headeronly
+function _add_target_moduleonly(cmakelists, target)
+ cmakelists:print("add_custom_target(%s)", target:name())
+end
+
-- add target dependencies
function _add_target_dependencies(cmakelists, target)
local deps = target:get("deps")
@@ -340,8 +346,8 @@ function _add_target_sources(cmakelists, target, outputdir)
local has_cuda = false
cmakelists:print("target_sources(%s PRIVATE", target:name())
local sourcebatches = target:sourcebatches()
- for _, sourcebatch in table.orderpairs(sourcebatches) do
- if _sourcebatch_is_built(sourcebatch) then
+ for name, sourcebatch in table.orderpairs(sourcebatches) do
+ if _sourcebatch_is_built(sourcebatch) and not name:startswith("c++.build.modules") then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
cmakelists:print(" " .. _get_relative_unix_path(sourcefile, outputdir))
end
@@ -1003,6 +1009,9 @@ function _add_target(cmakelists, target, outputdir)
_add_target_headeronly(cmakelists, target)
_add_target_include_directories(cmakelists, target, outputdir)
return
+ elseif targetkind == 'moduleonly' then
+ _add_target_moduleonly(cmakelists, target)
+ return
else
raise("unknown target kind %s", target:kind())
end
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index a8b48dada..b3c6f84c2 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -185,7 +185,6 @@ function _make_custom_commands_for_objectrules(commands, target, sourcebatch, vc
scriptname = "buildcmd_file" .. (suffix and ("_" .. suffix) or "")
script = ruleinst:script(scriptname)
if script then
- local sourcekind = sourcebatch.sourcekind
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local batchcmds_ = batchcmds.new({target = target})
script(target, batchcmds_, sourcefile, {})
@@ -219,7 +218,7 @@ function _make_custom_commands(target, vcxprojdir)
for _, sourcebatch in table.orderpairs(sourcebatches) do
local rulename = sourcebatch.rulename
local sourcekind = sourcebatch.sourcekind
- if rulename ~= "c.build" and rulename ~= "c++.build" and rulename ~= "asm.build" and rulename ~= "cuda.build" and sourcekind ~= "mrc" then
+ if rulename ~= "c.build" and rulename ~= "c++.build" and not rulename:startswith("c++.build.modules") and rulename ~= "asm.build" and rulename ~= "cuda.build" and sourcekind ~= "mrc" then
_make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, "before")
_make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, nil)
_make_custom_commands_for_objectrules(commands, target, sourcebatch, vcxprojdir, "after")
@@ -256,6 +255,9 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
-- save symbols
targetinfo.symbols = target:get("symbols")
+ -- has modules
+ targetinfo.has_modules = target:data("cxx.has_modules")
+
-- save target kind
targetinfo.targetkind = target:kind()
if target:is_phony() or target:is_headeronly() then
@@ -268,9 +270,6 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
-- save symbol file
targetinfo.symbolfile = target:symbolfile()
- -- save sourcebatches
- targetinfo.sourcebatches = target:sourcebatches()
-
-- save sourcekinds
targetinfo.sourcekinds = target:sourcekinds()
@@ -289,9 +288,9 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
local sourcekind = sourcebatch.sourcekind
local rulename = sourcebatch.rulename
if sourcekind then
- for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local compflags = compiler.compflags(sourcefile, {target = target, sourcekind = sourcekind})
- if not firstcompflags and (rulename == "c.build" or rulename == "c++.build" or rulename == "cuda.build") then
+ if not firstcompflags and (rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" or rulename == "cuda.build") then
firstcompflags = compflags
end
targetinfo.compflags[sourcefile] = compflags
@@ -309,8 +308,11 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
end
end
+ -- save sourcebatches
+ targetinfo.sourcebatches = target:sourcebatches()
+
-- save linker flags
- local linkflags = linker.linkflags(target:kind(), target:sourcekinds(), {target = target})
+ local linkflags = linker.linkflags(target:is_moduleonly() and 'static' or target:kind(), target:sourcekinds(), {target = target})
targetinfo.linkflags = linkflags
if table.contains(target:sourcekinds(), "cu") then
@@ -323,7 +325,7 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
end
-- save execution dir (when executed from VS)
- targetinfo.rundir = target:rundir()
+ targetinfo.rundir = target:is_moduleonly() and "" or target:rundir()
-- save runenvs
local targetrunenvs = {}
@@ -544,6 +546,13 @@ function make(outputdir, vsinfo)
-- save file groups
_target.filegroups = table.unique(table.join(_target.filegroups or {}, target:get("filegroups")))
+ -- save references to deps
+ for _, dep in ipairs(target:orderdeps()) do
+ _target.deps = _target.deps or {}
+ local dep_name = dep:name()
+ _target.deps[dep_name] = path.relative(path.join(vsinfo.solution_dir, dep_name, dep_name .. ".vcxproj"), _target.project_dir)
+ end
+
for filegroup, groupconf in pairs(target:extraconf("filegroups")) do
_target.filegroups_extraconf = _target.filegroups_extraconf or {}
local mergedconf = _target.filegroups_extraconf[filegroup]
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
index f5bb88d73..ee21e88b1 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua
@@ -218,6 +218,17 @@ function _make_header(vcxprojfile, vsinfo)
vcxprojfile:enter("<Project DefaultTargets=\"Build\" ToolsVersion=\"%s.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">", assert(vsinfo.project_version))
end
+-- make references
+function _make_references(vcxprojfile, vsinfo, target)
+ vcxprojfile:print("<ItemGroup>")
+ for dep_name, dep_vcxprojfile in pairs(target.deps) do
+ vcxprojfile:print("<ProjectReference Include=\"%s\">", dep_vcxprojfile)
+ vcxprojfile:print("<Project>{%s}</Project>", hash.uuid4(dep_name))
+ vcxprojfile:print("</ProjectReference>")
+ end
+ vcxprojfile:print("</ItemGroup>")
+end
+
-- make tailer
function _make_tailer(vcxprojfile, vsinfo, target)
vcxprojfile:print("<Import Project=\"%$(VCTargetsPath)\\Microsoft.Cpp.targets\" />")
@@ -242,6 +253,7 @@ function _make_configurations(vcxprojfile, vsinfo, target)
binary = "Application"
, shared = "DynamicLibrary"
, static = "StaticLibrary"
+ , moduleonly = "StaticLibrary" -- emulate moduleonly with staticlib
}
-- make ProjectConfigurations
@@ -307,8 +319,10 @@ function _make_configurations(vcxprojfile, vsinfo, target)
vcxprojfile:enter("<PropertyGroup Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\">", targetinfo.mode, targetinfo.arch)
vcxprojfile:print("<OutDir>%s\\</OutDir>", _make_dirs(targetinfo.targetdir, target.project_dir))
vcxprojfile:print("<IntDir>%s\\</IntDir>", _make_dirs(targetinfo.objectdir, target.project_dir))
- vcxprojfile:print("<TargetName>%s</TargetName>", path.basename(targetinfo.targetfile))
- vcxprojfile:print("<TargetExt>%s</TargetExt>", path.extension(targetinfo.targetfile))
+ if targetinfo.targetfile then
+ vcxprojfile:print("<TargetName>%s</TargetName>", path.basename(targetinfo.targetfile))
+ vcxprojfile:print("<TargetExt>%s</TargetExt>", path.extension(targetinfo.targetfile))
+ end
if target.kind == "binary" then
vcxprojfile:print("<LinkIncremental>true</LinkIncremental>")
@@ -723,7 +737,7 @@ endlocal &amp; call :xmErrorLevel %errorlevel% &amp; goto :xmDone
exit /b %1
:xmDone
if %errorlevel% neq 0 goto :VCEnd]]
- vcxprojfile:print("<Command>%s</Command>", cmdstr)
+ vcxprojfile:print("<Command>%s</Command>", cmdstr:replace("<", " &lt;"):replace(">", "&gt;"):replace("/Fo ", "/Fo"))
if suffix == "after" or suffix == "after_link" then
vcxprojfile:print("</PostBuildEvent>")
elseif suffix == "before" then
@@ -742,12 +756,12 @@ end
-- make common item
function _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
-
-- init the linker kinds
local linkerkinds =
{
binary = "Link"
, static = "Lib"
+ , moduleonly = "Lib" -- emulate moduleonly with staticlib
, shared = "Link"
}
if not linkerkinds[targetinfo.targetkind] then
@@ -892,6 +906,10 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
vcxprojfile:print("<LanguageStandard_C>%s</LanguageStandard_C>", cstandard)
end
+ if targetinfo.has_modules then
+ vcxprojfile:enter("<ScanSourceForModuleDependencies>true</ScanSourceForModuleDependencies>")
+ end
+
-- use c or c++ precompiled header
local pcheader = target.pcxxheader or target.pcheader
if pcheader then
@@ -959,9 +977,8 @@ function _build_common_items(vsinfo, target)
for _, sourcebatch in pairs(targetinfo.sourcebatches) do
local sourcekind = sourcebatch.sourcekind
local rulename = sourcebatch.rulename
- if (rulename == "c.build" or rulename == "c++.build" or rulename == "asm.build" or sourcekind == "mrc") then
+ if (rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" or rulename == "asm.build" or sourcekind == "mrc") then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
-
-- make compiler flags
local flags = _make_compflags(sourcefile, targetinfo, target.project_dir)
@@ -1028,7 +1045,7 @@ function _build_common_items(vsinfo, target)
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
sourceflags[sourcefile] = targetinfo.sourceflags[sourcefile]
end
- elseif rulename == "c.build" or rulename == "c++.build" then -- sourcekind maybe bind multiple rules, e.g. c++modules
+ elseif rulename == "c.build" or rulename == "c++.build" or rulename == "c++.build.modules" then -- sourcekind maybe bind multiple rules, e.g. c++modules
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local flags = targetinfo.sourceflags[sourcefile]
local otherflags = {}
@@ -1062,7 +1079,7 @@ function _make_common_items(vcxprojfile, vsinfo, target)
-- for each mode and arch
for _, targetinfo in ipairs(target.info) do
-- make common item
- _make_common_item(vcxprojfile, vsinfo, target, targetinfo, target.project_dir)
+ _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
end
end
@@ -1325,6 +1342,19 @@ function _make_source_files(vcxprojfile, vsinfo, target)
sourceinfos[sourcefile] = sourceinfos[sourcefile] or {}
table.insert(sourceinfos[sourcefile], {targetinfo = targetinfo, mode = targetinfo.mode, arch = targetinfo.arch, sourcekind = sourcekind, objectfile = objectfile, flags = flags, compargv = targetinfo.compargvs[sourcefile]})
end
+ elseif rulename == "c++.build.modules" then
+ local builder_batch = targetinfo.sourcebatches["c++.build.modules.builder"]
+ table.sort(builder_batch.objectfiles)
+ local objectfiles = builder_batch.objectfiles
+ for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local is_named_module = table.contains(builder_batch.sourcefiles, sourcefile)
+ if is_named_module then
+ local objectfile = objectfiles[idx]
+ local flags = targetinfo.sourceflags[sourcefile]
+ sourceinfos[sourcefile] = sourceinfos[sourcefile] or {}
+ table.insert(sourceinfos[sourcefile], {targetinfo = targetinfo, mode = targetinfo.mode, arch = targetinfo.arch, sourcekind = "cxx", objectfile = objectfile, flags = flags, compargv = targetinfo.compargvs[sourcefile]})
+ end
+ end
end
end
end
@@ -1386,6 +1416,9 @@ function make(vsinfo, target)
-- make source files
_make_source_files(vcxprojfile, vsinfo, target)
+ -- make deps references
+ _make_references(vcxprojfile, vsinfo, target)
+
-- make tailer
_make_tailer(vcxprojfile, vsinfo, target)
diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua
index e992c1bd4..af88b51f6 100644
--- a/xmake/plugins/project/vsxmake/getinfo.lua
+++ b/xmake/plugins/project/vsxmake/getinfo.lua
@@ -154,7 +154,7 @@ function _make_targetinfo(mode, arch, target)
-- fix c++17 to cxx17 for Xmake.props
targetinfo.languages = targetinfo.languages:replace("c++", "cxx", {plain = true})
end
- if target:is_phony() or target:is_headeronly() then
+ if target:is_phony() or target:is_headeronly() or target:is_moduleonly() then
return targetinfo
end