diff --git a/xmake/plugins/project/vstudio/impl/vs200x.lua b/xmake/plugins/project/vstudio/impl/vs200x.lua
index d1f220c8aac..409d73a4930 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x.lua
@@ -22,6 +22,7 @@
import("core.project.project")
import("vs200x_solution")
import("vs200x_vcproj")
+import("vs_csproj")
-- make vstudio project
function make(outputdir, vsinfo)
@@ -44,8 +45,17 @@ function make(outputdir, vsinfo)
-- make vsprojs
for _, target in pairs(project.targets()) do
- if not target:is_phony() then
- vs200x_vcproj.make(vsinfo, target)
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind == "cc" or sourcekind == "cxx" then
+ if not target:is_phony() then
+ vs200x_vcproj.make(vsinfo, target)
+ end
+ break
+ elseif sourcekind == "cs" then
+ vs_csproj.make(vsinfo, target)
+ break
+ end
end
end
diff --git a/xmake/plugins/project/vstudio/impl/vs200x_solution.lua b/xmake/plugins/project/vstudio/impl/vs200x_solution.lua
index 48b10445f57..b0a0987979f 100644
--- a/xmake/plugins/project/vstudio/impl/vs200x_solution.lua
+++ b/xmake/plugins/project/vstudio/impl/vs200x_solution.lua
@@ -31,15 +31,29 @@ end
-- make projects
function _make_projects(slnfile, vsinfo)
- -- the vstudio tool uuid for vc project
- local vctool = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
-
-- make all targets
for targetname, target in pairs(project.targets()) do
+
+ tool_id = "" -- the vstudio tool uuid for project
+ proj_extension = ""
+
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind == "cc" or sourcekind == "cxx" then
+ tool_id = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
+ proj_extension = "vcxproj"
+ break
+ elseif sourcekind == "cs" then
+ tool_id = "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"
+ proj_extension = "csproj"
+ break
+ end
+ end
+
if not target:is_phony() then
-- enter project
- slnfile:enter("Project(\"{%s}\") = \"%s\", \"%s\\%s.vcproj\", \"{%s}\"", vctool, targetname, targetname, targetname, hash.uuid4(targetname))
+ slnfile:enter("Project(\"{%s}\") = \"%s\", \"%s\\%s.%s\", \"{%s}\"", tool_id, targetname, targetname, targetname, proj_extension, hash.uuid4(targetname))
-- add dependences
for _, dep in ipairs(target:get("deps")) do
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index a8b48dada5f..0d071270010 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -32,6 +32,7 @@ import("core.tool.toolchain")
import("vs201x_solution")
import("vs201x_vcxproj")
import("vs201x_vcxproj_filters")
+import("vs_csproj")
import("vsutils")
import("core.cache.memcache")
import("core.cache.localcache")
@@ -288,7 +289,7 @@ function _make_targetinfo(mode, arch, target, vcxprojdir)
for _, sourcebatch in table.orderpairs(sourcebatches) do
local sourcekind = sourcebatch.sourcekind
local rulename = sourcebatch.rulename
- if sourcekind then
+ if sourcekind and sourcekind ~= "cs" then -- TODO: temp, delete it when cs flags are done
for idx, 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
@@ -567,10 +568,18 @@ function make(outputdir, vsinfo)
-- make solution
vs201x_solution.make(vsinfo)
- -- make .vcxproj
+ -- make .vcxproj and .csproj
for _, target in table.orderpairs(targets) do
- vs201x_vcxproj.make(vsinfo, target)
- vs201x_vcxproj_filters.make(vsinfo, target)
+ for _, targetinfo in ipairs(target.info) do
+ if targetinfo.sourcekinds and table.contains(targetinfo.sourcekinds, "cc", "cxx") then
+ vs201x_vcxproj.make(vsinfo, target)
+ vs201x_vcxproj_filters.make(vsinfo, target)
+ break
+ elseif targetinfo.sourcekinds and table.contains(targetinfo.sourcekinds, "cs") then
+ vs_csproj.make(vsinfo, target)
+ break
+ end
+ end
end
-- clear local cache
diff --git a/xmake/plugins/project/vstudio/impl/vs201x_solution.lua b/xmake/plugins/project/vstudio/impl/vs201x_solution.lua
index 82ede489a75..4f8b5d14360 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x_solution.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x_solution.lua
@@ -35,7 +35,6 @@ function _make_projects(slnfile, vsinfo)
-- make all targets
local groups = {}
local targets = {}
- local vctool = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
for targetname, target in table.orderpairs(project.targets()) do
-- we need to set startup project for default or binary target
-- @see https://github.com/xmake-io/xmake/issues/1249
@@ -53,8 +52,23 @@ function _make_projects(slnfile, vsinfo)
end
end
for _, target in ipairs(targets) do
+ tool_id = ""
+ proj_extension = ""
+ for _, sourcebatch in pairs(target:sourcebatches()) do
+ local sourcekind = sourcebatch.sourcekind
+ if sourcekind == "cc" or sourcekind == "cxx" then
+ tool_id = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"
+ proj_extension = "vcxproj"
+ break
+ elseif sourcekind == "cs" then
+ tool_id = "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"
+ proj_extension = "csproj"
+ break
+ end
+ end
+
local targetname = target:name()
- slnfile:enter("Project(\"{%s}\") = \"%s\", \"%s\\%s.vcxproj\", \"{%s}\"", vctool, targetname, targetname, targetname, hash.uuid4(targetname))
+ slnfile:enter("Project(\"{%s}\") = \"%s\", \"%s\\%s.%s\", \"{%s}\"", tool_id, targetname, targetname, targetname, proj_extension, hash.uuid4(targetname))
for _, dep in ipairs(target:get("deps")) do
slnfile:enter("ProjectSection(ProjectDependencies) = postProject")
slnfile:print("{%s} = {%s}", hash.uuid4(dep), hash.uuid4(dep))
diff --git a/xmake/plugins/project/vstudio/impl/vs_csproj.lua b/xmake/plugins/project/vstudio/impl/vs_csproj.lua
new file mode 100644
index 00000000000..cff20ca687d
--- /dev/null
+++ b/xmake/plugins/project/vstudio/impl/vs_csproj.lua
@@ -0,0 +1,214 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author Kethers
+-- @file vs_csproj.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.hashset")
+import("core.project.rule")
+import("core.project.config")
+import("core.project.project")
+import("core.language.language")
+import("core.tool.toolchain")
+import("private.utils.batchcmds")
+import("vsfile")
+import("vsutils")
+import("plugins.project.vsxmake.getinfo", {rootdir = os.programdir()})
+
+
+function _make_dirs(dir, csprojdir)
+ dir = dir:trim()
+ if #dir == 0 then
+ return ""
+ end
+ dir = path.translate(dir)
+ if not path.is_absolute(dir) then
+ dir = path.relative(path.absolute(dir), csprojdir)
+ end
+ return dir
+end
+
+-- make header
+function _make_header(csprojfile, vsinfo)
+ csprojfile:print("")
+ csprojfile:enter("", assert(vsinfo.project_version))
+end
+
+function _make_configurations(csprojfile, vsinfo, target)
+ -- the target name
+ local targetname = target.name
+
+ -- init configuration type
+ local output_types =
+ {
+ binary = "Exe"
+ -- , winexe = "WinExe" TODO: this kind doesn't exist yet
+ , shared = "Library"
+ }
+
+ -- import Microsoft.Common.props
+ csprojfile:print("")
+
+ -- make Globals
+ csprojfile:enter("")
+ csprojfile:print("debug")
+ csprojfile:print("x64")
+ csprojfile:print("{%s}", hash.uuid4(targetname))
+ csprojfile:print("%s", output_types[target.kind] or "Unknown")
+ csprojfile:print("Properties")
+ csprojfile:print("%s", targetname)
+ csprojfile:print("%s", targetname)
+ csprojfile:print("v%s", vsinfo.dotnetframework_version)
+ csprojfile:print("512")
+ csprojfile:print("true")
+ csprojfile:leave("")
+
+ -- make Configuration
+ for _, targetinfo in ipairs(target.info) do
+ local mode = targetinfo.mode
+ local arch = targetinfo.arch
+
+ symbols = vsinfo._targets[targetname]._targets[mode][arch].symbols or ""
+ optimize = vsinfo._targets[targetname]._targets[mode][arch].optimize or ""
+
+ debugtype = "portable"
+ debugsymbols = "true"
+ if (symbols == "debug") then
+ debugtype = "full"
+ debugsymbols = "true"
+ elseif (symbols == "hidden") then
+ debugtype = "none"
+ debugsymbols = "false"
+ elseif (string.find(symbols, "debug") and string.find(symbols, "embed")) then
+ debugtype = "embedded"
+ debugsymbols = "true"
+ end
+
+ if optimize == "" or optimize == "none" then
+ optimize = "false"
+ else
+ optimize = "true"
+ end
+
+ csprojfile:enter("", mode, arch)
+ csprojfile:print("%s", debugtype)
+ csprojfile:print("%s", debugsymbols)
+ csprojfile:print("%s", optimize)
+ csprojfile:print("%s", _make_dirs(targetinfo.targetdir, target.project_dir))
+ csprojfile:print("%s", _make_dirs(targetinfo.objectdir, target.project_dir))
+ csprojfile:print("%$(BaseIntermediateOutputPath)")
+ csprojfile:print("%s", vsinfo._targets[targetname]._targets[mode][arch].defines)
+ csprojfile:print("prompt")
+ csprojfile:print("4")
+ csprojfile:leave("")
+ end
+end
+
+-- make source files
+function _make_source_files(csprojfile, vsinfo, target)
+ -- make source file infos
+ local sourceinfos = {}
+ for _, targetinfo in ipairs(target.info) do
+ for _, sourcebatch in pairs(targetinfo.sourcebatches) do
+ local sourcekind = sourcebatch.sourcekind
+ local rulename = sourcebatch.rulename
+ if (sourcekind == "cs") then
+ local objectfiles = sourcebatch.objectfiles
+ for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local objectfile = objectfiles[idx]
+ -- local flags = targetinfo.sourceflags[sourcefile] -- TODO: cs flags doesn't exist yet
+ 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
+ end
+ end
+ end
+
+ -- make source files
+ csprojfile:enter("")
+ for sourcefile, sourceinfo in table.orderpairs(sourceinfos) do
+ if #sourceinfo == #target.info then
+ csprojfile:print("", path.relative(path.absolute(sourcefile), target.project_dir))
+ end
+ end
+ csprojfile:leave("")
+end
+
+-- make project references
+function _make_project_references(csprojfile, vsinfo, target)
+ local deps = vsinfo._targets[target.name]._deps
+
+ csprojfile:enter("")
+
+ for depname, dep in table.orderpairs(deps) do
+ proj_extension = dep.proj_extension
+ csprojfile:enter(" ", depname, depname, proj_extension)
+ csprojfile:print("{%s}", dep.target_id)
+ csprojfile:print("%s", depname)
+ csprojfile:leave("")
+ end
+
+ csprojfile:leave("")
+end
+
+-- make tailer
+function _make_tailer(csprojfile, vsinfo, target)
+ -- import Microsoft.CSharp.targets
+ csprojfile:print("")
+
+ csprojfile:leave("")
+end
+
+-- make csproj
+function make(vsinfo, target)
+
+ -- TODO: getinfo will leads to repeat MSVC checking output, try not to use it
+ local info = getinfo(option.get("outputdir"), vsinfo)
+
+ -- the target name
+ local targetname = target.name
+
+ -- the csproj directory
+ local csprojdir = target.project_dir
+
+ -- open csproj file
+ local csprojpath = path.join(csprojdir, targetname .. ".csproj")
+ local csprojfile = vsfile.open(csprojpath, "w")
+
+ -- init indent character
+ vsfile.indentchar(' ')
+
+ -- make headers
+ _make_header(csprojfile, info)
+
+ -- make Configurations
+ _make_configurations(csprojfile, info, target)
+
+ -- make source files
+ _make_source_files(csprojfile, info, target)
+
+ -- make project references
+ _make_project_references(csprojfile, info, target)
+
+ -- make tailer
+ _make_tailer(csprojfile, info, target)
+
+ -- exit solution file
+ csprojfile:close()
+end
\ No newline at end of file
diff --git a/xmake/scripts/vsxmake/vsproj/templates/csproj/#target#.csproj b/xmake/scripts/vsxmake/vsproj/templates/csproj/#target#.csproj
index 6c85432b633..cf4a87b85c0 100644
--- a/xmake/scripts/vsxmake/vsproj/templates/csproj/#target#.csproj
+++ b/xmake/scripts/vsxmake/vsproj/templates/csproj/#target#.csproj
@@ -10,7 +10,7 @@
See https://github.com/xmake-io/xmake/pull/472 for more infomation.
-->
-
+
$(XMAKE_PROGRAM_DIR)
#programdir#
diff --git a/xmake/scripts/vsxmake/vsproj/templates/csproj/ProjectRef(dep) b/xmake/scripts/vsxmake/vsproj/templates/csproj/ProjectRef(dep)
index dfccc2095bd..52deb3110b7 100644
--- a/xmake/scripts/vsxmake/vsproj/templates/csproj/ProjectRef(dep)
+++ b/xmake/scripts/vsxmake/vsproj/templates/csproj/ProjectRef(dep)
@@ -1,4 +1,4 @@
{#target_id#}
- {#target#}
+ #target#
diff --git a/xmake/scripts/vsxmake/vsproj/templates/vcxproj/ProjectRef(dep) b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/ProjectRef(dep)
index dfccc2095bd..52deb3110b7 100644
--- a/xmake/scripts/vsxmake/vsproj/templates/vcxproj/ProjectRef(dep)
+++ b/xmake/scripts/vsxmake/vsproj/templates/vcxproj/ProjectRef(dep)
@@ -1,4 +1,4 @@
{#target_id#}
- {#target#}
+ #target#