diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a3514f9..687291a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,12 +1,6 @@ name: Build/test suite -on: - push: - branches: - mainline - pull_request: - branches: - mainline +on: push jobs: build: @@ -37,13 +31,20 @@ jobs: brew install mpfr catch2 eigen - name: CMake configure and build - uses: threeal/cmake-action@v2.0.0 + uses: threeal/cmake-action@v2.1.0 with: options: | - XPREC_BUILD_TESTING=${{ startsWith(matrix.os, 'windows') && 'OFF' || 'ON' }} + XPREC_BUILD_TESTING='ON' + CMAKE_VERBOSE_MAKEFILE='ON' run-build: true - - name: Run tests - if: (!startsWith(matrix.os, 'windows')) + # XXX this is a hack to allow CMake to find the library + - name: Move DLL to build directory + if: startsWith(matrix.os, 'windows') run: | - build/test/tests + copy build\\Debug\\xprec.dll build\\test + + - name: Run unit tests + uses: threeal/ctest-action@v1.1.0 + with: + verbose: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 469f716..faf18b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,16 @@ add_library(xprec SHARED if(NOT MSVC) target_compile_options(xprec PRIVATE -Wall -Wextra -pedantic) endif() +if (MSVC) + cmake_minimum_required(VERSION 3.11..3.31) + target_compile_definitions(xprec PRIVATE + "XPREC_API_EXPORT=__declspec(dllexport)" + ) + target_compile_definitions(xprec INTERFACE + "XPREC_API_EXPORT=__declspec(dllimport)" + ) +endif() + target_include_directories(xprec PUBLIC $ $ diff --git a/include/xprec/ddouble-header-only.hpp b/include/xprec/ddouble-header-only.hpp index ca25d30..a0acef5 100644 --- a/include/xprec/ddouble-header-only.hpp +++ b/include/xprec/ddouble-header-only.hpp @@ -14,7 +14,8 @@ // The strategy for header only use of ddouble is pretty simple: // conditionally inline globally defined functions and include the cxx files // directly. -#define XPREC_API_EXPORT inline +#undef XPREC_API_EXPORT +#define XPREC_API_EXPORT static #include "../../src/circular.cpp" #include "../../src/exp.cpp" diff --git a/include/xprec/ddouble.hpp b/include/xprec/ddouble.hpp index 736323c..d20c024 100644 --- a/include/xprec/ddouble.hpp +++ b/include/xprec/ddouble.hpp @@ -147,8 +147,6 @@ class DDouble { friend void swap(DDouble &x, DDouble &y); - friend std::ostream &operator<<(std::ostream &out, DDouble x); - private: double _hi; double _lo; @@ -236,38 +234,39 @@ class PowerOfTwo { // "using std::sin" and then call "sin". DDouble abs(DDouble a); -DDouble acos(DDouble a); -DDouble acosh(DDouble a); -DDouble asin(DDouble a); -DDouble asinh(DDouble a); -DDouble atan(DDouble a); -DDouble atan2(DDouble a, DDouble b); -DDouble atanh(DDouble a); DDouble ceil(DDouble a); -DDouble cos(DDouble a); -DDouble cosh(DDouble a); -DDouble exp(DDouble a); -DDouble expm1(DDouble a); DDouble fabs(DDouble a); DDouble fmax(DDouble a, DDouble b); DDouble fmin(DDouble a, DDouble b); DDouble floor(DDouble a); -DDouble hypot(DDouble a, DDouble b); DDouble ldexp(DDouble a, int m); -DDouble log(DDouble a); -DDouble log1p(DDouble a); DDouble logb(DDouble a); -DDouble modf(DDouble a, DDouble *b); -DDouble nextafter(DDouble a, DDouble b); -DDouble pow(DDouble a, DDouble b); -DDouble pow(DDouble a, int b); DDouble round(DDouble a); DDouble scalbn(DDouble a, int m); -DDouble sin(DDouble a); -DDouble sinh(DDouble a); -DDouble sqrt(DDouble a); -DDouble tan(DDouble a); -DDouble tanh(DDouble a); + +XPREC_API_EXPORT DDouble acos(DDouble a); +XPREC_API_EXPORT DDouble acosh(DDouble a); +XPREC_API_EXPORT DDouble asin(DDouble a); +XPREC_API_EXPORT DDouble asinh(DDouble a); +XPREC_API_EXPORT DDouble atan(DDouble a); +XPREC_API_EXPORT DDouble atan2(DDouble a, DDouble b); +XPREC_API_EXPORT DDouble atanh(DDouble a); +XPREC_API_EXPORT DDouble cos(DDouble a); +XPREC_API_EXPORT DDouble cosh(DDouble a); +XPREC_API_EXPORT DDouble exp(DDouble a); +XPREC_API_EXPORT DDouble expm1(DDouble a); +XPREC_API_EXPORT DDouble hypot(DDouble a, DDouble b); +XPREC_API_EXPORT DDouble log(DDouble a); +XPREC_API_EXPORT DDouble log1p(DDouble a); +XPREC_API_EXPORT DDouble modf(DDouble a, DDouble *b); +XPREC_API_EXPORT DDouble nextafter(DDouble a, DDouble b); +XPREC_API_EXPORT DDouble pow(DDouble a, DDouble b); +XPREC_API_EXPORT DDouble pow(DDouble a, int b); +XPREC_API_EXPORT DDouble sin(DDouble a); +XPREC_API_EXPORT DDouble sinh(DDouble a); +XPREC_API_EXPORT DDouble sqrt(DDouble a); +XPREC_API_EXPORT DDouble tan(DDouble a); +XPREC_API_EXPORT DDouble tanh(DDouble a); int fpclassify(DDouble x); int ilogb(DDouble x); @@ -277,6 +276,9 @@ bool isnan(DDouble x); bool isnormal(DDouble x); bool iszero(DDouble x); +XPREC_API_EXPORT std::ostream &operator<<(std::ostream &out, DDouble x); + + /** * Gauss-Chebyshev quadrature rule. * @@ -285,7 +287,7 @@ bool iszero(DDouble x); * the n-th Chebyshev polynomial. If w is given, store the quadrature weights * there. */ -void gauss_chebyshev(int n, DDouble x[], DDouble w[] = nullptr); +XPREC_API_EXPORT void gauss_chebyshev(int n, DDouble x[], DDouble w[] = nullptr); /** * Gauss-Legendre quadrature rule. @@ -294,10 +296,10 @@ void gauss_chebyshev(int n, DDouble x[], DDouble w[] = nullptr); * the Gauss-Legendre quadrature nodes of order n, i.e., the roots of the n-th * Legendre polynomial. If w is given, store the quadrature weights there. */ -void gauss_legendre(int n, DDouble x[], DDouble w[] = nullptr); +XPREC_API_EXPORT void gauss_legendre(int n, DDouble x[], DDouble w[] = nullptr); /** Trigonometric complement sqrt(1 - x*x) to full precision. */ -DDouble trig_complement(DDouble x); +XPREC_API_EXPORT DDouble trig_complement(DDouble x); } /* namespace xprec*/ diff --git a/include/xprec/version.h b/include/xprec/version.h index e2b1544..ebe3be5 100644 --- a/include/xprec/version.h +++ b/include/xprec/version.h @@ -7,3 +7,7 @@ #define XPREC_VERSION_MAJOR 0 #define XPREC_VERSION_MINOR 6 #define XPREC_VERSION_PATCH 0 + +#ifndef XPREC_API_EXPORT +#define XPREC_API_EXPORT +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 95b0fbf..fa97066 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,33 +15,42 @@ FetchContent_Declare( FetchContent_MakeAvailable(Catch2) # MPFR is required for tests -find_package(MPFR REQUIRED) +find_package(MPFR) find_package(Eigen3 3.3) add_executable(tests - arith.cpp - circular.cpp convert.cpp - exp.cpp gauss.cpp - hyperbolic.cpp inline.cpp limits.cpp - mpfloat.cpp random.cpp round.cpp - sqrt.cpp ) -target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) -target_link_libraries(tests PRIVATE MPFR::MPFR) -target_link_libraries(tests PRIVATE XPrec::xprec) -target_compile_options(tests PRIVATE -Wall -Wextra) +if (TARGET MPFR::MPFR) + target_sources(tests PRIVATE + arith.cpp + circular.cpp + exp.cpp + hyperbolic.cpp + mpfloat.cpp + sqrt.cpp + ) + target_link_libraries(tests PRIVATE MPFR::MPFR) +endif() if (TARGET Eigen3::Eigen) target_sources(tests PRIVATE eigen.cpp) target_link_libraries(tests PRIVATE Eigen3::Eigen) endif() +target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) +target_link_libraries(tests PRIVATE XPrec::xprec) + +if (NOT MSVC) + target_compile_options(tests PRIVATE -Wall -Wextra) +endif() + + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.12") set_property(TARGET tests PROPERTY CXX_STANDARD 20) else()