diff options
| author | Jérôme Leclercq <[email protected]> | 2021-12-22 20:56:39 +0100 |
|---|---|---|
| committer | Jérôme Leclercq <[email protected]> | 2021-12-22 20:56:39 +0100 |
| commit | 01b29068ec1effab05be538ed9df3e05727ae181 (patch) | |
| tree | e03fe3f0cc26ca2de3547e1ee8adf5e1cfa34f3b /xmake/plugins/project/vstudio/impl/vs201x.lua | |
| parent | 9d5658ade35f41bb2c8a348e4d835c52eb33cf5d (diff) | |
projects/vstudio: add support for runenvs
Diffstat (limited to 'xmake/plugins/project/vstudio/impl/vs201x.lua')
| -rw-r--r-- | xmake/plugins/project/vstudio/impl/vs201x.lua | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua index bf76b13dc..759789fda 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x.lua @@ -33,10 +33,69 @@ import("vs201x_vcxproj_filters") import("core.cache.memcache") import("core.cache.localcache") import("private.action.require.install", {alias = "install_requires"}) +import("private.action.run.make_runenvs") import("actions.config.configfiles", {alias = "generate_configfiles", rootdir = os.programdir()}) import("actions.config.configheader", {alias = "generate_configheader", rootdir = os.programdir()}) import("private.utils.batchcmds") +-- escape special chars in msbuild file +function _escape(str) + if not str then + return nil + end + + local map = + { + ["%"] = "%25" -- Referencing metadata + , ["$"] = "%24" -- Referencing properties + , ["@"] = "%40" -- Referencing item lists + , ["'"] = "%27" -- Conditions and other expressions + , [";"] = "%3B" -- List separator + , ["?"] = "%3F" -- Wildcard character for file names in Include and Exclude attributes + , ["*"] = "%2A" -- Wildcard character for use in file names in Include and Exclude attributes + -- html entities + , ["\""] = """ + , ["<"] = "<" + , [">"] = ">" + , ["&"] = "&" + } + + return (string.gsub(str, "[%%%$@';%?%*\"<>&]", function (c) return assert(map[c]) end)) +end + +function _make_dirs(dir, vcxprojdir) + if dir == nil then + return "" + end + if type(dir) == "string" then + dir = path.translate(dir) + if dir == "" then + return "" + end + if path.is_absolute(dir) then + print("absolute") + print(dir) + print("projectdir", project.directory()) + if dir:startswith(project.directory()) then + print("relative to ", vcxprojdir) + print(dir) + return _escape(path.relative(dir, vcxprojdir)) + end + return _escape(dir) + else + print("relative") + print(dir) + return _escape(path.relative(path.absolute(dir), vcxprojdir)) + end + end + local r = {} + for k, v in ipairs(dir) do + r[k] = _make_dirs(v, vcxprojdir) + end + r = table.unique(r) + return path.joinenv(r) +end + -- clear cache configuration function _clear_cacheconf() config.clear() @@ -180,7 +239,7 @@ function _make_custom_commands(target) end -- make target info -function _make_targetinfo(mode, arch, target) +function _make_targetinfo(mode, arch, target, vcxprojdir) -- init target info local targetinfo = { mode = mode, arch = (arch == "x86" and "Win32" or "x64") } @@ -246,6 +305,44 @@ function _make_targetinfo(mode, arch, target) -- save execution dir (when executed from VS) targetinfo.rundir = target:rundir() + -- save runenvs + local runenvs = {} + local addrunenvs, setrunenvs = make_runenvs(target) + for k, v in pairs(target:pkgenvs()) do + addrunenvs = addrunenvs or {} + addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v)) + end + for _, dep in ipairs(target:orderdeps()) do + for k, v in pairs(dep:pkgenvs()) do + addrunenvs = addrunenvs or {} + addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v)) + end + end + for k, v in pairs(addrunenvs) do + if k:upper() == "PATH" then + runenvs[k] = format("%s;$([System.Environment]::GetEnvironmentVariable('%s'))", _make_dirs(v, vcxprojdir), k) + else + runenvs[k] = format("%s;$([System.Environment]::GetEnvironmentVariable('%s'))", path.joinenv(v), k) + end + end + for k, v in pairs(setrunenvs) do + if #v == 1 then + v = v[1] + if path.is_absolute(v) and v:startswith(project.directory()) then + runenvs[k] = _make_dirs(v, vcxprojdir) + else + runenvs[k] = v[1] + end + else + runenvs[k] = path.joinenv(v) + end + end + local runenvstr = {} + for k, v in pairs(runenvs) do + table.insert(runenvstr, k .. "=" .. v) + end + targetinfo.runenvs = table.concat(runenvstr, "\n") + -- use mfc? save the mfc runtime kind if target:rule("win.sdk.mfc.shared_app") or target:rule("win.sdk.mfc.shared") then targetinfo.usemfc = "Dynamic" @@ -462,6 +559,9 @@ function make(outputdir, vsinfo) -- make target with the given mode and arch targets[targetname] = targets[targetname] or {} local _target = targets[targetname] + + -- the vcxproj directory + _target.project_dir = path.join(vsinfo.solution_dir, targetname) -- save c/c++ precompiled header _target.pcheader = target:pcheaderfile("c") -- header.h @@ -472,7 +572,7 @@ function make(outputdir, vsinfo) _target.kind = target:kind() _target.scriptdir = target:scriptdir() _target.info = _target.info or {} - table.insert(_target.info, _make_targetinfo(mode, arch, target)) + table.insert(_target.info, _make_targetinfo(mode, arch, target, _target.project_dir)) -- save all sourcefiles and headerfiles _target.sourcefiles = table.unique(table.join(_target.sourcefiles or {}, (target:sourcefiles()))) |
