work save

This commit is contained in:
royqh1979@gmail.com 2021-09-13 10:48:44 +08:00
parent e03f537a4e
commit fc34defe13
7 changed files with 227 additions and 24 deletions

View File

@ -280,14 +280,27 @@ QString Compiler::getCCompileArguments(bool checkSyntax)
result += " -fsyntax-only";
}
foreach (const 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];
for (int i=0;i<compilerSet()->options().size();i++) {
PCompilerOption pOption = compilerSet()->options()[i];
// consider project specific options for the compiler, else global compiler options
if (
(mProject && (i < mProject->options().compilerOptions.length()))
|| (!mProject && (pOption->value > 0))) {
int value;
if (mProject) {
value = Settings::CompilerSet::charToValue(mProject->options().compilerOptions[i]);
} else {
value = pOption->value;
}
if (value > 0 && pOption->isC) {
if (pOption->choices.isEmpty()) {
result += " " + pOption->setting;
} else if (value < pOption->choices.size()) {
QStringList nameValue=pOption->choices[value].split('=');
if (nameValue.count()==2) {
result += " " + pOption->setting + nameValue[1];
}
}
}
}
@ -301,6 +314,7 @@ QString Compiler::getCCompileArguments(bool checkSyntax)
QString Compiler::getCppCompileArguments(bool checkSyntax)
{
return getCCompileArguments(checkSyntax);
QString result;
if (checkSyntax) {
result += " -fsyntax-only";

View File

@ -1,5 +1,9 @@
#include "projectcompiler.h"
#include "project.h"
#include "compilermanager.h"
#include "../systemconsts.h"
#include <QDir>
ProjectCompiler::ProjectCompiler(std::shared_ptr<Project> project, bool silent, bool onlyCheckSyntax):
Compiler("",silent,onlyCheckSyntax)
@ -9,9 +13,9 @@ ProjectCompiler::ProjectCompiler(std::shared_ptr<Project> project, bool silent,
void ProjectCompiler::buildMakeFile()
{
if (mProject->options().useCustomMakefile)
mMakefileName = mProject->options().customMakefile;
return;
//we are using custom make file, don't overwrite it
if (!mProject->options().customMakefile.isEmpty())
return;
switch(mProject->options().type) {
case ProjectType::StaticLib:
@ -25,11 +29,188 @@ void ProjectCompiler::buildMakeFile()
}
}
void ProjectCompiler::createStandardMakeFile()
{
QFile file(mProject->makeFileName());
newMakeFile(file);
file.write("$(BIN): $(OBJ)\n");
if (!mOnlyCheckSyntax) {
if (mProject->options().useGPP) {
writeln(file,"$(BIN): $(OBJ)");
writeln(file,"\t$(CPP) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)");
} else
writeln(file,"\t$(CC) $(LINKOBJ) -o \"$(BIN)\" $(LIBS)");
}
writeMakeObjFilesRules(file);
}
void ProjectCompiler::newMakeFile(QFile& file)
{
// Create OBJ output directory
if (!mProject->options().objectOutput.isEmpty()) {
QDir(mProject->directory()).mkpath(mProject->options().objectOutput);
}
// 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 ProjectCompiler::writeMakeHeader(QFile &file)
{
writeln(file,"# Project: " + mProject->name());
writeln(file,QString("# Makefile created by Red Panda Dev-C++ ") + DEVCPP_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)
{
// Get list of object files
QString Objects;
QString LinkObjects;
// Create a list of object files
for (int i=0;i<mProject->units().count();i++) {
PProjectUnit unit = mProject[i];
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) {
if (!mProject->options().objectOutput.isEmpty()) {
// ofile = C:\MyProgram\obj\main.o
QString ObjFile = includeTrailingPathDelimiter(mProject->options().objectOutput)
+ extractFileName(unit->fileName());
ObjFile = genMakePath1(extractRelativePath(mProject->directory(), changeFileExt(ObjFile, OBJ_EXT)));
Objects += ' ' + ObjFile;
if (unit->link())
LinkObjects += ' ' + ObjFile;
} else {
Objects += ' ' + genMakePath1(changeFileExt(RelativeName, OBJ_EXT));
if (unit->link())
LinkObjects = LinkObjects + ' ' + genMakePath1(changeFileExt(RelativeName, OBJ_EXT));
}
}
}
Objects = Objects.trimmed();
LinkObjects = LinkObjects.trimmed();
// Get windres file
QString ObjResFile;
if (!mProject->options().privateResource.isEmpty()) {
if (!mProject->options().objectOutput.isEmpty()) {
ObjResFile = includeTrailingPathDelimiter(mProject->options().objectOutput) +
changeFileExt(mProject->options().privateResource, RES_EXT);
} else
ObjResFile = changeFileExt(mProject->options().privateResource, RES_EXT);
}
// Mention progress in the logs
if (!ObjResFile.isEmpty()) {
log(tr("- Resource File: %1").arg(QDir(mProject->directory()).absoluteFilePath(ObjResFile)));
}
log("");
// Get list of applicable flags
QString cCompileArguments = getCCompileArguments(mOnlyCheckSyntax);
QString cppCompileArguments = getCppCompileArguments(mOnlyCheckSyntax);
QString libraryArguments = getLibraryArguments();
QString cIncludeArguments = getCIncludeArguments();
QString cppIncludeArguments = getCppIncludeArguments();
QString projectIncludeArguments = getProjectIncludeArguments();
if (Pos(' -g3', fCompileParams) > 0) or (Pos('-g3', fCompileParams) = 1) then begin
Writeln(F, 'CPP = ' + fCompilerSet.gppName + ' -D__DEBUG__');
Writeln(F, 'CC = ' + fCompilerSet.gccName + ' -D__DEBUG__');
end else begin
Writeln(F, 'CPP = ' + fCompilerSet.gppName);
Writeln(F, 'CC = ' + fCompilerSet.gccName);
end;
Writeln(F, 'WINDRES = ' + fCompilerSet.windresName);
if (ObjResFile <> '') then begin
Writeln(F, 'RES = ' + GenMakePath1(ObjResFile));
Writeln(F, 'OBJ = ' + Objects + ' $(RES)');
Writeln(F, 'LINKOBJ = ' + LinkObjects + ' $(RES)');
end else begin
Writeln(F, 'OBJ = ' + Objects);
Writeln(F, 'LINKOBJ = ' + LinkObjects);
end;
Writeln(F, 'LIBS = ' + StringReplace(fLibrariesParams, '\', '/', [rfReplaceAll]));
Writeln(F, 'INCS = ' + StringReplace(fIncludesParams, '\', '/', [rfReplaceAll]));
Writeln(F, 'CXXINCS = ' + StringReplace(fCppIncludesParams, '\', '/', [rfReplaceAll]));
Writeln(F, 'BIN = ' + GenMakePath1(ExtractRelativePath(Makefile, fProject.Executable)));
Writeln(F, 'CXXFLAGS = $(CXXINCS) ' + fCppCompileParams);
Writeln(F, 'ENCODINGS = -finput-charset=utf-8 -fexec-charset='+GetSystemCharsetName);
Writeln(F, 'CFLAGS = $(INCS) ' + fCompileParams);
// Writeln(F, 'RM = ' + CLEAN_PROGRAM + ' -f'); // TODO: use del or rm?
Writeln(F, 'RM = ' + CLEAN_PROGRAM + ' /f'); // TODO: use del or rm?
if fProject.Options.UsePrecompiledHeader then begin
Writeln(F, 'PCH_H = ' + fProject.Options.PrecompiledHeader );
Writeln(F, 'PCH = ' + fProject.Options.PrecompiledHeader +'.gch' );
end;
// This needs to be put in before the clean command.
if fProject.Options.typ = dptDyn then begin
OutputFileDir := ExtractFilePath(Project.Executable);
LibOutputFile := OutputFileDir + 'lib' + ExtractFileName(Project.Executable);
if FileSamePath(LibOutputFile, Project.Directory) then
LibOutputFile := ExtractFileName(LibOutputFile)
else
LibOutputFile := ExtractRelativePath(Makefile, LibOutputFile);
Writeln(F, 'DEF = ' + GenMakePath1(ChangeFileExt(LibOutputFile, DEF_EXT)));
Writeln(F, 'STATIC = ' + GenMakePath1(ChangeFileExt(LibOutputFile, LIB_EXT)));
end;
Writeln(F);
}
void ProjectCompiler::writeln(QFile &file, const QString &s)
{
if (!s.isEmpty())
file.write(s.toLocal8Bit());
file.write("\n");
}
QString ProjectCompiler::pipedText()
{
return QString();
}
bool ProjectCompiler::prepareForRebuild()
{
//we use make argument to clean
return true;
}
bool ProjectCompiler::prepareForCompile()
{
if (!mProject)
@ -43,6 +224,10 @@ bool ProjectCompiler::prepareForCompile()
buildMakeFile();
mCompiler = QString("%1 -f \"%2\" all").arg(compilerSet()->make(),
mMakefileName);
mCompiler = compilerSet()->make();
if (mRebuild) {
mArguments = QString("-f \"%1\" clean all").arg(mProject->makeFileName());
} else {
mArguments = QString("-f \"%1\" all").arg(mProject->makeFileName());
}
}

View File

@ -13,13 +13,16 @@ public:
private:
void buildMakeFile();
void createStandardMakeFile();
void newMakeFile(QFile& file);
void writeMakeHeader(QFile& file);
void writeMakeDefines(QFile& file);
void writeln(QFile& file, const QString& s="");
// Compiler interface
protected:
bool prepareForCompile() override;
QString pipedText() override;
bool prepareForRebuild() override;
private:
QString mMakefileName;
};
#endif // PROJECTCOMPILER_H

View File

@ -540,7 +540,7 @@ bool Project::saveUnits()
return true;
}
void Project::setCompilerOption(const QString &optionString, const QChar &value)
void Project::setCompilerOption(const QString &optionString, char value)
{
if (mOptions.compilerSet<0 || mOptions.compilerSet>=pSettings->compilerSets().size()) {
return;
@ -607,7 +607,7 @@ void Project::saveOptions()
ini.SetBoolValue("Project","IncludeVersionInfo", mOptions.includeVersionInfo);
ini.SetBoolValue("Project","SupportXPThemes", mOptions.supportXPThemes);
ini.SetLongValue("Project","CompilerSet", mOptions.compilerSet);
ini.SetValue("Project","CompilerSettings", toByteArray(mOptions.compilerOptions));
ini.SetValue("Project","CompilerSettings", mOptions.compilerOptions);
ini.SetBoolValue("Project","StaticLink", mOptions.staticLink);
ini.SetBoolValue("Project","AddCharset", mOptions.addCharset);
ini.SetValue("Project","Encoding",toByteArray(mOptions.encoding));
@ -1103,7 +1103,7 @@ PFolderNode Project::folderNodeFromName(const QString &name)
return mNode;
}
QChar Project::getCompilerOption(const QString &optionString)
char Project::getCompilerOption(const QString &optionString)
{
// Does the option exist?
Settings::PCompilerSet compilerSet = pSettings->compilerSets().getSet(mOptions.compilerSet);
@ -1241,7 +1241,7 @@ void Project::loadOptions(SimpleIni& ini)
mOptions.compilerSet = pSettings->compilerSets().defaultIndex();
setModified(true);
}
mOptions.compilerOptions = fromByteArray(ini.GetValue("Project", "CompilerSettings", ""));
mOptions.compilerOptions = ini.GetValue("Project", "CompilerSettings", "");
mOptions.staticLink = ini.GetBoolValue("Project", "StaticLink", true);
mOptions.addCharset = ini.GetBoolValue("Project", "AddCharset", true);
bool useUTF8 = ini.GetBoolValue("Project", "UseUTF8", false);

View File

@ -130,7 +130,7 @@ struct ProjectOptions{
bool includeVersionInfo;
bool supportXPThemes;
int compilerSet;
QString compilerOptions;
QByteArray compilerOptions;
ProjectVersionInfo versionInfo;
QString cmdLineArgs;
bool staticLink;
@ -181,7 +181,7 @@ public:
void doAutoOpen();
bool fileAlreadyExists(const QString& s);
PFolderNode folderNodeFromName(const QString& name);
QChar getCompilerOption(const QString& optionString);
char getCompilerOption(const QString& optionString);
QString getFolderPath(PFolderNode node);
int getUnitFromString(const QString& s);
void incrementBuildNumber();
@ -206,7 +206,7 @@ public:
void saveUnitAs(int i, const QString& sFileName); // save single [UnitX]
void saveUnitLayout(Editor* e, int index); // save single [UnitX] cursor positions
bool saveUnits();
void setCompilerOption(const QString& optionString, const QChar& value);
void setCompilerOption(const QString& optionString, char value);
void sortUnitsByPriority();
void sortUnitsByAlpha();
void updateFolders();

View File

@ -871,9 +871,9 @@ public:
bool staticLink() const;
void setStaticLink(bool newStaticLink);
private:
int charToValue(char valueChar);
static int charToValue(char valueChar);
private:
// Initialization
void setExecutables();
void setUserInput();

View File

@ -22,6 +22,7 @@
#define RC_EXT "rc"
#define RES_EXT "rc"
#define H_EXT "h"
#define OBJ_EXT "o"
#define DEV_INTERNAL_OPEN "$__DEV_INTERNAL_OPEN"
#ifdef Q_OS_WIN