diff --git a/.github/workflows/ci-doxygen.yml b/.github/workflows/ci-doxygen.yml index e773b1737..5cf19d6c8 100644 --- a/.github/workflows/ci-doxygen.yml +++ b/.github/workflows/ci-doxygen.yml @@ -29,7 +29,7 @@ jobs: - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 actions-cache-folder: '.xmake-cache' - name: xmake repo --update diff --git a/.github/workflows/ci-xmake-linux.yml b/.github/workflows/ci-xmake-linux.yml index 0aefa0af5..73ac43ad6 100644 --- a/.github/workflows/ci-xmake-linux.yml +++ b/.github/workflows/ci-xmake-linux.yml @@ -39,7 +39,7 @@ jobs: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/.xmake-global" >> "${{ github.env }}" - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: xmake repo -u - uses: actions/checkout@v3 @@ -58,6 +58,8 @@ jobs: - name: build run: xmake build --yes -vD - name: test - run: xmake run --yes -vD --group=tests + run: | + xmake run --yes -vD --group=tests + xmake test -vD - name: benchmark run: xmake run --yes --group=bench diff --git a/.github/workflows/ci-xmake-macos.yml b/.github/workflows/ci-xmake-macos.yml index d370e942a..b80e10975 100644 --- a/.github/workflows/ci-xmake-macos.yml +++ b/.github/workflows/ci-xmake-macos.yml @@ -44,7 +44,7 @@ jobs: - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 actions-cache-folder: '.xmake-cache' - name: xmake repo --update @@ -63,6 +63,8 @@ jobs: - name: build run: xmake build --yes -vD - name: test - run: xmake run --yes -vD --diagnosis --group=tests + run: | + xmake run --yes -vD --group=tests + xmake test -vD - name: benchmark run: xmake run --yes --group=bench diff --git a/.github/workflows/ci-xmake-mingw.yml b/.github/workflows/ci-xmake-mingw.yml index 6cfb10e44..d1cb41fbc 100644 --- a/.github/workflows/ci-xmake-mingw.yml +++ b/.github/workflows/ci-xmake-mingw.yml @@ -39,7 +39,7 @@ jobs: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/.xmake-global" >> "${{ github.env }}" - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: xmake repo -u - uses: actions/checkout@v3 @@ -70,7 +70,7 @@ jobs: elvish-version: 0.19.2 - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: | xrepo update-repo diff --git a/.github/workflows/ci-xmake-wasm.yml b/.github/workflows/ci-xmake-wasm.yml index af2d3d4e3..6499ea4de 100644 --- a/.github/workflows/ci-xmake-wasm.yml +++ b/.github/workflows/ci-xmake-wasm.yml @@ -33,7 +33,7 @@ jobs: echo "XMAKE_GLOBALDIR=${{ runner.workspace }}/.xmake-global" >> "${{ github.env }}" - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: | xmake repo -u @@ -64,7 +64,7 @@ jobs: elvish-version: 0.19.2 - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: | xrepo update-repo diff --git a/.github/workflows/ci-xmake-windows.yml b/.github/workflows/ci-xmake-windows.yml index 518adf7a5..ef4e37ae1 100644 --- a/.github/workflows/ci-xmake-windows.yml +++ b/.github/workflows/ci-xmake-windows.yml @@ -34,7 +34,7 @@ jobs: steps: - uses: xmake-io/github-action-setup-xmake@v1 with: - xmake-version: v2.8.5 + xmake-version: v2.8.7 - name: update repo run: xmake repo -u - name: git crlf @@ -54,6 +54,8 @@ jobs: - name: build run: xmake build --yes -vD - name: test - run: xmake run --yes -vD --group=tests + run: | + xmake run --yes -vD --group=tests + xmake test -vD - name: benchmark run: xmake run --yes --group=bench diff --git a/lolly/system/shared_lib.cpp b/lolly/system/shared_lib.cpp new file mode 100644 index 000000000..8097352a5 --- /dev/null +++ b/lolly/system/shared_lib.cpp @@ -0,0 +1,34 @@ + +/** \file shared_lib.cpp + * \copyright GPLv3 + * \details dynamic (shared) library related routines + * \author jingkaimori + * \date 2024 + */ + +#include "shared_lib.hpp" + +#ifndef OS_WASM +namespace lolly { +namespace system { + +shared_lib_rep::shared_lib_rep (string dynamic_name, url path) + : dynamic_ref (tb_dynamic_init (c_string (as_system_string (path)))), + rep (dynamic_name) { + if (dynamic_ref == nullptr) { + TM_FAILED ("error occurs during loading of library") + } +}; +shared_lib_rep::~shared_lib_rep () { + tb_dynamic_exit (dynamic_ref); + shared_lib::instances->reset (res_name); +}; + +shared_lib +load_shared_library (string name, url path) { + return make (shared_lib, name, tm_new (name, path)); +} + +} // namespace system +} // namespace lolly +#endif diff --git a/lolly/system/shared_lib.hpp b/lolly/system/shared_lib.hpp new file mode 100644 index 000000000..7d1e0d390 --- /dev/null +++ b/lolly/system/shared_lib.hpp @@ -0,0 +1,41 @@ + +/** \file shared_lib.hpp + * \copyright GPLv3 + * \details dynamic (shared) library related routines + * \author jingkaimori + * \date 2024 + */ + +#pragma once + +#include "resource.hpp" +#include "url.hpp" +#include +#include + +#ifndef OS_WASM +namespace lolly { +namespace system { + +RESOURCE (shared_lib); + +struct shared_lib_rep : rep { +private: + tb_dynamic_ref_t dynamic_ref; + +public: + shared_lib_rep (string dynamic_name, url path); + virtual ~shared_lib_rep (); + template + auto get_function (string function_name) -> Ret (*) (Args...) { + return (Ret (*) (Args...)) tb_dynamic_func (dynamic_ref, + c_string (function_name)); + } + friend struct shared_lib; +}; + +shared_lib load_shared_library (string name, url path); + +} // namespace system +} // namespace lolly +#endif diff --git a/tests/lolly/system/example_dynamic_library.cpp b/tests/lolly/system/example_dynamic_library.cpp new file mode 100644 index 000000000..021ecb599 --- /dev/null +++ b/tests/lolly/system/example_dynamic_library.cpp @@ -0,0 +1,17 @@ + +/****************************************************************************** + * MODULE : example_dynamic_library.cpp + * DESCRIPTION: an example dynamic library for testing + * COPYRIGHT : (C) 2024 jingkaimori + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +extern "C" { +double +square_div_2 (int arg) { + return arg * arg / 2.0; +}; +} diff --git a/tests/lolly/system/shared_lib_test.cpp b/tests/lolly/system/shared_lib_test.cpp new file mode 100644 index 000000000..305970c72 --- /dev/null +++ b/tests/lolly/system/shared_lib_test.cpp @@ -0,0 +1,38 @@ + +/****************************************************************************** + * MODULE : shared_lib_test.cpp + * DESCRIPTION: tests on dynamic library loading + * COPYRIGHT : (C) 2024 jingkaimori + ******************************************************************************* + * This software falls under the GNU general public license version 3 or later. + * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE + * in the root directory or . + ******************************************************************************/ + +#include "a_lolly_test.hpp" +#include "lolly/system/shared_lib.hpp" +#include "sys_utils.hpp" + +#ifndef OS_WASM +using lolly::system::load_shared_library; +using lolly::system::shared_lib; +#endif + +TEST_CASE ("load_shared_library") { +#ifndef OS_WASM + url lib_path; + if (os_win ()) { + lib_path= url_pwd () * "example_dynamic_library.dll"; + } + else if (os_macos ()) { + lib_path= url_pwd () * "libexample_dynamic_library.dylib"; + } + else { + lib_path= url_pwd () * "libexample_dynamic_library.so"; + } + shared_lib lib= load_shared_library ("example_dynamic_library", lib_path); + double (*func) (int)= lib->get_function ("square_div_2"); + double res = func (5); + CHECK_EQ (res, 12.5); +#endif +} diff --git a/xmake.lua b/xmake.lua index a801c8d2d..40b7f5eda 100644 --- a/xmake.lua +++ b/xmake.lua @@ -358,6 +358,38 @@ function add_bench_target(filepath) end if has_config("enable_tests") then + target("example_dynamic_library") do + set_kind ("shared") + set_languages("c++17") + set_default (false) + add_files("tests/lolly/system/example_dynamic_library.cpp") + add_rules("utils.symbols.export_list", { + symbols = {"square_div_2"}}) + end + target("test_dynamic_library") do + set_kind ("binary") + set_languages("c++17") + set_default (false) + add_packages("tbox") + + add_deps("liblolly") + add_deps("example_dynamic_library", {inherit = false}) + + if is_plat("windows") then + set_encodings("utf-8") + add_ldflags("/LTCG") + add_syslinks("secur32", "shell32") + end + + add_includedirs(lolly_includedirs) + add_includedirs("tests") + add_forceincludes(path.absolute("$(buildir)/L1/config.h")) + add_tests("shared_lib_test", { + kind = "binary", + files = "$(projectdir)/tests/lolly/system/shared_lib_test.cpp", + packages = "doctest", + defines = "DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN"}) + end target("test_base")do set_kind("object") add_deps("liblolly") @@ -389,7 +421,7 @@ if has_config("enable_tests") then add_files("bench/nanobench.cpp") end - cpp_tests_on_all_plat = os.files("tests/**_test.cpp") + cpp_tests_on_all_plat = os.files("tests/**_test.cpp|**/shared_lib_test.cpp") for _, filepath in ipairs(cpp_tests_on_all_plat) do add_test_target (filepath) end