From 8be441e1b363f6287f4441d0cc775719d449cc6a Mon Sep 17 00:00:00 2001 From: huarkiou <46279300+huarkiou@users.noreply.github.com> Date: Wed, 1 May 2024 15:32:58 +0800 Subject: [PATCH] add windows support for "gnu-gsl" (#3924) * add Windows platform support for package gnu-gsl * remove usefulless comment * Update gnu-gsl to latest 2.7.1 * lowercase sha256 * change all sha256 string to lowercase * gnu-gsl only patch on windows * Rename CMakeLists.txt to cmakelists.txt * rename CMakeLists.txt to cmakelists.txt * move patches and cmakelists to sub-folders * Update xmake.lua --------- Co-authored-by: star9029 --- packages/g/gnu-gsl/cmake/cmakelists.txt | 86 ++++++++++ .../g/gnu-gsl/patches/add_fp_control.patch | 97 +++++++++++ packages/g/gnu-gsl/patches/configure.patch | 158 ++++++++++++++++++ packages/g/gnu-gsl/xmake.lua | 18 +- 4 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 packages/g/gnu-gsl/cmake/cmakelists.txt create mode 100644 packages/g/gnu-gsl/patches/add_fp_control.patch create mode 100644 packages/g/gnu-gsl/patches/configure.patch diff --git a/packages/g/gnu-gsl/cmake/cmakelists.txt b/packages/g/gnu-gsl/cmake/cmakelists.txt new file mode 100644 index 000000000..60559c00c --- /dev/null +++ b/packages/g/gnu-gsl/cmake/cmakelists.txt @@ -0,0 +1,86 @@ +cmake_minimum_required(VERSION 3.8) +project(gsl C) +include(GNUInstallDirs) +option(INSTALL_HEADERS "Install public header files" ON) + +# Function to extract parameter from makefile. Space separated values are returned as lists +function(extract_from_makefile PATTERN RETURN FILEPATH) + file(READ ${FILEPATH} MAKEFILE_CONTENT) + string(REGEX MATCH "${PATTERN}" CONTENTS "${MAKEFILE_CONTENT}") + set(CONTENTS ${CMAKE_MATCH_1}) + # Split string into list + string(REGEX REPLACE "([\t ]+(\\\\\n)?)+" ";" CONTENTS "${CONTENTS}") + string(REGEX REPLACE "[\t ]*\\\\\n[\t ]*;" "" CONTENTS "${CONTENTS}") + if("${CONTENTS}" STREQUAL "") + message(AUTHOR_WARNING "No match for \"${PATTERN}\" found in file ${FILEPATH}") + endif() + # Return + set(${RETURN} ${CONTENTS} PARENT_SCOPE) +endfunction(extract_from_makefile) + +# Function to extract C sources from makefile +function(extract_sources SUBFOLDER ALLSOURCES) + extract_from_makefile("lib[a-zA-Z1-9_]*_la_SOURCES[ \t]*=[ \t]*(((\\\\\n)?[^\n])*)" SOURCEFILES "${SUBFOLDER}/Makefile.am") + # Add the folder in front of the file names + string(REGEX REPLACE "([^;]+)" "${SUBFOLDER}/\\1" SOURCEFILES "${SOURCEFILES}") + # Return + set(${ALLSOURCES} ${${ALLSOURCES}} ${SOURCEFILES} PARENT_SCOPE) +endfunction(extract_sources) + +set(SOURCES) +set(CBLAS_SOURCES) +extract_from_makefile("SUBDIRS = (((\\\\\n)?[^\n])*)" FOLDERS "./Makefile.am") +extract_sources("." SOURCES) +foreach(DIR IN LISTS FOLDERS) + if("${DIR}" STREQUAL "cblas") + extract_sources("${DIR}" CBLAS_SOURCES) + else() + extract_sources("${DIR}" SOURCES) + endif() +endforeach() + +file(READ gsl_types.h GSLTYPES_H) +string(REPLACE "#ifdef WIN32" "#ifdef _WIN32" GSLTYPES_H "${GSLTYPES_H}") +if(BUILD_SHARED_LIBS) + string(REPLACE "# ifdef GSL_DLL" "# if 1 /*GSL_DLL*/" GSLTYPES_H "${GSLTYPES_H}") +endif() +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gsl_types.h "${GSLTYPES_H}") + +file(GLOB_RECURSE PUBLIC_HEADERS gsl*.h) +list(APPEND PUBLIC_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/gsl_types.h) + +# The debug libraries have a "d" postfix so that CMake's FindGSL.cmake +# module can distinguish between Release and Debug libraries +set(CMAKE_DEBUG_POSTFIX "d") + +add_library(gslcblas ${CBLAS_SOURCES}) +set_target_properties(gslcblas PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + +add_library(gsl ${SOURCES}) +set_target_properties(gsl PROPERTIES DEFINE_SYMBOL DLL_EXPORT WINDOWS_EXPORT_ALL_SYMBOLS ON) +target_link_libraries(gsl PUBLIC gslcblas) + + +if(INSTALL_HEADERS) + set_target_properties(gsl PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") +endif() +target_include_directories(gslcblas PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(gsl PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) +# For the build, we need to copy all headers to the gsl directory +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gsl) +file(COPY ${PUBLIC_HEADERS} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gsl") + +set(TARGET_INSTALL_OPTIONS) +if(INSTALL_HEADERS) + set(TARGET_INSTALL_OPTIONS PUBLIC_HEADER DESTINATION include/gsl) +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/gsl.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/gsl.pc" @ONLY) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/gsl.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + +install(TARGETS gsl gslcblas + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ${TARGET_INSTALL_OPTIONS} +) diff --git a/packages/g/gnu-gsl/patches/add_fp_control.patch b/packages/g/gnu-gsl/patches/add_fp_control.patch new file mode 100644 index 000000000..dceeb3881 --- /dev/null +++ b/packages/g/gnu-gsl/patches/add_fp_control.patch @@ -0,0 +1,97 @@ +--- + ieee-utils/fp-win.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + ieee-utils/fp.c | 2 ++ + 2 files changed, 72 insertions(+) + create mode 100644 ieee-utils/fp-win.c + +diff --git a/ieee-utils/fp-win.c b/ieee-utils/fp-win.c +new file mode 100644 +index 0000000..e024eae +--- /dev/null ++++ b/ieee-utils/fp-win.c +@@ -0,0 +1,70 @@ ++/* fp-win.c ++ * ++ * Author: Brian Gladman ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or (at ++ * your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++ ++const char *fp_env_string = "round-to-nearest,double-precision,mask-all"; ++ ++int ++gsl_ieee_set_mode (int precision, int rounding, int exception_mask) ++{ ++ unsigned int old, mode = _DN_SAVE, mask = _MCW_DN | _MCW_RC | _MCW_EM; ++ ++ switch(precision) ++ { ++ case GSL_IEEE_SINGLE_PRECISION: mode |= _PC_24; break; ++ case GSL_IEEE_EXTENDED_PRECISION: mode |= _PC_64; break; ++ case GSL_IEEE_DOUBLE_PRECISION: ++ default: mode |= _PC_53; ++ } ++#ifndef _M_AMD64 ++ mask |= _MCW_PC; ++#endif ++ ++ switch(rounding) ++ { ++ case GSL_IEEE_ROUND_DOWN: mode |= _RC_DOWN; break; ++ case GSL_IEEE_ROUND_UP: mode |= _RC_UP; break; ++ case GSL_IEEE_ROUND_TO_ZERO: mode |= _RC_CHOP; break; ++ case GSL_IEEE_ROUND_TO_NEAREST: ++ default: mode |= _RC_NEAR; ++ } ++ ++ if(exception_mask & GSL_IEEE_MASK_INVALID) ++ mode |= _EM_INVALID; ++ if(exception_mask & GSL_IEEE_MASK_DENORMALIZED) ++ mode |= _EM_DENORMAL; ++ if(exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) ++ mode |= _EM_ZERODIVIDE; ++ if(exception_mask & GSL_IEEE_MASK_OVERFLOW) ++ mode |= _EM_OVERFLOW; ++ if(exception_mask & GSL_IEEE_MASK_UNDERFLOW) ++ mode |= _EM_UNDERFLOW; ++ if(exception_mask & GSL_IEEE_TRAP_INEXACT) ++ mode &= ~_EM_INEXACT; ++ else ++ mode |= _EM_INEXACT; ++ ++ _controlfp_s( &old, mode, mask); ++ return GSL_SUCCESS; ++} +diff --git a/ieee-utils/fp.c b/ieee-utils/fp.c +index 445a14f..b6ae5af 100644 +--- a/ieee-utils/fp.c ++++ b/ieee-utils/fp.c +@@ -45,6 +45,8 @@ + #endif + #elif HAVE_DECL_FEENABLEEXCEPT || HAVE_DECL_FESETTRAPENABLE + #include "fp-gnuc99.c" ++#elif _MSC_VER ++#include "fp-win.c" + #else + #include "fp-unknown.c" + #endif +-- + diff --git a/packages/g/gnu-gsl/patches/configure.patch b/packages/g/gnu-gsl/patches/configure.patch new file mode 100644 index 000000000..404ae879b --- /dev/null +++ b/packages/g/gnu-gsl/patches/configure.patch @@ -0,0 +1,158 @@ +--- +diff --git a/config.h.in b/config.h +index adab7a58d..f6dc2278e 100644 +--- a/config.h.in ++++ b/config.h +@@ -11,19 +11,19 @@ + + /* Define to 1 if you have the declaration of `acosh', and to 0 if you don't. + */ +-#undef HAVE_DECL_ACOSH ++#define HAVE_DECL_ACOSH 1 + + /* Define to 1 if you have the declaration of `asinh', and to 0 if you don't. + */ +-#undef HAVE_DECL_ASINH ++#define HAVE_DECL_ASINH 1 + + /* Define to 1 if you have the declaration of `atanh', and to 0 if you don't. + */ +-#undef HAVE_DECL_ATANH ++#define HAVE_DECL_ATANH 1 + + /* Define to 1 if you have the declaration of `expm1', and to 0 if you don't. + */ +-#undef HAVE_DECL_EXPM1 ++#define HAVE_DECL_EXPM1 1 + + /* Define to 1 if you have the declaration of `feenableexcept', and to 0 if + you don't. */ +@@ -43,31 +43,31 @@ + + /* Define to 1 if you have the declaration of `frexp', and to 0 if you don't. + */ +-#undef HAVE_DECL_FREXP ++#define HAVE_DECL_FREXP 1 + + /* Define to 1 if you have the declaration of `hypot', and to 0 if you don't. + */ +-#undef HAVE_DECL_HYPOT ++#define HAVE_DECL_HYPOT 1 + + /* Define to 1 if you have the declaration of `isfinite', and to 0 if you + don't. */ +-#undef HAVE_DECL_ISFINITE ++#define HAVE_DECL_ISFINITE 1 + + /* Define to 1 if you have the declaration of `isinf', and to 0 if you don't. + */ +-#undef HAVE_DECL_ISINF ++#define HAVE_DECL_ISINF 1 + + /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't. + */ +-#undef HAVE_DECL_ISNAN ++#define HAVE_DECL_ISNAN 1 + + /* Define to 1 if you have the declaration of `ldexp', and to 0 if you don't. + */ +-#undef HAVE_DECL_LDEXP ++#define HAVE_DECL_LDEXP 1 + + /* Define to 1 if you have the declaration of `log1p', and to 0 if you don't. + */ +-#undef HAVE_DECL_LOG1P ++#define HAVE_DECL_LOG1P 1 + + /* Define to 1 if you have the header file. */ + #undef HAVE_DLFCN_H +@@ -76,13 +76,13 @@ + #undef HAVE_DOPRNT + + /* Defined if you have ansi EXIT_SUCCESS and EXIT_FAILURE in stdlib.h */ +-#undef HAVE_EXIT_SUCCESS_AND_FAILURE ++#define HAVE_EXIT_SUCCESS_AND_FAILURE 1 + + /* Defined on architectures with excess floating-point precision */ + #undef HAVE_EXTENDED_PRECISION_REGISTERS + + /* Define if x86 processor has sse extensions. */ +-#undef HAVE_FPU_X86_SSE ++#define HAVE_FPU_X86_SSE 1 + + /* Define to 1 if you have the header file. */ + #undef HAVE_IEEEFP_H +@@ -97,43 +97,43 @@ + #undef HAVE_INLINE + + /* Define to 1 if you have the header file. */ +-#undef HAVE_INTTYPES_H ++#define HAVE_INTTYPES_H 1 + + /* Define to 1 if you have the `m' library (-lm). */ + #undef HAVE_LIBM + + /* Define to 1 if you have the `memcpy' function. */ +-#undef HAVE_MEMCPY ++#define HAVE_MEMCPY 1 + + /* Define to 1 if you have the `memmove' function. */ +-#undef HAVE_MEMMOVE ++#define HAVE_MEMMOVE 1 + + /* Define this if printf can handle %Lf for long double */ + #undef HAVE_PRINTF_LONGDOUBLE + + /* Define to 1 if you have the header file. */ +-#undef HAVE_STDINT_H ++#define HAVE_STDINT_H 1 + + /* Define to 1 if you have the header file. */ +-#undef HAVE_STDIO_H ++#define HAVE_STDIO_H 1 + + /* Define to 1 if you have the header file. */ +-#undef HAVE_STDLIB_H ++#define HAVE_STDLIB_H 1 + + /* Define to 1 if you have the `strdup' function. */ +-#undef HAVE_STRDUP ++#define HAVE_STRDUP 1 + + /* Define to 1 if you have the header file. */ + #undef HAVE_STRINGS_H + + /* Define to 1 if you have the header file. */ +-#undef HAVE_STRING_H ++#define HAVE_STRING_H 1 + + /* Define to 1 if you have the `strtol' function. */ +-#undef HAVE_STRTOL ++#define HAVE_STRTOL 1 + + /* Define to 1 if you have the `strtoul' function. */ +-#undef HAVE_STRTOUL ++#define HAVE_STRTOUL 1 + + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_STAT_H +@@ -145,7 +145,7 @@ + #undef HAVE_UNISTD_H + + /* Define to 1 if you have the `vprintf' function. */ +-#undef HAVE_VPRINTF ++#define HAVE_VPRINTF 1 + + /* Define if you need to hide the static definitions of inline functions */ + #undef HIDE_INLINE_STATIC +@@ -180,7 +180,7 @@ + /* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +-#undef STDC_HEADERS ++#define STDC_HEADERS 1 + + /* Version number of package */ + #undef VERSION +--- + diff --git a/packages/g/gnu-gsl/xmake.lua b/packages/g/gnu-gsl/xmake.lua index f2eafbe54..b673ee96f 100644 --- a/packages/g/gnu-gsl/xmake.lua +++ b/packages/g/gnu-gsl/xmake.lua @@ -1,14 +1,21 @@ package("gnu-gsl") - set_homepage("https://www.gnu.org/software/gsl/") set_description("The GNU Scientific Library (GSL) is a numerical library for C and C++ programmers.") set_license("GPL-3.0") add_urls("https://ftpmirror.gnu.org/gsl/gsl-$(version).tar.gz", "https://ftp.gnu.org/gnu/gsl/gsl-$(version).tar.gz") + + add_versions("2.7.1", "dcb0fbd43048832b757ff9942691a8dd70026d5da0ff85601e52687f6deeb34b") add_versions("2.7", "efbbf3785da0e53038be7907500628b466152dbc3c173a87de1b5eba2e23602b") + if is_plat("windows") then + add_patches("2.7.x", path.join(os.scriptdir(), "patches", "configure.patch"), "50fe9e6a4e68750fa2e21febf05471423cc7a0a38e59cf41d5009cd79352b2e6") + add_patches("2.7.x", path.join(os.scriptdir(), "patches", "add_fp_control.patch"), "6c6782327126ea979c5aceab3ee022b5ddc7d9d01c244774294572e73427ec4b") + end + add_links("gsl", "gslcblas") + on_install("macosx", "linux", function (package) local configs = {"--disable-dependency-tracking"} table.insert(configs, "--enable-shared=" .. (package:config("shared") and "yes" or "no")) @@ -19,6 +26,15 @@ package("gnu-gsl") import("package.tools.autoconf").install(package, configs, {cppflags = cppflags, ldflags = ldflags}) end) + on_install("windows", function (package) + os.cp(path.join(os.scriptdir(), "cmake", "cmakelists.txt"), path.join(package:cachedir(), "source")) + local configs = {} + table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release")) + table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF")) + table.insert(configs, "-DCMAKE_POSITION_INDEPENDENT_CODE="..(package:config("pic") and "ON" or "OFF")) + import("package.tools.cmake").install(package, configs) + end) + on_test(function (package) assert(package:has_cfuncs("gsl_isnan", {includes = "gsl/gsl_math.h"})) end)