Skip to content

Commit bdbdeff

Browse files
committed
Ensure outputs for lib and exp files are emitted for dlls on Windows
1 parent daac3ac commit bdbdeff

File tree

2 files changed

+179
-2
lines changed

2 files changed

+179
-2
lines changed

modules/ninja/ninja_cpp.lua

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1162,8 +1162,33 @@ function m.linkTarget(cfg)
11621162
end
11631163

11641164
local hasPostBuild = #cfg.postbuildcommands > 0 or cfg.postbuildmessage
1165+
1166+
local implicitoutputs = {}
1167+
1168+
-- If this target is a shared library on Windows with NoImportLib not set, add an implicit output
1169+
-- for the .lib file
1170+
-- If this is on windows and building a shared library, emit a exp file as an implicit output
1171+
if cfg.system == p.WINDOWS and cfg.kind == p.SHAREDLIB then
1172+
local expFileName = cfg.buildtarget.name:gsub("%..-$", "") .. ".exp"
1173+
if expFileName then
1174+
local expFilePath = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. expFileName
1175+
table.insert(implicitoutputs, expFilePath)
1176+
end
1177+
1178+
if not cfg.flags.NoImportLib then
1179+
local importLibName = cfg.buildtarget.name:gsub("%..-$", "") .. ".lib"
1180+
if importLibName then
1181+
local importLibPath = path.getrelative(cfg.workspace.location, cfg.buildtarget.directory) .. "/" .. importLibName
1182+
table.insert(implicitoutputs, importLibPath)
1183+
end
1184+
end
1185+
end
11651186

1166-
_p("build %s: %s %s%s", targetPath, rule, table.concat(cfg._objectFiles, " "), implicitDeps)
1187+
if #implicitoutputs > 0 then
1188+
_p("build %s | %s: %s %s%s", targetPath, table.concat(implicitoutputs, " "), rule, table.concat(cfg._objectFiles, " "), implicitDeps)
1189+
else
1190+
_p("build %s: %s %s%s", targetPath, rule, table.concat(cfg._objectFiles, " "), implicitDeps)
1191+
end
11671192

11681193
if cfg.kind ~= p.STATICLIB then
11691194
_p(" ldflags = $ldflags_%s", ninja.key(cfg))

modules/ninja/tests/test_ninja_project.lua

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ end
143143
-- Get the actual project name for the test
144144
local targetName = cfg.buildtarget.name
145145

146-
-- Verify output contains the actual target name for link, not .link suffix
147146
test.capture(string.format([[
148147
build bin/Debug/%s: link obj/Debug/main.o
149148
ldflags = $ldflags_%s_Debug
@@ -184,3 +183,156 @@ build bin/Debug/%s: link obj/Debug/main.o
184183
ldflags = $ldflags_%s_Debug
185184
]], targetName, prj.name))
186185
end
186+
187+
188+
--
189+
-- Test that shared library on Windows without NoImportLib flag works correctly with GCC
190+
--
191+
function suite.sharedLibWindowsGCC()
192+
local wks = test.createWorkspace()
193+
configurations { "Debug" }
194+
toolset "gcc"
195+
_OS = "windows"
196+
197+
local prj = test.createProject(wks)
198+
kind "SharedLib"
199+
language "C++"
200+
files { "main.cpp" }
201+
202+
local cfg = test.getconfig(prj, "Debug")
203+
204+
-- Set up object files list (normally done by buildFiles)
205+
cfg._objectFiles = { "obj/Debug/main.o" }
206+
207+
-- Call linkTarget and check output
208+
ninja.cpp.linkTarget(cfg)
209+
210+
test.capture [[
211+
build bin/Debug/MyProject2.dll | bin/Debug/MyProject2.exp bin/Debug/MyProject2.lib: link obj/Debug/main.o
212+
ldflags = $ldflags_MyProject2_Debug
213+
]]
214+
end
215+
216+
217+
--
218+
-- Test that shared library on Windows without NoImportLib flag works correctly with MSVC
219+
--
220+
function suite.sharedLibWindowsMSVC()
221+
local wks = test.createWorkspace()
222+
configurations { "Debug" }
223+
toolset "msc"
224+
_OS = "windows"
225+
226+
local prj = test.createProject(wks)
227+
kind "SharedLib"
228+
language "C++"
229+
files { "main.cpp" }
230+
231+
local cfg = test.getconfig(prj, "Debug")
232+
233+
-- Set up object files list (normally done by buildFiles)
234+
cfg._objectFiles = { "obj/Debug/main.obj" }
235+
236+
-- Call linkTarget and check output
237+
ninja.cpp.linkTarget(cfg)
238+
239+
test.capture [[
240+
build bin/Debug/MyProject2.dll | bin/Debug/MyProject2.exp bin/Debug/MyProject2.lib: link obj/Debug/main.obj
241+
ldflags = $ldflags_MyProject2_Debug
242+
]]
243+
end
244+
245+
246+
--
247+
-- Test that shared library on Windows with NoImportLib flag works correctly with GCC
248+
--
249+
250+
function suite.sharedLibWindowsGCCNoImportLib()
251+
local wks = test.createWorkspace()
252+
configurations { "Debug" }
253+
toolset "gcc"
254+
_OS = "windows"
255+
256+
local prj = test.createProject(wks)
257+
kind "SharedLib"
258+
language "C++"
259+
files { "main.cpp" }
260+
flags { "NoImportLib" }
261+
262+
local cfg = test.getconfig(prj, "Debug")
263+
264+
-- Set up object files list (normally done by buildFiles)
265+
cfg._objectFiles = { "obj/Debug/main.o" }
266+
267+
-- Call linkTarget and check output
268+
ninja.cpp.linkTarget(cfg)
269+
270+
test.capture [[
271+
build bin/Debug/MyProject2.dll | bin/Debug/MyProject2.exp: link obj/Debug/main.o
272+
ldflags = $ldflags_MyProject2_Debug
273+
]]
274+
275+
end
276+
277+
278+
--
279+
-- Test that shared library on Windows with NoImportLib flag works correctly with MSVC
280+
--
281+
282+
function suite.sharedLibWindowsMSVCNoImportLib()
283+
local wks = test.createWorkspace()
284+
configurations { "Debug" }
285+
toolset "msc"
286+
_OS = "windows"
287+
288+
local prj = test.createProject(wks)
289+
kind "SharedLib"
290+
language "C++"
291+
files { "main.cpp" }
292+
flags { "NoImportLib" }
293+
294+
local cfg = test.getconfig(prj, "Debug")
295+
296+
-- Set up object files list (normally done by buildFiles)
297+
cfg._objectFiles = { "obj/Debug/main.obj" }
298+
299+
-- Call linkTarget and check output
300+
ninja.cpp.linkTarget(cfg)
301+
302+
test.capture [[
303+
build bin/Debug/MyProject2.dll | bin/Debug/MyProject2.exp: link obj/Debug/main.obj
304+
ldflags = $ldflags_MyProject2_Debug
305+
]]
306+
307+
end
308+
309+
310+
--
311+
-- Test the shared library not on Windows does not create exp or lib files
312+
--
313+
314+
function suite.sharedLibNotWindows()
315+
local wks = test.createWorkspace()
316+
configurations { "Debug" }
317+
toolset "gcc"
318+
_OS = "linux"
319+
320+
local prj = test.createProject(wks)
321+
kind "SharedLib"
322+
language "C++"
323+
files { "main.cpp" }
324+
325+
local cfg = test.getconfig(prj, "Debug")
326+
327+
-- Set up object files list (normally done by buildFiles)
328+
cfg._objectFiles = { "obj/Debug/main.o" }
329+
330+
-- Call linkTarget and check output
331+
ninja.cpp.linkTarget(cfg)
332+
333+
test.capture [[
334+
build bin/Debug/libMyProject2.so: link obj/Debug/main.o
335+
ldflags = $ldflags_MyProject2_Debug
336+
]]
337+
338+
end

0 commit comments

Comments
 (0)