@@ -34,9 +34,7 @@ function m.generate(prj)
3434 _p (" " ) -- Empty line at end of file
3535end
3636
37- -- Generate all ninja rules (compile, link, etc.)
3837function m .rules (prj )
39- -- Generate rules for each configuration to handle different toolsets
4038 local rulesDone = {}
4139
4240 for cfg in project .eachconfig (prj ) do
@@ -298,12 +296,18 @@ function m.getCFlags(cfg, toolset)
298296
299297 local defines = toolset .getdefines (cfg .defines )
300298 flags = table .join (flags , defines )
299+
300+ local undefines = toolset .getundefines (cfg .undefines )
301+ flags = table .join (flags , undefines )
301302
302303 local includedirs = toolset .getincludedirs (cfg , cfg .includedirs , cfg .externalincludedirs , cfg .frameworkdirs )
303304 flags = table .join (flags , includedirs )
304305
305306 local forceincludes = toolset .getforceincludes (cfg )
306307 flags = table .join (flags , forceincludes )
308+
309+ local buildopts = cfg .buildoptions or {}
310+ flags = table .join (flags , buildopts )
307311
308312 return flags
309313end
@@ -317,12 +321,18 @@ function m.getCxxFlags(cfg, toolset)
317321
318322 local defines = toolset .getdefines (cfg .defines )
319323 flags = table .join (flags , defines )
324+
325+ local undefines = toolset .getundefines (cfg .undefines )
326+ flags = table .join (flags , undefines )
320327
321328 local includedirs = toolset .getincludedirs (cfg , cfg .includedirs , cfg .externalincludedirs , cfg .frameworkdirs )
322329 flags = table .join (flags , includedirs )
323330
324331 local forceincludes = toolset .getforceincludes (cfg )
325332 flags = table .join (flags , forceincludes )
333+
334+ local buildopts = cfg .buildoptions or {}
335+ flags = table .join (flags , buildopts )
326336
327337 return flags
328338end
@@ -333,6 +343,9 @@ function m.getLdFlags(cfg, toolset)
333343
334344 local toolFlags = toolset .getldflags (cfg )
335345 flags = table .join (flags , toolFlags )
346+
347+ local linkopts = cfg .linkoptions or {}
348+ flags = table .join (flags , linkopts )
336349
337350 local libdirs = toolset .getLibraryDirectories (cfg )
338351 flags = table .join (flags , libdirs )
@@ -471,7 +484,19 @@ function m.objectFile(cfg, node, filecfg)
471484 local objdir = path .getrelative (cfg .workspace .location , cfg .objdir )
472485 local ext = path .getextension (node .abspath ):lower ()
473486
474- if path .iscppfile (node .abspath ) or path .iscfile (node .abspath ) then
487+ local shouldCompile = false
488+
489+ if filecfg and filecfg .compileas and filecfg .compileas ~= " Default" then
490+ if p .languages .isc (filecfg .compileas ) or p .languages .iscpp (filecfg .compileas ) then
491+ shouldCompile = true
492+ end
493+ else
494+ if path .iscppfile (node .abspath ) or path .iscfile (node .abspath ) then
495+ shouldCompile = true
496+ end
497+ end
498+
499+ if shouldCompile then
475500 local objname = filecfg .objname or path .getbasename (node .abspath )
476501 local toolset = ninja .gettoolset (cfg )
477502 local objext = toolset .gettooloutputext (" cc" )
@@ -485,20 +510,40 @@ function m.buildFile(cfg, node, filecfg, objFile, pchFile, prebuildTarget)
485510 local ext = path .getextension (node .abspath ):lower ()
486511 local rule = nil
487512 local flags = " "
513+ local extraFlags = {}
514+ local toolset = ninja .gettoolset (cfg )
488515
489- if path .iscfile (node .abspath ) then
490- rule = " cc"
491- flags = " cflags_" .. ninja .key (cfg )
492- elseif path .iscppfile (node .abspath ) then
493- rule = " cxx"
494- flags = " cxxflags_" .. ninja .key (cfg )
516+ if filecfg and filecfg .compileas and filecfg .compileas ~= " Default" then
517+ if p .languages .isc (filecfg .compileas ) then
518+ rule = " cc"
519+ flags = " cflags_" .. ninja .key (cfg )
520+
521+ if toolset .shared and toolset .shared .compileas and toolset .shared .compileas [" C" ] then
522+ table.insert (extraFlags , toolset .shared .compileas [" C" ])
523+ end
524+ elseif p .languages .iscpp (filecfg .compileas ) then
525+ rule = " cxx"
526+ flags = " cxxflags_" .. ninja .key (cfg )
527+
528+ if toolset .shared and toolset .shared .compileas and toolset .shared .compileas [" C++" ] then
529+ table.insert (extraFlags , toolset .shared .compileas [" C++" ])
530+ end
531+ end
532+ else
533+ if path .iscfile (node .abspath ) then
534+ rule = " cc"
535+ flags = " cflags_" .. ninja .key (cfg )
536+ elseif path .iscppfile (node .abspath ) then
537+ rule = " cxx"
538+ flags = " cxxflags_" .. ninja .key (cfg )
539+ end
495540 end
496541
497542 if rule then
498543 local relPath = path .getrelative (cfg .workspace .location , node .abspath )
499544 local implicitDeps = " "
500545
501- if pchFile and not filecfg .flags .NoPCH then
546+ if pchFile and filecfg and not filecfg .flags .NoPCH then
502547 implicitDeps = implicitDeps .. " | " .. pchFile
503548 end
504549
@@ -512,9 +557,17 @@ function m.buildFile(cfg, node, filecfg, objFile, pchFile, prebuildTarget)
512557 _p (" build %s: %s %s%s" , objFile , rule , relPath , implicitDeps )
513558
514559 if rule == " cc" then
515- _p (" cflags = $%s" , flags )
560+ if # extraFlags > 0 then
561+ _p (" cflags = $%s %s" , flags , table.concat (extraFlags , " " ))
562+ else
563+ _p (" cflags = $%s" , flags )
564+ end
516565 else
517- _p (" cxxflags = $%s" , flags )
566+ if # extraFlags > 0 then
567+ _p (" cxxflags = $%s %s" , flags , table.concat (extraFlags , " " ))
568+ else
569+ _p (" cxxflags = $%s" , flags )
570+ end
518571 end
519572 end
520573end
@@ -595,13 +648,9 @@ function m.linkTarget(cfg)
595648 end
596649
597650 local hasPostBuild = # cfg .postbuildcommands > 0 or cfg .postbuildmessage
598- local linkTargetName = targetPath
599651
600- if hasPostBuild then
601- linkTargetName = targetPath .. " .link"
602- end
603-
604- _p (" build %s: %s %s%s" , linkTargetName , rule , table.concat (cfg ._objectFiles , " " ), implicitDeps )
652+ -- Always use the actual target name for the link rule
653+ _p (" build %s: %s %s%s" , targetPath , rule , table.concat (cfg ._objectFiles , " " ), implicitDeps )
605654
606655 if cfg .kind ~= p .STATICLIB then
607656 _p (" ldflags = $ldflags_%s" , ninja .key (cfg ))
@@ -613,7 +662,7 @@ function m.linkTarget(cfg)
613662 end
614663
615664 if hasPostBuild then
616- m .buildPostBuildEvents (cfg , linkTargetName , targetPath )
665+ m .buildPostBuildEvents (cfg , targetPath )
617666 end
618667end
619668
@@ -630,15 +679,15 @@ function m.buildPreBuildEvents(cfg)
630679
631680 if hasMessage and not hasCommands then
632681 _p (" build %s: prebuildmessage" , prebuildTarget )
633- _p (" prebuildmessage = %s " , cfg .prebuildmessage )
682+ _p (" prebuildmessage = \" %s \" " , cfg .prebuildmessage )
634683 elseif hasCommands and not hasMessage then
635684 local commands = os .translateCommandsAndPaths (cfg .prebuildcommands , cfg .project .basedir , cfg .project .location )
636685 local cmdStr = table.concat (commands , " && " )
637686 _p (" build %s: prebuild" , prebuildTarget )
638687 _p (" prebuildcommands = %s" , cmdStr )
639688 else
640689 local commands = os .translateCommandsAndPaths (cfg .prebuildcommands , cfg .project .basedir , cfg .project .location )
641- local cmdStr = " echo " .. ninja . esc ( cfg .prebuildmessage ) .. " && " .. table.concat (commands , " && " )
690+ local cmdStr = " echo \" " .. cfg .prebuildmessage .. " \ " && " .. table.concat (commands , " && " )
642691 _p (" build %s: prebuild" , prebuildTarget )
643692 _p (" prebuildcommands = %s" , cmdStr )
644693 end
@@ -659,42 +708,45 @@ function m.buildPreLinkEvents(cfg)
659708
660709 if hasMessage and not hasCommands then
661710 _p (" build %s: prelinkmessage" , prelinkTarget )
662- _p (" prelinkmessage = %s " , cfg .prelinkmessage )
711+ _p (" prelinkmessage = \" %s \" " , cfg .prelinkmessage )
663712 elseif hasCommands and not hasMessage then
664713 local commands = os .translateCommandsAndPaths (cfg .prelinkcommands , cfg .project .basedir , cfg .project .location )
665714 local cmdStr = table.concat (commands , " && " )
666715 _p (" build %s: prelink" , prelinkTarget )
667716 _p (" prelinkcommands = %s" , cmdStr )
668717 else
669718 local commands = os .translateCommandsAndPaths (cfg .prelinkcommands , cfg .project .basedir , cfg .project .location )
670- local cmdStr = " echo " .. ninja . esc ( cfg .prelinkmessage ) .. " && " .. table.concat (commands , " && " )
719+ local cmdStr = " echo \" " .. cfg .prelinkmessage .. " \ " && " .. table.concat (commands , " && " )
671720 _p (" build %s: prelink" , prelinkTarget )
672721 _p (" prelinkcommands = %s" , cmdStr )
673722 end
674723
675724 return prelinkTarget
676725end
677726
678- function m .buildPostBuildEvents (cfg , linkTarget , finalTarget )
727+ function m .buildPostBuildEvents (cfg , targetPath )
679728 local hasMessage = cfg .postbuildmessage ~= nil
680729 local hasCommands = # cfg .postbuildcommands > 0
681730
682731 if not hasMessage and not hasCommands then
683732 return
684733 end
685734
735+ -- Create a phony intermediate target for the postbuild step
736+ local postbuildPhony = path .getrelative (cfg .workspace .location , cfg .buildtarget .directory ) .. " /" .. cfg .project .name .. " .postbuild"
737+
686738 if hasMessage and not hasCommands then
687- _p (" build %s: postbuildmessage %s" , finalTarget , linkTarget )
688- _p (" postbuildmessage = %s " , cfg .postbuildmessage )
739+ _p (" build %s: postbuildmessage | %s" , postbuildPhony , targetPath )
740+ _p (" postbuildmessage = \" %s \" " , cfg .postbuildmessage )
689741 elseif hasCommands and not hasMessage then
690742 local commands = os .translateCommandsAndPaths (cfg .postbuildcommands , cfg .project .basedir , cfg .project .location )
691743 local cmdStr = table.concat (commands , " && " )
692- _p (" build %s: postbuild %s" , finalTarget , linkTarget )
744+ _p (" build %s: postbuild | %s" , postbuildPhony , targetPath )
693745 _p (" postbuildcommands = %s" , cmdStr )
694746 else
695747 local commands = os .translateCommandsAndPaths (cfg .postbuildcommands , cfg .project .basedir , cfg .project .location )
696- local cmdStr = " echo " .. ninja . esc ( cfg .postbuildmessage ) .. " && " .. table.concat (commands , " && " )
697- _p (" build %s: postbuild %s" , finalTarget , linkTarget )
748+ local cmdStr = " echo \" " .. cfg .postbuildmessage .. " \ " && " .. table.concat (commands , " && " )
749+ _p (" build %s: postbuild | %s" , postbuildPhony , targetPath )
698750 _p (" postbuildcommands = %s" , cmdStr )
699751 end
700752end
@@ -707,7 +759,14 @@ function m.buildTargets(prj)
707759 local targetPath = path .getrelative (cfg .workspace .location , cfg .buildtarget .directory ) .. " /" .. cfg .buildtarget .name
708760 local cfgName = ninja .key (cfg )
709761
710- _p (" build %s: phony %s" , cfgName , targetPath )
762+ -- If there are postbuild events, point to the postbuild target instead
763+ local hasPostBuild = # cfg .postbuildcommands > 0 or cfg .postbuildmessage
764+ if hasPostBuild then
765+ local postbuildTarget = path .getrelative (cfg .workspace .location , cfg .buildtarget .directory ) .. " /" .. cfg .project .name .. " .postbuild"
766+ _p (" build %s: phony %s" , cfgName , postbuildTarget )
767+ else
768+ _p (" build %s: phony %s" , cfgName , targetPath )
769+ end
711770 end
712771
713772 _p (" " )
@@ -720,7 +779,15 @@ function m.projectPhonies(prj)
720779 local firstCfg = project .getfirstconfig (prj )
721780 if firstCfg then
722781 local targetPath = path .getrelative (firstCfg .workspace .location , firstCfg .buildtarget .directory ) .. " /" .. firstCfg .buildtarget .name
723- _p (" build %s: phony %s" , prj .name , targetPath )
782+
783+ -- If there are postbuild events in the first config, point to the postbuild target
784+ local hasPostBuild = # firstCfg .postbuildcommands > 0 or firstCfg .postbuildmessage
785+ if hasPostBuild then
786+ local postbuildTarget = path .getrelative (firstCfg .workspace .location , firstCfg .buildtarget .directory ) .. " /" .. firstCfg .project .name .. " .postbuild"
787+ _p (" build %s: phony %s" , prj .name , postbuildTarget )
788+ else
789+ _p (" build %s: phony %s" , prj .name , targetPath )
790+ end
724791 end
725792
726793 _p (" " )
0 commit comments