const fs = require('fs'); const path = require('path'); const process = require('process'); const { spawnSync, execSync } = require('child_process'); const rimraf = require('rimraf'); const DIR_BUILD = path.resolve('build'); const DIR_GENERATED = path.resolve(DIR_BUILD, 'generated'); const DIR_OBJ = path.resolve(DIR_BUILD, 'obj'); const DIR_SRC = path.resolve('src'); const DIR_GBDK = path.resolve(process.env['GBDKDIR']); const FILE_OUT = path.resolve(DIR_BUILD, 'Penny.gb'); const FILE_LINKFILE = path.join(DIR_BUILD, `linkflile.lk`); const LCC = path.join(DIR_GBDK, 'bin', 'lcc'); const LCCFLAGS = ''; // Create build dirs [ DIR_BUILD, DIR_GENERATED, DIR_OBJ ].forEach(d => { if(fs.existsSync(d)) return; fs.mkdirSync(d); }); // Scandir const buildSourceFiles = directory => { const sources = []; fs.readdirSync(directory).forEach(file => { const fullPath = path.join(directory, file); const stats = fs.statSync(fullPath); if(stats.isDirectory()) { sources.push(...buildSourceFiles(fullPath)); return; } if(file.endsWith('.c')) { sources.push(file.split(DIR_SRC).join('')); } }); return sources; } const logOut = (out, buffer) => { const str = [ out.stderr, out.stdout ].filter(n => n) .map(n => n.toString()) .filter(n => n) .join('') ; if(!str || !str.length) return; buffer(str); } // Get a list of sources and build each of them prior to linking. const allSources = buildSourceFiles(DIR_SRC); const compiledSources = []; for(let i = 0; i < allSources.length; i++) { const source = allSources[i]; const fileIn = path.join(DIR_SRC, source); const fileNameOut = path.basename(fileIn, '.c') + '.o'; const sourceRelativePath = path.dirname(source).split(DIR_SRC).join(''); const fileOut = path.join(DIR_OBJ, sourceRelativePath, fileNameOut); compiledSources.push(path.join(sourceRelativePath, fileNameOut)); if(fs.existsSync(fileOut)) continue; let result; try { result = execSync(`${LCC} ${LCCFLAGS} -c -o ${fileOut} ${fileIn}`); logOut(result, console.log); } catch(e) { logOut(e, console.error); process.exit(1); } } // Generate a linkfile. fs.writeFileSync(FILE_LINKFILE, compiledSources.map(cs=>{ return path.join(DIR_OBJ, cs); }).join('\n')); // Compile BIN let result; try { result = execSync(`${LCC} ${LCCFLAGS} -o ${FILE_OUT} -Wl-f${FILE_LINKFILE}`); logOut(result, console.log); } catch(e) { logOut(e, console.error); process.exit(1); }