From 6b2a800d37b391d70bc363fe48b37ac1b208698d Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 17 Aug 2023 19:24:49 +0800 Subject: [PATCH] - enhancement: Support SDCC Project. --- NEWS.md | 1 + RedPandaIDE/RedPandaIDE.pro | 6 +- RedPandaIDE/compiler/compilermanager.cpp | 20 +- RedPandaIDE/compiler/compilermanager.h | 4 +- RedPandaIDE/compiler/projectcompiler.cpp | 85 ++-- RedPandaIDE/compiler/projectcompiler.h | 4 +- RedPandaIDE/compiler/sdccprojectcompiler.cpp | 362 ++++++++++++++++++ RedPandaIDE/compiler/sdccprojectcompiler.h | 50 +++ RedPandaIDE/parser/cppparser.cpp | 3 + RedPandaIDE/project.cpp | 8 + RedPandaIDE/projectoptions.h | 3 +- RedPandaIDE/settings.cpp | 27 ++ .../settingsdialog/projectcompilerwidget.cpp | 28 +- .../settingsdialog/projectgeneralwidget.cpp | 8 + .../settingsdialog/projectgeneralwidget.ui | 8 +- RedPandaIDE/settingsdialog/settingsdialog.cpp | 27 +- RedPandaIDE/systemconsts.h | 1 + RedPandaIDE/widgets/newprojectdialog.cpp | 12 +- .../linux/templates/sdcc-mcs51/info.template | 18 + platform/linux/templates/sdcc-mcs51/main.c | 7 + .../templates/sdcc-mcs51/microcontroller.ico | Bin 0 -> 67646 bytes .../templates/sdcc-mcs51/info.template | 18 + platform/windows/templates/sdcc-mcs51/main.c | 7 + .../templates/sdcc-mcs51/microcontroller.ico | Bin 0 -> 67646 bytes 24 files changed, 624 insertions(+), 83 deletions(-) create mode 100644 RedPandaIDE/compiler/sdccprojectcompiler.cpp create mode 100644 RedPandaIDE/compiler/sdccprojectcompiler.h create mode 100644 platform/linux/templates/sdcc-mcs51/info.template create mode 100644 platform/linux/templates/sdcc-mcs51/main.c create mode 100644 platform/linux/templates/sdcc-mcs51/microcontroller.ico create mode 100644 platform/windows/templates/sdcc-mcs51/info.template create mode 100644 platform/windows/templates/sdcc-mcs51/main.c create mode 100644 platform/windows/templates/sdcc-mcs51/microcontroller.ico diff --git a/NEWS.md b/NEWS.md index bed26140..47803aaa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -33,6 +33,7 @@ Red Panda C++ Version 2.24 - fix: Can't suggest header filename starting with numbers. - enhancement: Better layout for compiler options page. - enhancement: False branches are displayed as comments. + - enhancement: Support SDCC Project. Red Panda C++ Version 2.23 diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index c57e629b..d9fae4bc 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -397,10 +397,12 @@ ENABLE_SDCC { DEFINES += ENABLE_SDCC SOURCES += \ - compiler/sdccfilecompiler.cpp + compiler/sdccfilecompiler.cpp \ + compiler/sdccprojectcompiler.cpp HEADERS += \ - compiler/sdccfilecompiler.h + compiler/sdccfilecompiler.h \ + compiler/sdccprojectcompiler.h } diff --git a/RedPandaIDE/compiler/compilermanager.cpp b/RedPandaIDE/compiler/compilermanager.cpp index ce4af2e4..255474fc 100644 --- a/RedPandaIDE/compiler/compilermanager.cpp +++ b/RedPandaIDE/compiler/compilermanager.cpp @@ -16,8 +16,10 @@ */ #include "compilermanager.h" #include "filecompiler.h" +#include "../project.h" #ifdef ENABLE_SDCC #include "sdccfilecompiler.h" +#include "sdccprojectcompiler.h" #endif #include "stdincompiler.h" #include "../mainwindow.h" @@ -126,7 +128,7 @@ void CompilerManager::compileProject(std::shared_ptr project, bool rebu mCompileErrorCount = 0; mCompileIssueCount = 0; //deleted when thread finished - mCompiler = new ProjectCompiler(project,false); + mCompiler = createProjectCompiler(project); mCompiler->setRebuild(rebuild); connect(mCompiler, &Compiler::finished, mCompiler, &QObject::deleteLater); connect(mCompiler, &Compiler::compileFinished, this, &CompilerManager::onCompileFinished); @@ -158,7 +160,7 @@ void CompilerManager::cleanProject(std::shared_ptr project) mCompileErrorCount = 0; mCompileIssueCount = 0; //deleted when thread finished - ProjectCompiler* compiler = new ProjectCompiler(project,false); + ProjectCompiler* compiler = createProjectCompiler(project); compiler->setOnlyClean(true); mCompiler = compiler; mCompiler->setRebuild(false); @@ -189,10 +191,10 @@ void CompilerManager::buildProjectMakefile(std::shared_ptr project) if (mCompiler!=nullptr) { return; } - ProjectCompiler compiler(project,false); - compiler.buildMakeFile(); + ProjectCompiler* pCompiler=createProjectCompiler(project); + pCompiler->buildMakeFile(); + delete pCompiler; } - } void CompilerManager::checkSyntax(const QString &filename, const QByteArray& encoding, const QString &content, std::shared_ptr project) @@ -461,6 +463,14 @@ void CompilerManager::onSyntaxCheckIssue(PCompileIssue issue) mSyntaxCheckIssueCount++; } +ProjectCompiler *CompilerManager::createProjectCompiler(std::shared_ptr project) +{ + if (project->options().type==ProjectType::MicroController) + return new SDCCProjectCompiler(project); + else + return new ProjectCompiler(project); +} + int CompilerManager::syntaxCheckIssueCount() const { return mSyntaxCheckIssueCount; diff --git a/RedPandaIDE/compiler/compilermanager.h b/RedPandaIDE/compiler/compilermanager.h index 6f1773c4..7bfb209c 100644 --- a/RedPandaIDE/compiler/compilermanager.h +++ b/RedPandaIDE/compiler/compilermanager.h @@ -25,6 +25,7 @@ class Runner; class Project; class Compiler; +class ProjectCompiler; struct OJProblem; using POJProblem = std::shared_ptr; struct OJProblemCase; @@ -85,7 +86,8 @@ private slots: void onCompileIssue(PCompileIssue issue); void onSyntaxCheckFinished(QString filename); void onSyntaxCheckIssue(PCompileIssue issue); - +private: + ProjectCompiler* createProjectCompiler(std::shared_ptr project); private: Compiler* mCompiler; int mCompileErrorCount; diff --git a/RedPandaIDE/compiler/projectcompiler.cpp b/RedPandaIDE/compiler/projectcompiler.cpp index bc43bf2e..5fa82921 100644 --- a/RedPandaIDE/compiler/projectcompiler.cpp +++ b/RedPandaIDE/compiler/projectcompiler.cpp @@ -23,8 +23,8 @@ #include -ProjectCompiler::ProjectCompiler(std::shared_ptr project, bool onlyCheckSyntax): - Compiler("",onlyCheckSyntax), +ProjectCompiler::ProjectCompiler(std::shared_ptr project): + Compiler("",false), mOnlyClean(false) { setProject(project); @@ -66,10 +66,8 @@ void ProjectCompiler::createStaticMakeFile() QFile file(mProject->makeFileName()); newMakeFile(file); writeln(file,"$(BIN): $(LINKOBJ)"); - if (!mOnlyCheckSyntax) { - writeln(file,"\tar r $(BIN) $(LINKOBJ)"); - writeln(file,"\tranlib $(BIN)"); - } + writeln(file,"\tar r $(BIN) $(LINKOBJ)"); + writeln(file,"\tranlib $(BIN)"); writeMakeObjFilesRules(file); } @@ -78,12 +76,10 @@ void ProjectCompiler::createDynamicMakeFile() QFile file(mProject->makeFileName()); newMakeFile(file); writeln(file,"$(BIN): $(LINKOBJ)"); - if (!mOnlyCheckSyntax) { - if (mProject->options().isCpp) { - writeln(file, "\t$(CPP) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); - } else { - writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); - } + if (mProject->options().isCpp) { + writeln(file, "\t$(CPP) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); + } else { + writeln(file, "\t$(CC) -mdll $(LINKOBJ) -o $(BIN) $(LIBS) -Wl,--output-def,$(DEF),--out-implib,$(STATIC)"); } writeMakeObjFilesRules(file); } @@ -136,11 +132,6 @@ void ProjectCompiler::writeMakeHeader(QFile &file) writeln(file,"# Project: " + mProject->name()); writeln(file,QString("# Makefile created by Red Panda C++ ") + REDPANDA_CPP_VERSION); writeln(file); - if (mOnlyCheckSyntax) { - writeln(file,"# This Makefile is written for syntax check!"); - writeln(file,"# Regenerate it if you want to use this Makefile to build."); - writeln(file); - } } void ProjectCompiler::writeMakeDefines(QFile &file) @@ -221,8 +212,8 @@ void ProjectCompiler::writeMakeDefines(QFile &file) log(""); // Get list of applicable flags - QString cCompileArguments = getCCompileArguments(mOnlyCheckSyntax); - QString cppCompileArguments = getCppCompileArguments(mOnlyCheckSyntax); + QString cCompileArguments = getCCompileArguments(false); + QString cppCompileArguments = getCppCompileArguments(false); QString libraryArguments = getLibraryArguments(FileType::Project); QString cIncludeArguments = getCIncludeArguments() + " " + getProjectIncludeArguments(); QString cppIncludeArguments = getCppIncludeArguments() + " " +getProjectIncludeArguments(); @@ -240,7 +231,7 @@ void ProjectCompiler::writeMakeDefines(QFile &file) #endif if (!objResFile.isEmpty()) { writeln(file,"RES = " + objResFile2); - writeln(file,"OBJ = " + Objects + " $(RES)"); + writeln(file,"OBJ = " + Objects); writeln(file,"LINKOBJ = " + LinkObjects + " " + objResFile); #ifdef Q_OS_WIN writeln(file,"CLEANOBJ = " + cleanObjects + @@ -314,10 +305,7 @@ void ProjectCompiler::writeMakeDefines(QFile &file) void ProjectCompiler::writeMakeTarget(QFile &file) { - if (mOnlyCheckSyntax) - writeln(file, ".PHONY: all all-before all-after clean clean-custom $(OBJ) $(BIN)"); - else - writeln(file, ".PHONY: all all-before all-after clean clean-custom"); + writeln(file, ".PHONY: all all-before all-after clean clean-custom"); writeln(file); writeln(file, "all: all-before $(BIN) all-after"); writeln(file); @@ -468,21 +456,12 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) } if (fileType==FileType::CSource || fileType==FileType::CppSource) { - if (mOnlyCheckSyntax) { - if (unit->compileCpp()) - writeln(file, "\t$(CPP) -c " + genMakePath1(shortFileName) + " $(CXXFLAGS) " + encodingStr); - else - writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " $(CFLAGS) " + encodingStr); - } else { - if (unit->compileCpp()) - writeln(file, "\t$(CPP) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CXXFLAGS) " + encodingStr); - else - writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CFLAGS) " + encodingStr); - } - } else if (fileType==FileType::GAS) { - if (!mOnlyCheckSyntax) { + if (unit->compileCpp()) + writeln(file, "\t$(CPP) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CXXFLAGS) " + encodingStr); + else writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CFLAGS) " + encodingStr); - } + } else if (fileType==FileType::GAS) { + writeln(file, "\t$(CC) -c " + genMakePath1(shortFileName) + " -o " + objFileName2 + " $(CFLAGS) " + encodingStr); } } } @@ -499,17 +478,15 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) QString resFiles; // Concatenate all resource filenames (not created when syntax checking) - if (!mOnlyCheckSyntax) { - foreach(const PProjectUnit& unit, mProject->unitList()) { - if (getFileType(unit->fileName())!=FileType::WindowsResourceSource) - continue; - if (fileExists(unit->fileName())) { - QString ResFile = extractRelativePath(mProject->makeFileName(), unit->fileName()); - resFiles = resFiles + genMakePath2(ResFile) + ' '; - } + foreach(const PProjectUnit& unit, mProject->unitList()) { + if (getFileType(unit->fileName())!=FileType::WindowsResourceSource) + continue; + if (fileExists(unit->fileName())) { + QString ResFile = extractRelativePath(mProject->makeFileName(), unit->fileName()); + resFiles = resFiles + genMakePath2(ResFile) + ' '; } - resFiles = resFiles.trimmed(); } + resFiles = resFiles.trimmed(); // Determine resource output file QString fullName; @@ -530,16 +507,10 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file) if (mProject->getCompileOption(CC_CMD_OPT_POINTER_SIZE)=="32") windresArgs = " -F pe-i386"; - if (mOnlyCheckSyntax) { - writeln(file); - writeln(file, objFileName2 + ':'); - writeln(file, "\t$(WINDRES) -i " + privResName + windresArgs + " --input-format=rc -o nul -O coff $(WINDRESFLAGS)" + ResIncludes); - } else { - writeln(file); - writeln(file, objFileName2 + ": " + privResName2 + ' ' + resFiles); - writeln(file, "\t$(WINDRES) -i " + privResName + windresArgs + " --input-format=rc -o " + objFileName + " -O coff $(WINDRESFLAGS)" - + ResIncludes); - } + writeln(file); + writeln(file, objFileName2 + ": " + privResName2 + ' ' + resFiles); + writeln(file, "\t$(WINDRES) -i " + privResName + windresArgs + " --input-format=rc -o " + objFileName + " -O coff $(WINDRESFLAGS)" + + ResIncludes); writeln(file); } #endif diff --git a/RedPandaIDE/compiler/projectcompiler.h b/RedPandaIDE/compiler/projectcompiler.h index 20406c32..552f76fc 100644 --- a/RedPandaIDE/compiler/projectcompiler.h +++ b/RedPandaIDE/compiler/projectcompiler.h @@ -26,10 +26,10 @@ class ProjectCompiler : public Compiler { Q_OBJECT public: - ProjectCompiler(std::shared_ptr project, bool onlyCheckSyntax); + ProjectCompiler(std::shared_ptr project); ProjectCompiler(const ProjectCompiler&)=delete; ProjectCompiler& operator=(const ProjectCompiler&)=delete; - void buildMakeFile(); + virtual void buildMakeFile(); bool onlyClean() const; void setOnlyClean(bool newOnlyClean); diff --git a/RedPandaIDE/compiler/sdccprojectcompiler.cpp b/RedPandaIDE/compiler/sdccprojectcompiler.cpp new file mode 100644 index 00000000..e360985e --- /dev/null +++ b/RedPandaIDE/compiler/sdccprojectcompiler.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "sdccprojectcompiler.h" +#include "../project.h" +#include "compilermanager.h" +#include "../systemconsts.h" + +#include + +SDCCProjectCompiler::SDCCProjectCompiler(std::shared_ptr project): + ProjectCompiler(project) +{ +} + +void SDCCProjectCompiler::buildMakeFile() +{ + //we are using custom make file, don't overwrite it + if (mProject->options().useCustomMakefile && !mProject->options().customMakefile.isEmpty()) + return; + createStandardMakeFile(); +} + +void SDCCProjectCompiler::createStandardMakeFile() +{ + QFile file(mProject->makeFileName()); + newMakeFile(file); + QString suffix = compilerSet()->executableSuffix(); + if (suffix == SDCC_IHX_SUFFIX) { + writeln(file,"$(BIN): $(OBJ)"); + writeln(file,"\t$(CC) $(LIBS) -o $(BIN) $(LINKOBJ)"); + } else { + writeln(file,"$(IHX): $(OBJ)\n"); + writeln(file,"\t$(CC) $(LIBS) -o $(IHX) $(LINKOBJ)"); + if (suffix == SDCC_HEX_SUFFIX) { + writeln(file,"$(BIN): $(IHX)"); + writeln(file,"\t$(PACKIHX) $(IHX) > $(BIN)"); + } else { + writeln(file,"$(BIN): $(IHX)"); + writeln(file,"\t$(MAKEBIN) $(IHX) $(BIN)"); + } + } + writeMakeObjFilesRules(file); +} + +void SDCCProjectCompiler::newMakeFile(QFile& file) +{ + // Create OBJ output directory + if (!mProject->options().objectOutput.isEmpty()) { + QDir(mProject->directory()).mkpath(mProject->options().objectOutput); + } + // Create executable output directory + if (!mProject->options().exeOutput.isEmpty()) { + QDir(mProject->directory()).mkpath(mProject->options().exeOutput); + } + // Write more information to the log file than before + log(tr("Building makefile...")); + log("--------"); + log(tr("- Filename: %1").arg(mProject->makeFileName())); + + // Create the actual file + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + throw CompileError(tr("Can't open '%1' for write!").arg(mProject->makeFileName())); + + // Write header + writeMakeHeader(file); + + // Writes definition list + writeMakeDefines(file); + + // Write PHONY and all targets + writeMakeTarget(file); + + // Write list of includes + writeMakeIncludes(file); + + // Write clean command + writeMakeClean(file); + +} + +void SDCCProjectCompiler::writeMakeHeader(QFile &file) +{ + writeln(file,"# Project: " + mProject->name()); + writeln(file,QString("# Makefile created by Red Panda C++ ") + REDPANDA_CPP_VERSION); + writeln(file); +} + +void SDCCProjectCompiler::writeMakeDefines(QFile &file) +{ + // Get list of object files + QString Objects; + QString LinkObjects; + QString cleanObjects; + + // Create a list of object files + foreach(const PProjectUnit &unit, mProject->unitList()) { + if (!unit->compile() && !unit->link()) + continue; + + // Only process source files + QString RelativeName = extractRelativePath(mProject->directory(), unit->fileName()); + FileType fileType = getFileType(RelativeName); + + if (fileType == FileType::CSource || fileType == FileType::CppSource + || fileType==FileType::GAS) { + if (!mProject->options().objectOutput.isEmpty()) { + // ofile = C:\MyProgram\obj\main.o + QString fullObjFile = includeTrailingPathDelimiter(mProject->options().objectOutput) + + extractFileName(unit->fileName()); + QString relativeObjFile = extractRelativePath(mProject->directory(), changeFileExt(fullObjFile, SDCC_REL_SUFFIX)); + QString objFile = genMakePath2(relativeObjFile); + Objects += ' ' + objFile; +#ifdef Q_OS_WIN + cleanObjects += ' ' + genMakePath1(relativeObjFile).replace("/",QDir::separator()); +#else + cleanObjects += ' ' + genMakePath1(relativeObjFile); +#endif + if (unit->link()) { + LinkObjects += ' ' + genMakePath1(relativeObjFile); + } + } else { + Objects += ' ' + genMakePath2(changeFileExt(RelativeName, SDCC_REL_SUFFIX)); +#ifdef Q_OS_WIN + cleanObjects += ' ' + genMakePath1(changeFileExt(RelativeName, SDCC_REL_SUFFIX)).replace("/",QDir::separator()); +#else + cleanObjects += ' ' + genMakePath1(changeFileExt(RelativeName, SDCC_REL_SUFFIX)); +#endif + if (unit->link()) + LinkObjects = LinkObjects + ' ' + genMakePath1(changeFileExt(RelativeName, SDCC_REL_SUFFIX)); + } + } + } + + Objects = Objects.trimmed(); + LinkObjects = LinkObjects.trimmed(); + + + // Get list of applicable flags + QString cCompileArguments = getCCompileArguments(mOnlyCheckSyntax); + QString libraryArguments = getLibraryArguments(FileType::Project); + QString cIncludeArguments = getCIncludeArguments() + " " + getProjectIncludeArguments(); + + if (cCompileArguments.indexOf(" -g3")>=0 + || cCompileArguments.startsWith("-g3")) { + cCompileArguments += " -D__DEBUG__"; + } + + writeln(file,"CC = " + extractFileName(compilerSet()->CCompiler())); + writeln(file,QString("PACKIHX = ") + PACKIHX_PROGRAM); + writeln(file,QString("MAKEBIN = ") + MAKEBIN_PROGRAM); + + writeln(file,"OBJ = " + Objects); + writeln(file,"LINKOBJ = " + LinkObjects); +#ifdef Q_OS_WIN + writeln(file,"CLEANOBJ = " + cleanObjects + + + " " + genMakePath1(extractRelativePath(mProject->makeFileName(), changeFileExt(mProject->executable(),SDCC_IHX_SUFFIX))).replace("/",QDir::separator()) + + " " + genMakePath1(extractRelativePath(mProject->makeFileName(), mProject->executable())).replace("/",QDir::separator()) ); +#else + writeln(file,"CLEANOBJ = " + cleanObjects + + + " " + genMakePath1(extractRelativePath(mProject->makeFileName(), mProject->executable()))); +#endif + libraryArguments.replace('\\', '/'); + writeln(file,"LIBS = " + libraryArguments); + cIncludeArguments.replace('\\', '/'); + writeln(file,"INCS = " + cIncludeArguments); + writeln(file,"IHX = " + genMakePath1(extractRelativePath(mProject->makeFileName(), changeFileExt(mProject->executable(), SDCC_IHX_SUFFIX)))); + writeln(file,"BIN = " + genMakePath1(extractRelativePath(mProject->makeFileName(), mProject->executable()))); + //writeln(file,"ENCODINGS = -finput-charset=utf-8 -fexec-charset='+GetSystemCharsetName); + cCompileArguments.replace('\\', '/'); + writeln(file,"CFLAGS = $(INCS) " + cCompileArguments); + writeln(file, QString("RM = ") + CLEAN_PROGRAM ); + + writeln(file); +} + +void SDCCProjectCompiler::writeMakeTarget(QFile &file) +{ + writeln(file, ".PHONY: all all-before all-after clean clean-custom"); + writeln(file); + writeln(file, "all: all-before $(BIN) all-after"); + writeln(file); + +} + +void SDCCProjectCompiler::writeMakeIncludes(QFile &file) +{ + foreach(const QString& s, mProject->options().makeIncludes) { + writeln(file, "include " + genMakePath1(s)); + } + if (!mProject->options().makeIncludes.isEmpty()) { + writeln(file); + } +} + +void SDCCProjectCompiler::writeMakeClean(QFile &file) +{ + writeln(file, "clean: clean-custom"); + QString target="$(CLEANOBJ)"; + + writeln(file, QString("\t-$(RM) %1 > %2 2>&1").arg(target,NULL_FILE)); + writeln(file); +} + +void SDCCProjectCompiler::writeMakeObjFilesRules(QFile &file) +{ + PCppParser parser = mProject->cppParser(); + QString precompileStr; + + QList projectUnits=mProject->unitList(); + foreach(const PProjectUnit &unit, projectUnits) { + if (!unit->compile()) + continue; + FileType fileType = getFileType(unit->fileName()); + // Only process source files + if (fileType!=FileType::CSource && fileType!=FileType::CppSource + && fileType!=FileType::GAS) + continue; + + QString shortFileName = extractRelativePath(mProject->makeFileName(),unit->fileName()); + + writeln(file); + QString objStr=genMakePath2(shortFileName); + // if we have scanned it, use scanned info + if (parser && parser->scannedFiles().contains(unit->fileName())) { + QSet fileIncludes = parser->getFileIncludes(unit->fileName()); + foreach(const PProjectUnit &unit2, projectUnits) { + if (unit2==unit) + continue; + if (fileIncludes.contains(unit2->fileName())) { + objStr = objStr + ' ' + genMakePath2(extractRelativePath(mProject->makeFileName(),unit2->fileName())); + } + } + } else { + foreach(const PProjectUnit &unit2, projectUnits) { + FileType fileType = getFileType(unit2->fileName()); + if (fileType == FileType::CHeader || fileType==FileType::CppHeader) + objStr = objStr + ' ' + genMakePath2(extractRelativePath(mProject->makeFileName(),unit2->fileName())); + } + } + QString objFileName; + QString objFileName2; + if (!mProject->options().objectOutput.isEmpty()) { + QString fullObjname = includeTrailingPathDelimiter(mProject->options().objectOutput) + + extractFileName(unit->fileName()); + objFileName = genMakePath2(extractRelativePath(mProject->makeFileName(), changeFileExt(fullObjname, SDCC_REL_SUFFIX))); + objFileName2 = genMakePath1(extractRelativePath(mProject->makeFileName(), changeFileExt(fullObjname, SDCC_REL_SUFFIX))); +// if (!extractFileDir(ObjFileName).isEmpty()) { +// objStr = genMakePath2(includeTrailingPathDelimiter(extractFileDir(ObjFileName))) + objStr; +// } + } else { + objFileName = genMakePath2(changeFileExt(shortFileName, SDCC_REL_SUFFIX)); + objFileName2 = genMakePath1(changeFileExt(shortFileName, SDCC_REL_SUFFIX)); + } + + objStr = objFileName + ": "+objStr+precompileStr; + + writeln(file,objStr); + + // Write custom build command + if (unit->overrideBuildCmd() && !unit->buildCmd().isEmpty()) { + QString BuildCmd = unit->buildCmd(); + BuildCmd.replace("", "\n\t"); + writeln(file, '\t' + BuildCmd); + // Or roll our own + } else { + if (fileType==FileType::CSource) { + writeln(file, "\t$(CC) $(CFLAGS) -c " + genMakePath1(shortFileName)); + } + } + } + +} + +void SDCCProjectCompiler::writeln(QFile &file, const QString &s) +{ + if (!s.isEmpty()) + file.write(s.toLocal8Bit()); + file.write("\n"); +} + +bool SDCCProjectCompiler::prepareForRebuild() +{ + //we use make argument to clean + return true; +} + +bool SDCCProjectCompiler::prepareForCompile() +{ + if (!mProject) + return false; + //initProgressForm(); + log(tr("Compiling project changes...")); + log("--------"); + log(tr("- Project Filename: %1").arg(mProject->filename())); + log(tr("- Compiler Set Name: %1").arg(compilerSet()->name())); + log(""); + + buildMakeFile(); + + mCompiler = compilerSet()->make(); + + if (!fileExists(mCompiler)) { + throw CompileError( + tr("Make program '%1' doesn't exists!").arg(mCompiler) + +"
" + +tr("Please check the \"program\" page of compiler settings.")); + } + + QString parallelParam; + if (mProject->options().allowParallelBuilding) { + if (mProject->options().parellelBuildingJobs==0) { + parallelParam = " --jobs"; + } else { + parallelParam = QString(" -j%1").arg(mProject->options().parellelBuildingJobs); + } + } + + if (onlyClean()) { + mArguments = QString(" %1 -f \"%2\" clean").arg(parallelParam, + extractRelativePath( + mProject->directory(), + mProject->makeFileName())); + } else if (mRebuild) { + mArguments = QString(" -f \"%1\" clean").arg(extractRelativePath( + mProject->directory(), + mProject->makeFileName())); + mExtraCompilersList.append(mCompiler); + mExtraOutputFilesList.append(""); + mExtraArgumentsList.append(QString(" %1 -f \"%2\" all").arg(parallelParam, + extractRelativePath( + mProject->directory(), + mProject->makeFileName()))); + } else { + mArguments = QString(" %1 -f \"%2\" all").arg(parallelParam, + extractRelativePath( + mProject->directory(), + mProject->makeFileName())); + } + mDirectory = mProject->directory(); + + log(tr("Processing makefile:")); + log("--------"); + log(tr("- makefile processer: %1").arg(mCompiler)); + log(tr("- Command: %1 %2").arg(extractFileName(mCompiler)).arg(mArguments)); + log(""); + + return true; +} diff --git a/RedPandaIDE/compiler/sdccprojectcompiler.h b/RedPandaIDE/compiler/sdccprojectcompiler.h new file mode 100644 index 00000000..550e5e1a --- /dev/null +++ b/RedPandaIDE/compiler/sdccprojectcompiler.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef SDCCPROJECTCOMPILER_H +#define SDCCPROJECTCOMPILER_H + +#include "projectcompiler.h" +#include +#include + +class Project; +class SDCCProjectCompiler : public ProjectCompiler +{ + Q_OBJECT +public: + SDCCProjectCompiler(std::shared_ptr project); + SDCCProjectCompiler(const SDCCProjectCompiler&)=delete; + SDCCProjectCompiler& operator=(const SDCCProjectCompiler&)=delete; + void buildMakeFile(); + +private: + void createStandardMakeFile(); + void newMakeFile(QFile& file); + void writeMakeHeader(QFile& file); + void writeMakeDefines(QFile& file); + void writeMakeTarget(QFile& file); + void writeMakeIncludes(QFile& file); + void writeMakeClean(QFile& file); + void writeMakeObjFilesRules(QFile& file); + void writeln(QFile& file, const QString& s=""); + // Compiler interface +protected: + bool prepareForCompile() override; + bool prepareForRebuild() override; +}; + +#endif // PROJECTCOMPILER_H diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index fe0203c6..ef96dba7 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -855,6 +855,9 @@ QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &h bool CppParser::isLineVisible(const QString &fileName, int line) { QMutexLocker locker(&mMutex); + if (mParsing) { + return true; + } PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName); if (!fileIncludes) return true; diff --git a/RedPandaIDE/project.cpp b/RedPandaIDE/project.cpp index f3d938ee..3fa5190c 100644 --- a/RedPandaIDE/project.cpp +++ b/RedPandaIDE/project.cpp @@ -130,6 +130,14 @@ QString Project::executable() const exeFileName = mOptions.overridenOutput; } else { switch(mOptions.type) { + case ProjectType::MicroController: { + Settings::PCompilerSet pSet=pSettings->compilerSets().getSet(mOptions.compilerSet); + if (pSet) + exeFileName = changeFileExt(extractFileName(mFilename),pSet->executableSuffix()); + else + exeFileName = changeFileExt(extractFileName(mFilename),SDCC_HEX_SUFFIX); + } + break; case ProjectType::StaticLib: exeFileName = changeFileExt(extractFileName(mFilename),STATIC_LIB_EXT); if (!exeFileName.startsWith("lib")) diff --git a/RedPandaIDE/projectoptions.h b/RedPandaIDE/projectoptions.h index d18ed671..b71a468a 100644 --- a/RedPandaIDE/projectoptions.h +++ b/RedPandaIDE/projectoptions.h @@ -35,7 +35,8 @@ enum class ProjectType { GUI=0, Console=1, StaticLib=2, - DynamicLib=3 + DynamicLib=3, + MicroController=4 }; struct ProjectVersionInfo{ diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index d68a1443..3177e82e 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -2456,7 +2456,34 @@ void Settings::CompilerSet::setExecutables() mDebugServer = findProgramInBinDirs(GDB_SERVER_PROGRAM); } mMake = findProgramInBinDirs(MAKE_PROGRAM); +#ifdef Q_OS_WIN mResourceCompiler = findProgramInBinDirs(WINDRES_PROGRAM); + if (mMake.isEmpty()) { + mMake = findProgramInBinDirs(MAKE2_PROGRAM); + } + if (mMake.isEmpty()) { + QSet searched; + + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString path = env.value("PATH"); + QStringList pathList = path.split(PATH_SEPARATOR); + QString folder; + for (int i=pathList.count()-1;i>=0;i--) { + folder = pathList[i]; + if (searched.contains(folder)) + continue; + searched.insert(folder); + QDir dir(folder); + if (dir.exists(MAKE_PROGRAM)) { + mMake = dir.absoluteFilePath(MAKE_PROGRAM); + break; + } else if (dir.exists(MAKE2_PROGRAM)) { + mMake = dir.absoluteFilePath(MAKE2_PROGRAM); + break; + } + } + } +#endif } void Settings::CompilerSet::setDirectories(const QString& binDir) diff --git a/RedPandaIDE/settingsdialog/projectcompilerwidget.cpp b/RedPandaIDE/settingsdialog/projectcompilerwidget.cpp index 243b67ab..e4f7646b 100644 --- a/RedPandaIDE/settingsdialog/projectcompilerwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectcompilerwidget.cpp @@ -127,12 +127,34 @@ void ProjectCompilerWidget::on_cbCompilerSet_currentIndexChanged(int index) if (!mInitialized || index==project->options().compilerSet) { return; } + Settings::PCompilerSet pSet=pSettings->compilerSets().getSet(index); + if (pSet) { + if (project->options().type==ProjectType::MicroController) { + if (pSet->compilerType()!=CompilerType::SDCC) { + QMessageBox::information(this, + tr("Wrong Compiler Type"), + tr("Compiler %1 can't compile a microcontroller project.").arg(pSet->name()) + ); + ui->cbCompilerSet->setCurrentIndex(project->options().compilerSet); + return; + } + } else { + if (pSet->compilerType()==CompilerType::SDCC) { + QMessageBox::information(this, + tr("Wrong Compiler Type"), + tr("Compiler %1 can only compile microcontroller project.").arg(pSet->name()) + ); + ui->cbCompilerSet->setCurrentIndex(project->options().compilerSet); + return; + } + } + } if (QMessageBox::warning( this, - MainWindow::tr("Change Project Compiler Set"), - MainWindow::tr("Change the project's compiler set will lose all custom compiler set options.") + tr("Change Project Compiler Set"), + tr("Change the project's compiler set will lose all custom compiler set options.") +"
" - + MainWindow::tr("Do you really want to do that?"), + + tr("Do you really want to do that?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) { ui->cbCompilerSet->setCurrentIndex(project->options().compilerSet); diff --git a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp index 8a8b4986..2f48cf1e 100644 --- a/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp +++ b/RedPandaIDE/settingsdialog/projectgeneralwidget.cpp @@ -53,6 +53,14 @@ void ProjectGeneralWidget::doLoad() std::shared_ptr project = pMainWindow->project(); if (!project) return; + + bool isMicroControllerProject=(project->options().type==ProjectType::MicroController); + + ui->grpType->setVisible(!isMicroControllerProject); + ui->grpIcon->setVisible(!isMicroControllerProject); + ui->lblEncoding->setVisible(!isMicroControllerProject); + ui->panelEncoding->setVisible(!isMicroControllerProject); + ui->txtName->setText(project->name()); ui->txtFileName->setText(project->filename()); ui->txtOutputFile->setText(project->executable()); diff --git a/RedPandaIDE/settingsdialog/projectgeneralwidget.ui b/RedPandaIDE/settingsdialog/projectgeneralwidget.ui index 7a2d223b..bd4a35ed 100644 --- a/RedPandaIDE/settingsdialog/projectgeneralwidget.ui +++ b/RedPandaIDE/settingsdialog/projectgeneralwidget.ui @@ -60,7 +60,7 @@ - + Default encoding: @@ -70,7 +70,7 @@ - + 0 @@ -172,7 +172,7 @@ - + Type @@ -279,7 +279,7 @@ - + 0 diff --git a/RedPandaIDE/settingsdialog/settingsdialog.cpp b/RedPandaIDE/settingsdialog/settingsdialog.cpp index 5c3c8132..08b8bdd2 100644 --- a/RedPandaIDE/settingsdialog/settingsdialog.cpp +++ b/RedPandaIDE/settingsdialog/settingsdialog.cpp @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include "../mainwindow.h" #include "settingsdialog.h" #include "ui_settingsdialog.h" #include "settingswidget.h" @@ -40,7 +41,6 @@ #include "debuggeneralwidget.h" #include "formattergeneralwidget.h" #include "languageasmgenerationwidget.h" -#include "languagecformatwidget.h" #include "projectgeneralwidget.h" #include "projectfileswidget.h" #include "projectcompilerwidget.h" @@ -252,6 +252,13 @@ PSettingsDialog SettingsDialog::projectOptionDialog() { PSettingsDialog dialog = std::make_shared(); + + bool isMicroControllerProject=false; + std::shared_ptr project = pMainWindow->project(); + if (project) + isMicroControllerProject=(project->options().type==ProjectType::MicroController); + + dialog->setWindowTitle(tr("Project Options")); SettingsWidget* widget = new ProjectGeneralWidget(tr("General"),tr("Project")); @@ -269,8 +276,10 @@ PSettingsDialog SettingsDialog::projectOptionDialog() widget = new ProjectDirectoriesWidget(tr("Directories"),tr("Project")); dialog->addWidget(widget); - widget = new ProjectPreCompileWidget(tr("Precompiled Header"),tr("Project")); - dialog->addWidget(widget); + if (!isMicroControllerProject) { + widget = new ProjectPreCompileWidget(tr("Precompiled Header"),tr("Project")); + dialog->addWidget(widget); + } widget = new ProjectMakefileWidget(tr("Makefile"),tr("Project")); dialog->addWidget(widget); @@ -278,12 +287,16 @@ PSettingsDialog SettingsDialog::projectOptionDialog() widget = new ProjectOutputWidget(tr("Output"),tr("Project")); dialog->addWidget(widget); - widget = new ProjectDLLHostWidget(tr("DLL host"),tr("Project")); - dialog->addWidget(widget); + if (!isMicroControllerProject) { + widget = new ProjectDLLHostWidget(tr("DLL host"),tr("Project")); + dialog->addWidget(widget); + } #ifdef Q_OS_WIN - widget = new ProjectVersionInfoWidget(tr("Version info"),tr("Project")); - dialog->addWidget(widget); + if (!isMicroControllerProject) { + widget = new ProjectVersionInfoWidget(tr("Version info"),tr("Project")); + dialog->addWidget(widget); + } #endif dialog->selectFirstWidget(); diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h index 26df5b62..c2267554 100644 --- a/RedPandaIDE/systemconsts.h +++ b/RedPandaIDE/systemconsts.h @@ -40,6 +40,7 @@ #define SDCC_PROGRAM "sdcc.exe" #define PACKIHX_PROGRAM "packihx.exe" #define MAKEBIN_PROGRAM "makebin.exe" +#define MAKE2_PROGRAM "make.exe" #elif defined(Q_OS_LINUX) #define CONSOLE_PAUSER "consolepauser" #define ASSEMBLER "nasm" diff --git a/RedPandaIDE/widgets/newprojectdialog.cpp b/RedPandaIDE/widgets/newprojectdialog.cpp index 52caa826..10364414 100644 --- a/RedPandaIDE/widgets/newprojectdialog.cpp +++ b/RedPandaIDE/widgets/newprojectdialog.cpp @@ -121,7 +121,17 @@ void NewProjectDialog::addTemplate(const QString &filename) return; PProjectTemplate t = std::make_shared(); t->readTemplateFile(filename); - mTemplates.append(t); + Settings::PCompilerSet pSet=pSettings->compilerSets().defaultSet(); + if (pSet) { + if (pSet->compilerType()==CompilerType::SDCC) { + if (t->options().type==ProjectType::MicroController) + mTemplates.append(t); + } else { + if (t->options().type!=ProjectType::MicroController) + mTemplates.append(t); + } + } else + mTemplates.append(t); } void NewProjectDialog::readTemplateDirs() diff --git a/platform/linux/templates/sdcc-mcs51/info.template b/platform/linux/templates/sdcc-mcs51/info.template new file mode 100644 index 00000000..638d521c --- /dev/null +++ b/platform/linux/templates/sdcc-mcs51/info.template @@ -0,0 +1,18 @@ +[Template] +ver=2 +Name=MCS51 +Name[zh_CN]=MCS51 +Icon=microcontroller.ico +Description=A simple MCS51 program +Description[zh_CN]=MCS51单片机程序 +Category=SDCC +Category[zh_CN]=SDCC + +[Unit0] +CName=main.c +C=main.c + +[Project] +UnitCount=1 +Type=4 +IsCpp=0 diff --git a/platform/linux/templates/sdcc-mcs51/main.c b/platform/linux/templates/sdcc-mcs51/main.c new file mode 100644 index 00000000..2ddb35dd --- /dev/null +++ b/platform/linux/templates/sdcc-mcs51/main.c @@ -0,0 +1,7 @@ +#include <8051.h> + +void main(void) { + for(;;) { + P1--; + } +} \ No newline at end of file diff --git a/platform/linux/templates/sdcc-mcs51/microcontroller.ico b/platform/linux/templates/sdcc-mcs51/microcontroller.ico new file mode 100644 index 0000000000000000000000000000000000000000..9bda4643899647e9b0e0c1d2af70e05b86b77ec9 GIT binary patch literal 67646 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 CP`2*? literal 0 HcmV?d00001 diff --git a/platform/windows/templates/sdcc-mcs51/info.template b/platform/windows/templates/sdcc-mcs51/info.template new file mode 100644 index 00000000..638d521c --- /dev/null +++ b/platform/windows/templates/sdcc-mcs51/info.template @@ -0,0 +1,18 @@ +[Template] +ver=2 +Name=MCS51 +Name[zh_CN]=MCS51 +Icon=microcontroller.ico +Description=A simple MCS51 program +Description[zh_CN]=MCS51单片机程序 +Category=SDCC +Category[zh_CN]=SDCC + +[Unit0] +CName=main.c +C=main.c + +[Project] +UnitCount=1 +Type=4 +IsCpp=0 diff --git a/platform/windows/templates/sdcc-mcs51/main.c b/platform/windows/templates/sdcc-mcs51/main.c new file mode 100644 index 00000000..2ddb35dd --- /dev/null +++ b/platform/windows/templates/sdcc-mcs51/main.c @@ -0,0 +1,7 @@ +#include <8051.h> + +void main(void) { + for(;;) { + P1--; + } +} \ No newline at end of file diff --git a/platform/windows/templates/sdcc-mcs51/microcontroller.ico b/platform/windows/templates/sdcc-mcs51/microcontroller.ico new file mode 100644 index 0000000000000000000000000000000000000000..9bda4643899647e9b0e0c1d2af70e05b86b77ec9 GIT binary patch literal 67646 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 CP`2*? literal 0 HcmV?d00001