/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. Copyright (c) 2004 Alexander Neundorf neundorf@kde.org, All rights reserved. Copyright (c) 2007 Miguel A. Figueroa-Villanueva. All rights reserved. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "cmExtraEclipseCDT4Generator.h" #include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmGeneratedFileStream.h" #include "cmTarget.h" #include "cmSystemTools.h" //---------------------------------------------------------------------------- cmExtraEclipseCDT4Generator ::cmExtraEclipseCDT4Generator() : cmExternalMakefileProjectGenerator() { #if defined(_WIN32) this->SupportedGlobalGenerators.push_back("NMake Makefiles"); // this->SupportedGlobalGenerators.push_back("MSYS Makefiles"); // this->SupportedGlobalGenerators.push_back("MinGW Makefiles"); #endif this->SupportedGlobalGenerators.push_back("Unix Makefiles"); } //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator ::GetDocumentation(cmDocumentationEntry& entry, const char*) const { entry.name = this->GetName(); entry.brief = "Generates Eclipse CDT 4.0 project files."; entry.full = "Project files for Eclipse will be created in the top directory " "and will have a linked resource to every subdirectory which " "features a CMakeLists.txt file containing a PROJECT() call." "Additionally a hierarchy of makefiles is generated into the " "build tree. The appropriate make program can build the project through " "the default make target. A \"make install\" target is also provided."; } //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator ::SetGlobalGenerator(cmGlobalGenerator* generator) { cmExternalMakefileProjectGenerator::SetGlobalGenerator(generator); cmGlobalUnixMakefileGenerator3* mf = static_cast(generator); mf->SetToolSupportsColor(false); mf->SetForceVerboseMakefiles(true); mf->EnableInstallTarget(); } //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator::Generate() { // create a .project file this->CreateProjectFile(); // create a .cproject file this->CreateCProjectFile(); } //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator::CreateProjectFile() const { const cmMakefile* mf = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile(); std::string filename = mf->GetStartOutputDirectory(); filename = filename + "/" + ".project"; cmGeneratedFileStream fout(filename.c_str()); if (!fout) { return; } fout << "\n" "\n" "\t" << mf->GetProjectName() << "\n" "\t\n" "\t\n" "\t\n" "\t\n" "\t\t\n" "\t\t\torg.eclipse.cdt.make.core.makeBuilder\n" "\t\t\tclean,full,incremental,\n" "\t\t\t\n" ; // use clean target... fout << "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.cleanBuildTarget\n" "\t\t\t\t\tclean\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.enableCleanBuild\n" "\t\t\t\t\ttrue\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.append_environment\n" "\t\t\t\t\ttrue\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.stopOnError\n" "\t\t\t\t\ttrue\n" "\t\t\t\t\n" ; // set the make command... std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); //fout << "\t\t\t\t\n" // "\t\t\t\t\torg.eclipse.cdt.make.core.buildCommand\n" // "\t\t\t\t\t" + make + "\n" // "\t\t\t\t\n" // ; fout << "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.enabledIncrementalBuild\n" "\t\t\t\t\ttrue\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.command\n" "\t\t\t\t\t" + make + "\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.contents\n" "\t\t\t\t\torg.eclipse.cdt.make.core.activeConfigSettings\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.target.inc\n" "\t\t\t\t\tall\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.arguments\n" "\t\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.buildLocation\n" "\t\t\t\t\t" << this->GetEclipsePath(mf->GetStartOutputDirectory()) << "\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.useDefaultBuildCmd\n" "\t\t\t\t\tfalse\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.environment\n" "\t\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.enableFullBuild\n" "\t\t\t\t\ttrue\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.target.auto\n" "\t\t\t\t\tall\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.enableAutoBuild\n" "\t\t\t\t\tfalse\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.target.clean\n" "\t\t\t\t\tclean\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.fullBuildTarget\n" "\t\t\t\t\tall\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.buildArguments\n" "\t\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.build.location\n" "\t\t\t\t\t" << this->GetEclipsePath(mf->GetStartOutputDirectory()) << "\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.make.core.autoBuildTarget\n" "\t\t\t\t\tall\n" "\t\t\t\t\n" "\t\t\t\t\n" "\t\t\t\t\torg.eclipse.cdt.core.errorOutputParser\n" "\t\t\t\t\t" "org.eclipse.cdt.core.MakeErrorParser;" "org.eclipse.cdt.core.GCCErrorParser;" "org.eclipse.cdt.core.GASErrorParser;" "org.eclipse.cdt.core.GLDErrorParser;" // *** "org.eclipse.cdt.core.VCErrorParser;" "\n" "\t\t\t\t\n" "\t\t\t\n" "\t\t\n" "\t\t\n" "\t\t\torg.eclipse.cdt.make.core.ScannerConfigBuilder\n" "\t\t\t\n" "\t\t\t\n" "\t\t\n" "\t\n" "\t\n" // *** ccnature only if it is c++ ??? "\t\torg.eclipse.cdt.core.ccnature\n" "\t\torg.eclipse.cdt.make.core.makeNature\n" "\t\torg.eclipse.cdt.make.core.ScannerConfigNature\n" "\t\torg.eclipse.cdt.core.cnature\n" "\t\n" "\t\n" ; // for each sub project create a linked resource to the source dir for (std::map >::const_iterator it = this->GlobalGenerator->GetProjectMap().begin(); it != this->GlobalGenerator->GetProjectMap().end(); ++it) { fout << "\t\t\n" "\t\t\t" << it->first << "\n" "\t\t\t2\n" "\t\t\t" << this->GetEclipsePath( it->second[0]->GetMakefile()->GetStartDirectory()) << "\n" "\t\t\n" ; } fout << "\t\n" "\n" ; } //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator::CreateCProjectFile() const { std::set emmited; const cmMakefile* mf = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile(); std::string filename = mf->GetStartOutputDirectory(); filename = filename + "/" + ".cproject"; cmGeneratedFileStream fout(filename.c_str()); if (!fout) { return; } // add header fout << "\n" "\n\n" "\n" "\n" ; fout << "\n"; // *** what is this... fout << "\n" "\n" "\n" ; // *** refactor this out... switch (GetToolChainType(*mf)) { case EclipseToolchainLinux : fout << "\n" ; fout << "\n" "\n" "\n" "\n" ; break; case EclipseToolchainCygwin : fout << "\n" "\n" "\n" "\n" "\n" "\n" ; break; case EclipseToolchainMinGW : fout << "\n" ; break; case EclipseToolchainSolaris : fout << "\n" ; break; case EclipseToolchainMacOSX : fout << "\n" "\n" "\n" ; break; case EclipseToolchainOther : fout << "\n" ; fout << "\n" ; break; default : // *** Should never get here *** fout << "\n"; } fout << "\n" "\n" ; // ??? fout << "\n" "\n" "\n" ; // ??? fout<<"\n" ; // set the path entries (includes, libs, source dirs, etc.) fout << "\n" ; // for each sub project with a linked resource to the source dir: // - make it type 'src' // - and exclude it from type 'out' std::string exclude_from_out; for (std::map >::const_iterator it = this->GlobalGenerator->GetProjectMap().begin(); it != this->GlobalGenerator->GetProjectMap().end(); ++it) { fout << "first << "\"/>\n" ; exclude_from_out += it->first + "/,"; } exclude_from_out.resize(exclude_from_out.size()-1); fout << "\n" ; // include dirs emmited.clear(); for (std::vector::const_iterator it = this->GlobalGenerator->GetLocalGenerators().begin(); it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) { const std::vector& includeDirs = (*it)->GetMakefile()->GetIncludeDirectories(); for(std::vector::const_iterator inc = includeDirs.begin(); inc != includeDirs.end(); ++inc) { if(emmited.find(*inc) == emmited.end()) { emmited.insert(*inc); fout << "GetEclipsePath(*inc) << "\" kind=\"inc\" path=\"\" system=\"true\"/>\n"; } } } fout << "\n" ; // add build targets fout << "\n" "\n" ; emmited.clear(); for (std::vector::const_iterator it = this->GlobalGenerator->GetLocalGenerators().begin(); it != this->GlobalGenerator->GetLocalGenerators().end(); ++it) { const cmTargets& targets = (*it)->GetMakefile()->GetTargets(); for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t) { if(emmited.find(t->first) == emmited.end()) { emmited.insert(t->first); this->AppendTarget(fout, t->first); } } } fout << "\n" "\n" ; this->AppendStorageScanners(fout, *mf); fout << "\n" "\n" "\n" "GetProjectName() << ".null.1\"" " name=\"" << mf->GetProjectName() << "\"/>\n" "\n" "\n" ; } //---------------------------------------------------------------------------- cmExtraEclipseCDT4Generator::EclipseToolchainType cmExtraEclipseCDT4Generator::GetToolChainType(const cmMakefile& makefile) const { if (makefile.IsSet("UNIX")) { if (makefile.IsSet("CYGWIN")) { return EclipseToolchainCygwin; } if (makefile.IsSet("APPLE" )) { return EclipseToolchainMacOSX; } // *** how do I determine if it is Solaris ??? return EclipseToolchainLinux; } else if (makefile.IsSet("WIN32")) { if (makefile.IsSet("MINGW")) { return EclipseToolchainMinGW; } if (makefile.IsSet("MSYS" )) { return EclipseToolchainMinGW; } return EclipseToolchainOther; } else { return EclipseToolchainOther; } } std::string cmExtraEclipseCDT4Generator::GetEclipsePath(const std::string& path) const { #if defined(__CYGWIN__) std::string cmd = "cygpath -w " + path; std::string out; if (!cmSystemTools::RunCommand(cmd.c_str(), out, 0, false)) { return path; } else { out.erase(out.find_last_of('\n')); return out; } #else return path; #endif } //---------------------------------------------------------------------------- // Helper functions //---------------------------------------------------------------------------- void cmExtraEclipseCDT4Generator ::AppendStorageScanners(cmGeneratedFileStream& fout, const cmMakefile& /* makefile*/) const { fout << "\n" "\n" ; this->AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile", true, "", true, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile", true, "", true, "makefileGenerator", "-f ${project_name}_scd.mk", "make", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); this->AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); /* // *** this needs to be conditional on platform ??? fout << "\n" "\n" ; AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile", true, "", true, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile", true, "", true, "makefileGenerator", "-f ${project_name}_scd.mk", "make", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC", true, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); // *** this needs to be conditional on platform ??? fout << "\n" "\n" "\n" ; AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile", true, "", true, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile", true, "", true, "makefileGenerator", "-f ${project_name}_scd.mk", "make", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/${specs_file}", "gcc", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.cpp", "g++", true, true); AppendScannerProfile(fout, "org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC", false, "", false, "specsFile", "-E -P -v -dD ${plugin_state_location}/specs.c", "gcc", true, true); fout << "\n" ; */ fout << "\n" ; } void cmExtraEclipseCDT4Generator ::AppendTarget(cmGeneratedFileStream& fout, const std::string& target) const { const cmMakefile& mf = *(this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile()); std::string make = mf.GetRequiredDefinition("CMAKE_MAKE_PROGRAM"); fout << "\n" "" << make << "\n" "\n" "" << target << "\n" "true\n" "false\n" "\n" ; } void cmExtraEclipseCDT4Generator ::AppendScannerProfile(cmGeneratedFileStream& fout, const std::string& profileID, bool openActionEnabled, const std::string& openActionFilePath, bool pParserEnabled, const std::string& scannerInfoProviderID, const std::string& runActionArguments, const std::string& runActionCommand, bool runActionUseDefault, bool sipParserEnabled) const { fout << "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" ; }