This commit is contained in:
Zengtudor 2024-08-12 15:30:14 +08:00
parent 3dea7cd4ab
commit 75d224d735
11 changed files with 61 additions and 29 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
/build /build
/test*
# ---> Node # ---> Node
# Logs # Logs
logs logs

View File

@ -7,29 +7,51 @@ import fs from "fs"
import printDebug from "../Tools/DebugPrint.js"; import printDebug from "../Tools/DebugPrint.js";
import sourceFilesToString from "../Tools/SourceFilesToString.js"; import sourceFilesToString from "../Tools/SourceFilesToString.js";
import execAsync from "../Tools/ExecAsync.js"; import execAsync from "../Tools/ExecAsync.js";
import protectPath from "../Tools/ProtectPath.js";
import printErrorOrDebug from "../Tools/PrintErrorOrDebug.js";
import getExecutableExtension from "../Tools/GetExecutableExtension.js";
export default class CppBuilder implements Builder{ export default class CppBuilder implements Builder{
compile = async ()=>{ compile = async ()=>{
printDebug("compiling") printDebug("compiling")
const cppProjects = getProjectsByTypeName("cpp") as CppProject[] const cppProjects = getProjectsByTypeName("cpp") as CppProject[]
const tasks = cppProjects.map((e)=>{ const tasks:Promise<{
printDebug(`making dir ${path.join(getBuildDir(),e.name)}`) stdout: string;
fs.mkdirSync(path.join(getBuildDir(),e.name),{recursive:true}) stderr: string;
const command = `${e.compiler.compilerPath} -o ${path.join(getBuildDir(),e.name,`${e.name}.o`)} ${e.optimizeToBuildString()} ${sourceFilesToString(e)}` }>[] = []
printDebug(command) cppProjects.forEach((e)=>{
// tasks.push() e.sourceFilesPath.forEach((v)=>{
return execAsync(command) const objDir = path.join(getBuildDir(),e.name,".objs")
printDebug(`making dir ${objDir}`)
if(!fs.existsSync(objDir))fs.mkdirSync(objDir,{recursive:true});
const objPath = path.join(objDir,path.parse(v).name+".o")
e.objs.push(objPath)
const command = `${protectPath(e.compiler.compilerPath)} -c ${protectPath(v)} -o ${protectPath(objPath)} ${e.optimizeToBuildString()}`
tasks.push(execAsync(command))
printDebug(command)
})
}); });
(await Promise.all(tasks)).forEach(e=>{ (await Promise.all(tasks)).forEach(e=>{
printDebug(`stdout:${e.stdout}`) printDebug(`stdout:${e.stdout}`)
printDebug(`stderr:${e.stderr}`) if(e.stderr){printErrorOrDebug(`stderr:${e.stderr}`)}
}) })
} }
link = async()=>{ link = async()=>{
printDebug("linking")
const cppProjects = getProjectsByTypeName("cpp") as CppProject[]
const tasks:Promise<{
stdout: string;
stderr: string;
}>[] =[]
cppProjects.forEach(i=>{
const command = `${protectPath(i.compiler.compilerPath)} ${sourceFilesToString(i.objs)} -o ${path.join(getBuildDir(),i.name,`${i.name}${getExecutableExtension()}`)}`
printDebug(command)
tasks.push(execAsync(command))
})
} }
build = async () =>{ build = async () =>{
printDebug("building") printDebug("building")
await this.compile() await this.compile()
await this.link()
} }
} }

View File

@ -12,11 +12,11 @@ export default class GppCompiler implements Compiler{
constructor(path:string) constructor(path:string)
constructor(path?:string,version?:string){ constructor(path?:string,version?:string){
if(path){ if(path){
this.compilerPath = protectPath(path) this.compilerPath = path
}else{ }else{
const compilerPaths = getExecutablePathsFromEnv(this.compilerName) const compilerPaths = getExecutablePathsFromEnv(this.compilerName)
if(compilerPaths.length==0)throw Error(`cannot find ${this.compilerName} compiler`) if(compilerPaths.length==0)throw Error(`cannot find ${this.compilerName} compiler`)
this.compilerPath = protectPath(compilerPaths[0]) this.compilerPath = compilerPaths[0]
} }
if(version){ if(version){
this.compilerVersion = version this.compilerVersion = version

View File

@ -17,6 +17,7 @@ export default class CppProject implements Project , SourceFiles,HaveCompiler,Op
compiler: GppCompiler; compiler: GppCompiler;
sourceFilesPath: string[]=[]; sourceFilesPath: string[]=[];
optimize: "fast" | "fastest" | "normal" = "fast" optimize: "fast" | "fastest" | "normal" = "fast"
objs:string[]=[]
optimizeToBuildString = ():string=>{ optimizeToBuildString = ():string=>{
let ret = "" let ret = ""
switch (this.optimize) { switch (this.optimize) {
@ -40,7 +41,7 @@ export default class CppProject implements Project , SourceFiles,HaveCompiler,Op
printDebug("adding source files "+files) printDebug("adding source files "+files)
files.forEach(v=>{ files.forEach(v=>{
this.sourceFilesPath.push( this.sourceFilesPath.push(
protectPath(path.join(getNmakeDir(),v)) path.join(getNmakeDir(),v)
) )
}); });
printDebug("all files in "+this.name+" :"+this.sourceFilesPath) printDebug("all files in "+this.name+" :"+this.sourceFilesPath)

View File

@ -0,0 +1,13 @@
import os from "os"
function getExecutableExtension() {
const platform = os.platform();
if (platform === 'win32') {
return '.exe';
} else {
return ''; // Unix-like systems usually don't have a suffix for executables
}
}
export default getExecutableExtension

View File

@ -3,7 +3,7 @@ import { getNmakePath } from "./NmakePath.js"
import printDebug from "./DebugPrint.js" import printDebug from "./DebugPrint.js"
export const getNmakeDir =():string=>{ export const getNmakeDir =():string=>{
let nmakeDir = path.join(getNmakePath(),"../") let nmakeDir = path.join(process.cwd())
printDebug("getting nmake dir "+nmakeDir) printDebug("getting nmake dir "+nmakeDir)
return nmakeDir return nmakeDir
} }

View File

@ -1,10 +1,11 @@
import SourceFiles from "../Project/interface/SourceFiles.js"; import SourceFiles from "../Project/interface/SourceFiles.js";
import printDebug from "./DebugPrint.js"; import printDebug from "./DebugPrint.js";
import protectPath from "./ProtectPath.js";
const sourceFilesToString = (project:SourceFiles):string=>{ const sourceFilesToString = (project:string[]):string=>{
let ret = "" let ret = ""
project.sourceFilesPath.forEach(v=>{ project.forEach(v=>{
ret = `${ret} ${v}` ret = `${ret} ${protectPath(v)}`
}) })
printDebug(`tostring: ${ret}`) printDebug(`tostring: ${ret}`)
return ret return ret

View File

@ -9,7 +9,7 @@ import CppBuilder from "./Builder/CppBuilder.js";
import minimist from "minimist"; import minimist from "minimist";
const argv = minimist(process.argv.slice(2)) const argv = minimist(process.argv.slice(2))
let nmakeFileName = "nmake.ts" let nmakeFileName = "nmake.js"
if(argv["v"])(global as any).isDebug=true if(argv["v"])(global as any).isDebug=true
if (argv["f"]) {nmakeFileName = argv["f"];printDebug(`setting nmake file name to ${argv["f"]}`)} if (argv["f"]) {nmakeFileName = argv["f"];printDebug(`setting nmake file name to ${argv["f"]}`)}
@ -24,9 +24,9 @@ printDebug("found nmake file")
setNmakePath(nmakeFilePath) setNmakePath(nmakeFilePath)
printDebug("adding ts-node") printDebug("adding ts-node")
import ts_node from "ts-node" // import ts_node from "ts-node"
import { pathToFileURL } from "url"; import { pathToFileURL } from "url";
ts_node.register() // ts_node.register()
printDebug("adding global values") printDebug("adding global values")
@ -34,7 +34,7 @@ console.log("running nmake file "+nmakeFilePath)
printDebug(`running file ${nmakeFilePath}`) printDebug(`running file ${nmakeFilePath}`)
// require(nmakeFilePath) // require(nmakeFilePath)
import(pathToFileURL(nmakeFilePath).toString()) await import(pathToFileURL(nmakeFilePath).toString())
printDebug(`run completion!`,nmakeFilePath) printDebug(`run completion!`,nmakeFilePath)
if(argv["b"]){ if(argv["b"]){

View File

@ -1,6 +0,0 @@
import CppProject from "../../src/Project/CppProject.js";
import { addProject } from "../../src/Tools/AddProject.js";
// const compiler = new GppCompiler()
addProject(function () {
return new CppProject("hello");
});

View File

@ -4,5 +4,5 @@ import { addProject } from "../../src/Tools/AddProject.js";
// const compiler = new GppCompiler() // const compiler = new GppCompiler()
addProject(()=>{ addProject(()=>{
return new CppProject("hello") return new CppProject("hello").addFiles("main.cpp")
}) })

View File

@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */ /* Language and Environment */
"target": "ES2023", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */ // "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
@ -55,7 +55,7 @@
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */ "outDir": "./build", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */ // "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */ // "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */