diff --git a/source/dub/dub.d b/source/dub/dub.d index 3075ec0..30d5b8e 100644 --- a/source/dub/dub.d +++ b/source/dub/dub.d @@ -128,19 +128,20 @@ @property string name() const { return m_main ? m_main.name : "app"; } /// Returns the DFLAGS - @property string[] getDflags(string platform, string architecture) + @property string[] getDflags(BuildPlatform platform) const { auto ret = appender!(string[])(); - if( m_main ) ret.put(m_main.getDflags(platform, architecture)); + if( m_main ) processVars(ret, ".", m_main.getDflags(platform)); ret.put("-Isource"); ret.put("-Jviews"); foreach( string s, pkg; m_packages ){ + auto pack_path = ".dub/modules/"~pkg.name; void addPath(string prefix, string name){ - auto path = ".dub/modules/"~pkg.name~"/"~name; + auto path = pack_path~"/"~name; if( exists(path) ) ret.put(prefix ~ path); } - ret.put(pkg.getDflags(platform, architecture)); + processVars(ret, pack_path, pkg.getDflags(platform)); addPath("-I", "source"); addPath("-J", "views"); } @@ -416,7 +417,7 @@ /// Returns a list of flags which the application needs to be compiled /// properly. - string[] getDflags(string platform, string architecture) { return m_app.getDflags(platform, architecture); } + string[] getDflags(BuildPlatform platform) { return m_app.getDflags(platform); } /// Lists all installed modules void list() { @@ -637,3 +638,40 @@ logInfo("Uninstalled package: '"~packageId~"'"); } } + +private void processVars(ref Appender!(string[]) dst, string project_path, string[] vars) +{ + foreach( var; vars ){ + auto idx = std.string.indexOf(var, '$'); + if( idx < 0 ) dst.put(var); + else { + auto vres = appender!string(); + while( idx >= 0 ){ + if( idx+1 >= var.length ) break; + if( var[idx+1] == '$' ){ + vres.put(var[0 .. idx+1]); + var = var[idx+2 .. $]; + } else { + vres.put(var[0 .. idx]); + var = var[idx+1 .. $]; + + size_t idx2 = 0; + while( idx2 < var.length && isIdentChar(var[idx2]) ) idx2++; + auto varname = var[0 .. idx2]; + var = var[idx2 .. $]; + + if( varname == "PACKAGE_DIR" ) vres.put(project_path); + else enforce(false, "Invalid variable: "~varname); + } + idx = std.string.indexOf(var, '$'); + } + vres.put(var); + dst.put(vres.data); + } + } +} + +private bool isIdentChar(char ch) +{ + return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' || ch == '_'; +} \ No newline at end of file diff --git a/source/dub/package_.d b/source/dub/package_.d index 0cb740f..fdddbba 100644 --- a/source/dub/package_.d +++ b/source/dub/package_.d @@ -16,6 +16,11 @@ import vibe.data.json; import vibe.inet.url; +struct BuildPlatform { + string[] platform; + string[] architecture; + string compiler; +} /// Representing an installed package // Json file example: @@ -55,25 +60,28 @@ @property const(Url) url() const { return Url.parse(cast(string)m_meta["url"]); } @property const(Dependency[string]) dependencies() const { return m_dependencies; } - string[] getDflags(string platform, string architecture) + string[] getPlatformField(string name, BuildPlatform platform) const { + auto c = platform.compiler; + auto ret = appender!(string[])(); - foreach( j; m_meta["dflags"].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["dflags-"~platform].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["dflags-"~architecture].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["dflags-"~platform~"-"~architecture].opt!(Json[]) ) ret.put(j.get!string); + // TODO: turn these loops around and iterate over m_metas fields instead for efficiency reason + foreach( j; m_meta[name].opt!(Json[]) ) ret.put(j.get!string); + foreach( j; m_meta[name~"-"~c].opt!(Json[]) ) ret.put(j.get!string); + foreach( p; platform.platform ){ + foreach( j; m_meta[name~"-"~p].opt!(Json[]) ) ret.put(j.get!string); + foreach( j; m_meta[name~"-"~p~"-"~c].opt!(Json[]) ) ret.put(j.get!string); + foreach( a; platform.architecture ){ + foreach( j; m_meta[name~"-"~p~"-"~a].opt!(Json[]) ) ret.put(j.get!string); + foreach( j; m_meta[name~"-"~p~"-"~a~"-"~c].opt!(Json[]) ) ret.put(j.get!string); + } + } return ret.data; + } - string[] getLibs(string platform, string architecture) - const { - auto ret = appender!(string[])(); - foreach( j; m_meta["libs"].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["libs-"~platform].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["libs-"~architecture].opt!(Json[]) ) ret.put(j.get!string); - foreach( j; m_meta["libs-"~platform~"-"~architecture].opt!(Json[]) ) ret.put(j.get!string); - return ret.data; - } + string[] getDflags(BuildPlatform platform) const { return getPlatformField("dflags", platform); } + string[] getLibs(BuildPlatform platform) const { return getPlatformField("libs", platform); } string info() const { string s; diff --git a/source/dub/platform.d b/source/dub/platform.d new file mode 100644 index 0000000..67f56e5 --- /dev/null +++ b/source/dub/platform.d @@ -0,0 +1,88 @@ +/** + Determines the strings to identify the current build platform. + + Copyright: © 2012 rejectedsoftware e.K. + License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. + Authors: Sönke Ludwig +*/ +module dub.platform; + +import std.array; + +string[] determinePlatform() +{ + auto ret = appender!(string[])(); + version(Windows) ret.put("windows"); + version(linux) ret.put("linux"); + version(Posix) ret.put("posix"); + version(OSX) ret.put("osx"); + version(FreeBSD) ret.put("freebsd"); + version(OpenBSD) ret.put("openbsd"); + version(NetBSD) ret.put("netbsd"); + version(DragonFlyBSD) ret.put("dragonflybsd"); + version(BSD) ret.put("bsd"); + version(Solaris) ret.put("solaris"); + version(AIX) ret.put("aix"); + version(Haiku) ret.put("haiku"); + version(SkyOS) ret.put("skyos"); + version(SysV3) ret.put("sysv3"); + version(SysV4) ret.put("sysv4"); + version(Hurd) ret.put("hurd"); + version(Android) ret.put("android"); + version(Cygwin) ret.put("cygwin"); + version(MinGW) ret.put("mingw"); + return ret.data; +} + +string[] determineArchitecture() +{ + auto ret = appender!(string[])(); + version(X86) ret.put("x86"); + version(X86_64) ret.put("x86_64"); + version(ARM) ret.put("arm"); + version(ARM_Thumb) ret.put("arm_thumb"); + version(ARM_Soft) ret.put("arm_soft"); + version(ARM_SoftFP) ret.put("arm_softfp"); + version(ARM_HardFP) ret.put("arm_hardfp"); + version(ARM64) ret.put("arm64"); + version(PPC) ret.put("ppc"); + version(PPC_SoftFP) ret.put("ppc_softfp"); + version(PPC_HardFP) ret.put("ppc_hardfp"); + version(PPC64) ret.put("ppc64"); + version(IA64) ret.put("ia64"); + version(MIPS) ret.put("mips"); + version(MIPS32) ret.put("mips32"); + version(MIPS64) ret.put("mips64"); + version(MIPS_O32) ret.put("mips_o32"); + version(MIPS_N32) ret.put("mips_n32"); + version(MIPS_O64) ret.put("mips_o64"); + version(MIPS_N64) ret.put("mips_n64"); + version(MIPS_EABI) ret.put("mips_eabi"); + version(MIPS_NoFloat) ret.put("mips_nofloat"); + version(MIPS_SoftFloat) ret.put("mips_softfloat"); + version(MIPS_HardFloat) ret.put("mips_hardfloat"); + version(SPARC) ret.put("sparc"); + version(SPARC_V8Plus) ret.put("sparc_v8plus"); + version(SPARC_SoftFP) ret.put("sparc_softfp"); + version(SPARC_HardFP) ret.put("sparc_hardfp"); + version(SPARC64) ret.put("sparc64"); + version(S390) ret.put("s390"); + version(S390X) ret.put("s390x"); + version(HPPA) ret.put("hppa"); + version(HPPA64) ret.put("hppa64"); + version(SH) ret.put("sh"); + version(SH64) ret.put("sh64"); + version(Alpha) ret.put("alpha"); + version(Alpha_SoftFP) ret.put("alpha_softfp"); + version(Alpha_HardFP) ret.put("alpha_hardfp"); + return ret.data; +} + +string determineCompiler() +{ + version(DigitalMars) return "dmd"; + else version(GNU) return "gdc"; + else version(LDC) return "ldc"; + else version(SDC) return "sdc"; + else return null; +}