From 4888f584e8cac792995203d593ceaa4e784dc4d9 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 13 Jul 2017 17:48:11 +0800 Subject: support asm source files for vs201x project --- CHANGELOG.md | 2 + .../project/vstudio/impl/vs201x_vcxproj.lua | 157 ++++++++++++--------- .../vstudio/impl/vs201x_vcxproj_filters.lua | 5 +- 3 files changed, 97 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa65cb767..afbb8ad2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ * [#71](https://github.com/tboox/xmake/issues/71): Improve to detect compiler and linker from env vars * Improve the option detection (cache and multi-jobs) and increase 70% speed * [#129](https://github.com/tboox/xmake/issues/129): Check link deps and cache the target file +* Support `*.asm` source files for vs201x project plugin ### Bugs fixed @@ -334,6 +335,7 @@ * [#71](https://github.com/tboox/xmake/issues/71): 改进从环境变量中探测链接器和编译器 * 改进option选项检测,通过多任务检测,提升70%的检测速度 * [#129](https://github.com/tboox/xmake/issues/129): 检测链接依赖,如果源文件没有改变,就不必重新链接目标文件了 +* 在vs201x工程插件中增加对`*.asm`文件的支持 ### Bugs修复 diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua index 2bc68af20..122218c17 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj.lua @@ -385,21 +385,25 @@ function _make_common_items(vcxprojfile, vsinfo, target, vcxprojdir) local first_flags = nil targetinfo.sourceflags = {} for sourcekind, sourcebatch in pairs(targetinfo.sourcebatches) do - if sourcekind == "cc" or sourcekind == "cxx" then + if sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do -- make compiler flags local flags = _make_compflags(sourcefile, targetinfo, vcxprojdir) - for _, flag in ipairs(flags) do - flags_stats[flag] = (flags_stats[flag] or 0) + 1 - end - -- update files count - files_count = files_count + 1 + -- no common flags for asm + if sourcekind ~= "as" then + for _, flag in ipairs(flags) do + flags_stats[flag] = (flags_stats[flag] or 0) + 1 + end + + -- update files count + files_count = files_count + 1 - -- save first flags - if first_flags == nil then - first_flags = flags + -- save first flags + if first_flags == nil then + first_flags = flags + end end -- save source flags @@ -442,105 +446,130 @@ end -- make source file for all modes function _make_source_file_forall(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir) - -- get object file - local objectfile = nil + -- get object file and source kind + local sourcekind = nil for _, info in ipairs(sourceinfo) do - objectfile = info.objectfile + sourcekind = info.sourcekind break end -- enter it - vcxprojfile:enter("", path.relative(path.absolute(sourcefile), vcxprojdir)) - - -- make ObjectFileName - vcxprojfile:print("%s", path.relative(path.absolute(objectfile), vcxprojdir)) + sourcefile = path.relative(path.absolute(sourcefile), vcxprojdir) + vcxprojfile:enter("<%s Include=\"%s\">", ifelse(sourcekind == "as", "CustomBuild", "ClCompile"), sourcefile) + + -- for *.asm files + if sourcekind == "as" then + vcxprojfile:print("false") + vcxprojfile:print("Document") + for _, info in ipairs(sourceinfo) do + local objectfile = path.relative(path.absolute(info.objectfile), vcxprojdir) + vcxprojfile:print("%s", info.mode .. '|' .. info.arch, objectfile) + vcxprojfile:print("%s /nologo /c %s -Fo%s %s", info.mode .. '|' .. info.arch, ifelse(info.arch == "x64", "ml64", "ml"), os.args(info.flags), objectfile, sourcefile) + end - -- make AdditionalOptions - local mergeflags = {} - for _, info in ipairs(sourceinfo) do - local flags = os.args(info.flags) - if flags ~= "" then + -- for *.c/cpp files + else + + -- make AdditionalOptions + local mergeflags = {} + local objectfiles = {} + for _, info in ipairs(sourceinfo) do + local flags = os.args(info.flags) mergeflags[flags] = mergeflags[flags] or {} mergeflags[flags][info.mode .. '|' .. info.arch] = true + objectfiles[flags] = path.relative(path.absolute(info.objectfile), vcxprojdir) end - end - for flags, mergeinfos in pairs(mergeflags) do - - -- merge mode and arch first - local count = 0 - for _, mode in ipairs(vsinfo.modes) do - if mergeinfos[mode .. "|Win32"] and mergeinfos[mode .. "|x64"] then - mergeinfos[mode .. "|Win32"] = nil - mergeinfos[mode .. "|x64"] = nil - mergeinfos[mode] = true - end - if mergeinfos[mode] then - count = count + 1 + for flags, mergeinfos in pairs(mergeflags) do + + -- merge mode and arch first + local count = 0 + for _, mode in ipairs(vsinfo.modes) do + if mergeinfos[mode .. "|Win32"] and mergeinfos[mode .. "|x64"] then + mergeinfos[mode .. "|Win32"] = nil + mergeinfos[mode .. "|x64"] = nil + mergeinfos[mode] = true + end + if mergeinfos[mode] then + count = count + 1 + end end - end - -- all modes and archs exist? - if count == #vsinfo.modes then - vcxprojfile:print("%s %%(AdditionalOptions)", flags) - else - for cond, _ in pairs(mergeinfos) do - if cond:find('|', 1, true) then - -- for mode | arch - vcxprojfile:print("%s %%(AdditionalOptions)", cond, flags) - else - -- only for mode - vcxprojfile:print("%s %%(AdditionalOptions)", cond, flags) + -- all modes and archs exist? + if count == #vsinfo.modes then + vcxprojfile:print("%s", objectfiles[flags]) + if #flags > 0 then + vcxprojfile:print("%s %%(AdditionalOptions)", flags) + end + else + for cond, _ in pairs(mergeinfos) do + if cond:find('|', 1, true) then + -- for mode | arch + vcxprojfile:print("%s", cond, objectfiles[flags]) + if #flags > 0 then + vcxprojfile:print("%s %%(AdditionalOptions)", cond, flags) + end + else + -- only for mode + vcxprojfile:print("%s", cond, objectfiles[flags]) + if #flags > 0 then + vcxprojfile:print("%s %%(AdditionalOptions)", cond, flags) + end + end end end end end -- leave it - vcxprojfile:leave("") + vcxprojfile:leave("", ifelse(sourcekind == "as", "CustomBuild", "ClCompile")) end -- make source file for specific modes function _make_source_file_forspec(vcxprojfile, vsinfo, sourcefile, sourceinfo, vcxprojdir) -- add source file + sourcefile = path.relative(path.absolute(sourcefile), vcxprojdir) for _, info in ipairs(sourceinfo) do -- enter it - vcxprojfile:enter("", info.mode, info.arch, path.relative(path.absolute(sourcefile), vcxprojdir)) - - -- make ObjectFileName - vcxprojfile:print("%s", path.relative(path.absolute(info.objectfile), vcxprojdir)) - - -- get source flags - local flags = os.args(info.flags) - - -- make AdditionalOptions - if flags ~= "" then - vcxprojfile:print("%s %%(AdditionalOptions)", flags) + vcxprojfile:enter("<%s Condition=\"\'%$(Configuration)|%$(Platform)\'==\'%s|%s\'\" Include=\"%s\">", ifelse(info.sourcekind == "as", "CustomBuild", "ClCompile"), info.mode, info.arch, sourcefile) + + -- for *.asm files + local objectfile = path.relative(path.absolute(info.objectfile), vcxprojdir) + if info.sourcekind == "as" then + vcxprojfile:print("false") + vcxprojfile:print("Document") + vcxprojfile:print("%s", objectfile) + vcxprojfile:print("%s /nologo /c %s -Fo%s %s", ifelse(info.arch == "x64", "ml64", "ml"), os.args(info.flags), objectfile, sourcefile) + + -- for *.c/cpp files + else + vcxprojfile:print("%s", objectfile) + vcxprojfile:print("%s %%(AdditionalOptions)", os.args(info.flags)) end -- leave it - vcxprojfile:leave("") + vcxprojfile:leave("", ifelse(info.sourcekind == "as", "CustomBuild", "ClCompile")) end end -- make source files function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir) - -- enter ItemGroup + -- add source files vcxprojfile:enter("") -- make source file infos local sourceinfos = {} for _, targetinfo in ipairs(target.info) do for sourcekind, sourcebatch in pairs(targetinfo.sourcebatches) do - if sourcekind == "cc" or sourcekind == "cxx" then + if sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" then local objectfiles = sourcebatch.objectfiles for idx, sourcefile in ipairs(sourcebatch.sourcefiles) do local objectfile = objectfiles[idx] local flags = targetinfo.sourceflags[sourcefile] sourceinfos[sourcefile] = sourceinfos[sourcefile] or {} - table.insert(sourceinfos[sourcefile], {mode = targetinfo.mode, arch = targetinfo.arch, objectfile = objectfile, flags = flags}) + table.insert(sourceinfos[sourcefile], {mode = targetinfo.mode, arch = targetinfo.arch, sourcekind = sourcekind, objectfile = objectfile, flags = flags}) end end end @@ -557,10 +586,8 @@ function _make_source_files(vcxprojfile, vsinfo, target, vcxprojdir) vcxprojfile:leave("") - -- enter header group + -- add headers vcxprojfile:enter("") - - -- add headers for _, includefile in ipairs(target.headerfiles) do _make_header_file(vcxprojfile, includefile, vcxprojdir) end diff --git a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua index c10137303..a1a7be693 100644 --- a/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua +++ b/xmake/plugins/project/vstudio/impl/vs201x_vcxproj_filters.lua @@ -93,9 +93,10 @@ function _make_sources(filtersfile, vsinfo, target, vcxprojdir) for _, sourcefile in ipairs(target.sourcefiles) do local filter = _make_filter(sourcefile, target, vcxprojdir) if filter then - filtersfile:enter("", path.relative(path.absolute(sourcefile), vcxprojdir)) + local as = sourcefile:endswith(".asm") + filtersfile:enter("<%s Include=\"%s\">", ifelse(as, "CustomBuild", "ClCompile"), path.relative(path.absolute(sourcefile), vcxprojdir)) filtersfile:print("%s", filter) - filtersfile:leave("") + filtersfile:leave("", ifelse(as, "CustomBuild", "ClCompile")) end end filtersfile:leave("") -- cgit v1.3.1