diff --git a/test/issue2377-dynLib-dep-extra-files.script.d b/test/issue2377-dynLib-dep-extra-files.script.d new file mode 100644 index 0000000..4eb90ec --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files.script.d @@ -0,0 +1,135 @@ +/+ dub.sdl: +name "issue2377_dynlib_dep_extra_files" ++/ + +module issue2377_dynlib_dep_extra_files.script; + +import std.exception : enforce; +import std.file; +import std.path; + +version (DigitalMars) version (Windows) version = DMD_Windows; +version (DMD_Windows) { + void main() { + import std.stdio; + writeln("WARNING: skipping test '" ~ __FILE_FULL_PATH__.baseName ~ "' with DMD on Windows."); + } +} else: + +void main() { + import std.process : environment; + + version (Windows) enum exeExt = ".exe"; + else enum exeExt = ""; + const dub = environment.get("DUB", buildPath(__FILE_FULL_PATH__.dirName.dirName, "bin", "dub"~exeExt)); + + enum testDir = buildPath(__FILE_FULL_PATH__.dirName, "issue2377-dynLib-dep-extra-files"); + + // 1. `parent` as root package (depending on dynamic/static dep1, which depends on dynamic/static dep2) + chdir(buildPath(testDir, "parent")); + if (exists("output")) + rmdirRecurse("output"); + + // 1.1 dynlib config + run(dub ~ " build -c dynlib"); + chdir("output/dynlib"); + assertDynLibExists("parent"); + assertDynLibExists("dep1"); + assertDynLibExists("dep2"); + version (Windows) { + assertFileExists("parent.pdb"); + assertFileExists("parent.lib"); + assertFileExists("parent.exp"); + assertFileExists("dep1.pdb"); + assertFileExists("dep1.lib"); + assertFileExists("dep1.exp"); + assertFileExists("dep2.pdb"); + assertFileExists("dep2.lib"); + assertFileExists("dep2.exp"); + } + chdir("../.."); + + // 1.2 dynlib_static config + run(dub ~ " build -c dynlib_static"); + chdir("output/dynlib_static"); + assertDynLibExists("parent"); + version (Windows) { + assertFileExists("parent.pdb"); + assertFileExists("parent.lib"); + assertFileExists("parent.exp"); + } + enforce(!canFindFiles("*dep*"), "unexpected dependency files in statically linked dynlib output dir"); + chdir("../.."); + + // 1.3 exe_static config + run(dub ~ " build -c exe_static"); + chdir("output/exe_static"); + version (Windows) run(`.\parent.exe`); + else run("./parent"); + version (Windows) { + assertFileExists("parent.pdb"); + enforce(!exists("parent.lib"), "unexpected import .lib for executable"); + enforce(!exists("parent.exp"), "unexpected .exp file for executable"); + } + enforce(!canFindFiles("*dep*"), "unexpected dependency files in statically linked executable output dir"); + chdir("../.."); + + // 1.4 exe_dynamic config + run(dub ~ " build -c exe_dynamic"); + chdir("output/exe_dynamic"); + version (Windows) run(`.\parent.exe`); + else run(`LD_LIBRARY_PATH=".:${LD_LIBRARY_PATH:-}" ./parent`); + assertDynLibExists("dep1"); + assertDynLibExists("dep2"); + version (Windows) { + assertFileExists("dep1.pdb"); + assertFileExists("dep2.pdb"); + enforce(!canFindFiles("*.lib"), "unexpected import libs in dynamically linked executable output dir"); + enforce(!canFindFiles("*.exp"), "unexpected .exp files in dynamically linked executable output dir"); + } + chdir("../.."); + + // 2. `framework` as root package (targetType `none`) + chdir(buildPath(testDir, "framework")); + run(dub ~ " build"); + assertDynLibExists("dep1"); + assertDynLibExists("dep2"); + version (Windows) { + assertFileExists("dep1.pdb"); + assertFileExists("dep1.lib"); + assertFileExists("dep1.exp"); + assertFileExists("dep2.pdb"); + assertFileExists("dep2.lib"); + assertFileExists("dep2.exp"); + } +} + +void run(string command) { + import std.process; + const status = spawnShell(command).wait(); + enforce(status == 0, "command '" ~ command ~ "' failed"); +} + +void assertFileExists(string path) { + enforce(exists(path), "expected file '" ~ path ~ "' not found"); +} + +void assertDynLibExists(string name) { + version (Windows) { + enum prefix = ""; + enum suffix = ".dll"; + } else version (OSX) { + enum prefix = "lib"; + enum suffix = ".dylib"; + } else { + enum prefix = "lib"; + enum suffix = ".so"; + } + + assertFileExists(prefix ~ name ~ suffix); +} + +bool canFindFiles(string pattern) { + auto entries = dirEntries(".", pattern, SpanMode.shallow); + return !entries.empty(); +} diff --git a/test/issue2377-dynLib-dep-extra-files/.gitignore b/test/issue2377-dynLib-dep-extra-files/.gitignore new file mode 100644 index 0000000..5d658ec --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/.gitignore @@ -0,0 +1 @@ +/parent/output/ diff --git a/test/issue2377-dynLib-dep-extra-files/.no_build b/test/issue2377-dynLib-dep-extra-files/.no_build new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/.no_build diff --git a/test/issue2377-dynLib-dep-extra-files/dep1/dub.sdl b/test/issue2377-dynLib-dep-extra-files/dep1/dub.sdl new file mode 100644 index 0000000..19d1989 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/dep1/dub.sdl @@ -0,0 +1,14 @@ +name "dep1" +dependency "dep2" path="../dep2" + +configuration "library" { + targetType "staticLibrary" + targetPath "output/library" + subConfiguration "dep2" "library" +} + +configuration "dynlib" { + targetType "dynamicLibrary" + targetPath "output/dynlib" + subConfiguration "dep2" "dynlib" +} diff --git a/test/issue2377-dynLib-dep-extra-files/dep1/source/dep1.d b/test/issue2377-dynLib-dep-extra-files/dep1/source/dep1.d new file mode 100644 index 0000000..80e536c --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/dep1/source/dep1.d @@ -0,0 +1,6 @@ +module dep1; + +void foo1() { + import dep2; + foo2(); +} diff --git a/test/issue2377-dynLib-dep-extra-files/dep2/dub.sdl b/test/issue2377-dynLib-dep-extra-files/dep2/dub.sdl new file mode 100644 index 0000000..e323ee7 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/dep2/dub.sdl @@ -0,0 +1,11 @@ +name "dep2" + +configuration "library" { + targetType "staticLibrary" + targetPath "output/library" +} + +configuration "dynlib" { + targetType "dynamicLibrary" + targetPath "output/dynlib" +} diff --git a/test/issue2377-dynLib-dep-extra-files/dep2/source/dep2.d b/test/issue2377-dynLib-dep-extra-files/dep2/source/dep2.d new file mode 100644 index 0000000..c5e04d6 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/dep2/source/dep2.d @@ -0,0 +1,3 @@ +module dep2; + +void foo2() {} diff --git a/test/issue2377-dynLib-dep-extra-files/framework/dub.sdl b/test/issue2377-dynLib-dep-extra-files/framework/dub.sdl new file mode 100644 index 0000000..dfbb79b --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/framework/dub.sdl @@ -0,0 +1,5 @@ +name "framework" +targetType "none" + +dependency "dep1" path="../dep1" +subConfiguration "dep1" "dynlib" diff --git a/test/issue2377-dynLib-dep-extra-files/parent/dub.sdl b/test/issue2377-dynLib-dep-extra-files/parent/dub.sdl new file mode 100644 index 0000000..dd43bf6 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/parent/dub.sdl @@ -0,0 +1,28 @@ +name "parent" +dependency "dep1" path="../dep1" + +configuration "dynlib" { + targetType "dynamicLibrary" + targetPath "output/dynlib" + subConfiguration "dep1" "dynlib" +} + +configuration "dynlib_static" { + targetType "dynamicLibrary" + targetPath "output/dynlib_static" + subConfiguration "dep1" "library" +} + +configuration "exe_static" { + targetType "executable" + targetPath "output/exe_static" + subConfiguration "dep1" "library" +} + +configuration "exe_dynamic" { + targetType "executable" + targetPath "output/exe_dynamic" + subConfiguration "dep1" "dynlib" + dflags "-link-defaultlib-shared" platform="ldc" + dflags "-defaultlib=libphobos2.so" platform="linux-dmd" +} diff --git a/test/issue2377-dynLib-dep-extra-files/parent/source/app.d b/test/issue2377-dynLib-dep-extra-files/parent/source/app.d new file mode 100644 index 0000000..d7fa2b1 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/parent/source/app.d @@ -0,0 +1,11 @@ +module app; + +// Add a dummy export to enforce creation of import .lib and .exp file for the (Windows) executable. +// They shouldn't be copied to the output dir though. +export void dummy() {} + +void main() { + import parent; + parent_bar(); + dummy(); +} diff --git a/test/issue2377-dynLib-dep-extra-files/parent/source/parent.d b/test/issue2377-dynLib-dep-extra-files/parent/source/parent.d new file mode 100644 index 0000000..3c35529 --- /dev/null +++ b/test/issue2377-dynLib-dep-extra-files/parent/source/parent.d @@ -0,0 +1,6 @@ +module parent; + +void parent_bar() { + import dep1; + foo1(); +}