cmake: fix issue #25048 have cmake fail when pivy and swig use different API versions, update status messages
This commit is contained in:
@@ -1,12 +1,160 @@
|
||||
macro(SetupSwig)
|
||||
# -------------------------------- Swig ----------------------------------
|
||||
|
||||
find_package(SWIG)
|
||||
#-------------------------------- Swig ----------------------------------
|
||||
|
||||
if (NOT SWIG_FOUND)
|
||||
message("=====================================================\n"
|
||||
"SWIG not found, will not build SWIG binding for pivy.\n"
|
||||
"=====================================================\n")
|
||||
endif(NOT SWIG_FOUND)
|
||||
# force cmake to re-search for SWIG when CMAKE_PREFIX_PATH changes
|
||||
unset(SWIG_EXECUTABLE CACHE)
|
||||
unset(SWIG_DIR CACHE)
|
||||
unset(SWIG_VERSION CACHE)
|
||||
unset(SWIG_FOUND CACHE)
|
||||
|
||||
endmacro(SetupSwig)
|
||||
if(BUILD_SKETCHER)
|
||||
# SWIG is required for sketcher WB (use QUIET to provide custom error message)
|
||||
find_package(SWIG QUIET)
|
||||
|
||||
if(NOT SWIG_FOUND)
|
||||
message(FATAL_ERROR
|
||||
"-----------------------------------------------------\n"
|
||||
"SWIG not found, swig & pivy required for sketcher WB.\n"
|
||||
"-----------------------------------------------------\n")
|
||||
# do not continue with check if swig not found
|
||||
return()
|
||||
endif()
|
||||
|
||||
# check swig/pivy runtime compatibility
|
||||
message(STATUS "checking SWIG/Pivy runtime compatibility...")
|
||||
|
||||
# get SWIG's runtime version using -external-runtime flag
|
||||
execute_process(
|
||||
COMMAND ${SWIG_EXECUTABLE} -python -external-runtime "${CMAKE_BINARY_DIR}/swig_runtime_check.h"
|
||||
RESULT_VARIABLE SWIG_EXTERNAL_RUNTIME_RESULT
|
||||
ERROR_VARIABLE SWIG_EXTERNAL_RUNTIME_ERROR
|
||||
ERROR_QUIET
|
||||
)
|
||||
# NOTE: only print the below output if using `cmake --log-level=DEBUG`
|
||||
message(DEBUG "SWIG external-runtime result: ${SWIG_EXTERNAL_RUNTIME_RESULT}")
|
||||
message(DEBUG "SWIG external-runtime error: ${SWIG_EXTERNAL_RUNTIME_ERROR}")
|
||||
|
||||
message(STATUS "Looking for: ${CMAKE_BINARY_DIR}/swig_runtime_check.h")
|
||||
if(EXISTS "${CMAKE_BINARY_DIR}/swig_runtime_check.h")
|
||||
message(STATUS "File exists: YES")
|
||||
else()
|
||||
message(STATUS "File exists: NO")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${CMAKE_BINARY_DIR}/swig_runtime_check.h")
|
||||
file(STRINGS "${CMAKE_BINARY_DIR}/swig_runtime_check.h"
|
||||
SWIG_RUNTIME_VERSION_LINE
|
||||
REGEX "^#define SWIG_RUNTIME_VERSION")
|
||||
|
||||
message(STATUS "SWIG_RUNTIME_VERSION_LINE: ${SWIG_RUNTIME_VERSION_LINE}")
|
||||
|
||||
if(SWIG_RUNTIME_VERSION_LINE)
|
||||
# extract the version number (it's in quotes: "5")
|
||||
string(REGEX MATCH "\"([0-9]+)\"" _ "${SWIG_RUNTIME_VERSION_LINE}")
|
||||
set(SWIG_RUNTIME_VERSION "${CMAKE_MATCH_1}")
|
||||
message(STATUS "Extracted SWIG_RUNTIME_VERSION: ${SWIG_RUNTIME_VERSION}")
|
||||
endif()
|
||||
|
||||
file(REMOVE "${CMAKE_BINARY_DIR}/swig_runtime_check.h")
|
||||
else()
|
||||
message(STATUS "swig_runtime_check.h not found!")
|
||||
endif()
|
||||
|
||||
# extract pivy's SWIG runtime version from the compiled module
|
||||
# NOTE: python code can not be indented
|
||||
set(PYTHON_CHECK_PIVY_RUNTIME [=[
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
try:
|
||||
import pivy
|
||||
pivy_dir = os.path.dirname(pivy.__file__)
|
||||
print(f'DEBUG:pivy_dir={pivy_dir}', file=sys.stderr)
|
||||
print(f'DEBUG:files={os.listdir(pivy_dir)}', file=sys.stderr)
|
||||
|
||||
pivy_path = None
|
||||
|
||||
# Look for _coin module with any extension (.so on Unix, .pyd on Windows)
|
||||
for f in os.listdir(pivy_dir):
|
||||
print(f'DEBUG:checking={f}', file=sys.stderr)
|
||||
if f.startswith('_coin') and (f.endswith('.so') or f.endswith('.pyd')):
|
||||
pivy_path = os.path.join(pivy_dir, f)
|
||||
break
|
||||
|
||||
print(f'DEBUG:pivy_path={pivy_path}', file=sys.stderr)
|
||||
|
||||
if pivy_path and os.path.exists(pivy_path):
|
||||
with open(pivy_path, 'rb') as f:
|
||||
content = f.read().decode('latin-1', errors='ignore')
|
||||
|
||||
print(f'DEBUG:content_len={len(content)}', file=sys.stderr)
|
||||
|
||||
# Use regex to find swig_runtime_data followed by a number
|
||||
match = re.search(r'swig_runtime_data(\d+)', content)
|
||||
print(f'DEBUG:match={match}', file=sys.stderr)
|
||||
if match:
|
||||
print(match.group(1))
|
||||
|
||||
except ImportError as e:
|
||||
print(f'DEBUG:import_error={e}', file=sys.stderr)
|
||||
print('ERROR_IMPORT')
|
||||
except Exception as e:
|
||||
print(f'DEBUG:exception={e}', file=sys.stderr)
|
||||
]=])
|
||||
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -c "${PYTHON_CHECK_PIVY_RUNTIME}"
|
||||
OUTPUT_VARIABLE PIVY_RUNTIME_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_VARIABLE PIVY_DEBUG_OUTPUT
|
||||
TIMEOUT 10
|
||||
)
|
||||
|
||||
message(DEBUG "Pivy debug output: ${PIVY_DEBUG_OUTPUT}")
|
||||
|
||||
# Handle errors and compare versions
|
||||
if(PIVY_RUNTIME_VERSION STREQUAL "ERROR_IMPORT")
|
||||
message(WARNING
|
||||
"Could not import pivy to check SWIG compatibility.\n"
|
||||
"Proceeding without SWIG version check."
|
||||
)
|
||||
elseif(SWIG_RUNTIME_VERSION AND PIVY_RUNTIME_VERSION)
|
||||
if(NOT SWIG_RUNTIME_VERSION STREQUAL PIVY_RUNTIME_VERSION)
|
||||
message(FATAL_ERROR
|
||||
" --------------------------------------------------------
|
||||
|
||||
SWIG / PIVY RUNTIME VERSION MISMATCH DETECTED!
|
||||
|
||||
SWIG runtime API version: ${SWIG_RUNTIME_VERSION}
|
||||
Pivy runtime API version: ${PIVY_RUNTIME_VERSION}
|
||||
|
||||
These must match for compatibility.
|
||||
This will cause runtime errors: 'No SWIG wrapped library loaded'
|
||||
|
||||
swig v4.4.x is not compatible with pivy built with swig <=4.3.x
|
||||
|
||||
FIX: Install a SWIG version that uses runtime ${PIVY_RUNTIME_VERSION}
|
||||
or rebuild Pivy with your current SWIG ${SWIG_VERSION}.
|
||||
|
||||
--------------------------------------------------------"
|
||||
)
|
||||
else()
|
||||
message(STATUS "SWIG/Pivy runtime compatibility: PASSED")
|
||||
message(STATUS "swig runtime API version: ${SWIG_RUNTIME_VERSION}")
|
||||
message(STATUS "pivy runtime API version: ${PIVY_RUNTIME_VERSION}")
|
||||
message(STATUS "swig binary version building freecad: ${SWIG_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
if(NOT SWIG_RUNTIME_VERSION)
|
||||
message(WARNING "Could not determine SWIG runtime version")
|
||||
endif()
|
||||
if(NOT PIVY_RUNTIME_VERSION)
|
||||
message(WARNING "Could not determine Pivy runtime version")
|
||||
endif()
|
||||
message(WARNING "Proceeding without SWIG/Pivy compatibility check.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
Reference in New Issue
Block a user