diff --git a/config/generate.py b/config/generate.py index 05e9c2339..ae323ee34 100755 --- a/config/generate.py +++ b/config/generate.py @@ -23,6 +23,14 @@ def wrap_text(s, initial_indent="# "): def extract_flags(binary_path): ret = {} data = subprocess.run([binary_path, "--help-xml"], stdout=subprocess.PIPE).stdout.decode("utf-8") + # If something is printed out before the help output, it will break the the + # XML parsing -> filter out if something is not XML line because something + # can be logged before gflags output (e.g. during the global objects init). + # This gets called during memgraph build phase to generate default config + # file later installed under /etc/memgraph/memgraph.conf + # NOTE: Don't use \n in the gflags description strings. + # NOTE: Check here if gflags version changes because of the XML format. + data = "\n".join([line for line in data.split("\n") if line.startswith("<")]) root = ET.fromstring(data) for child in root: if child.tag == "usage" and child.text.lower().count("warning"): diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 618c0ce5c..4c5367961 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -12,6 +12,7 @@ find_package(Boost 1.78 REQUIRED) find_package(BZip2 1.0.6 REQUIRED) find_package(Threads REQUIRED) set(GFLAGS_NOTHREADS OFF) +# NOTE: config/generate.py depends on the gflags help XML format. find_package(gflags REQUIRED) find_package(fmt 8.0.1) find_package(Jemalloc REQUIRED) diff --git a/release/CMakeLists.txt b/release/CMakeLists.txt index 4bdb4bf69..7055f4543 100644 --- a/release/CMakeLists.txt +++ b/release/CMakeLists.txt @@ -48,7 +48,7 @@ set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION_SUMMARY} # Add `openssl` package to dependencies list. Used to generate SSL certificates. # We also depend on `python3` because we embed it in Memgraph. -set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0), python3 (>= 3.5.0), libstdc++6") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl (>= 1.1.0), python3 (>= 3.5.0)") # Setting arhitecture extension for rpm packages set(MG_ARCH_EXTENSION_RPM "noarch") @@ -69,6 +69,12 @@ set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION set(CPACK_RPM_PACKAGE_REQUIRES_PRE "shadow-utils") set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_CURRENT_SOURCE_DIR}/rpm/memgraph.spec.in") set(CPACK_RPM_PACKAGE_LICENSE "Memgraph License") +# CPACK deduces dependency to libstdc++ which: +# * can't be easily installed on Centos 7 (the one from the toolchain, +# only required to avoid printing issue within query modules) +# * it causes issues with glibcxx 2.4 +# `if(DISTRO STREQUAL "Amazon Linux" AND DISTRO_VERSION STREQUAL "2")` +set(CPACK_RPM_PACKAGE_AUTOREQ " no") # Description formatting is important, no line must be greater than 80 characters. set(CPACK_RPM_PACKAGE_DESCRIPTION "Contains Memgraph, the graph database. @@ -77,13 +83,7 @@ the next generation of applications driver by real-time connected data.") # Add `openssl` package to dependencies list. Used to generate SSL certificates. # We also depend on `python3` because we embed it in Memgraph. -set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.0.0, curl >= 7.29.0, python3 >= 3.5.0, libstdc++ >= 3.4.29, logrotate") - -# If amzn-2 -if(DISTRO STREQUAL "Amazon Linux" AND DISTRO_VERSION STREQUAL "2") - # It causes issues with glibcxx 2.4 - set(CPACK_RPM_PACKAGE_AUTOREQ " no") -endif() +set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.0.0, curl >= 7.29.0, python3 >= 3.5.0, logrotate") # All variables must be set before including. include(CPack) diff --git a/src/query/procedure/module.hpp b/src/query/procedure/module.hpp index 82478257b..ccb56b2fc 100644 --- a/src/query/procedure/module.hpp +++ b/src/query/procedure/module.hpp @@ -1,4 +1,4 @@ -// Copyright 2022 Memgraph Ltd. +// Copyright 2023 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -131,7 +131,12 @@ class ModuleRegistry final { private: class SharedLibraryHandle { public: - SharedLibraryHandle(const std::string &shared_library, int mode) : handle_{dlopen(shared_library.c_str(), mode)} {} + SharedLibraryHandle(const std::string &shared_library, int mode, const std::string &hint_message = "") + : handle_{dlopen(shared_library.c_str(), mode)} { + if (!handle_) { + spdlog::warn("Unable to load {}. {}", shared_library, hint_message); + } + } SharedLibraryHandle(const SharedLibraryHandle &) = delete; SharedLibraryHandle(SharedLibraryHandle &&) = delete; SharedLibraryHandle operator=(const SharedLibraryHandle &) = delete; @@ -147,10 +152,13 @@ class ModuleRegistry final { void *handle_; }; + inline static const std::string kLibstdcppWarning = + "Query modules might not work as expected. Printing non-string values from query modules might not work. Please " + "install libstdc++ or compile from source with the recent toolchain (all included)."; #if __has_feature(address_sanitizer) // This is why we need RTLD_NODELETE and we must not use RTLD_DEEPBIND with // ASAN: https://github.com/google/sanitizers/issues/89 - SharedLibraryHandle libstd_handle{"libstdc++.so.6", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE}; + SharedLibraryHandle libstd_handle{"libstdc++.so.6", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE, kLibstdcppWarning}; #else // The reason behind opening share library during runtime is to avoid issues // with loading symbols from stdlib. We have encounter issues with locale @@ -161,7 +169,7 @@ class ModuleRegistry final { // mentioned library will be first performed in the already existing binded // libraries and then the global namespace. // RTLD_DEEPBIND => https://linux.die.net/man/3/dlopen - SharedLibraryHandle libstd_handle{"libstdc++.so.6", RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND}; + SharedLibraryHandle libstd_handle{"libstdc++.so.6", RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND, kLibstdcppWarning}; #endif std::vector modules_dirs_; std::filesystem::path internal_module_dir_;