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 // The index is off-by-one due to the first empty item added above.
248 this->PlatformOptions->setCurrentIndex(platform_index + 1);
252 PlatformFrame->hide();
255 // Display the toolset box for the generators supporting it
256 if (GeneratorsSupportingToolset.contains(name)) {
257 ToolsetFrame->show();
259 ToolsetFrame->hide();
263 int StartCompilerSetup::nextId() const
265 if (compilerSetup()) {
268 if (crossCompilerSetup()) {
271 if (crossCompilerToolChainFile()) {
272 return ToolchainSetup;
277 NativeCompilerSetup::NativeCompilerSetup(QWidget* p)
280 QVBoxLayout* l = new QVBoxLayout(this);
281 QWidget* c = new QWidget(this);
286 NativeCompilerSetup::~NativeCompilerSetup() = default;
288 QString NativeCompilerSetup::getCCompiler() const
290 return this->CCompiler->text();
293 void NativeCompilerSetup::setCCompiler(const QString& s)
295 this->CCompiler->setText(s);
298 QString NativeCompilerSetup::getCXXCompiler() const
300 return this->CXXCompiler->text();
303 void NativeCompilerSetup::setCXXCompiler(const QString& s)
305 this->CXXCompiler->setText(s);
308 QString NativeCompilerSetup::getFortranCompiler() const
310 return this->FortranCompiler->text();
313 void NativeCompilerSetup::setFortranCompiler(const QString& s)
315 this->FortranCompiler->setText(s);
318 CrossCompilerSetup::CrossCompilerSetup(QWidget* p)
322 QWidget::setTabOrder(systemName, systemVersion);
323 QWidget::setTabOrder(systemVersion, systemProcessor);
324 QWidget::setTabOrder(systemProcessor, CrossCompilers->CCompiler);
325 QWidget::setTabOrder(CrossCompilers->CCompiler, CrossCompilers->CXXCompiler);
326 QWidget::setTabOrder(CrossCompilers->CXXCompiler,
327 CrossCompilers->FortranCompiler);
328 QWidget::setTabOrder(CrossCompilers->FortranCompiler, crossFindRoot);
329 QWidget::setTabOrder(crossFindRoot, crossProgramMode);
330 QWidget::setTabOrder(crossProgramMode, crossLibraryMode);
331 QWidget::setTabOrder(crossLibraryMode, crossIncludeMode);
333 // fill in combo boxes
335 modes << tr("Search in Target Root, then native system");
336 modes << tr("Search only in Target Root");
337 modes << tr("Search only in native system");
338 crossProgramMode->addItems(modes);
339 crossLibraryMode->addItems(modes);
340 crossIncludeMode->addItems(modes);
341 crossProgramMode->setCurrentIndex(2);
342 crossLibraryMode->setCurrentIndex(1);
343 crossIncludeMode->setCurrentIndex(1);
345 this->registerField("systemName*", this->systemName);
348 CrossCompilerSetup::~CrossCompilerSetup() = default;
350 QString CrossCompilerSetup::getCCompiler() const
352 return this->CrossCompilers->CCompiler->text();
355 void CrossCompilerSetup::setCCompiler(const QString& s)
357 this->CrossCompilers->CCompiler->setText(s);
360 QString CrossCompilerSetup::getCXXCompiler() const
362 return this->CrossCompilers->CXXCompiler->text();
365 void CrossCompilerSetup::setCXXCompiler(const QString& s)
367 this->CrossCompilers->CXXCompiler->setText(s);
370 QString CrossCompilerSetup::getFortranCompiler() const
372 return this->CrossCompilers->FortranCompiler->text();
375 void CrossCompilerSetup::setFortranCompiler(const QString& s)
377 this->CrossCompilers->FortranCompiler->setText(s);
380 QString CrossCompilerSetup::getSystem() const
382 return this->systemName->text();
385 void CrossCompilerSetup::setSystem(const QString& t)
387 this->systemName->setText(t);
390 QString CrossCompilerSetup::getVersion() const
392 return this->systemVersion->text();
395 void CrossCompilerSetup::setVersion(const QString& t)
397 this->systemVersion->setText(t);
400 QString CrossCompilerSetup::getProcessor() const
402 return this->systemProcessor->text();
405 void CrossCompilerSetup::setProcessor(const QString& t)
407 this->systemProcessor->setText(t);
410 QString CrossCompilerSetup::getFindRoot() const
412 return this->crossFindRoot->text();
415 void CrossCompilerSetup::setFindRoot(const QString& t)
417 this->crossFindRoot->setText(t);
420 int CrossCompilerSetup::getProgramMode() const
422 return this->crossProgramMode->currentIndex();
425 int CrossCompilerSetup::getLibraryMode() const
427 return this->crossLibraryMode->currentIndex();
430 int CrossCompilerSetup::getIncludeMode() const
432 return this->crossIncludeMode->currentIndex();
435 void CrossCompilerSetup::setProgramMode(int m)
437 this->crossProgramMode->setCurrentIndex(m);
440 void CrossCompilerSetup::setLibraryMode(int m)
442 this->crossLibraryMode->setCurrentIndex(m);
445 void CrossCompilerSetup::setIncludeMode(int m)
447 this->crossIncludeMode->setCurrentIndex(m);
450 ToolchainCompilerSetup::ToolchainCompilerSetup(QWidget* p)
453 QVBoxLayout* l = new QVBoxLayout(this);
454 l->addWidget(new QLabel(tr("Specify the Toolchain file")));
455 this->ToolchainFile = new QCMakeFilePathEditor(this);
456 l->addWidget(this->ToolchainFile);
459 ToolchainCompilerSetup::~ToolchainCompilerSetup() = default;
461 QString ToolchainCompilerSetup::toolchainFile() const
463 return this->ToolchainFile->text();
466 void ToolchainCompilerSetup::setToolchainFile(const QString& t)
468 this->ToolchainFile->setText(t);
471 FirstConfigure::FirstConfigure()
473 const char* env_generator = std::getenv("CMAKE_GENERATOR");
474 const char* env_generator_platform = nullptr;
475 const char* env_generator_toolset = nullptr;
476 if (env_generator && std::strlen(env_generator)) {
477 mDefaultGenerator = env_generator;
478 env_generator_platform = std::getenv("CMAKE_GENERATOR_PLATFORM");
479 env_generator_toolset = std::getenv("CMAKE_GENERATOR_TOOLSET");
482 if (!env_generator_platform) {
483 env_generator_platform = "";
486 if (!env_generator_toolset) {
487 env_generator_toolset = "";
490 // this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
491 this->mStartCompilerSetupPage = new StartCompilerSetup(
492 env_generator_platform, env_generator_toolset, this);
493 this->setPage(Start, this->mStartCompilerSetupPage);
494 QObject::connect(this->mStartCompilerSetupPage,
495 &StartCompilerSetup::selectionChanged, this,
496 &FirstConfigure::restart);
497 this->mNativeCompilerSetupPage = new NativeCompilerSetup(this);
498 this->setPage(NativeSetup, this->mNativeCompilerSetupPage);
500 this->mCrossCompilerSetupPage = new CrossCompilerSetup(this);
501 this->setPage(CrossSetup, this->mCrossCompilerSetupPage);
503 this->mToolchainCompilerSetupPage = new ToolchainCompilerSetup(this);
504 this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage);
507 FirstConfigure::~FirstConfigure() = default;
509 void FirstConfigure::setGenerators(
510 std::vector<cmake::GeneratorInfo> const& gens)
512 this->mStartCompilerSetupPage->setGenerators(gens);
515 void FirstConfigure::setCurrentGenerator(const QString& gen)
517 this->mStartCompilerSetupPage->setCurrentGenerator(gen);
520 void FirstConfigure::setPlatform(const QString& platform)
522 this->mStartCompilerSetupPage->setPlatform(platform);
525 void FirstConfigure::setToolset(const QString& toolset)
527 this->mStartCompilerSetupPage->setToolset(toolset);
530 void FirstConfigure::setCompilerOption(CompilerOption option)
532 this->mStartCompilerSetupPage->setCompilerOption(option);
535 QString FirstConfigure::getGenerator() const
537 return this->mStartCompilerSetupPage->getGenerator();
540 QString FirstConfigure::getPlatform() const
542 return this->mStartCompilerSetupPage->getPlatform();
545 QString FirstConfigure::getToolset() const
547 return this->mStartCompilerSetupPage->getToolset();
550 void FirstConfigure::loadFromSettings()
554 settings.beginGroup("Settings/StartPath");
555 QString lastGen = settings.value("LastGenerator").toString();
556 this->setCurrentGenerator(lastGen);
559 // restore compiler setup
560 settings.beginGroup("Settings/Compiler");
561 this->mNativeCompilerSetupPage->setCCompiler(
562 settings.value("CCompiler").toString());
563 this->mNativeCompilerSetupPage->setCXXCompiler(
564 settings.value("CXXCompiler").toString());
565 this->mNativeCompilerSetupPage->setFortranCompiler(
566 settings.value("FortranCompiler").toString());
569 // restore cross compiler setup
570 settings.beginGroup("Settings/CrossCompiler");
571 this->mCrossCompilerSetupPage->setCCompiler(
572 settings.value("CCompiler").toString());
573 this->mCrossCompilerSetupPage->setCXXCompiler(
574 settings.value("CXXCompiler").toString());
575 this->mCrossCompilerSetupPage->setFortranCompiler(
576 settings.value("FortranCompiler").toString());
577 this->mToolchainCompilerSetupPage->setToolchainFile(
578 settings.value("ToolChainFile").toString());
579 this->mCrossCompilerSetupPage->setSystem(
580 settings.value("SystemName").toString());
581 this->mCrossCompilerSetupPage->setVersion(
582 settings.value("SystemVersion").toString());
583 this->mCrossCompilerSetupPage->setProcessor(
584 settings.value("SystemProcessor").toString());
585 this->mCrossCompilerSetupPage->setFindRoot(
586 settings.value("FindRoot").toString());
587 this->mCrossCompilerSetupPage->setProgramMode(
588 settings.value("ProgramMode", 0).toInt());
589 this->mCrossCompilerSetupPage->setLibraryMode(
590 settings.value("LibraryMode", 0).toInt());
591 this->mCrossCompilerSetupPage->setIncludeMode(
592 settings.value("IncludeMode", 0).toInt());
595 // environment variables take precedence over application settings because...
596 // - they're harder to set
597 // - settings always exist after the program is run once, so the environment
598 // variables would never be used otherwise
599 // - platform and toolset are populated only from environment variables, so
600 // this prevents them from being taken from environment, while the
601 // generator is taken from application settings
602 if (!mDefaultGenerator.isEmpty()) {
603 this->setCurrentGenerator(mDefaultGenerator);
607 void FirstConfigure::saveToSettings()
612 settings.beginGroup("Settings/StartPath");
613 QString lastGen = this->mStartCompilerSetupPage->getGenerator();
614 settings.setValue("LastGenerator", lastGen);
617 // save compiler setup
618 settings.beginGroup("Settings/Compiler");
619 settings.setValue("CCompiler",
620 this->mNativeCompilerSetupPage->getCCompiler());
621 settings.setValue("CXXCompiler",
622 this->mNativeCompilerSetupPage->getCXXCompiler());
623 settings.setValue("FortranCompiler",
624 this->mNativeCompilerSetupPage->getFortranCompiler());
627 // save cross compiler setup
628 settings.beginGroup("Settings/CrossCompiler");
629 settings.setValue("CCompiler",
630 this->mCrossCompilerSetupPage->getCCompiler());
631 settings.setValue("CXXCompiler",
632 this->mCrossCompilerSetupPage->getCXXCompiler());
633 settings.setValue("FortranCompiler",
634 this->mCrossCompilerSetupPage->getFortranCompiler());
635 settings.setValue("ToolChainFile", this->getCrossCompilerToolChainFile());
636 settings.setValue("SystemName", this->mCrossCompilerSetupPage->getSystem());
637 settings.setValue("SystemVersion",
638 this->mCrossCompilerSetupPage->getVersion());
639 settings.setValue("SystemProcessor",
640 this->mCrossCompilerSetupPage->getProcessor());
641 settings.setValue("FindRoot", this->mCrossCompilerSetupPage->getFindRoot());
642 settings.setValue("ProgramMode",
643 this->mCrossCompilerSetupPage->getProgramMode());
644 settings.setValue("LibraryMode",
645 this->mCrossCompilerSetupPage->getLibraryMode());
646 settings.setValue("IncludeMode",
647 this->mCrossCompilerSetupPage->getIncludeMode());
651 bool FirstConfigure::defaultSetup() const
653 return this->mStartCompilerSetupPage->defaultSetup();
656 bool FirstConfigure::compilerSetup() const
658 return this->mStartCompilerSetupPage->compilerSetup();
661 bool FirstConfigure::crossCompilerSetup() const
663 return this->mStartCompilerSetupPage->crossCompilerSetup();
666 bool FirstConfigure::crossCompilerToolChainFile() const
668 return this->mStartCompilerSetupPage->crossCompilerToolChainFile();
671 QString FirstConfigure::getCrossCompilerToolChainFile() const
673 return this->mToolchainCompilerSetupPage->toolchainFile();
676 QString FirstConfigure::getSystemName() const
678 return this->mCrossCompilerSetupPage->getSystem();
681 QString FirstConfigure::getCCompiler() const
683 if (this->compilerSetup()) {
684 return this->mNativeCompilerSetupPage->getCCompiler();
686 if (this->crossCompilerSetup()) {
687 return this->mCrossCompilerSetupPage->getCCompiler();
692 QString FirstConfigure::getCXXCompiler() const
694 if (this->compilerSetup()) {
695 return this->mNativeCompilerSetupPage->getCXXCompiler();
697 if (this->crossCompilerSetup()) {
698 return this->mCrossCompilerSetupPage->getCXXCompiler();
703 QString FirstConfigure::getFortranCompiler() const
705 if (this->compilerSetup()) {
706 return this->mNativeCompilerSetupPage->getFortranCompiler();
708 if (this->crossCompilerSetup()) {
709 return this->mCrossCompilerSetupPage->getFortranCompiler();
714 QString FirstConfigure::getSystemVersion() const
716 return this->mCrossCompilerSetupPage->getVersion();
719 QString FirstConfigure::getSystemProcessor() const
721 return this->mCrossCompilerSetupPage->getProcessor();
724 QString FirstConfigure::getCrossRoot() const
726 return this->mCrossCompilerSetupPage->getFindRoot();
729 const QString CrossModes[] = { "BOTH", "ONLY", "NEVER" };
731 QString FirstConfigure::getCrossProgramMode() const
733 return CrossModes[this->mCrossCompilerSetupPage->getProgramMode()];
736 QString FirstConfigure::getCrossLibraryMode() const
738 return CrossModes[this->mCrossCompilerSetupPage->getLibraryMode()];
741 QString FirstConfigure::getCrossIncludeMode() const
743 return CrossModes[this->mCrossCompilerSetupPage->getIncludeMode()];