Skip to content

Commit 1bc1de2

Browse files
committed
Fix prepost build step on Windows
1 parent 56552aa commit 1bc1de2

File tree

6 files changed

+272
-63
lines changed

6 files changed

+272
-63
lines changed

modules/ninja/ninja_cpp.lua

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ function m.buildFiles(cfg)
666666

667667
local prebuildTarget = m.buildPreBuildEvents(cfg)
668668
cfg._hasPrebuild = (prebuildTarget ~= nil)
669+
cfg._prebuildTarget = prebuildTarget
669670

670671
if not cfg.project._ninja_output_tracking then
671672
cfg.project._ninja_output_tracking = {}
@@ -987,13 +988,20 @@ function m.checkCustomRuleFile(cfg, node, filecfg, outputTracking)
987988
end
988989
end
989990

990-
if cfg._dependsOnTarget and not cfg._hasPrebuild then
991+
if cfg._dependsOnTarget then
991992
if deps == "" then
992993
deps = " |"
993994
end
994995
deps = deps .. " " .. cfg._dependsOnTarget
995996
end
996997

998+
if cfg._prebuildTarget then
999+
if deps == "" then
1000+
deps = " |"
1001+
end
1002+
deps = deps .. " " .. cfg._prebuildTarget
1003+
end
1004+
9971005
local commands = {}
9981006
if buildcommands then
9991007
local translatedCommands = os.translateCommandsAndPaths(buildcommands, cfg.project.basedir, cfg.project.location)
@@ -1065,14 +1073,22 @@ function m.buildCustomFile(cfg, node, filecfg, outputTracking)
10651073
end
10661074
end
10671075

1068-
-- Add dependson target if it exists and no prebuild (prebuild already has the dep)
1069-
if cfg._dependsOnTarget and not cfg._hasPrebuild then
1076+
-- Add dependson target if it exists
1077+
if cfg._dependsOnTarget then
10701078
if deps == "" then
10711079
deps = " |"
10721080
end
10731081
deps = deps .. " " .. cfg._dependsOnTarget
10741082
end
10751083

1084+
-- Add prebuild target if it exists
1085+
if cfg._prebuildTarget then
1086+
if deps == "" then
1087+
deps = " |"
1088+
end
1089+
deps = deps .. " " .. cfg._prebuildTarget
1090+
end
1091+
10761092
local commands = os.translateCommandsAndPaths(filecfg.buildcommands, cfg.project.basedir, cfg.project.location)
10771093
local cmdStr = table.concat(commands, " && ")
10781094

@@ -1165,9 +1181,12 @@ function m.linkTarget(cfg)
11651181
end
11661182
end
11671183

1184+
local postbuildStamp = nil
11681185
if hasPostBuild then
1169-
m.buildPostBuildEvents(cfg, targetPath)
1186+
postbuildStamp = m.buildPostBuildEvents(cfg, targetPath)
11701187
end
1188+
1189+
cfg._postbuildStamp = postbuildStamp
11711190
end
11721191

11731192
function m.buildPreBuildEvents(cfg)
@@ -1178,30 +1197,33 @@ function m.buildPreBuildEvents(cfg)
11781197
return nil
11791198
end
11801199

1181-
local targetPath = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.buildtarget.name
1182-
local prebuildTarget = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".prebuild"
1200+
local stampFile = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".prebuild.stamp"
1201+
1202+
-- Determine touch command based on target system, not host system
1203+
local shell = _OPTIONS.shell or iif(cfg.system == p.WINDOWS, "cmd", "posix")
1204+
local touchCmd = iif(shell == "cmd", "type nul > \"" .. stampFile .. "\"", "touch \"" .. stampFile .. "\"")
11831205

11841206
local implicitDeps = ""
11851207
if cfg._dependsOnTarget then
11861208
implicitDeps = " | " .. cfg._dependsOnTarget
11871209
end
11881210

11891211
if hasMessage and not hasCommands then
1190-
_p("build %s: prebuildmessage%s", prebuildTarget, implicitDeps)
1191-
_p(" prebuildmessage = \"%s\"", cfg.prebuildmessage)
1212+
_p("build %s: prebuildmessage%s", stampFile, implicitDeps)
1213+
_p(" prebuildmessage = \"%s && %s\"", cfg.prebuildmessage, touchCmd)
11921214
elseif hasCommands and not hasMessage then
11931215
local commands = os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.project.basedir, cfg.project.location)
1194-
local cmdStr = table.concat(commands, " && ")
1195-
_p("build %s: prebuild%s", prebuildTarget, implicitDeps)
1216+
local cmdStr = table.concat(commands, " && ") .. " && " .. touchCmd
1217+
_p("build %s: prebuild%s", stampFile, implicitDeps)
11961218
_p(" prebuildcommands = %s", cmdStr)
11971219
else
11981220
local commands = os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.project.basedir, cfg.project.location)
1199-
local cmdStr = "echo \"" .. cfg.prebuildmessage .. "\" && " .. table.concat(commands, " && ")
1200-
_p("build %s: prebuild%s", prebuildTarget, implicitDeps)
1221+
local cmdStr = "echo \"" .. cfg.prebuildmessage .. "\" && " .. table.concat(commands, " && ") .. " && " .. touchCmd
1222+
_p("build %s: prebuild%s", stampFile, implicitDeps)
12011223
_p(" prebuildcommands = %s", cmdStr)
12021224
end
12031225

1204-
return prebuildTarget
1226+
return stampFile
12051227
end
12061228

12071229
function m.buildPreLinkEvents(cfg, objectFiles)
@@ -1212,30 +1234,33 @@ function m.buildPreLinkEvents(cfg, objectFiles)
12121234
return nil
12131235
end
12141236

1215-
local targetPath = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.buildtarget.name
1216-
local prelinkTarget = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".prelinkevents"
1237+
local stampFile = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".prelink.stamp"
1238+
1239+
-- Determine touch command based on target system, not host system
1240+
local shell = _OPTIONS.shell or iif(cfg.system == p.WINDOWS, "cmd", "posix")
1241+
local touchCmd = iif(shell == "cmd", "type nul > \"" .. stampFile .. "\"", "touch \"" .. stampFile .. "\"")
12171242

12181243
local objDeps = ""
12191244
if objectFiles and #objectFiles > 0 then
12201245
objDeps = " " .. table.concat(objectFiles, " ")
12211246
end
12221247

12231248
if hasMessage and not hasCommands then
1224-
_p("build %s: prelinkmessage%s", prelinkTarget, objDeps)
1225-
_p(" prelinkmessage = \"%s\"", cfg.prelinkmessage)
1249+
_p("build %s: prelinkmessage%s", stampFile, objDeps)
1250+
_p(" prelinkmessage = \"%s && %s\"", cfg.prelinkmessage, touchCmd)
12261251
elseif hasCommands and not hasMessage then
12271252
local commands = os.translateCommandsAndPaths(cfg.prelinkcommands, cfg.project.basedir, cfg.project.location)
1228-
local cmdStr = table.concat(commands, " && ")
1229-
_p("build %s: prelink%s", prelinkTarget, objDeps)
1253+
local cmdStr = table.concat(commands, " && ") .. " && " .. touchCmd
1254+
_p("build %s: prelink%s", stampFile, objDeps)
12301255
_p(" prelinkcommands = %s", cmdStr)
12311256
else
12321257
local commands = os.translateCommandsAndPaths(cfg.prelinkcommands, cfg.project.basedir, cfg.project.location)
1233-
local cmdStr = "echo \"" .. cfg.prelinkmessage .. "\" && " .. table.concat(commands, " && ")
1234-
_p("build %s: prelink%s", prelinkTarget, objDeps)
1258+
local cmdStr = "echo \"" .. cfg.prelinkmessage .. "\" && " .. table.concat(commands, " && ") .. " && " .. touchCmd
1259+
_p("build %s: prelink%s", stampFile, objDeps)
12351260
_p(" prelinkcommands = %s", cmdStr)
12361261
end
12371262

1238-
return prelinkTarget
1263+
return stampFile
12391264
end
12401265

12411266
function m.buildPostBuildEvents(cfg, targetPath)
@@ -1246,22 +1271,28 @@ function m.buildPostBuildEvents(cfg, targetPath)
12461271
return
12471272
end
12481273

1249-
local postbuildPhony = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".postbuild"
1274+
local stampFile = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".postbuild.stamp"
1275+
1276+
-- Determine touch command based on target system, not host system
1277+
local shell = _OPTIONS.shell or iif(cfg.system == p.WINDOWS, "cmd", "posix")
1278+
local touchCmd = iif(shell == "cmd", "type nul > \"" .. stampFile .. "\"", "touch \"" .. stampFile .. "\"")
12501279

12511280
if hasMessage and not hasCommands then
1252-
_p("build %s: postbuildmessage | %s", postbuildPhony, targetPath)
1253-
_p(" postbuildmessage = \"%s\"", cfg.postbuildmessage)
1281+
_p("build %s: postbuildmessage | %s", stampFile, targetPath)
1282+
_p(" postbuildmessage = \"%s && %s\"", cfg.postbuildmessage, touchCmd)
12541283
elseif hasCommands and not hasMessage then
12551284
local commands = os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.project.basedir, cfg.project.location)
1256-
local cmdStr = table.concat(commands, " && ")
1257-
_p("build %s: postbuild | %s", postbuildPhony, targetPath)
1285+
local cmdStr = table.concat(commands, " && ") .. " && " .. touchCmd
1286+
_p("build %s: postbuild | %s", stampFile, targetPath)
12581287
_p(" postbuildcommands = %s", cmdStr)
12591288
else
12601289
local commands = os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.project.basedir, cfg.project.location)
1261-
local cmdStr = "echo \"" .. cfg.postbuildmessage .. "\" && " .. table.concat(commands, " && ")
1262-
_p("build %s: postbuild | %s", postbuildPhony, targetPath)
1290+
local cmdStr = "echo \"" .. cfg.postbuildmessage .. "\" && " .. table.concat(commands, " && ") .. " && " .. touchCmd
1291+
_p("build %s: postbuild | %s", stampFile, targetPath)
12631292
_p(" postbuildcommands = %s", cmdStr)
12641293
end
1294+
1295+
return stampFile
12651296
end
12661297

12671298
function m.buildTargets(prj)
@@ -1272,10 +1303,8 @@ function m.buildTargets(prj)
12721303
local targetPath = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.buildtarget.name
12731304
local cfgName = ninja.key(cfg)
12741305

1275-
local hasPostBuild = #cfg.postbuildcommands > 0 or cfg.postbuildmessage
1276-
if hasPostBuild then
1277-
local postbuildTarget = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. cfg.project.name .. ".postbuild"
1278-
_p("build %s: phony %s", cfgName, postbuildTarget)
1306+
if cfg._postbuildStamp then
1307+
_p("build %s: phony %s", cfgName, cfg._postbuildStamp)
12791308
else
12801309
_p("build %s: phony %s", cfgName, targetPath)
12811310
end
@@ -1290,13 +1319,10 @@ function m.projectPhonies(prj)
12901319

12911320
local firstCfg = project.getfirstconfig(prj)
12921321
if firstCfg then
1293-
local targetPath = path.getrelative(firstCfg.workspace.location, firstCfg.buildtarget.directory) .. "/" .. firstCfg.buildtarget.name
1294-
1295-
local hasPostBuild = #firstCfg.postbuildcommands > 0 or firstCfg.postbuildmessage
1296-
if hasPostBuild then
1297-
local postbuildTarget = path.getrelative(firstCfg.workspace.location, firstCfg.buildtarget.directory) .. "/" .. firstCfg.project.name .. ".postbuild"
1298-
_p("build %s: phony %s", prj.name, postbuildTarget)
1322+
if firstCfg._postbuildStamp then
1323+
_p("build %s: phony %s", prj.name, firstCfg._postbuildStamp)
12991324
else
1325+
local targetPath = path.getrelative(firstCfg.workspace.location, firstCfg.buildtarget.directory) .. "/" .. firstCfg.buildtarget.name
13001326
_p("build %s: phony %s", prj.name, targetPath)
13011327
end
13021328
end

modules/ninja/tests/_tests.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ return {
1818
"test_ninja_implib.lua",
1919
"test_ninja_pch.lua",
2020
"test_ninja_perfile_config.lua",
21+
"test_ninja_postbuild_stamp.lua",
2122
"test_ninja_project.lua",
2223
"test_ninja_tokens.lua",
2324
"test_ninja_workspace.lua",

modules/ninja/tests/test_ninja_build_commands.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,6 @@ function suite.prebuildCommands_withQuotedPaths_onWindows()
192192
cpp.buildPreBuildEvents(cfg)
193193

194194
-- The command should have quotes around paths
195-
test.string_contains(premake.captured(), 'copy /B /Y')
195+
local captured = premake.captured()
196+
test.istrue(captured:find('copy /B /Y', 1, true) ~= nil)
196197
end

0 commit comments

Comments
 (0)