* can compile now

This commit is contained in:
royqh1979@gmail.com 2021-04-20 22:24:33 +08:00
parent 4c4fd9fb2b
commit cea9b757ab
20 changed files with 707 additions and 109 deletions

View File

@ -9,6 +9,9 @@ CONFIG += c++14
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
compiler/compiler.cpp \
compiler/compilermanager.cpp \
compiler/filecompiler.cpp \
editor.cpp \
editorlist.cpp \
main.cpp \
@ -22,6 +25,9 @@ SOURCES += \
utils.cpp
HEADERS += \
compiler/compiler.h \
compiler/compilermanager.h \
compiler/filecompiler.h \
editor.h \
editorlist.h \
mainwindow.h \

View File

@ -0,0 +1,202 @@
#include "compiler.h"
#include "utils.h"
#include <QFileInfo>
#include <QProcess>
#include <QString>
#include <QTextCodec>
#include <QDebug>
#include <QTime>
Compiler::Compiler(bool silent,bool onlyCheckSyntax):
QThread(),
mSilent(silent),
mOnlyCheckSyntax(onlyCheckSyntax)
{
}
void Compiler::run()
{
emit compileStarted();
if (prepareForCompile()){
QElapsedTimer timer;
timer.start();
runCommand(mCompiler, mArguments, QFileInfo(mCompiler).absolutePath());
log("");
log(tr("Compile Result:"));
log("------------------");
log(tr("- Errors: %1").arg(0));
log(tr("- Warnings: %1").arg(0));
log(tr("- Time Elasped: %1 secs").arg(timer.elapsed() / 1000.0));
}
this->deleteLater();
emit compileFinished();
}
void Compiler::stopCompile()
{
mStop = true;
}
QString Compiler::getCharsetArgument(const QByteArray& encoding)
{
QString result;
if (compilerSet()->autoAddCharsetParams() && encoding != ENCODING_ASCII) {
QString encodingName;
QString systemEncodingName=QTextCodec::codecForLocale()->name();
if (encoding == ENCODING_SYSTEM_DEFAULT) {
encodingName = systemEncodingName;
} else if (encoding == ENCODING_UTF8_BOM) {
encodingName = "UTF-8";
} else {
encodingName = encoding;
}
result += QString(" -finput-charset=%1 -fexec-charset=%2")
.arg(encodingName)
.arg(systemEncodingName);
}
return result;
}
QString Compiler::getCCompileArguments(bool checkSyntax)
{
QString result;
if (checkSyntax) {
result += " -fsyntax-only";
}
for (PCompilerOption pOption: compilerSet()->options()) {
if (pOption->value > 0 && pOption->isC) {
if (pOption->choices.isEmpty()) {
result += " " + pOption->setting;
} else if (pOption->value < pOption->choices.size()) {
QStringList nameValue=pOption->choices[pOption->value].split('=');
if (nameValue.count()==2) {
result += " " + pOption->setting + nameValue[1];
}
}
}
}
if (compilerSet()->useCustomCompileParams() && !compilerSet()->customCompileParams().isEmpty()) {
result += " "+compilerSet()->customCompileParams();
}
return result;
}
QString Compiler::getCppCompileArguments(bool checkSyntax)
{
QString result;
if (checkSyntax) {
result += " -fsyntax-only";
}
for (PCompilerOption pOption: compilerSet()->options()) {
if (pOption->value > 0 && pOption->isCpp) {
if (pOption->choices.isEmpty()) {
result += " "+pOption->setting;
} else if (pOption->value < pOption->choices.size()) {
QStringList nameValue=pOption->choices[pOption->value].split('=');
if (nameValue.count()==2) {
result += " "+pOption->setting + nameValue[1];
}
}
}
}
if (compilerSet()->useCustomCompileParams() && !compilerSet()->customCompileParams().isEmpty()) {
result += " "+compilerSet()->customCompileParams();
}
return result;
}
QString Compiler::getCIncludeArguments()
{
QString result;
for (const QString& folder:compilerSet()->CIncludeDirs()) {
result += QString(" -I\"%1\"").arg(folder);
}
return result;
}
QString Compiler::getCppIncludeArguments()
{
QString result;
for (const QString& folder:compilerSet()->CppIncludeDirs()) {
result += QString(" -I\"%1\"").arg(folder);
}
return result;
}
QString Compiler::getLibraryArguments()
{
QString result;
for (const QString& folder:compilerSet()->libDirs()) {
result += QString(" -L\"%1\"").arg(folder);
}
// Add global compiler linker extras
if (compilerSet()->useCustomLinkParams() && !compilerSet()->customLinkParams().isEmpty()) {
result += " "+compilerSet()->customCompileParams();
}
//options like "-static" must be added after "-lxxx"
for (PCompilerOption pOption: compilerSet()->options()) {
if (pOption->value > 0 && pOption->isLinker) {
if (pOption->choices.isEmpty()) {
result += " " + pOption->setting;
} else if (pOption->value < pOption->choices.size()) {
QStringList nameValue=pOption->choices[pOption->value].split('=');
if (nameValue.count()==2) {
result += " " + pOption->setting + nameValue[1];
}
}
}
}
return result;
}
void Compiler::runCommand(const QString &cmd, const QString &arguments, const QString &workingDir, const QString& inputText)
{
QProcess process;
mStop = false;
process.setProgram(cmd);
process.setArguments(QProcess::splitCommand(arguments));
process.setWorkingDirectory(workingDir);
process.connect(&process, &QProcess::readyReadStandardError,[&process,this](){
this->log(process.readAllStandardError());
});
process.connect(&process, &QProcess::readyReadStandardOutput,[&process,this](){
this->log(process.readAllStandardOutput());
});
process.start();
if (!inputText.isEmpty())
process.write(inputText.toUtf8());
process.closeWriteChannel();
while (true) {
process.waitForFinished(1000);
if (process.state()!=QProcess::Running) {
break;
}
if (mStop) {
process.kill();
break;
}
}
}
void Compiler::log(const QString &msg)
{
emit compileOutput(msg);
}
void Compiler::error(const QString &msg)
{
emit compileError(msg);
}

View File

@ -0,0 +1,55 @@
#ifndef COMPILER_H
#define COMPILER_H
#include <QThread>
#include "settings.h"
class Compiler : public QThread
{
Q_OBJECT
public:
enum class TargetType {
Invalid,
cttNone,
File,
Project,
StdIn
};
Compiler(bool silent,bool onlyCheckSyntax);
signals:
void compileStarted();
void compileFinished();
void compileOutput(const QString& msg);
void compileError(const QString& errorMsg);
public slots:
void stopCompile();
protected:
void run() override;
protected:
virtual Settings::PCompilerSet compilerSet() = 0;
virtual bool prepareForCompile() = 0;
virtual QString getCharsetArgument(const QByteArray& encoding);
virtual QString getCCompileArguments(bool checkSyntax);
virtual QString getCppCompileArguments(bool checkSyntax);
virtual QString getCIncludeArguments();
virtual QString getCppIncludeArguments();
virtual QString getLibraryArguments();
void log(const QString& msg);
void error(const QString& msg);
void runCommand(const QString& cmd, const QString& arguments, const QString& workingDir, const QString& inputText=QString());
protected:
bool mSilent;
bool mOnlyCheckSyntax;
QString mCompiler;
QString mArguments;
private:
bool mStop;
};
#endif // COMPILER_H

View File

@ -0,0 +1,44 @@
#include "compilermanager.h"
#include "filecompiler.h"
#include <QDebug>
#include "../mainwindow.h"
CompilerManager::CompilerManager(QObject *parent) : QObject(parent)
{
mCompiler = nullptr;
mBackgroundSyntaxChecker = nullptr;
}
bool CompilerManager::compiling()
{
return mCompiler!=nullptr;
}
bool CompilerManager::backgroundSyntaxChecking()
{
return mBackgroundSyntaxChecker!=nullptr;
}
void CompilerManager::compile(const QString& filename, const QByteArray& encoding, bool silent, bool onlyCheckSyntax)
{
{
QMutexLocker locker(&compileMutex);
if (mCompiler!=nullptr) {
return;
}
mCompiler = new FileCompiler(filename,encoding,silent,onlyCheckSyntax);
connect(mCompiler, &Compiler::compileFinished, this ,&CompilerManager::onCompileFinished);
connect(mCompiler, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mCompiler, &Compiler::compileError, pMainWindow, &MainWindow::onCompileError);
mCompiler->start();
}
}
void CompilerManager::onCompileFinished()
{
QMutexLocker locker(&compileMutex);
qDebug() << " Compile Finished";
mCompiler=nullptr;
}

View File

@ -0,0 +1,27 @@
#ifndef COMPILERMANAGER_H
#define COMPILERMANAGER_H
#include <QObject>
#include "compiler.h"
#include <QMutex>
class CompilerManager : public QObject
{
Q_OBJECT
public:
explicit CompilerManager(QObject *parent = nullptr);
bool compiling();
bool backgroundSyntaxChecking();
void compile(const QString& filename, const QByteArray& encoding, bool silent=false,bool onlyCheckSyntax=false);
private slots:
void onCompileFinished();
private:
Compiler* mCompiler;
Compiler* mBackgroundSyntaxChecker;
QMutex compileMutex;
QMutex backgroundSyntaxChekMutex;
};
#endif // COMPILERMANAGER_H

View File

@ -0,0 +1,73 @@
#include "filecompiler.h"
#include "utils.h"
#include "../mainwindow.h"
#include <QFile>
#include <QFileInfo>
#include <QMessageBox>
FileCompiler::FileCompiler(const QString &filename, const QByteArray &encoding,bool silent,bool onlyCheckSyntax):
Compiler(silent,onlyCheckSyntax),
mFileName(filename),
mEncoding(encoding)
{
}
Settings::PCompilerSet FileCompiler::compilerSet()
{
return pSettings->compilerSets().defaultSet();
}
bool FileCompiler::prepareForCompile()
{
log(tr("Compiling single file..."));
log("------------------");
log(tr("- Filename: %1").arg(mFileName));
log(tr("- Compiler Set Name: %1").arg(compilerSet()->name()));
log("");
FileType fileType = getFileType(mFileName);
mArguments= QString(" \"%1\"").arg(mFileName);
if (!mOnlyCheckSyntax) {
QString outputFilename = getCompiledExecutableName(mFileName);
mArguments+=QString(" -o \"%1\"").arg(outputFilename);
//remove the old file it exists
QFile outputFile(outputFilename);
if (outputFile.exists()) {
if (!outputFile.remove()) {
error(tr("Can't delete the old executable file \"%1\".\n").arg(outputFilename));
return false;
}
}
}
mArguments += getCharsetArgument(mEncoding);
QString strFileType;
switch(fileType) {
case FileType::CSource:
mArguments += getCCompileArguments(mOnlyCheckSyntax);
mArguments += getCIncludeArguments();
strFileType = "C";
mCompiler = compilerSet()->CCompiler();
break;
case FileType::CppSource:
mArguments += getCCompileArguments(mOnlyCheckSyntax);
mArguments += getCIncludeArguments();
strFileType = "C++";
mCompiler = compilerSet()->cppCompiler();
break;
default:
error(tr("Can't the compiler for file %1").arg(mFileName));
return false;
}
mArguments += getLibraryArguments();
log(tr("Processing %1 source file:").arg(strFileType));
log("------------------");
log(tr("%1 Compiler: %2").arg(strFileType).arg(mCompiler));
log(tr("Command: %1 %2").arg(QFileInfo(mCompiler).fileName()).arg(mArguments));
return true;
}

View File

@ -0,0 +1,22 @@
#ifndef FILECOMPILER_H
#define FILECOMPILER_H
#include "compiler.h"
class FileCompiler : public Compiler
{
Q_OBJECT
public:
FileCompiler(const QString& filename, const QByteArray& encoding,bool silent,bool onlyCheckSyntax);
// Compiler interface
protected:
Settings::PCompilerSet compilerSet() override;
bool prepareForCompile() override;
private:
QString mFileName;
QByteArray mEncoding;
};
#endif // FILECOMPILER_H

View File

@ -289,7 +289,7 @@ void Editor::onCursorPositionChanged(int line, int index) {
}
void Editor::onLinesChanged() {
qDebug()<<"lala"<<lines();
qDebug()<<"Editor lines changed"<<lines();
}
void Editor::updateCaption(const QString& newCaption) {

View File

@ -14,11 +14,11 @@ Settings* createAppSettings(const QString& filepath = QString()) {
QString filename;
if (filepath.isEmpty()) {
if (isGreenEdition()) {
filename = QApplication::applicationDirPath() + QDir::separator() +
"config" + QDir::separator() + APP_SETTSINGS_FILENAME;
filename = includeTrailingPathDelimiter(QApplication::applicationDirPath()) +
"config/" + APP_SETTSINGS_FILENAME;
} else {
filename = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0]
+ QDir::separator() + APP_SETTSINGS_FILENAME;
filename =includeTrailingPathDelimiter(QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0])
+ APP_SETTSINGS_FILENAME;
}
} else {
filename = filepath;

View File

@ -10,7 +10,9 @@
#include <QFileDialog>
#include <QLabel>
#include <settingsdialog/settingsdialog.h>
#include "settingsdialog/settingsdialog.h"
#include "compiler/compilermanager.h"
#include <QDebug>
MainWindow* pMainWindow;
@ -38,6 +40,8 @@ MainWindow::MainWindow(QWidget *parent)
connect(mCompilerSet,QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &MainWindow::onCompilerSetChanged);
updateCompilerSet();
mCompilerManager = new CompilerManager(this);
}
MainWindow::~MainWindow()
@ -167,3 +171,21 @@ void MainWindow::onCompilerSetChanged(int index)
pSettings->compilerSets().setDefaultIndex(index);
pSettings->compilerSets().saveDefaultIndex();
}
void MainWindow::onCompileLog(const QString &msg)
{
ui->txtCompilerOutput->appendPlainText(msg);
}
void MainWindow::onCompileError(const QString &msg)
{
qDebug()<<msg;
}
void MainWindow::on_actionCompile_triggered()
{
Editor * editor = mEditorList->getEditor();
if (editor != NULL) {
mCompilerManager->compile(editor->filename(),editor->fileEncoding());
}
}

View File

@ -3,6 +3,7 @@
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
@ -10,6 +11,7 @@ QT_END_NAMESPACE
class EditorList;
class QLabel;
class QComboBox;
class CompilerManager;
class MainWindow : public QMainWindow
{
@ -41,6 +43,13 @@ private slots:
// qt will auto bind slots with the prefix "on_"
void onCompilerSetChanged(int index);
void on_actionCompile_triggered();
public slots:
void onCompileLog(const QString& msg);
void onCompileError(const QString& msg);
private:
void setupActions();
@ -52,6 +61,8 @@ private:
QLabel* mFileInfoStatus;
QLabel* mFileEncodingStatus;
QComboBox* mCompilerSet;
CompilerManager* mCompilerManager;
// QWidget interface
protected:

View File

@ -41,7 +41,7 @@
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -151,24 +151,49 @@
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<widget class="QWidget" name="tabCompilerOutput">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
<string>Compiler Output</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QPlainTextEdit" name="txtCompilerOutput">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="backgroundVisible">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
@ -201,7 +226,14 @@
</property>
<addaction name="actionOptions"/>
</widget>
<widget class="QMenu" name="menuRun">
<property name="title">
<string>Run</string>
</property>
<addaction name="actionCompile"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuRun"/>
<addaction name="menuTools"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
@ -231,6 +263,18 @@
<bool>false</bool>
</attribute>
</widget>
<widget class="QToolBar" name="toolBarCompile">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionCompile"/>
</widget>
<action name="actionNew">
<property name="icon">
<iconset>
@ -301,6 +345,22 @@
<string>Options</string>
</property>
</action>
<action name="actionCompile">
<property name="icon">
<iconset>
<normalon>:/icons/images/newlook24/013-compile.png</normalon>
</iconset>
</property>
<property name="text">
<string>Compile</string>
</property>
<property name="toolTip">
<string>Compile</string>
</property>
<property name="shortcut">
<string>F9</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@ -137,7 +137,6 @@ void Settings::Editor::setAutoIndent(bool indent)
Settings::CompilerSet::CompilerSet(const QString& compilerFolder):
mStaticLink(true),
mAutoAddCharsetParams(true)
{
if (!compilerFolder.isEmpty()) {
@ -176,7 +175,6 @@ Settings::CompilerSet::CompilerSet(const Settings::CompilerSet &set):
mUseCustomLinkParams(set.mUseCustomLinkParams),
mCustomCompileParams(set.mCustomCompileParams),
mCustomLinkParams(set.mCustomLinkParams),
mStaticLink(set.mStaticLink),
mAutoAddCharsetParams(set.mAutoAddCharsetParams)
{
// Executables, most are hardcoded
@ -410,16 +408,6 @@ void Settings::CompilerSet::setCustomLinkParams(const QString &value)
mCustomLinkParams = value;
}
bool Settings::CompilerSet::staticLink()
{
return mStaticLink;
}
void Settings::CompilerSet::setStaticLink(bool value)
{
mStaticLink = value;
}
bool Settings::CompilerSet::autoAddCharsetParams()
{
return mAutoAddCharsetParams;
@ -526,10 +514,10 @@ void Settings::CompilerSet::setProperties(const QString &binDir)
mDumpMachine = getCompilerOutput(binDir, GCC_PROGRAM, arguments);
// Add the default directories
addExistingDirectory(mBinDirs, folder + QDir::separator() + "bin");
addExistingDirectory(mLibDirs, folder + QDir::separator() + "lib");
addExistingDirectory(mCIncludeDirs, folder + QDir::separator() + "include");
addExistingDirectory(mCppIncludeDirs, folder + QDir::separator() + "include");
addExistingDirectory(mBinDirs, includeTrailingPathDelimiter(folder) + "bin");
addExistingDirectory(mLibDirs, includeTrailingPathDelimiter(folder) + "lib");
addExistingDirectory(mCIncludeDirs, includeTrailingPathDelimiter(folder) + "include");
addExistingDirectory(mCppIncludeDirs, includeTrailingPathDelimiter(folder) + "include");
// Find default directories
arguments.clear();
@ -644,59 +632,51 @@ void Settings::CompilerSet::setDirectories(const QString& folder)
if (!mDumpMachine.isEmpty()) {
//mingw-w64 bin folder
addExistingDirectory(mBinDirs,
folder + QDir::separator() + "lib"
+ QDir::separator() + "gcc" + mDumpMachine
+ QDir::separator() + mVersion);
includeTrailingPathDelimiter(folder) + "lib/"
"gcc/" + mDumpMachine
+ "/" + mVersion);
// Regular include folder
addExistingDirectory(mCIncludeDirs, folder + QDir::separator() + mDumpMachine + QDir::separator() + "include");
addExistingDirectory(mCppIncludeDirs, folder + QDir::separator()+ mDumpMachine + QDir::separator() + "include");
addExistingDirectory(mCIncludeDirs, includeTrailingPathDelimiter(folder) + mDumpMachine + "/include");
addExistingDirectory(mCppIncludeDirs, includeTrailingPathDelimiter(folder)+ mDumpMachine + "/include");
// Other include folder?
addExistingDirectory(mCIncludeDirs,
folder + QDir::separator() + "lib" + QDir::separator() + "gcc"
+ QDir::separator() + mDumpMachine + QDir::separator()
+ mVersion + QDir::separator() + "include");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include");
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "lib" + QDir::separator() + "gcc"
+ QDir::separator() + mDumpMachine + QDir::separator()
+ mVersion + QDir::separator() + "include");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include");
addExistingDirectory(mCIncludeDirs,
folder + QDir::separator() + "lib"
+ QDir::separator() + "gcc" + QDir::separator() + mDumpMachine
+ QDir::separator() + mVersion + QDir::separator() + "include-fixed");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include-fixed");
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "lib"
+ QDir::separator() + "gcc" + QDir::separator() + mDumpMachine
+ QDir::separator() + mVersion + QDir::separator() + "include-fixed");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include-fixed");
// C++ only folder (mingw.org)
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "lib" + QDir::separator() + "gcc"
+ QDir::separator() + mDumpMachine + QDir::separator() + mVersion
+ QDir::separator() + "include" + QDir::separator() + "c++");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include/c++");
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "lib" + QDir::separator() + "gcc"
+ QDir::separator() + mDumpMachine + QDir::separator() + mVersion
+ QDir::separator() + "include" + QDir::separator() + "c++"
+ QDir::separator() + mDumpMachine );
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include/c++/"
+ mDumpMachine);
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "lib" + QDir::separator() + "gcc"
+ QDir::separator() + mDumpMachine + QDir::separator() + mVersion
+ QDir::separator() + "include" + QDir::separator() + "c++"
+ QDir::separator() + "backward");
includeTrailingPathDelimiter(folder) + "lib/gcc/"
+ mDumpMachine + "/" + mVersion + "/include/c++/backward");
// C++ only folder (Mingw-w64)
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "include" + QDir::separator() + "c++"
+ QDir::separator() + mVersion );
includeTrailingPathDelimiter(folder) + "include/c++/"
+ mVersion );
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "include" + QDir::separator() + "c++"
+ QDir::separator() + mVersion + QDir::separator() + mDumpMachine );
includeTrailingPathDelimiter(folder) + "include/c++/"
+ mVersion + "/backward");
addExistingDirectory(mCppIncludeDirs,
folder + QDir::separator() + "include" + QDir::separator() + "c++"
+ QDir::separator() + mVersion + QDir::separator() + "backward");
includeTrailingPathDelimiter(folder) + "include/c++/"
+ mVersion + "/" + mDumpMachine);
}
}
@ -704,7 +684,6 @@ void Settings::CompilerSet::setUserInput()
{
mUseCustomCompileParams = false;
mUseCustomLinkParams = false;
mStaticLink = true;
mAutoAddCharsetParams = true;
}
@ -813,6 +792,8 @@ void Settings::CompilerSet::setOptions()
sl.append("GNU C++17=gnu++17");
sl.append("GNU C++20=gnu++20");
addOption(tr("Language standard (-std)"), groupName, true, true, false, 0, "-std=", sl);
addOption(tr("Generate debugging information (-g3)"), groupName, true, true, false, 0, "-g3");
addOption(tr("Generate profiling info for analysis (-pg)"), groupName, true, true, true, 0, "-pg");
// Warnings
groupName = tr("Warnings");
@ -824,23 +805,19 @@ void Settings::CompilerSet::setOptions()
addOption(tr("Make all warnings into errors (-Werror)"), groupName, true, true, false, 0, "-Werror");
addOption(tr("Abort compilation on first error (-Wfatal-errors)"), groupName, true, true, false, 0, "-Wfatal-errors");
// Profiling
groupName = tr("Profiling");
addOption(tr("Generate profiling info for analysis (-pg)"), groupName, true, true, true, 0, "-pg");
// Linker
groupName = tr("Linker");
addOption(tr("Link an Objective C program (-lobjc)"), groupName, false, false, true, 0, "-lobjc");
addOption(tr("Do not use standard system libraries (-nostdlib)"), groupName, true, true, true, 0, "-nostdlib");
addOption(tr("Do not create a console window (-mwindows)"), groupName,true, true, true, 0, "-mwindows");
addOption(tr("Do not use standard system libraries (-nostdlib)"), groupName, false, false, true, 0, "-nostdlib");
addOption(tr("Do not create a console window (-mwindows)"), groupName,false, false, true, 0, "-mwindows");
addOption(tr("Strip executable (-s)"), groupName, false, false, true, 0, "-s");
addOption(tr("Generate debugging information (-g3)"), groupName, true, true, true, 0, "-g3");
addOption(tr("Link libraries statically (-static)"), groupName, false, false, true, 0, "-static");
// Output
groupName = tr("Output");
addOption(tr("-fverbose-asm"), groupName, true, true, false, 0, "-fverbose-asm");
addOption(tr("Do not assemble, but output assembler code (-S)"), groupName, true, true, false, 0, "-S");
addOption(tr("Use pipes instead of temporary files during compilation (-pipe)"), groupName, true, true, false, 0, "-pipe");
addOption(tr("Do not assemble, compile and generate the assemble code (-S)"), groupName, true, true, false, 0, "-S");
}
QString Settings::CompilerSet::findProgramInBinDirs(const QString name)
@ -877,7 +854,7 @@ void Settings::CompilerSet::setIniOptions(const QByteArray &value)
QByteArray Settings::CompilerSet::getCompilerOutput(const QString &binDir, const QString &binFile, const QStringList &arguments)
{
QByteArray result = runAndGetOutput(binDir + QDir::separator()+binFile, binDir, arguments);
QByteArray result = runAndGetOutput(includeTrailingPathDelimiter(binDir)+binFile, binDir, arguments);
return result.trimmed();
}
@ -917,6 +894,11 @@ static void setReleaseOptions(Settings::PCompilerSet pSet) {
if (pOption) {
pSet->setOption(pOption,'1');
}
pOption = pSet->findOption("-static");
if (pOption) {
pSet->setOption(pOption,'1');
}
}
static void setDebugOptions(Settings::PCompilerSet pSet) {
@ -932,6 +914,10 @@ static void setDebugOptions(Settings::PCompilerSet pSet) {
if (pOption) {
pSet->setOption(pOption,'1');
}
pOption = pSet->findOption("-static");
if (pOption) {
pSet->setOption(pOption,'1');
}
}
static void setProfileOptions(Settings::PCompilerSet pSet) {
@ -939,6 +925,11 @@ static void setProfileOptions(Settings::PCompilerSet pSet) {
if (pOption) {
pSet->setOption(pOption,'1');
}
pOption = pSet->findOption("-static");
if (pOption) {
pSet->setOption(pOption,'1');
}
}
void Settings::CompilerSets::addSets(const QString &folder)
@ -1077,9 +1068,9 @@ void Settings::CompilerSets::savePath(const QString& name, const QString& path)
QString s;
QString prefix1 = excludeTrailingPathDelimiter(mSettings->mDirs.app()) + "/";
QString prefix2 = excludeTrailingPathDelimiter(mSettings->mDirs.app()) + QDir::separator();
if (path.startsWith(prefix1, Qt::CaseInsensitive)) {
if (path.startsWith(prefix1, PATH_SENSITIVITY)) {
s = "%AppPath%/"+ path.mid(prefix1.length());
} else if (path.startsWith(prefix2, Qt::CaseInsensitive)) {
} else if (path.startsWith(prefix2, PATH_SENSITIVITY)) {
s = "%AppPath%/"+ path.mid(prefix2.length());
} else {
s= path;
@ -1093,9 +1084,9 @@ void Settings::CompilerSets::savePathList(const QString& name, const QStringList
QString s;
QString prefix1 = excludeTrailingPathDelimiter(mSettings->mDirs.app()) + "/";
QString prefix2 = excludeTrailingPathDelimiter(mSettings->mDirs.app()) + QDir::separator();
if (path.startsWith(prefix1, Qt::CaseInsensitive)) {
if (path.startsWith(prefix1, PATH_SENSITIVITY)) {
s = "%AppPath%/"+ path.mid(prefix1.length());
} else if (path.startsWith(prefix2, Qt::CaseInsensitive)) {
} else if (path.startsWith(prefix2, PATH_SENSITIVITY)) {
s = "%AppPath%/" + path.mid(prefix2.length());
} else {
s= path;
@ -1125,7 +1116,6 @@ void Settings::CompilerSets::saveSet(int index)
mSettings->mSettings.setValue("customCompileParams", pSet->customCompileParams());
mSettings->mSettings.setValue("useCustomLinkParams", pSet->useCustomLinkParams());
mSettings->mSettings.setValue("customLinkParams", pSet->customLinkParams());
mSettings->mSettings.setValue("StaticLink", pSet->staticLink());
mSettings->mSettings.setValue("AddCharset", pSet->autoAddCharsetParams());
// Misc. properties
@ -1187,7 +1177,6 @@ Settings::PCompilerSet Settings::CompilerSets::loadSet(int index)
pSet->setCustomCompileParams(mSettings->mSettings.value("customCompileParams").toString());
pSet->setUseCustomLinkParams(mSettings->mSettings.value("useCustomLinkParams").toBool());
pSet->setCustomLinkParams(mSettings->mSettings.value("customLinkParams").toString());
pSet->setStaticLink(mSettings->mSettings.value("StaticLink").toBool());
pSet->setAutoAddCharsetParams(mSettings->mSettings.value("AddCharset").toBool());
pSet->setDumpMachine(mSettings->mSettings.value("DumpMachine").toString());

View File

@ -128,8 +128,6 @@ public:
void setCustomCompileParams(const QString& value);
const QString& customLinkParams();
void setCustomLinkParams(const QString& value);
bool staticLink();
void setStaticLink(bool value);
bool autoAddCharsetParams();
void setAutoAddCharsetParams(bool value);
@ -184,7 +182,6 @@ public:
bool mUseCustomLinkParams;
QString mCustomCompileParams;
QString mCustomLinkParams;
bool mStaticLink;
bool mAutoAddCharsetParams;
// Options

View File

@ -78,7 +78,7 @@ void CompilerSetDirectoriesWidget::on_btnRemoveInvalid_pressed()
for (const QString& folder : dirList() ) {
QFileInfo info(folder);
if (info.exists() && info.isDir() ) {
lst.append(folder);
lst.append(folder.trimmed());
}
}
setDirList(lst);

View File

@ -96,7 +96,6 @@ static void loadCompilerSetSettings(Settings::PCompilerSet pSet, Ui::CompilerSet
ui->chkUseCustomLinkParams->setChecked(pSet->useCustomLinkParams());
ui->txtCustomLinkParams->setPlainText(pSet->customLinkParams());
ui->txtCustomLinkParams->setEnabled(pSet->useCustomLinkParams());
ui->chkStaticLink->setChecked(pSet->staticLink());
ui->chkAutoAddCharset->setChecked(pSet->autoAddCharsetParams());
//rest tabs in the options widget
@ -170,18 +169,17 @@ void CompilerSetOptionWidget::saveCurrentCompilerSet()
Settings::PCompilerSet pSet = pSettings->compilerSets().defaultSet();
pSet->setUseCustomCompileParams(ui->chkUseCustomCompilerParams->isChecked());
pSet->setCustomCompileParams(ui->txtCustomCompileParams->toPlainText());
pSet->setCustomCompileParams(ui->txtCustomCompileParams->toPlainText().trimmed());
pSet->setUseCustomLinkParams(ui->chkUseCustomLinkParams->isChecked());
pSet->setCustomLinkParams(ui->txtCustomLinkParams->toPlainText());
pSet->setStaticLink(ui->chkStaticLink->isChecked());
pSet->setCustomLinkParams(ui->txtCustomLinkParams->toPlainText().trimmed());
pSet->setAutoAddCharsetParams(ui->chkAutoAddCharset->isChecked());
pSet->setCCompiler(ui->txtCCompiler->text());
pSet->setCppCompiler(ui->txtCppCompiler->text());
pSet->setMake(ui->txtMake->text());
pSet->setDebugger(ui->txtDebugger->text());
pSet->setResourceCompiler(ui->txtResourceCompiler->text());
pSet->setProfiler(ui->txtProfiler->text());
pSet->setCCompiler(ui->txtCCompiler->text().trimmed());
pSet->setCppCompiler(ui->txtCppCompiler->text().trimmed());
pSet->setMake(ui->txtMake->text().trimmed());
pSet->setDebugger(ui->txtDebugger->text().trimmed());
pSet->setResourceCompiler(ui->txtResourceCompiler->text().trimmed());
pSet->setProfiler(ui->txtProfiler->text().trimmed());
pSet->binDirs()=mBinDirWidget->dirList();

View File

@ -125,13 +125,6 @@
<item>
<widget class="QPlainTextEdit" name="txtCustomLinkParams"/>
</item>
<item>
<widget class="QCheckBox" name="chkStaticLink">
<property name="text">
<string>Statically Link</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkAutoAddCharset">
<property name="text">

View File

@ -14,7 +14,17 @@
#define CLEAN_PROGRAM "rm.exe"
#define CPP_PROGRAM "cpp.exe"
#define NULL_FILE "NUL"
#ifdef Q_OS_WIN
# define PATH_SENSITIVITY Qt::CaseInsensitive
# define NULL_FILE "NUL"
# define EXECUTABE_EXT ".exe"
#elif Q_OS_LINUX
# define PATH_SENSITIVITY Qt::CaseSensitive
# define NULL_FILE "/dev/null"
# define EXECUTABE_EXT ""
#else
#error "Only support windows and linux now!"
#endif
class SystemConsts
{

View File

@ -1,4 +1,5 @@
#include "utils.h"
#include "systemconsts.h"
#include <QApplication>
#include <QByteArray>
#include <QDir>
@ -9,6 +10,8 @@
#include <QSettings>
#include <QString>
#include <QTextCodec>
#include <QtGlobal>
#include <QDebug>
const QByteArray GuessTextEncoding(const QByteArray& text){
bool allAscii;
@ -93,8 +96,6 @@ QByteArray runAndGetOutput(const QString &cmd, const QString& workingDir, const
process.setProcessEnvironment(QProcessEnvironment());
}
process.setWorkingDirectory(workingDir);
process.start(cmd,arguments,QIODevice::ReadOnly);
process.closeWriteChannel();
process.connect(&process,&QProcess::readyReadStandardError,
[&](){
result.append(process.readAllStandardError());
@ -103,7 +104,10 @@ QByteArray runAndGetOutput(const QString &cmd, const QString& workingDir, const
[&](){
result.append(process.readAllStandardOutput());
});
process.waitForFinished();
process.start(cmd,arguments);
process.closeWriteChannel();
process.waitForFinished(-1);
return result;
}
@ -134,7 +138,7 @@ QString includeTrailingPathDelimiter(const QString &path)
if (path.endsWith('/') || path.endsWith(QDir::separator())) {
return path;
} else {
return path + QDir::separator();
return path + "/";
}
}
@ -145,3 +149,77 @@ QString excludeTrailingPathDelimiter(const QString &path)
pos--;
return path.mid(0,pos+1);
}
FileType getFileType(const QString &filename)
{
if (filename.endsWith(".c",PATH_SENSITIVITY)) {
return FileType::CSource;
}
if (filename.endsWith(".cpp",PATH_SENSITIVITY)) {
return FileType::CppSource;
}
if (filename.endsWith(".cc",PATH_SENSITIVITY)) {
return FileType::CppSource;
}
if (filename.endsWith(".cxx",PATH_SENSITIVITY)) {
return FileType::CppSource;
}
if (filename.endsWith(".c++",PATH_SENSITIVITY)) {
return FileType::CppSource;
}
if (filename.endsWith(".h",PATH_SENSITIVITY)) {
return FileType::CHeader;
}
if (filename.endsWith(".hpp",PATH_SENSITIVITY)) {
return FileType::CppHeader;
}
if (filename.endsWith(".hh",PATH_SENSITIVITY)) {
return FileType::CppHeader;
}
if (filename.endsWith(".hxx",PATH_SENSITIVITY)) {
return FileType::CppHeader;
}
if (filename.endsWith(".inl",PATH_SENSITIVITY)) {
return FileType::CppHeader;
}
if (filename.endsWith(".res",PATH_SENSITIVITY)) {
return FileType::WindowsResourceSource;
}
return FileType::Other;
}
QString getCompiledExecutableName(const QString filename)
{
QFileInfo info(filename);
QString baseName = includeTrailingPathDelimiter(info.absolutePath())+info.baseName();
return baseName + EXECUTABE_EXT;
}
void splitStringArguments(const QString &arguments, QStringList &argumentList)
{
QString word;
bool inQuota;
inQuota = false;
for (QChar ch:arguments) {
if (ch == '"') {
inQuota = !inQuota;
} else if (ch == '\n' || ch == ' ' || ch == '\t' || ch == '\r') {
if (!inQuota) {
word = word.trimmed();
if (!word.isEmpty()) {
argumentList.append(word);
}
word = "";
} else {
word.append(ch);
}
} else {
word.append(ch);
}
}
word = word.trimmed();
if (!word.isEmpty()) {
argumentList.append(word);
}
}

View File

@ -4,7 +4,6 @@
#include <type_traits>
#include <utility>
class QByteArray;
class QString;
class QStringList;
@ -15,6 +14,15 @@ class QStringList;
#define ENCODING_SYSTEM_DEFAULT "SYSTEM"
#define ENCODING_ASCII "ASCII"
enum class FileType{
CSource, // c source file (.c)
CppSource, // c++ source file (.cpp)
CHeader, // c header (.h)
CppHeader, // c++ header (.hpp)
WindowsResourceSource, // resource source (.res)
Other // any others
};
typedef void (*LineOutputFunc) (const QString& line);
typedef bool (*CheckAbortFunc) ();
bool isGreenEdition();
@ -32,6 +40,9 @@ bool fileExists(const QString& dir, const QString& fileName);
bool directoryExists(const QString& file);
QString includeTrailingPathDelimiter(const QString& path);
QString excludeTrailingPathDelimiter(const QString& path);
FileType getFileType(const QString& filename);
QString getCompiledExecutableName(const QString filename);
void splitStringArguments(const QString& arguments, QStringList& argumentList);
template <class F>
class final_action