diff options
Diffstat (limited to 'Source')
27 files changed, 675 insertions, 266 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index df989fa..818b1bd 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 18) -set(CMake_VERSION_PATCH 20200925) +set(CMake_VERSION_PATCH 20200929) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx index f5e0777..1075895 100644 --- a/Source/QtDialog/AddCacheEntry.cxx +++ b/Source/QtDialog/AddCacheEntry.cxx @@ -40,8 +40,10 @@ AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& varNames, AddCacheEntry::setTabOrder(string, this->Description); QCompleter* completer = new QCompleter(this->VarNames, this); this->Name->setCompleter(completer); - connect(completer, SIGNAL(activated(const QString&)), this, - SLOT(onCompletionActivated(const QString&))); + connect( + completer, + static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated), + this, &AddCacheEntry::onCompletionActivated); } QString AddCacheEntry::name() const diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index fcc8408..f6bde8f 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -103,76 +103,87 @@ CMakeSetupDialog::CMakeSetupDialog() QMenu* FileMenu = this->menuBar()->addMenu(tr("&File")); this->ReloadCacheAction = FileMenu->addAction(tr("&Reload Cache")); - QObject::connect(this->ReloadCacheAction, SIGNAL(triggered(bool)), this, - SLOT(doReloadCache())); + QObject::connect(this->ReloadCacheAction, &QAction::triggered, this, + &CMakeSetupDialog::doReloadCache); this->DeleteCacheAction = FileMenu->addAction(tr("&Delete Cache")); - QObject::connect(this->DeleteCacheAction, SIGNAL(triggered(bool)), this, - SLOT(doDeleteCache())); + QObject::connect(this->DeleteCacheAction, &QAction::triggered, this, + &CMakeSetupDialog::doDeleteCache); this->ExitAction = FileMenu->addAction(tr("E&xit")); - this->ExitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); - QObject::connect(this->ExitAction, SIGNAL(triggered(bool)), this, - SLOT(close())); + QObject::connect(this->ExitAction, &QAction::triggered, this, + &CMakeSetupDialog::close); + this->ExitAction->setShortcut(QKeySequence::Quit); QMenu* ToolsMenu = this->menuBar()->addMenu(tr("&Tools")); this->ConfigureAction = ToolsMenu->addAction(tr("&Configure")); + QObject::connect(this->ConfigureAction, &QAction::triggered, this, + &CMakeSetupDialog::doConfigure); // prevent merging with Preferences menu item on macOS this->ConfigureAction->setMenuRole(QAction::NoRole); - QObject::connect(this->ConfigureAction, SIGNAL(triggered(bool)), this, - SLOT(doConfigure())); this->GenerateAction = ToolsMenu->addAction(tr("&Generate")); - QObject::connect(this->GenerateAction, SIGNAL(triggered(bool)), this, - SLOT(doGenerate())); - QAction* showChangesAction = ToolsMenu->addAction(tr("&Show My Changes")); - QObject::connect(showChangesAction, SIGNAL(triggered(bool)), this, - SLOT(showUserChanges())); + QObject::connect(this->GenerateAction, &QAction::triggered, this, + &CMakeSetupDialog::doGenerate); + auto* a = ToolsMenu->addAction(tr("&Show My Changes")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::showUserChanges); #if defined(Q_WS_MAC) || defined(Q_OS_MAC) this->InstallForCommandLineAction = ToolsMenu->addAction(tr("&How to Install For Command Line Use")); - QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)), - this, SLOT(doInstallForCommandLine())); + QObject::connect(this->InstallForCommandLineAction, &QAction::triggered, + this, &CMakeSetupDialog::doInstallForCommandLine); #endif ToolsMenu->addSeparator(); - ToolsMenu->addAction(tr("Regular Expression Explorer..."), this, - SLOT(doRegexExplorerDialog())); + a = ToolsMenu->addAction(tr("Regular Expression Explorer...")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doRegexExplorerDialog); ToolsMenu->addSeparator(); - ToolsMenu->addAction(tr("&Find in Output..."), this, - SLOT(doOutputFindDialog()), QKeySequence::Find); - ToolsMenu->addAction(tr("Find Next"), this, SLOT(doOutputFindNext()), - QKeySequence::FindNext); - ToolsMenu->addAction(tr("Find Previous"), this, SLOT(doOutputFindPrev()), - QKeySequence::FindPrevious); - ToolsMenu->addAction(tr("Goto Next Error"), this, SLOT(doOutputErrorNext()), - QKeySequence(Qt::Key_F8)); // in Visual Studio - new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Period), this, - SLOT(doOutputErrorNext())); // in Eclipse + a = ToolsMenu->addAction(tr("&Find in Output...")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindDialog); + a->setShortcut(QKeySequence::Find); + a = ToolsMenu->addAction(tr("Find Next")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindNext); + a->setShortcut(QKeySequence::FindNext); + a = ToolsMenu->addAction(tr("Find Previous")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindPrev); + a->setShortcut(QKeySequence::FindPrevious); + a = ToolsMenu->addAction(tr("Goto Next Error")); // in Visual Studio + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputErrorNext); + a->setShortcut(QKeySequence(Qt::Key_F8)); + auto* s = new QShortcut(this); + s->setKey(QKeySequence(Qt::CTRL + Qt::Key_Period)); + QObject::connect(s, &QShortcut::activated, this, + &CMakeSetupDialog::doOutputErrorNext); // in Eclipse QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options")); - OptionsMenu->addAction(tr("Warning Messages..."), this, - SLOT(doWarningMessagesDialog())); + a = OptionsMenu->addAction(tr("Warning Messages...")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doWarningMessagesDialog); this->WarnUninitializedAction = OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)")); this->WarnUninitializedAction->setCheckable(true); QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output")); debugAction->setCheckable(true); - QObject::connect(debugAction, SIGNAL(toggled(bool)), this, - SLOT(setDebugOutput(bool))); + QObject::connect(debugAction, &QAction::toggled, this, + &CMakeSetupDialog::setDebugOutput); OptionsMenu->addSeparator(); - QAction* expandAction = - OptionsMenu->addAction(tr("&Expand Grouped Entries")); - QObject::connect(expandAction, SIGNAL(triggered(bool)), this->CacheValues, - SLOT(expandAll())); - QAction* collapseAction = - OptionsMenu->addAction(tr("&Collapse Grouped Entries")); - QObject::connect(collapseAction, SIGNAL(triggered(bool)), this->CacheValues, - SLOT(collapseAll())); + a = OptionsMenu->addAction(tr("&Expand Grouped Entries")); + QObject::connect(a, &QAction::triggered, this->CacheValues, + &QCMakeCacheView::expandAll); + a = OptionsMenu->addAction(tr("&Collapse Grouped Entries")); + QObject::connect(a, &QAction::triggered, this->CacheValues, + &QCMakeCacheView::collapseAll); QMenu* HelpMenu = this->menuBar()->addMenu(tr("&Help")); - QAction* a = HelpMenu->addAction(tr("About")); - QObject::connect(a, SIGNAL(triggered(bool)), this, SLOT(doAbout())); + a = HelpMenu->addAction(tr("About")); + QObject::connect(a, &QAction::triggered, this, &CMakeSetupDialog::doAbout); a = HelpMenu->addAction(tr("Help")); - QObject::connect(a, SIGNAL(triggered(bool)), this, SLOT(doHelp())); + QObject::connect(a, &QAction::triggered, this, &CMakeSetupDialog::doHelp); + a->setShortcut(QKeySequence::HelpContents); this->setAcceptDrops(true); @@ -189,16 +200,16 @@ CMakeSetupDialog::CMakeSetupDialog() this->ErrorFormat.setForeground(QBrush(Qt::red)); this->Output->setContextMenuPolicy(Qt::CustomContextMenu); - connect(this->Output, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(doOutputContextMenu(const QPoint&))); + connect(this->Output, &QTextEdit::customContextMenuRequested, this, + &CMakeSetupDialog::doOutputContextMenu); // disable open project button this->OpenProjectButton->setDisabled(true); // start the cmake worker thread this->CMakeThread = new QCMakeThread(this); - QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()), this, - SLOT(initialize()), Qt::QueuedConnection); + QObject::connect(this->CMakeThread, &QCMakeThread::cmakeInitialized, this, + &CMakeSetupDialog::initialize, Qt::QueuedConnection); this->CMakeThread->start(); this->enterState(ReadyConfigure); @@ -211,82 +222,79 @@ void CMakeSetupDialog::initialize() { // now the cmake worker thread is running, lets make our connections to it QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(propertiesChanged(const QCMakePropertyList&)), - this->CacheValues->cacheModel(), - SLOT(setProperties(const QCMakePropertyList&))); + &QCMake::propertiesChanged, this->CacheValues->cacheModel(), + &QCMakeCacheModel::setProperties); - QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)), this, - SLOT(doConfigure())); + QObject::connect(this->ConfigureButton, &QPushButton::clicked, this, + &CMakeSetupDialog::doConfigure); - QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(configureDone(int)), this, SLOT(exitLoop(int))); - QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(generateDone(int)), this, SLOT(exitLoop(int))); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::configureDone, + this, &CMakeSetupDialog::exitLoop); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::generateDone, + this, &CMakeSetupDialog::exitLoop); - QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)), this, - SLOT(doGenerate())); - QObject::connect(this->OpenProjectButton, SIGNAL(clicked(bool)), this, - SLOT(doOpenProject())); + QObject::connect(this->GenerateButton, &QPushButton::clicked, this, + &CMakeSetupDialog::doGenerate); + QObject::connect(this->OpenProjectButton, &QPushButton::clicked, this, + &CMakeSetupDialog::doOpenProject); - QObject::connect(this->BrowseSourceDirectoryButton, SIGNAL(clicked(bool)), - this, SLOT(doSourceBrowse())); - QObject::connect(this->BrowseBinaryDirectoryButton, SIGNAL(clicked(bool)), - this, SLOT(doBinaryBrowse())); + QObject::connect(this->BrowseSourceDirectoryButton, &QPushButton::clicked, + this, &CMakeSetupDialog::doSourceBrowse); + QObject::connect(this->BrowseBinaryDirectoryButton, &QPushButton::clicked, + this, &CMakeSetupDialog::doBinaryBrowse); - QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)), - this, SLOT(onBinaryDirectoryChanged(QString))); - QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)), this, - SLOT(onSourceDirectoryChanged(QString))); + QObject::connect(this->BinaryDirectory, &QComboBox::editTextChanged, this, + &CMakeSetupDialog::onBinaryDirectoryChanged); + QObject::connect(this->SourceDirectory, &QLineEdit::textChanged, this, + &CMakeSetupDialog::onSourceDirectoryChanged); QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(sourceDirChanged(QString)), this, - SLOT(updateSourceDirectory(QString))); + &QCMake::sourceDirChanged, this, + &CMakeSetupDialog::updateSourceDirectory); QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(binaryDirChanged(QString)), this, - SLOT(updateBinaryDirectory(QString))); + &QCMake::binaryDirChanged, this, + &CMakeSetupDialog::updateBinaryDirectory); QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(progressChanged(QString, float)), this, - SLOT(showProgress(QString, float))); + &QCMake::progressChanged, this, + &CMakeSetupDialog::showProgress); - QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(errorMessage(QString)), this, SLOT(error(QString))); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::errorMessage, + this, &CMakeSetupDialog::error); - QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(outputMessage(QString)), this, - SLOT(message(QString))); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::outputMessage, + this, &CMakeSetupDialog::message); - QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(openPossible(bool)), this->OpenProjectButton, - SLOT(setEnabled(bool))); + QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::openPossible, + this->OpenProjectButton, &CMakeSetupDialog::setEnabled); - QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)), this, - SLOT(setGroupedView(bool))); - QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)), this, - SLOT(setAdvancedView(bool))); - QObject::connect(this->Search, SIGNAL(textChanged(QString)), this, - SLOT(setSearchFilter(QString))); + QObject::connect(this->groupedCheck, &QCheckBox::toggled, this, + &CMakeSetupDialog::setGroupedView); + QObject::connect(this->advancedCheck, &QCheckBox::toggled, this, + &CMakeSetupDialog::setAdvancedView); + QObject::connect(this->Search, &QLineEdit::textChanged, this, + &CMakeSetupDialog::setSearchFilter); QObject::connect(this->CMakeThread->cmakeInstance(), - SIGNAL(generatorChanged(QString)), this, - SLOT(updateGeneratorLabel(QString))); + &QCMake::generatorChanged, this, + &CMakeSetupDialog::updateGeneratorLabel); this->updateGeneratorLabel(QString()); QObject::connect(this->CacheValues->cacheModel(), - SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, - SLOT(setCacheModified())); + &QCMakeCacheModel::dataChanged, this, + &CMakeSetupDialog::setCacheModified); QObject::connect(this->CacheValues->selectionModel(), - SIGNAL(selectionChanged(QItemSelection, QItemSelection)), - this, SLOT(selectionChanged())); - QObject::connect(this->RemoveEntry, SIGNAL(clicked(bool)), this, - SLOT(removeSelectedCacheEntries())); - QObject::connect(this->AddEntry, SIGNAL(clicked(bool)), this, - SLOT(addCacheEntry())); - - QObject::connect(this->WarnUninitializedAction, SIGNAL(triggered(bool)), + &QItemSelectionModel::selectionChanged, this, + &CMakeSetupDialog::selectionChanged); + QObject::connect(this->RemoveEntry, &QToolButton::clicked, this, + &CMakeSetupDialog::removeSelectedCacheEntries); + QObject::connect(this->AddEntry, &QToolButton::clicked, this, + &CMakeSetupDialog::addCacheEntry); + + QObject::connect(this->WarnUninitializedAction, &QAction::triggered, this->CMakeThread->cmakeInstance(), - SLOT(setWarnUninitializedMode(bool))); + &QCMake::setWarnUninitializedMode); if (!this->SourceDirectory->text().isEmpty() || !this->BinaryDirectory->lineEdit()->text().isEmpty()) { @@ -445,7 +453,8 @@ void CMakeSetupDialog::doInstallForCommandLine() lab->setTextInteractionFlags(Qt::TextSelectableByMouse); QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog); - QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); + QObject::connect(btns, &QDialogButtonBox::accepted, &dialog, + &QDialog::accept); l->addWidget(btns); dialog.exec(); } @@ -602,7 +611,8 @@ void CMakeSetupDialog::doHelp() lab->setWordWrap(true); QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog); - QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); + QObject::connect(btns, &QDialogButtonBox::accepted, &dialog, + &QDialog::accept); l->addWidget(lab); l->addWidget(btns); dialog.exec(); @@ -891,7 +901,8 @@ void CMakeSetupDialog::doAbout() lab->setWordWrap(true); QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, &dialog); - QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); + QObject::connect(btns, &QDialogButtonBox::accepted, &dialog, + &QDialog::accept); l->addWidget(btns); dialog.exec(); } @@ -1074,8 +1085,10 @@ void CMakeSetupDialog::addCacheEntry() new AddCacheEntry(&dialog, this->AddVariableNames, this->AddVariableTypes); QDialogButtonBox* btns = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); - QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); - QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(reject())); + QObject::connect(btns, &QDialogButtonBox::accepted, &dialog, + &QDialog::accept); + QObject::connect(btns, &QDialogButtonBox::rejected, &dialog, + &QDialog::reject); l->addWidget(w); l->addStretch(); l->addWidget(btns); @@ -1153,7 +1166,8 @@ void CMakeSetupDialog::showUserChanges() l->addWidget(textedit); QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, &dialog); - QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(accept())); + QObject::connect(btns, &QDialogButtonBox::rejected, &dialog, + &QDialog::accept); l->addWidget(btns); QString command; @@ -1207,15 +1221,23 @@ void CMakeSetupDialog::doOutputContextMenu(QPoint pt) std::unique_ptr<QMenu> menu(this->Output->createStandardContextMenu()); menu->addSeparator(); - menu->addAction(tr("Find..."), this, SLOT(doOutputFindDialog()), - QKeySequence::Find); - menu->addAction(tr("Find Next"), this, SLOT(doOutputFindNext()), - QKeySequence::FindNext); - menu->addAction(tr("Find Previous"), this, SLOT(doOutputFindPrev()), - QKeySequence::FindPrevious); + auto* a = menu->addAction(tr("Find...")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindDialog); + a->setShortcut(QKeySequence::Find); + a = menu->addAction(tr("Find Next")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindNext); + a->setShortcut(QKeySequence::FindNext); + a = menu->addAction(tr("Find Previous")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputFindPrev); + a->setShortcut(QKeySequence::FindPrevious); menu->addSeparator(); - menu->addAction(tr("Goto Next Error"), this, SLOT(doOutputErrorNext()), - QKeySequence(Qt::Key_F8)); + a = menu->addAction(tr("Goto Next Error")); + QObject::connect(a, &QAction::triggered, this, + &CMakeSetupDialog::doOutputErrorNext); + a->setShortcut(QKeySequence(Qt::Key_F8)); menu->exec(this->Output->mapToGlobal(pt)); } diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx index 3c24b9b..918f137 100644 --- a/Source/QtDialog/FirstConfigure.cxx +++ b/Source/QtDialog/FirstConfigure.cxx @@ -47,17 +47,18 @@ StartCompilerSetup::StartCompilerSetup(QString defaultGeneratorPlatform, this->CompilerSetupOptions[0]->setChecked(true); - QObject::connect(this->CompilerSetupOptions[0], SIGNAL(toggled(bool)), this, - SLOT(onSelectionChanged(bool))); - QObject::connect(this->CompilerSetupOptions[1], SIGNAL(toggled(bool)), this, - SLOT(onSelectionChanged(bool))); - QObject::connect(this->CompilerSetupOptions[2], SIGNAL(toggled(bool)), this, - SLOT(onSelectionChanged(bool))); - QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)), this, - SLOT(onSelectionChanged(bool))); - QObject::connect(this->GeneratorOptions, - SIGNAL(currentIndexChanged(QString const&)), this, - SLOT(onGeneratorChanged(QString const&))); + QObject::connect(this->CompilerSetupOptions[0], &QRadioButton::toggled, this, + &StartCompilerSetup::onSelectionChanged); + QObject::connect(this->CompilerSetupOptions[1], &QRadioButton::toggled, this, + &StartCompilerSetup::onSelectionChanged); + QObject::connect(this->CompilerSetupOptions[2], &QRadioButton::toggled, this, + &StartCompilerSetup::onSelectionChanged); + QObject::connect(this->CompilerSetupOptions[3], &QRadioButton::toggled, this, + &StartCompilerSetup::onSelectionChanged); + QObject::connect( + this->GeneratorOptions, + static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + this, &StartCompilerSetup::onGeneratorChanged); } QFrame* StartCompilerSetup::CreateToolsetWidgets() @@ -186,8 +187,10 @@ void StartCompilerSetup::onSelectionChanged(bool on) } } -void StartCompilerSetup::onGeneratorChanged(QString const& name) +void StartCompilerSetup::onGeneratorChanged(int index) { + QString name = this->GeneratorOptions->itemText(index); + // Display the generator platform for the generators supporting it if (GeneratorsSupportingPlatform.contains(name)) { @@ -458,9 +461,9 @@ FirstConfigure::FirstConfigure() this->mStartCompilerSetupPage = new StartCompilerSetup( env_generator_platform, env_generator_toolset, this); this->setPage(Start, this->mStartCompilerSetupPage); - QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()), - this, SLOT(restart())); - + QObject::connect(this->mStartCompilerSetupPage, + &StartCompilerSetup::selectionChanged, this, + &FirstConfigure::restart); this->mNativeCompilerSetupPage = new NativeCompilerSetup(this); this->setPage(NativeSetup, this->mNativeCompilerSetupPage); diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h index 4c757da..ca5f52e 100644 --- a/Source/QtDialog/FirstConfigure.h +++ b/Source/QtDialog/FirstConfigure.h @@ -49,7 +49,7 @@ signals: protected slots: void onSelectionChanged(bool); - void onGeneratorChanged(QString const& name); + void onGeneratorChanged(int index); protected: QComboBox* GeneratorOptions; diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 3bf4409..4f4b218 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -576,15 +576,15 @@ QWidget* QCMakeCacheModelDelegate::createEditor( if (type == QCMakeProperty::PATH) { QCMakePathEditor* editor = new QCMakePathEditor(p, var.data(Qt::DisplayRole).toString()); - QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, - SLOT(setFileDialogFlag(bool))); + QObject::connect(editor, &QCMakePathEditor::fileDialogExists, this, + &QCMakeCacheModelDelegate::setFileDialogFlag); return editor; } if (type == QCMakeProperty::FILEPATH) { QCMakeFilePathEditor* editor = new QCMakeFilePathEditor(p, var.data(Qt::DisplayRole).toString()); - QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, - SLOT(setFileDialogFlag(bool))); + QObject::connect(editor, &QCMakePathEditor::fileDialogExists, this, + &QCMakeCacheModelDelegate::setFileDialogFlag); return editor; } if (type == QCMakeProperty::STRING && diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx index d16ea58..1fc839f 100644 --- a/Source/QtDialog/QCMakeWidgets.cxx +++ b/Source/QtDialog/QCMakeWidgets.cxx @@ -17,8 +17,8 @@ QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var) this->ToolButton = new QToolButton(this); this->ToolButton->setText("..."); this->ToolButton->setCursor(QCursor(Qt::ArrowCursor)); - QObject::connect(this->ToolButton, SIGNAL(clicked(bool)), this, - SLOT(chooseFile())); + QObject::connect(this->ToolButton, &QToolButton::clicked, this, + &QCMakeFileEditor::chooseFile); } QCMakeFilePathEditor::QCMakeFilePathEditor(QWidget* p, const QString& var) diff --git a/Source/QtDialog/WarningMessagesDialog.cxx b/Source/QtDialog/WarningMessagesDialog.cxx index f608a84..1fcf2b1 100644 --- a/Source/QtDialog/WarningMessagesDialog.cxx +++ b/Source/QtDialog/WarningMessagesDialog.cxx @@ -26,18 +26,22 @@ void WarningMessagesDialog::setInitialValues() void WarningMessagesDialog::setupSignals() { - QObject::connect(this->buttonBox, SIGNAL(accepted()), this, - SLOT(doAccept())); + QObject::connect(this->buttonBox, &QDialogButtonBox::accepted, this, + &WarningMessagesDialog::doAccept); - QObject::connect(this->suppressDeveloperWarnings, SIGNAL(stateChanged(int)), - this, SLOT(doSuppressDeveloperWarningsChanged(int))); - QObject::connect(this->suppressDeprecatedWarnings, SIGNAL(stateChanged(int)), - this, SLOT(doSuppressDeprecatedWarningsChanged(int))); + QObject::connect(this->suppressDeveloperWarnings, &QCheckBox::stateChanged, + this, + &WarningMessagesDialog::doSuppressDeveloperWarningsChanged); + QObject::connect( + this->suppressDeprecatedWarnings, &QCheckBox::stateChanged, this, + &WarningMessagesDialog::doSuppressDeprecatedWarningsChanged); - QObject::connect(this->developerWarningsAsErrors, SIGNAL(stateChanged(int)), - this, SLOT(doDeveloperWarningsAsErrorsChanged(int))); - QObject::connect(this->deprecatedWarningsAsErrors, SIGNAL(stateChanged(int)), - this, SLOT(doDeprecatedWarningsAsErrorsChanged(int))); + QObject::connect(this->developerWarningsAsErrors, &QCheckBox::stateChanged, + this, + &WarningMessagesDialog::doDeveloperWarningsAsErrorsChanged); + QObject::connect( + this->deprecatedWarningsAsErrors, &QCheckBox::stateChanged, this, + &WarningMessagesDialog::doDeprecatedWarningsAsErrorsChanged); } void WarningMessagesDialog::doAccept() diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 1ff093f..51137b3 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -576,6 +576,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) loadedPackage = true; } } + + if (this->DebugMode) { + this->DebugMessage(this->DebugBuffer); + this->DebugBuffer.clear(); + } } this->AppendSuccessInformation(); @@ -788,6 +793,17 @@ bool cmFindPackageCommand::FindModule(bool& found) this->Makefile->AddDefinition(var, "1"); bool result = this->ReadListFile(mfile, DoPolicyScope); this->Makefile->RemoveDefinition(var); + + if (this->DebugMode) { + std::string foundVar = cmStrCat(this->Name, "_FOUND"); + if (this->Makefile->IsDefinitionSet(foundVar) && + !this->Makefile->IsOn(foundVar)) { + + this->DebugBuffer = cmStrCat( + this->DebugBuffer, "The module is considered not found due to ", + foundVar, " being FALSE."); + } + } return result; } return true; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index b2014e0..b57bdbc 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -621,10 +621,14 @@ void cmGlobalXCodeGenerator::AddExtraTargets( root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(allbuild, root)); // Add XCODE depend helper - std::string dir = root->GetCurrentBinaryDirectory(); - cmCustomCommandLines commandLines = cmMakeSingleCommandLine( - { "make", "-C", dir, "-f", this->CurrentXCodeHackMakefile, - "OBJDIR=$(OBJDIR)", /* placeholder, see below */ "" }); + std::string legacyDependHelperDir = root->GetCurrentBinaryDirectory(); + cmCustomCommandLines legacyDependHelperCommandLines; + if (this->XcodeBuildSystem == BuildSystem::One) { + legacyDependHelperCommandLines = cmMakeSingleCommandLine( + { "make", "-C", legacyDependHelperDir, "-f", + this->CurrentXCodeHackMakefile, "OBJDIR=$(OBJDIR)", + /* placeholder, see below */ "" }); + } // Add ZERO_CHECK bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION"); @@ -663,15 +667,15 @@ void cmGlobalXCodeGenerator::AddExtraTargets( // run the depend check makefile as a post build rule // this will make sure that when the next target is built // things are up-to-date - if (isGenerateProject && + if (this->XcodeBuildSystem == BuildSystem::One && isGenerateProject && target->GetType() == cmStateEnums::OBJECT_LIBRARY) { - commandLines.front().back() = // fill placeholder + legacyDependHelperCommandLines.front().back() = // fill placeholder this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)"); gen->AddCustomCommandToTarget( - target->GetName(), no_byproducts, no_depends, commandLines, - cmCustomCommandType::POST_BUILD, "Depend check for xcode", - dir.c_str(), true, false, "", "", false, - cmObjectLibraryCommands::Accept); + target->GetName(), no_byproducts, no_depends, + legacyDependHelperCommandLines, cmCustomCommandType::POST_BUILD, + "Depend check for xcode", legacyDependHelperDir.c_str(), true, false, + "", "", false, cmObjectLibraryCommands::Accept); } if (!this->IsExcluded(gens[0], target.get())) { @@ -1284,9 +1288,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReference( bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname) { - if (tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" || - tname == "install" || tname == "package" || tname == "RUN_TESTS" || - tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET) { + if (tname == "ALL_BUILD" || tname == "install" || tname == "package" || + tname == "RUN_TESTS" || tname == CMAKE_CHECK_BUILD_SYSTEM_TARGET) { if (this->TargetDoneSet.find(tname) != this->TargetDoneSet.end()) { return true; } @@ -3986,7 +3989,9 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects( for (auto t : targets) { this->AddDependAndLinkInformation(t); } - this->CreateXCodeDependHackTarget(targets); + if (this->XcodeBuildSystem == BuildSystem::One) { + this->CreateXCodeDependHackMakefile(targets); + } // now add all targets to the root object cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST); for (auto t : targets) { @@ -4046,7 +4051,7 @@ void cmGlobalXCodeGenerator::ComputeObjectDirArch(cmMakefile* mf) } } -void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget( +void cmGlobalXCodeGenerator::CreateXCodeDependHackMakefile( std::vector<cmXCodeObject*>& targets) { cmGeneratedFileStream makefileStream(this->CurrentXCodeHackMakefile); diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index fca9c27..5b05214 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -227,7 +227,7 @@ private: std::vector<cmXCodeObject*>&); bool IsHeaderFile(cmSourceFile*); void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget); - void CreateXCodeDependHackTarget(std::vector<cmXCodeObject*>& targets); + void CreateXCodeDependHackMakefile(std::vector<cmXCodeObject*>& targets); bool SpecialTargetEmitted(std::string const& tname); void SetGenerationRoot(cmLocalGenerator* root); void AddExtraTargets(cmLocalGenerator* root, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 47931b0..4e6010c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1955,17 +1955,6 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags, } else if (lang == "CUDA") { target->AddCUDAArchitectureFlags(flags); target->AddCUDAToolkitFlags(flags); - - if (compiler == "Clang") { - bool separable = target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION"); - - if (separable) { - this->Makefile->IssueMessage( - MessageType::FATAL_ERROR, - "CUDA_SEPARABLE_COMPILATION isn't supported on Clang. " - "See CMake issue #20726."); - } - } } else if (lang == "ISPC") { target->AddISPCTargetFlags(flags); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index fad6136..22d3599 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -446,7 +446,7 @@ public: void GetTargetCompileFlags(cmGeneratorTarget* target, std::string const& config, std::string const& lang, std::string& flags, - std::string const& arch = std::string()); + std::string const& arch); std::vector<BT<std::string>> GetTargetCompileFlags( cmGeneratorTarget* target, std::string const& config, std::string const& lang, std::string const& arch = std::string()); diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 9b5c6e6..871878c 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -91,19 +91,12 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( std::vector<std::string> commands; - // Get the language to use for linking this library. - std::string linkLanguage = "CUDA"; + // Get the name of the device object to generate. std::string const& objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); - - // Build list of dependencies. - std::vector<std::string> depends; - this->AppendLinkDepends(depends, linkLanguage); - - // Get the name of the device object to generate. - std::string const targetOutputReal = + std::string const targetOutput = this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt; - this->DeviceLinkObject = targetOutputReal; + this->DeviceLinkObject = targetOutput; this->NumberOfProgressActions++; if (!this->NoRuleMessages) { @@ -111,7 +104,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->MakeEchoProgress(progress); // Add the link message. std::string buildEcho = - cmStrCat("Linking ", linkLanguage, " device code ", + cmStrCat("Linking CUDA device code ", this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), @@ -121,6 +114,29 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } + if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") { + this->WriteDeviceLinkRule(commands, targetOutput); + } else { + this->WriteNvidiaDeviceExecutableRule(relink, commands, targetOutput); + } + + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(targetOutput, relink); +#else + static_cast<void>(relink); +#endif +} + +void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule( + bool relink, std::vector<std::string>& commands, + const std::string& targetOutput) +{ + const std::string linkLanguage = "CUDA"; + + // Build list of dependencies. + std::vector<std::string> depends; + this->AppendLinkDepends(depends, linkLanguage); + // Build a list of compiler flags and linker flags. std::string langFlags; std::string linkFlags; @@ -136,7 +152,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // may need to be cleaned. std::vector<std::string> exeCleanFiles; exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal)); + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput)); // Determine whether a link script will be used. bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); @@ -195,7 +211,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( : cmOutputConverter::SHELL; std::string target = this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal), + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput), output); std::string targetFullPathCompilePDB = @@ -226,7 +242,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->LocalGenerator->CreateRulePlaceholderExpander()); // Expand placeholders in the commands. - rulePlaceholderExpander->SetTargetImpLib(targetOutputReal); + rulePlaceholderExpander->SetTargetImpLib(targetOutput); for (std::string& real_link_command : real_link_commands) { real_link_command = cmStrCat(launcher, real_link_command); rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, @@ -255,17 +271,10 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( // Write the build rule. this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, - targetOutputReal, depends, commands, - false); - - // Write the main driver rule to build everything in this target. - this->WriteTargetDriverRule(targetOutputReal, relink); + targetOutput, depends, commands, false); // Clean all the possible executable names and symlinks. this->CleanFiles.insert(exeCleanFiles.begin(), exeCleanFiles.end()); -#else - static_cast<void>(relink); -#endif } void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h index 782692a..520f577 100644 --- a/Source/cmMakefileExecutableTargetGenerator.h +++ b/Source/cmMakefileExecutableTargetGenerator.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmMakefileTargetGenerator.h" @@ -23,6 +24,9 @@ public: protected: virtual void WriteExecutableRule(bool relink); virtual void WriteDeviceExecutableRule(bool relink); + virtual void WriteNvidiaDeviceExecutableRule( + bool relink, std::vector<std::string>& commands, + const std::string& targetOutput); private: std::string DeviceLinkObject; diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 1c25fc4..b32ea6a 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -129,8 +129,7 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() const bool requiresDeviceLinking = requireDeviceLinking( *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName()); if (requiresDeviceLinking) { - std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; - this->WriteDeviceLibraryRules(linkRuleVar, false); + this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", false); } std::string linkLanguage = @@ -156,8 +155,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink) const bool requiresDeviceLinking = requireDeviceLinking( *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName()); if (requiresDeviceLinking) { - std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; - this->WriteDeviceLibraryRules(linkRuleVar, relink); + this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink); } } @@ -191,8 +189,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink) const bool requiresDeviceLinking = requireDeviceLinking( *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName()); if (requiresDeviceLinking) { - std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY"; - this->WriteDeviceLibraryRules(linkRuleVar, relink); + this->WriteDeviceLibraryRules("CMAKE_CUDA_DEVICE_LINK_LIBRARY", relink); } } @@ -239,29 +236,13 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( // TODO: Merge the methods that call this method to avoid // code duplication. std::vector<std::string> commands; - - // Get the language to use for linking this library. - std::string linkLanguage = "CUDA"; std::string const objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); - // Build list of dependencies. - std::vector<std::string> depends; - this->AppendLinkDepends(depends, linkLanguage); - - // Add language-specific flags. - std::string langFlags; - this->LocalGenerator->AddLanguageFlagsForLinking( - langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName()); - - // Create set of linking flags. - std::string linkFlags; - this->GetDeviceLinkFlags(linkFlags, linkLanguage); - // Get the name of the device object to generate. - std::string const targetOutputReal = + std::string const targetOutput = this->GeneratorTarget->ObjectDirectory + "cmake_device_link" + objExt; - this->DeviceLinkObject = targetOutputReal; + this->DeviceLinkObject = targetOutput; this->NumberOfProgressActions++; if (!this->NoRuleMessages) { @@ -269,7 +250,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->MakeEchoProgress(progress); // Add the link message. std::string buildEcho = - cmStrCat("Linking ", linkLanguage, " device code ", + cmStrCat("Linking CUDA device code ", this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), @@ -278,10 +259,41 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->LocalGenerator->AppendEcho( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } + + if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") { + this->WriteDeviceLinkRule(commands, targetOutput); + } else { + this->WriteNvidiaDeviceLibraryRules(linkRuleVar, relink, commands, + targetOutput); + } + + // Write the main driver rule to build everything in this target. + this->WriteTargetDriverRule(targetOutput, relink); +} + +void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules( + const std::string& linkRuleVar, bool relink, + std::vector<std::string>& commands, const std::string& targetOutput) +{ + std::string linkLanguage = "CUDA"; + + // Build list of dependencies. + std::vector<std::string> depends; + this->AppendLinkDepends(depends, linkLanguage); + + // Add language-specific flags. + std::string langFlags; + this->LocalGenerator->AddLanguageFlagsForLinking( + langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName()); + + // Create set of linking flags. + std::string linkFlags; + this->GetDeviceLinkFlags(linkFlags, linkLanguage); + // Clean files associated with this library. std::set<std::string> libCleanFiles; libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal)); + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput)); // Determine whether a link script will be used. bool useLinkScript = this->GlobalGenerator->GetUseLinkScript(); @@ -335,7 +347,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( std::string target = this->LocalGenerator->ConvertToOutputFormat( this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal), + this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutput), output); std::string targetFullPathCompilePDB = @@ -364,7 +376,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->LocalGenerator->CreateRulePlaceholderExpander()); // Construct the main link rule and expand placeholders. - rulePlaceholderExpander->SetTargetImpLib(targetOutputReal); + rulePlaceholderExpander->SetTargetImpLib(targetOutput); std::string linkRule = this->GetLinkRule(linkRuleVar); cmExpandList(linkRule, real_link_commands); @@ -399,14 +411,11 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( commands1.clear(); // Compute the list of outputs. - std::vector<std::string> outputs(1, targetOutputReal); + std::vector<std::string> outputs(1, targetOutput); // Write the build rule. this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends, commands, false); - - // Write the main driver rule to build everything in this target. - this->WriteTargetDriverRule(targetOutputReal, relink); #else static_cast<void>(linkRuleVar); static_cast<void>(relink); diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index 6a38e18..cc989e7 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <string> +#include <vector> #include "cmMakefileTargetGenerator.h" @@ -27,6 +28,10 @@ protected: void WriteModuleLibraryRules(bool relink); void WriteDeviceLibraryRules(const std::string& linkRule, bool relink); + void WriteNvidiaDeviceLibraryRules(const std::string& linkRuleVar, + bool relink, + std::vector<std::string>& commands, + const std::string& targetOutput); void WriteLibraryRules(const std::string& linkRule, const std::string& extraFlags, bool relink); // MacOSX Framework support methods diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e1fe0e5..5f97d86 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -2,10 +2,13 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmMakefileTargetGenerator.h" +#include <algorithm> #include <cassert> #include <cstdio> +#include <iterator> #include <sstream> #include <unordered_map> +#include <unordered_set> #include <utility> #include <cm/memory> @@ -25,6 +28,7 @@ #include "cmMakefileExecutableTargetGenerator.h" #include "cmMakefileLibraryTargetGenerator.h" #include "cmMakefileUtilityTargetGenerator.h" +#include "cmMessageType.h" #include "cmOutputConverter.h" #include "cmPolicies.h" #include "cmProperty.h" @@ -1323,6 +1327,130 @@ void cmMakefileTargetGenerator::WriteObjectDependRules( } } +void cmMakefileTargetGenerator::WriteDeviceLinkRule( + std::vector<std::string>& commands, const std::string& output) +{ + std::string architecturesStr = + this->GeneratorTarget->GetSafeProperty("CUDA_ARCHITECTURES"); + + if (cmIsOff(architecturesStr)) { + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "CUDA_SEPARABLE_COMPILATION on Clang " + "requires CUDA_ARCHITECTURES to be set."); + return; + } + + std::vector<std::string> architectures = cmExpandedList(architecturesStr); + + // Ensure there are no duplicates. + const std::vector<std::string> linkDeps = [&]() -> std::vector<std::string> { + std::vector<std::string> deps; + this->AppendTargetDepends(deps, true); + this->GeneratorTarget->GetLinkDepends(deps, this->GetConfigName(), "CUDA"); + std::copy(this->Objects.begin(), this->Objects.end(), + std::back_inserter(deps)); + + std::unordered_set<std::string> depsSet(deps.begin(), deps.end()); + deps.clear(); + std::copy(depsSet.begin(), depsSet.end(), std::back_inserter(deps)); + return deps; + }(); + + const std::string objectDir = this->GeneratorTarget->ObjectDirectory; + const std::string relObjectDir = + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), objectDir); + + // Construct a list of files associated with this executable that + // may need to be cleaned. + std::vector<std::string> cleanFiles; + cleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), output)); + + std::string profiles; + std::vector<std::string> fatbinaryDepends; + std::string registerFile = cmStrCat(objectDir, "cmake_cuda_register.h"); + + // Link device code for each architecture. + for (const std::string& architectureKind : architectures) { + // Clang always generates real code, so strip the specifier. + const std::string architecture = + architectureKind.substr(0, architectureKind.find('-')); + const std::string cubin = + cmStrCat(relObjectDir, "sm_", architecture, ".cubin"); + + profiles += cmStrCat(" -im=profile=sm_", architecture, ",file=", cubin); + fatbinaryDepends.emplace_back(cubin); + + std::string registerFileCmd; + + // The generated register file contains macros that when expanded register + // the device routines. Because the routines are the same for all + // architectures the register file will be the same too. Thus generate it + // only on the first invocation to reduce overhead. + if (fatbinaryDepends.size() == 1) { + std::string registerFileRel = + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), registerFile); + registerFileCmd = + cmStrCat(" --register-link-binaries=", registerFileRel); + cleanFiles.push_back(registerFileRel); + } + + std::string command = cmStrCat( + this->Makefile->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"), + " -arch=sm_", architecture, registerFileCmd, " -o=$@ ", + cmJoin(linkDeps, " ")); + + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, cubin, + linkDeps, { command }, false); + } + + // Combine all architectures into a single fatbinary. + const std::string fatbinaryCommand = + cmStrCat(this->Makefile->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"), + " -64 -cmdline=--compile-only -compress-all -link " + "--embedded-fatbin=$@", + profiles); + const std::string fatbinaryOutput = + cmStrCat(objectDir, "cmake_cuda_fatbin.h"); + const std::string fatbinaryOutputRel = + this->LocalGenerator->MaybeConvertToRelativePath( + this->LocalGenerator->GetCurrentBinaryDirectory(), fatbinaryOutput); + + this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, nullptr, + fatbinaryOutputRel, fatbinaryDepends, + { fatbinaryCommand }, false); + + // Compile the stub that registers the kernels and contains the fatbinaries. + cmRulePlaceholderExpander::RuleVariables vars; + vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str(); + vars.CMTargetType = + cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str(); + + vars.Language = "CUDA"; + vars.Object = output.c_str(); + vars.Fatbinary = fatbinaryOutput.c_str(); + vars.RegisterFile = registerFile.c_str(); + + std::string flags = this->GetFlags("CUDA", this->GetConfigName()); + vars.Flags = flags.c_str(); + + std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE"); + std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( + this->LocalGenerator->CreateRulePlaceholderExpander()); + rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, + compileCmd, vars); + + commands.emplace_back(compileCmd); + this->LocalGenerator->WriteMakeRule( + *this->BuildFileStream, nullptr, output, + { cmStrCat(relObjectDir, "cmake_cuda_fatbin.h") }, commands, false); + + // Clean all the possible executable names and symlinks. + this->CleanFiles.insert(cleanFiles.begin(), cleanFiles.end()); +} + void cmMakefileTargetGenerator::GenerateCustomRuleFile( cmCustomCommandGenerator const& ccg) { @@ -1579,10 +1707,11 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule( } void cmMakefileTargetGenerator::AppendTargetDepends( - std::vector<std::string>& depends) + std::vector<std::string>& depends, bool ignoreType) { // Static libraries never depend on anything for linking. - if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) { + if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY && + !ignoreType) { return; } diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 1740d54..cb804e0 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -104,6 +104,10 @@ protected: void WriteObjectDependRules(cmSourceFile const& source, std::vector<std::string>& depends); + // CUDA device linking. + void WriteDeviceLinkRule(std::vector<std::string>& commands, + const std::string& output); + // write the build rule for a custom command void GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg); @@ -127,7 +131,8 @@ protected: void DriveCustomCommands(std::vector<std::string>& depends); // append intertarget dependencies - void AppendTargetDepends(std::vector<std::string>& depends); + void AppendTargetDepends(std::vector<std::string>& depends, + bool ignoreType = false); // Append object file dependencies. void AppendObjectDepends(std::vector<std::string>& depends); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 210b36e..ccb959b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -8,6 +8,7 @@ #include <map> #include <set> #include <sstream> +#include <unordered_set> #include <utility> #include <cm/memory> @@ -25,6 +26,7 @@ #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" +#include "cmMessageType.h" #include "cmNinjaLinkLineDeviceComputer.h" #include "cmNinjaTypes.h" #include "cmOSXBundleGenerator.h" @@ -178,6 +180,33 @@ std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule( "_", config); } +std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaDeviceRule( + const std::string& config) const +{ + return cmStrCat( + this->TargetLinkLanguage(config), "_DEVICE_LINK__", + cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()), + '_', config); +} + +std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaDeviceCompileRule( + const std::string& config) const +{ + return cmStrCat( + this->TargetLinkLanguage(config), "_DEVICE_LINK_COMPILE__", + cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()), + '_', config); +} + +std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaFatbinaryRule( + const std::string& config) const +{ + return cmStrCat( + this->TargetLinkLanguage(config), "_FATBINARY__", + cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()), + '_', config); +} + struct cmNinjaRemoveNoOpCommands { bool operator()(std::string const& cmd) @@ -186,7 +215,7 @@ struct cmNinjaRemoveNoOpCommands } }; -void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule( +void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule( bool useResponseFile, const std::string& config) { cmNinjaRule rule(this->LanguageLinkerDeviceRule(config)); @@ -272,6 +301,55 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule( } } +void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( + const std::string& config) +{ + const cmMakefile* mf = this->GetMakefile(); + + cmNinjaRule rule(LanguageLinkerCudaDeviceRule(config)); + rule.Command = this->GetLocalGenerator()->BuildCommandLine( + { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"), + " -arch=$ARCH $REGISTER -o=$out $in") }); + rule.Comment = "Rule for CUDA device linking."; + rule.Description = "Linking CUDA $out"; + this->GetGlobalGenerator()->AddRule(rule); + + cmRulePlaceholderExpander::RuleVariables vars; + vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str(); + vars.CMTargetType = + cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str(); + + vars.Language = "CUDA"; + vars.Object = "$out"; + vars.Fatbinary = "$FATBIN"; + vars.RegisterFile = "$REGISTER"; + + std::string flags = this->GetFlags("CUDA", config); + vars.Flags = flags.c_str(); + + std::string compileCmd = this->GetMakefile()->GetRequiredDefinition( + "CMAKE_CUDA_DEVICE_LINK_COMPILE"); + std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( + this->GetLocalGenerator()->CreateRulePlaceholderExpander()); + rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), + compileCmd, vars); + + rule.Name = LanguageLinkerCudaDeviceCompileRule(config); + rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }); + rule.Comment = "Rule for compiling CUDA device stubs."; + rule.Description = "Compiling CUDA device stub $out"; + this->GetGlobalGenerator()->AddRule(rule); + + rule.Name = LanguageLinkerCudaFatbinaryRule(config); + rule.Command = this->GetLocalGenerator()->BuildCommandLine( + { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"), + " -64 -cmdline=--compile-only -compress-all -link " + "--embedded-fatbin=$out $PROFILES") }); + rule.Comment = "Rule for CUDA fatbinaries."; + rule.Description = "Creating fatbinary $out"; + this->GetGlobalGenerator()->AddRule(rule); +} + void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, const std::string& config) { @@ -586,7 +664,6 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( // First and very important step is to make sure while inside this // step our link language is set to CUDA - std::string cudaLinkLanguage = "CUDA"; std::string const& objExt = this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION"); @@ -598,6 +675,118 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( std::string targetOutputReal = ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt); + if (firstForConfig) { + globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal); + } + this->DeviceLinkObject = targetOutputReal; + + // Write comments. + cmGlobalNinjaGenerator::WriteDivider(this->GetCommonFileStream()); + this->GetCommonFileStream() + << "# Device Link build statements for " + << cmState::GetTargetTypeName(genTarget->GetType()) << " target " + << this->GetTargetName() << "\n\n"; + + if (this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID") == "Clang") { + std::string architecturesStr = + this->GeneratorTarget->GetSafeProperty("CUDA_ARCHITECTURES"); + + if (cmIsOff(architecturesStr)) { + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "CUDA_SEPARABLE_COMPILATION on Clang " + "requires CUDA_ARCHITECTURES to be set."); + return; + } + + this->WriteDeviceLinkRules(config); + this->WriteDeviceLinkStatements(config, cmExpandedList(architecturesStr), + targetOutputReal); + } else { + this->WriteNvidiaDeviceLinkStatement(config, fileConfig, targetOutputDir, + targetOutputReal); + } +} + +void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements( + const std::string& config, const std::vector<std::string>& architectures, + const std::string& output) +{ + // Ensure there are no duplicates. + const cmNinjaDeps explicitDeps = [&]() -> std::vector<std::string> { + std::unordered_set<std::string> depsSet; + const cmNinjaDeps linkDeps = + this->ComputeLinkDeps(this->TargetLinkLanguage(config), config, true); + const cmNinjaDeps objects = this->GetObjects(config); + depsSet.insert(linkDeps.begin(), linkDeps.end()); + depsSet.insert(objects.begin(), objects.end()); + + std::vector<std::string> deps; + std::copy(depsSet.begin(), depsSet.end(), std::back_inserter(deps)); + return deps; + }(); + + const std::string objectDir = + cmStrCat(this->GeneratorTarget->GetSupportDirectory(), + this->GetGlobalGenerator()->ConfigDirectory(config)); + const std::string ninjaOutputDir = this->ConvertToNinjaPath(objectDir); + + cmNinjaBuild fatbinary(LanguageLinkerCudaFatbinaryRule(config)); + + // Link device code for each architecture. + for (const std::string& architectureKind : architectures) { + // Clang always generates real code, so strip the specifier. + const std::string architecture = + architectureKind.substr(0, architectureKind.find('-')); + const std::string cubin = + cmStrCat(ninjaOutputDir, "/sm_", architecture, ".cubin"); + + fatbinary.Variables["PROFILES"] += + cmStrCat(" -im=profile=sm_", architecture, ",file=", cubin); + fatbinary.ExplicitDeps.emplace_back(cubin); + + cmNinjaBuild dlink(LanguageLinkerCudaDeviceRule(config)); + dlink.ExplicitDeps = explicitDeps; + dlink.Outputs = { cubin }; + dlink.Variables["ARCH"] = cmStrCat("sm_", architecture); + + // The generated register file contains macros that when expanded register + // the device routines. Because the routines are the same for all + // architectures the register file will be the same too. Thus generate it + // only on the first invocation to reduce overhead. + if (fatbinary.ExplicitDeps.size() == 1) { + dlink.Variables["REGISTER"] = cmStrCat( + "--register-link-binaries=", ninjaOutputDir, "/cmake_cuda_register.h"); + } + + this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), dlink); + } + + // Combine all architectures into a single fatbinary. + fatbinary.Outputs = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") }; + this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), + fatbinary); + + // Compile the stub that registers the kernels and contains the fatbinaries. + cmNinjaBuild dcompile(LanguageLinkerCudaDeviceCompileRule(config)); + dcompile.Outputs = { output }; + dcompile.ExplicitDeps = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") }; + dcompile.Variables["FATBIN"] = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmStrCat(objectDir, "/cmake_cuda_fatbin.h"), cmOutputConverter::SHELL); + dcompile.Variables["REGISTER"] = + this->GetLocalGenerator()->ConvertToOutputFormat( + cmStrCat(objectDir, "/cmake_cuda_register.h"), cmOutputConverter::SHELL); + this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), + dcompile); +} + +void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( + const std::string& config, const std::string& fileConfig, + const std::string& outputDir, const std::string& output) +{ + cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); + cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator(); + std::string targetOutputImplib = ConvertToNinjaPath( genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); @@ -606,8 +795,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget), globalGen->ConfigDirectory(fileConfig), "/"); targetOutputFileConfigDir = - globalGen->ExpandCFGIntDir(targetOutputDir, fileConfig); - if (targetOutputDir == targetOutputFileConfigDir) { + globalGen->ExpandCFGIntDir(outputDir, fileConfig); + if (outputDir == targetOutputFileConfigDir) { return; } @@ -623,27 +812,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( } } - if (firstForConfig) { - globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal); - } - this->DeviceLinkObject = targetOutputReal; - - // Write comments. - cmGlobalNinjaGenerator::WriteDivider(this->GetCommonFileStream()); - const cmStateEnums::TargetType targetType = genTarget->GetType(); - this->GetCommonFileStream() << "# Device Link build statements for " - << cmState::GetTargetTypeName(targetType) - << " target " << this->GetTargetName() << "\n\n"; - // Compute the comment. cmNinjaBuild build(this->LanguageLinkerDeviceRule(config)); build.Comment = - cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal); + cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', output); cmNinjaVars& vars = build.Variables; // Compute outputs. - build.Outputs.push_back(targetOutputReal); + build.Outputs.push_back(output); // Compute specific libraries to link with. build.ExplicitDeps = this->GetObjects(config); build.ImplicitDeps = @@ -659,7 +836,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator(); vars["TARGET_FILE"] = - localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL); + localGen.ConvertToOutputFormat(output, cmOutputConverter::SHELL); std::unique_ptr<cmLinkLineComputer> linkLineComputer( new cmNinjaLinkLineDeviceComputer( @@ -683,8 +860,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( // Compute language specific link flags. std::string langFlags; - localGen.AddLanguageFlagsForLinking(langFlags, genTarget, cudaLinkLanguage, - config); + localGen.AddLanguageFlagsForLinking(langFlags, genTarget, "CUDA", config); vars["LANGUAGE_COMPILE_FLAGS"] = langFlags; auto const tgtNames = this->TargetNames(config); @@ -692,7 +868,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( vars["SONAME_FLAG"] = this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config)); vars["SONAME"] = tgtNames.SharedObject; - if (targetType == cmStateEnums::SHARED_LIBRARY) { + if (genTarget->GetType() == cmStateEnums::SHARED_LIBRARY) { std::string install_dir = this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config); if (!install_dir.empty()) { @@ -731,7 +907,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( // do not check if the user has explicitly forced a response file. int const commandLineLengthLimit = static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) - - globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config)); + globalGen->GetRuleCmdLength(build.Rule); build.RspFile = this->ConvertToNinjaPath( cmStrCat("CMakeFiles/", genTarget->GetName(), @@ -746,7 +922,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( bool usedResponseFile = false; globalGen->WriteBuild(this->GetCommonFileStream(), build, commandLineLengthLimit, &usedResponseFile); - this->WriteDeviceLinkRule(usedResponseFile, config); + this->WriteNvidiaDeviceLinkRule(usedResponseFile, config); } void cmNinjaNormalTargetGenerator::WriteLinkStatement( diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index 25e40d0..ffc405c 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -21,18 +21,31 @@ public: private: std::string LanguageLinkerRule(const std::string& config) const; std::string LanguageLinkerDeviceRule(const std::string& config) const; + std::string LanguageLinkerCudaDeviceRule(const std::string& config) const; + std::string LanguageLinkerCudaDeviceCompileRule( + const std::string& config) const; + std::string LanguageLinkerCudaFatbinaryRule(const std::string& config) const; const char* GetVisibleTypeName() const; void WriteLanguagesRules(const std::string& config); void WriteLinkRule(bool useResponseFile, const std::string& config); - void WriteDeviceLinkRule(bool useResponseFile, const std::string& config); + void WriteDeviceLinkRules(const std::string& config); + void WriteNvidiaDeviceLinkRule(bool useResponseFile, + const std::string& config); void WriteLinkStatement(const std::string& config, const std::string& fileConfig, bool firstForConfig); void WriteDeviceLinkStatement(const std::string& config, const std::string& fileConfig, bool firstForConfig); + void WriteDeviceLinkStatements(const std::string& config, + const std::vector<std::string>& architectures, + const std::string& output); + void WriteNvidiaDeviceLinkStatement(const std::string& config, + const std::string& fileConfig, + const std::string& outputDir, + const std::string& output); void WriteObjectLibStatement(const std::string& config); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index accdcf1..04d84a0 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -346,11 +346,13 @@ std::string cmNinjaTargetGenerator::ComputeIncludes( } cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps( - const std::string& linkLanguage, const std::string& config) const + const std::string& linkLanguage, const std::string& config, + bool ignoreType) const { // Static libraries never depend on other targets for linking. - if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || - this->GeneratorTarget->GetType() == cmStateEnums::OBJECT_LIBRARY) { + if (!ignoreType && + (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || + this->GeneratorTarget->GetType() == cmStateEnums::OBJECT_LIBRARY)) { return cmNinjaDeps(); } @@ -1009,6 +1011,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( { std::vector<cmSourceFile const*> objectSources; this->GeneratorTarget->GetObjectSources(objectSources, config); + for (cmSourceFile const* sf : objectSources) { this->WriteObjectBuildStatement(sf, config, fileConfig, firstForConfig); } diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 9d9ce60..a27c9b4 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -113,7 +113,8 @@ protected: /// @return the list of link dependency for the given target @a target. cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage, - const std::string& config) const; + const std::string& config, + bool ignoreType = false) const; /// @return the source file path for the given @a source. std::string GetSourceFilePath(cmSourceFile const* source) const; diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 6f40ec6..f5f9c67 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -141,6 +141,16 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( return replaceValues.DependencyFile; } } + if (replaceValues.Fatbinary) { + if (variable == "FATBINARY") { + return replaceValues.Fatbinary; + } + } + if (replaceValues.RegisterFile) { + if (variable == "REGISTER_FILE") { + return replaceValues.RegisterFile; + } + } if (replaceValues.Target) { if (variable == "TARGET_QUOTED") { diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index dfce8bb..c8d107d 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -64,6 +64,8 @@ public: const char* SwiftOutputFileMap; const char* SwiftSources; const char* ISPCHeader; + const char* Fatbinary; + const char* RegisterFile; }; // Expand rule variables in CMake of the type found in language rules diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index fbf4ceb..1e625a4 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -5,7 +5,8 @@ // POSIX APIs are needed # define _POSIX_C_SOURCE 200809L #endif -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__QNX__) // For isascii # define _XOPEN_SOURCE 700 #endif diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index bd6bb3d..67f7e11 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -5,7 +5,8 @@ // POSIX APIs are needed # define _POSIX_C_SOURCE 200809L #endif -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__QNX__) // For isascii # define _XOPEN_SOURCE 700 #endif |