2 #include "FirstConfigure.h"
5 #include <QRadioButton>
9 #include "cmStringAlgorithms.h"
11 #include "Compilers.h"
13 StartCompilerSetup::StartCompilerSetup(QString defaultGeneratorPlatform,
14 QString defaultGeneratorToolset,
17 , DefaultGeneratorPlatform(std::move(defaultGeneratorPlatform))
18 , DefaultGeneratorToolset(std::move(defaultGeneratorToolset))
20 QVBoxLayout* l = new QVBoxLayout(this);
21 l->addWidget(new QLabel(tr("Specify the generator for this project")));
22 this->GeneratorOptions = new QComboBox(this);
23 l->addWidget(this->GeneratorOptions);
25 // Add the generator platform
26 this->PlatformFrame = CreatePlatformWidgets();
27 l->addWidget(PlatformFrame);
29 // Add the ability to specify toolset (-T parameter)
30 this->ToolsetFrame = CreateToolsetWidgets();
31 l->addWidget(ToolsetFrame);
35 this->CompilerSetupOptions[0] =
36 new QRadioButton(tr("Use default native compilers"), this);
37 this->CompilerSetupOptions[1] =
38 new QRadioButton(tr("Specify native compilers"), this);
39 this->CompilerSetupOptions[2] =
40 new QRadioButton(tr("Specify toolchain file for cross-compiling"), this);
41 this->CompilerSetupOptions[3] =
42 new QRadioButton(tr("Specify options for cross-compiling"), this);
43 l->addWidget(this->CompilerSetupOptions[0]);
44 l->addWidget(this->CompilerSetupOptions[1]);
45 l->addWidget(this->CompilerSetupOptions[2]);
46 l->addWidget(this->CompilerSetupOptions[3]);
48 this->CompilerSetupOptions[0]->setChecked(true);
50 QObject::connect(this->CompilerSetupOptions[0], &QRadioButton::toggled, this,
51 &StartCompilerSetup::onSelectionChanged);
52 QObject::connect(this->CompilerSetupOptions[1], &QRadioButton::toggled, this,
53 &StartCompilerSetup::onSelectionChanged);
54 QObject::connect(this->CompilerSetupOptions[2], &QRadioButton::toggled, this,
55 &StartCompilerSetup::onSelectionChanged);
56 QObject::connect(this->CompilerSetupOptions[3], &QRadioButton::toggled, this,
57 &StartCompilerSetup::onSelectionChanged);
59 this->GeneratorOptions,
60 static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
61 this, &StartCompilerSetup::onGeneratorChanged);
64 QFrame* StartCompilerSetup::CreateToolsetWidgets()
66 QFrame* frame = new QFrame(this);
67 QVBoxLayout* l = new QVBoxLayout(frame);
68 l->setContentsMargins(0, 0, 0, 0);
70 ToolsetLabel = new QLabel(tr("Optional toolset to use (argument to -T)"));
71 l->addWidget(ToolsetLabel);
73 Toolset = new QLineEdit(frame);
74 l->addWidget(Toolset);
76 // Default to CMAKE_GENERATOR_TOOLSET env var if set
77 if (!DefaultGeneratorToolset.isEmpty()) {
78 this->Toolset->setText(DefaultGeneratorToolset);
83 QFrame* StartCompilerSetup::CreatePlatformWidgets()
85 QFrame* frame = new QFrame(this);
86 QVBoxLayout* l = new QVBoxLayout(frame);
87 l->setContentsMargins(0, 0, 0, 0);
89 this->PlatformLabel = new QLabel(tr("Optional platform for generator"));
90 l->addWidget(this->PlatformLabel);
92 this->PlatformOptions = new QComboBox(frame);
93 this->PlatformOptions->setEditable(true);
95 l->addWidget(this->PlatformOptions);
100 StartCompilerSetup::~StartCompilerSetup() = default;
102 void StartCompilerSetup::setGenerators(
103 std::vector<cmake::GeneratorInfo> const& gens)
105 this->GeneratorOptions->clear();
107 QStringList generator_list;
109 for (cmake::GeneratorInfo const& gen : gens) {
110 generator_list.append(QString::fromStdString(gen.name));
112 if (gen.supportsPlatform) {
113 this->GeneratorsSupportingPlatform.append(
114 QString::fromStdString(gen.name));
116 this->GeneratorDefaultPlatform[QString::fromStdString(gen.name)] =
117 QString::fromStdString(gen.defaultPlatform);
119 auto platformIt = gen.supportedPlatforms.cbegin();
120 while (platformIt != gen.supportedPlatforms.cend()) {
122 this->GeneratorSupportedPlatforms.insert(
123 QString::fromStdString(gen.name),
124 QString::fromStdString((*platformIt)));
130 if (gen.supportsToolset) {
131 this->GeneratorsSupportingToolset.append(
132 QString::fromStdString(gen.name));
136 this->GeneratorOptions->addItems(generator_list);
139 void StartCompilerSetup::setCurrentGenerator(const QString& gen)
141 int idx = this->GeneratorOptions->findText(gen);
143 this->GeneratorOptions->setCurrentIndex(idx);
147 void StartCompilerSetup::setPlatform(const QString& platform)
149 this->PlatformOptions->setCurrentText(platform);
152 void StartCompilerSetup::setToolset(const QString& toolset)
154 this->Toolset->setText(toolset);
157 void StartCompilerSetup::setCompilerOption(CompilerOption option)
159 std::size_t index = 0;
161 case CompilerOption::DefaultNative:
164 case CompilerOption::SpecifyNative:
167 case CompilerOption::ToolchainFile:
170 case CompilerOption::Options:
174 this->CompilerSetupOptions[index]->setChecked(true);
177 QString StartCompilerSetup::getGenerator() const
179 return this->GeneratorOptions->currentText();
182 QString StartCompilerSetup::getPlatform() const
184 return this->PlatformOptions->currentText();
187 QString StartCompilerSetup::getToolset() const
189 return this->Toolset->text();
192 bool StartCompilerSetup::defaultSetup() const
194 return this->CompilerSetupOptions[0]->isChecked();
197 bool StartCompilerSetup::compilerSetup() const
199 return this->CompilerSetupOptions[1]->isChecked();
202 bool StartCompilerSetup::crossCompilerToolChainFile() const
204 return this->CompilerSetupOptions[2]->isChecked();
207 bool StartCompilerSetup::crossCompilerSetup() const
209 return this->CompilerSetupOptions[3]->isChecked();
212 void StartCompilerSetup::onSelectionChanged(bool on)
215 emit selectionChanged();
219 void StartCompilerSetup::onGeneratorChanged(int index)
221 QString name = this->GeneratorOptions->itemText(index);
223 // Display the generator platform for the generators supporting it
224 if (GeneratorsSupportingPlatform.contains(name)) {
226 // Change the label title to include the default platform
228 cmStrCat("Optional platform for generator(if empty, generator uses: ",
229 this->GeneratorDefaultPlatform[name].toStdString(), ')');
230 this->PlatformLabel->setText(tr(label.c_str()));
232 // Regenerate the list of supported platform
233 this->PlatformOptions->clear();
234 QStringList platform_list;
235 platform_list.append("");
237 QList<QString> platforms = this->GeneratorSupportedPlatforms.values(name);
238 platform_list.append(platforms);
240 this->PlatformOptions->addItems(platform_list);
241 PlatformFrame->show();
243 // Default to generator platform from environment
244 if (!DefaultGeneratorPlatform.isEmpty()) {
245 int platform_index = platforms.indexOf(DefaultGeneratorPlatform);
246 if (platform_index != -1) {
247 this->PlatformOptions->setCurrentIndex(platform_index);
251 PlatformFrame->hide();
254 // Display the toolset box for the generators supporting it
255 if (GeneratorsSupportingToolset.contains(name)) {
256 ToolsetFrame->show();
258 ToolsetFrame->hide();
262 int StartCompilerSetup::nextId() const
264 if (compilerSetup()) {
267 if (crossCompilerSetup()) {
270 if (crossCompilerToolChainFile()) {
271 return ToolchainSetup;
276 NativeCompilerSetup::NativeCompilerSetup(QWidget* p)
279 QVBoxLayout* l = new QVBoxLayout(this);
280 QWidget* c = new QWidget(this);
285 NativeCompilerSetup::~NativeCompilerSetup() = default;
287 QString NativeCompilerSetup::getCCompiler() const
289 return this->CCompiler->text();
292 void NativeCompilerSetup::setCCompiler(const QString& s)
294 this->CCompiler->setText(s);
297 QString NativeCompilerSetup::getCXXCompiler() const
299 return this->CXXCompiler->text();
302 void NativeCompilerSetup::setCXXCompiler(const QString& s)
304 this->CXXCompiler->setText(s);
307 QString NativeCompilerSetup::getFortranCompiler() const
309 return this->FortranCompiler->text();
312 void NativeCompilerSetup::setFortranCompiler(const QString& s)
314 this->FortranCompiler->setText(s);
317 CrossCompilerSetup::CrossCompilerSetup(QWidget* p)
321 QWidget::setTabOrder(systemName, systemVersion);
322 QWidget::setTabOrder(systemVersion, systemProcessor);
323 QWidget::setTabOrder(systemProcessor, CrossCompilers->CCompiler);
324 QWidget::setTabOrder(CrossCompilers->CCompiler, CrossCompilers->CXXCompiler);
325 QWidget::setTabOrder(CrossCompilers->CXXCompiler,
326 CrossCompilers->FortranCompiler);
327 QWidget::setTabOrder(CrossCompilers->FortranCompiler, crossFindRoot);
328 QWidget::setTabOrder(crossFindRoot, crossProgramMode);
329 QWidget::setTabOrder(crossProgramMode, crossLibraryMode);
330 QWidget::setTabOrder(crossLibraryMode, crossIncludeMode);
332 // fill in combo boxes
334 modes << tr("Search in Target Root, then native system");
335 modes << tr("Search only in Target Root");
336 modes << tr("Search only in native system");
337 crossProgramMode->addItems(modes);
338 crossLibraryMode->addItems(modes);
339 crossIncludeMode->addItems(modes);
340 crossProgramMode->setCurrentIndex(2);
341 crossLibraryMode->setCurrentIndex(1);
342 crossIncludeMode->setCurrentIndex(1);
344 this->registerField("systemName*", this->systemName);
347 CrossCompilerSetup::~CrossCompilerSetup() = default;
349 QString CrossCompilerSetup::getCCompiler() const
351 return this->CrossCompilers->CCompiler->text();
354 void CrossCompilerSetup::setCCompiler(const QString& s)
356 this->CrossCompilers->CCompiler->setText(s);
359 QString CrossCompilerSetup::getCXXCompiler() const
361 return this->CrossCompilers->CXXCompiler->text();
364 void CrossCompilerSetup::setCXXCompiler(const QString& s)
366 this->CrossCompilers->CXXCompiler->setText(s);
369 QString CrossCompilerSetup::getFortranCompiler() const
371 return this->CrossCompilers->FortranCompiler->text();
374 void CrossCompilerSetup::setFortranCompiler(const QString& s)
376 this->CrossCompilers->FortranCompiler->setText(s);
379 QString CrossCompilerSetup::getSystem() const
381 return this->systemName->text();
384 void CrossCompilerSetup::setSystem(const QString& t)
386 this->systemName->setText(t);
389 QString CrossCompilerSetup::getVersion() const
391 return this->systemVersion->text();
394 void CrossCompilerSetup::setVersion(const QString& t)
396 this->systemVersion->setText(t);
399 QString CrossCompilerSetup::getProcessor() const
401 return this->systemProcessor->text();
404 void CrossCompilerSetup::setProcessor(const QString& t)
406 this->systemProcessor->setText(t);
409 QString CrossCompilerSetup::getFindRoot() const
411 return this->crossFindRoot->text();
414 void CrossCompilerSetup::setFindRoot(const QString& t)
416 this->crossFindRoot->setText(t);
419 int CrossCompilerSetup::getProgramMode() const
421 return this->crossProgramMode->currentIndex();
424 int CrossCompilerSetup::getLibraryMode() const
426 return this->crossLibraryMode->currentIndex();
429 int CrossCompilerSetup::getIncludeMode() const
431 return this->crossIncludeMode->currentIndex();
434 void CrossCompilerSetup::setProgramMode(int m)
436 this->crossProgramMode->setCurrentIndex(m);
439 void CrossCompilerSetup::setLibraryMode(int m)
441 this->crossLibraryMode->setCurrentIndex(m);
444 void CrossCompilerSetup::setIncludeMode(int m)
446 this->crossIncludeMode->setCurrentIndex(m);
449 ToolchainCompilerSetup::ToolchainCompilerSetup(QWidget* p)
452 QVBoxLayout* l = new QVBoxLayout(this);
453 l->addWidget(new QLabel(tr("Specify the Toolchain file")));
454 this->ToolchainFile = new QCMakeFilePathEditor(this);
455 l->addWidget(this->ToolchainFile);
458 ToolchainCompilerSetup::~ToolchainCompilerSetup() = default;
460 QString ToolchainCompilerSetup::toolchainFile() const
462 return this->ToolchainFile->text();
465 void ToolchainCompilerSetup::setToolchainFile(const QString& t)
467 this->ToolchainFile->setText(t);
470 FirstConfigure::FirstConfigure()
472 const char* env_generator = std::getenv("CMAKE_GENERATOR");
473 const char* env_generator_platform = nullptr;
474 const char* env_generator_toolset = nullptr;
475 if (env_generator && std::strlen(env_generator)) {
476 mDefaultGenerator = env_generator;
477 env_generator_platform = std::getenv("CMAKE_GENERATOR_PLATFORM");
478 env_generator_toolset = std::getenv("CMAKE_GENERATOR_TOOLSET");
481 if (!env_generator_platform) {
482 env_generator_platform = "";
485 if (!env_generator_toolset) {
486 env_generator_toolset = "";
489 // this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
490 this->mStartCompilerSetupPage = new StartCompilerSetup(
491 env_generator_platform, env_generator_toolset, this);
492 this->setPage(Start, this->mStartCompilerSetupPage);
493 QObject::connect(this->mStartCompilerSetupPage,
494 &StartCompilerSetup::selectionChanged, this,
495 &FirstConfigure::restart);
496 this->mNativeCompilerSetupPage = new NativeCompilerSetup(this);
497 this->setPage(NativeSetup, this->mNativeCompilerSetupPage);
499 this->mCrossCompilerSetupPage = new CrossCompilerSetup(this);
500 this->setPage(CrossSetup, this->mCrossCompilerSetupPage);
502 this->mToolchainCompilerSetupPage = new ToolchainCompilerSetup(this);
503 this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage);
506 FirstConfigure::~FirstConfigure() = default;
508 void FirstConfigure::setGenerators(
509 std::vector<cmake::GeneratorInfo> const& gens)
511 this->mStartCompilerSetupPage->setGenerators(gens);
514 void FirstConfigure::setCurrentGenerator(const QString& gen)
516 this->mStartCompilerSetupPage->setCurrentGenerator(gen);
519 void FirstConfigure::setPlatform(const QString& platform)
521 this->mStartCompilerSetupPage->setPlatform(platform);
524 void FirstConfigure::setToolset(const QString& toolset)
526 this->mStartCompilerSetupPage->setToolset(toolset);
529 void FirstConfigure::setCompilerOption(CompilerOption option)
531 this->mStartCompilerSetupPage->setCompilerOption(option);
534 QString FirstConfigure::getGenerator() const
536 return this->mStartCompilerSetupPage->getGenerator();
539 QString FirstConfigure::getPlatform() const
541 return this->mStartCompilerSetupPage->getPlatform();
544 QString FirstConfigure::getToolset() const
546 return this->mStartCompilerSetupPage->getToolset();
549 void FirstConfigure::loadFromSettings()
553 settings.beginGroup("Settings/StartPath");
554 QString lastGen = settings.value("LastGenerator").toString();
555 this->setCurrentGenerator(lastGen);
558 // restore compiler setup
559 settings.beginGroup("Settings/Compiler");
560 this->mNativeCompilerSetupPage->setCCompiler(
561 settings.value("CCompiler").toString());
562 this->mNativeCompilerSetupPage->setCXXCompiler(
563 settings.value("CXXCompiler").toString());
564 this->mNativeCompilerSetupPage->setFortranCompiler(
565 settings.value("FortranCompiler").toString());
568 // restore cross compiler setup
569 settings.beginGroup("Settings/CrossCompiler");
570 this->mCrossCompilerSetupPage->setCCompiler(
571 settings.value("CCompiler").toString());
572 this->mCrossCompilerSetupPage->setCXXCompiler(
573 settings.value("CXXCompiler").toString());
574 this->mCrossCompilerSetupPage->setFortranCompiler(
575 settings.value("FortranCompiler").toString());
576 this->mToolchainCompilerSetupPage->setToolchainFile(
577 settings.value("ToolChainFile").toString());
578 this->mCrossCompilerSetupPage->setSystem(
579 settings.value("SystemName").toString());
580 this->mCrossCompilerSetupPage->setVersion(
581 settings.value("SystemVersion").toString());
582 this->mCrossCompilerSetupPage->setProcessor(
583 settings.value("SystemProcessor").toString());
584 this->mCrossCompilerSetupPage->setFindRoot(
585 settings.value("FindRoot").toString());
586 this->mCrossCompilerSetupPage->setProgramMode(
587 settings.value("ProgramMode", 0).toInt());
588 this->mCrossCompilerSetupPage->setLibraryMode(
589 settings.value("LibraryMode", 0).toInt());
590 this->mCrossCompilerSetupPage->setIncludeMode(
591 settings.value("IncludeMode", 0).toInt());
594 // environment variables take precedence over application settings because...
595 // - they're harder to set
596 // - settings always exist after the program is run once, so the environment
597 // variables would never be used otherwise
598 // - platform and toolset are populated only from environment variables, so
599 // this prevents them from being taken from environment, while the
600 // generator is taken from application settings
601 if (!mDefaultGenerator.isEmpty()) {
602 this->setCurrentGenerator(mDefaultGenerator);
606 void FirstConfigure::saveToSettings()
611 settings.beginGroup("Settings/StartPath");
612 QString lastGen = this->mStartCompilerSetupPage->getGenerator();
613 settings.setValue("LastGenerator", lastGen);
616 // save compiler setup
617 settings.beginGroup("Settings/Compiler");
618 settings.setValue("CCompiler",
619 this->mNativeCompilerSetupPage->getCCompiler());
620 settings.setValue("CXXCompiler",
621 this->mNativeCompilerSetupPage->getCXXCompiler());
622 settings.setValue("FortranCompiler",
623 this->mNativeCompilerSetupPage->getFortranCompiler());
626 // save cross compiler setup
627 settings.beginGroup("Settings/CrossCompiler");
628 settings.setValue("CCompiler",
629 this->mCrossCompilerSetupPage->getCCompiler());
630 settings.setValue("CXXCompiler",
631 this->mCrossCompilerSetupPage->getCXXCompiler());
632 settings.setValue("FortranCompiler",
633 this->mCrossCompilerSetupPage->getFortranCompiler());
634 settings.setValue("ToolChainFile", this->getCrossCompilerToolChainFile());
635 settings.setValue("SystemName", this->mCrossCompilerSetupPage->getSystem());
636 settings.setValue("SystemVersion",
637 this->mCrossCompilerSetupPage->getVersion());
638 settings.setValue("SystemProcessor",
639 this->mCrossCompilerSetupPage->getProcessor());
640 settings.setValue("FindRoot", this->mCrossCompilerSetupPage->getFindRoot());
641 settings.setValue("ProgramMode",
642 this->mCrossCompilerSetupPage->getProgramMode());
643 settings.setValue("LibraryMode",
644 this->mCrossCompilerSetupPage->getLibraryMode());
645 settings.setValue("IncludeMode",
646 this->mCrossCompilerSetupPage->getIncludeMode());
650 bool FirstConfigure::defaultSetup() const
652 return this->mStartCompilerSetupPage->defaultSetup();
655 bool FirstConfigure::compilerSetup() const
657 return this->mStartCompilerSetupPage->compilerSetup();
660 bool FirstConfigure::crossCompilerSetup() const
662 return this->mStartCompilerSetupPage->crossCompilerSetup();
665 bool FirstConfigure::crossCompilerToolChainFile() const
667 return this->mStartCompilerSetupPage->crossCompilerToolChainFile();
670 QString FirstConfigure::getCrossCompilerToolChainFile() const
672 return this->mToolchainCompilerSetupPage->toolchainFile();
675 QString FirstConfigure::getSystemName() const
677 return this->mCrossCompilerSetupPage->getSystem();
680 QString FirstConfigure::getCCompiler() const
682 if (this->compilerSetup()) {
683 return this->mNativeCompilerSetupPage->getCCompiler();
685 if (this->crossCompilerSetup()) {
686 return this->mCrossCompilerSetupPage->getCCompiler();
691 QString FirstConfigure::getCXXCompiler() const
693 if (this->compilerSetup()) {
694 return this->mNativeCompilerSetupPage->getCXXCompiler();
696 if (this->crossCompilerSetup()) {
697 return this->mCrossCompilerSetupPage->getCXXCompiler();
702 QString FirstConfigure::getFortranCompiler() const
704 if (this->compilerSetup()) {
705 return this->mNativeCompilerSetupPage->getFortranCompiler();
707 if (this->crossCompilerSetup()) {
708 return this->mCrossCompilerSetupPage->getFortranCompiler();
713 QString FirstConfigure::getSystemVersion() const
715 return this->mCrossCompilerSetupPage->getVersion();
718 QString FirstConfigure::getSystemProcessor() const
720 return this->mCrossCompilerSetupPage->getProcessor();
723 QString FirstConfigure::getCrossRoot() const
725 return this->mCrossCompilerSetupPage->getFindRoot();
728 const QString CrossModes[] = { "BOTH", "ONLY", "NEVER" };
730 QString FirstConfigure::getCrossProgramMode() const
732 return CrossModes[this->mCrossCompilerSetupPage->getProgramMode()];
735 QString FirstConfigure::getCrossLibraryMode() const
737 return CrossModes[this->mCrossCompilerSetupPage->getLibraryMode()];
740 QString FirstConfigure::getCrossIncludeMode() const
742 return CrossModes[this->mCrossCompilerSetupPage->getIncludeMode()];