From 4983652ddf80dde30aa97333ae8ed3c83c70be5a Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sun, 4 Dec 2022 17:02:16 +0100 Subject: [PATCH] Added helper script for Linux and MinGW/Cygwin build. --- .gitignore | 1 + README.md | 23 +++++++++++++++++++++++ etc/utils/build-cygwin.sh | 22 ++++++++++++++++++++++ etc/utils/build-linux.sh | 22 ++++++++++++++++++++++ etc/utils/build-mingw.cmd | 9 +++++++++ test/hash-map/src/main.c | 11 +++++++---- test/hash-set/src/main.c | 11 +++++++---- test/shared/include/time_in.h | 3 ++- test/shared/src/time_in.c | 20 +++++++++++++++++--- 9 files changed, 110 insertions(+), 12 deletions(-) create mode 100755 etc/utils/build-cygwin.sh create mode 100755 etc/utils/build-linux.sh create mode 100644 etc/utils/build-mingw.cmd diff --git a/.gitignore b/.gitignore index a8a61ef..244517f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /**/lib /**/obj /.vs +/out diff --git a/README.md b/README.md index 71d0894..54520f9 100644 --- a/README.md +++ b/README.md @@ -868,6 +868,17 @@ LibHashSet is ***thread-safe***, in the sense that all public functions operate However, LibHashSet does **nothing** to synchronize access to a particular `hash_set_t` or `hash_map_t` instance! Consequently, in situations where the *same* instance needs to be shared across *multiple* concurrent threads, the calling application is responsible for serializing all access to the "shared" instance, e.g. by using a [*mutex*](https://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_lock.html) lock! +Source Codes +============ + +The "official" Git repository is mirrored at: + +* `git clone https://github.com/lordmulder/HashSet.git` ([Browse](https://github.com/lordmulder/HashSet)) + +* `git clone https://punkindrublic.mooo.com:3000/Muldersoft/LibHashSet.git` ([Browse](https://punkindrublic.mooo.com:3000/Muldersoft/LibHashSet)) + +* `git clone https://gitlab.com/lord_mulder/libhashset.git` ([Browse](https://gitlab.com/lord_mulder/libhashset)) + Build Instructions ================== @@ -888,6 +899,18 @@ On Linux or *BSD, building LibHashSet with *GCC* or *Clang* is recommended. Simply run `make` (or `gmake`, if on *BSD) from the project base directory. That's it! +### Influential environment variables + +The following environment variables can be used to control the build process: + +* `CC` – specifies the C compiler (default is `cc`) + +* `FLTO` – set to a non-zero value in order to enable *link-time optimizer* (`-flto`) + +* `DEBUG` – set to a non-zero value in order to enable "debug" build + +* `ASAN` – set to a non-zero value in order to enable the [address-sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer) + License ======= diff --git a/etc/utils/build-cygwin.sh b/etc/utils/build-cygwin.sh new file mode 100755 index 0000000..eebd50f --- /dev/null +++ b/etc/utils/build-cygwin.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." + +mkdir -pv "out/_next/include" +cp -rfv "libhashset/include/"*.h "out/_next/include" + +target="$(gcc -dumpmachine)" +echo -e "--------------------------------\n${target}\n--------------------------------" +make CC="gcc" clean +make CC="gcc" +rm -rf "out/_next/lib/${target}" "out/_next/bin/${target}" +mkdir -pv "out/_next/lib/${target}" "out/_next/bin/${target}" +cp -rv "libhashset/lib/"* "out/_next/lib/${target}" +for i in example test; do + for j in hash-set hash-map; do + cp -fv "${i}/${j}/bin/${i}-${j}.exe" "out/_next/bin/${target}" + done +done + +[ "$(uname -o | tr 'A-Z' 'a-z')" == "cygwin" ] && \ + cp -fv "$(which cygwin1.dll)" "out/_next/bin/${target}" || true diff --git a/etc/utils/build-linux.sh b/etc/utils/build-linux.sh new file mode 100755 index 0000000..2743e4b --- /dev/null +++ b/etc/utils/build-linux.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." + +rm -rf "out" +mkdir -pv "out/include" +cp -rfv "libhashset/include/"*.h "out/include" + +for target in i686 x86_64 arm64; do + compiler="/usr/local/musl/${target}/bin/musl-gcc" + target="$("${compiler}" -dumpmachine)" + echo -e "--------------------------------\n${target}\n--------------------------------" + make CC="${compiler}" clean + make CC="${compiler}" + mkdir -pv "out/lib/${target}" "out/bin/${target}" + cp -rv "libhashset/lib/"* "out/lib/${target}" + for i in example test; do + for j in hash-set hash-map; do + cp -fv "${i}/${j}/bin/${i}-${j}" "out/bin/${target}" + done + done +done diff --git a/etc/utils/build-mingw.cmd b/etc/utils/build-mingw.cmd new file mode 100644 index 0000000..9c8b0c5 --- /dev/null +++ b/etc/utils/build-mingw.cmd @@ -0,0 +1,9 @@ +@echo off +cd /d "%~dp0..\.." + +set "MSYS2_DIR=C:\msys64" + +call "%MSYS2_DIR%\msys2_shell.cmd" -mingw32 -no-start -defterm -where "%CD%" -c "./etc/utils/build-cygwin.sh" +call "%MSYS2_DIR%\msys2_shell.cmd" -mingw64 -no-start -defterm -where "%CD%" -c "./etc/utils/build-cygwin.sh" + +pause diff --git a/test/hash-map/src/main.c b/test/hash-map/src/main.c index 918abd4..30ead32 100644 --- a/test/hash-map/src/main.c +++ b/test/hash-map/src/main.c @@ -18,8 +18,6 @@ } \ while(0) -#define SEED ((uint32_t)clock_now()) - /* ========================================================================= */ /* MAIN */ /* ========================================================================= */ @@ -27,11 +25,14 @@ while(0) int main(void) { hash_map64_t *hash_set; + uint64_t clk_begin, clk_end; printf("LibHashSet Hash-Map Test v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n", HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE); - hash_set = hash_map_create64(0U, -1.0, SEED); + clk_begin = clock_query(); + + hash_set = hash_map_create64(0U, -1.0, clock_query()); if (!hash_set) { puts("Allocation has failed!"); @@ -44,7 +45,9 @@ int main(void) RUN_TEST_CASE(4); hash_map_destroy64(hash_set); - puts("Tests completed successfully."); + clk_end = clock_query(); + + printf("Tests completed successfully [%.2f].", (clk_end - clk_begin) / ((double)clock_frequency())); return EXIT_SUCCESS; failure: diff --git a/test/hash-set/src/main.c b/test/hash-set/src/main.c index 572ebc2..a243e27 100644 --- a/test/hash-set/src/main.c +++ b/test/hash-set/src/main.c @@ -18,8 +18,6 @@ } \ while(0) -#define SEED ((uint32_t)clock_now()) - /* ========================================================================= */ /* MAIN */ /* ========================================================================= */ @@ -27,11 +25,14 @@ while(0) int main(void) { hash_set64_t *hash_set; + uint64_t clk_begin, clk_end; printf("LibHashSet Hash-Set Test v%" PRIu16 ".%" PRIu16 ".%" PRIu16 " [%s]\n\n", HASHSET_VERSION_MAJOR, HASHSET_VERSION_MINOR, HASHSET_VERSION_PATCH, HASHSET_BUILD_DATE); - hash_set = hash_set_create64(0U, -1.0, SEED); + clk_begin = clock_query(); + + hash_set = hash_set_create64(0U, -1.0, clock_query()); if (!hash_set) { puts("Allocation has failed!"); @@ -44,7 +45,9 @@ int main(void) RUN_TEST_CASE(4); hash_set_destroy64(hash_set); - puts("Tests completed successfully."); + clk_end = clock_query(); + + printf("Tests completed successfully [%.2f].", (clk_end - clk_begin) / ((double)clock_frequency())); return EXIT_SUCCESS; failure: diff --git a/test/shared/include/time_in.h b/test/shared/include/time_in.h index 7707726..639dca0 100644 --- a/test/shared/include/time_in.h +++ b/test/shared/include/time_in.h @@ -9,6 +9,7 @@ #include #include -uint64_t clock_now(void); +uint64_t clock_query(void); +uint64_t clock_frequency(void); #endif /*_TEST_TIME_INCLUDED*/ diff --git a/test/shared/src/time_in.c b/test/shared/src/time_in.c index 971d55b..6c9d276 100644 --- a/test/shared/src/time_in.c +++ b/test/shared/src/time_in.c @@ -12,7 +12,7 @@ # include #endif -uint64_t clock_now(void) +uint64_t clock_query(void) { #ifdef _WIN32 LARGE_INTEGER counter; @@ -24,8 +24,22 @@ uint64_t clock_now(void) struct timespec spec; if (!clock_gettime(CLOCK_MONOTONIC, &spec)) { - return (((uint64_t)spec.tv_sec) << 32) | (((uint64_t)spec.tv_nsec) & UINT64_C(0xFFFFFFFF)); + return (((uint64_t)spec.tv_sec) * UINT64_C(1000000)) + (((uint64_t)spec.tv_nsec) / UINT64_C(10000)); } #endif - return 0U; + abort(); +} + +uint64_t clock_frequency(void) +{ +#ifdef _WIN32 + LARGE_INTEGER frequency; + if (QueryPerformanceFrequency(&frequency)) + { + return frequency.QuadPart; + } + abort(); +#else + return UINT64_C(1000000); +#endif }