diff --git a/modules/modpython/CMakeLists.txt b/modules/modpython/CMakeLists.txt index e65cc860..7184f42f 100644 --- a/modules/modpython/CMakeLists.txt +++ b/modules/modpython/CMakeLists.txt @@ -29,6 +29,17 @@ if(APPLE) endif() if(SWIG_FOUND) + set(SWIG_VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/swig_version.h") + + add_custom_command( + OUTPUT "${SWIG_VERSION_HEADER}" + COMMAND ${CMAKE_COMMAND} + -DSWIG_EXECUTABLE=${SWIG_EXECUTABLE} + -DSWIG_VERSION_HEADER=${SWIG_VERSION_HEADER} + -P "${CMAKE_CURRENT_SOURCE_DIR}/generate_swig_version.cmake" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/generate_swig_version.cmake" + ) + add_custom_command( OUTPUT "pyfunctions.cpp" COMMAND "${PERL_EXECUTABLE}" @@ -36,7 +47,7 @@ if(SWIG_FOUND) "${CMAKE_CURRENT_SOURCE_DIR}/functions.in" "pyfunctions.cpp" VERBATIM - DEPENDS codegen.pl functions.in) + DEPENDS codegen.pl functions.in "${SWIG_VERSION_HEADER}") add_custom_command( OUTPUT "swigpyrun.h" @@ -98,7 +109,7 @@ endfunction() add_custom_target(modpython_dist COMMAND "${CMAKE_COMMAND}" -E tar cz "${CMAKE_CURRENT_SOURCE_DIR}/generated.tar.gz" - "swigpyrun.h" "znc_core.py" "modpython_biglib.cpp" "pyfunctions.cpp" - DEPENDS swigpyrun.h znc_core.py modpython_biglib.cpp pyfunctions.cpp + "swigpyrun.h" "znc_core.py" "modpython_biglib.cpp" "pyfunctions.cpp" "${SWIG_VERSION_HEADER}" + DEPENDS swigpyrun.h znc_core.py modpython_biglib.cpp pyfunctions.cpp "${SWIG_VERSION_HEADER}" VERBATIM) add_dependencies(modpython_dist copy_csocket_h) diff --git a/modules/modpython/codegen.pl b/modules/modpython/codegen.pl index 1f01dd81..bbd8e2d5 100755 --- a/modules/modpython/codegen.pl +++ b/modules/modpython/codegen.pl @@ -49,6 +49,8 @@ print $out <<'EOF'; * Don't change it manually. * ***************************************************************************/ +#include "swig_version.h" + namespace { inline swig_type_info* ZNC_SWIG_pchar_descriptor(void) { static int init = 0; @@ -60,11 +62,8 @@ namespace { return info; } -// SWIG 4.2.0 replaced SWIG_Python_str_AsChar with SWIG_PyUnicode_AsUTF8AndSize. -// SWIG doesn't provide any good way to detect SWIG version (other than parsing -// `swig -version`), but it also introduced SWIG_NULLPTR in 4.2.0. -// So let's abuse that define to do different code for new SWIG. -#ifdef SWIG_NULLPTR +// SWIG_VERSION is defined as 0x040200 for 4.2.0. +#if defined(SWIG_VERSION) && SWIG_VERSION >= 0x040200 // This is copied/adapted from SWIG 4.2.0 from pystrings.swg inline int ZNC_SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) { #if PY_VERSION_HEX>=0x03000000 diff --git a/modules/modpython/generate_swig_version.cmake b/modules/modpython/generate_swig_version.cmake new file mode 100644 index 00000000..2d52501c --- /dev/null +++ b/modules/modpython/generate_swig_version.cmake @@ -0,0 +1,53 @@ +# generate_swig_version.cmake +execute_process( + COMMAND ${SWIG_EXECUTABLE} -version + OUTPUT_VARIABLE SWIG_OUTPUT + ERROR_VARIABLE SWIG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE +) + +set(FULL_OUTPUT "${SWIG_OUTPUT}\n${SWIG_ERROR}") + +string(REGEX MATCH "SWIG Version ([0-9]+)\\.([0-9]+)\\.([0-9]+)" MATCH_FOUND "${FULL_OUTPUT}") + +if(MATCH_FOUND) + # Extract capture groups + set(SWIG_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(SWIG_VERSION_MINOR ${CMAKE_MATCH_2}) + set(SWIG_VERSION_PATCH ${CMAKE_MATCH_3}) + + message(STATUS "Found SWIG Version: ${SWIG_VERSION_MAJOR}.${SWIG_VERSION_MINOR}.${SWIG_VERSION_PATCH}") + + # Format: 0x (assuming 8 bits per component) + # Calculation: (Major << 16) | (Minor << 8) | Patch + + math(EXPR VERSION_NUM + "(${SWIG_VERSION_MAJOR} << 16) + (${SWIG_VERSION_MINOR} << 8) + ${SWIG_VERSION_PATCH}" + OUTPUT_FORMAT HEXADECIMAL + ) + + set(HEADER_FILE "swig_version.h") + + file(WRITE ${SWIG_VERSION_HEADER} +"// Auto-generated by CMake +#ifndef SWIG_VERSION_META_H +#define SWIG_VERSION_META_H + +#define SWIG_VERSION_MAJOR ${SWIG_VERSION_MAJOR} +#define SWIG_VERSION_MINOR ${SWIG_VERSION_MINOR} +#define SWIG_VERSION_PATCH ${SWIG_VERSION_PATCH} + +// Hex format 0xMAJMINPAT (e.g. 4.1.0 -> 0x40100) +#define SWIG_VERSION ${VERSION_NUM} + +#endif // SWIG_VERSION_META_H +" + ) + + message(STATUS "Generated ${HEADER_FILE} with version ${VERSION_NUM}") + +else() + message(WARNING "Could not parse SWIG version from output:\n${FULL_OUTPUT}") +endif() +