@@ -26,6 +26,7 @@ import("core.project.project")
2626import (" core.language.language" )
2727import (" core.tool.toolchain" )
2828import (" private.utils.batchcmds" )
29+ import (" detect.sdks.find_cuda" )
2930import (" vsfile" )
3031
3132function _make_dirs (dir , vcxprojdir )
@@ -40,6 +41,22 @@ function _make_dirs(dir, vcxprojdir)
4041 return dir
4142end
4243
44+ -- check for CUDA
45+ function _check_cuda (target )
46+ local sourcekinds = target :sourcekinds ()
47+ if table .contains (sourcekinds , " cu" ) then
48+ return
49+ end
50+ local cuda = find_cuda ()
51+ if cuda then
52+ if cuda .msbuildextensionsdir and cuda .version and os .isfile (path .join (cuda .msbuildextensionsdir , format (" CUDA %s.props" , cuda .version ))) then
53+ return cuda
54+ else
55+ os .raise (" The Visual Studio Integration for CUDA %s is not found. Please check your CUDA installation." , cuda .version )
56+ end
57+ end
58+ end
59+
4360-- get toolset version
4461function _get_toolset_ver (targetinfo , vsinfo )
4562
@@ -159,9 +176,13 @@ function _make_header(vcxprojfile, vsinfo)
159176end
160177
161178-- make tailer
162- function _make_tailer (vcxprojfile , vsinfo )
179+ function _make_tailer (vcxprojfile , vsinfo , target )
163180 vcxprojfile :print (" <Import Project=\" %$(VCTargetsPath)\\ Microsoft.Cpp.targets\" />" )
164181 vcxprojfile :enter (" <ImportGroup Label=\" ExtensionTargets\" >" )
182+ local cuda = _check_cuda (target )
183+ if cuda then
184+ vcxprojfile :print (" <Import Project=\" %s\" />" , path .join (cuda .msbuildextensionsdir , format (" CUDA %s.targets" , cuda .version )))
185+ end
165186 vcxprojfile :leave (" </ImportGroup>" )
166187 vcxprojfile :leave (" </Project>" )
167188end
@@ -219,6 +240,10 @@ function _make_configurations(vcxprojfile, vsinfo, target)
219240
220241 -- make ExtensionSettings
221242 vcxprojfile :enter (" <ImportGroup Label=\" ExtensionSettings\" >" )
243+ local cuda = _check_cuda (target )
244+ if cuda then
245+ vcxprojfile :print (" <Import Project=\" %s\" />" , path .join (cuda .msbuildextensionsdir , format (" CUDA %s.props" , cuda .version )))
246+ end
222247 vcxprojfile :leave (" </ImportGroup>" )
223248
224249 -- make PropertySheets
@@ -562,7 +587,7 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
562587
563588 vcxprojfile :leave (" </%s>" , linkerkinds [targetinfo .targetkind ])
564589
565- -- for compiler?
590+ -- for C/C++ compiler?
566591 vcxprojfile :enter (" <ClCompile>" )
567592
568593 -- make source options
@@ -628,6 +653,17 @@ function _make_common_item(vcxprojfile, vsinfo, target, targetinfo)
628653 end
629654
630655 vcxprojfile :leave (" </ClCompile>" )
656+
657+ -- for CUDA compiler?
658+ local cuda = _check_cuda (target )
659+ if cuda then
660+ vcxprojfile :enter (" <CudaCompile>" )
661+
662+ -- architecture
663+ vcxprojfile :print (" <TargetMachinePlatform>%s</TargetMachinePlatform>" , targetinfo .mode :endswith (" 64" ) and " 64" or " 32" )
664+
665+ vcxprojfile :leave (" </CudaCompile>" )
666+ end
631667
632668 -- make custom commands
633669 _make_custom_commands (vcxprojfile , targetinfo )
@@ -725,7 +761,12 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
725761 end
726762
727763 -- enter it
728- local nodename = (sourcekind == " as" and " CustomBuild" or (sourcekind == " mrc" and " ResourceCompile" or " ClCompile" ))
764+ local nodename
765+ if sourcekind == " as" then nodename = " CustomBuild"
766+ elseif sourcekind == " mrc" then nodename = " ResourceCompile"
767+ elseif sourcekind == " cu" then nodename = " CudaCompile"
768+ elseif sourcekind == " cc" or sourcekind == " cxx" then nodename = " ClCompile"
769+ end
729770 sourcefile = path .relative (path .absolute (sourcefile ), target .project_dir )
730771 vcxprojfile :enter (" <%s Include=\" %s\" >" , nodename , sourcefile )
731772
@@ -749,7 +790,7 @@ function _make_source_file_forall(vcxprojfile, vsinfo, target, sourcefile, sourc
749790 info .mode , info .arch , objectfile )
750791 end
751792
752- -- for *.c/cpp files
793+ -- for *.c/cpp/cu files
753794 else
754795
755796 -- we need use different object directory and allow parallel building
@@ -858,7 +899,12 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
858899 for _ , info in ipairs (sourceinfo ) do
859900
860901 -- enter it
861- local nodename = (info .sourcekind == " as" and " CustomBuild" or (info .sourcekind == " mrc" and " ResourceCompile" or " ClCompile" ))
902+ local nodename
903+ if info .sourcekind == " as" then nodename = " CustomBuild"
904+ elseif info .sourcekind == " mrc" then nodename = " ResourceCompile"
905+ elseif info .sourcekind == " cu" then nodename = " CudaCompile"
906+ elseif info .sourcekind == " cc" or info .sourcekind == " cxx" then nodename = " ClCompile"
907+ end
862908 vcxprojfile :enter (" <%s Condition=\"\' %$(Configuration)|%$(Platform)\' ==\' %s|%s\'\" Include=\" %s\" >" ,
863909 nodename , info .mode , info .arch , sourcefile )
864910
@@ -872,11 +918,11 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
872918 vcxprojfile :print (" <Command>%s</Command>" , compcmd )
873919
874920 -- for *.rc files
875- elseif sourcekind == " mrc" then
921+ elseif info . sourcekind == " mrc" then
876922 vcxprojfile :print (" <ResourceOutputFileName Condition=\"\' %$(Configuration)|%$(Platform)\' ==\' %s|%s\'\" >%s</ResourceOutputFileName>" ,
877923 info .mode , info .arch , objectfile )
878924
879- -- for *.c/cpp files
925+ -- for *.c/cpp/cu files
880926 else
881927 -- we need use different object directory and allow parallel building
882928 --
@@ -888,6 +934,7 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
888934 targetinfo .objectnames = hashset :new ()
889935 end
890936 local targetinfo = info .targetinfo
937+ local outputnode = (info .sourcekind == " cu" and " CompileOut" or " ObjectFileName" )
891938 if targetinfo .objectnames :has (objectname ) then
892939 vcxprojfile :print (" <ObjectFileName Condition=\"\' %$(Configuration)|%$(Platform)\' ==\' %s|%s\'\" >%s</ObjectFileName>" ,
893940 info .mode , info .arch , objectfile )
@@ -897,7 +944,7 @@ function _make_source_file_forspec(vcxprojfile, vsinfo, target, sourcefile, sour
897944
898945 -- disable the precompiled header if sourcekind ~= headerkind
899946 local pcheader = target .pcxxheader or target .pcheader
900- if pcheader and language .sourcekind_of (sourcefile ) ~= (target .pcxxheader and " cxx" or " cc" ) then
947+ if pcheader and info . sourcekind ~= " cu " and language .sourcekind_of (sourcefile ) ~= (target .pcxxheader and " cxx" or " cc" ) then
901948 vcxprojfile :print (" <PrecompiledHeader>NotUsing</PrecompiledHeader>" )
902949 end
903950 vcxprojfile :print (" <AdditionalOptions>%s %%(AdditionalOptions)</AdditionalOptions>" , os .args (info .flags ))
@@ -1017,7 +1064,7 @@ function make(vsinfo, target)
10171064 _make_source_files (vcxprojfile , vsinfo , target )
10181065
10191066 -- make tailer
1020- _make_tailer (vcxprojfile , vsinfo )
1067+ _make_tailer (vcxprojfile , vsinfo , target )
10211068
10221069 -- exit solution file
10231070 vcxprojfile :close ()
0 commit comments