| 1609 | } |
| 1610 | |
| 1611 | void cmMakefileTargetGenerator::WriteDeviceLinkRule( |
| 1612 | std::vector<std::string>& commands, std::string const& output) |
| 1613 | { |
| 1614 | std::string architecturesStr = |
| 1615 | this->GeneratorTarget->GetSafeProperty("CUDA_ARCHITECTURES"); |
| 1616 | |
| 1617 | if (cmIsOff(architecturesStr)) { |
| 1618 | this->Makefile->IssueMessage(MessageType::FATAL_ERROR, |
| 1619 | "CUDA_SEPARABLE_COMPILATION on Clang " |
| 1620 | "requires CUDA_ARCHITECTURES to be set."); |
| 1621 | return; |
| 1622 | } |
| 1623 | |
| 1624 | cmLocalUnixMakefileGenerator3* localGen{ this->LocalGenerator }; |
| 1625 | cmList architectures{ architecturesStr }; |
| 1626 | std::string const& relPath = localGen->GetHomeRelativeOutputPath(); |
| 1627 | |
| 1628 | // Ensure there are no duplicates. |
| 1629 | std::vector<std::string> const linkDeps = [&]() -> std::vector<std::string> { |
| 1630 | std::vector<std::string> deps; |
| 1631 | this->AppendTargetDepends(deps, true); |
| 1632 | this->GeneratorTarget->GetLinkDepends(deps, this->GetConfigName(), "CUDA"); |
| 1633 | |
| 1634 | for (std::string const& obj : this->Objects) { |
| 1635 | deps.emplace_back(cmStrCat(relPath, obj)); |
| 1636 | } |
| 1637 | |
| 1638 | std::unordered_set<std::string> const depsSet(deps.begin(), deps.end()); |
| 1639 | deps.clear(); |
| 1640 | std::copy(depsSet.begin(), depsSet.end(), std::back_inserter(deps)); |
| 1641 | return deps; |
| 1642 | }(); |
| 1643 | |
| 1644 | std::string const objectDir = this->GeneratorTarget->ObjectDirectory; |
| 1645 | std::string const relObjectDir = |
| 1646 | localGen->MaybeRelativeToCurBinDir(objectDir); |
| 1647 | |
| 1648 | // Construct a list of files associated with this executable that |
| 1649 | // may need to be cleaned. |
| 1650 | std::vector<std::string> cleanFiles; |
| 1651 | cleanFiles.push_back(localGen->MaybeRelativeToCurBinDir(output)); |
| 1652 | |
| 1653 | std::string profiles; |
| 1654 | std::vector<std::string> fatbinaryDepends; |
| 1655 | std::string const registerFile = |
| 1656 | cmStrCat(objectDir, "cmake_cuda_register.h"); |
| 1657 | |
| 1658 | // Link device code for each architecture. |
| 1659 | for (std::string const& architectureKind : architectures) { |
| 1660 | std::string registerFileCmd; |
| 1661 | |
| 1662 | // The generated register file contains macros that when expanded |
| 1663 | // register the device routines. Because the routines are the same for |
| 1664 | // all architectures the register file will be the same too. Thus |
| 1665 | // generate it only on the first invocation to reduce overhead. |
| 1666 | if (fatbinaryDepends.empty()) { |
| 1667 | std::string const registerFileRel = |
| 1668 | cmStrCat(relPath, relObjectDir, "cmake_cuda_register.h"); |
no test coverage detected