diff --git a/.github/workflows/code-linting-checks.yaml b/.github/workflows/code-linting-checks.yaml index 23c2822..3ce4170 100644 --- a/.github/workflows/code-linting-checks.yaml +++ b/.github/workflows/code-linting-checks.yaml @@ -45,4 +45,9 @@ jobs: tar --version task --version + - name: "Install project dependencies " + timeout-minutes: 10 + continue-on-error: false + run: "task deps:lib_install" + - run: "task lint:check" diff --git a/.gitmodules b/.gitmodules index 2d96d0d..09604b1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "tools/yscope-dev-utils"] path = tools/yscope-dev-utils url = https://github.com/y-scope/yscope-dev-utils.git +[submodule "submodules/Catch2"] + path = submodules/Catch2 + url = https://github.com/catchorg/Catch2.git diff --git a/CMakeLists.txt b/CMakeLists.txt index ccefcf6..d6ab6a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,10 +29,96 @@ if(NOT CMAKE_BUILD_TYPE) ) endif() -add_executable(spider) -target_compile_features(spider PRIVATE cxx_std_20) +# Add local CMake module directory to CMake's modules path +set(CMAKE_MODULE_PATH + ${CMAKE_MODULE_PATH} + "${CMAKE_SOURCE_DIR}/cmake/Modules/" +) + +# Macro providing the length of the absolute source directory path so we can +# create a relative (rather than absolute) __FILE__ macro +string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE) +add_definitions("-DSOURCE_PATH_SIZE=${SOURCE_PATH_SIZE}") + +# Profiling options +add_definitions(-DPROF_ENABLED=0) + +# Compile-in debug logging statements +#add_definitions(-DSPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_DEBUG) + +# Flush to disk switch +add_definitions(-DFLUSH_TO_DISK_ENABLED=1) + +# Make off_t 64-bit +add_definitions(-D_FILE_OFFSET_BITS=64) + +# Detect linking mode (static or shared); Default to static. +set(SPIDER_USE_STATIC_LIBS ON CACHE BOOL "Whether to link against static libraries") +if(SPIDER_USE_STATIC_LIBS) + if(APPLE) + set(SPIDER_STATIC_LIBS_UNSUPPORTED_PLATFORM "macOS") + elseif(EXISTS "/etc/centos-release") + set(SPIDER_STATIC_LIBS_UNSUPPORTED_PLATFORM "CentOS") + endif() + + if(DEFINED SPIDER_STATIC_LIBS_UNSUPPORTED_PLATFORM) + message( + AUTHOR_WARNING + "Building with static libraries is unsupported on" + " ${SPIDER_STATIC_LIBS_UNSUPPORTED_PLATFORM}. Switching to shared libraries." + ) + set(SPIDER_USE_STATIC_LIBS OFF) + endif() +endif() +if(SPIDER_USE_STATIC_LIBS) + set(SPIDER_LIBS_STRING "static") +else() + set(SPIDER_LIBS_STRING "shared") +endif() +message(STATUS "Building using ${SPIDER_LIBS_STRING} libraries") + +# Find and setup fmt +find_package(fmt 8.0.1 REQUIRED) +if(fmt_FOUND) + message(STATUS "Found fmt ${fmt_VERSION}") +else() + message(FATAL_ERROR "Could not find static libraries for fmt") +endif() + +# Find and setup spdlog +if(SPIDER_USE_STATIC_LIBS) + # NOTE: On some Linux distributions (e.g. Ubuntu), the spdlog package only contains a dynamic + # library. If the `find_package(spdlog)` call below fails, re-run + # `tools/scripts/lib_install//install-packages-from-source.sh` to build spdlog from + # source. + set(spdlog_USE_STATIC_LIBS ON) +endif() +set(SPDLOG_FMT_EXTERNAL ON) +find_package(spdlog 1.9.2 REQUIRED) +if(spdlog_FOUND) + message(STATUS "Found spdlog ${spdlog_VERSION}") +else() + if(SPIDER_USE_STATIC_LIBS) + message(FATAL_ERROR "Could not find static libraries for spdlog.`") + else() + message(FATAL_ERROR "Could not find libraries for spdlog.") + endif() +endif() + +# Find and setup MariaDBClient library +if(CLP_USE_STATIC_LIBS) + # NOTE: We can't statically link to MariaDBClient since it's GPL + message(AUTHOR_WARNING "MariaDBClient cannot be statically linked due to its license.") +endif() +find_package(MariaDBClient 3.1.0 REQUIRED) +if(MariaDBClient_FOUND) + message(STATUS "Found MariaDBClient ${MariaDBClient_VERSION}") +else() + message(FATAL_ERROR "Could not find ${CLP_LIBS_STRING} libraries for MariaDBClient") +endif() + +find_package(Threads REQUIRED) -set(SPIDER_SOURCES src/spider/spider.cpp) -target_sources(spider PRIVATE ${SPIDER_SOURCES}) +add_subdirectory(src/spider) -target_include_directories(spider PRIVATE src/) +add_subdirectory(tests) diff --git a/cmake/Modules/FindLibraryDependencies.cmake b/cmake/Modules/FindLibraryDependencies.cmake new file mode 100644 index 0000000..f0f3951 --- /dev/null +++ b/cmake/Modules/FindLibraryDependencies.cmake @@ -0,0 +1,59 @@ +# Find the given libraries ignoring libraries that should be dynamically linked +# Params: +# fld_LIBNAME - Name of the library (without the 'lib' prefix) +# fld_PREFIX - Prefix for created variables +# fld_STATIC_LIBS - List of libraries to find +# Returns: +# ${fld_LIBNAME}_DYNAMIC_LIBS - List of libraries that should be dynamically linked +# ${fld_PREFIX}_LIBRARY_DEPENDENCIES - Found libraries +macro(FindStaticLibraryDependencies fld_LIBNAME fld_PREFIX fld_STATIC_LIBS) + # NOTE: libc, libm, libpthread, and librt should be dynamically linked + set(fld_DYNAMIC_LIBS "c;m;pthread;rt") + + # Get absolute path of dependent libraries + foreach(fld_DEP_LIB ${fld_STATIC_LIBS}) + # Skip dynamic libs + set(fld_IGNORE_LIB FALSE) + foreach(fld_DYNAMIC_LIB ${fld_DYNAMIC_LIBS}) + if(${fld_DEP_LIB} STREQUAL ${fld_DYNAMIC_LIB}) + set(fld_IGNORE_LIB TRUE) + list(APPEND ${fld_PREFIX}_DYNAMIC_LIBS "${fld_DEP_LIB}") + endif() + endforeach() + if(fld_IGNORE_LIB OR ${fld_DEP_LIB} STREQUAL ${fld_LIBNAME}) + continue() + endif() + + find_library(${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY NAMES ${fld_DEP_LIB} PATH_SUFFIXES lib) + if(${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY) + list( + APPEND + ${fld_PREFIX}_LIBRARY_DEPENDENCIES + "${${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY}" + ) + else() + message(SEND_ERROR "Static ${fld_DEP_LIB} library not found") + endif() + endforeach() +endmacro() + +# Find the given libraries +# Params: +# fld_PREFIX - Prefix for created variables +# fld_DYNAMIC_LIBS - List of libraries to find +# Returns: +# ${fld_PREFIX}_LIBRARY_DEPENDENCIES - Found libraries +macro(FindDynamicLibraryDependencies fld_PREFIX fld_DYNAMIC_LIBS) + foreach(fld_DEP_LIB ${fld_DYNAMIC_LIBS}) + find_library(${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY NAMES ${fld_DEP_LIB} PATH_SUFFIXES lib) + if(${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY) + list( + APPEND + ${fld_PREFIX}_LIBRARY_DEPENDENCIES + "${${fld_PREFIX}_${fld_DEP_LIB}_LIBRARY}" + ) + else() + message(SEND_ERROR "${fld_DEP_LIB} library not found") + endif() + endforeach() +endmacro() diff --git a/cmake/Modules/FindMariaDBClient.cmake b/cmake/Modules/FindMariaDBClient.cmake new file mode 100644 index 0000000..b36820f --- /dev/null +++ b/cmake/Modules/FindMariaDBClient.cmake @@ -0,0 +1,123 @@ +# Try to find MariaDBClient +# NOTE: The FindMariaDBClient.cmake included with CMake has no support for static libraries, so we use our own. +# +# Set MariaDBClient_USE_STATIC_LIBS=ON to look for static libraries. +# +# Once done this will define: +# MariaDBClient_FOUND - Whether MariaDBClient was found on the system +# MariaDBClient_INCLUDE_DIR - The MariaDBClient include directories +# MariaDBClient_VERSION - The version of MariaDBClient installed on the system +# +# Conventions: +# - Variables only for use within the script are prefixed with "mariadbclient_" +# - Variables that should be externally visible are prefixed with "MariaDBClient_" + +set(mariadbclient_LIBNAME "mariadb") + +include(cmake/Modules/FindLibraryDependencies.cmake) + +# Run pkg-config +find_package(PkgConfig) +pkg_check_modules(mariadbclient_PKGCONF QUIET "lib${mariadbclient_LIBNAME}") + +# Set include directory +find_path( + MariaDBClient_INCLUDE_DIR + mysql.h + HINTS + ${mariadbclient_PKGCONF_INCLUDEDIR} + PATH_SUFFIXES + mariadb +) + +# Handle static libraries +if(MariaDBClient_USE_STATIC_LIBS) + # Save current value of CMAKE_FIND_LIBRARY_SUFFIXES + set(mariadbclient_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + + # Temporarily change CMAKE_FIND_LIBRARY_SUFFIXES to static library suffix + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) +endif() + +# Find library +find_library( + MariaDBClient_LIBRARY + NAMES + ${mariadbclient_LIBNAME} + HINTS + ${mariadbclient_PKGCONF_LIBDIR} + PATH_SUFFIXES + lib +) +if(MariaDBClient_LIBRARY) + # NOTE: This must be set for find_package_handle_standard_args to work + set(MariaDBClient_FOUND ON) +endif() + +if(MariaDBClient_USE_STATIC_LIBS) + findstaticlibrarydependencies(${mariadbclient_LIBNAME} mariadbclient + "${mariadbclient_PKGCONF_STATIC_LIBRARIES}" + ) + + # Restore original value of CMAKE_FIND_LIBRARY_SUFFIXES + set(CMAKE_FIND_LIBRARY_SUFFIXES ${mariadbclient_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(mariadbclient_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() + +finddynamiclibrarydependencies(mariadbclient "${mariadbclient_DYNAMIC_LIBS}") + +# Set version +set(MariaDBClient_VERSION ${mariadbclient_PKGCONF_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + MariaDBClient + REQUIRED_VARS + MariaDBClient_INCLUDE_DIR + VERSION_VAR MariaDBClient_VERSION +) + +if(NOT TARGET MariaDBClient::MariaDBClient) + # Add library to build + if(MariaDBClient_FOUND) + if(MariaDBClient_USE_STATIC_LIBS) + add_library(MariaDBClient::MariaDBClient STATIC IMPORTED) + else() + # NOTE: We use UNKNOWN so that if the user doesn't have the SHARED + # libraries installed, we can still use the STATIC libraries + add_library(MariaDBClient::MariaDBClient UNKNOWN IMPORTED) + endif() + endif() + + # Set include directories for library + if(MariaDBClient_INCLUDE_DIR) + set_target_properties( + MariaDBClient::MariaDBClient + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES + "${MariaDBClient_INCLUDE_DIR}" + ) + endif() + + # Set location of library + if(EXISTS "${MariaDBClient_LIBRARY}") + set_target_properties( + MariaDBClient::MariaDBClient + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES + "C" + IMPORTED_LOCATION + "${MariaDBClient_LIBRARY}" + ) + + # Add component's dependencies for linking + if(mariadbclient_LIBRARY_DEPENDENCIES) + set_target_properties( + MariaDBClient::MariaDBClient + PROPERTIES + INTERFACE_LINK_LIBRARIES + "${mariadbclient_LIBRARY_DEPENDENCIES}" + ) + endif() + endif() +endif() diff --git a/cmake/Modules/Findspdlog.cmake b/cmake/Modules/Findspdlog.cmake new file mode 100644 index 0000000..09991e7 --- /dev/null +++ b/cmake/Modules/Findspdlog.cmake @@ -0,0 +1,130 @@ +# Try to find spdlog +# +# Set spdlog_USE_STATIC_LIBS=ON to look for static libraries. +# +# Once done this will define: +# spdlog_FOUND - Whether spdlog was found on the system +# spdlog_INCLUDE_DIR - The spdlog include directories +# spdlog_VERSION - The version of spdlog installed on the system +# +# Conventions: +# - Variables only for use within the script are prefixed with "SPDLOG_" +# - Variables that should be externally visible are prefixed with "spdlog_" + +set(SPDLOG_LIBNAME "spdlog") +set(SPDLOG_TARGET_NAME "spdlog::spdlog") + +include(cmake/Modules/FindLibraryDependencies.cmake) + +# Run pkg-config +find_package(PkgConfig) +pkg_check_modules(SPDLOG_PKGCONF QUIET ${SPDLOG_LIBNAME}) + +# Set include directory +find_path(spdlog_INCLUDE_DIR spdlog.h HINTS ${SPDLOG_PKGCONF_INCLUDEDIR} PATH_SUFFIXES spdlog) + +# Handle static libraries +if(spdlog_USE_STATIC_LIBS) + # Save current value of CMAKE_FIND_LIBRARY_SUFFIXES + set(SPDLOG_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + + # Temporarily change CMAKE_FIND_LIBRARY_SUFFIXES to static library suffix + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) +endif() + +# Find library +find_library( + SPDLOG_LIBRARY + NAMES + ${SPDLOG_LIBNAME} + HINTS + ${SPDLOG_PKGCONF_LIBDIR} + PATH_SUFFIXES + lib +) +if(SPDLOG_LIBRARY) + # NOTE: This must be set for find_package_handle_standard_args to work + set(spdlog_FOUND ON) +endif() + +if(spdlog_USE_STATIC_LIBS) + findstaticlibrarydependencies(${SPDLOG_LIBNAME} SPDLOG "${SPDLOG_PKGCONF_STATIC_LIBRARIES}") + + # Restore original value of CMAKE_FIND_LIBRARY_SUFFIXES + set(CMAKE_FIND_LIBRARY_SUFFIXES ${SPDLOG_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(SPDLOG_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() + +finddynamiclibrarydependencies(SPDLOG "${SPDLOG_PKGCONF_LIBRARIES}") + +# Set version +set(spdlog_VERSION ${SPDLOG_PKGCONF_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + ${SPDLOG_LIBNAME} + REQUIRED_VARS + spdlog_INCLUDE_DIR + VERSION_VAR spdlog_VERSION +) + +if(NOT TARGET ${SPDLOG_TARGET_NAME}) + # Add library to build + if(spdlog_FOUND) + if(spdlog_USE_STATIC_LIBS) + add_library(${SPDLOG_TARGET_NAME} STATIC IMPORTED) + set_target_properties( + ${SPDLOG_TARGET_NAME} + PROPERTIES + COMPILE_FLAGS + "${SPDLOG_PKGCONF_STATIC_CFLAGS}" + ) + else() + # NOTE: We use UNKNOWN so that if the user doesn't have the SHARED + # libraries installed, we can still use the STATIC libraries. + add_library(${SPDLOG_TARGET_NAME} UNKNOWN IMPORTED) + set_target_properties( + ${SPDLOG_TARGET_NAME} + PROPERTIES + COMPILE_FLAGS + "${SPDLOG_PKGCONF_CFLAGS}" + ) + endif() + endif() + + # Set include directories for library + if(NOT EXISTS "${spdlog_INCLUDE_DIR}") + set(spdlog_FOUND OFF) + else() + set_target_properties( + ${SPDLOG_TARGET_NAME} + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES + "${spdlog_INCLUDE_DIR}" + ) + endif() + + # Set location of library + if(NOT EXISTS "${SPDLOG_LIBRARY}") + set(spdlog_FOUND OFF) + else() + set_target_properties( + ${SPDLOG_TARGET_NAME} + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES + "C" + IMPORTED_LOCATION + "${SPDLOG_LIBRARY}" + ) + + # Add component's dependencies for linking + if(SPDLOG_LIBRARY_DEPENDENCIES) + set_target_properties( + ${SPDLOG_TARGET_NAME} + PROPERTIES + INTERFACE_LINK_LIBRARIES + "${SPDLOG_LIBRARY_DEPENDENCIES}" + ) + endif() + endif() +endif() diff --git a/dep-tasks.yaml b/dep-tasks.yaml new file mode 100644 index 0000000..aa99401 --- /dev/null +++ b/dep-tasks.yaml @@ -0,0 +1,23 @@ +version: "3" + +vars: + G_SCRIPT_DIR: "{{.ROOT_DIR}}/tools/scripts" + +tasks: + + lib_install: + deps: ["lib_install_mac", "lib_install_linux"] + + lib_install_mac: + internal: true + platforms: ["darwin"] + dir: "{{.G_SCRIPT_DIR}}/macOS" + cmds: + - "./install-lib.sh" + + lib_install_linux: + internal: true + platforms: ["linux"] + dir: "{{.G_SCRIPT_DIR}}/linux" + cmds: + - "./install-lib.sh" diff --git a/lint-tasks.yaml b/lint-tasks.yaml index 20c7d3e..68f800d 100644 --- a/lint-tasks.yaml +++ b/lint-tasks.yaml @@ -105,6 +105,7 @@ tasks: .gersemirc \ .github/ \ lint-tasks.yaml \ + dep-tasks.yaml \ taskfile.yaml clang-format: @@ -135,9 +136,16 @@ tasks: internal: true requires: vars: ["FLAGS"] - cmd: |- - . "{{.G_LINT_VENV_DIR}}/bin/activate" - gersemi {{.FLAGS}} CMakeLists.txt src/ + sources: + - "CMakeLists.txt" + - "src/spider/CMakeLists.txt" + - "tests/CMakeLists.txt" + - "cmake/Modules/*.cmake" + cmds: + - for: "sources" + cmd: |- + . "{{.G_LINT_VENV_DIR}}/bin/activate" + gersemi {{.FLAGS}} {{.ITEM}} venv: internal: true diff --git a/src/spider/CMakeLists.txt b/src/spider/CMakeLists.txt new file mode 100644 index 0000000..5e1d236 --- /dev/null +++ b/src/spider/CMakeLists.txt @@ -0,0 +1,14 @@ +# set variable as CACHE INTERNAL to access it from other scope +set(SPIDER_CORE_SOURCES storage/MetadataStorage.hpp CACHE INTERNAL "spider core source files") + +set(SPIDER_WORKER_SOURCES worker/worker.cpp CACHE INTERNAL "spider worker source files") + +add_executable(spider_worker) +target_compile_features(spider_worker PRIVATE cxx_std_20) +target_sources( + spider_worker + PRIVATE + ${SPIDER_CORE_SOURCES} + ${SPIDER_WORKER_SOURCES} +) +add_executable(spider::worker ALIAS spider_worker) diff --git a/src/spider/spider.cpp b/src/spider/spider.cpp deleted file mode 100644 index 3f80fc3..0000000 --- a/src/spider/spider.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include - -auto main() -> int { - std::cout << "Hello, world!" << '\n'; - return 0; -} diff --git a/src/spider/storage/MetadataStorage.hpp b/src/spider/storage/MetadataStorage.hpp new file mode 100644 index 0000000..c71dc17 --- /dev/null +++ b/src/spider/storage/MetadataStorage.hpp @@ -0,0 +1,4 @@ +#ifndef SPIDER_METADATASTORAGE_HPP +#define SPIDER_METADATASTORAGE_HPP + +#endif // SPIDER_METADATASTORAGE_HPP diff --git a/src/spider/worker/worker.cpp b/src/spider/worker/worker.cpp new file mode 100644 index 0000000..dfadebc --- /dev/null +++ b/src/spider/worker/worker.cpp @@ -0,0 +1,4 @@ + +auto main(int /*argc*/, char** /*argv*/) -> int { + return 0; +} diff --git a/submodules/Catch2 b/submodules/Catch2 new file mode 160000 index 0000000..a6ee7e2 --- /dev/null +++ b/submodules/Catch2 @@ -0,0 +1 @@ +Subproject commit a6ee7e20cd4011129816df7992c1a9db2ef4b58f diff --git a/taskfile.yaml b/taskfile.yaml index 6b8904e..763e06e 100644 --- a/taskfile.yaml +++ b/taskfile.yaml @@ -2,6 +2,7 @@ version: "3" includes: lint: "lint-tasks.yaml" + deps: "dep-tasks.yaml" utils: "tools/yscope-dev-utils/taskfiles/utils.yml" vars: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1 @@ + diff --git a/tools/scripts/lib_install/fmtlib.sh b/tools/scripts/lib_install/fmtlib.sh new file mode 100755 index 0000000..6673c81 --- /dev/null +++ b/tools/scripts/lib_install/fmtlib.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# Dependencies: +# - cmake +# - curl +# - g++ +# NOTE: Dependencies should be installed outside the script to allow the script to be largely distro-agnostic + +# Exit on any error +set -e + +cUsage="Usage: ${BASH_SOURCE[0]} [ <.deb output directory>]" +if [ "$#" -lt 1 ] ; then + echo $cUsage + exit +fi +version=$1 + +package_name=fmtlib +temp_dir=/tmp/${package_name}-installation +deb_output_dir=${temp_dir} +if [[ "$#" -gt 1 ]] ; then + deb_output_dir="$(readlink -f "$2")" + if [ ! -d ${deb_output_dir} ] ; then + echo "${deb_output_dir} does not exist or is not a directory" + exit + fi +fi + +# Check if already installed +set +e +dpkg -l ${package_name} | grep ${version} +installed=$? +set -e +if [ $installed -eq 0 ] ; then + # Nothing to do + exit +fi + +echo "Checking for elevated privileges..." +privileged_command_prefix="" +if [ ${EUID:-$(id -u)} -ne 0 ] ; then + sudo echo "Script can elevate privileges." + privileged_command_prefix="${privileged_command_prefix} sudo" +fi + +# Get number of cpu cores +num_cpus=$(grep -c ^processor /proc/cpuinfo) + +# Download +mkdir -p $temp_dir +cd $temp_dir +extracted_dir=${temp_dir}/fmt-${version} +if [ ! -e ${extracted_dir} ] ; then + tar_filename=${version}.tar.gz + if [ ! -e ${tar_filename} ] ; then + curl -fsSL https://github.com/fmtlib/fmt/archive/refs/tags/${tar_filename} -o ${tar_filename} + fi + + tar -xf ${tar_filename} +fi + +# Build +cd ${extracted_dir} +mkdir -p cmake-build-release +cd cmake-build-release +cmake ../ +make -j${num_cpus} + +# Check if checkinstall is installed +set +e +command -v checkinstall +checkinstall_installed=$? +set -e + +# Install +install_command_prefix="${privileged_command_prefix}" +if [ $checkinstall_installed -eq 0 ] ; then + install_command_prefix="${install_command_prefix} checkinstall --pkgname '${package_name}' --pkgversion '${version}' --provides '${package_name}' --nodoc -y --pakdir \"${deb_output_dir}\"" +fi +${install_command_prefix} make install + +# Clean up +rm -rf $temp_dir \ No newline at end of file diff --git a/tools/scripts/lib_install/mariadb-connector-c.sh b/tools/scripts/lib_install/mariadb-connector-c.sh new file mode 100755 index 0000000..3c46291 --- /dev/null +++ b/tools/scripts/lib_install/mariadb-connector-c.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# Dependencies: +# - curl +# - rsync +# NOTE: Dependencies should be installed outside the script to allow the script to be largely distro-agnostic + +# Exit on any error +set -e + +cUsage="Usage: ${BASH_SOURCE[0]} [ <.deb output directory>]" +if [ "$#" -lt 1 ] ; then + echo $cUsage + exit +fi +version=$1 + +package_name=libmariadb-dev +temp_dir=/tmp/${package_name}-installation +deb_output_dir=${temp_dir} +if [[ "$#" -gt 1 ]] ; then + deb_output_dir="$(readlink -f "$2")" + if [ ! -d ${deb_output_dir} ] ; then + echo "${deb_output_dir} does not exist or is not a directory" + exit + fi +fi + +# Check if already installed +set +e +dpkg -l ${package_name} | grep ${version} +installed=$? +set -e +if [ $installed -eq 0 ] ; then + # Nothing to do + exit +fi + +echo "Checking for elevated privileges..." +privileged_command_prefix="" +if [ ${EUID:-$(id -u)} -ne 0 ] ; then + sudo echo "Script can elevate privileges." + privileged_command_prefix="${privileged_command_prefix} sudo" +fi + +# Get OS version +source /etc/os-release +if [ $ID = "ubuntu" ] ; then + os_version=ubuntu-$UBUNTU_CODENAME +else + echo "Unsupported OS ID: $ID" + exit 1 +fi + +# Download +mkdir -p $temp_dir +cd $temp_dir +extracted_dir=${temp_dir}/mariadb-connector-c-${version}-${os_version}-amd64 +if [ ! -e ${extracted_dir} ] ; then + tar_filename=mariadb-connector-c-${version}-${os_version}-amd64.tar.gz + if [ ! -e ${tar_filename} ] ; then + curl -fsSL https://downloads.mariadb.com/Connectors/c/connector-c-${version}/${tar_filename} -o ${tar_filename} + fi + + tar -xf ${tar_filename} +fi + +cd ${extracted_dir} + +# Check if checkinstall is installed +set +e +command -v checkinstall +checkinstall_installed=$? +set -e + +# Install +install_dir=/usr/local +${privileged_command_prefix} mkdir -p ${install_dir} + +install_command_prefix="${privileged_command_prefix}" +if [ $checkinstall_installed -eq 0 ] ; then + install_command_prefix="${install_command_prefix} checkinstall --pkgname '${package_name}' --pkgversion '${version}' --provides '${package_name}' --nodoc -y --pakdir \"${deb_output_dir}\"" +fi +${install_command_prefix} rsync -a . ${install_dir}/ + +# Update ld cache +${privileged_command_prefix} ldconfig ${install_dir}/lib/mariadb + +# Clean up +rm -rf $temp_dir \ No newline at end of file diff --git a/tools/scripts/lib_install/spdlog.sh b/tools/scripts/lib_install/spdlog.sh new file mode 100755 index 0000000..24837f5 --- /dev/null +++ b/tools/scripts/lib_install/spdlog.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +# Dependencies: +# - cmake +# - curl +# - g++ +# NOTE: Dependencies should be installed outside the script to allow the script to be largely distro-agnostic + +# Exit on any error +set -e + +cUsage="Usage: ${BASH_SOURCE[0]} [ <.deb output directory>]" +if [ "$#" -lt 1 ] ; then + echo $cUsage + exit +fi +version=$1 + +lib_name=spdlog +package_name=libspdlog-dev +temp_dir=/tmp/${package_name}-installation +deb_output_dir=${temp_dir} +if [[ "$#" -gt 1 ]] ; then + deb_output_dir="$(readlink -f "$2")" + if [ ! -d ${deb_output_dir} ] ; then + echo "${deb_output_dir} does not exist or is not a directory" + exit + fi +fi + +# Check if already installed +set +e +pkg-config --exact-version="${version}" "${lib_name}" +pkg_found=$? +if [ $pkg_found -eq 0 ] ; then + find /usr/lib/ /usr/local/lib/ -name "libspdlog.a" | grep -q "." + static_lib_found=$? +fi +installed=$((pkg_found | static_lib_found)) +set -e +if [ $installed -eq 0 ] ; then + echo "Found ${lib_name}=${version}." + # Nothing to do + exit +fi + +echo "Checking for elevated privileges..." +privileged_command_prefix="" +if [ ${EUID:-$(id -u)} -ne 0 ] ; then + sudo echo "Script can elevate privileges." + privileged_command_prefix="${privileged_command_prefix} sudo" +fi + +# Get number of cpu cores +num_cpus=$(grep -c ^processor /proc/cpuinfo) + +# Download +mkdir -p $temp_dir +cd $temp_dir +extracted_dir=${temp_dir}/spdlog-${version} +if [ ! -e ${extracted_dir} ] ; then + tar_filename=v${version}.tar.gz + if [ ! -e ${tar_filename} ] ; then + curl -fsSL https://github.com/gabime/spdlog/archive/${tar_filename} -o ${tar_filename} + fi + + tar -xf ${tar_filename} +fi + +# Build +cd ${extracted_dir} +mkdir -p build +cd build +cmake ../ +make -j${num_cpus} + +# Check if checkinstall is installed +set +e +command -v checkinstall +checkinstall_installed=$? +set -e + +# Install +install_command_prefix="${privileged_command_prefix}" +if [ $checkinstall_installed -eq 0 ] ; then + # NOTE: We use "1:${version}" to override the version installed by Ubuntu 18.04 + install_command_prefix="${install_command_prefix} checkinstall --pkgname '${package_name}' --pkgversion '1:${version}' --provides '${package_name}' --nodoc -y --pakdir \"${deb_output_dir}\"" +fi +${install_command_prefix} make install + +# Clean up +rm -rf $temp_dir \ No newline at end of file diff --git a/tools/scripts/linux/install-lib.sh b/tools/scripts/linux/install-lib.sh new file mode 100755 index 0000000..eca3c1d --- /dev/null +++ b/tools/scripts/linux/install-lib.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Exit on any error +set -e + +# Error on undefined variable +set -u + +script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +lib_install_scripts_dir=$script_dir/.. + +"$lib_install_scripts_dir"/lib_install/fmtlib.sh 11.0.2 +"$lib_install_scripts_dir"/lib_install/spdlog.sh 1.14.1 +"$lib_install_scripts_dir"/lib_install/mariadb-connector-c.sh 3.4.1 diff --git a/tools/scripts/macOS/install-lib.sh b/tools/scripts/macOS/install-lib.sh new file mode 100755 index 0000000..a7ff99a --- /dev/null +++ b/tools/scripts/macOS/install-lib.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Exit on any error +set -e + +# Error on undefined variable +set -u + +brew update +brew install \ + boost \ + coreutils \ + fmt \ + mariadb-connector-c \ + spdlog \ + pkg-config \ No newline at end of file