Skip to content

Commit

Permalink
LDC: Apply dflags affecting symbol visibility to all deps
Browse files Browse the repository at this point in the history
Example scenarios on Windows:

* If an .exe is linked against druntime/Phobos DLLs (e.g., to enable
  loading other D DLLs, all sharing central druntime/Phobos), all
  static-lib dub dependencies need to be compiled with
  `-dllimport=defaultLibsOnly` too [the default with
  `-link-defaultlib-shared`].
* To make large DLLs with few selective `export`ed symbols work after #2412,
  the implicit flags need to be overridden - for the DLL itself and
  all its static-lib dependencies. This can currently only be
  accomplished by setting the DFLAGS environment variable. This PR
  enables overriding these `dflags` either in the DLL root project/
  config directly, or in some dependency shared by multiple DLLs/
  executables.
  E.g., at Symmetry, we have an .exe with lots of plugin DLLs. All
  plugins and the .exe have a shared dependency, so adding
  `dflags "-fvisibility=hidden" "-dllimport=defaultLibsOnly" platform="windows-ldc"`
  once in the dub.sdl of that shared dependency suffices to compile
  *everything* with those required flags.
  • Loading branch information
kinke committed Aug 19, 2023
1 parent b58ba5c commit 9f06df5
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions source/dub/generators/generator.d
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,39 @@ class ProjectGenerator
configureDependents(*roottarget, targets);
visited.clear();

// LDC: need to pass down dflags affecting symbol visibility, especially on Windows
if (genSettings.platform.compiler == "ldc")
{
const isWindows = genSettings.platform.isWindows();
bool passDownDFlag(string flag)
{
if (flag.startsWith("--"))
flag = flag[1 .. $];
return flag.startsWith("-fvisibility=") || (isWindows &&
(flag.startsWith("-link-defaultlib-shared") ||
flag.startsWith("-dllimport=")));
}

// all dflags from dependencies have already been added to the root project
auto rootDFlagsToPassDown = roottarget.buildSettings.dflags.filter!passDownDFlag.array;

if (rootDFlagsToPassDown.length)
{
foreach (name, ref ti; targets)
{
if (&ti != roottarget)
{
import std.range : chain;
ti.buildSettings.dflags = ti.buildSettings.dflags
// remove all existing visibility flags first to reduce duplicates
.filter!(f => !passDownDFlag(f))
.chain(rootDFlagsToPassDown)
.array;
}
}
}
}

// 4. As an extension to configureDependents we need to copy any injectSourceFiles
// in our dependencies (ignoring targetType)
void configureDependentsFinalImages(ref TargetInfo ti, TargetInfo[string] targets, ref TargetInfo finalBinaryTarget, size_t level = 0)
Expand Down

0 comments on commit 9f06df5

Please sign in to comment.