diff --git a/ide/src/IDESettings.ec b/ide/src/IDESettings.ec index 47c84e5560..5a73376006 100644 --- a/ide/src/IDESettings.ec +++ b/ide/src/IDESettings.ec @@ -140,7 +140,8 @@ CompilerConfig MakeDefaultCompiler(char * name, bool readOnly) ecsDefaultCommand, earDefaultCommand, cppDefaultCommand, - ccDefaultCommand + ccDefaultCommand, + cxxDefaultCommand }; incref defaultCompiler; return defaultCompiler; @@ -745,6 +746,12 @@ public: get { return ccCommand; } isset { return ccCommand && ccCommand[0]; } } + property char * cxxCommand + { + set { delete cxxCommand; if(value && value[0]) cxxCommand = CopyString(value); } + get { return cxxCommand; } + isset { return cxxCommand && cxxCommand[0]; } + } property char * execPrefixCommand { set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); } @@ -830,6 +837,7 @@ private: char * earCommand; char * cppCommand; char * ccCommand; + char * cxxCommand; char * execPrefixCommand; char * distccHosts; /*union @@ -847,6 +855,7 @@ private: delete earCommand; delete cppCommand; delete ccCommand; + delete cxxCommand; delete makeCommand; delete execPrefixCommand; delete distccHosts; @@ -871,6 +880,7 @@ private: earCommand, cppCommand, ccCommand, + cxxCommand, execPrefixCommand, ccacheEnabled, distccEnabled, diff --git a/ide/src/OldIDESettings.ec b/ide/src/OldIDESettings.ec index 7c2d256c3c..8a747b89da 100644 --- a/ide/src/OldIDESettings.ec +++ b/ide/src/OldIDESettings.ec @@ -13,6 +13,7 @@ define ecsCommandSetting = "ECS Command"; define earCommandSetting = "EAR Command"; define cPreprocessorCommandSetting = "C Preprocessor Command"; define cCompilerCommandSetting = "C Compiler Command"; +define cxxCompilerCommandSetting = "C++ Compiler Command"; define projectOptions = "Project Options"; define defaultTargetDir = "Default Target Directory"; @@ -25,6 +26,7 @@ define ecsDefaultCommand = "ecs"; define earDefaultCommand = "ear"; define cppDefaultCommand = "cpp"; define ccDefaultCommand = "gcc"; +define cxxDefaultCommand = "g++"; class OldIDESettings : GlobalAppSettings { @@ -151,6 +153,7 @@ class OldIDESettings : GlobalAppSettings GetGlobalValue(section, earCommandSetting, singleString, &v); compiler.earCommand = v && v[0] ? v : earDefaultCommand; delete v; GetGlobalValue(section, cPreprocessorCommandSetting, singleString, &v); compiler.cppCommand = v && v[0] ? v : cppDefaultCommand; delete v; GetGlobalValue(section, cCompilerCommandSetting, singleString, &v); compiler.ccCommand = v && v[0] ? v : ccDefaultCommand; delete v; + GetGlobalValue(section, cCompilerCommandSetting, singleString, &v); compiler.cxxCommand = v && v[0] ? v : cxxDefaultCommand; delete v; delete section; section = new char[len + 13]; sprintf(section, "%s Directories", configName); @@ -254,6 +257,7 @@ class OldIDESettings : GlobalAppSettings PutGlobalValue(section, earCommandSetting, singleString, compiler.earCommand); PutGlobalValue(section, cPreprocessorCommandSetting, singleString, compiler.cppCommand); PutGlobalValue(section, cCompilerCommandSetting, singleString, compiler.ccCommand); + PutGlobalValue(section, cxxCompilerCommandSetting, singleString, compiler.cxxCommand); delete section; section = new char[len + 13]; sprintf(section, "%s Directories", compiler.name); diff --git a/ide/src/dialogs/GlobalSettingsDialog.ec b/ide/src/dialogs/GlobalSettingsDialog.ec index 3008a5fba1..785cf0216f 100644 --- a/ide/src/dialogs/GlobalSettingsDialog.ec +++ b/ide/src/dialogs/GlobalSettingsDialog.ec @@ -16,7 +16,7 @@ class GlobalSettingsDialog : Window hasClose = true; borderStyle = sizable; text = $"Global Settings"; - minClientSize = { 560, 420 }; + minClientSize = { 560, 446 }; nativeDecorations = true; IDESettings ideSettings; @@ -697,16 +697,22 @@ class CompilerToolchainTab : CompilersSubTab this, anchor = { left = 120, top = 138, right = 8 }; text = $"C Compiler", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument; }; - Label makeLabel { this, position = { 8, 168 }, labeledWindow = make, tabCycle = false, inactive = true }; - PathBox make + Label cxxLabel { this, position = { 8, 168 }, labeledWindow = cxx, tabCycle = false, inactive = true }; + PathBox cxx { this, anchor = { left = 120, top = 164, right = 8 }; + text = $"C++ Compiler", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument; + }; + Label makeLabel { this, position = { 8, 194 }, labeledWindow = make, tabCycle = false, inactive = true }; + PathBox make + { + this, anchor = { left = 120, top = 190, right = 8 }; text = $"GNU Make", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument; }; - Label execPrefixLabel { this, position = { 8, 194 }, labeledWindow = execPrefix, tabCycle = false, inactive = true }; + Label execPrefixLabel { this, position = { 8, 220 }, labeledWindow = execPrefix, tabCycle = false, inactive = true }; PathBox execPrefix { - this, anchor = { left = 120, top = 190, right = 8 }; + this, anchor = { left = 120, top = 216, right = 8 }; text = $"Execution Prefix", browseDialog = toolchainFileDialog, NotifyModified = NotifyModifiedDocument; }; @@ -727,6 +733,8 @@ class CompilerToolchainTab : CompilersSubTab compiler.cppCommand = pathBox.slashPath; else if(pathBox == cc) compiler.ccCommand = pathBox.slashPath; + else if(pathBox == cxx) + compiler.cxxCommand = pathBox.slashPath; else if(pathBox == make) compiler.makeCommand = pathBox.slashPath; else if(pathBox == execPrefix) @@ -750,6 +758,7 @@ class CompilerToolchainTab : CompilersSubTab ear.path = compiler.earCommand; cpp.path = compiler.cppCommand; cc.path = compiler.ccCommand; + cxx.path = compiler.cxxCommand; make.path = compiler.makeCommand; execPrefix.path = compiler.execPrefixCommand; diff --git a/ide/src/project/Project.ec b/ide/src/project/Project.ec index 7b0bab6451..3174460b13 100644 --- a/ide/src/project/Project.ec +++ b/ide/src/project/Project.ec @@ -1191,12 +1191,14 @@ private: char cppCommand[MAX_LOCATION]; char ccCommand[MAX_LOCATION]; + char cxxCommand[MAX_LOCATION]; char ecpCommand[MAX_LOCATION]; char eccCommand[MAX_LOCATION]; char ecsCommand[MAX_LOCATION]; char earCommand[MAX_LOCATION]; char * cc = compiler.ccCommand; + char * cxx = compiler.cxxCommand; char * cpp = compiler.cppCommand; sprintf(cppCommand, "%s%s%s%s ", compiler.ccacheEnabled ? "ccache " : "", @@ -1208,6 +1210,11 @@ private: compiler.ccacheEnabled && !compiler.distccEnabled ? " " : "", compiler.distccEnabled ? "distcc " : "", compiler.ccCommand); + sprintf(cxxCommand, "%s%s%s%s ", + compiler.ccacheEnabled ? "ccache " : "", + compiler.ccacheEnabled && !compiler.distccEnabled ? " " : "", + compiler.distccEnabled ? "distcc " : "", + compiler.cxxCommand); sprintf(ecpCommand, "%s ", compiler.ecpCommand); sprintf(eccCommand, "%s ", compiler.eccCommand); sprintf(ecsCommand, "%s ", compiler.ecsCommand); @@ -1248,14 +1255,14 @@ private: } else if(strstr(line, "ear ") == line); else if(strstr(line, "strip ") == line); - else if(strstr(line, ccCommand) == line || strstr(line, ecpCommand) == line || strstr(line, eccCommand) == line) + else if(strstr(line, ccCommand) == line || strstr(line, cxxCommand) == line || strstr(line, ecpCommand) == line || strstr(line, eccCommand) == line) { char moduleName[MAX_FILENAME]; byte * tokens[1]; char * module; bool isPrecomp = false; - if(strstr(line, ccCommand) == line) + if(strstr(line, ccCommand) == line || strstr(line, cxxCommand) == line) { module = strstr(line, " -c "); if(module) module += 4; @@ -1766,7 +1773,7 @@ private: char path[MAX_LOCATION]; char * name; char * compilerName; - bool gccCompiler = compiler.ccCommand && strstr(compiler.ccCommand, "gcc") != null; + bool gccCompiler = compiler.ccCommand && (strstr(compiler.ccCommand, "gcc") != null || strstr(compiler.ccCommand, "g++") != null); Platform platform = GetRuntimePlatform(); compilerName = CopyString(compiler.name); @@ -1793,6 +1800,7 @@ private: //f.Printf("SHELL := %s\n", "ar"/*compiler.arCommand*/); // is this really needed? f.Printf("CPP := $(CCACHE_COMPILE) $(DISTCC_COMPILE) %s\n", compiler.cppCommand); f.Printf("CC := $(CCACHE_COMPILE) $(DISTCC_COMPILE) %s\n", compiler.ccCommand); + f.Printf("CXX := $(CCACHE_COMPILE) $(DISTCC_COMPILE) %s\n", compiler.cxxCommand); f.Printf("ECP := %s\n", compiler.ecpCommand); f.Printf("ECC := %s\n", compiler.eccCommand); f.Printf("ECS := %s%s%s\n", compiler.ecsCommand, @@ -1897,12 +1905,13 @@ private: // Non-zero if we're building eC code // We'll have to be careful with this when merging configs where eC files can be excluded in some configs and included in others int numCObjects = 0; + bool containsCXX = false; // True if the project contains a C++ file bool sameObjTargetDirs; DirExpression objDirExp = GetObjDir(compiler, config); TargetTypes targetType = GetTargetType(config); bool crossCompiling = compiler.targetPlatform != runtimePlatform; - bool gccCompiler = compiler.ccCommand && strstr(compiler.ccCommand, "gcc") != null; + bool gccCompiler = compiler.ccCommand && (strstr(compiler.ccCommand, "gcc") != null || strstr(compiler.ccCommand, "g++") != null); bool tccCompiler = compiler.ccCommand && strstr(compiler.ccCommand, "tcc") != null; bool defaultPreprocessor = compiler.cppCommand && (strstr(compiler.cppCommand, "gcc") != null || compiler.cppCommand && strstr(compiler.cppCommand, "cpp") != null); char cfDir[MAX_LOCATION]; @@ -2087,7 +2096,7 @@ private: topNode.GenMakefileGetNameCollisionInfo(namesInfo, config); - numCObjects = topNode.GenMakefilePrintNode(f, this, objects, namesInfo, listItems, config); + numCObjects = topNode.GenMakefilePrintNode(f, this, objects, namesInfo, listItems, config, &containsCXX); if(numCObjects) listItems.Add(CopyString("$(OBJ)$(MODULE).main$(O)")); objectsParts = OutputFileList(f, "OBJECTS", listItems, varStringLenDiffs, null); @@ -2096,7 +2105,7 @@ private: int c; char * map[4][2] = { { "COBJECTS", "C" }, { "SYMBOLS", "S" }, { "IMPORTS", "I" }, { "BOWLS", "B" } }; - topNode.GenMakefilePrintNode(f, this, eCsources, namesInfo, listItems, config); + topNode.GenMakefilePrintNode(f, this, eCsources, namesInfo, listItems, config, null); eCsourcesParts = OutputFileList(f, "_ECSOURCES", listItems, varStringLenDiffs, null); f.Printf("ECSOURCES = $(call shwspace,$(_ECSOURCES))\n"); @@ -2125,11 +2134,11 @@ private: } } - topNode.GenMakefilePrintNode(f, this, sources, null, listItems, config); + topNode.GenMakefilePrintNode(f, this, sources, null, listItems, config, null); OutputFileList(f, "SOURCES", listItems, varStringLenDiffs, "$(ECSOURCES)"); if(!noResources) - resNode.GenMakefilePrintNode(f, this, resources, null, listItems, config); + resNode.GenMakefilePrintNode(f, this, resources, null, listItems, config, null); OutputFileList(f, "RESOURCES", listItems, varStringLenDiffs, null); f.Printf("LIBS += $(SHAREDLIB) $(EXECUTABLE) $(LINKOPT)\n\n"); @@ -2404,7 +2413,7 @@ private: f.Printf("$(TARGET): $(SOURCES) $(RESOURCES) $(SYMBOLS) $(OBJECTS) | objdir%s\n", sameObjTargetDirs ? "" : " targetdir"); f.Printf("ifneq \"$(TARGET_TYPE)\" \"%s\"\n", TargetTypeToMakefileVariable(staticLibrary)); - f.Printf("\t$(CC) $(OFLAGS) $(OBJECTS) $(LIBS) -o $(TARGET) $(INSTALLNAME)\n"); + f.Printf("\t$(%s) $(OFLAGS) $(OBJECTS) $(LIBS) %s-o $(TARGET) $(INSTALLNAME)\n", containsCXX ? "CXX" : "CC", containsCXX ? "-lstdc++ " : ""); if(!GetDebug(config)) { f.Printf("ifndef NOSTRIP\n"); diff --git a/ide/src/project/ProjectNode.ec b/ide/src/project/ProjectNode.ec index 5206685c68..9f21cb11f6 100644 --- a/ide/src/project/ProjectNode.ec +++ b/ide/src/project/ProjectNode.ec @@ -1381,7 +1381,7 @@ private: int GenMakefilePrintNode(File f, Project project, GenMakefilePrintTypes printType, Map namesInfo, Array items, - ProjectConfig prjConfig) + ProjectConfig prjConfig, bool * containsCXX) { int count = 0; if(type == file) @@ -1453,6 +1453,8 @@ private: collision = info ? info.IsExtensionColliding(extension) : false; sprintf(s, "%s$(OBJ)%s%s%s.o%s", ts.a, moduleName, collision ? "." : "", collision ? extension : "", ts.b); items.Add(CopyString(s)); + if(containsCXX && (!strcmpi(extension, "cpp") || !strcmpi(extension, "cc") || !strcmpi(extension, "cxx"))) + *containsCXX = true; } } else if(!strcmpi(extension, "ec")) @@ -1480,7 +1482,7 @@ private: for(child : files) { if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig))) - count += child.GenMakefilePrintNode(f, project, printType, namesInfo, items, prjConfig); + count += child.GenMakefilePrintNode(f, project, printType, namesInfo, items, prjConfig, containsCXX); } } return count; @@ -1969,7 +1971,8 @@ private: if(!strcmpi(extension, "ec")) sprintf(command, "%s -MT $(OBJ)%s.o -MM $(OBJ)%s.c", compiler.ccCommand, moduleName, moduleName); else - sprintf(command, "%s -MT $(OBJ)%s.o -MM %s%s.%s", compiler.ccCommand, moduleName, modulePath, moduleName, extension); + sprintf(command, "%s -MT $(OBJ)%s.o -MM %s%s.%s", (!strcmpi(extension, "cc") || !strcmpi(extension, "cxx") || !strcmpi(extension, "cpp")) ? compiler.cxxCommand : compiler.ccCommand, + moduleName, modulePath, moduleName, extension); if(!strcmpi(extension, "ec")) f.Printf("$(OBJ)%s.o: $(OBJ)%s.c\n", moduleName, moduleName); @@ -2054,7 +2057,7 @@ private: } #endif } - f.Printf("\t$(CC)"); + f.Printf("\t$(%s)", (!strcmpi(extension, "cc") || !strcmpi(extension, "cpp") || !strcmpi(extension, "cxx")) ? "CXX" : "CC"); // Give priority to file flags GenFileFlags(f, project, prjConfig);