Added start of custom D build system.
This commit is contained in:
		
							parent
							
								
									80f9167ab9
								
							
						
					
					
						commit
						1a442c4b9d
					
				| 
						 | 
					@ -0,0 +1,124 @@
 | 
				
			||||||
 | 
					#!/usr/bin/env rdmd
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This module is responsible for building the project.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					module build;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import std.stdio;
 | 
				
			||||||
 | 
					import std.file;
 | 
				
			||||||
 | 
					import std.string;
 | 
				
			||||||
 | 
					import std.conv;
 | 
				
			||||||
 | 
					import std.path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const string MCU_ID = "atmega328p";
 | 
				
			||||||
 | 
					const ulong CPU_FREQ = 16_000_000;
 | 
				
			||||||
 | 
					const string BOOTLOADER = "arduino";
 | 
				
			||||||
 | 
					const ulong AVRDUDE_BAUDRATE = 57_600;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const string SOURCE_DIR = "src";
 | 
				
			||||||
 | 
					const string BUILD_DIR = "bin";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const string[] COMPILER_FLAGS = [
 | 
				
			||||||
 | 
					    "-Wall",
 | 
				
			||||||
 | 
					    "-Os"
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(string[] args) {
 | 
				
			||||||
 | 
					    build();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int build() {
 | 
				
			||||||
 | 
					    if (!exists(BUILD_DIR)) mkdir(BUILD_DIR);
 | 
				
			||||||
 | 
					    string[] sources = findFiles(SOURCE_DIR, ".c");
 | 
				
			||||||
 | 
					    writefln!"Found %d source files."(sources.length);
 | 
				
			||||||
 | 
					    string[] objects;
 | 
				
			||||||
 | 
					    objects.reserve(sources.length);
 | 
				
			||||||
 | 
					    foreach (source; sources) {
 | 
				
			||||||
 | 
					        objects ~= compileSourceToObject(source);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    string elfFile = linkObjects(objects);
 | 
				
			||||||
 | 
					    string hexFile = copyToHex(elfFile);
 | 
				
			||||||
 | 
					    writefln!"Built %s"(hexFile);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-------- Utility functions below here -------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int run(string shellCommand) {
 | 
				
			||||||
 | 
					    import std.process : Pid, spawnShell, wait;
 | 
				
			||||||
 | 
					    Pid pid = spawnShell(shellCommand);
 | 
				
			||||||
 | 
					    return wait(pid);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void runOrQuit(string shellCommand, int[] successExitCodes = [0]) {
 | 
				
			||||||
 | 
					    import core.stdc.stdlib : exit;
 | 
				
			||||||
 | 
					    import std.algorithm : canFind;
 | 
				
			||||||
 | 
					    int result = run(shellCommand);
 | 
				
			||||||
 | 
					    if (!canFind(successExitCodes, result)) exit(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string compileSourceToObject(string sourcePath) {
 | 
				
			||||||
 | 
					    string flags = join(COMPILER_FLAGS, " ");
 | 
				
			||||||
 | 
					    string name = baseName(sourcePath);
 | 
				
			||||||
 | 
					    name = name[0 .. name.lastIndexOf('.')];
 | 
				
			||||||
 | 
					    string objectPath = buildPath("bin", name ~ ".o");
 | 
				
			||||||
 | 
					    string cmd = format!"avr-gcc %s -DF_CPU=%dUL -mmcu=%s -c -o %s %s"(
 | 
				
			||||||
 | 
					        flags,
 | 
				
			||||||
 | 
					        CPU_FREQ,
 | 
				
			||||||
 | 
					        MCU_ID,
 | 
				
			||||||
 | 
					        objectPath,
 | 
				
			||||||
 | 
					        sourcePath
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    writeln(cmd);
 | 
				
			||||||
 | 
					    runOrQuit(cmd);
 | 
				
			||||||
 | 
					    return objectPath;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string linkObjects(string[] objectPaths) {
 | 
				
			||||||
 | 
					    string objectsArg = join(objectPaths, " ");
 | 
				
			||||||
 | 
					    string flags = join(COMPILER_FLAGS, " ");
 | 
				
			||||||
 | 
					    string elfFile = buildPath(BUILD_DIR, "gympal.elf");
 | 
				
			||||||
 | 
					    string cmd = format!"avr-gcc %s -o %s %s"(
 | 
				
			||||||
 | 
					        flags,
 | 
				
			||||||
 | 
					        elfFile,
 | 
				
			||||||
 | 
					        objectsArg
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    writeln(cmd);
 | 
				
			||||||
 | 
					    runOrQuit(cmd);
 | 
				
			||||||
 | 
					    return elfFile;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string copyToHex(string elfFile) {
 | 
				
			||||||
 | 
					    string hexFile = buildPath(BUILD_DIR, "gympal.hex");
 | 
				
			||||||
 | 
					    string cmd = format!"avr-objcopy -O ihex -R .eeprom %s %s"(
 | 
				
			||||||
 | 
					        elfFile,
 | 
				
			||||||
 | 
					        hexFile
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    writeln(cmd);
 | 
				
			||||||
 | 
					    runOrQuit(cmd);
 | 
				
			||||||
 | 
					    return hexFile;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int flashToMCU(string hexFile) {
 | 
				
			||||||
 | 
					    string cmd = format!"avrdude -c %s -p %s -P /dev/ttyUSB0 -b %d flash:w:%s:i"(
 | 
				
			||||||
 | 
					        BOOTLOADER,
 | 
				
			||||||
 | 
					        MCU_ID,
 | 
				
			||||||
 | 
					        AVRDUDE_BAUDRATE,
 | 
				
			||||||
 | 
					        hexFile
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    writeln(cmd);
 | 
				
			||||||
 | 
					    return run(cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string[] findFiles(string path, string suffix = null) {
 | 
				
			||||||
 | 
					    import std.array;
 | 
				
			||||||
 | 
					    import std.algorithm;
 | 
				
			||||||
 | 
					    auto app = appender!(string[]);
 | 
				
			||||||
 | 
					    foreach (DirEntry entry; dirEntries(path, SpanMode.breadth, false)) {
 | 
				
			||||||
 | 
					        if (entry.isFile && (suffix is null || entry.name.endsWith(suffix))) {
 | 
				
			||||||
 | 
					            app ~= entry.name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return app[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue