Last active
September 16, 2020 14:37
-
-
Save roman-kirsanov/a45620f4ddbac14d5562c158155bff7f to your computer and use it in GitHub Desktop.
Clang Build System powered by Node.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = options => { | |
options = Object.assign({ | |
path: null, | |
name: null | |
}, options); | |
if (options.path === null || options.path === undefined) | |
throw new Error('BuildSystem: "path" is required'); | |
const libcp = require('child_process'); | |
const libfs = require('fs'); | |
const libpath = require('path'); | |
const fileSize = p => { | |
if (libfs.existsSync(p)) | |
return libfs.statSync(p).size; | |
else throw new Error(`fileSize: File "${p}" not found`); | |
} | |
const fileModified = p => { | |
if (libfs.existsSync(p)) | |
return libfs.statSync(p).mtime.getTime(); | |
else throw new Error(`fileModified: File "${p}" not found`); | |
} | |
const removeDir = p => { | |
if (libfs.existsSync(p)) { | |
libfs.readdirSync(p).forEach(f => { | |
const pp = libpath.join(p, f); | |
if (libfs.lstatSync(pp).isDirectory()) removeDir(pp); | |
else libfs.unlinkSync(pp); | |
}); | |
libfs.rmdirSync(p); | |
} | |
} | |
const changeExt = (p, e) => [...p.split('.').slice(0, -1), e].join('.'); | |
const platform = require('os').platform(); | |
const projectpath = libpath.normalize(options.path); | |
const projectname = options.name || libpath.basename(projectpath); | |
const projectext = (platform == 'win32') ? 'exe' : 'out'; | |
const __tempPath = (platform == 'win32') ? 'C:\\Temp' : '/tmp'; | |
const __searchPath = []; | |
const __libraryPath = []; | |
const __libraries = []; | |
const __frameworks = []; | |
const __sourceFiles = []; | |
const __arguments = []; | |
const __defines = []; | |
const __pchs = []; | |
let __compiler = 'clang'; | |
let __errorLimit = null; | |
let __targetStandard = null; | |
let __debugMode = true; | |
let __runProgram = false; | |
let __lastClangCmd = ''; | |
const clang = cmd => { | |
const p = libcp.spawnSync((__lastClangCmd = cmd.join(' ')), [], { shell: true }); | |
const out = p.stdout.toString().trim(); | |
const err = p.stderr.toString().trim(); | |
return { | |
out: (out.length > 0) ? out : null, | |
err: (err.length > 0) ? err : null | |
} | |
} | |
const setCompiler = a => __compiler = a; | |
const addSearchPath = p => { | |
const pp = libpath.normalize(p); | |
if (libfs.existsSync(pp)) { | |
if (libfs.lstatSync(pp).isDirectory()) __searchPath.push(pp); | |
else throw new Error(`addSearchPath: "${pp}" is not a directory`); | |
} else throw new Error(`addSearchPath: "${pp}" path not found`); | |
} | |
const addLibraryPath = p => { | |
const pp = libpath.normalize(p); | |
if (libfs.existsSync(pp)) { | |
if (libfs.lstatSync(pp).isDirectory()) __libraryPath.push(pp); | |
else throw new Error(`addLibraryPath: "${pp}" is not a directory`); | |
} else throw new Error(`addLibraryPath: "${pp}" path not found`); | |
} | |
const addLibrary = a => __libraries.push(a); | |
const addFramework = a => __frameworks.push(a); | |
const addStandardWin32Libs = () => { | |
__libraries.push('user32.lib'); | |
__libraries.push('gdi32.lib'); | |
__libraries.push('shell32.lib'); | |
__libraries.push('Winmm.lib'); | |
} | |
const addStandardDarwinLibs = () => { | |
__frameworks.push('Cocoa'); | |
} | |
const addSourceFile = p => { | |
const pp = libpath.normalize(p); | |
if (libfs.existsSync(pp)) { | |
if (!libfs.lstatSync(pp).isDirectory()) __sourceFiles.push(pp); | |
else throw new Error(`addSourceFile: "${pp}" is not a file`); | |
} else throw new Error(`addSourceFile: "${pp}" path not found`); | |
} | |
const addSourceFolder = (p, e) => { | |
libfs.readdirSync(p).forEach(f => { | |
if (e.includes(libpath.extname(f))) | |
addSourceFile(libpath.join(p, f)); | |
}); | |
} | |
const addArgument = a => __arguments.push(a); | |
const addDefine = a => __defines.push(a); | |
const addPCH = a => a.forEach(i => __pchs.push(i)); | |
const setErrorLimit = a => __errorLimit = a; | |
const setStandard = a => __targetStandard = a; | |
const setRelease = a => __debugMode = !a; | |
const setRun = a => __runProgram = a; | |
const buildCommandLine = options => { | |
options = Object.assign({ | |
compiler: true, | |
debugging: true, | |
includeSearch: true, | |
librarySearch: true, | |
frameworks: true, | |
libraries: true, | |
arguments: true, | |
defines: true | |
}, options); | |
const ret = []; | |
if (options.compiler) | |
ret.push(__compiler); | |
if (__targetStandard) | |
ret.push(`-std=${__targetStandard}`); | |
// if (platform == 'darwin') | |
// ret.push('-fobjc-arc'); | |
if (options.debugging) { | |
if (__debugMode) { | |
ret.push('-g'); | |
ret.push('-O0'); | |
ret.push('-fsanitize=address'); | |
if (__errorLimit) | |
ret.push(`-ferror-limit=${__errorLimit}`); | |
} else { | |
ret.push('-O3'); | |
ret.push('-DNDEBUG'); | |
} | |
} | |
if (options.includeSearch) | |
__searchPath.forEach(p => ret.push(`-I"${p}"`)); | |
if (options.librarySearch) | |
__libraryPath.forEach(p => ret.push(`-L"${p}"`)); | |
if (options.libraries) | |
__libraries.forEach(l => ret.push(`-l${l}`)); | |
if (options.frameworks) | |
__frameworks.forEach(f => ret.push(`-framework ${f}`)); | |
if (options.defines) | |
__defines.forEach(a => ret.push(`-D${a}`)); | |
if (options.arguments) | |
__arguments.forEach(a => ret.push(a)); | |
return ret; | |
} | |
const getFileDependencies = p => { | |
const getFileList = a => a | |
.split('\n') | |
.slice(1) | |
.map(ln => ln.trim()) | |
.reduce((ret, ln) => { | |
const fn = ((ln.slice(-1) == '\\') | |
? libpath.normalize(ln.slice(0, -1)) | |
: libpath.normalize(ln)).trim(); | |
if (!ret.includes(fn)) | |
ret.push(fn); | |
return ret; | |
}, []); | |
const getFileInfoList = a => a.map(fn => { | |
const stat = libfs.statSync(fn); | |
return { | |
filename: fn, | |
modified: stat.mtime.getTime(), | |
size: stat.size | |
} | |
}); | |
if (libfs.existsSync(p)) { | |
const cmd = buildCommandLine({ | |
debugging: false, | |
frameworks: false, | |
libraries: false, | |
librarySearch: false, | |
arguments: false | |
}); | |
const res = clang([...cmd, '-MM', p]); | |
if (res.err) return { | |
status: 'error', | |
message: (res.err + '\n' + res.out) | |
} | |
const files = getFileList(res.out); | |
const info = getFileInfoList(files); | |
return { | |
status: 'success', | |
result: info | |
} | |
} else return { | |
status: 'error', | |
message: `File "${p}" not found` | |
} | |
} | |
const getLineCount = p => { | |
if (p === null || p === undefined) | |
throw new Error(`getLineCount: Specify first argument (input fileName)`); | |
if (libfs.existsSync(p)) { | |
let ret = 0; | |
const buf = libfs.readFileSync(p); | |
for (const byte of buf.values()) { | |
if (byte == '\n'.charCodeAt(0)) | |
ret += 1; | |
} | |
return { | |
status: 'success', | |
result: ret | |
}; | |
} else return { | |
status: 'error', | |
message: `File "${p}" not found` | |
} | |
} | |
const preprocessFile = (p, o) => { | |
if (p === null || p === undefined) | |
throw new Error(`preprocessFile: Specify first argument (input fileName)`); | |
if (o === null || o === undefined) | |
throw new Error(`preprocessFile: Specify second argument (output fileName)`); | |
if (libfs.existsSync(p)) { | |
const t_begin = (new Date()).getTime(); | |
const cmd = buildCommandLine({ | |
frameworks: false, | |
libraries: false, | |
librarySearch: false | |
}); | |
const res = clang([...cmd, '-E', p, '-o', o]); | |
if (res.err) return { | |
status: 'error', | |
message: (res.err + '\n' + res.out) | |
} | |
const t_end = (new Date()).getTime(); | |
if (!libfs.existsSync(o)) return { | |
status: 'error', | |
message: `File not created "${o}"` | |
} | |
return { | |
status: 'success', | |
filename: o, | |
duration: (t_end - t_begin) | |
} | |
} else return { | |
status: 'error', | |
message: `File "${p}" not found` | |
} | |
} | |
const compileFile = (p, o) => { | |
if (p === null || p === undefined) | |
throw new Error(`compileFile: Specify first argument (input fileName)`); | |
if (o === null || o === undefined) | |
throw new Error(`compileFile: Specify second argument (output fileName)`); | |
if (libfs.existsSync(p)) { | |
const t_begin = (new Date()).getTime(); | |
const cmd = buildCommandLine({ | |
frameworks: false, | |
libraries: false | |
}); | |
const res = clang([...cmd, '-c', p, '-o', o]); | |
if (res.err) return { | |
status: 'error', | |
message: (res.err + '\n' + res.out) | |
}; | |
const t_end = (new Date()).getTime(); | |
if (!libfs.existsSync(o)) return { | |
status: 'error', | |
message: `File not created "${o}"` | |
}; | |
return { | |
status: 'success', | |
filename: o, | |
duration: (t_end - t_begin) | |
} | |
} else return { | |
status: 'error', | |
message: `File "${p}" not found` | |
} | |
} | |
const linkFiles = (files, o) => { | |
if (files === null || files === undefined) | |
throw new Error(`linkFiles: Specify first argument (input fileName list)`); | |
if (!Array.isArray(files)) | |
throw new Error(`linkFiles: First argument must be an array`); | |
if (o === null || o === undefined) | |
throw new Error(`linkFiles: Specify second argument (output fileName)`); | |
for (const fn of files) | |
if (!libfs.existsSync(fn)) | |
return { status: 'error', message: `File "${fn}" not found` }; | |
const cmd = buildCommandLine(); | |
const t_begin = (new Date()).getTime(); | |
const input = files.map(fn => `"${fn}"`); | |
const res = clang([...cmd, ...input, '-o', o]); | |
if (res.err) return { | |
status: 'error', | |
message: (res.err + '\n' + res.out) | |
}; | |
const t_end = (new Date()).getTime(); | |
if (!libfs.existsSync(o)) return { | |
status: 'error', | |
message: `File not created "${o}"` | |
}; | |
return { | |
status: 'success', | |
filename: o, | |
duration: (t_end - t_begin) | |
} | |
} | |
const createPCH = (a, o) => { | |
if (a === null || a === undefined) | |
throw new Error(`createPCH: Specify first argument (list of headers)`); | |
if (!Array.isArray(a)) | |
throw new Error(`createPCH: First argument must be an array`); | |
if (o === null || o === undefined) | |
throw new Error(`createPCH: Specify second argument (output fileName)`); | |
const hfile = a.map(h => `#include <${h}>`).join('\n'); | |
const path_pch = o; | |
const path_h = changeExt(o, 'h'); | |
libfs.writeFileSync(path_h, hfile); | |
const cmd = buildCommandLine({ | |
frameworks: false, | |
libraries: false, | |
librarySearch: false | |
}); | |
const t_begin = (new Date()).getTime(); | |
const res = clang([...cmd, path_h, '-emit-pch', '-o', path_pch]); | |
if (res.err) return { | |
status: 'error', | |
message: (res.err + '\n' + res.out) | |
}; | |
const t_end = (new Date()).getTime(); | |
if (!libfs.existsSync(path_pch)) return { | |
status: 'error', | |
message: `File not created "${path_pch}"` | |
}; | |
return { | |
status: 'success', | |
filename: path_pch, | |
duration: (t_end - t_begin) | |
} | |
} | |
const createMakeInfo = sinkpath => { | |
const getFolderName = filename => { | |
const dirname = libpath.dirname(filename); | |
const basename = libpath.basename(dirname); | |
if (basename.toUpperCase() != 'IMPL') return basename; | |
else { | |
const dirname2 = libpath.dirname(dirname); | |
const basename2 = libpath.basename(dirname2); | |
return basename2; | |
} | |
} | |
const makeInfo = { | |
duration: 0, | |
translationUnits: __sourceFiles.map(filename => ({ | |
baseName: libpath.basename(filename), | |
displayName: '', | |
sourceFileName: filename, | |
targetFileName: libpath.join( | |
sinkpath, | |
libpath.basename(libpath.dirname(filename)) + '_' + | |
changeExt(libpath.basename(filename), 'o') | |
), | |
preprFileName: libpath.join( | |
sinkpath, | |
libpath.basename(libpath.dirname(filename)) + '_' + | |
changeExt(libpath.basename(filename), `preprocessed${libpath.extname(filename)}`) | |
), | |
infoFileName: libpath.join( | |
sinkpath, | |
libpath.basename(libpath.dirname(filename)) + '_' + | |
changeExt(libpath.basename(filename), 'makeinfo.json') | |
), | |
modified: fileModified(filename), | |
dependenciesTime: 0, | |
preprocessTime: 0, | |
compilationTime: 0, | |
unitTime: 0, | |
linesOfCode: 0, | |
linesOfCode_prep: 0, | |
unitSize: 0, | |
action: null, | |
dependencies: [] | |
})) | |
}; | |
makeInfo.translationUnits.forEach(tu => { | |
const o2 = makeInfo.translationUnits.find(t => t.targetFileName == tu.targetFileName && t != tu); | |
if (o2) | |
throw new Error(`BuildSystem: Duplicate file found "${t.targetFileName}"`); | |
const tu2 = makeInfo.translationUnits.find(t => t.baseName == tu.baseName && t != tu); | |
if (tu2) { | |
tu2.displayName = `${tu2.baseName} (${getFolderName(tu2.sourceFileName)})`; | |
tu.displayName = `${tu.baseName} (${getFolderName(tu.sourceFileName)})`; | |
} else { | |
tu.displayName = tu.baseName; | |
} | |
}); | |
return makeInfo; | |
}; | |
const prepareTranslationUnit = tu => { | |
if (tu === null || tu === undefined) | |
throw new Error(`prepareTranslationUnit: Specify first argument (TU object)`); | |
const t_begin = (new Date()).getTime(); | |
tu.action = 'skip'; | |
tu.dependencies = getFileDependencies(tu.sourceFileName).result; | |
const prevTU = libfs.existsSync(tu.infoFileName) | |
? JSON.parse(libfs.readFileSync(tu.infoFileName).toString()) | |
: null; | |
if (prevTU) { | |
if (tu.modified == prevTU.modified) { | |
if (prevTU.dependencies.length == tu.dependencies.length) { | |
let all_skip = true; | |
for (let i = 0; i < tu.dependencies.length; i++) { | |
const dep = tu.dependencies[i]; | |
const prevDep = prevTU.dependencies[i]; | |
if (dep.filename == prevDep.filename) { | |
if (dep.modified == prevDep.modified) { | |
/* skip */ | |
} else { | |
all_skip = false; | |
break; | |
} | |
} else { | |
all_skip = false; | |
break; | |
} | |
} | |
if (all_skip) { | |
tu.linesOfCode = prevTU.linesOfCode; | |
tu.linesOfCode_prep = prevTU.linesOfCode_prep; | |
tu.unitSize = prevTU.unitSize; | |
} else tu.action = 'compile'; | |
} else tu.action = 'compile'; | |
} else tu.action = 'compile'; | |
} else tu.action = 'compile'; | |
const t_end = (new Date()).getTime(); | |
return { | |
duration: (t_end - t_begin) | |
} | |
} | |
const print = (a, b) => process.stdout.write(a.toString().padEnd(b || 0)); | |
const clean = () => { | |
const path = libpath.join(__tempPath, projectname); | |
if (libfs.existsSync(path)) | |
removeDir(path); | |
} | |
const make = () => { | |
const sinkpath = libpath.join(__tempPath, projectname, __debugMode ? 'Debug' : 'Release'); | |
const outpath = libpath.join(sinkpath, `${projectname}.${projectext}`); | |
if (!__debugMode) { | |
if (libfs.existsSync(sinkpath)) | |
removeDir(sinkpath); | |
libfs.mkdirSync(sinkpath, { recursive: true }); | |
} else { | |
if (!libfs.existsSync(sinkpath)) | |
libfs.mkdirSync(sinkpath, { recursive: true }); | |
} | |
const makeInfo = createMakeInfo(sinkpath); | |
const maxFileName = Math.max.apply(null, makeInfo.translationUnits.map(tu => tu.displayName.length)); | |
const NFormat = new Intl.NumberFormat('es-ES'); | |
const formatLOC = a => NFormat.format(a).replace(/\./g, ' '); | |
const formatTime = a => `${(a / 1000).toFixed(2)} Sec`; | |
const formatSize = a => `${(a / 1024 / 1024).toFixed(2)} MiB`; | |
const COLUMN_FILENAME = (maxFileName + 4); | |
const COLUMN_ACTION = 11; | |
const COLUMN_TIME = 12; | |
const COLUMN_LOC = 11; | |
const COLUMN_SIZE = 10; | |
console.log(`COMPILATION (${__debugMode ? 'Debug' : 'Release'})\n`); | |
console.log( | |
'File Name'.padEnd(COLUMN_FILENAME) + | |
'-MM Time'.padEnd(COLUMN_TIME) + | |
'Action'.padEnd(COLUMN_ACTION) + | |
'LOC'.padEnd(COLUMN_LOC) + | |
'-E Time'.padEnd(COLUMN_TIME) + | |
'LOC (-E)'.padEnd(COLUMN_LOC) + | |
'-c Time'.padEnd(COLUMN_TIME) + | |
'TU Time'.padEnd(COLUMN_TIME) + | |
'TU Size'.padEnd(COLUMN_SIZE) | |
); | |
console.log( | |
'-'.padEnd(COLUMN_FILENAME, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_ACTION, '-') + | |
'-'.padEnd(COLUMN_LOC, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_LOC, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_SIZE, '-') | |
); | |
let total_mmt = 0; | |
let total_loc = 0; | |
let total_etime = 0; | |
let total_locpr = 0; | |
let total_ctime = 0; | |
let total_tutime = 0; | |
let error = null; | |
for (const tu of makeInfo.translationUnits) { | |
print(tu.displayName, COLUMN_FILENAME); | |
const res0 = prepareTranslationUnit(tu); | |
tu.dependenciesTime = res0.duration; | |
print(formatTime(tu.dependenciesTime), COLUMN_TIME); | |
print(tu.action, COLUMN_ACTION); | |
if (tu.action == 'compile') { | |
const res1 = getLineCount(tu.sourceFileName); | |
if (res1.status == 'error') { | |
error = res1.message; | |
break; | |
} else tu.linesOfCode = res1.result; | |
print(formatLOC(tu.linesOfCode), COLUMN_LOC); | |
const res2 = preprocessFile(tu.sourceFileName, tu.preprFileName); | |
if (res2.status == 'error') { | |
error = res2.message; | |
break; | |
} else tu.preprocessTime = res2.duration; | |
print(formatTime(tu.preprocessTime), COLUMN_TIME); | |
const res3 = getLineCount(tu.preprFileName); | |
if (res3.status == 'error') { | |
error = res3.message; | |
break; | |
} else tu.linesOfCode_prep = res3.result; | |
print(formatLOC(tu.linesOfCode_prep), COLUMN_LOC); | |
const res4 = compileFile(tu.preprFileName, tu.targetFileName); | |
if (res4.status == 'error') { | |
error = res4.message; | |
break; | |
} else tu.compilationTime = res4.duration; | |
print(formatTime(tu.compilationTime), COLUMN_TIME); | |
tu.unitSize = fileSize(tu.targetFileName); | |
} else { | |
print(formatLOC(tu.linesOfCode), COLUMN_LOC); | |
print('-', COLUMN_TIME); | |
print(formatLOC(tu.linesOfCode_prep), COLUMN_LOC); | |
print('-', COLUMN_TIME); | |
} | |
tu.unitTime = tu.dependenciesTime + tu.preprocessTime + tu.compilationTime; | |
print(formatTime(tu.unitTime), COLUMN_TIME); | |
print(formatSize(tu.unitSize), COLUMN_SIZE); | |
total_mmt += tu.dependenciesTime; | |
total_etime += tu.preprocessTime; | |
total_ctime += tu.compilationTime; | |
total_tutime += tu.unitTime; | |
total_loc += tu.linesOfCode; | |
total_locpr += tu.linesOfCode_prep; | |
libfs.writeFileSync(tu.infoFileName, JSON.stringify(tu)); | |
console.log(''); | |
} | |
if (!error) { | |
console.log( | |
'-'.padEnd(COLUMN_FILENAME, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_ACTION, '-') + | |
'-'.padEnd(COLUMN_LOC, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_LOC, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_SIZE, '-') | |
); | |
print('Total', COLUMN_FILENAME); | |
print(formatTime(total_mmt), COLUMN_TIME); | |
print('-', COLUMN_ACTION); | |
print(formatLOC(total_loc), COLUMN_LOC); | |
print(formatTime(total_etime), COLUMN_TIME); | |
print(formatLOC(total_locpr), COLUMN_LOC); | |
print(formatTime(total_ctime), COLUMN_TIME); | |
print(formatTime(total_tutime), COLUMN_TIME); | |
print('-', COLUMN_SIZE); | |
console.log('\n'); | |
console.log(`LINKAGE (${__debugMode ? 'Debug' : 'Release'})\n`); | |
console.log( | |
'File Name'.padEnd(COLUMN_FILENAME) + | |
'Time'.padEnd(COLUMN_TIME) + | |
'Size'.padEnd(COLUMN_SIZE) | |
); | |
console.log( | |
'-'.padEnd(COLUMN_FILENAME, '-') + | |
'-'.padEnd(COLUMN_TIME, '-') + | |
'-'.padEnd(COLUMN_SIZE, '-') | |
); | |
print(libpath.basename(outpath), COLUMN_FILENAME); | |
const res5 = linkFiles( | |
makeInfo.translationUnits.map(tu => tu.targetFileName), | |
outpath | |
); | |
if (res5.status == 'error') { | |
console.log('*\n'); | |
console.log(res5.message + '\n' + __lastClangCmd); | |
} else { | |
print(formatTime(res5.duration), COLUMN_TIME); | |
print(formatSize(fileSize(outpath)), COLUMN_SIZE); | |
console.log('\n'); | |
if (__runProgram) | |
libcp.spawn(outpath, [], { stdio: 'inherit', shell: true }); | |
} | |
} else { | |
console.log('*\n'); | |
console.log(error + '\n' + __lastClangCmd); | |
} | |
} | |
return { | |
clean: clean, | |
make: make, | |
setCompiler, | |
addSearchPath, | |
addLibraryPath, | |
addLibrary, | |
addFramework, | |
addStandardDarwinLibs, | |
addStandardWin32Libs, | |
addSourceFile, | |
addSourceFolder, | |
addArgument, | |
addDefine, | |
addPCH, | |
setErrorLimit, | |
setStandard, | |
setRelease, | |
setRun, | |
getFileDependencies, | |
getLineCount, | |
preprocessFile, | |
compileFile, | |
linkFiles, | |
name: () => projectname, | |
platform: () => platform, | |
} | |
} | |
/* USAGE */ | |
const libfs = require('fs'); | |
const libpath = require('path'); | |
const BuildSystem = require('../Path/To/clang-BuildSystem.js'); | |
const builder = BuildSystem({ path: __dirname }); | |
const libraryPath = libpath.join(builder.path(), '..', 'Library'); | |
const chipmunkPath = libpath.join(libraryPath, '3rdParty', 'Chipmunk2D'); | |
builder.addSearchPath(libraryPath); | |
builder.addSearchPath(libpath.join(chipmunkPath, 'include')); | |
builder.addSourceFolder(libpath.join(chipmunkPath, 'src'), ['.c']); | |
if (builder.platform() == 'win32') { | |
builder.addStandardWin32Libs(); | |
builder.addSourceFile(libpath.join(libraryPath, 'Win32', 'Impl', 'File1.cc')); | |
builder.addSourceFile(libpath.join(libraryPath, 'Win32', 'Impl', 'File2.cc')); | |
} else if (builder.platform() == 'darwin') { | |
builder.addStandardDarwinLibs(); | |
builder.addFramework('QuartzCore'); | |
builder.addSourceFile(libpath.join(libraryPath, 'MacOS', 'Impl', 'File1.cc')); | |
builder.addSourceFile(libpath.join(libraryPath, 'MacOS', 'Impl', 'File2.cc')); | |
} | |
builder.setStandard('c++2a'); | |
builder.addSourceFile(libpath.join(builder.path(), 'Source', 'main.cc')); | |
builder.setRelease(process.argv.includes('--release')); | |
builder.setRun(process.argv.includes('--run')); | |
builder.make(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment