From 7db16cf229d1c63067c556fa794f57c640d692bc Mon Sep 17 00:00:00 2001 From: rturrado Date: Tue, 22 Oct 2024 13:46:03 +0200 Subject: [PATCH 01/57] Add an initial version of .clang-tidy. Update run_cpp_linters.py to run clang-tidy-18. Fix some clang-tidy issues across the code base. TODO 1: clang-tidy fails to find many header files. TODO 2: clang-tidy fails to recognize 'fs' namespace alias is used. --- .clang-tidy | 47 +++++++++++++++++++ CMakeLists.txt | 2 + emscripten/emscripten_wrapper.hpp | 1 + include/libqasm/v3x/analyzer.hpp | 1 - .../v3x/antlr_custom_error_listener.hpp | 6 +-- include/libqasm/v3x/cqasm_python.hpp | 9 ++-- include/libqasm/v3x/resolver.hpp | 2 + include/libqasm/v3x/syntactic_analyzer.hpp | 4 +- .../libqasm/v3x/syntactic_analyzer_base.hpp | 2 +- scripts/run_cpp_linters.py | 25 ++++++---- src/v3x/antlr_custom_error_listener.cpp | 15 +++--- src/v3x/syntactic_analyzer.cpp | 10 ++-- test/v3x/cpp/integration_test.cpp | 7 ++- test/v3x/cpp/matcher_values.cpp | 10 ++-- test/v3x/cpp/matcher_values.hpp | 6 +-- test/v3x/cpp/test_parse_helper.cpp | 16 +++---- test/v3x/cpp/test_semantic_analyzer.cpp | 15 +++--- 17 files changed, 119 insertions(+), 59 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..2fbdd2bd --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,47 @@ +Checks: | + -*, + clang-analyzer-*, + clang-diagnostic-*, + misc-*, + -misc-const-correctness, + -misc-include-cleaner + -misc-non-private-member-variables-in-classes, + -misc-no-recursion, + -misc-unused-parameters, + -misc-use-anonymous-namespace, + modernize-*, + -modernize-use-trailing-return-type, + readability-identifier-naming, + +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.ClassIgnoredRegexp + value: "bf_cp|f_cp|uf_cp" + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: lower_case + - key: readability-identifier-naming.FunctionIgnoredRegexp + value: ".*_|SetUp|MOCK_METHOD|TEST|TEST_F|TestBody\ + |DescribeNegationTo|DescribeTo|MatchAndExplain|ValuesEq\ + |addErrorListener|copyNodeAnnotation|expandNodeAnnotation|setNodeAnnotation|syntaxError\ + |visit.*" + - key: readability-identifier-naming.MemberCase + value: lower_case + - key: readability-identifier-naming.MemberIgnoredRegexp + value: ".*_" + - key: readability-identifier-naming.ParameterCase + value: lower_case + - key: readability-identifier-naming.ParameterIgnoredRegexp + value: ".*_|AnalysisResult|ParseResult" + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: lower_case + - key: readability-identifier-naming.IgnoreMainLikeFunctions + value: 1 + - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors + value: 1 + - key: modernize-use-default-member-init.UseAssignment + value: 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c576472..b1694e46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_EXPORT_COMPILE_COMMANDS True) + # Library type option. Default is a static library. option(BUILD_SHARED_LIBS "whether the cqasm library should be built as a shared object or as a static library" diff --git a/emscripten/emscripten_wrapper.hpp b/emscripten/emscripten_wrapper.hpp index c373a88a..575ff018 100644 --- a/emscripten/emscripten_wrapper.hpp +++ b/emscripten/emscripten_wrapper.hpp @@ -91,6 +91,7 @@ struct EmscriptenWrapper { std::string analyze_string_to_json(const std::string& data, const std::string& file_name); }; +// NOLINTNEXTLINE EMSCRIPTEN_BINDINGS(CqasmJS) { emscripten::class_("EmscriptenWrapper") .constructor() diff --git a/include/libqasm/v3x/analyzer.hpp b/include/libqasm/v3x/analyzer.hpp index 62dd1c26..07cdc2b3 100644 --- a/include/libqasm/v3x/analyzer.hpp +++ b/include/libqasm/v3x/analyzer.hpp @@ -14,7 +14,6 @@ #include #include "analysis_result.hpp" -#include "analyzer.hpp" #include "libqasm/v3x/ast.hpp" #include "libqasm/v3x/core_function.hpp" #include "libqasm/v3x/parse_helper.hpp" diff --git a/include/libqasm/v3x/antlr_custom_error_listener.hpp b/include/libqasm/v3x/antlr_custom_error_listener.hpp index 39d172c2..95e87937 100644 --- a/include/libqasm/v3x/antlr_custom_error_listener.hpp +++ b/include/libqasm/v3x/antlr_custom_error_listener.hpp @@ -14,12 +14,12 @@ class AntlrCustomErrorListener : public antlr4::BaseErrorListener { */ std::optional file_name_; - void syntaxError(antlr4::Recognizer* recognizer, antlr4::Token* offendingSymbol, size_t line, - size_t charPositionInLine, const std::string& msg, std::exception_ptr e) override; + void syntaxError(antlr4::Recognizer* recognizer, antlr4::Token* offending_symbol, size_t line, + size_t char_position_in_line, const std::string& msg, std::exception_ptr e) override; public: explicit AntlrCustomErrorListener(const std::optional& file_name); - void syntaxError(size_t line, size_t charPositionInLine, const std::string& msg); + void syntaxError(size_t line, size_t char_position_in_line, const std::string& msg); }; } // namespace cqasm::v3x::parser diff --git a/include/libqasm/v3x/cqasm_python.hpp b/include/libqasm/v3x/cqasm_python.hpp index a9093b91..9225c92e 100644 --- a/include/libqasm/v3x/cqasm_python.hpp +++ b/include/libqasm/v3x/cqasm_python.hpp @@ -146,24 +146,25 @@ class V3xAnalyzer { /** * Parses and analyzes a file containing a cQASM v3.0 program. */ - std::vector analyze_file(const std::string& file_name) const; + [[nodiscard]] std::vector analyze_file(const std::string& file_name) const; /** * Parses and analyzes a file containing a cQASM v3.0 program. */ - std::string analyze_file_to_json(const std::string& file_name) const; + [[nodiscard]] std::string analyze_file_to_json(const std::string& file_name) const; /** * Parses and analyzes a string containing a cQASM v3.0 program. * * `file_name` is optional. It is only used when reporting errors. */ - std::vector analyze_string(const std::string& data, const std::string& file_name = "") const; + [[nodiscard]] std::vector analyze_string( + const std::string& data, const std::string& file_name = "") const; /** * Parses and analyzes a string containing a cQASM v3.0 program. * * `file_name` is optional. It is only used when reporting errors. */ - std::string analyze_string_to_json(const std::string& data, const std::string& file_name = "") const; + [[nodiscard]] std::string analyze_string_to_json(const std::string& data, const std::string& file_name = "") const; }; diff --git a/include/libqasm/v3x/resolver.hpp b/include/libqasm/v3x/resolver.hpp index f70796a1..b5801ea0 100644 --- a/include/libqasm/v3x/resolver.hpp +++ b/include/libqasm/v3x/resolver.hpp @@ -36,6 +36,7 @@ using Values = values::Values; // Analysis errors // //-----------------// +// NOLINTBEGIN /** * Exception for failed name resolutions. */ @@ -50,6 +51,7 @@ CQASM_ANALYSIS_ERROR(OverloadResolutionFailure); * Exception for failed resolutions. */ CQASM_ANALYSIS_ERROR(ResolutionFailure); +// NOLINTEND //------------------------// // OverloadedNameResolver // diff --git a/include/libqasm/v3x/syntactic_analyzer.hpp b/include/libqasm/v3x/syntactic_analyzer.hpp index 08657da7..c2bf39d8 100644 --- a/include/libqasm/v3x/syntactic_analyzer.hpp +++ b/include/libqasm/v3x/syntactic_analyzer.hpp @@ -34,7 +34,7 @@ class SyntacticAnalyzer : public BaseSyntacticAnalyzer { std::int64_t get_int_value(antlr4::tree::TerminalNode* node) const; double get_float_value(antlr4::tree::TerminalNode* node) const; - tree::Maybe getArraySize(CqasmParser::ArraySizeDeclarationContext* context); + tree::Maybe get_array_size(CqasmParser::ArraySizeDeclarationContext* context); template tree::One visitVariable(Context* context) { @@ -104,7 +104,7 @@ class SyntacticAnalyzer : public BaseSyntacticAnalyzer { std::any visitFloatLiteral(CqasmParser::FloatLiteralContext* context) override; explicit SyntacticAnalyzer(const std::optional& file_name); - void addErrorListener(AntlrCustomErrorListener* errorListener) override; + void addErrorListener(AntlrCustomErrorListener* error_listener) override; void syntaxError(size_t line, size_t char_position_in_line, const std::string& text) const override; void setNodeAnnotation(const ast::One& node, antlr4::Token* token) const override; void expandNodeAnnotation(const ast::One& node, antlr4::Token* token) const override; diff --git a/include/libqasm/v3x/syntactic_analyzer_base.hpp b/include/libqasm/v3x/syntactic_analyzer_base.hpp index c0caf26a..fedb24eb 100644 --- a/include/libqasm/v3x/syntactic_analyzer_base.hpp +++ b/include/libqasm/v3x/syntactic_analyzer_base.hpp @@ -17,7 +17,7 @@ namespace cqasm::v3x::parser { class BaseSyntacticAnalyzer : public CqasmParserVisitor { public: - virtual void addErrorListener(AntlrCustomErrorListener* errorListener) = 0; + virtual void addErrorListener(AntlrCustomErrorListener* error_listener) = 0; virtual void syntaxError(size_t line, size_t char_position_in_line, const std::string& text) const = 0; virtual void setNodeAnnotation(const ast::One& node, antlr4::Token* token) const = 0; virtual void expandNodeAnnotation(const ast::One& node, antlr4::Token* token) const = 0; diff --git a/scripts/run_cpp_linters.py b/scripts/run_cpp_linters.py index e19f883f..633515c4 100644 --- a/scripts/run_cpp_linters.py +++ b/scripts/run_cpp_linters.py @@ -32,27 +32,36 @@ def get_list_of_cpp_files(root_folder: os.PathLike) -> list[str]: return ret -def run_clang_format(root_folder: os.PathLike): +def run_clang_format(root_folder: os.PathLike, file_list_str: str) -> None: logging.info("Running clang-format") - file_list = get_list_of_cpp_files(root_folder) try: format_file_path = os.path.join(root_folder, ".clang-format") - file_list_str = " ".join(file_list) - command = f"clang-format-18 -i --style=file:{format_file_path} --verbose {file_list_str}" + options = f"-i --style=file:{format_file_path} --verbose" + command = f"clang-format-18 {options} {file_list_str}" subprocess.run(command, shell=True) except FileNotFoundError as err: print("Error running clang-format: {}".format(err.strerror)) exit(3) -def run_clang_tidy(root_folder: os.PathLike): - pass +def run_clang_tidy(root_folder: os.PathLike, file_list_str: str) -> None : + logging.info("Running clang-tidy") + try: + config_file_path = os.path.join(root_folder, ".clang-tidy") + options = f"--config-file={config_file_path} --fix --format-style=file --use-color" + command = f"clang-tidy-18 {options} {file_list_str}" + subprocess.run(command, shell=True) + except FileNotFoundError as err: + print("Error running clang-tidy: {}".format(err.strerror)) + exit(4) def run_cpp_linters(root_folder: os.PathLike): logging.info("Running C++ linters") - run_clang_format(root_folder) - run_clang_tidy(root_folder) + file_list = get_list_of_cpp_files(root_folder) + file_list_str = " ".join(file_list) + run_clang_format(root_folder, file_list_str) + run_clang_tidy(root_folder, file_list_str) def main(argv): diff --git a/src/v3x/antlr_custom_error_listener.cpp b/src/v3x/antlr_custom_error_listener.cpp index de54cdca..cbc873c9 100644 --- a/src/v3x/antlr_custom_error_listener.cpp +++ b/src/v3x/antlr_custom_error_listener.cpp @@ -15,18 +15,19 @@ AntlrCustomErrorListener::AntlrCustomErrorListener(const std::optional" text, so we avoid calculating the size of EOF from its text // Instead, we just return a zero size - size_t token_size = - (offendingSymbol && offendingSymbol->getType() != antlr4::Token::EOF) ? offendingSymbol->getText().size() : 0; + size_t token_size = (offending_symbol && offending_symbol->getType() != antlr4::Token::EOF) + ? offending_symbol->getText().size() + : 0; auto end_column = start_column + token_size; throw error::ParseError{ msg, @@ -35,8 +36,8 @@ void AntlrCustomErrorListener::syntaxError(antlr4::Recognizer* /* recognizer */, { static_cast(line), static_cast(end_column) } } }; } -void AntlrCustomErrorListener::syntaxError(size_t line, size_t charPositionInLine, const std::string& msg) { - syntaxError(nullptr, nullptr, line, charPositionInLine, msg, nullptr); +void AntlrCustomErrorListener::syntaxError(size_t line, size_t char_position_in_line, const std::string& msg) { + syntaxError(nullptr, nullptr, line, char_position_in_line, msg, nullptr); } } // namespace cqasm::v3x::parser diff --git a/src/v3x/syntactic_analyzer.cpp b/src/v3x/syntactic_analyzer.cpp index 1b359b55..175462df 100644 --- a/src/v3x/syntactic_analyzer.cpp +++ b/src/v3x/syntactic_analyzer.cpp @@ -28,8 +28,8 @@ SyntacticAnalyzer::SyntacticAnalyzer(const std::optional& file_name } } -void SyntacticAnalyzer::addErrorListener(AntlrCustomErrorListener* errorListener) { - error_listener_p_ = errorListener; +void SyntacticAnalyzer::addErrorListener(AntlrCustomErrorListener* error_listener) { + error_listener_p_ = error_listener; } void SyntacticAnalyzer::syntaxError(size_t line, size_t char_position_in_line, const std::string& text) const { @@ -239,7 +239,7 @@ std::any SyntacticAnalyzer::visitType(CqasmParser::TypeContext* context) { std::any SyntacticAnalyzer::visitQubitType(CqasmParser::QubitTypeContext* context) { auto ret = - tree::make(tree::make(types::qubit_type_name), getArraySize(context->arraySizeDeclaration())); + tree::make(tree::make(types::qubit_type_name), get_array_size(context->arraySizeDeclaration())); setNodeAnnotation(ret, context->QUBIT_TYPE()->getSymbol()); if (context->arraySizeDeclaration()) { expandNodeAnnotation(ret, context->arraySizeDeclaration()->CLOSE_BRACKET()->getSymbol()); @@ -249,7 +249,7 @@ std::any SyntacticAnalyzer::visitQubitType(CqasmParser::QubitTypeContext* contex std::any SyntacticAnalyzer::visitBitType(CqasmParser::BitTypeContext* context) { auto ret = - tree::make(tree::make(types::bit_type_name), getArraySize(context->arraySizeDeclaration())); + tree::make(tree::make(types::bit_type_name), get_array_size(context->arraySizeDeclaration())); setNodeAnnotation(ret, context->BIT_TYPE()->getSymbol()); if (context->arraySizeDeclaration()) { expandNodeAnnotation(ret, context->arraySizeDeclaration()->CLOSE_BRACKET()->getSymbol()); @@ -257,7 +257,7 @@ std::any SyntacticAnalyzer::visitBitType(CqasmParser::BitTypeContext* context) { return ret; } -Maybe SyntacticAnalyzer::getArraySize(CqasmParser::ArraySizeDeclarationContext* context) { +Maybe SyntacticAnalyzer::get_array_size(CqasmParser::ArraySizeDeclarationContext* context) { return (context) ? Maybe{ std::any_cast>(context->accept(this)).get_ptr() } : Maybe{}; } diff --git a/test/v3x/cpp/integration_test.cpp b/test/v3x/cpp/integration_test.cpp index d3cf730a..85201982 100644 --- a/test/v3x/cpp/integration_test.cpp +++ b/test/v3x/cpp/integration_test.cpp @@ -15,7 +15,6 @@ namespace cqasm::v3x::test { -namespace cq3x = cqasm::v3x; namespace fs = std::filesystem; /** @@ -33,8 +32,8 @@ class IntegrationTest : public ::testing::Test { // Parse the test input file std::string input{}; ASSERT_TRUE(cqasm::test::read_file(path_ / "input.cq", input)); - cq3x::parser::ParseResult parse_result{}; - parse_result = cq3x::parser::parse_string(input, "input.cq"); + parser::ParseResult parse_result{}; + parse_result = parser::parse_string(input, "input.cq"); // Check the debug dump of the parse result std::string ast_actual_file_contents = parse_result.errors.empty() @@ -68,7 +67,7 @@ class IntegrationTest : public ::testing::Test { // If there were no errors, try semantic analysis for (const auto& api_version : std::vector({ "3.0" })) { - auto analyzer = cq3x::analyzer::Analyzer{ api_version }; + auto analyzer = analyzer::Analyzer{ api_version }; analyzer.register_default_constants(); analyzer.register_default_functions(); diff --git a/test/v3x/cpp/matcher_values.cpp b/test/v3x/cpp/matcher_values.cpp index f0eab134..9d781fc1 100644 --- a/test/v3x/cpp/matcher_values.cpp +++ b/test/v3x/cpp/matcher_values.cpp @@ -8,11 +8,11 @@ namespace cqasm::v3x::values { -ValuesEqMatcher::ValuesEqMatcher(const Values& expectedValue) -: expectedValue_(expectedValue) {} +ValuesEqMatcher::ValuesEqMatcher(const Values& expected_value) +: expected_value_(expected_value) {} bool ValuesEqMatcher::MatchAndExplain(const Values& args, std::ostream* /* os */) const { - return args.equals(expectedValue_); + return args.equals(expected_value_); } void ValuesEqMatcher::DescribeTo(std::ostream* os) const { @@ -23,8 +23,8 @@ void ValuesEqMatcher::DescribeNegationTo(std::ostream* os) const { *os << "does not contain values equal to the expected"; } -::testing::Matcher ValuesEq(const Values& expectedValue) { - return ValuesEqMatcher(expectedValue); +::testing::Matcher ValuesEq(const values::Values& expected_value) { + return ValuesEqMatcher(expected_value); } } // namespace cqasm::v3x::values diff --git a/test/v3x/cpp/matcher_values.hpp b/test/v3x/cpp/matcher_values.hpp index 4e3fb690..1fa6707f 100644 --- a/test/v3x/cpp/matcher_values.hpp +++ b/test/v3x/cpp/matcher_values.hpp @@ -12,15 +12,15 @@ class ValuesEqMatcher { public: using is_gtest_matcher = void; - ValuesEqMatcher(const values::Values& expectedValue); + ValuesEqMatcher(const values::Values& expected_value); bool MatchAndExplain(const values::Values& args, std::ostream* os) const; void DescribeTo(std::ostream* os) const; void DescribeNegationTo(std::ostream* os) const; private: - const values::Values& expectedValue_; + const values::Values& expected_value_; }; -::testing::Matcher ValuesEq(const values::Values& expectedValue); +::testing::Matcher ValuesEq(const values::Values& expected_value); } // namespace cqasm::v3x::values diff --git a/test/v3x/cpp/test_parse_helper.cpp b/test/v3x/cpp/test_parse_helper.cpp index 2da4a7fa..4e21f070 100644 --- a/test/v3x/cpp/test_parse_helper.cpp +++ b/test/v3x/cpp/test_parse_helper.cpp @@ -23,19 +23,19 @@ namespace cqasm::v3x::parser { class ParseHelperParseTest : public ::testing::Test { protected: void SetUp() override { scanner_up = std::make_unique(); } - void ExpectScannerParseThrowsParseError() { + void expect_scanner_parse_throws_parse_error() { EXPECT_CALL(*scanner_up, parse()) .WillRepeatedly(::testing::Throw(ParseError{ parse_error_message, file_name, range })); } - void ExpectScannerParseThrowsRuntimeError() { + void expect_scanner_parse_throws_runtime_error() { EXPECT_CALL(*scanner_up, parse()) .WillRepeatedly(::testing::Throw(std::runtime_error{ runtime_error_message.c_str() })); } - void ExpectScannerParseReturnsIllFormedRoot() { + void expect_scanner_parse_returns_ill_formed_root() { auto parse_result = ParseResult{ tree::make(), error::ParseErrors{} }; EXPECT_CALL(*scanner_up, parse()).WillOnce(::testing::Return(parse_result)); } - void ExpectScannerParseReturnsWellFormedRoot() { + void expect_scanner_parse_returns_well_formed_root() { auto one_version = tree::make(version_3_0); auto one_global_block = tree::make(); auto one_program = tree::make(one_version, one_global_block); @@ -56,7 +56,7 @@ class ParseHelperParseTest : public ::testing::Test { }; TEST_F(ParseHelperParseTest, scanner_parse_throws_parse_error) { - ExpectScannerParseThrowsParseError(); + expect_scanner_parse_throws_parse_error(); auto parse_helper = ParseHelper{ std::move(scanner_up), file_name }; auto parse_result = parse_helper.parse(); const auto& errors = parse_result.errors; @@ -70,7 +70,7 @@ TEST_F(ParseHelperParseTest, scanner_parse_throws_parse_error) { parse_error_message)); } TEST_F(ParseHelperParseTest, scanner_parse_throws_runtime_error) { - ExpectScannerParseThrowsRuntimeError(); + expect_scanner_parse_throws_runtime_error(); auto parse_helper = ParseHelper{ std::move(scanner_up), file_name }; auto parse_result = parse_helper.parse(); const auto& errors = parse_result.errors; @@ -78,13 +78,13 @@ TEST_F(ParseHelperParseTest, scanner_parse_throws_runtime_error) { EXPECT_EQ(fmt::format("{}", errors[0]), fmt::format("Error: {}", runtime_error_message)); } TEST_F(ParseHelperParseTest, parse_result_errors_is_empty_and_root_is_ill_formed) { - ExpectScannerParseReturnsIllFormedRoot(); + expect_scanner_parse_returns_ill_formed_root(); auto parse_helper = ParseHelper{ std::move(scanner_up), file_name }; EXPECT_THAT([&]() { parse_helper.parse(); }, ThrowsMessage(::testing::HasSubstr(ill_formed_root_message))); } TEST_F(ParseHelperParseTest, parse_result_errors_is_empty_and_root_is_well_formed) { - ExpectScannerParseReturnsWellFormedRoot(); + expect_scanner_parse_returns_well_formed_root(); auto parse_helper = ParseHelper{ std::move(scanner_up), file_name }; auto parse_result = parse_helper.parse(); auto program = parse_result.root->as_program(); diff --git a/test/v3x/cpp/test_semantic_analyzer.cpp b/test/v3x/cpp/test_semantic_analyzer.cpp index 7b12fff9..169c541e 100644 --- a/test/v3x/cpp/test_semantic_analyzer.cpp +++ b/test/v3x/cpp/test_semantic_analyzer.cpp @@ -7,7 +7,6 @@ #include "libqasm/v3x/values.hpp" #include "mock_analyzer.hpp" -namespace analyzer = cqasm::v3x::analyzer; namespace ast = cqasm::v3x::ast; namespace error = cqasm::error; namespace values = cqasm::v3x::values; @@ -17,16 +16,16 @@ namespace cqasm::v3x::analyzer { class VisitFunctionResolveTest : public ::testing::Test { protected: void SetUp() override {} - void ExpectAnalyzerResolveFunctionOK(const values::Value& function_return_value) { + void expect_analyzer_resolve_function_ok(const values::Value& function_return_value) { EXPECT_CALL(analyzer, resolve_function(::testing::_, ::testing::_)) .WillOnce(::testing::Return(function_return_value)); } - void ExpectAnalyzerResolveFunctionThrow(const std::string& error_message) { + void expect_analyzer_resolve_function_throw(const std::string& error_message) { EXPECT_CALL(analyzer, resolve_function(::testing::_, ::testing::_)) .WillRepeatedly(::testing::Throw(std::runtime_error{ error_message.c_str() })); } - analyzer::MockAnalyzer analyzer; - analyzer::SemanticAnalyzer visitor{ analyzer }; + MockAnalyzer analyzer; + SemanticAnalyzer visitor{ analyzer }; }; /** @@ -34,7 +33,7 @@ class VisitFunctionResolveTest : public ::testing::Test { */ TEST_F(VisitFunctionResolveTest, analyzer_resolve_function_returns_a_non_empty_value) { const auto& function_return_value = values::Value{ cqasm::tree::make(0) }; - ExpectAnalyzerResolveFunctionOK(function_return_value); + expect_analyzer_resolve_function_ok(function_return_value); auto name = cqasm::tree::make("function_that_returns_a_non_empty_value"); auto arguments = cqasm::tree::make(cqasm::tree::Any{}); @@ -45,7 +44,7 @@ TEST_F(VisitFunctionResolveTest, analyzer_resolve_function_returns_a_non_empty_v TEST_F(VisitFunctionResolveTest, analyzer_resolve_function_returns_an_empty_value) { const auto& function_return_value = values::Value{}; - ExpectAnalyzerResolveFunctionOK(function_return_value); + expect_analyzer_resolve_function_ok(function_return_value); auto name = cqasm::tree::make("function_that_returns_an_empty_value"); auto arguments = cqasm::tree::make(cqasm::tree::Any{}); @@ -57,7 +56,7 @@ TEST_F(VisitFunctionResolveTest, analyzer_resolve_function_returns_an_empty_valu TEST_F(VisitFunctionResolveTest, analyzer_resolve_function_throws) { const auto& function_name = std::string{ "function_that_is_not_registered" }; const auto& error_message = fmt::format("failed to resolve '{}'", function_name); - ExpectAnalyzerResolveFunctionThrow(error_message); + expect_analyzer_resolve_function_throw(error_message); auto name = cqasm::tree::make(function_name); auto arguments = cqasm::tree::make(cqasm::tree::Any{}); From 26afd021bb7ea7fd0a0787b96907497afb4e890f Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 7 Nov 2024 17:04:24 +0100 Subject: [PATCH 02/57] Add -misc-unused-alias-decls, as they seem to be false positives. Add BUILD_FOLDER optional parameter to run_cpp_linters.py. Fix some clang-tidy issues across the code base. TODO: update cpp-linters job to run clang-tidy. TODO: potential memory leak warning in gtest.h. --- .clang-tidy | 1 + include/libqasm/error.hpp | 4 ++-- include/libqasm/overload.hpp | 1 - include/libqasm/v3x/analysis_result.hpp | 2 ++ include/libqasm/v3x/antlr_scanner.hpp | 4 ++-- scripts/run_cpp_linters.py | 21 ++++++++++++--------- src/CMakeLists.txt | 3 +-- src/v3x/antlr_scanner.cpp | 8 ++++---- src/v3x/instruction_set.cpp | 2 ++ src/v3x/resolver.cpp | 6 +++++- test/CMakeLists.txt | 1 - 11 files changed, 31 insertions(+), 22 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 2fbdd2bd..f93a7859 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,6 +7,7 @@ Checks: | -misc-include-cleaner -misc-non-private-member-variables-in-classes, -misc-no-recursion, + -misc-unused-alias-decls, -misc-unused-parameters, -misc-use-anonymous-namespace, modernize-*, diff --git a/include/libqasm/error.hpp b/include/libqasm/error.hpp index 24dfe9b2..f7b575d1 100644 --- a/include/libqasm/error.hpp +++ b/include/libqasm/error.hpp @@ -75,7 +75,7 @@ class Error : public std::runtime_error { /** * Returns the message exception-style. */ - const char* what() const noexcept override; + [[nodiscard]] const char* what() const noexcept override; /** * Returns a string with a JSON representation of an Error. @@ -83,7 +83,7 @@ class Error : public std::runtime_error { * Every error is mapped to an LSP Diagnostic structure: * Severity is hardcoded to 1 at the moment (value corresponding to an Error level) */ - std::string to_json() const; + [[nodiscard]] std::string to_json() const; }; /** diff --git a/include/libqasm/overload.hpp b/include/libqasm/overload.hpp index 6f5d44a0..bb5319bf 100644 --- a/include/libqasm/overload.hpp +++ b/include/libqasm/overload.hpp @@ -6,7 +6,6 @@ #include // pair #include -#include "libqasm/overload.hpp" #include "libqasm/tree.hpp" /** diff --git a/include/libqasm/v3x/analysis_result.hpp b/include/libqasm/v3x/analysis_result.hpp index 9d42b3d3..2ba4518f 100644 --- a/include/libqasm/v3x/analysis_result.hpp +++ b/include/libqasm/v3x/analysis_result.hpp @@ -21,8 +21,10 @@ using Root = ast::One; */ class AnalysisFailed : public std::runtime_error { public: + // NOLINTBEGIN AnalysisFailed() : std::runtime_error{ "cQASM analysis failed" } {}; + // NOLINTEND }; /** diff --git a/include/libqasm/v3x/antlr_scanner.hpp b/include/libqasm/v3x/antlr_scanner.hpp index d3c6c14f..6b55d818 100644 --- a/include/libqasm/v3x/antlr_scanner.hpp +++ b/include/libqasm/v3x/antlr_scanner.hpp @@ -42,7 +42,7 @@ class FileAntlrScanner : public AntlrScanner { public: FileAntlrScanner(std::unique_ptr build_visitor_up, - std::unique_ptr error_listener_up, const std::string& file_path); + std::unique_ptr error_listener_up, std::string file_path); ~FileAntlrScanner() override; @@ -54,7 +54,7 @@ class StringAntlrScanner : public AntlrScanner { public: StringAntlrScanner(std::unique_ptr build_visitor_up, - std::unique_ptr error_listener_up, const std::string& data); + std::unique_ptr error_listener_up, std::string data); ~StringAntlrScanner() override; diff --git a/scripts/run_cpp_linters.py b/scripts/run_cpp_linters.py index 633515c4..c30ae8fd 100644 --- a/scripts/run_cpp_linters.py +++ b/scripts/run_cpp_linters.py @@ -9,11 +9,12 @@ def print_usage(): usage_str = ''' Usage: - python3 run_cpp_linters.py + python3 run_cpp_linters.py [] Where: ROOT_FOLDER: folder containing the .clang-format, .clang-tidy, and C++ files. + BUILD_FOLDER: build folder (optional, defaulted to 'build'). Example: - python3 run_cpp_linters.py . + python3 run_cpp_linters.py . cmake-build-debug-clang-wsl ''' logging.info(usage_str) @@ -21,7 +22,7 @@ def print_usage(): def get_list_of_cpp_files(root_folder: os.PathLike) -> list[str]: ret: list[str] = [] file_types = ['cpp', 'hpp'] - input_subfolders = ['emscripten', 'include', 'src', 'test'] + input_subfolders = ['include', 'src', 'test'] for input_subfolder in input_subfolders: input_folder = os.path.join(root_folder, input_subfolder) for root, dirs, files in os.walk(input_folder): @@ -44,11 +45,11 @@ def run_clang_format(root_folder: os.PathLike, file_list_str: str) -> None: exit(3) -def run_clang_tidy(root_folder: os.PathLike, file_list_str: str) -> None : +def run_clang_tidy(root_folder: os.PathLike, build_folder: os.PathLike, file_list_str: str) -> None : logging.info("Running clang-tidy") try: config_file_path = os.path.join(root_folder, ".clang-tidy") - options = f"--config-file={config_file_path} --fix --format-style=file --use-color" + options = f"--config-file={config_file_path} --fix --format-style=file -p {build_folder} --use-color" command = f"clang-tidy-18 {options} {file_list_str}" subprocess.run(command, shell=True) except FileNotFoundError as err: @@ -56,20 +57,22 @@ def run_clang_tidy(root_folder: os.PathLike, file_list_str: str) -> None : exit(4) -def run_cpp_linters(root_folder: os.PathLike): +def run_cpp_linters(root_folder: os.PathLike, build_folder: os.PathLike): logging.info("Running C++ linters") file_list = get_list_of_cpp_files(root_folder) file_list_str = " ".join(file_list) run_clang_format(root_folder, file_list_str) - run_clang_tidy(root_folder, file_list_str) + run_clang_tidy(root_folder, build_folder, file_list_str) def main(argv): logging.basicConfig(level=logging.INFO, format='%(message)s') - if len(argv) != 2: + if len(argv) < 2 or len(argv) > 3: print_usage() exit(2) - run_cpp_linters(os.path.abspath(argv[1])) + root_folder = os.path.abspath(argv[1]) + build_folder = os.path.abspath(argv[2] if len(argv) == 3 else "build") + run_cpp_linters(root_folder, build_folder) if __name__ == '__main__': main(sys.argv) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2afc1b9a..2f28c5d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -248,8 +248,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) -Wall -Wextra -Werror -Wfatal-errors -fPIC -Wno-error=deprecated-declarations - -Wno-error=maybe-uninitialized - -Wno-error=restrict + -Wno-error=uninitialized -Wno-error=sign-compare -Wno-error=unused-parameter ) diff --git a/src/v3x/antlr_scanner.cpp b/src/v3x/antlr_scanner.cpp index db8ca117..5e0a9f3b 100644 --- a/src/v3x/antlr_scanner.cpp +++ b/src/v3x/antlr_scanner.cpp @@ -45,9 +45,9 @@ cqasm::v3x::parser::ParseResult AntlrScanner::parse_(antlr4::ANTLRInputStream& i } FileAntlrScanner::FileAntlrScanner(std::unique_ptr build_visitor_up, - std::unique_ptr error_listener_up, const std::string& file_path) + std::unique_ptr error_listener_up, std::string file_path) : AntlrScanner{ std::move(build_visitor_up), std::move(error_listener_up) } -, file_path_{ file_path } { +, file_path_{ std::move(file_path) } { if (!fs::exists(file_path_) || !fs::is_regular_file(file_path_)) { throw cqasm::error::ParseError{ fmt::format("FileAntlrScanner couldn't access file '{}'.", file_path_) }; } @@ -62,9 +62,9 @@ cqasm::v3x::parser::ParseResult FileAntlrScanner::parse() { } StringAntlrScanner::StringAntlrScanner(std::unique_ptr build_visitor_up, - std::unique_ptr error_listener_up, const std::string& data) + std::unique_ptr error_listener_up, std::string data) : AntlrScanner{ std::move(build_visitor_up), std::move(error_listener_up) } -, data_{ data } {} +, data_{ std::move(data) } {} StringAntlrScanner::~StringAntlrScanner() = default; diff --git a/src/v3x/instruction_set.cpp b/src/v3x/instruction_set.cpp index 20d20df1..4aee3d21 100644 --- a/src/v3x/instruction_set.cpp +++ b/src/v3x/instruction_set.cpp @@ -6,6 +6,7 @@ namespace cqasm::v3x::instruction { +// NOLINTBEGIN InstructionSet::InstructionSet() : named_gate_map{ { "CNOT", { std::nullopt, "QQ" } }, @@ -77,6 +78,7 @@ InstructionSet::InstructionSet() "CNOT", "CR", "CRk", "CZ" } {} +// NOLINTEND [[nodiscard]] /* static */ InstructionSet& InstructionSet::get_instance() { static InstructionSet instance; diff --git a/src/v3x/resolver.cpp b/src/v3x/resolver.cpp index 46da405e..92007c5b 100644 --- a/src/v3x/resolver.cpp +++ b/src/v3x/resolver.cpp @@ -41,8 +41,10 @@ void VariableTable::add(const std::string& name, const Value& value) { // ConstEvalCoreFunctionTable // //----------------------------// +// NOLINTBEGIN ConstEvalCoreFunctionTable::ConstEvalCoreFunctionTable() -: resolver{ std::make_unique() } {} +: resolver{ std::make_unique() } {}; +// NOLINTEND ConstEvalCoreFunctionTable::~ConstEvalCoreFunctionTable() = default; ConstEvalCoreFunctionTable::ConstEvalCoreFunctionTable(const ConstEvalCoreFunctionTable& t) : resolver{ std::make_unique(*t.resolver) } {} @@ -93,8 +95,10 @@ Value ConstEvalCoreFunctionTable::resolve(const std::string& name, const Values& // InstructionTable // //------------------// +// NOLINTBEGIN InstructionTable::InstructionTable() : resolver{ std::make_unique() } {} +// NOLINTEND InstructionTable::~InstructionTable() = default; InstructionTable::InstructionTable(const InstructionTable& t) : resolver{ std::make_unique(*t.resolver) } {} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0375debe..5acd4552 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,7 +34,6 @@ if(CMAKE_COMPILER_IS_GNUCXX) -Wall -Wextra -Werror -Wfatal-errors -fPIC -Wno-error=deprecated-declarations - -Wno-error=restrict -Wno-error=sign-compare ) elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") From ecf49203b89311049687d6070cb06a1e5dcbaa01 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 21 Nov 2024 12:48:20 +0100 Subject: [PATCH 03/57] setup.py: - Change some double quotes to single quotes. - Use CMAKE_BUILD_TYPE instead of LIBQASM_BUILD_TYPE. test.yaml: - Remove export of LIBQASM_BUILD_TYPE. - Reorder list of needed jobs for the 'complete' job. - Add python-macos-arm64 to the list of needed jobs for the 'complete' job. --- .github/workflows/test.yaml | 23 ++++------------------- setup.py | 15 +++++++-------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6fdff61e..12433c8f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -190,10 +190,6 @@ jobs: run: | sudo apt-get install -y swig shell: bash - - name: Export LIBQASM_BUILD_TYPE - run: | - echo "LIBQASM_BUILD_TYPE=Debug" >> $GITHUB_ENV - shell: bash - uses: ./.github/actions/python-tests with: shell: bash @@ -208,10 +204,6 @@ jobs: run: | brew install swig shell: bash - - name: Export LIBQASM_BUILD_TYPE - run: | - echo "LIBQASM_BUILD_TYPE=Debug" >> $GITHUB_ENV - shell: bash - uses: ./.github/actions/python-tests with: shell: bash @@ -226,10 +218,6 @@ jobs: run: | brew install swig shell: bash - - name: Export LIBQASM_BUILD_TYPE - run: | - echo "LIBQASM_BUILD_TYPE=Debug" >> $GITHUB_ENV - shell: bash - uses: ./.github/actions/python-tests with: shell: bash @@ -240,10 +228,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Export LIBQASM_BUILD_TYPE - run: | - echo "LIBQASM_BUILD_TYPE=Release" >> $env:GITHUB_ENV - shell: powershell - uses: ./.github/actions/python-tests with: shell: bash @@ -266,15 +250,16 @@ jobs: # see https://github.community/t/status-check-for-a-matrix-jobs/127354/7 name: Report status needs: - - cpp-shared - cpp-linux-x64 - - cpp-macos-x64 - - cpp-windows-x64 - cpp-linux-arm64 + - cpp-macos-x64 - cpp-macos-arm64 + - cpp-windows-x64 + - cpp-shared - ts-emscripten-wasm - python-linux-x64 - python-macos-x64 + - python-macos-arm64 - python-windows-x64 - docker if: ${{ always() }} diff --git a/setup.py b/setup.py index 829753b5..ed9058fe 100755 --- a/setup.py +++ b/setup.py @@ -16,10 +16,10 @@ def get_version(verbose=False): """Extract version information from source code""" - inc_dir = os.path.join(root_dir, "include", "libqasm") # C++ include directory - matcher = re.compile('static const char\* version\{ "(.*)" \}') + inc_dir = os.path.join(root_dir, 'include', 'libqasm') # C++ include directory + matcher = re.compile('static const char\* version\{ "(.*)" }') version = None - with open(os.path.join(inc_dir, "versioning.hpp"), "r") as f: + with open(os.path.join(inc_dir, 'versioning.hpp'), 'r') as f: for ln in f: m = matcher.match(ln) if m: @@ -91,9 +91,8 @@ def run(self): # Configure and build using Conan with local.cwd(root_dir): - # Build type can be set using an environment variable - build_type = os.environ.get('LIBQASM_BUILD_TYPE', 'Release') - build_tests = os.environ.get("LIBQASM_BUILD_TESTS", "False") + build_type = os.environ.get('CMAKE_BUILD_TYPE', 'Release') + build_tests = os.environ.get('LIBQASM_BUILD_TESTS', 'False') cmd = local['conan']['profile']['detect']['--force'] cmd & FG @@ -117,9 +116,9 @@ def run(self): ['-b']['missing'] ['-tf'][''] ) - if build_tests == "True": + if build_tests == 'True': cmd = cmd['-c']['tools.build:skip_test=False'] - if platform.system() == "Darwin": + if platform.system() == 'Darwin': cmd = cmd['-c']['tools.build:defines=["_LIBCPP_DISABLE_AVAILABILITY"]'] cmd & FG From 8d2f723cea59cb8de4025f4ed9a3494048856ccd Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 13:34:08 +0100 Subject: [PATCH 04/57] Add cpp-linters badge to README.md. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 89e6ac84..716d0c53 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![CI](https://github.com/QuTech-Delft/libqasm/workflows/Test/badge.svg)](https://github.com/qutech-delft/libqasm/actions) [![Conan Center](https://img.shields.io/conan/v/libqasm)](https://conan.io/center/recipes/libqasm) +[![cpp-linter](https://github.com/cpp-linter/cpp-linter-action/actions/workflows/cpp-linter.yml/badge.svg)](https://github.com/cpp-linter/cpp-linter-action/actions/workflows/cpp-linter.yml) [![PyPI](https://badgen.net/pypi/v/libqasm)](https://pypi.org/project/libqasm/) ![OS](https://img.shields.io/badge/os-emscripten%20%7C%20linux%20%7C%20macos%20%7C%20windows-blue?style=flat-square) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) From b4594e49f43f262c51b43ecccce417a0997c871a Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 13:34:41 +0100 Subject: [PATCH 05/57] Enable clang-tidy checks in linters workflow. --- .github/workflows/linters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index b7dc446d..fff1fc4d 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -23,7 +23,7 @@ jobs: with: extensions: 'cpp,hpp' style: 'file' # use .clang-format config file - tidy-checks: '-*' # disable clang-tidy checks + tidy-checks: '' # use .clang-tidy config file version: 18 - name: Fail fast if: steps.linter.outputs.clang-format-checks-failed > 0 From 9fbac229992cd52abec0b66a9d5e0805e9daa2bc Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 13:47:49 +0100 Subject: [PATCH 06/57] Change the value of two variables from True to ON. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1694e46..5167e0e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,10 +20,10 @@ project(cqasm LANGUAGES C CXX) if(NOT TARGET cqasm) set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_EXPORT_COMPILE_COMMANDS True) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Library type option. Default is a static library. option(BUILD_SHARED_LIBS From 822704c74840f40faef0cd40e8f92b88054d8ed5 Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 13:48:02 +0100 Subject: [PATCH 07/57] Update cpp-linters job checks. --- .github/workflows/linters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index fff1fc4d..a6daddc5 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -26,7 +26,7 @@ jobs: tidy-checks: '' # use .clang-tidy config file version: 18 - name: Fail fast - if: steps.linter.outputs.clang-format-checks-failed > 0 + if: steps.linter.outputs.checks-failed > 0 run: | echo "::notice::Try executing 'python3 ./scripts/run_cpp_linters.py .' to fix linter issues." exit 1 From 2341fc7d7524fdc350bb8a8322b8b3355e8a9cfc Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:00:45 +0100 Subject: [PATCH 08/57] Change cpp-linters job to build gcc/Linux/x64 before running the linters. --- .github/workflows/linters.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index a6daddc5..66051401 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -15,6 +15,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Build C++ tests (gcc/Linux/x64) + uses: ./.github/actions/cpp-tests + with: + build_type: Release + conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-gcc-linux-x64 + shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 id: linter From 56e2e701da373d53f41d76bcde9b51b160b6d5ca Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:00:45 +0100 Subject: [PATCH 09/57] Change cpp-linters job to build gcc/Linux/x64 before running the linters. --- .github/workflows/linters.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index a6daddc5..c6b8e6f2 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -15,6 +15,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Build C++ tests (gcc/Linux/x64) + uses: ./.github/actions/cpp-tests + with: + build_type: Release + conan_profile_host: conan/profiles/tests-release-gcc-linux-x64 + shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 id: linter From d60595904952a0acc638c8abf27da7d786db76ec Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:25:41 +0100 Subject: [PATCH 10/57] Trying to correctly set cpp-linter-action database (folder where compile_commands.json is). --- .github/workflows/linters.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index c6b8e6f2..939e9c28 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -27,6 +27,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: + database: '${{ github.workspace }}/build/Release' extensions: 'cpp,hpp' style: 'file' # use .clang-format config file tidy-checks: '' # use .clang-tidy config file From c0edcb5596d83c8a063bd2167a741d3814b756b3 Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:42:37 +0100 Subject: [PATCH 11/57] Building emscripten binaries (so that cpp-linters can find emscripten/bind.h). --- .github/workflows/linters.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index 939e9c28..2c586ebb 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -19,7 +19,7 @@ jobs: uses: ./.github/actions/cpp-tests with: build_type: Release - conan_profile_host: conan/profiles/tests-release-gcc-linux-x64 + conan_profile_host: conan/profiles/tests-release-clang-emscripten-wasm shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 From 7d8301a0fdc6d7152a69b5d95f9f6e85bfd1b097 Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:44:29 +0100 Subject: [PATCH 12/57] Building emscripten binaries (so that cpp-linters can find emscripten/bind.h). --- .github/workflows/linters.yaml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index 2c586ebb..f59c3b8a 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -15,12 +15,25 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Build C++ tests (gcc/Linux/x64) - uses: ./.github/actions/cpp-tests + - name: Install node + uses: actions/setup-node@v4 with: - build_type: Release - conan_profile_host: conan/profiles/tests-release-clang-emscripten-wasm - shell: bash + node-version: 16.20.2 + - name: Install conan + run: | + pipx install conan + shell: bash + - name: Get latest CMake + uses: lukka/get-cmake@latest + # We clean the Conan cache as a preventive measure for our runs in self-hosted runners + # Self-hosted runners use containers that cache Conan packages from previous runs, + # and that can cause different type of problems + - name: Configure and build TS tests (clang/emscripten/wasm) + run: | + conan profile detect --force + conan remove -c "*/*" + conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing + shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 id: linter From e471a5f34e78c1b5f08fc07493a9d6563c2e5420 Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 18:51:32 +0100 Subject: [PATCH 13/57] Building gcc/Linux/x64 but ignoring emscripten_wrapper.hpp. --- .github/workflows/linters.yaml | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index f59c3b8a..a5103b26 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -15,25 +15,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install node - uses: actions/setup-node@v4 + - name: Build C++ tests (gcc/Linux/x64) + uses: ./.github/actions/cpp-tests with: - node-version: 16.20.2 - - name: Install conan - run: | - pipx install conan - shell: bash - - name: Get latest CMake - uses: lukka/get-cmake@latest - # We clean the Conan cache as a preventive measure for our runs in self-hosted runners - # Self-hosted runners use containers that cache Conan packages from previous runs, - # and that can cause different type of problems - - name: Configure and build TS tests (clang/emscripten/wasm) - run: | - conan profile detect --force - conan remove -c "*/*" - conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing - shell: bash + build_type: Release + conan_profile_host: conan/profiles/tests-release-gcc-linux-x64 + shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 id: linter @@ -42,6 +29,7 @@ jobs: with: database: '${{ github.workspace }}/build/Release' extensions: 'cpp,hpp' + ignore: 'emscripten/emscripten_wrapper.hpp' style: 'file' # use .clang-format config file tidy-checks: '' # use .clang-tidy config file version: 18 From fdc9cd861f35d5ee130d81dc8532812654e656cb Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 22 Nov 2024 19:03:06 +0100 Subject: [PATCH 14/57] Run cpp-linters both for gcc and clang. --- .github/workflows/linters.yaml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index a5103b26..bcedc18b 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -12,14 +12,22 @@ jobs: cpp-linters: name: "C++ linters" runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + build_type: + - Release + compiler: + - clang + - gcc steps: - name: Checkout uses: actions/checkout@v4 - - name: Build C++ tests (gcc/Linux/x64) + - name: Build C++ tests (gcc-clang/Linux/x64) uses: ./.github/actions/cpp-tests with: - build_type: Release - conan_profile_host: conan/profiles/tests-release-gcc-linux-x64 + build_type: ${{ matrix.build_type }} + conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-x64 shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 From c3efeb4bbaa3f601937f0c5295905451ba227cd9 Mon Sep 17 00:00:00 2001 From: rturrado Date: Sat, 23 Nov 2024 00:02:31 +0100 Subject: [PATCH 15/57] Temporarily remove clang compiler from cpp-linters job. --- .github/workflows/linters.yaml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index bcedc18b..cb50b2ec 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -12,22 +12,14 @@ jobs: cpp-linters: name: "C++ linters" runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - build_type: - - Release - compiler: - - clang - - gcc steps: - name: Checkout uses: actions/checkout@v4 - name: Build C++ tests (gcc-clang/Linux/x64) uses: ./.github/actions/cpp-tests with: - build_type: ${{ matrix.build_type }} - conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-x64 + build_type: Release + conan_profile_host: conan/profiles/tests-release-gcc-linux-x64 shell: bash - name: Run C++ linters uses: cpp-linter/cpp-linter-action@v2 From ddca4921fbc688bd18f65e047a3a8eb678dad8ac Mon Sep 17 00:00:00 2001 From: rturrado Date: Sat, 23 Nov 2024 00:03:01 +0100 Subject: [PATCH 16/57] Test multi-line notice message. --- .github/workflows/linters.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index cb50b2ec..02db3ae0 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -34,7 +34,9 @@ jobs: tidy-checks: '' # use .clang-tidy config file version: 18 - name: Fail fast - if: steps.linter.outputs.checks-failed > 0 +# if: steps.linter.outputs.checks-failed > 0 run: | - echo "::notice::Try executing 'python3 ./scripts/run_cpp_linters.py .' to fix linter issues." + echo "::notice::Try: \ + Building with 'conan build . -pr:a=conan/profiles/tests-release-gcc-linux-x64 -b missing'. \ + And then executing 'python3 ./scripts/run_cpp_linters.py . build/Release' to fix linter issues." exit 1 From 7d68140df81f49f64f5fa79ad1b6fa1178f0be73 Mon Sep 17 00:00:00 2001 From: rturrado Date: Sat, 23 Nov 2024 00:16:40 +0100 Subject: [PATCH 17/57] run_cpp_linters.py: change default build folder to build/Release. --- scripts/run_cpp_linters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/run_cpp_linters.py b/scripts/run_cpp_linters.py index c30ae8fd..7dfaba77 100644 --- a/scripts/run_cpp_linters.py +++ b/scripts/run_cpp_linters.py @@ -12,7 +12,7 @@ def print_usage(): python3 run_cpp_linters.py [] Where: ROOT_FOLDER: folder containing the .clang-format, .clang-tidy, and C++ files. - BUILD_FOLDER: build folder (optional, defaulted to 'build'). + BUILD_FOLDER: build folder (optional, defaulted to 'build/Release'). Example: python3 run_cpp_linters.py . cmake-build-debug-clang-wsl ''' @@ -71,7 +71,7 @@ def main(argv): print_usage() exit(2) root_folder = os.path.abspath(argv[1]) - build_folder = os.path.abspath(argv[2] if len(argv) == 3 else "build") + build_folder = os.path.abspath(argv[2] if len(argv) == 3 else os.path.join("build", "Release")) run_cpp_linters(root_folder, build_folder) if __name__ == '__main__': From 4a37b4c952611b6cb5c76d20cb5339ff30972177 Mon Sep 17 00:00:00 2001 From: rturrado Date: Sat, 23 Nov 2024 00:20:58 +0100 Subject: [PATCH 18/57] linters.yaml: change multi-line notice warning message. --- .github/workflows/linters.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linters.yaml b/.github/workflows/linters.yaml index 02db3ae0..2bb80eff 100644 --- a/.github/workflows/linters.yaml +++ b/.github/workflows/linters.yaml @@ -34,9 +34,9 @@ jobs: tidy-checks: '' # use .clang-tidy config file version: 18 - name: Fail fast -# if: steps.linter.outputs.checks-failed > 0 + if: steps.linter.outputs.checks-failed > 0 run: | - echo "::notice::Try: \ - Building with 'conan build . -pr:a=conan/profiles/tests-release-gcc-linux-x64 -b missing'. \ - And then executing 'python3 ./scripts/run_cpp_linters.py . build/Release' to fix linter issues." + echo "::notice::Try running the following commands to fix and/or understand linter issues:" + echo "::notice:: conan build . -pr:a=conan/profiles/tests-release-gcc-linux-x64 -b missing" + echo "::notice:: python3 ./scripts/run_cpp_linters.py ." exit 1 From 13807f2f06a5622add39a4c1960dfae581ae7d70 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 25 Nov 2024 15:18:51 +0100 Subject: [PATCH 19/57] Remove a couple of linter warnings: - One is due to a 'new' in gtest/gtest.h code. - The other seems to be a false positive. Update docs. Make CoreFunction code look like Instruction code. Fix Instruction::operator==. Pass linters. --- docs/dev-guide/dev-guide.md | 9 +++++++-- include/libqasm/v3x/core_function.hpp | 8 +------- src/v3x/core_function.cpp | 23 +++++++++++++---------- src/v3x/instruction.cpp | 5 ++++- test/v3x/cpp/integration_test.cpp | 5 ++++- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index 6a5c277e..e3ab57a9 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -119,7 +119,7 @@ Tests are disabled by default. To enable them, use `-c tools.build:skip_test=Fal Build and serve on `http://127.0.0.1:8000/`. ```shell -export PTYHONPATH=./scripts/python +export PYTHONPATH=./scripts/python mkdocs serve ``` @@ -137,12 +137,17 @@ Continuous Integration will fail if the files do not adhere to a series of forma It is recommended to run these linters before pushing any change: ```shell +conan build . -pr:a=conan/profiles/tests-release-gcc-linux-x64 -b missing python3 ./scripts/run_cpp_linters.py . ``` !!! note - The linters require `clang-format-18` and `clang-tidy-18` to be installed on the system. + The linters require: + + - `clang-format-18` and `clang-tidy-18` to be installed on the system, and + - a build folder containing a `compile_commands.json`. `run_cpp_linters.py` will use `build/Release` as default, + but a different folder can be passed as second argument to the script. ## Docker diff --git a/include/libqasm/v3x/core_function.hpp b/include/libqasm/v3x/core_function.hpp index e5030c38..52655d66 100644 --- a/include/libqasm/v3x/core_function.hpp +++ b/include/libqasm/v3x/core_function.hpp @@ -49,14 +49,8 @@ class CoreFunction : public tree::Base { * param_types is a shorthand type specification string as parsed by cqasm::types::from_spec(). * return_type is a shorthand type specification char as parsed by cqasm::types::from_spec(). */ - CoreFunction(std::string name, const std::string& param_types, const char return_type); - CoreFunction() = default; - ~CoreFunction() override = default; - CoreFunction(const CoreFunction& t) = default; - CoreFunction(CoreFunction&& t) noexcept = default; - CoreFunction& operator=(const CoreFunction& t) = default; - CoreFunction& operator=(CoreFunction&& t) noexcept = default; + CoreFunction(std::string name, const std::string& param_types, const char return_type); bool operator==(const CoreFunction& rhs) const; inline bool operator!=(const CoreFunction& rhs) const { return !(*this == rhs); } diff --git a/src/v3x/core_function.cpp b/src/v3x/core_function.cpp index c723fad0..7930f822 100644 --- a/src/v3x/core_function.cpp +++ b/src/v3x/core_function.cpp @@ -50,29 +50,32 @@ void serialize(const function::CoreFunctionRef& obj, ::tree::cbor::MapWriter& ma if (obj.empty()) { return; } - map.append_string("n", obj->name); - auto aw = map.append_array("pt"); + map.append_string("name", obj->name); + auto param_types_array = map.append_array("param_types"); for (const auto& t : obj->param_types) { - aw.append_binary(::tree::base::serialize(::tree::base::Maybe{ t.get_ptr() })); + param_types_array.append_binary(::tree::base::serialize(::tree::base::Maybe{ t.get_ptr() })); } - aw.close(); + param_types_array.close(); map.append_binary( - "rt", ::tree::base::serialize(::tree::base::Maybe{ obj->return_type.get_ptr() })); + "return_type", ::tree::base::serialize(::tree::base::Maybe{ obj->return_type.get_ptr() })); } template <> function::CoreFunctionRef deserialize(const ::tree::cbor::MapReader& map) { - if (!map.count("n")) { + // Remove what seems to be a false positive clang-analyzer-optin.cplusplus.VirtualCall + // NOLINTBEGIN + if (!map.count("name")) { return {}; } auto ret = tree::make(); - ret->name = map.at("n").as_string(); - auto ar = map.at("pt").as_array(); - for (const auto& element : ar) { + ret->name = map.at("name").as_string(); + auto param_types_array = map.at("param_types").as_array(); + for (const auto& element : param_types_array) { ret->param_types.add(::tree::base::deserialize(element.as_binary())); } - ret->return_type = ::tree::base::deserialize(map.at("rt").as_binary()); + ret->return_type = ::tree::base::deserialize(map.at("return_type").as_binary()); return ret; + // NOLINTEND } } // namespace cqasm::v3x::primitives diff --git a/src/v3x/instruction.cpp b/src/v3x/instruction.cpp index 39a7c00c..7b01a635 100644 --- a/src/v3x/instruction.cpp +++ b/src/v3x/instruction.cpp @@ -23,7 +23,7 @@ Instruction::Instruction(std::string name, const std::optional& ope * Equality operator. */ bool Instruction::operator==(const Instruction& rhs) const { - return name == rhs.name && operand_types == rhs.operand_types; + return name == rhs.name && operand_types.equals(rhs.operand_types); } /** @@ -59,6 +59,8 @@ void serialize(const instruction::InstructionRef& obj, ::tree::cbor::MapWriter& template <> instruction::InstructionRef deserialize(const ::tree::cbor::MapReader& map) { + // Remove what seems to be a false positive clang-analyzer-optin.cplusplus.VirtualCall + // NOLINTBEGIN if (!map.count("name")) { return {}; } @@ -69,6 +71,7 @@ instruction::InstructionRef deserialize(const ::tree::cbor::MapReader& map) { ret->operand_types.add(::tree::base::deserialize(element.as_binary())); } return ret; + // NOLINTEND } } // namespace cqasm::v3x::primitives diff --git a/test/v3x/cpp/integration_test.cpp b/test/v3x/cpp/integration_test.cpp index 85201982..1b7f247b 100644 --- a/test/v3x/cpp/integration_test.cpp +++ b/test/v3x/cpp/integration_test.cpp @@ -110,8 +110,11 @@ class IntegrationTest : public ::testing::Test { }; void register_tests() { + // Remove a clang-analyzer.cplusplus.NewDeleteLeaks warning in gtest/gtest.h + // NOLINTBEGIN cqasm::test::register_tests(fs::path{ "res" } / "v3x" / "tests" / "integration", - [=](fs::path test_path) -> IntegrationTest* { return new IntegrationTest(std::move(test_path)); }); + [=](fs::path test_path) -> IntegrationTest* { return new IntegrationTest{ std::move(test_path) }; }); + // NOLINTEND } } // namespace cqasm::v3x::test From d486d60e7b28d19e2a2706cd218e4de0d0d60d59 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 25 Nov 2024 15:39:45 +0100 Subject: [PATCH 20/57] Update docs. --- docs/dev-guide/dev-guide.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index e3ab57a9..7a359598 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -143,11 +143,12 @@ python3 ./scripts/run_cpp_linters.py . !!! note - The linters require: - - - `clang-format-18` and `clang-tidy-18` to be installed on the system, and - - a build folder containing a `compile_commands.json`. `run_cpp_linters.py` will use `build/Release` as default, - but a different folder can be passed as second argument to the script. + - The linters require`clang-format-18` and `clang-tidy-18`. + - It is mandatory to have a build before running the linters. + - `clang-tidy` expects to find a `compile_commands.json` in a build folder. + - It is recommended to build with _gcc_ and in _Release_ mode. + - We have observed `clang-tidy` fails to find some standard headers when compiling with _clang_. + - `run_cpp_linters.py` can receive a build folder as second argument, but defaults to `build/Release`. ## Docker From 05e7b4a8a7353fc55a05adf800b80ed6504fd75b Mon Sep 17 00:00:00 2001 From: Roberto Turrado Camblor Date: Fri, 29 Nov 2024 16:01:51 +0100 Subject: [PATCH 21/57] Apply suggestions from code review Co-authored-by: Chris Elenbaas <67630508+elenbaasc@users.noreply.github.com> --- docs/dev-guide/dev-guide.md | 2 +- scripts/run_cpp_linters.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index 7a359598..7bd65a77 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -146,7 +146,7 @@ python3 ./scripts/run_cpp_linters.py . - The linters require`clang-format-18` and `clang-tidy-18`. - It is mandatory to have a build before running the linters. - `clang-tidy` expects to find a `compile_commands.json` in a build folder. - - It is recommended to build with _gcc_ and in _Release_ mode. + - It is recommended to build with _gcc_ in _Release_ mode. - We have observed `clang-tidy` fails to find some standard headers when compiling with _clang_. - `run_cpp_linters.py` can receive a build folder as second argument, but defaults to `build/Release`. diff --git a/scripts/run_cpp_linters.py b/scripts/run_cpp_linters.py index 7dfaba77..dd76f5d2 100644 --- a/scripts/run_cpp_linters.py +++ b/scripts/run_cpp_linters.py @@ -14,7 +14,7 @@ def print_usage(): ROOT_FOLDER: folder containing the .clang-format, .clang-tidy, and C++ files. BUILD_FOLDER: build folder (optional, defaulted to 'build/Release'). Example: - python3 run_cpp_linters.py . cmake-build-debug-clang-wsl + python3 run_cpp_linters.py . build/Debug ''' logging.info(usage_str) From 2aa32533e664cde453646ded61f26df6c6f7cd84 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 2 Dec 2024 12:52:51 +0100 Subject: [PATCH 22/57] Error when redeclaring a variable. --- src/v3x/resolver.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v3x/resolver.cpp b/src/v3x/resolver.cpp index 92007c5b..ac6acc59 100644 --- a/src/v3x/resolver.cpp +++ b/src/v3x/resolver.cpp @@ -22,7 +22,9 @@ namespace cqasm::v3x::resolver { * Adds a variable. */ void VariableTable::add(const std::string& name, const Value& value) { - table.erase(name); + if (auto entry = table.find(name); entry != table.end()) { + throw NameResolutionFailure{ fmt::format("trying to redeclare variable '{}'", name) }; + } table.insert(std::make_pair(name, value)); } From 404e44e00893670b4e5f40edc10e1f6be9e70213 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 2 Dec 2024 12:53:02 +0100 Subject: [PATCH 23/57] Update integration tests. --- .../semantic.3.0.golden.txt | 37 +------------------ .../bit_b__bit_b/semantic.3.0.golden.txt | 37 +------------------ .../semantic.3.0.golden.txt | 37 +------------------ .../qubit_q__qubit_q/semantic.3.0.golden.txt | 37 +------------------ 4 files changed, 8 insertions(+), 140 deletions(-) diff --git a/res/v3x/tests/integration/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt b/res/v3x/tests/integration/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt index aef0a6d4..e353874d 100644 --- a/res/v3x/tests/integration/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt +++ b/res/v3x/tests/integration/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt @@ -1,35 +1,2 @@ -SUCCESS -Program( - api_version: 3.0 - version: < - Version( - items: 3 - ) - > - block: < - Block( - statements: [] - ) - > - variables: [ - Variable( - name: b - typ: < - BitArray( - size: 17 - ) - > - annotations: [] - ) - Variable( - name: b - typ: < - BitArray( - size: 17 - ) - > - annotations: [] - ) - ] -) - +ERROR +Error at input.cq:4:9..10: trying to redeclare variable 'b' diff --git a/res/v3x/tests/integration/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt b/res/v3x/tests/integration/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt index 32f860fd..9dd503b3 100644 --- a/res/v3x/tests/integration/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt +++ b/res/v3x/tests/integration/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt @@ -1,35 +1,2 @@ -SUCCESS -Program( - api_version: 3.0 - version: < - Version( - items: 3 - ) - > - block: < - Block( - statements: [] - ) - > - variables: [ - Variable( - name: b - typ: < - Bit( - size: 1 - ) - > - annotations: [] - ) - Variable( - name: b - typ: < - Bit( - size: 1 - ) - > - annotations: [] - ) - ] -) - +ERROR +Error at input.cq:4:5..6: trying to redeclare variable 'b' diff --git a/res/v3x/tests/integration/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt b/res/v3x/tests/integration/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt index 66db44e5..11b2e258 100644 --- a/res/v3x/tests/integration/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt +++ b/res/v3x/tests/integration/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt @@ -1,35 +1,2 @@ -SUCCESS -Program( - api_version: 3.0 - version: < - Version( - items: 3 - ) - > - block: < - Block( - statements: [] - ) - > - variables: [ - Variable( - name: q - typ: < - QubitArray( - size: 17 - ) - > - annotations: [] - ) - Variable( - name: q - typ: < - QubitArray( - size: 17 - ) - > - annotations: [] - ) - ] -) - +ERROR +Error at input.cq:4:11..12: trying to redeclare variable 'q' diff --git a/res/v3x/tests/integration/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt b/res/v3x/tests/integration/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt index 6e5ea893..285bce82 100644 --- a/res/v3x/tests/integration/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt +++ b/res/v3x/tests/integration/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt @@ -1,35 +1,2 @@ -SUCCESS -Program( - api_version: 3.0 - version: < - Version( - items: 3 - ) - > - block: < - Block( - statements: [] - ) - > - variables: [ - Variable( - name: q - typ: < - Qubit( - size: 1 - ) - > - annotations: [] - ) - Variable( - name: q - typ: < - Qubit( - size: 1 - ) - > - annotations: [] - ) - ] -) - +ERROR +Error at input.cq:4:7..8: trying to redeclare variable 'q' From 7012877a7eec0a463162e212dcee0badfcb68f20 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 2 Dec 2024 13:11:54 +0100 Subject: [PATCH 24/57] Update CHANGELOG.md. We are starting to follow a bit more seriously the semantic versioning. Since this PR introduces a change that breaks backward compatibility (valid programs up to now become invalid programs with the error redeclaration change), we MUST change the major version of the future release. --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3956b82..c6f52813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [ 1.0.0 ] - [ xxxx-yy-zz ] + +### Added +- `.clang-tidy`. + +### Changed +- Error when redeclaring a variable. + +### Removed + + ## [ 0.6.9 ] - [ 2024-11-13 ] ### Added From 496636a4e2e43064e85bab8e50912f59e06c0e9a Mon Sep 17 00:00:00 2001 From: rturrado Date: Sat, 14 Dec 2024 01:07:22 +0100 Subject: [PATCH 25/57] Add clang-format option: AlignArrayOfStructures=Right. Update CHANGELOG.md: change cQasm to cQASM. Update python/CMakeLists.txt: put SWIG code together. Rename mkdocs.yml and mkdocs-base.yml to use yaml extension. --- .clang-format | 1 + CHANGELOG.md | 4 +- mkdocs-base.yml => mkdocs-base.yaml | 2 +- mkdocs.yml => mkdocs.yaml | 2 +- python/CMakeLists.txt | 20 +++++----- src/v3x/antlr_custom_error_listener.cpp | 6 ++- src/v3x/syntactic_analyzer.cpp | 8 ++-- test/test_annotations.cpp | 24 +++++++++--- test/test_error.cpp | 49 +++++++++++++++++++------ test/v3x/cpp/test_analyzer.cpp | 18 +++++++-- test/v3x/cpp/test_functions.hpp | 12 ++++-- test/v3x/cpp/test_parse_helper.cpp | 5 ++- 12 files changed, 105 insertions(+), 46 deletions(-) rename mkdocs-base.yml => mkdocs-base.yaml (98%) rename mkdocs.yml => mkdocs.yaml (57%) diff --git a/.clang-format b/.clang-format index 5c76ce64..f77fab92 100644 --- a/.clang-format +++ b/.clang-format @@ -3,6 +3,7 @@ BasedOnStyle: Google Language: Cpp AccessModifierOffset: -4 AlignAfterOpenBracket: DontAlign +AlignArrayOfStructures: Right AlignOperands: DontAlign AlignTrailingComments: false AllowAllArgumentsOnNextLine: true diff --git a/CHANGELOG.md b/CHANGELOG.md index c6f52813..21a4b7db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -135,12 +135,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [ 0.6.0 ] - [ 2024-03-28 ] ### Added -- cQasm 3.0 parser. MVP (Minimum Viable Product) implemented. +- cQASM 3.0 parser. MVP (Minimum Viable Product) implemented. - Conan as package manager. ### Changed - Different upgrades: C++20, CMake 3.12, Python 3.8 to 3.12. ### Removed -- cQasm 1.x support. +- cQASM 1.x support. - Git submodules. diff --git a/mkdocs-base.yml b/mkdocs-base.yaml similarity index 98% rename from mkdocs-base.yml rename to mkdocs-base.yaml index 4d3129dd..ec74e1ee 100644 --- a/mkdocs-base.yml +++ b/mkdocs-base.yaml @@ -72,4 +72,4 @@ plugins: default_handler: python watch: - - mkdocs-base.yml + - mkdocs-base.yaml diff --git a/mkdocs.yml b/mkdocs.yaml similarity index 57% rename from mkdocs.yml rename to mkdocs.yaml index fa558412..e0577a58 100644 --- a/mkdocs.yml +++ b/mkdocs.yaml @@ -1,4 +1,4 @@ -INHERIT: ./mkdocs-base.yml +INHERIT: ./mkdocs-base.yaml extra: version: diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 82fec437..6290815e 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -66,14 +66,6 @@ endif() message(STATUS "Found python3 include directory at ${PYTHON_INCLUDE_DIRS}") -# SWIG ------------------------------------------------------------------------ - -# Look for SWIG. -find_package(SWIG REQUIRED) - -include(${SWIG_USE_FILE}) - - #=============================================================================# # CMake configuration # #=============================================================================# @@ -89,14 +81,20 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) +# SWIG ------------------------------------------------------------------------ + +# Look for SWIG. +find_package(SWIG REQUIRED) + +include(${SWIG_USE_FILE}) + + #=============================================================================# # Build the SWIG module # #=============================================================================# # Configure SWIG. -set(SWIG_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/libqasm.i" -) +set(SWIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/libqasm.i") set_source_files_properties("${SWIG_FILE}" PROPERTIES CPLUSPLUS ON diff --git a/src/v3x/antlr_custom_error_listener.cpp b/src/v3x/antlr_custom_error_listener.cpp index cbc873c9..c3e6de71 100644 --- a/src/v3x/antlr_custom_error_listener.cpp +++ b/src/v3x/antlr_custom_error_listener.cpp @@ -30,10 +30,12 @@ void AntlrCustomErrorListener::syntaxError(antlr4::Recognizer* /* recognizer */, : 0; auto end_column = start_column + token_size; - throw error::ParseError{ msg, + throw error::ParseError{ + msg, file_name_, { { static_cast(line), static_cast(start_column) }, - { static_cast(line), static_cast(end_column) } } }; + { static_cast(line), static_cast(end_column) } } + }; } void AntlrCustomErrorListener::syntaxError(size_t line, size_t char_position_in_line, const std::string& msg) { diff --git a/src/v3x/syntactic_analyzer.cpp b/src/v3x/syntactic_analyzer.cpp index 48676592..a10d50f9 100644 --- a/src/v3x/syntactic_analyzer.cpp +++ b/src/v3x/syntactic_analyzer.cpp @@ -43,11 +43,13 @@ void SyntacticAnalyzer::syntaxError(size_t line, size_t char_position_in_line, c */ void SyntacticAnalyzer::setNodeAnnotation(const ast::One& node, antlr4::Token* token) const { auto token_size = token->getStopIndex() - token->getStartIndex() + 1; - node->set_annotation(annotations::SourceLocation{ file_name_, + node->set_annotation(annotations::SourceLocation{ + file_name_, { { static_cast(token->getLine()), static_cast(token->getCharPositionInLine() + 1) }, - { static_cast(token->getLine()), - static_cast(token->getCharPositionInLine() + 1 + token_size) } } }); + { static_cast(token->getLine()), + static_cast(token->getCharPositionInLine() + 1 + token_size) } } + }); } void SyntacticAnalyzer::expandNodeAnnotation(const One& node, antlr4::Token* token) const { diff --git a/test/test_annotations.cpp b/test/test_annotations.cpp index 1358d0e2..04a4b462 100644 --- a/test/test_annotations.cpp +++ b/test/test_annotations.cpp @@ -17,26 +17,38 @@ TEST(source_location_constructor, no_file_name__no_line_numbers__no_column_numbe EXPECT_EQ(fmt::format("{}", location), ""); } TEST(source_location_constructor, null_file_name__yes_line_numbers__no_column_numbers) { - auto location = SourceLocation{ std::nullopt, { { 10, 0 }, { 10, 0 } } }; + auto location = SourceLocation{ + std::nullopt, { { 10, 0 }, { 10, 0 } } + }; EXPECT_EQ(fmt::format("{}", location), ":10"); } TEST(source_location_constructor, no_file_name__yes_line_numbers__no_column_numbers) { - auto location = SourceLocation{ "", { { 10, 0 }, { 10, 0 } } }; + auto location = SourceLocation{ + "", { { 10, 0 }, { 10, 0 } } + }; EXPECT_EQ(fmt::format("{}", location), ":10"); } TEST(source_location_constructor, null_file_name__yes_line_numbers__yes_column_numbers) { - auto location = SourceLocation{ std::nullopt, { { 10, 12 }, { 10, 15 } } }; + auto location = SourceLocation{ + std::nullopt, { { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(fmt::format("{}", location), ":10:12..15"); } TEST(source_location_constructor, no_file_name__yes_line_numbers__yes_column_numbers) { - auto location = SourceLocation{ "", { { 10, 12 }, { 10, 15 } } }; + auto location = SourceLocation{ + "", { { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(fmt::format("{}", location), ":10:12..15"); } TEST(source_location_constructor, yes_file_name__yes_line_numbers__yes_column_numbers) { - auto location = SourceLocation{ "input.cq", { { 10, 12 }, { 10, 15 } } }; + auto location = SourceLocation{ + "input.cq", { { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(fmt::format("{}", location), "input.cq:10:12..15"); } TEST(source_location_constructor, unknown_file_name__yes_line_numbers__yes_column_numbers) { - auto location = SourceLocation{ "", { { 10, 12 }, { 10, 15 } } }; + auto location = SourceLocation{ + "", { { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(fmt::format("{}", location), ":10:12..15"); } diff --git a/test/test_error.cpp b/test/test_error.cpp index 6bc2018a..f132926f 100644 --- a/test/test_error.cpp +++ b/test/test_error.cpp @@ -35,7 +35,9 @@ TEST(constructor_message_node, message_and_node_with_empty_location) { } TEST(constructor_message_node, message_and_node_with_location) { auto node = FakeNode{}; - node.set_annotation(SourceLocation{ "input.cq", { { 10, 12 }, { 10, 15 } } }); + node.set_annotation(SourceLocation{ + "input.cq", { { 10, 12 }, { 10, 15 } } + }); auto err = Error{ "syntax error", &node }; EXPECT_EQ(fmt::format("{}", err), "Error at input.cq:10:12..15: syntax error"); } @@ -48,11 +50,14 @@ TEST(constructor_message_location, message_and_empty_location) { auto err = Error{ "syntax error", std::make_shared() }; EXPECT_EQ(fmt::format("{}", err), "Error at : syntax error"); } +// clang-format off TEST(constructor_message_location, message_and_location) { - auto err = Error{ "syntax error", - std::make_shared("input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } }) }; + auto err = Error{ + "syntax error", std::make_shared("input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } }) + }; EXPECT_EQ(fmt::format("{}", err), "Error at input.cq:10:12..15: syntax error"); } +// clang-format on TEST(constructor_message_location_fields, empty_message) { auto err = Error{ "", std::nullopt, SourceLocation::Range{} }; @@ -63,16 +68,26 @@ TEST(constructor_message_location_fields, message_and_empty_location) { EXPECT_EQ(fmt::format("{}", err), "Error at : syntax error"); } TEST(constructor_message_location_fields, message_and_location) { - auto err = Error{ "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } }; + auto err = Error{ + "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(fmt::format("{}", err), "Error at input.cq:10:12..15: syntax error"); } TEST(context, location) { auto node_1 = FakeNode{}; - node_1.set_annotation(SourceLocation("input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } })); + node_1.set_annotation(SourceLocation("input.cq", + SourceLocation::Range{ + { 10, 12 }, + { 10, 15 } + })); auto err = Error{ "syntax error", &node_1 }; auto node_2 = FakeNode{}; - node_2.set_annotation(SourceLocation("input.cq", SourceLocation::Range{ { 20, 22 }, { 20, 25 } })); + node_2.set_annotation(SourceLocation("input.cq", + SourceLocation::Range{ + { 20, 22 }, + { 20, 25 } + })); err.context(node_2); EXPECT_EQ(fmt::format("{}", err), "Error at input.cq:10:12..15: syntax error"); } @@ -85,7 +100,11 @@ TEST(context, no_location_and_node_does_not_have_source_location) { TEST(context, no_location_and_node_has_source_location) { auto err = Error{ "syntax error" }; auto node_2 = FakeNode{}; - node_2.set_annotation(SourceLocation("input.cq", SourceLocation::Range{ { 20, 22 }, { 20, 25 } })); + node_2.set_annotation(SourceLocation("input.cq", + SourceLocation::Range{ + { 20, 22 }, + { 20, 25 } + })); err.context(node_2); EXPECT_EQ(fmt::format("{}", err), "Error at input.cq:20:22..25: syntax error"); } @@ -103,11 +122,15 @@ TEST(what, message_and_empty_location) { EXPECT_EQ(std::string{ err.what() }, "Error at : syntax error"); } TEST(what, message_and_location_with_unknown_file_name) { - auto err = Error{ "syntax error", std::nullopt, SourceLocation::Range{ { 10, 12 }, { 10, 15 } } }; + auto err = Error{ + "syntax error", std::nullopt, SourceLocation::Range{ { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(std::string{ err.what() }, "Error at :10:12..15: syntax error"); } TEST(what, message_and_location_with_known_file_name) { - auto err = Error{ "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } }; + auto err = Error{ + "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(std::string{ err.what() }, "Error at input.cq:10:12..15: syntax error"); } @@ -148,7 +171,9 @@ TEST(to_json, message_and_empty_location) { R"(})"); } TEST(to_json, message_and_location_with_unknown_file_name) { - auto err = Error{ "syntax error", std::nullopt, SourceLocation::Range{ { 10, 12 }, { 10, 15 } } }; + auto err = Error{ + "syntax error", std::nullopt, SourceLocation::Range{ { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(err.to_json(), R"({)" R"("range":{)" @@ -160,7 +185,9 @@ TEST(to_json, message_and_location_with_unknown_file_name) { R"(})"); } TEST(to_json, message_and_location_with_known_file_name) { - auto err = Error{ "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } }; + auto err = Error{ + "syntax error", "input.cq", SourceLocation::Range{ { 10, 12 }, { 10, 15 } } + }; EXPECT_EQ(err.to_json(), R"({)" R"("range":{)" diff --git a/test/v3x/cpp/test_analyzer.cpp b/test/v3x/cpp/test_analyzer.cpp index 0756f056..15a5017b 100644 --- a/test/v3x/cpp/test_analyzer.cpp +++ b/test/v3x/cpp/test_analyzer.cpp @@ -88,7 +88,9 @@ TEST_F(AnalyzerTest, add_statement_to_current_scope) { } TEST_F(AnalyzerTest, add_statement_with_source_location_information_to_current_scope) { MockAnalyzer analyzer{}; - const auto& statement_source_location = annotations::SourceLocation{ "input.cq", { { 10, 20 }, { 11, 10 } } }; + const auto& statement_source_location = annotations::SourceLocation{ + "input.cq", { { 10, 20 }, { 11, 10 } } + }; statement->set_annotation(statement_source_location); analyzer.add_statement_to_current_scope(statement); EXPECT_EQ(analyzer.current_block()->statements.size(), 1); @@ -102,12 +104,16 @@ TEST_F(AnalyzerTest, // 10 15 20 25 30 // 5 < // 8 > - const auto& block_initial_source_location = annotations::SourceLocation{ "input.cq", { { 5, 15 }, { 8, 30 } } }; + const auto& block_initial_source_location = annotations::SourceLocation{ + "input.cq", { { 5, 15 }, { 8, 30 } } + }; analyzer.current_block()->set_annotation(block_initial_source_location); // 10 15 20 25 30 // 10 < // 11 > - const auto& statement_source_location = annotations::SourceLocation{ "input.cq", { { 10, 10 }, { 11, 20 } } }; + const auto& statement_source_location = annotations::SourceLocation{ + "input.cq", { { 10, 10 }, { 11, 20 } } + }; statement->set_annotation(statement_source_location); analyzer.add_statement_to_current_scope(statement); EXPECT_EQ(analyzer.current_block()->statements.size(), 1); @@ -116,7 +122,11 @@ TEST_F(AnalyzerTest, // 11 > const auto& block_final_source_location = analyzer.current_block()->get_annotation(); EXPECT_EQ(block_final_source_location.file_name, "input.cq"); - EXPECT_EQ(block_final_source_location.range, (annotations::SourceLocation::Range{ { 5, 15 }, { 11, 20 } })); + EXPECT_EQ(block_final_source_location.range, + (annotations::SourceLocation::Range{ + { 5, 15 }, + { 11, 20 } + })); } } // namespace cqasm::v3x::analyzer diff --git a/test/v3x/cpp/test_functions.hpp b/test/v3x/cpp/test_functions.hpp index ece1b294..bdee9405 100644 --- a/test/v3x/cpp/test_functions.hpp +++ b/test/v3x/cpp/test_functions.hpp @@ -29,7 +29,9 @@ auto invoke_binary(ParamsType a, ParamsType b) { using FReturnValue = typename decltype(F)::return_value; using FParamValue = typename decltype(F)::param_value; - auto values = values::Values{ { cqasm::tree::make(a), cqasm::tree::make(b) } }; + auto values = values::Values{ + { cqasm::tree::make(a), cqasm::tree::make(b) } + }; auto ret = F(values); return dynamic_cast(*ret).value; } @@ -39,9 +41,11 @@ auto invoke_ternary(bool condition, ParamsType if_true, ParamsType if_false) { using FReturnValue = typename decltype(F)::return_value; using FParamValue = typename decltype(F)::param_value; - auto values = values::Values{ { cqasm::tree::make(condition), - cqasm::tree::make(if_true), - cqasm::tree::make(if_false) } }; + auto values = values::Values{ + { cqasm::tree::make(condition), + cqasm::tree::make(if_true), + cqasm::tree::make(if_false) } + }; auto ret = F(values); return dynamic_cast(*ret).value; } diff --git a/test/v3x/cpp/test_parse_helper.cpp b/test/v3x/cpp/test_parse_helper.cpp index 4e21f070..5c89aadf 100644 --- a/test/v3x/cpp/test_parse_helper.cpp +++ b/test/v3x/cpp/test_parse_helper.cpp @@ -44,7 +44,10 @@ class ParseHelperParseTest : public ::testing::Test { } std::string file_name = "input.cq"; - annotations::SourceLocation::Range range{ { 10, 12 }, { 10, 15 } }; + annotations::SourceLocation::Range range{ + { 10, 12 }, + { 10, 15 } + }; std::string parse_error_message = "parse error"; std::string runtime_error_message = "runtime error"; From a6ac4a0b2acc6689f924ca4cbda281fee577cd74 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 2 Jan 2025 17:22:13 +0100 Subject: [PATCH 26/57] Minor tweaks to documentation. --- README.md | 3 +-- docs/about/license.md | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 716d0c53..85852c51 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ CNOT q[0], q[1] b = measure q ``` -We can parse or analyze this circuit, using libQASM through the following programming language: +We can parse or analyze this circuit using libQASM through the following programming language: ### C++ @@ -58,7 +58,6 @@ int main() { } ``` - ### Emscripten The emscripten API only allows to input a cQASM program as a string. diff --git a/docs/about/license.md b/docs/about/license.md index 5ec3bba1..77af536e 100644 --- a/docs/about/license.md +++ b/docs/about/license.md @@ -1,3 +1,2 @@ -libQASM is licensed under the Apache License, Version 2.0. See -[LICENSE](https://github.com/QuTech-Delft/OpenSquirrel/blob/master/LICENSE.md) for the full -license text. +libQASM is licensed under the Apache License, Version 2.0. +See [LICENSE](https://github.com/QuTech-Delft/OpenSquirrel/blob/master/LICENSE.md) for the full license text. From 2073475cf59dd5bb9ad0501d90658d0c75b4fa9b Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 3 Jan 2025 17:43:39 +0100 Subject: [PATCH 27/57] Update dev-guide.md. --- docs/dev-guide/dev-guide.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index 7bd65a77..c810eaa1 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -85,10 +85,9 @@ conan build . -pr:a=conan/profiles/tests-debug -b missing ### Profiles A group of predefined profiles is provided under the `conan/profiles` folder. -They follow the `[tests-|docs-](build_type)(-compiler)(-os)(-arch)[-shared]` naming convention: +They follow the `[tests-](build_type)(-compiler)(-os)(-arch)[-shared]` naming convention: - `tests`: if tests are being built. -- `docs`: if docs are being built. - `build_type`: can be `debug` or `release`. - `compiler`: `apple-clang`, `clang`, `gcc`, `msvc`. - `os`: `emscripten`, `linux`, `macos`, `windows`. From 595d020dd58c2d6e9b931c04a8f4eaec8f5876ec Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 3 Jan 2025 17:46:29 +0100 Subject: [PATCH 28/57] Update dev-guide.md. --- docs/dev-guide/dev-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index c810eaa1..a6b1cf34 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -108,7 +108,7 @@ conan build . -s:a compiler.cppstd=20 -s:a libqasm/*:build_type=Debug -o libqasm This is the list of options that could be specified either in a profile or in the command line: - `libqasm/*:asan_enabled={True,False}`: enables Address Sanitizer. -- `libqasm/*:build_type={Debug,Release}`: builds in debug or release mode. +- `libqasm/*:build_type={Debug,Release}`: builds in Debug or Release mode. - `libqasm/*:shared={True,False}`: builds a shared object library instead of a static library, if applicable. Tests are disabled by default. To enable them, use `-c tools.build:skip_test=False`. From d24e5a0349eed460ad32a15efa598178c5b7d267 Mon Sep 17 00:00:00 2001 From: rturrado Date: Fri, 3 Jan 2025 18:12:08 +0100 Subject: [PATCH 29/57] Updated docs. --- docs/dev-guide/cpp.md | 1 + docs/dev-guide/emscripten.md | 1 + docs/user-guide/cpp.md | 5 +++-- docs/user-guide/emscripten.md | 2 -- docs/user-guide/python.md | 8 ++++++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/dev-guide/cpp.md b/docs/dev-guide/cpp.md index 59702040..36bda12f 100644 --- a/docs/dev-guide/cpp.md +++ b/docs/dev-guide/cpp.md @@ -2,6 +2,7 @@ You can build the C++ binaries from the project's root directory. The following line will also build and cache the `libqasm` Conan package. !!! note + You may need to execute the `conan profile detect` command if this is the first time you run Conan. ```shell diff --git a/docs/dev-guide/emscripten.md b/docs/dev-guide/emscripten.md index 1b151b41..bd69aa9b 100644 --- a/docs/dev-guide/emscripten.md +++ b/docs/dev-guide/emscripten.md @@ -11,6 +11,7 @@ The output of this build lives in `build/Release/emscripten`: - `cqasm_emscripten.wasm`. !!! note + `cqasm_emscripten.js` is an ES6 module. Its extension has to be renamed to `.mjs` before using it from Typescript code. diff --git a/docs/user-guide/cpp.md b/docs/user-guide/cpp.md index 66a97a00..5afc2b73 100644 --- a/docs/user-guide/cpp.md +++ b/docs/user-guide/cpp.md @@ -1,4 +1,4 @@ -libQASM can be requested as a Conan package from a `conanfile.py`. +libQASM can be requested as a Conan package from a `conanfile.py`: ``` def build_requirements(self): @@ -14,9 +14,10 @@ target_link_libraries( PUBLIC libqasm::libqasm) ``` !!! note + You will need to have `Java JRE` >= 11 installed in case Conan needs to build libQASM. -**Example**: +And used from a C++ program: ```cpp #include "libqasm/v3x/cqasm_python.hpp" diff --git a/docs/user-guide/emscripten.md b/docs/user-guide/emscripten.md index 5f17642d..75987586 100644 --- a/docs/user-guide/emscripten.md +++ b/docs/user-guide/emscripten.md @@ -3,8 +3,6 @@ libQASM can be used from a web environment via a Typescript frontend. Emscripten API only allows to input a cQASM program via a string and always returns a JSON string output. -**Example**: - ```typescript import { default as wrapper } from 'cqasm_emscripten.mjs'; diff --git a/docs/user-guide/python.md b/docs/user-guide/python.md index 314195fd..22a94fc0 100644 --- a/docs/user-guide/python.md +++ b/docs/user-guide/python.md @@ -1,6 +1,10 @@ -libQASM can be imported as a Python package. +libQASM can be installed as a Python package: -**Example**: +```shell +pip install libqasm +``` + +And then imported from a Python program: ```python from libqasm import Analyzer From 57a61f0771bfcf284a7e51245992a43b7af127ff Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 6 Jan 2025 17:58:58 +0100 Subject: [PATCH 30/57] Updated docs. --- docs/dev-guide/dev-guide.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index a6b1cf34..16f1bcd8 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -55,10 +55,10 @@ For the time being, we install Java manually for this platform. On a Linux machine, these linters can be installed with the following commands: ```shell - wget https://apt.llvm.org/llvm.sh -O llvm_install.sh - chmod +x llvm_install.sh - ./llvm_install.sh - apt-get install -y clang-format-18 clang-tidy-18 +wget https://apt.llvm.org/llvm.sh -O llvm_install.sh +chmod +x llvm_install.sh +./llvm_install.sh +apt-get install -y clang-format-18 clang-tidy-18 ``` ## Build From 8d08ad8a3ee144ba838a140956ee5c06ab30e1c5 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 15:22:53 +0100 Subject: [PATCH 31/57] Trying to fix clang/Linux/x64 GitHub Actions jobs. Due to GitHub hosted runners moving from Ubuntu 22 to Ubuntu 24. --- .github/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 12433c8f..4300a0ed 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,6 +23,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libc++-18-dev libc++abi-18-dev - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} From c2ccb80fac80857e6bfe0c1d6fc7ff333b2f0707 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 15:30:15 +0100 Subject: [PATCH 32/57] Trying to fix clang/Linux/x64 GitHub Actions jobs. --- test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5acd4552..400982e1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,6 +41,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") -Wall -Wextra -Werror -Wfatal-errors -fPIC -Wno-error=sign-compare + -Wno-error=unused-parameter -Wno-error=unused-private-field -Wno-error=unused-but-set-variable ) From e7eb613c53ed44227b37dc17e5dae64b12904cc8 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:01:46 +0100 Subject: [PATCH 33/57] Trying to fix Debug clang/Linux/x64 GitHub Actions job. It seems clang complains about trying to use 20 functions that have been previously discarded. --- .../v3x/register_consteval_core_functions.hpp | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/include/libqasm/v3x/register_consteval_core_functions.hpp b/include/libqasm/v3x/register_consteval_core_functions.hpp index 74d7d11e..9845d22b 100644 --- a/include/libqasm/v3x/register_consteval_core_functions.hpp +++ b/include/libqasm/v3x/register_consteval_core_functions.hpp @@ -86,7 +86,7 @@ constexpr auto op_div_ff = bf_cp{}; constexpr auto op_mod_ii = bf_cp{}; -constexpr auto pow = [](auto base, auto exp) { return std::pow(base, exp); }; +inline constexpr auto pow = [](auto base, auto exp) { return std::pow(base, exp); }; constexpr auto op_pow_ff = bf_cp{}; constexpr auto op_eq_ff = bf_cp{}; @@ -115,53 +115,53 @@ constexpr auto op_band_ii = bf_cp{}; constexpr auto op_bor_ii = bf_cp{}; -constexpr auto shl = [](primitives::Int a, primitives::Int b) { return a << b; }; +inline constexpr auto shl = [](primitives::Int a, primitives::Int b) { return a << b; }; constexpr auto op_shl_ii = bf_cp{}; -constexpr auto shr = [](primitives::Int a, primitives::Int b) { return a >> b; }; +inline constexpr auto shr = [](primitives::Int a, primitives::Int b) { return a >> b; }; constexpr auto op_shr_ii = bf_cp{}; constexpr auto op_linv_b = uf_cp{}; constexpr auto op_land_bb = bf_cp{}; -constexpr auto lxor = [](primitives::Bool lhs, primitives::Bool rhs) { return !lhs ^ !rhs; }; +inline constexpr auto lxor = [](primitives::Bool lhs, primitives::Bool rhs) { return !lhs ^ !rhs; }; constexpr auto op_lxor_bb = bf_cp{}; constexpr auto op_lor_bb = bf_cp{}; -constexpr auto tcnd = [](bool condition, auto if_true, auto if_false) { return condition ? if_true : if_false; }; +inline constexpr auto tcnd = [](bool condition, auto if_true, auto if_false) { return condition ? if_true : if_false; }; constexpr auto op_tcnd_bff = tf_cp{}; constexpr auto op_tcnd_bii = tf_cp{}; constexpr auto op_tcnd_bbb = tf_cp{}; -constexpr auto sqrt = [](auto num) { return std::sqrt(num); }; +inline constexpr auto sqrt = [](auto num) { return std::sqrt(num); }; constexpr auto fn_sqrt_f = uf_cp{}; -constexpr auto exp = [](auto num) { return std::exp(num); }; +inline constexpr auto exp = [](auto num) { return std::exp(num); }; constexpr auto fn_exp_f = uf_cp{}; -constexpr auto log = [](auto num) { return std::log(num); }; +inline constexpr auto log = [](auto num) { return std::log(num); }; constexpr auto fn_log_f = uf_cp{}; -constexpr auto sin = [](auto num) { return std::sin(num); }; +inline constexpr auto sin = [](auto num) { return std::sin(num); }; constexpr auto fn_sin_f = uf_cp{}; -constexpr auto cos = [](auto num) { return std::cos(num); }; +inline constexpr auto cos = [](auto num) { return std::cos(num); }; constexpr auto fn_cos_f = uf_cp{}; -constexpr auto tan = [](auto num) { return std::tan(num); }; +inline constexpr auto tan = [](auto num) { return std::tan(num); }; constexpr auto fn_tan_f = uf_cp{}; -constexpr auto sinh = [](auto num) { return std::sinh(num); }; +inline constexpr auto sinh = [](auto num) { return std::sinh(num); }; constexpr auto fn_sinh_f = uf_cp{}; -constexpr auto cosh = [](auto num) { return std::cosh(num); }; +inline constexpr auto cosh = [](auto num) { return std::cosh(num); }; constexpr auto fn_cosh_f = uf_cp{}; -constexpr auto tanh = [](auto num) { return std::tanh(num); }; +inline constexpr auto tanh = [](auto num) { return std::tanh(num); }; constexpr auto fn_tanh_f = uf_cp{}; -constexpr auto asin = [](auto num) { return std::asin(num); }; +inline constexpr auto asin = [](auto num) { return std::asin(num); }; constexpr auto fn_asin_f = uf_cp{}; -constexpr auto acos = [](auto num) { return std::acos(num); }; +inline constexpr auto acos = [](auto num) { return std::acos(num); }; constexpr auto fn_acos_f = uf_cp{}; -constexpr auto atan = [](auto num) { return std::atan(num); }; +inline constexpr auto atan = [](auto num) { return std::atan(num); }; constexpr auto fn_atan_f = uf_cp{}; -constexpr auto asinh = [](auto num) { return std::asinh(num); }; +inline constexpr auto asinh = [](auto num) { return std::asinh(num); }; constexpr auto fn_asinh_f = uf_cp{}; -constexpr auto acosh = [](auto num) { return std::acosh(num); }; +inline constexpr auto acosh = [](auto num) { return std::acosh(num); }; constexpr auto fn_acosh_f = uf_cp{}; -constexpr auto atanh = [](auto num) { return std::atanh(num); }; +inline constexpr auto atanh = [](auto num) { return std::atanh(num); }; constexpr auto fn_atanh_f = uf_cp{}; -constexpr auto abs = [](auto num) { return std::abs(num); }; +inline constexpr auto abs = [](auto num) { return std::abs(num); }; constexpr auto fn_abs_f = uf_cp{}; constexpr auto fn_abs_i = uf_cp{}; From 75f671a189eab1374431ab34f822dfeb4a0ea740 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:13:09 +0100 Subject: [PATCH 34/57] Test if we can install libc++ without specifying the exact version. --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4300a0ed..c6a8b193 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y libc++-18-dev libc++abi-18-dev + sudo apt-get install -y libc++-dev libc++abi-dev - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} From 8eca9896631795fee1edae4212f258a49b3989e7 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:21:40 +0100 Subject: [PATCH 35/57] Revert changes on test/CMakeLists.txt. I had done this change because I had read a StackOverflow answer saying that the .rodata errors may be due to using different options when building cqasm_test and the cqasm library. --- test/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 400982e1..5acd4552 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -41,7 +41,6 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") -Wall -Wextra -Werror -Wfatal-errors -fPIC -Wno-error=sign-compare - -Wno-error=unused-parameter -Wno-error=unused-private-field -Wno-error=unused-but-set-variable ) From 2f32f1c196fa3fff041ed630ac06176ceb5f069b Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:22:30 +0100 Subject: [PATCH 36/57] Test if we really need to install libc++. --- .github/workflows/test.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c6a8b193..12433c8f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,10 +23,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y libc++-dev libc++abi-dev - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} From 7ada41422ee1bd5f21559ca80b47885ec5811b86 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:24:07 +0100 Subject: [PATCH 37/57] Revert "Test if we really need to install libc++." This reverts commit 2f32f1c196fa3fff041ed630ac06176ceb5f069b. --- .github/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 12433c8f..c6a8b193 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,6 +23,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libc++-dev libc++abi-dev - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} From 2b533b260b1b0b697d2c4440ae7deb5ea64788eb Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 9 Jan 2025 16:40:40 +0100 Subject: [PATCH 38/57] Update CHANGELOG.md. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21a4b7db..fd1b81dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Error when redeclaring a variable. +- Fix clang/Linux/x64 GitHub Actions jobs (which use Ubuntu 24.04.1 since 2025). ### Removed From 0bee72f6c939b0c5dbf35ca730e45c0b1bd666d8 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 13 Jan 2025 12:11:11 +0100 Subject: [PATCH 39/57] Use unique names for md files. --- docs/api/{cpp.md => cpp-api.md} | 0 docs/api/{emscripten.md => emscripten-api.md} | 0 docs/api/{python.md => python-api.md} | 0 docs/dev-guide/{cpp.md => cpp-dev-guide.md} | 0 docs/dev-guide/dev-guide.md | 6 +++--- .../{emscripten.md => emscripten-dev-guide.md} | 0 .../{python.md => python-dev-guide.md} | 0 docs/user-guide/{cpp.md => cpp-user-guide.md} | 0 ...{emscripten.md => emscripten-user-guide.md} | 0 .../{python.md => python-user-guide.md} | 0 mkdocs-base.yaml | 18 +++++++++--------- 11 files changed, 12 insertions(+), 12 deletions(-) rename docs/api/{cpp.md => cpp-api.md} (100%) rename docs/api/{emscripten.md => emscripten-api.md} (100%) rename docs/api/{python.md => python-api.md} (100%) rename docs/dev-guide/{cpp.md => cpp-dev-guide.md} (100%) rename docs/dev-guide/{emscripten.md => emscripten-dev-guide.md} (100%) rename docs/dev-guide/{python.md => python-dev-guide.md} (100%) rename docs/user-guide/{cpp.md => cpp-user-guide.md} (100%) rename docs/user-guide/{emscripten.md => emscripten-user-guide.md} (100%) rename docs/user-guide/{python.md => python-user-guide.md} (100%) diff --git a/docs/api/cpp.md b/docs/api/cpp-api.md similarity index 100% rename from docs/api/cpp.md rename to docs/api/cpp-api.md diff --git a/docs/api/emscripten.md b/docs/api/emscripten-api.md similarity index 100% rename from docs/api/emscripten.md rename to docs/api/emscripten-api.md diff --git a/docs/api/python.md b/docs/api/python-api.md similarity index 100% rename from docs/api/python.md rename to docs/api/python-api.md diff --git a/docs/dev-guide/cpp.md b/docs/dev-guide/cpp-dev-guide.md similarity index 100% rename from docs/dev-guide/cpp.md rename to docs/dev-guide/cpp-dev-guide.md diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index 16f1bcd8..bfb2ee7e 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -77,7 +77,7 @@ conan build . -pr:a=conan/profiles/tests-debug -b missing !!! note - - the `conan profile` command only has to be run only once, and not before every build. + - the `conan profile` command has to be run only once, and not before every build. - the `conan build` command is building libQASM in Debug mode with tests using the `tests-debug` profile. - the `-b missing` parameter asks `conan` to build packages from sources in case it cannot find the binary packages for the current configuration (platform, OS, compiler, build type...). @@ -133,7 +133,7 @@ Continuous Integration will fail if the files do not adhere to a series of forma - Formatting checks are defined in `.clang-format`. - Code style checks are defined in `.clang-tidy`. -It is recommended to run these linters before pushing any change: +It is recommended to run these linters before pushing any changes: ```shell conan build . -pr:a=conan/profiles/tests-release-gcc-linux-x64 -b missing @@ -142,7 +142,7 @@ python3 ./scripts/run_cpp_linters.py . !!! note - - The linters require`clang-format-18` and `clang-tidy-18`. + - The linters require `clang-format-18` and `clang-tidy-18`. - It is mandatory to have a build before running the linters. - `clang-tidy` expects to find a `compile_commands.json` in a build folder. - It is recommended to build with _gcc_ in _Release_ mode. diff --git a/docs/dev-guide/emscripten.md b/docs/dev-guide/emscripten-dev-guide.md similarity index 100% rename from docs/dev-guide/emscripten.md rename to docs/dev-guide/emscripten-dev-guide.md diff --git a/docs/dev-guide/python.md b/docs/dev-guide/python-dev-guide.md similarity index 100% rename from docs/dev-guide/python.md rename to docs/dev-guide/python-dev-guide.md diff --git a/docs/user-guide/cpp.md b/docs/user-guide/cpp-user-guide.md similarity index 100% rename from docs/user-guide/cpp.md rename to docs/user-guide/cpp-user-guide.md diff --git a/docs/user-guide/emscripten.md b/docs/user-guide/emscripten-user-guide.md similarity index 100% rename from docs/user-guide/emscripten.md rename to docs/user-guide/emscripten-user-guide.md diff --git a/docs/user-guide/python.md b/docs/user-guide/python-user-guide.md similarity index 100% rename from docs/user-guide/python.md rename to docs/user-guide/python-user-guide.md diff --git a/mkdocs-base.yaml b/mkdocs-base.yaml index ec74e1ee..8eea4ad6 100644 --- a/mkdocs-base.yaml +++ b/mkdocs-base.yaml @@ -7,19 +7,19 @@ nav: - Home: index.md - User Guide: - User Guide: user-guide/user-guide.md - - C++: user-guide/cpp.md + - C++: user-guide/cpp-user-guide.md - Docker: user-guide/docker.md - - Emscripten: user-guide/emscripten.md - - Python: user-guide/python.md + - Emscripten: user-guide/emscripten-user-guide.md + - Python: user-guide/python-user-guide.md - Developer Guide: - Dev Guide: dev-guide/dev-guide.md - - C++: dev-guide/cpp.md - - Emscripten: dev-guide/emscripten.md - - Python: dev-guide/python.md + - C++: dev-guide/cpp-dev-guide.md + - Emscripten: dev-guide/emscripten-dev-guide.md + - Python: dev-guide/python-dev-guide.md - API: - - C++: api/cpp.md - - Emscripten: api/emscripten.md - - Python: api/python.md + - C++: api/cpp-api.md + - Emscripten: api/emscripten-api.md + - Python: api/python-api.md - About: - Release Notes: about/release-notes.md - Contributing: about/contributing.md From 55a8a09c51fb6d172ea29b596e7feb962b6848f2 Mon Sep 17 00:00:00 2001 From: rturrado Date: Mon, 13 Jan 2025 12:13:56 +0100 Subject: [PATCH 40/57] Minor changes to dev-guide.md. --- docs/dev-guide/dev-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/dev-guide/dev-guide.md b/docs/dev-guide/dev-guide.md index bfb2ee7e..abb54114 100644 --- a/docs/dev-guide/dev-guide.md +++ b/docs/dev-guide/dev-guide.md @@ -145,8 +145,8 @@ python3 ./scripts/run_cpp_linters.py . - The linters require `clang-format-18` and `clang-tidy-18`. - It is mandatory to have a build before running the linters. - `clang-tidy` expects to find a `compile_commands.json` in a build folder. - - It is recommended to build with _gcc_ in _Release_ mode. - - We have observed `clang-tidy` fails to find some standard headers when compiling with _clang_. + - It is recommended to build with `gcc` in Release mode. + - We have observed `clang-tidy` fails to find some standard headers when compiling with `clang`. - `run_cpp_linters.py` can receive a build folder as second argument, but defaults to `build/Release`. ## Docker From 2b8f1b05587ec6c96c4641ee07d581bd79c09a0a Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 22:18:15 +0100 Subject: [PATCH 41/57] Add clang-format option: QualifierAlignment=Left. --- .clang-format | 1 + 1 file changed, 1 insertion(+) diff --git a/.clang-format b/.clang-format index f77fab92..cee653f7 100644 --- a/.clang-format +++ b/.clang-format @@ -32,6 +32,7 @@ IndentWidth: 4 LambdaBodyIndentation: Signature PackConstructorInitializers: Never PointerAlignment: Left +QualifierAlignment: Left ReferenceAlignment: Left ReflowComments: true SpacesBeforeTrailingComments: 2 From 55e34f5f05ab89255ee6282d6453539b12470c52 Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 22:32:47 +0100 Subject: [PATCH 42/57] Update GitHub workflows: - assets.yaml: - Add Linux/ARM64 OS to cibw-wheels, and remove cibw-wheels-linux-arm64. - test.yml: - Change cpp-linux-arm64 job to use GitHub-hosted runner. - Build cpp-linux-arm64 both with clang and gcc. --- .github/workflows/assets.yaml | 46 ++++++----------------------------- .github/workflows/test.yaml | 28 ++++++--------------- 2 files changed, 15 insertions(+), 59 deletions(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index 54379b48..1da26f09 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -14,8 +14,13 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - # macos-13 is an x64 runner, macos-14 is an arm64 runner - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ + ubuntu-latest, # Linux/x64 + macos-13, # MacOS/x64 + windows-latest, # Windows/x64 + ubuntu-24.04-arm, # Linux/ARM64 + macos-14 # MacOS/ARM64 + ] steps: - name: Checkout uses: actions/checkout@v4 @@ -29,42 +34,6 @@ jobs: name: cibw-wheels-${{ matrix.os }} path: ./wheelhouse/*.whl - cibw-wheels-linux-arm64: - name: Build wheels on linux-arm64 - runs-on: [self-hosted, ARM64, Linux] - container: - image: python:3.12-slim - volumes: - - /var/run/docker.sock:/var/run/docker.sock - steps: - - name: Checkout - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - - name: Install docker - run: | - apt-get update - apt-get install -y ca-certificates curl - install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc - chmod a+r /etc/apt/keyrings/docker.asc - - echo \ - "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ - $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ - tee /etc/apt/sources.list.d/docker.list > /dev/null - apt-get update - apt-get install -y docker-ce-cli - - name: Install cibuildwheel and build wheels - run: | - pip install cibuildwheel==2.18.1 - cibuildwheel --output-dir wheelhouse - env: - CIBW_BEFORE_ALL_LINUX: yum install -y java-11-openjdk - - uses: actions/upload-artifact@v4 - with: - name: cibw-wheels-linux-arm64 - path: ./wheelhouse/*.whl - emscripten-wasm: name: WASM binaries for emscripten runs-on: ubuntu-latest @@ -108,7 +77,6 @@ jobs: name: Publish Python packages needs: - cibw-wheels - - cibw-wheels-linux-arm64 - emscripten-wasm runs-on: ubuntu-latest steps: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index c6a8b193..abf5f749 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,35 +35,24 @@ jobs: cpp-linux-arm64: name: "C++ tests (gcc/Linux/ARM64)" - runs-on: [self-hosted, ARM64, Linux] - container: python:3.11 - # Run only when merging to develop - # (until we have a GitHub-hosted runner for Linux/ARM64) - if: github.ref == 'refs/heads/develop' + runs-on: ubuntu-24.04-arm strategy: fail-fast: false matrix: build_type: - Debug - Release + compiler: + - clang + - gcc steps: - name: Checkout uses: actions/checkout@v4 - # We are having problems when using zulu-opendjk Conan package on an armv8 architecture. - # zulu-openjdk provides the Java JRE required by the ANTLR generator. - # So, for the time being, we are installing Java manually for this platform - - name: Install dependencies - run: | - apt-get update - apt-get install -y default-jre pipx - # Add Conan to path (even before it is installed) - - name: Add Conan to path - run: | - echo "${HOME}/.local/bin" >> $GITHUB_PATH - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} - conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-gcc-linux-arm64 + conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-arm64 + conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-arm64 shell: bash cpp-macos-x64: @@ -86,7 +75,7 @@ jobs: cpp-macos-arm64: name: "C++ tests (clang/macos/ARM64)" - runs-on: macos-14 # arm64 + runs-on: macos-14 # ARM4 strategy: fail-fast: false matrix: @@ -204,7 +193,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install SWIG + - name: Install dependencies run: | brew install swig shell: bash @@ -279,7 +268,6 @@ jobs: || ( github.ref != 'refs/heads/develop' && contains(needs.*.result, 'skipped') - && !contains(needs.cpp-linux-arm64.result, 'skipped') ) || ( From b25bbdc2416ba5c9ac25e48d6a6912c9d91e4545 Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 22:37:21 +0100 Subject: [PATCH 43/57] Update step names in test.yaml. To look exactly like in QX. --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index abf5f749..567efffd 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -193,7 +193,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies + - name: Install SWIG run: | brew install swig shell: bash @@ -207,7 +207,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies + - name: Install SWIG run: | brew install swig shell: bash From e8e8cd31987fd7e48d4b2993c681683a490c4d46 Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 22:52:27 +0100 Subject: [PATCH 44/57] Always set conan_profile_build. To look exactly like in QX. --- .github/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 567efffd..f36fb695 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -31,6 +31,7 @@ jobs: with: build_type: ${{ matrix.build_type }} conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-x64 + conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-x64 shell: bash cpp-linux-arm64: @@ -71,6 +72,7 @@ jobs: with: build_type: ${{ matrix.build_type }} conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-x64 + conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-x64 shell: bash cpp-macos-arm64: @@ -89,6 +91,7 @@ jobs: with: build_type: ${{ matrix.build_type }} conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-arm64 + conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-arm64 shell: bash cpp-windows-x64: @@ -126,6 +129,7 @@ jobs: with: build_type: ${{ matrix.build_type }} conan_profile_host: conan/profiles/${{ matrix.build_type }}-gcc-linux-x64-shared + conan_profile_build: conan/profiles/${{ matrix.build_type }}-gcc-linux-x64-shared shell: bash ts-emscripten-wasm: From b9d5cf5e4f756461dba4f27b3026de0788aa7e0b Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 22:52:40 +0100 Subject: [PATCH 45/57] Update step names in test.yaml. To look exactly like in QX. --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f36fb695..945c89dc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install dependencies + - name: Install libc++ run: | sudo apt-get update sudo apt-get install -y libc++-dev libc++abi-dev From 957fb0b6472bee541a0a787163423390e513e0fa Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 23:02:32 +0100 Subject: [PATCH 46/57] Update CHANGELOG.md. --- CHANGELOG.md | 63 ++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1b81dc..c9e058f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,14 @@ -# Change Log +# Changelog All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +### Types of changes: +- **Added** for new features. +- **Changed** for changes in existing functionality. +- **Fixed** for any bug fixes. +- **Removed** for now removed features. + ## [ 1.0.0 ] - [ xxxx-yy-zz ] @@ -11,9 +17,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Error when redeclaring a variable. -- Fix clang/Linux/x64 GitHub Actions jobs (which use Ubuntu 24.04.1 since 2025). +- Change Linux/ARM64 jobs to use GitHub-hosted runners. -### Removed +### Fixed +- clang/Linux/x64 GitHub Actions jobs (which use Ubuntu 24.04.1 since 2025). ## [ 0.6.9 ] - [ 2024-11-13 ] @@ -22,8 +29,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). - `SWAP` unitary instruction. - `init`, `barrier`, and `wait` non-unitary instructions. -### Changed - ### Removed - `reset` without qubit operands form. @@ -35,12 +40,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). - C++ linters GitHub Actions job (just running clang-format at the moment). ### Changed -- Fix bug: empty lists are written out to JSON as `"[]"` instead of `[]`. -- Fix bug: CRk and CZ parameter types were interchanged in the instruction set. - More descriptive and consistent (snake case) file names. - Minor fixes and tweaks to documentation. -### Removed +### Fixed +- Empty lists are written out to JSON as `"[]"` instead of `[]`. +- `CRk` and `CZ` parameter types were interchanged in the instruction set. ## [ 0.6.7 ] - [ 2024-05-30 ] @@ -49,10 +54,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). - `pyproject.toml`. - GitHub pages. -### Changed -- Fix building of tests in Conan profiles and `setup.py`. -- Fix Python MacOS/x64 (with Python > 3.11) packages. -- Fix deserialization of CBOR strings. +### Fixed +- Building of tests in Conan profiles and `setup.py`. +- Python MacOS/x64 (with Python > 3.11) packages. +- Deserialization of CBOR strings. ### Removed - Python 3.8 packages generation. @@ -62,39 +67,35 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Allow multiple qubit/bit (register) definitions and mid-circuit measurements. -- Python MacOS/arm64 jobs. +- Python MacOS/ARM64 jobs. - `python/test_libqasm.py` to test Python jobs. ### Changed -- Fix Python MacOS/arm64 packages. -- Fix `scripts/generate_antlr_parser.py`. -- MacOS/x64 jobs now run in macos-13, and MacOS/arm64 jobs in macos-14, both GitHub runners. +- MacOS/x64 jobs now run in macos-13, and MacOS/ARM64 jobs in macos-14, both GitHub runners. - Python module name from `libQasm` to `libqasm`. +## Fixed +- Python MacOS/arm64 packages. +- `scripts/generate_antlr_parser.py`. + ### Removed - `python/module/libQasm` folder. ## [ 0.6.5 ] - [ 2024-04-23 ] -### Added - ### Changed - Update emscripten compilation flags. -- Change GitHub Actions `js-emscripten-wasm` job to work with `deno` instead of `node`. - -### Removed +- GitHub Actions `js-emscripten-wasm` job to work with `deno` instead of `node`. ## [ 0.6.4 ] - [ 2024-04-15 ] -### Added - ### Changed -- Fix CMake install. - `generate_antlr_parser.py` writes output include files in a given `include` folder. -### Removed +### Fixed +- CMake install. ## [ 0.6.3 ] - [ 2024-04-12 ] @@ -105,8 +106,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Allow multiple `measure` instructions at the end of a program. -### Removed - ## [ 0.6.2 ] - [ 2024-04-09 ] @@ -114,8 +113,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - `.clang-format`. - `emscripten-wasm` assets job. -### Changed -- Fix shared library build. +### Fixed +- Shared library build. ### Removed - `TREEN_GEN_BUILD_TESTS` option. @@ -123,12 +122,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [ 0.6.1 ] - [ 2024-04-08 ] -### Added - ### Changed -- Fix Python interface. - Update GitHub Actions versions. +### Fixed +- Python interface. + ### Removed - `m4` dependency. From 584f12b063b58c074859c692f284e6684b448b98 Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 23:06:56 +0100 Subject: [PATCH 47/57] Trying to fix cpp-linux-arm64 job. --- .github/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 945c89dc..327ceb7d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -49,6 +49,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Install libc++ + run: | + sudo apt-get update + sudo apt-get install -y libc++-dev libc++abi-dev - uses: ./.github/actions/cpp-tests with: build_type: ${{ matrix.build_type }} From 2bf32b17a8001ad5f2d2c60fbfcea4cfa45c7a24 Mon Sep 17 00:00:00 2001 From: rturrado Date: Wed, 29 Jan 2025 23:41:17 +0100 Subject: [PATCH 48/57] Trying to fix cpp-linux-arm64 job. Disable address sanitizer for clang/Linux/ARM64 too. --- conan/profiles/tests-debug-clang-linux-arm64 | 5 +++++ conan/profiles/tests-release-clang-linux-arm64 | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/conan/profiles/tests-debug-clang-linux-arm64 b/conan/profiles/tests-debug-clang-linux-arm64 index 76ef4bab..d57f514d 100644 --- a/conan/profiles/tests-debug-clang-linux-arm64 +++ b/conan/profiles/tests-debug-clang-linux-arm64 @@ -7,3 +7,8 @@ compiler.version=14 [conf] tools.build:cxxflags=["-stdlib=libc++"] tools.build:compiler_executables={ 'c' : 'clang', 'cpp' : 'clang++' } + +[options] +# Disable ASAN for Linux/x64 because we are having problems with gtest and address sanitizer +# Possible hints: libc++ ABI compatibility, small string optimization +libqasm/*:asan_enabled=False diff --git a/conan/profiles/tests-release-clang-linux-arm64 b/conan/profiles/tests-release-clang-linux-arm64 index 3f39a2ca..182edb7f 100644 --- a/conan/profiles/tests-release-clang-linux-arm64 +++ b/conan/profiles/tests-release-clang-linux-arm64 @@ -7,3 +7,8 @@ compiler.version=14 [conf] tools.build:cxxflags=["-stdlib=libc++"] tools.build:compiler_executables={ 'c' : 'clang', 'cpp' : 'clang++' } + +[options] +# Disable ASAN for Linux/x64 because we are having problems with gtest and address sanitizer +# Possible hints: libc++ ABI compatibility, small string optimization +libqasm/*:asan_enabled=False From ee2508863e97b1aa6dfbdb6124c29196b3b73a78 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 17:58:30 +0100 Subject: [PATCH 49/57] Creating release 1.0.0. --- CHANGELOG.md | 2 +- docs/dev-guide/cpp-dev-guide.md | 2 +- docs/user-guide/cpp-user-guide.md | 4 ++-- emscripten/test_libqasm.ts | 2 +- include/libqasm/versioning.hpp | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e058f6..d9162e3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - **Removed** for now removed features. -## [ 1.0.0 ] - [ xxxx-yy-zz ] +## [ 1.0.0 ] - [ 2025-01-30 ] ### Added - `.clang-tidy`. diff --git a/docs/dev-guide/cpp-dev-guide.md b/docs/dev-guide/cpp-dev-guide.md index 36bda12f..dbc99b4f 100644 --- a/docs/dev-guide/cpp-dev-guide.md +++ b/docs/dev-guide/cpp-dev-guide.md @@ -7,7 +7,7 @@ The following line will also build and cache the `libqasm` Conan package. ```shell conan profile detect -conan create --version 0.6.9 . -pr:a=tests-debug -b missing +conan create --version 1.0.0 . -pr:a=tests-debug -b missing ``` You can test the C++ binaries: diff --git a/docs/user-guide/cpp-user-guide.md b/docs/user-guide/cpp-user-guide.md index 5afc2b73..2c4daa2e 100644 --- a/docs/user-guide/cpp-user-guide.md +++ b/docs/user-guide/cpp-user-guide.md @@ -2,9 +2,9 @@ libQASM can be requested as a Conan package from a `conanfile.py`: ``` def build_requirements(self): - self.tool_requires("libqasm/0.6.9") + self.tool_requires("libqasm/1.0.0") def requirements(self): - self.requires("libqasm/0.6.9") + self.requires("libqasm/1.0.0") ``` And then linked against from a `CMakeLists.txt`: diff --git a/emscripten/test_libqasm.ts b/emscripten/test_libqasm.ts index d0539186..f141b451 100644 --- a/emscripten/test_libqasm.ts +++ b/emscripten/test_libqasm.ts @@ -8,7 +8,7 @@ wrapper().then(function(result: any) { try { let output = cqasm.get_version() - let expected_output = "0.6.9" + let expected_output = "1.0.0" console.log("\nThe version of libqasm compiled with emscripten is:", output); if (output !== expected_output) { console.log("\tExpected output:", expected_output) diff --git a/include/libqasm/versioning.hpp b/include/libqasm/versioning.hpp index 8b2c037e..f35c95b8 100644 --- a/include/libqasm/versioning.hpp +++ b/include/libqasm/versioning.hpp @@ -2,8 +2,8 @@ namespace cqasm { -static const char* version{ "0.6.9" }; -static const char* release_year{ "2024" }; +static const char* version{ "1.0.0" }; +static const char* release_year{ "2025" }; [[nodiscard]] [[maybe_unused]] static const char* get_version() { return version; From 4e14daeb3f99a8f7501d4624f15022344b03f858 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 18:33:26 +0100 Subject: [PATCH 50/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index 1da26f09..ae4fdfb4 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -24,6 +24,12 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + # The Linux/ARM64 runner seems to be missing Java + - name: Install dependencies + if: matrix.os == 'ubuntu-24.04-arm' + run: | + apt-get update + apt-get install -y default-jre - uses: actions/setup-python@v5 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.18.1 From 9b721cffe9c64b68612f0afd44e27727d53af41c Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 18:43:35 +0100 Subject: [PATCH 51/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index ae4fdfb4..e2948512 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -24,13 +24,13 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - uses: actions/setup-python@v5 # The Linux/ARM64 runner seems to be missing Java - name: Install dependencies - if: matrix.os == 'ubuntu-24.04-arm' + if: ${{ matrix.os == 'ubuntu-24.04-arm' }} run: | apt-get update apt-get install -y default-jre - - uses: actions/setup-python@v5 - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.18.1 - name: Build wheels From ff9eb39b4d38e138fc0b63595bb891c8c14492fc Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 18:44:19 +0100 Subject: [PATCH 52/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index e2948512..f508a3bb 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -29,8 +29,8 @@ jobs: - name: Install dependencies if: ${{ matrix.os == 'ubuntu-24.04-arm' }} run: | - apt-get update - apt-get install -y default-jre + sudo apt-get update + sudo apt-get install -y default-jre - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.18.1 - name: Build wheels From ea21932d2f30d2ddf35a3def12915227eeb8499b Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 19:02:28 +0100 Subject: [PATCH 53/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index f508a3bb..fbccc26d 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -26,11 +26,13 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-python@v5 # The Linux/ARM64 runner seems to be missing Java - - name: Install dependencies + - name: Install Java and add it to the path if: ${{ matrix.os == 'ubuntu-24.04-arm' }} run: | sudo apt-get update sudo apt-get install -y default-jre + echo "/usr/bin" >> $GITHUB_PATH + java --version - name: Install cibuildwheel run: python -m pip install cibuildwheel==2.18.1 - name: Build wheels From c423d1b3275682626fe1288d945049ea6ce6d81d Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 19:09:15 +0100 Subject: [PATCH 54/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index fbccc26d..b442ebdc 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -25,18 +25,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 - uses: actions/setup-python@v5 - # The Linux/ARM64 runner seems to be missing Java - - name: Install Java and add it to the path - if: ${{ matrix.os == 'ubuntu-24.04-arm' }} - run: | - sudo apt-get update - sudo apt-get install -y default-jre - echo "/usr/bin" >> $GITHUB_PATH - java --version - name: Install cibuildwheel - run: python -m pip install cibuildwheel==2.18.1 + run: | + python -m pip install cibuildwheel==2.18.1 - name: Build wheels - run: python -m cibuildwheel --output-dir wheelhouse + run: | + python -m cibuildwheel --output-dir wheelhouse + if: ${{ matrix.os == 'ubuntu-24.04-arm' }} + env: + CIBW_BEFORE_ALL_LINUX: sudo yum install -y java-11-openjdk - uses: actions/upload-artifact@v4 with: name: cibw-wheels-${{ matrix.os }} From 9b5e573e84b655a6288c9f09937b6a13593877f1 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 19:10:50 +0100 Subject: [PATCH 55/57] Trying to fix cibw-wheels job for Linux/ARM64. --- .github/workflows/assets.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/assets.yaml b/.github/workflows/assets.yaml index b442ebdc..9acb7190 100644 --- a/.github/workflows/assets.yaml +++ b/.github/workflows/assets.yaml @@ -33,7 +33,7 @@ jobs: python -m cibuildwheel --output-dir wheelhouse if: ${{ matrix.os == 'ubuntu-24.04-arm' }} env: - CIBW_BEFORE_ALL_LINUX: sudo yum install -y java-11-openjdk + CIBW_BEFORE_ALL_LINUX: yum install -y java-11-openjdk - uses: actions/upload-artifact@v4 with: name: cibw-wheels-${{ matrix.os }} From a054333b351fd8fbac2e43acc8ee596796d3d984 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 19:25:12 +0100 Subject: [PATCH 56/57] Add python-linux-arm64 job. --- .github/workflows/test.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 327ceb7d..43e5b0a8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -195,6 +195,20 @@ jobs: with: shell: bash + python-linux-arm64: + name: "Python tests (Linux/arm64)" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install SWIG + run: | + sudo apt-get install -y swig + shell: bash + - uses: ./.github/actions/python-tests + with: + shell: bash + python-macos-x64: name: "Python tests (macOS/x64)" runs-on: macos-13 @@ -259,6 +273,7 @@ jobs: - cpp-shared - ts-emscripten-wasm - python-linux-x64 + - python-linux-arm64 - python-macos-x64 - python-macos-arm64 - python-windows-x64 From f7d73cbc6b1ec9b0222143937136d9b52b87fa50 Mon Sep 17 00:00:00 2001 From: rturrado Date: Thu, 30 Jan 2025 19:44:10 +0100 Subject: [PATCH 57/57] Update CHANGELOG.md. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9162e3a..ef9d4dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - `.clang-tidy`. +- Python Linux/ARM64 GitHub Actions job. ### Changed - Error when redeclaring a variable. @@ -75,7 +76,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Python module name from `libQasm` to `libqasm`. ## Fixed -- Python MacOS/arm64 packages. +- Python MacOS/ARM64 packages. - `scripts/generate_antlr_parser.py`. ### Removed