Skip to content

Commit

Permalink
Added a "subConfigurations" field and implemented proper configuratio…
Browse files Browse the repository at this point in the history
…n selection for dependencies.
  • Loading branch information
s-ludwig committed Mar 8, 2013
1 parent 0662e82 commit f7c9da0
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 34 deletions.
3 changes: 2 additions & 1 deletion source/dub/generators/visuald.d
Expand Up @@ -207,7 +207,8 @@ EndGlobal");
}

version(VISUALD_SEPERATE_PROJECT_FILES){
auto files = pack.getBuildSettings(settings.platform, m_app.getPackageConfig(pack, settings.platform, settings.config));
auto configs = m_app.getPackageConfigs(settings.platform, settings.config);
auto files = pack.getBuildSettings(settings.platform, configs[pack.name]);

files.sourceFiles ~= pack.packageInfoFile.toNativeString();

Expand Down
34 changes: 27 additions & 7 deletions source/dub/package_.d
Expand Up @@ -161,7 +161,7 @@ class Package {
}

/// Returns all BuildSettings for the given platform and config.
BuildSettings getBuildSettings(BuildPlatform platform, string config)
BuildSettings getBuildSettings(in BuildPlatform platform, string config)
const {
logDebug("Using config %s for %s", config, this.name);
foreach(ref conf; m_info.configurations){
Expand All @@ -175,8 +175,23 @@ class Package {
assert(false, "Unknown configuration for "~m_info.name~": "~config);
}

string getSubConfiguration(string config, in Package dependency, in BuildPlatform platform)
const {
bool found = false;
foreach(ref c; m_info.configurations){
if( c.name == config ){
if( auto pv = dependency.name in c.buildSettings.subConfigurations ) return *pv;
found = true;
break;
}
}
assert(found, "Invliad configuration "~config~" for "~this.name);
if( auto pv = dependency.name in m_info.buildSettings.subConfigurations ) return *pv;
return null;
}

/// Returns the default configuration to build for the given platform
string getDefaultConfiguration(BuildPlatform platform, bool is_main_package = false)
string getDefaultConfiguration(in BuildPlatform platform, bool is_main_package = false)
const {
foreach(ref conf; m_info.configurations){
if( !conf.matchesPlatform(platform) ) continue;
Expand Down Expand Up @@ -348,7 +363,7 @@ struct ConfigurationInfo {
return ret;
}

bool matchesPlatform(BuildPlatform platform)
bool matchesPlatform(in BuildPlatform platform)
const {
if( platforms.empty ) return true;
foreach(p; platforms)
Expand All @@ -362,6 +377,7 @@ struct BuildSettingsTemplate {
TargetType targetType = TargetType.autodetect;
string targetPath;
string targetName;
string[string] subConfigurations;
string[][string] dflags;
string[][string] lflags;
string[][string] libs;
Expand Down Expand Up @@ -399,6 +415,10 @@ struct BuildSettingsTemplate {
enforce(suffix.empty, "targetName does not support platform customization.");
this.targetName = value.get!string;
break;
case "subConfigurations":
enforce(suffix.empty, "subConfigurations does not support platform customization.");
this.subConfigurations = deserializeJson!(string[string])(value);
break;
case "dflags": this.dflags[suffix] = deserializeJson!(string[])(value); break;
case "lflags": this.lflags[suffix] = deserializeJson!(string[])(value); break;
case "libs": this.libs[suffix] = deserializeJson!(string[])(value); break;
Expand Down Expand Up @@ -442,7 +462,7 @@ struct BuildSettingsTemplate {
return ret;
}

void getPlatformSettings(ref BuildSettings dst, BuildPlatform platform, Path base_path)
void getPlatformSettings(ref BuildSettings dst, in BuildPlatform platform, Path base_path)
const {
dst.targetType = this.targetType;
dst.targetPath = this.targetPath;
Expand Down Expand Up @@ -483,7 +503,7 @@ struct BuildSettingsTemplate {
getPlatformSetting!("postBuildCommands", "addPostBuildCommands")(dst, platform);
}

void getPlatformSetting(string name, string addname)(ref BuildSettings dst, BuildPlatform platform)
void getPlatformSetting(string name, string addname)(ref BuildSettings dst, in BuildPlatform platform)
const {
foreach(suffix, values; __traits(getMember, this, name)){
if( matchesPlatform(suffix, platform) )
Expand All @@ -493,7 +513,7 @@ struct BuildSettingsTemplate {
}


private bool matchesPlatform(string suffix, BuildPlatform platform)
private bool matchesPlatform(string suffix, in BuildPlatform platform)
{
if( suffix.length == 0 ) return true;
// TODO: optimize
Expand All @@ -514,7 +534,7 @@ private bool matchesPlatform(string suffix, BuildPlatform platform)
/// "-dmd"
/// "-arm"
///
private int delegate(scope int delegate(ref string)) getPlatformSuffixIterator(BuildPlatform platform)
private int delegate(scope int delegate(ref string)) getPlatformSuffixIterator(in BuildPlatform platform)
{
int iterator(scope int delegate(ref string s) del)
{
Expand Down
10 changes: 7 additions & 3 deletions source/dub/packagemanager.d
Expand Up @@ -357,7 +357,7 @@ class PackageManager {
logInfo("Uninstalled package: '"~pack.name~"'");
}

void addLocalPackage(in Path path, in Version ver, LocalPackageType type)
Package addLocalPackage(in Path path, in Version ver, LocalPackageType type)
{
Package[]* packs = getLocalPackageList(type);
auto info = jsonFromFile(path ~ PackageJsonFilename, false);
Expand All @@ -369,13 +369,17 @@ class PackageManager {
foreach( p; *packs ){
if( p.path == path ){
enforce(p.ver == ver, "Adding local twice with different versions is not allowed.");
return;
return p;
}
}

*packs ~= new Package(info, InstallLocation.local, path);
auto pack = new Package(info, InstallLocation.local, path);

*packs ~= pack;

writeLocalPackageList(type);

return pack;
}

void removeLocalPackage(in Path path, LocalPackageType type)
Expand Down
79 changes: 56 additions & 23 deletions source/dub/project.d
Expand Up @@ -44,6 +44,7 @@ class Project {
Package m_main;
//Package[string] m_packages;
Package[] m_dependencies;
Package[][Package] m_dependees;
}

this(PackageManager package_manager, Path project_path)
Expand Down Expand Up @@ -98,13 +99,10 @@ class Project {
if( ret ) return;
}

foreach(d; p.dependencies.byKey)
foreach(dp; m_dependencies)
if( dp.name == d ){
perform_rec(dp);
if( ret ) return;
break;
}
foreach(d; p.dependencies.byKey){
perform_rec(getDependency(d));
if( ret ) return;
}

if( children_first ){
ret = del(p);
Expand All @@ -117,6 +115,14 @@ class Project {
return &iterator;
}

inout(Package) getDependency(string name)
inout {
foreach(dp; m_dependencies)
if( dp.name == name )
return dp;
assert(false, "Unknown dependency");
}

string getDefaultConfiguration(BuildPlatform platform)
const {
return m_main.getDefaultConfiguration(platform, true);
Expand Down Expand Up @@ -161,21 +167,23 @@ class Project {
{
logDebug("Collecting dependencies for %s", pack.name);
foreach( name, vspec; pack.dependencies ){
Package p;
if( !vspec.path.empty ){
Path path = vspec.path;
if( !path.absolute ) path = pack.path ~ path;
logDebug("Adding local %s %s", path, vspec.version_);
m_packageManager.addLocalPackage(path, vspec.version_, LocalPackageType.temporary);
p = m_packageManager.addLocalPackage(path, vspec.version_, LocalPackageType.temporary);
} else {
auto p = m_packageManager.getBestPackage(name, vspec);
if( !m_dependencies.canFind(p) ){
logDebug("Found dependency %s %s: %s", name, vspec.toString(), p !is null);
if( p ){
m_dependencies ~= p;
collectDependenciesRec(p);
}
p = m_packageManager.getBestPackage(name, vspec);
}
if( !m_dependencies.canFind(p) ){
logDebug("Found dependency %s %s: %s", name, vspec.toString(), p !is null);
if( p ){
m_dependencies ~= p;
collectDependenciesRec(p);
}
}
m_dependees[p] ~= pack;
//enforce(p !is null, "Failed to resolve dependency "~name~" "~vspec.toString());
}
}
Expand All @@ -187,21 +195,46 @@ class Project {

@property string[] configurations() const { return m_main.configurations; }

string getPackageConfig(in Package pack, BuildPlatform platform, string config)
/// Returns a map with the configuration for all packages in the dependency tree.
string[string] getPackageConfigs(in BuildPlatform platform, string config)
const {
if( pack is m_main ) return config;
else {
// TODO: check the dependees for special wishes in terms on the configuration
return pack.getDefaultConfiguration(platform, false);
string[string] configs;
void determineConfigsRec(in Package p, bool use_default){
if( p.name !in configs ){
if( use_default ) configs[p.name] = p.getDefaultConfiguration(platform);
else return;
}
auto pconf = configs[p.name];
foreach(dn; p.dependencies.byKey){
auto dep = getDependency(dn);
auto conf = p.getSubConfiguration(config, dep, platform);
if( !conf.empty ){
if( auto pc = dn in configs ){
enforce(*pc == conf, format("Conflicting configurations detected for %s: %s vs. %s", dn, *pc, conf));
} else {
configs[dn] = conf;
determineConfigsRec(dep, use_default);
}
} else if( use_default && dn !in configs ){
configs[dn] = dep.getDefaultConfiguration(platform);
determineConfigsRec(dep, use_default);
}
}
}

configs[m_main.name] = config;
determineConfigsRec(m_main, false); // first only match all explicit selections
determineConfigsRec(m_main, true); // then fill up the rest with default configurations
return configs;
}

/// Returns the DFLAGS
void addBuildSettings(ref BuildSettings dst, BuildPlatform platform, string config)
void addBuildSettings(ref BuildSettings dst, in BuildPlatform platform, string config)
const {
auto configs = getPackageConfigs(platform, config);

foreach(pkg; this.getTopologicalPackageList()){
auto pkgconf = getPackageConfig(pkg, platform, config);
auto psettings = pkg.getBuildSettings(platform, pkgconf);
auto psettings = pkg.getBuildSettings(platform, configs[pkg.name]);
processVars(dst, pkg.path.toNativeString(), psettings);
if( pkg is m_main ){
dst.targetType = psettings.targetType;
Expand Down

0 comments on commit f7c9da0

Please sign in to comment.