Build managers

Rikki Cattermole via Digitalmars-d digitalmars-d at puremagic.com
Mon Feb 2 02:54:15 PST 2015


So I'm going to through a massive spanner in the works here.
I want to clarify something first. I love dub and what it stands for.  I 
don't want to change it.

Just before dub came about, I was working on a build manager as well. 
Except it was based heavily on Maven, but had more native usage.

The reason I believe this should at least be made out in the open is 
that we have people who want more control over their project building 
and dub will not provide that. Especially mixing c/c++ and D.

There was a recent suggestion to split dub up into a package manager and 
builder. This might be a worthwhile alternative as a builder.

Here was the spec that I wrote for it:

<Languages>
	<Language>
		<Name>D</Name>
		<Extensions>
			<Extension>d</Extension>
			<Extension>di</Extension>
		</Extensions>
		<Compilers>
			<Compiler>
				<Application>dmd</Application>
				<CompileCommand>{cmd} -c {source} -of{ObjectDir}/{source}.obj 
{includesArgument}</CompileCommand>
				<LinkCommand>{cmd} {objects} {libraries} 
-of{OuputDir}/{name}{extension} {includes}</LinkCommand>
				<IncludesArgument> -I{include}</IncludesArgument>
				<StaticLibraryArgument> -lib</StaticLibraryArgument>
				<DynamicLibraryArgument> -lib</DynamicLibraryArgument>
				<Platforms>
					<Platform>
						<Type>windows</Type>
						<Targets>
							<Target>win32</Target>
							<Target>win64</Target>
						</Targets>
						<CompilerLocation>C:/D/dmd2/windows/bin/</CompilerLocation>
						<StandardLibrary 
include="false">C:/D/dmd2/windows/lib/phobos.lib</StandardLibrary>
						<BinaryExtension>.exe</BinaryExtension>
						<DynamicLibraryExtension>.dll</DynamicLibraryExtension>
						<StaticLibraryExtension>.lib</StaticLibraryExtension>
						<Compatibility>
						</Compatibility>
					</Platform>
					<Platform>
						<Type>linux</Type>
						<BinaryExtension></BinaryExtension>
						<DynamicLibraryExtension>.so</DynamicLibraryExtension>
						<StaticLibraryExtension>.a</StaticLibraryExtension>
						<Compatibility>
							<Language objectsOnly="true">c</Language>
						</Compatibility>
					</Platform>
				</Platforms>
				<Profiles>
					<Profile default="true">
						<Name>Release</Name>
						<LinkCommand> -release</LinkCommand>
					</Profile>
					<Profile>
						<Name>Debug</Name>
						<CompileCommand> -debug -gc</CompileCommand>
						<LinkCommand> -debug -gc</LinkCommand>
					</Profile>
					<Profile>
						<Name>Unittest</Name>
						<CompileCommand> -unittest -gc</CompileCommand>
						<LinkCommand> -unittest -gc</LinkCommand>
					</Profile>
				</Profiles>
				<Project>
					<SourceDir>{project_dir}/src</SourceDir>
					<OutputDir clean="true">{project_dir}/bin/{target}</OutputDir>
					<ObjectDir clean="true">{project_dir}/obj/{target}</ObjectDir>
					<ResourceDir>{project_dir}/resources</ResourceDir>
					<Includes>
					</Includes>
					<ProvidesModules>
					</ProvidesModules>
					<target>{hostPlatform}</target>
				</Project>
			</Compiler>
		</Compilers>
	</Language>
	<Language>
		<Name>C</Name>
		<Extensions>
			<Extension>c</Extension>
		</Extensions>
		<Compilers>
			<Compiler>
				<Application>gcc</Application>
				<CompileCommand>{cmd} -c {source} -o{ObjectDir}/{source}.obj 
{includesArgument}</CompileCommand>
				<LinkCommand>{cmd} {objects} {libraries} 
-o{OuputDir}/{name}{extension} {includes}</LinkCommand>
				<IncludesArgument> -I{include}</IncludesArgument>
				<StaticLibraryArgument> -lib</StaticLibraryArgument>
				<DynamicLibraryArgument> -lib</DynamicLibraryArgument>
				<Platforms>
					<Platform>
						<Type>windows</Type>
						<Targets>
							<Target>win32</Target>
							<Target>win64</Target>
						</Targets>
						<CompilerLocation>C:/MinGW/bin/</CompilerLocation>
						<BinaryExtension>.exe</BinaryExtension>
						<DynamicLibraryExtension>.dll</DynamicLibraryExtension>
						<StaticLibraryExtension>.lib</StaticLibraryExtension>
						<Compatibility>
							<Language objectsOnly="true">C++</Language>
						</Compatibility>
					</Platform>
					<Platform>
						<Type>linux</Type>
						<BinaryExtension></BinaryExtension>
						<DynamicLibraryExtension>.so</DynamicLibraryExtension>
						<StaticLibraryExtension>.a</StaticLibraryExtension>
						<Compatibility>
							<Language objectsOnly="true">C++</Language>
							<Language objectsOnly="true" 
requireStandardLibrary="true">D</Language>
						</Compatibility>
					</Platform>
				</Platforms>
				<Profiles>
					<Profile default="true">
						<Name>Release</Name>
					</Profile>
					<Profile>
						<Name>Debug</Name>
						<CompileCommand> -ggdb</CompileCommand>
						<LinkCommand> -ggdb</LinkCommand>
					</Profile>
				</Profiles>
				<Project>
					<SourceDir>{project_dir}/src</SourceDir>
					<OutputDir clean="true">{project_dir}/bin/{target}</OutputDir>
					<ObjectDir clean="true">{project_dir}/obj/{target}</ObjectDir>
					<ResourceDir>{project_dir}/resources</ResourceDir>
					<Includes>
						<Include>{project_dir}/headers</Include>
					</Includes>
					<ProvidesModules>
					</ProvidesModules>
					<target>{hostPlatform}</target>
				</Project>
			</Compiler>
		</Compilers>
	</Language>
	<Language>
		<Name>C++</Name>
		<Extensions>
			<Extension>cpp</Extension>
		</Extensions>
		<Compilers>
			<Compiler>
				<Application>g++</Application>
				<CompileCommand>{cmd} -c {source} -o{ObjectDir}/{source}.obj 
{includesArgument}</CompileCommand>
				<LinkCommand>{cmd} {objects} {libraries} 
-o{OuputDir}/{name}{extension} {includes}</LinkCommand>
				<IncludesArgument> -I{include}</IncludesArgument>
				<StaticLibraryArgument> -lib</StaticLibraryArgument>
				<DynamicLibraryArgument> -lib</DynamicLibraryArgument>
				<Platforms>
					<Platform>
						<Type>windows</Type>
						<Targets>
							<Target>win32</Target>
							<Target>win64</Target>
						</Targets>
						<CompilerLocation>C:/MinGW/bin/</CompilerLocation>
						<BinaryExtension>.exe</BinaryExtension>
						<DynamicLibraryExtension>.dll</DynamicLibraryExtension>
						<StaticLibraryExtension>.lib</StaticLibraryExtension>
						<Compatibility>
							<Language>C</Language>
						</Compatibility>
					</Platform>
					<Platform>
						<Type>linux</Type>
						<BinaryExtension></BinaryExtension>
						<DynamicLibraryExtension>.so</DynamicLibraryExtension>
						<StaticLibraryExtension>.a</StaticLibraryExtension>
						<Compatibility>
							<CompatibilityLanguage>C</CompatibilityLanguage>
							<CompatibilityLanguage objectsOnly="true" 
requireStandardLibrary="true">D</CompatibilityLanguage>
						</Compatibility>
					</Platform>
				</Platforms>
				<Profiles>
					<Profile default="true">
						<Name>Release</Name>
					</Profile>
					<Profile>
						<Name>Debug</Name>
						<CompileCommand> -ggdb</CompileCommand>
						<LinkCommand> -ggdb</LinkCommand>
					</Profile>
				</Profiles>
				<Project>
					<SourceDir>{project_dir}/src</SourceDir>
					<OutputDir clean="true">{project_dir}/bin/{target}</OutputDir>
					<ObjectDir clean="true">{project_dir}/obj/{target}</ObjectDir>
					<ResourceDir>{project_dir}/resources</ResourceDir>
					<Includes>
						<Include>{project_dir}/headers</Include>
					</Includes>
					<ProvidesModules>
					</ProvidesModules>
					<Target>{hostPlatform}</Target>
					<Repositories>
						<Repository>
							<Name>Main Repository</Name>
							<BaseURL>http://example.com/repo</BaseURL>
						</Repository>
						<Repository>
							<Name>Local repository</Name>
							<Directory>{bspDataDir}/repo</Directory>
						</Repository>
					</Repositories>
				</Project>
			</Compiler>
		</Compilers>
	</Language>
</Languages>

If targets is not specified for a platform of a compiler then check
against it's type.
The type insignifies the binary of the compiler is in. Not the output it 
produces.
The output of a compiler is the type.
The type should match one of these:
	windows
	linux
	osx
	freeBSD
	solaris
	posix
Targets are made up of the platform and a more specific information.
	win32
	win64

<Project>
	<Name>ABC project</Name>
	<Version>x.y.z</Version>
	<Description>An amazing project!</Description>
	<Profile>Release</Profile>
	<ProvidesModules>
		<Module>project.abc.test</Module>
	</ProvidesModules>
	<Developers>
		<Developer>Person here person at company.com</Developer>
	</Developers>
	<VCS>https://example.com/repo/abc.git</VCS>
	<URL>http://example.com/project/abc</URL>
	
	<Dependencies>
		<Dependency>
			<Name>DEF project</Name>
			<Version>i.j.k</Version>
			<Module>project.def.test</Module>
			<Directory>{ProjectDir}/../DEF</Directory>
		</Dependency>
	</Dependencies>
</Project>

Configuration 'flattening' occurs in these steps
1. Load all files and keep output seperate
2. Create list of all languages which have unique names
3. Add to list of languages a new version of each language that has 
conflicts
	If append is available append to previous value for property otherwise 
overide.
	Prefer the later files not the first ones.
4. For each project in languages create a new one and use it as the base 
then overlay the projects configuration.
5. For each project created in last step gather the application, compile 
command, link command, includes, dynamic library and static library 
arguments.
6. Create base command to be executed for each project for storage.

Make sure 1-4 can be made into a cached file. (Preferably a mmfile).

Folder structure
~/.bsp/languages.xml
e.g. ~/.bsp/repo/m.o.d.u.l.e/v.e.r.s.i.o.n/project.xml
e.g. ~/.bsp/repo/m.o.d.u.l.e/v.e.r.s.i.o.n/languages.xml
e.g. ~/.bsp/repo/m.o.d.u.l.e/v.e.r.s.i.o.n/src
e.g. ~/.bsp/repo/m.o.d.u.l.e/v.e.r.s.i.o.n/bin/win32/bin.dll
e.g. ~/.bsp/repo/m.o.d.u.l.e/v.e.r.s.i.o.n/bin/win32/bin.lib
project_dir/project.xml
project_dir/languages.xml
project_dir/project_cached.xml
e.g. project_dir/bin/win32/bin.dll
e.g. project_dir/src
e.g. project_dir/obj/win32/bin.obj
e.g. project_dir/obj/win32/dependencies/m.o.d.u.l.e/bin.lib
e.g. project_dir/resources


More information about the Digitalmars-d mailing list