- enhancement: Support compile asm files using nasm in the project.

This commit is contained in:
Roy Qu 2023-02-08 21:07:41 +08:00
parent 62737d6716
commit 78ff319a75
11 changed files with 196 additions and 92 deletions

View File

@ -12,6 +12,7 @@ Red Panda C++ Version 2.11
- enhancement: Auto reload openned project files that use "Project Default" as the encoding, when the project encoding setting is changed in the project options dialog.
- fix: Correctly handle files whose name contains spaces in the generated makefile.
- fix: Correctly handle custom obj folder in the generated makefile.
- enhancement: Support compile asm files using nasm in the project.
Red Panda C++ Version 2.10

View File

@ -156,7 +156,11 @@ void ProjectCompiler::writeMakeDefines(QFile &file)
// Only process source files
QString RelativeName = extractRelativePath(mProject->directory(), unit->fileName());
FileType fileType = getFileType(RelativeName);
if (fileType == FileType::CSource || fileType == FileType::CppSource) {
if (fileType==FileType::ASM && !compilerSet()->canAssemble())
continue;
if (fileType == FileType::CSource || fileType == FileType::CppSource
|| fileType == FileType::ASM) {
if (!mProject->options().objectOutput.isEmpty()) {
// ofile = C:\MyProgram\obj\main.o
QString fullObjFile = includeTrailingPathDelimiter(mProject->options().objectOutput)
@ -201,11 +205,11 @@ void ProjectCompiler::writeMakeDefines(QFile &file)
QString relativeResFile = extractRelativePath(mProject->directory(), fullResFile);
objResFile = genMakePath1(relativeResFile);
objResFile2 = genMakePath2(relativeResFile);
cleanRes += ' ' + genMakePath1(changeFileExt(relativeResFile, OBJ_EXT)).replace("/",QDir::separator());
cleanRes += ' ' + genMakePath1(changeFileExt(relativeResFile, RES_EXT)).replace("/",QDir::separator());
} else {
objResFile = genMakePath1(changeFileExt(mProject->options().privateResource, RES_EXT));
objResFile2 = genMakePath2(changeFileExt(mProject->options().privateResource, RES_EXT));
cleanRes += ' ' + genMakePath1(changeFileExt(mProject->options().privateResource, OBJ_EXT)).replace("/",QDir::separator());
cleanRes += ' ' + genMakePath1(changeFileExt(mProject->options().privateResource, RES_EXT)).replace("/",QDir::separator());
}
}
#endif
@ -229,6 +233,8 @@ void ProjectCompiler::writeMakeDefines(QFile &file)
cppCompileArguments+= " -D__DEBUG__";
}
if (compilerSet()->canAssemble())
writeln(file,"ASM = " + extractFileName(compilerSet()->assembler()));
writeln(file,"CPP = " + extractFileName(compilerSet()->cppCompiler()));
writeln(file,"CC = " + extractFileName(compilerSet()->CCompiler()));
#ifdef Q_OS_WIN
@ -279,7 +285,21 @@ void ProjectCompiler::writeMakeDefines(QFile &file)
#ifdef Q_OS_WIN
writeln(file,"WINDRESFLAGS = " + mProject->options().resourceCmd);
#endif
#ifdef Q_OS_WIN
if (compilerSet()->canAssemble() &&
Settings::CompilerSets::isTarget64Bit(compilerSet()->target())) {
if (mProject->getCompileOption(CC_CMD_OPT_POINTER_SIZE)=="32")
writeln(file,"ASMFLAGS = -f win32");
else
writeln(file,"ASMFLAGS = -f win64");
} else {
writeln(file,"ASMFLAGS = -f win32");
}
#elif defined(Q_OS_LINUX)
writeln(file,"ASMFLAGS = -f elf64");
#elif defined(Q_OS_MACOS)
writeln(file,"ASMFLAGS = -f macho64");
#endif
// This needs to be put in before the clean command.
if (mProject->options().type == ProjectType::DynamicLib) {
@ -354,9 +374,12 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
QList<PProjectUnit> 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)
if (fileType!=FileType::CSource && fileType!=FileType::CppSource
&& fileType!=FileType::ASM)
continue;
QString shortFileName = extractRelativePath(mProject->makeFileName(),unit->fileName());
@ -459,16 +482,22 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
}
}
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);
if (fileType==FileType::CppSource || 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::ASM) {
if (!mOnlyCheckSyntax) {
writeln(file, "\t$(ASM) $(ASMFLAGS) " + genMakePath1(shortFileName) + " -o " + objFileName2);
}
}
}
}

View File

@ -1261,6 +1261,11 @@ PProjectUnit Project::internalAddUnit(const QString &inFileName, PProjectModelNo
// Determine compilation flags
switch(getFileType(inFileName)) {
case FileType::ASM:
newUnit->setCompile(true);
newUnit->setCompileCpp(false);
newUnit->setLink(true);
break;
case FileType::CSource:
newUnit->setCompile(true);
newUnit->setCompileCpp(false);

View File

@ -1692,6 +1692,7 @@ Settings::CompilerSet::CompilerSet(const Settings::CompilerSet &set):
mProfiler(set.mProfiler),
mResourceCompiler(set.mResourceCompiler),
mDebugServer(set.mDebugServer),
mAssembler(set.assembler()),
mBinDirs(set.mBinDirs),
mCIncludeDirs(set.mCIncludeDirs),
@ -2329,6 +2330,7 @@ void Settings::CompilerSet::setExecutables()
mMake = findProgramInBinDirs(MAKE_PROGRAM);
mResourceCompiler = findProgramInBinDirs(WINDRES_PROGRAM);
mProfiler = findProgramInBinDirs(GPROF_PROGRAM);
mAssembler = findProgramInBinDirs(ASSEMBLER);
}
void Settings::CompilerSet::setDirectories(const QString& binDir,CompilerType compilerType)
@ -2506,6 +2508,11 @@ bool Settings::CompilerSet::canDebug()
return fileExists(mDebugger);
}
bool Settings::CompilerSet::canAssemble()
{
return fileExists(mAssembler);
}
void Settings::CompilerSet::setUserInput()
{
mUseCustomCompileParams = false;
@ -2551,6 +2558,16 @@ QByteArray Settings::CompilerSet::getCompilerOutput(const QString &binDir, const
return result.trimmed();
}
const QString &Settings::CompilerSet::assembler() const
{
return mAssembler;
}
void Settings::CompilerSet::setAssembler(const QString &newAssembler)
{
mAssembler = newAssembler;
}
Settings::CompilerSet::CompilationStage Settings::CompilerSet::compilationStage() const
{
return mCompilationStage;
@ -3073,6 +3090,8 @@ void Settings::CompilerSets::saveSet(int index)
savePath("make", pSet->make());
savePath("windres", pSet->resourceCompiler());
savePath("profiler", pSet->profiler());
savePath("assembler", pSet->assembler());
mSettings->mSettings.remove("Options");
foreach(const PCompilerOption& option, CompilerInfoManager::getInstance()->getCompilerOptions(pSet->compilerType())) {
@ -3151,6 +3170,7 @@ Settings::PCompilerSet Settings::CompilerSets::loadSet(int index)
pSet->setMake(loadPath("make"));
pSet->setResourceCompiler(loadPath("windres"));
pSet->setProfiler(loadPath("profiler"));
pSet->setAssembler(loadPath("assembler"));
pSet->setDumpMachine(mSettings->mSettings.value("DumpMachine").toString());
pSet->setVersion(mSettings->mSettings.value("Version").toString());

View File

@ -1300,6 +1300,7 @@ public:
bool canCompileCPP();
bool canMake();
bool canDebug();
bool canAssemble();
// bool dirsValid(QString& msg);
// bool validateExes(QString& msg);
//properties
@ -1389,6 +1390,9 @@ public:
QString getOutputFilename(const QString& sourceFilename,Settings::CompilerSet::CompilationStage stage);
bool isOutputExecutable();
bool isOutputExecutable(Settings::CompilerSet::CompilationStage stage);
const QString &assembler() const;
void setAssembler(const QString &newAssembler);
private:
void setDirectories(const QString& binDir, CompilerType mCompilerType);
//load hard defines
@ -1409,6 +1413,7 @@ public:
QString mProfiler;
QString mResourceCompiler;
QString mDebugServer;
QString mAssembler;
// Directories, mostly hardcoded too
QStringList mBinDirs;
@ -1471,6 +1476,7 @@ public:
QString getKeyFromCompilerCompatibleIndex(int idx) const;
static bool isTarget64Bit(const QString &target);
private:
PCompilerSet addSet(const QString& folder, const QString& c_prog);
PCompilerSet addSet(const PCompilerSet &pSet);
@ -1482,7 +1488,6 @@ public:
void loadPathList(const QString& name, QStringList& list);
PCompilerSet loadSet(int index);
void prepareCompatibleIndex();
static bool isTarget64Bit(const QString &target);
private:
CompilerSetList mList;
int mDefaultIndex;

View File

@ -99,6 +99,7 @@ static void loadCompilerSetSettings(Settings::PCompilerSet pSet, Ui::CompilerSet
ui->txtGDBServer->setText(pSet->debugServer());
ui->txtResourceCompiler->setText(pSet->resourceCompiler());
ui->txtProfiler->setText(pSet->profiler());
ui->txtAssembler->setText(pSet->assembler());
if (pSet->execCharset() == ENCODING_AUTO_DETECT
|| pSet->execCharset() == ENCODING_SYSTEM_DEFAULT
@ -208,6 +209,7 @@ void CompilerSetOptionWidget::saveCurrentCompilerSet()
pSet->setDebugServer(ui->txtGDBServer->text().trimmed());
pSet->setResourceCompiler(ui->txtResourceCompiler->text().trimmed());
pSet->setProfiler(ui->txtProfiler->text().trimmed());
pSet->setAssembler(ui->txtAssembler->text().trimmed());
pSet->binDirs()=mBinDirWidget->dirList();
@ -334,6 +336,7 @@ void CompilerSetOptionWidget::updateIcons(const QSize& /*size*/)
pIconsManager->setIcon(ui->btnChooseGDBServer, IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnChooseMake, IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnChooseProfiler, IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnChooseAssembler, IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnChooseResourceCompiler, IconsManager::ACTION_FILE_OPEN_FOLDER);
}
@ -445,3 +448,15 @@ void CompilerSetOptionWidget::on_btnChooseProfiler_clicked()
ui->txtProfiler->setText(fileName);
}
void CompilerSetOptionWidget::on_btnChooseAssembler_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Locate nasm"),
getBinDir(),
tr("Executable files (*.exe)"));
if (fileExists(fileName))
ui->txtAssembler->setText(fileName);
}

View File

@ -71,6 +71,7 @@ private slots:
void on_btnChooseGDBServer_clicked();
void on_btnChooseResourceCompiler_clicked();
void on_btnChooseProfiler_clicked();
void on_btnChooseAssembler_clicked();
};
#endif // COMPILERSETOPTIONWIDGET_H

View File

@ -110,7 +110,7 @@
<item>
<widget class="QTabWidget" name="settingTabs">
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<property name="movable">
<bool>false</bool>
@ -249,10 +249,10 @@
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="2">
<widget class="QToolButton" name="btnChooseMake">
<item row="5" column="2">
<widget class="QToolButton" name="btnChooseResourceCompiler">
<property name="toolTip">
<string>Choose make</string>
<string>Choose Resource Compiler</string>
</property>
<property name="text">
<string>...</string>
@ -264,17 +264,10 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>C Compiler(gcc)</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QToolButton" name="btnChooseProfiler">
<item row="0" column="2">
<widget class="QToolButton" name="btnChooseCCompiler">
<property name="toolTip">
<string>Choose Profiler</string>
<string>Choose C Compiler</string>
</property>
<property name="text">
<string>...</string>
@ -286,8 +279,11 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="txtResourceCompiler"/>
<item row="7" column="1">
<widget class="QLineEdit" name="txtProfiler"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="txtDebugger"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
@ -296,6 +292,20 @@
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QToolButton" name="btnChooseGDBServer">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/images/newlook24/053-open.png</normaloff>:/icons/images/newlook24/053-open.png</iconset>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="txtResourceCompiler"/>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="btnChooseCppCompiler">
<property name="toolTip">
@ -311,20 +321,18 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Profiler(gprof)</string>
<item row="7" column="2">
<widget class="QToolButton" name="btnChooseProfiler">
<property name="toolTip">
<string>Choose Profiler</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="txtProfiler"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>make</string>
<string>...</string>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/images/newlook24/053-open.png</normalon>
</iconset>
</property>
</widget>
</item>
@ -343,54 +351,15 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="txtDebugger"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="txtMake"/>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="btnChooseCCompiler">
<property name="toolTip">
<string>Choose C Compiler</string>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/images/newlook24/053-open.png</normalon>
</iconset>
<string>make</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtCppCompiler"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>gdb</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QToolButton" name="btnChooseResourceCompiler">
<property name="toolTip">
<string>Choose Resource Compiler</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/images/newlook24/053-open.png</normalon>
</iconset>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtCCompiler"/>
<item row="4" column="1">
<widget class="QLineEdit" name="txtGDBServer"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
@ -399,6 +368,44 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="txtCCompiler"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>C Compiler(gcc)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txtCppCompiler"/>
</item>
<item row="2" column="2">
<widget class="QToolButton" name="btnChooseMake">
<property name="toolTip">
<string>Choose make</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset>
<normalon>:/icons/images/newlook24/053-open.png</normalon>
</iconset>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Profiler(gprof)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="txtMake"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
@ -406,11 +413,25 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="txtGDBServer"/>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>gdb</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QToolButton" name="btnChooseGDBServer">
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Assembler</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="txtAssembler"/>
</item>
<item row="6" column="2">
<widget class="QToolButton" name="btnChooseAssembler">
<property name="text">
<string>...</string>
</property>

View File

@ -22,6 +22,7 @@
#define APP_SETTSINGS_FILENAME "redpandacpp.ini"
#ifdef Q_OS_WIN
#define CONSOLE_PAUSER "consolepauser.exe"
#define ASSEMBLER "nasm.exe"
#define GCC_PROGRAM "gcc.exe"
#define GPP_PROGRAM "g++.exe"
#define GDB_PROGRAM "gdb.exe"
@ -39,6 +40,7 @@
#define LLDB_SERVER_PROGRAM "lldb-server.exe"
#elif defined(Q_OS_LINUX)
#define CONSOLE_PAUSER "consolepauser"
#define ASSEMBLER "nasm"
#define GCC_PROGRAM "gcc"
#define GPP_PROGRAM "g++"
#define GDB_PROGRAM "gdb"
@ -55,6 +57,7 @@
#define LLDB_MI_PROGRAM "lldb-mi"
#define LLDB_SERVER_PROGRAM "lldb-server"
#elif defined(Q_OS_MACOS)
#define ASSEMBLER "nasm"
#define GCC_PROGRAM "gcc"
#define GPP_PROGRAM "g++"
#define GDB_PROGRAM "gdb"

View File

@ -83,6 +83,9 @@ QStringList splitProcessCommand(const QString &cmd)
FileType getFileType(const QString &filename)
{
if (filename.endsWith(".asm",PATH_SENSITIVITY)) {
return FileType::ASM;
}
if (filename.endsWith(".dev",PATH_SENSITIVITY)) {
return FileType::Project;
}

View File

@ -32,6 +32,7 @@ using SimpleIni = CSimpleIniA;
using PSimpleIni = std::shared_ptr<SimpleIni>;
enum class FileType{
ASM, // asm source file (.asm)
CSource, // c source file (.c)
CppSource, // c++ source file (.cpp)
CHeader, // c header (.h)