diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..159771b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,29 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + branches: [ master ] + push: + branches: [ master ] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + tests: + uses: ./.github/workflows/step_test.yaml + + pass: + needs: [ tests ] + runs-on: ubuntu-latest + steps: + - name: Check all CI jobs + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + if: always() diff --git a/.github/workflows/step_test.yaml b/.github/workflows/step_test.yaml new file mode 100644 index 0000000..70c9447 --- /dev/null +++ b/.github/workflows/step_test.yaml @@ -0,0 +1,62 @@ +name: test +run-name: Run tests + +on: + workflow_call: + +permissions: + contents: read + +jobs: + tests: + name: Check ${{ matrix.toolchain }} + runs-on: ${{ matrix.os || 'ubuntu-latest' }} + container: ${{ !matrix.os && 'ghcr.io/lecrisut/dev-env:main' || '' }} + continue-on-error: ${{ matrix.experimental || false }} + strategy: + fail-fast: false + matrix: + toolchain: [ gcc, llvm, intel, windows, macos ] + openmp: [ ON, OFF ] + include: + - os: windows-latest + toolchain: windows + # Need to find how to install on windows + experimental: true + - os: macos-latest + toolchain: macos + - os: macos-latest + toolchain: macos + openmp: ON + # Need to find how to install openmp on macos + experimental: true + env: + WITH_OPENMP: ${{ matrix.openmp }} + steps: + - name: Enable msvc toolchain on windows + uses: ilammy/msvc-dev-cmd@v1 + if: contains(matrix.os, 'windows') + - name: Activate Intel compilers + # Not elegant, it will propagate all environment variable. + # Intel does not provide a way to output the environment variables to a file + # Note: PATH needs to be exported to GITHUB_PATH otherwise it can be overwritten + run: | + source /opt/intel/oneapi/setvars.sh + printenv >> $GITHUB_ENV + echo $PATH >> $GITHUB_PATH + if: matrix.toolchain == 'intel' + - uses: actions/checkout@v4 + - uses: lukka/get-cmake@latest + - name: Run CMake configuration for ${{ matrix.toolchain }} toolchain + uses: lukka/run-cmake@v10.3 + with: + workflowPreset: "${{ matrix.toolchain }}-ci" + pass: + needs: [ tests ] + runs-on: ubuntu-latest + steps: + - name: Check test jobs + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + if: always() diff --git a/.gitignore b/.gitignore index 80d93c4..a182556 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ dkms.conf build/ lib/ .svn/ + +### Project specific +CMakeUserPresets.json +cmake-build-* diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd1b4b..ccbe957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,209 @@ -cmake_minimum_required(VERSION 2.8) -project(GKlib C) +cmake_minimum_required(VERSION 3.15) +# CMake version compatibility +# TODO: Remove when cmake 3.25 is commonly distributed +if (POLICY CMP0140) + cmake_policy(SET CMP0140 NEW) +endif () -option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF) +#[==============================================================================================[ +# Basic project definition # +]==============================================================================================] -get_filename_component(abs "." ABSOLUTE) -set(GKLIB_PATH ${abs}) -unset(abs) -include(GKlibSystem.cmake) +list(APPEND CMAKE_MESSAGE_CONTEXT GKlib) +project(GKlib + VERSION 5.3.0 + DESCRIPTION "A library of various helper routines and frameworks used by many of the KarypisLab's software" + HOMEPAGE_URL https://github.com/KarypisLab/GKlib + LANGUAGES C +) -include_directories(".") -if(MSVC) - include_directories("win32") - file(GLOB win32_sources RELATIVE "win32" "*.c") -else(MSVC) - set(win32_sources, "") -endif(MSVC) +# Back-porting to PROJECT_IS_TOP_LEVEL to older cmake +# TODO: Remove when requiring cmake >= 3.21 +if (NOT DEFINED Spglib_IS_TOP_LEVEL) + if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + set(PROJECT_IS_TOP_LEVEL ON) + else () + set(PROJECT_IS_TOP_LEVEL OFF) + endif () +endif () -add_library(GKlib ${GKlib_sources} ${win32_sources}) +# Specify C standard +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) -if(UNIX) - target_link_libraries(GKlib m) -endif(UNIX) +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif () -include_directories("test") -add_subdirectory("test") +#[==============================================================================================[ +# Options # +]==============================================================================================] -install(TARGETS GKlib - ARCHIVE DESTINATION lib/${LINSTALL_PATH} - LIBRARY DESTINATION lib/${LINSTALL_PATH}) -install(FILES ${GKlib_includes} DESTINATION include/${HINSTALL_PATH}) +include(CMakeDependentOption) +include(FeatureSummary) +option(GKLIB_TESTS "GKlib: Build unit tests" ${PROJECT_IS_TOP_LEVEL}) +option(GKLIB_SHARED_LIBS "GKlib: Build as a shared library" ${PROJECT_IS_TOP_LEVEL}) +option(GKLIB_INSTALL "GKlib: Install project" ${PROJECT_IS_TOP_LEVEL}) + +# TODO: Discuss these options. Non-standard and easily conflicting +option(GKLIB_ASSERT "GKlib: Turn asserts on" OFF) +option(GKLIB_ASSERT2 "GKlib: Additional assertions" OFF) +option(GKLIB_NO_X86 "GKlib: Enable NO_X86 support" ON) +option(GKLIB_GPROF "GKlib: Add gprof support" OFF) + +option(GKLIB_OpenMP "GKlib: Enable OpenMP support" OFF) +add_feature_info(GKLIB_OpenMP GKLIB_OpenMP "OpenMP support") +option(GKLIB_PCRE "GKlib: Enable PCRE support" OFF) +add_feature_info(GKLIB_PCRE GKLIB_PCRE "PCRE support") +cmake_dependent_option(GKLIB_GKREGEX "GKlib: Enable GKREGEX support" OFF "NOT GKLIB_PCRE" OFF) +add_feature_info(GKLIB_GKREGEX GKLIB_GKREGEX "GKREGEX support") +option(GKLIB_GKRAND "GKlib: Enable GKRAND support" OFF) +add_feature_info(GKLIB_GKRAND GKLIB_GKRAND "GKRAND support") + +#[==============================================================================================[ +# Project configuration # +]==============================================================================================] + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +# Include basic tools +include(FetchContent) +if (GKLIB_INSTALL) + include(CMakePackageConfigHelpers) + if (UNIX) + include(GNUInstallDirs) + endif () +endif () + +# Define basic parameters +set(BUILD_SHARED_LIBS ${GKLIB_SHARED_LIBS}) + +#[==============================================================================================[ +# External packages # +]==============================================================================================] + +if (GKLIB_OpenMP) + # Normally these packages are pulled outside of if statements to allow to be added optionally. + # Making an exception for basic packages like OpenMP, MPI, etc. that drastically change a + # library's implementation and expected behaviour + find_package(OpenMP COMPONENTS C) + set_package_properties(OpenMP PROPERTIES TYPE REQUIRED) +endif () +if (GKLIB_PCRE) + # TODO: This option should be obsolete and moved to optional find_package control + # TODO: Move to PCRE2, since PCRE1 is dead +# find_package(pcre2 COMPONENTS POSIX) +# set_package_properties(pcre2 PROPERTIES TYPE REQUIRED) +endif () +include(GKlib_PackagesInfo) + +feature_summary( + FILENAME ${CMAKE_CURRENT_BINARY_DIR}/GKlib.info + VAR GKlib_Info + DESCRIPTION "GKlib supported libraries" + FATAL_ON_MISSING_REQUIRED_PACKAGES + WHAT ALL +) +message(STATUS ${GKlib_Info}) + +#[==============================================================================================[ +# Main definition # +]==============================================================================================] + +# Main project +add_library(GKlib_GKlib) +set_target_properties(GKlib_GKlib PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + EXPORT_NAME GKlib + OUTPUT_NAME gk +) +add_library(GKlib::GKlib ALIAS GKlib_GKlib) +add_subdirectory(include) +add_subdirectory(src) + + +if (GKLIB_TESTS) + enable_testing() + add_subdirectory(test) +endif () + +#[==============================================================================================[ +# Install or Export # +]==============================================================================================] + +# Installation +if (GKLIB_INSTALL) + # pkg-config files + # TODO: Figure how to make this work +# file(GENERATE OUTPUT gklib.pc +# INPUT cmake/gklib.pc.in +# ) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/gklib.pc +# DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig +# COMPONENT GKlib_Development +# ) + + # cmake export files + write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/GKlibConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ) + configure_package_config_file( + cmake/GKlibConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/GKlibConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/GKlib + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/GKlibConfigVersion.cmake + ${CMAKE_CURRENT_BINARY_DIR}/GKlibConfig.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/GKlib + COMPONENT GKlib_Development + ) + export(EXPORT GKlibTargets + FILE GKlibTargets.cmake + NAMESPACE GKlib:: + ) + install(EXPORT GKlibTargets + FILE GKlibTargets.cmake + NAMESPACE GKlib:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/GKlib + COMPONENT GKlib_Development + ) +endif () + +# Make project available for FetchContent +if (NOT PROJECT_IS_TOP_LEVEL) + # Set variables for FetchContent + # All variables have to be consistent with GKlibConfig.cmake + set(GKlib_OpenMP GKLIB_OpenMP) + set(GKlib_PCRE GKLIB_PCRE) + set(GKlib_GKREGEX GKLIB_GKREGEX) + set(GKlib_GKRAND GKLIB_GKRAND) + # Propagate variables + if (CMAKE_VERSION VERSION_LESS 3.25) + # TODO: Remove when cmake 3.25 is commonly distributed + set(GKlib_VERSION ${GKlib_VERSION} PARENT_SCOPE) + set(GKlib_VERSION_MAJOR ${GKlib_VERSION_MAJOR} PARENT_SCOPE) + set(GKlib_VERSION_MINOR ${GKlib_VERSION_MINOR} PARENT_SCOPE) + set(GKlib_VERSION_PATCH ${GKlib_VERSION_PATCH} PARENT_SCOPE) + set(GKlib_VERSION_TWEAK ${GKlib_VERSION_TWEAK} PARENT_SCOPE) + set(GKlib_OpenMP ${GKlib_OpenMP} PARENT_SCOPE) + set(GKlib_PCRE ${GKlib_PCRE} PARENT_SCOPE) + set(GKlib_GKREGEX ${GKlib_GKREGEX} PARENT_SCOPE) + set(GKlib_GKRAND ${GKlib_GKRAND} PARENT_SCOPE) + else () + return(PROPAGATE + GKlib_VERSION + GKlib_VERSION_MAJOR + GKlib_VERSION_MINOR + GKlib_VERSION_PATCH + GKlib_VERSION_TWEAK + GKlib_OpenMP + GKlib_PCRE + GKlib_GKREGEX + GKlib_GKRAND + ) + endif () +endif () diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..3db1fed --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,12 @@ +{ + "version": 6, + "cmakeMinimumRequired": { + "major": 3, + "minor": 25, + "patch": 0 + }, + "include": [ + "cmake/CMakePresets-defaults.json", + "cmake/CMakePresets-CI.json" + ] +} diff --git a/GKlibSystem.cmake b/GKlibSystem.cmake deleted file mode 100644 index 31a1cf1..0000000 --- a/GKlibSystem.cmake +++ /dev/null @@ -1,152 +0,0 @@ -# Helper modules. -include(CheckFunctionExists) -include(CheckIncludeFile) - -# Setup options. -option(GDB "enable use of GDB" OFF) -option(ASSERT "turn asserts on" OFF) -option(ASSERT2 "additional assertions" OFF) -option(DEBUG "add debugging support" OFF) -option(GPROF "add gprof support" OFF) -option(VALGRIND "add valgrind support" OFF) -option(OPENMP "enable OpenMP support" OFF) -option(PCRE "enable PCRE support" OFF) -option(GKREGEX "enable GKREGEX support" OFF) -option(GKRAND "enable GKRAND support" OFF) -option(NO_X86 "enable NO_X86 support" OFF) - - -# Add compiler flags. -if(MSVC) - set(GKlib_COPTS "/Ox") - set(GKlib_COPTIONS "-DWIN32 -DMSC -D_CRT_SECURE_NO_DEPRECATE -DUSE_GKREGEX") -elseif(MINGW) - set(GKlib_COPTS "-DUSE_GKREGEX") -else() - set(GKlib_COPTIONS "-DLINUX -D_FILE_OFFSET_BITS=64") -endif(MSVC) -if(CYGWIN) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DCYGWIN") -endif(CYGWIN) -if(CMAKE_COMPILER_IS_GNUCC) -# GCC opts. - set(GKlib_COPTIONS "${GKlib_COPTIONS} -std=c99 -fno-strict-aliasing") -if(VALGRIND) - set(GKlib_COPTIONS "${GK_COPTIONS} -march=x86-64 -mtune=generic") -else() -# -march=native is not a valid flag on PPC: -if(CMAKE_SYSTEM_PROCESSOR MATCHES "power|ppc|powerpc|ppc64|powerpc64" OR (APPLE AND CMAKE_OSX_ARCHITECTURES MATCHES "ppc|ppc64")) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -mtune=native") -else() - set(GKlib_COPTIONS "${GKlib_COPTIONS} -march=native") -endif() -endif(VALGRIND) - if(NOT MINGW) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -fPIC") - endif(NOT MINGW) -# GCC warnings. - set(GKlib_COPTIONS "${GKlib_COPTIONS} -Werror -Wall -pedantic -Wno-unused-function -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unknown-pragmas -Wno-unused-label") -elseif(${CMAKE_C_COMPILER_ID} MATCHES "Sun") -# Sun insists on -xc99. - set(GKlib_COPTIONS "${GKlib_COPTIONS} -xc99") -endif(CMAKE_COMPILER_IS_GNUCC) - -# Intel compiler -if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") - set(GKlib_COPTIONS "${GKlib_COPTIONS} -xHost -std=c99") -endif() - -# Find OpenMP if it is requested. -if(OPENMP) - include(FindOpenMP) - if(OPENMP_FOUND) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__OPENMP__ ${OpenMP_C_FLAGS}") - else() - message(WARNING "OpenMP was requested but support was not found") - endif(OPENMP_FOUND) -endif(OPENMP) - -# Set the CPU type -if(NO_X86) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DNO_X86=${NO_X86}") -endif(NO_X86) - -# Add various definitions. -if(GDB) - set(GKlib_COPTS "${GKlib_COPTS} -g") - set(GKlib_COPTIONS "${GKlib_COPTIONS} -Werror") -else() - set(GKlib_COPTS "-O3") -endif(GDB) - - -if(DEBUG) - set(GKlib_COPTS "-g") - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DDEBUG") -endif(DEBUG) - -if(GPROF) - set(GKlib_COPTS "-pg") -endif(GPROF) - -if(NOT ASSERT) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DNDEBUG") -endif(NOT ASSERT) - -if(NOT ASSERT2) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DNDEBUG2") -endif(NOT ASSERT2) - - -# Add various options -if(PCRE) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__WITHPCRE__") -endif(PCRE) - -if(GKREGEX) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DUSE_GKREGEX") -endif(GKREGEX) - -if(GKRAND) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DUSE_GKRAND") -endif(GKRAND) - - -# Check for features. -check_include_file(execinfo.h HAVE_EXECINFO_H) -if(HAVE_EXECINFO_H) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DHAVE_EXECINFO_H") -endif(HAVE_EXECINFO_H) - -check_function_exists(getline HAVE_GETLINE) -if(HAVE_GETLINE) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -DHAVE_GETLINE") -endif(HAVE_GETLINE) - - -# Custom check for TLS. -if(MSVC) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__thread=__declspec(thread)") - - # This if checks if that value is cached or not. - if("${HAVE_THREADLOCALSTORAGE}" MATCHES "^${HAVE_THREADLOCALSTORAGE}$") - try_compile(HAVE_THREADLOCALSTORAGE - ${CMAKE_BINARY_DIR} - ${GKLIB_PATH}/conf/check_thread_storage.c) - if(HAVE_THREADLOCALSTORAGE) - message(STATUS "checking for thread-local storage - found") - else() - message(STATUS "checking for thread-local storage - not found") - endif() - endif() - if(NOT HAVE_THREADLOCALSTORAGE) - set(GKlib_COPTIONS "${GKlib_COPTIONS} -D__thread=") - endif() -endif() - -# Finally set the official C flags. -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GKlib_COPTIONS} ${GKlib_COPTS}") - -# Find GKlib sources. -file(GLOB GKlib_sources ${GKLIB_PATH}/*.c) -file(GLOB GKlib_includes ${GKLIB_PATH}/*.h) diff --git a/Makefile b/Makefile deleted file mode 100644 index 6ac97b9..0000000 --- a/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -# Configuration options. -cc = gcc -prefix = ~/local -openmp = not-set -gdb = not-set -assert = not-set -assert2 = not-set -debug = not-set -gprof = not-set -valgrind = not-set -pcre = not-set -gkregex = not-set -gkrand = not-set - - -# Basically proxies everything to the builddir cmake. -cputype = $(shell uname -m | sed "s/\\ /_/g") -systype = $(shell uname -s) - -BUILDDIR = build/$(systype)-$(cputype) - -# Process configuration options. -CONFIG_FLAGS = -DCMAKE_VERBOSE_MAKEFILE=1 -ifneq ($(gdb), not-set) - CONFIG_FLAGS += -DGDB=$(gdb) -endif -ifneq ($(assert), not-set) - CONFIG_FLAGS += -DASSERT=$(assert) -endif -ifneq ($(assert2), not-set) - CONFIG_FLAGS += -DASSERT2=$(assert2) -endif -ifneq ($(debug), not-set) - CONFIG_FLAGS += -DDEBUG=$(debug) -endif -ifneq ($(gprof), not-set) - CONFIG_FLAGS += -DGPROF=$(gprof) -endif -ifneq ($(valgrind), not-set) - CONFIG_FLAGS += -DVALGRIND=$(valgrind) -endif -ifneq ($(openmp), not-set) - CONFIG_FLAGS += -DOPENMP=$(openmp) -endif -ifneq ($(pcre), not-set) - CONFIG_FLAGS += -DPCRE=$(pcre) -endif -ifneq ($(gkregex), not-set) - CONFIG_FLAGS += -DGKREGEX=$(pcre) -endif -ifneq ($(gkrand), not-set) - CONFIG_FLAGS += -DGKRAND=$(pcre) -endif -ifneq ($(prefix), not-set) - CONFIG_FLAGS += -DCMAKE_INSTALL_PREFIX=$(prefix) -endif -ifneq ($(cc), not-set) - CONFIG_FLAGS += -DCMAKE_C_COMPILER=$(cc) -endif -ifneq ($(cputype), x86_64) - CONFIG_FLAGS += -DNO_X86=$(cputype) -endif - -define run-config -mkdir -p $(BUILDDIR) -cd $(BUILDDIR) && cmake $(CURDIR) $(CONFIG_FLAGS) -endef - -all clean install: $(BUILDDIR) - make -C $(BUILDDIR) $@ - -uninstall: - xargs rm < $(BUILDDIR)/install_manifest.txt - -$(BUILDDIR): - $(run-config) - -config: distclean - $(run-config) - -distclean: - rm -rf $(BUILDDIR) - -remake: - find . -name CMakeLists.txt -exec touch {} ';' - -.PHONY: config distclean all clean install uninstall remake diff --git a/README.md b/README.md index f94eeea..0b2e307 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,12 @@ # GKlib A library of various helper routines and frameworks used by many of the lab's software -## Build requirements - - CMake 2.8, found at http://www.cmake.org/, as well as GNU make. +## Building GKlib -Assuming that the above are available, two commands should suffice to -build the software: +To build GKlib you can follow the instructions below: +```console +$ cmake -B ./build +$ cmake --build ./build ``` -make config -make -``` - -## Configuring the build -It is primarily configured by passing options to make config. For example: -``` -make config cc=icc -``` - -would configure it to be built using icc. - -Configuration options are: -``` -cc=[compiler] - The C compiler to use [default: gcc] -prefix=[PATH] - Set the installation prefix [default: ~/local] -openmp=set - To build a version with OpenMP support -``` - - -## Building and installing -To build and install, run the following -``` -make -make install -``` - -By default, the library file, header file, and binaries will be installed in -``` -~/local/lib -~/local/include -~/local/bin -``` - -## Other make commands - make uninstall - Removes all files installed by 'make install'. - - make clean - Removes all object files but retains the configuration options. - - make distclean - Performs clean and completely removes the build directory. - +See the top-level [`CMakeLists.txt`](CMakeLists.txt) for more details on the available options diff --git a/cmake/CMakePresets-CI.json b/cmake/CMakePresets-CI.json new file mode 100644 index 0000000..86e547a --- /dev/null +++ b/cmake/CMakePresets-CI.json @@ -0,0 +1,305 @@ +{ + "version": 6, + "include": [ + "CMakePresets-defaults.json" + ], + "configurePresets": [ + { + "name": "ci-base", + "hidden": true, + "generator": "Ninja", + "inherits": [ + "default" + ], + "cacheVariables": { + "GKLIB_TESTS": { + "type": "BOOL", + "value": true + }, + "GKLIB_OpenMP": { + "type": "BOOL", + "value": "$env{WITH_OPENMP}" + } + }, + "errors": { + "deprecated": true + } + }, + { + "name": "gcc-ci", + "displayName": "GCC toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-gcc", + "cacheVariables": { + "CMAKE_C_COMPILER": { + "type": "FILEPATH", + "value": "gcc" + }, + "CMAKE_LINKER_TYPE": { + "type": "STRING", + "value": "SYSTEM" + } + } + }, + { + "name": "intel-ci", + "displayName": "Intel toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-intel", + "cacheVariables": { + "CMAKE_C_COMPILER": { + "type": "FILEPATH", + "value": "icx" + }, + "CMAKE_LINKER_TYPE": { + "type": "STRING", + "value": "SYSTEM" + } + } + }, + { + "name": "llvm-ci", + "displayName": "LLVM (Clang) toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-llvm", + "cacheVariables": { + "CMAKE_C_COMPILER": { + "type": "FILEPATH", + "value": "clang" + }, + "CMAKE_LINKER_TYPE": { + "type": "STRING", + "value": "LLD" + } + } + }, + { + "name": "windows-ci", + "displayName": "Windows native toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-windows", + "cacheVariables": { + "CMAKE_C_COMPILER": { + "type": "FILEPATH", + "value": "cl" + } + } + }, + { + "name": "macos-ci", + "displayName": "MacOS native toolchain", + "inherits": [ + "ci-base" + ], + "binaryDir": "cmake-build-ci-macos", + "cacheVariables": { + "CMAKE_C_COMPILER": { + "type": "FILEPATH", + "value": "clang" + } + } + } + ], + "buildPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "cleanFirst": true + }, + { + "name": "gcc-ci", + "displayName": "GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "intel-ci", + "displayName": "Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + }, + { + "name": "llvm-ci", + "displayName": "LLVM (Clang) toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + }, + { + "name": "windows-ci", + "displayName": "Windows native toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "windows-ci" + }, + { + "name": "macos-ci", + "displayName": "MacOS native toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "macos-ci" + } + ], + "testPresets": [ + { + "name": "ci-base", + "hidden": true, + "inherits": [ + "default" + ], + "output": { + "outputOnFailure": true + } + }, + { + "name": "gcc-ci", + "displayName": "GCC toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "gcc-ci" + }, + { + "name": "intel-ci", + "displayName": "Intel toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "intel-ci" + }, + { + "name": "llvm-ci", + "displayName": "LLVM (Clang) toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "llvm-ci" + }, + { + "name": "windows-ci", + "displayName": "Windows native toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "windows-ci" + }, + { + "name": "macos-ci", + "displayName": "MacOS native toolchain", + "inherits": [ + "ci-base" + ], + "configurePreset": "macos-ci" + } + ], + "workflowPresets": [ + { + "name": "gcc-ci", + "displayName": "GCC toolchain", + "steps": [ + { + "type": "configure", + "name": "gcc-ci" + }, + { + "type": "build", + "name": "gcc-ci" + }, + { + "type": "test", + "name": "gcc-ci" + } + ] + }, + { + "name": "intel-ci", + "displayName": "Intel toolchain", + "steps": [ + { + "type": "configure", + "name": "intel-ci" + }, + { + "type": "build", + "name": "intel-ci" + }, + { + "type": "test", + "name": "intel-ci" + } + ] + }, + { + "name": "llvm-ci", + "displayName": "LLVM (Clang) toolchain", + "steps": [ + { + "type": "configure", + "name": "llvm-ci" + }, + { + "type": "build", + "name": "llvm-ci" + }, + { + "type": "test", + "name": "llvm-ci" + } + ] + }, + { + "name": "windows-ci", + "displayName": "Windows native toolchain", + "steps": [ + { + "type": "configure", + "name": "windows-ci" + }, + { + "type": "build", + "name": "windows-ci" + }, + { + "type": "test", + "name": "windows-ci" + } + ] + }, + { + "name": "macos-ci", + "displayName": "MacOS native toolchain", + "steps": [ + { + "type": "configure", + "name": "macos-ci" + }, + { + "type": "build", + "name": "macos-ci" + }, + { + "type": "test", + "name": "macos-ci" + } + ] + } + ] +} diff --git a/cmake/CMakePresets-defaults.json b/cmake/CMakePresets-defaults.json new file mode 100644 index 0000000..6327111 --- /dev/null +++ b/cmake/CMakePresets-defaults.json @@ -0,0 +1,54 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "default", + "displayName": "Default preset", + "binaryDir": "cmake-build-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": { + "type": "STRING", + "value": "Release" + }, + "CMAKE_MESSAGE_CONTEXT_SHOW": { + "type": "BOOL", + "value": true + } + } + } + ], + "buildPresets": [ + { + "name": "default", + "displayName": "Default preset", + "configurePreset": "default" + } + ], + "testPresets": [ + { + "name": "default", + "displayName": "Default preset", + "configurePreset": "default" + } + ], + "workflowPresets": [ + { + "name": "default", + "displayName": "Default workflow", + "steps": [ + { + "type": "configure", + "name": "default" + }, + { + "type": "build", + "name": "default" + }, + { + "type": "test", + "name": "default" + } + ] + } + ] +} diff --git a/cmake/GKlibConfig.cmake.in b/cmake/GKlibConfig.cmake.in new file mode 100644 index 0000000..43b227b --- /dev/null +++ b/cmake/GKlibConfig.cmake.in @@ -0,0 +1,35 @@ +@PACKAGE_INIT@ + +## Define exported variables +set(GKlib_OpenMP @GKLIB_OpenMP@) +set(GKlib_PCRE @GKLIB_PCRE@) +set(GKlib_GKREGEX @GKLIB_GKREGEX@) +set(GKlib_GKRAND @GKLIB_GKRAND@) + +## Add all exported targets +include(${CMAKE_CURRENT_LIST_DIR}/GKlibTargets.cmake) + +set(_GKlib_supported_components OpenMP) +set(${CMAKE_FIND_PACKAGE_NAME}_OpenMP_FOUND ${GKlib_OpenMP}) + +include(CMakeFindDependencyMacro) +if (GKlib_OpenMP) + # OpenMP dependency propagates. It needs to be included by other packages + find_dependency(OpenMP COMPONENTS C) +endif () + +# Handle components +foreach (_comp ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS}) + if (NOT _comp IN_LIST _GKlib_supported_components) + set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) + set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") + endif () + # Currently there is only OpenMP component and that does not export a custom target set + # (should have the same SONAME/SOVERSION etc. unless these components are dynamically loaded) + if (_comp STREQUAL OpenMP) + if (${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${_comp} AND NOT GKlib_OpenMP) + set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False) + set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Missing component: ${_comp}") + endif () + endif () +endforeach () diff --git a/cmake/GKlib_PackagesInfo.cmake b/cmake/GKlib_PackagesInfo.cmake new file mode 100644 index 0000000..6c880cf --- /dev/null +++ b/cmake/GKlib_PackagesInfo.cmake @@ -0,0 +1,12 @@ +set_package_properties(pcre2 PROPERTIES + URL https://github.com/PCRE2Project/pcre2 + DESCRIPTION "Perl-Compatible Regular Expressions" + TYPE RECOMMENDED + PURPOSE "Regex parser" +) +set_package_properties(OpenMP PROPERTIES + URL https://www.openmp.org/resources/openmp-compilers-tools/ + DESCRIPTION "The OpenMP API specification for parallel programming" + TYPE RECOMMENDED + PURPOSE "Parallelization library" +) \ No newline at end of file diff --git a/cmake/gklib.pc.in b/cmake/gklib.pc.in new file mode 100644 index 0000000..e8d1a6f --- /dev/null +++ b/cmake/gklib.pc.in @@ -0,0 +1,6 @@ +Name: $<1:${PROJECT_NAME}> +Description: $<1:${PROJECT_DESCRIPTION}> +Version: $<1:${PROJECT_VERSION}> + +Libs: -L$<1:${CMAKE_INSTALL_FULL_LIBDIR}> -l$ +Cflags: -I$<1:${CMAKE_INSTALL_FULL_INCLUDEDIR}> $ diff --git a/conf/check_thread_storage.c b/conf/check_thread_storage.c deleted file mode 100644 index e6e1e98..0000000 --- a/conf/check_thread_storage.c +++ /dev/null @@ -1,5 +0,0 @@ -extern __thread int x; - -int main(int argc, char **argv) { - return 0; -} diff --git a/gk_externs.h b/gk_externs.h deleted file mode 100644 index 2c0fdd9..0000000 --- a/gk_externs.h +++ /dev/null @@ -1,25 +0,0 @@ -/*! -\file gk_externs.h -\brief This file contains definitions of external variables created by GKlib - -\date Started 3/27/2007 -\author George -\version\verbatim $Id: gk_externs.h 10711 2011-08-31 22:23:04Z karypis $ \endverbatim -*/ - -#ifndef _GK_EXTERNS_H_ -#define _GK_EXTERNS_H_ - - -/************************************************************************* -* Extern variable definition. Hopefully, the __thread makes them thread-safe. -**************************************************************************/ -#ifndef _GK_ERROR_C_ -/* declared in error.c */ -extern __thread int gk_cur_jbufs; -extern __thread jmp_buf gk_jbufs[]; -extern __thread jmp_buf gk_jbuf; - -#endif - -#endif diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..3455622 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,46 @@ +target_include_directories(GKlib_GKlib PUBLIC + "$" + "$" +) +# TODO: These headers should be moved to a folder structure +set(public_header_files + gk_arch.h + gk_defs.h + gk_externs.h + gk_getopt.h + gk_macros.h + gk_mkblas.h + gk_mkmemory.h + gk_mkpqueue.h + gk_mkpqueue2.h + gk_mkrandom.h + gk_mksort.h + gk_mkutils.h + gk_ms_inttypes.h + gk_ms_stat.h + gk_ms_stdint.h + gk_proto.h + gk_struct.h + gk_types.h + GKlib.h + gkregex.h +) +if (WIN32) + # TODO: This does not work because it would strip the path. Need to move to FILE_SET +# list(APPEND public_header_files +# win32/adapt.h +# ) + if (GKLIB_INSTALL) + install(FILES win32/adapt.h ${CMAKE_INSTALL_INCLUDEDIR}/win32) + endif () +endif () +# Prepend ${CMAKE_CURRENT_SOURCE_DIR} to all the header paths to be use in `PUBLIC_HEADER` property +set(public_headers) +foreach (header IN LISTS public_header_files) + list(APPEND public_headers ${CMAKE_CURRENT_SOURCE_DIR}/${header}) +endforeach () + +set_target_properties(GKlib_GKlib PROPERTIES + # TODO: Move to FILE_SET to properly install with paths + PUBLIC_HEADER "${public_headers}" +) diff --git a/GKlib.h b/include/GKlib.h similarity index 98% rename from GKlib.h rename to include/GKlib.h index 9278fe4..2548e66 100644 --- a/GKlib.h +++ b/include/GKlib.h @@ -55,7 +55,7 @@ -#if defined(__OPENMP__) +#if defined(_OPENMP) #include #endif diff --git a/gk_arch.h b/include/gk_arch.h similarity index 100% rename from gk_arch.h rename to include/gk_arch.h diff --git a/gk_defs.h b/include/gk_defs.h similarity index 100% rename from gk_defs.h rename to include/gk_defs.h diff --git a/include/gk_externs.h b/include/gk_externs.h new file mode 100644 index 0000000..8338217 --- /dev/null +++ b/include/gk_externs.h @@ -0,0 +1,35 @@ +/*! +\file gk_externs.h +\brief This file contains definitions of external variables created by GKlib + +\date Started 3/27/2007 +\author George +\version\verbatim $Id: gk_externs.h 10711 2011-08-31 22:23:04Z karypis $ \endverbatim +*/ + +#ifndef _GK_EXTERNS_H_ +#define _GK_EXTERNS_H_ + +// Windows does not support _Thread_local. Use appropriate aliases +// Reference: https://stackoverflow.com/a/18298965 +#ifndef thread_local +#if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ +#define thread_local _Thread_local +#elif defined _MSC_VER +#define thread_local __declspec(thread) +#elif defined __GNUC__ +#define thread_local __thread +#else +#error "Cannot define thread_local" +#endif +#endif + +#ifndef _GK_ERROR_C_ +/* declared in error.c */ +extern thread_local int gk_cur_jbufs; +extern thread_local jmp_buf gk_jbufs[]; +extern thread_local jmp_buf gk_jbuf; + +#endif + +#endif diff --git a/gk_getopt.h b/include/gk_getopt.h similarity index 100% rename from gk_getopt.h rename to include/gk_getopt.h diff --git a/gk_macros.h b/include/gk_macros.h similarity index 100% rename from gk_macros.h rename to include/gk_macros.h diff --git a/gk_mkblas.h b/include/gk_mkblas.h similarity index 100% rename from gk_mkblas.h rename to include/gk_mkblas.h diff --git a/gk_mkmemory.h b/include/gk_mkmemory.h similarity index 100% rename from gk_mkmemory.h rename to include/gk_mkmemory.h diff --git a/gk_mkpqueue.h b/include/gk_mkpqueue.h similarity index 100% rename from gk_mkpqueue.h rename to include/gk_mkpqueue.h diff --git a/gk_mkpqueue2.h b/include/gk_mkpqueue2.h similarity index 100% rename from gk_mkpqueue2.h rename to include/gk_mkpqueue2.h diff --git a/gk_mkrandom.h b/include/gk_mkrandom.h similarity index 100% rename from gk_mkrandom.h rename to include/gk_mkrandom.h diff --git a/gk_mksort.h b/include/gk_mksort.h similarity index 100% rename from gk_mksort.h rename to include/gk_mksort.h diff --git a/gk_mkutils.h b/include/gk_mkutils.h similarity index 100% rename from gk_mkutils.h rename to include/gk_mkutils.h diff --git a/gk_ms_inttypes.h b/include/gk_ms_inttypes.h similarity index 100% rename from gk_ms_inttypes.h rename to include/gk_ms_inttypes.h diff --git a/gk_ms_stat.h b/include/gk_ms_stat.h similarity index 100% rename from gk_ms_stat.h rename to include/gk_ms_stat.h diff --git a/gk_ms_stdint.h b/include/gk_ms_stdint.h similarity index 100% rename from gk_ms_stdint.h rename to include/gk_ms_stdint.h diff --git a/gk_proto.h b/include/gk_proto.h similarity index 99% rename from gk_proto.h rename to include/gk_proto.h index 6fd6bd4..aa943a5 100644 --- a/gk_proto.h +++ b/include/gk_proto.h @@ -292,7 +292,7 @@ uint32_t gk_randint32(void); /*------------------------------------------------------------- * OpenMP fake functions *-------------------------------------------------------------*/ -#if !defined(__OPENMP__) +#if !defined(_OPENMP) void omp_set_num_threads(int num_threads); int omp_get_num_threads(void); int omp_get_max_threads(void); @@ -303,7 +303,7 @@ void omp_set_dynamic(int num_threads); int omp_get_dynamic(void); void omp_set_nested(int nested); int omp_get_nested(void); -#endif /* __OPENMP__ */ +#endif /* _OPENMP */ /*------------------------------------------------------------- diff --git a/gk_struct.h b/include/gk_struct.h similarity index 100% rename from gk_struct.h rename to include/gk_struct.h diff --git a/gk_types.h b/include/gk_types.h similarity index 100% rename from gk_types.h rename to include/gk_types.h diff --git a/gkregex.h b/include/gkregex.h similarity index 100% rename from gkregex.h rename to include/gkregex.h diff --git a/win32/adapt.h b/include/win32/adapt.h similarity index 100% rename from win32/adapt.h rename to include/win32/adapt.h diff --git a/scripts/gexpand.pl b/scripts/gexpand.pl deleted file mode 100755 index 2b82134..0000000 --- a/scripts/gexpand.pl +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/perl -w - -die "Usage $0 \n" unless @ARGV == 2; - -$filein = shift(@ARGV); -$ncopies = shift(@ARGV); - -open(FPIN, "<$filein") or die "Could not open $filein. $!\n"; - -$_ = ; -chomp($_); -($nvtxs, $nedges) = split(' ', $_); - -#print "nvtxs: $nvtxs, nedges: $nedges\n"; - -$u = 1; -while () { - chomp($_); - @edges = split(' ', $_); - - # put the within layer edges - foreach $v (@edges) { - next if $v < $u; - for ($i=0; $i<$ncopies; $i++) { - printf("%d %d\n", $i*$nvtxs+$u-1, $i*$nvtxs+$v-1); - printf("%d %d\n", $i*$nvtxs+$v-1, $i*$nvtxs+$u-1); - } - } - - # put the vertex across layer edges - for ($i=0; $i<$ncopies-1; $i++) { - printf("%d %d\n", $i*$nvtxs+$u-1, ($i+1)*$nvtxs+$u-1); - printf("%d %d\n", ($i+1)*$nvtxs+$u-1, $i*$nvtxs+$u-1); - } - - # put the adjacent across layer edges - for ($i=0; $i<$ncopies-1; $i++) { - $j=0; - foreach $v (@edges) { - $j++; - next if (($j+$i)%2 == 0); - printf("%d %d\n", $i*$nvtxs+$u-1, ($i+1)*$nvtxs+$v-1); - printf("%d %d\n", ($i+1)*$nvtxs+$v-1, $i*$nvtxs+$u-1); - } - } - - goto DONE; - -DONE: - $u++; -} - -close(FPIN); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..54d8545 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,79 @@ +target_sources(GKlib_GKlib PRIVATE + b64.c + blas.c + cache.c + CMakeLists.txt + csr.c + error.c + evaluate.c + fkvkselect.c + fs.c + getopt.c + gk_util.c + gkregex.c + graph.c + htable.c + io.c + itemsets.c + mcore.c + memory.c + pqueue.c + random.c + rw.c + seq.c + sort.c + string.c + timers.c + tokenizer.c +) + +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckIncludeFile) +check_include_file(execinfo.h HAVE_EXECINFO_H) +check_symbol_exists(getline stdio.h HAVE_GETLINE) + +target_compile_definitions(GKlib_GKlib PUBLIC + # TODO: Use PCRE2 instead + # TODO: Missing link library to pcre anyway + $<$:__WITHPCRE__> + $<$:USE_GKREGEX> + $<$:USE_GKRAND> + PRIVATE + $<$:HAVE_EXECINFO_H> + $<$:HAVE_GETLINE> + # TODO: Remove as non-standard + $<$>:NO_X86> + $<$:NDEBUG> + $<$:NDEBUG2> +) +target_compile_options(GKlib_GKlib PRIVATE + $<$:-pg> +) + +check_function_exists(getline HAVE_GETLINE) +if (HAVE_GETLINE) + set(GKlib_COPTIONS "${GKlib_COPTIONS} -DHAVE_GETLINE") +endif (HAVE_GETLINE) + +if (WIN32) + add_subdirectory(win32) +endif () +find_library(MATH_LIBRARY m) +if (MATH_LIBRARY) + target_link_libraries(GKlib_GKlib PUBLIC ${MATH_LIBRARY}) +endif () +if (GKLIB_OpenMP) + target_link_libraries(GKlib_GKlib PUBLIC OpenMP::OpenMP_C) +endif () + +# Install +if (GKLIB_INSTALL) + install(TARGETS GKlib_GKlib + EXPORT GKlibTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT GKlib_Runtime NAMELINK_COMPONENT GKlib_Development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT GKlib_Development + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT GKlib_Development + RUNTIME DESTINATION ${CMAKE_INSTALL_RUNTIMEDIR} COMPONENT GKlib_Runtime + ) +endif () diff --git a/b64.c b/src/b64.c similarity index 100% rename from b64.c rename to src/b64.c diff --git a/blas.c b/src/blas.c similarity index 100% rename from blas.c rename to src/blas.c diff --git a/cache.c b/src/cache.c similarity index 100% rename from cache.c rename to src/cache.c diff --git a/csr.c b/src/csr.c similarity index 100% rename from csr.c rename to src/csr.c diff --git a/error.c b/src/error.c similarity index 92% rename from error.c rename to src/error.c index e2a18cf..e053537 100644 --- a/error.c +++ b/src/error.c @@ -19,17 +19,17 @@ This file contains functions dealing with error reporting and termination /* These are the jmp_buf for the graceful exit in case of severe errors. Multiple buffers are defined to allow for recursive invokation. */ #define MAX_JBUFS 128 -__thread int gk_cur_jbufs=-1; -__thread jmp_buf gk_jbufs[MAX_JBUFS]; -__thread jmp_buf gk_jbuf; +thread_local int gk_cur_jbufs=-1; +thread_local jmp_buf gk_jbufs[MAX_JBUFS]; +thread_local jmp_buf gk_jbuf; typedef void (*gksighandler_t)(int); /* These are the holders of the old singal handlers for the trapped signals */ -static __thread gksighandler_t old_SIGMEM_handler; /* Custom signal */ -static __thread gksighandler_t old_SIGERR_handler; /* Custom signal */ -static __thread gksighandler_t old_SIGMEM_handlers[MAX_JBUFS]; /* Custom signal */ -static __thread gksighandler_t old_SIGERR_handlers[MAX_JBUFS]; /* Custom signal */ +static thread_local gksighandler_t old_SIGMEM_handler; /* Custom signal */ +static thread_local gksighandler_t old_SIGERR_handler; /* Custom signal */ +static thread_local gksighandler_t old_SIGMEM_handlers[MAX_JBUFS]; /* Custom signal */ +static thread_local gksighandler_t old_SIGERR_handlers[MAX_JBUFS]; /* Custom signal */ /* The following is used to control if the gk_errexit() will actually abort or not. There is always a single copy of this variable */ @@ -178,7 +178,7 @@ char *gk_strerror(int errnum) return strerror(errnum); #else #ifndef SUNOS - static __thread char buf[1024]; + static thread_local char buf[1024]; strerror_r(errnum, buf, 1024); diff --git a/evaluate.c b/src/evaluate.c similarity index 100% rename from evaluate.c rename to src/evaluate.c diff --git a/fkvkselect.c b/src/fkvkselect.c similarity index 100% rename from fkvkselect.c rename to src/fkvkselect.c diff --git a/fs.c b/src/fs.c similarity index 100% rename from fs.c rename to src/fs.c diff --git a/getopt.c b/src/getopt.c similarity index 100% rename from getopt.c rename to src/getopt.c diff --git a/gk_util.c b/src/gk_util.c similarity index 100% rename from gk_util.c rename to src/gk_util.c diff --git a/gkregex.c b/src/gkregex.c similarity index 100% rename from gkregex.c rename to src/gkregex.c diff --git a/graph.c b/src/graph.c similarity index 100% rename from graph.c rename to src/graph.c diff --git a/htable.c b/src/htable.c similarity index 100% rename from htable.c rename to src/htable.c diff --git a/io.c b/src/io.c similarity index 100% rename from io.c rename to src/io.c diff --git a/itemsets.c b/src/itemsets.c similarity index 100% rename from itemsets.c rename to src/itemsets.c diff --git a/mcore.c b/src/mcore.c similarity index 100% rename from mcore.c rename to src/mcore.c diff --git a/memory.c b/src/memory.c similarity index 99% rename from memory.c rename to src/memory.c index e6dc99c..616436d 100644 --- a/memory.c +++ b/src/memory.c @@ -16,7 +16,7 @@ can be used to define other memory allocation routines. #include /* This is for the global mcore that tracks all heap allocations */ -static __thread gk_mcore_t *gkmcore = NULL; +static thread_local gk_mcore_t *gkmcore = NULL; /*************************************************************************/ diff --git a/pqueue.c b/src/pqueue.c similarity index 100% rename from pqueue.c rename to src/pqueue.c diff --git a/random.c b/src/random.c similarity index 100% rename from random.c rename to src/random.c diff --git a/rw.c b/src/rw.c similarity index 100% rename from rw.c rename to src/rw.c diff --git a/seq.c b/src/seq.c similarity index 100% rename from seq.c rename to src/seq.c diff --git a/sort.c b/src/sort.c similarity index 100% rename from sort.c rename to src/sort.c diff --git a/string.c b/src/string.c similarity index 100% rename from string.c rename to src/string.c diff --git a/timers.c b/src/timers.c similarity index 96% rename from timers.c rename to src/timers.c index bb8f296..3dc27cc 100644 --- a/timers.c +++ b/src/timers.c @@ -35,8 +35,7 @@ double gk_WClockSeconds(void) **************************************************************************/ double gk_CPUSeconds(void) { -//#ifdef __OPENMP__ -#ifdef __OPENMPXXXX__ +#ifdef _OPENMP return omp_get_wtime(); #else #if defined(WIN32) || defined(__MINGW32__) diff --git a/tokenizer.c b/src/tokenizer.c similarity index 100% rename from tokenizer.c rename to src/tokenizer.c diff --git a/src/win32/CMakeLists.txt b/src/win32/CMakeLists.txt new file mode 100644 index 0000000..48904b2 --- /dev/null +++ b/src/win32/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(GKlib_GKlib PRIVATE + adapt.c +) diff --git a/win32/adapt.c b/src/win32/adapt.c similarity index 85% rename from win32/adapt.c rename to src/win32/adapt.c index 546857c..d56f767 100644 --- a/win32/adapt.c +++ b/src/win32/adapt.c @@ -3,7 +3,7 @@ \brief Implementation of Win32 adaptation of libc functions */ -#include "adapt.h" +#include "win32/adapt.h" pid_t getpid(void) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8584820..3dd7375 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,19 +1,75 @@ -# Build program. -add_executable(strings strings.c) -add_executable(gksort gksort.c) -add_executable(fis fis.c) -add_executable(gkrw rw.c) -add_executable(gkgraph gkgraph.c) -add_executable(csrcnv csrcnv.c) -add_executable(grKx grKx.c) -add_executable(m2mnbrs m2mnbrs.c) -add_executable(cmpnbrs cmpnbrs.c) -add_executable(splatt2svd splatt2svd.c) -add_executable(gkuniq gkuniq.c) - -foreach(prog strings gksort fis gkrw gkgraph csrcnv grKx m2mnbrs cmpnbrs splatt2svd gkuniq) - target_link_libraries(${prog} GKlib) -endforeach(prog) - -# Install a subset of them -install(TARGETS csrcnv RUNTIME DESTINATION bin) +function(GKlib_add_test test) + #[===[.md + # GKlib_add_test + + Internal helper for adding GKlib tests + + ## Synopsis + ```cmake + GKlib_add_test( + [TEST_NAME ] + [TARGET ] + [LABELS ]) + ``` + + ## Options + + `` + Path to the CMake project to be executed relative to `${CMAKE_CURRENT_SOURCE_DIR}` + + `TEST_NAME` [Default: ``] + Name for the test to be used as the ctest name + + `LABELS` + Additional labels to be added + + ]===] + + list(APPEND CMAKE_MESSAGE_CONTEXT GKlib_add_test) + set(ARGS_Options) + set(ARGS_OneValue + TEST_NAME + ) + set(ARGS_MultiValue + LABELS + ) + cmake_parse_arguments(PARSE_ARGV 1 ARGS "${ARGS_Options}" "${ARGS_OneValue}" "${ARGS_MultiValue}") + # Check required/optional arguments + if (ARGC LESS 1) + message(FATAL_ERROR "Missing test name") + endif () + if (NOT DEFINED ARGS_TEST_NAME) + set(ARGS_TEST_NAME ${test}) + endif () + + add_test(NAME ${ARGS_TEST_NAME} + COMMAND ${CMAKE_CTEST_COMMAND} --build-and-test ${CMAKE_CURRENT_SOURCE_DIR}/${test} + ${CMAKE_CURRENT_BINARY_DIR}/${test} + --build-generator "${CMAKE_GENERATOR}" + --build-options -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + # Generated Config file point to binary targets until it is installed + -DFETCHCONTENT_TRY_FIND_PACKAGE_MODE=ALWAYS + -DGKlib_ROOT=${PROJECT_BINARY_DIR} + # TODO: Implement recursive ctest and remove --notests flag + --test-command ${CMAKE_CTEST_COMMAND} --test-dir ${CMAKE_CURRENT_BINARY_DIR}/${test} --no-tests=ignore + ) + set_tests_properties(${ARGS_TEST_NAME} PROPERTIES + LABELS "${ARGS_LABELS}" + ) +endfunction() + +foreach (test IN ITEMS + cmpnbrs + csrcnv + fis + gkgraph + gksort + gkuniq + grKx + m2mnbrs + rw + splatt2svd + strings +) + GKlib_add_test(${test}) +endforeach () diff --git a/test/cmpnbrs/CMakeLists.txt b/test/cmpnbrs/CMakeLists.txt new file mode 100644 index 0000000..3969d03 --- /dev/null +++ b/test/cmpnbrs/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(cmpnbrs + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(cmpnbrs cmpnbrs.c) +target_link_libraries(cmpnbrs PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/cmpnbrs.c b/test/cmpnbrs/cmpnbrs.c similarity index 100% rename from test/cmpnbrs.c rename to test/cmpnbrs/cmpnbrs.c diff --git a/test/csrcnv/CMakeLists.txt b/test/csrcnv/CMakeLists.txt new file mode 100644 index 0000000..fe20cd9 --- /dev/null +++ b/test/csrcnv/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(csrcnv + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(csrcnv csrcnv.c) +target_link_libraries(csrcnv PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/csrcnv.c b/test/csrcnv/csrcnv.c similarity index 100% rename from test/csrcnv.c rename to test/csrcnv/csrcnv.c diff --git a/test/fis/CMakeLists.txt b/test/fis/CMakeLists.txt new file mode 100644 index 0000000..88eb7c7 --- /dev/null +++ b/test/fis/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(fis + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(fis fis.c) +target_link_libraries(fis PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/fis.c b/test/fis/fis.c similarity index 100% rename from test/fis.c rename to test/fis/fis.c diff --git a/test/gkgraph/CMakeLists.txt b/test/gkgraph/CMakeLists.txt new file mode 100644 index 0000000..6f5f8a6 --- /dev/null +++ b/test/gkgraph/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(gkgraph + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(gkgraph gkgraph.c) +target_link_libraries(gkgraph PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/gkgraph.c b/test/gkgraph/gkgraph.c similarity index 100% rename from test/gkgraph.c rename to test/gkgraph/gkgraph.c diff --git a/test/gksort/CMakeLists.txt b/test/gksort/CMakeLists.txt new file mode 100644 index 0000000..dd4cd8d --- /dev/null +++ b/test/gksort/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(gksort + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(gksort gksort.c) +target_link_libraries(gksort PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/gksort.c b/test/gksort/gksort.c similarity index 100% rename from test/gksort.c rename to test/gksort/gksort.c diff --git a/test/gkuniq/CMakeLists.txt b/test/gkuniq/CMakeLists.txt new file mode 100644 index 0000000..a6881ee --- /dev/null +++ b/test/gkuniq/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(gkuniq + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(gkuniq gkuniq.c) +target_link_libraries(gkuniq PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/gkuniq.c b/test/gkuniq/gkuniq.c similarity index 100% rename from test/gkuniq.c rename to test/gkuniq/gkuniq.c diff --git a/test/grKx/CMakeLists.txt b/test/grKx/CMakeLists.txt new file mode 100644 index 0000000..5bf7487 --- /dev/null +++ b/test/grKx/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(grKx + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(grKx grKx.c) +target_link_libraries(grKx PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/grKx.c b/test/grKx/grKx.c similarity index 100% rename from test/grKx.c rename to test/grKx/grKx.c diff --git a/test/m2mnbrs/CMakeLists.txt b/test/m2mnbrs/CMakeLists.txt new file mode 100644 index 0000000..f9825d0 --- /dev/null +++ b/test/m2mnbrs/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(m2mnbrs + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(m2mnbrs m2mnbrs.c) +target_link_libraries(m2mnbrs PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/m2mnbrs.c b/test/m2mnbrs/m2mnbrs.c similarity index 100% rename from test/m2mnbrs.c rename to test/m2mnbrs/m2mnbrs.c diff --git a/test/rw/CMakeLists.txt b/test/rw/CMakeLists.txt new file mode 100644 index 0000000..cc30d06 --- /dev/null +++ b/test/rw/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(rw + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(rw rw.c) +target_link_libraries(rw PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/rw.c b/test/rw/rw.c similarity index 100% rename from test/rw.c rename to test/rw/rw.c diff --git a/test/splatt2svd/CMakeLists.txt b/test/splatt2svd/CMakeLists.txt new file mode 100644 index 0000000..b7fc3ec --- /dev/null +++ b/test/splatt2svd/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(splatt2svd + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(splatt2svd splatt2svd.c) +target_link_libraries(splatt2svd PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/splatt2svd.c b/test/splatt2svd/splatt2svd.c similarity index 100% rename from test/splatt2svd.c rename to test/splatt2svd/splatt2svd.c diff --git a/test/strings/CMakeLists.txt b/test/strings/CMakeLists.txt new file mode 100644 index 0000000..54cb65b --- /dev/null +++ b/test/strings/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.15) + +project(strings + LANGUAGES C +) + +include(FetchContent) +FetchContent_Declare(GKlib + GIT_REPOSITORY https://github.com/KarypisLab/GKlib + GIT_TAG master + FIND_PACKAGE_ARGS CONFIG +) +FetchContent_MakeAvailable(GKlib) + +add_executable(strings strings.c) +target_link_libraries(strings PRIVATE GKlib::GKlib) + +# TODO: Add ctest calling for each internal project +enable_testing() diff --git a/test/strings.c b/test/strings/strings.c similarity index 100% rename from test/strings.c rename to test/strings/strings.c