1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2021 Ivan Komissarov (abbapoh@gmail.com) 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qbs. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef PC_PACKAGE_H 41 #define PC_PACKAGE_H 42 43 #include <variant.h> 44 45 #include <map> 46 #include <optional> 47 #include <stdexcept> 48 #include <string> 49 #include <unordered_map> 50 #include <unordered_set> 51 #include <utility> 52 #include <vector> 53 54 namespace qbs { 55 56 class PcPackage 57 { 58 public: 59 struct Flag 60 { 61 enum class Type { 62 LibraryName = (1 << 0), 63 StaticLibraryName = (1 << 1), 64 LibraryPath = (1 << 2), 65 Framework = (1 << 3), 66 FrameworkPath = (1 << 4), 67 LinkerFlag = (1 << 5), // this is a lie, this is DriverLinkerFlags 68 IncludePath = (1 << 6), 69 SystemIncludePath = (1 << 7), 70 DirAfterIncludePath = (1 << 8), 71 Define = (1 << 9), 72 CompilerFlag = (1 << 10), 73 }; 74 Type type{Type::CompilerFlag}; 75 std::string value; 76 77 static std::string_view typeToString(Type t); 78 static std::optional<Type> typeFromString(std::string_view s); 79 }; 80 81 struct RequiredVersion 82 { 83 enum class ComparisonType { 84 LessThan, 85 GreaterThan, 86 LessThanEqual, 87 GreaterThanEqual, 88 Equal, 89 NotEqual, 90 AlwaysMatch 91 }; 92 93 std::string name; 94 ComparisonType comparison{ComparisonType::GreaterThanEqual}; 95 std::string version; 96 97 static std::string_view comparisonToString(ComparisonType t); 98 static std::optional<ComparisonType> comparisonFromString(std::string_view s); 99 }; 100 101 std::string filePath; 102 std::string baseFileName; 103 std::string name; 104 std::string version; 105 std::string description; 106 std::string url; 107 108 std::vector<Flag> libs; 109 std::vector<Flag> libsPrivate; 110 std::vector<Flag> cflags; 111 112 std::vector<RequiredVersion> requiresPublic; 113 std::vector<RequiredVersion> requiresPrivate; 114 std::vector<RequiredVersion> conflicts; 115 116 using VariablesMap = std::map<std::string, std::string, std::less<>>; 117 VariablesMap variables; 118 119 bool uninstalled{false}; 120 121 PcPackage prependSysroot(std::string_view sysroot) &&; 122 PcPackage removeSystemLibraryPaths(const std::unordered_set<std::string> &libraryPaths) &&; 123 }; 124 125 class PcBrokenPackage 126 { 127 public: 128 std::string filePath; 129 std::string baseFileName; 130 std::string errorText; 131 }; 132 133 class PcPackageVariant: public Variant::variant<PcPackage, PcBrokenPackage> 134 { 135 public: 136 using Base = Variant::variant<PcPackage, PcBrokenPackage>; 137 using Base::Base; 138 isValid()139 bool isValid() const noexcept { return index() == 0; } isBroken()140 bool isBroken() const noexcept { return index() == 1; } 141 asPackage()142 const PcPackage &asPackage() const { return Variant::get<PcPackage>(*this); } asPackage()143 PcPackage &asPackage() { return Variant::get<PcPackage>(*this); } 144 asBrokenPackage()145 const PcBrokenPackage &asBrokenPackage() const { return Variant::get<PcBrokenPackage>(*this); } asBrokenPackage()146 PcBrokenPackage &asBrokenPackage() { return Variant::get<PcBrokenPackage>(*this); } 147 148 template<typename F> decltype(auto)149 decltype(auto) visit(F &&f) const 150 { 151 return Variant::visit(std::forward<F>(f), static_cast<const Base &>(*this)); 152 } 153 154 template<typename F> decltype(auto)155 decltype(auto) visit(F &&f) 156 { 157 return Variant::visit(std::forward<F>(f), static_cast<Base &>(*this)); 158 } 159 getBaseFileName()160 const std::string &getBaseFileName() const 161 { 162 return visit([](auto &&value) noexcept -> const std::string & { 163 return value.baseFileName; 164 }); 165 } 166 }; 167 168 class PcException: public std::runtime_error 169 { 170 public: PcException(const std::string & message)171 explicit PcException(const std::string &message) : std::runtime_error(message) {} 172 }; 173 174 inline bool operator==(const PcPackage::Flag &lhs, const PcPackage::Flag &rhs) 175 { 176 return lhs.type == rhs.type && lhs.value == rhs.value; 177 } 178 179 inline bool operator!=(const PcPackage::Flag &lhs, const PcPackage::Flag &rhs) 180 { 181 return !(lhs == rhs); 182 } 183 184 } // namespace qbs 185 186 namespace std { 187 template<> struct hash<qbs::PcPackage::Flag> 188 { 189 size_t operator()(const qbs::PcPackage::Flag &v) const noexcept 190 { 191 return hash<std::string>()(v.value) + size_t(v.type); 192 } 193 }; 194 } // namespace std 195 196 #endif // PC_PACKAGE_H 197