mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-15 18:14:08 +00:00
0e3f8cba8d
Next to `EXPORTED_FUNCTIONS` and avoid possible issues with pyodide in the future (pyodide is using `SIDE_MODULE=1`, but currently not providing it libraries of type `MODULE`, only for shared ones).
190 lines
8.8 KiB
CMake
190 lines
8.8 KiB
CMake
################################################################################
|
|
# #
|
|
# This file is part of IfcOpenShell. #
|
|
# #
|
|
# IfcOpenShell is free software: you can redistribute it and/or modify #
|
|
# it under the terms of the Lesser GNU General Public License as published by #
|
|
# the Free Software Foundation, either version 3.0 of the License, or #
|
|
# (at your option) any later version. #
|
|
# #
|
|
# IfcOpenShell 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 #
|
|
# Lesser GNU General Public License for more details. #
|
|
# #
|
|
# You should have received a copy of the Lesser GNU General Public License #
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
|
# #
|
|
################################################################################
|
|
|
|
if(POLICY CMP0148) # 3.27
|
|
cmake_policy(SET CMP0148 OLD)
|
|
endif()
|
|
if(POLICY CMP0177) # 3.31
|
|
cmake_policy(SET CMP0177 OLD)
|
|
endif()
|
|
|
|
FIND_PACKAGE(SWIG)
|
|
IF(NOT SWIG_FOUND)
|
|
MESSAGE(
|
|
FATAL_ERROR
|
|
"BUILD_IFCPYTHON enabled, but unable to find SWIG. Disable BUILD_IFCPYTHON or fix SWIG paths to proceed. "
|
|
"Likely SWIG_EXECUTABLE is missing (current value - '${SWIG_EXECUTABLE}')."
|
|
)
|
|
ENDIF()
|
|
include(GNUInstallDirs)
|
|
INCLUDE(${SWIG_USE_FILE})
|
|
|
|
IF(NOT "${PYTHON_INCLUDE_DIR}" STREQUAL "")
|
|
# Hint for FindPython where to find Python_INCLUDE_DIRS.
|
|
set(Python_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
|
|
MESSAGE(STATUS "Looking for Python header files in: ${Python_INCLUDE_DIR}")
|
|
ENDIF()
|
|
IF(NOT "${PYTHON_LIBRARY}" STREQUAL "")
|
|
# Hint for FindPython where to find Python_LIBRARIES.
|
|
set(Python_LIBRARY "${PYTHON_LIBRARY}")
|
|
MESSAGE(STATUS "Looking for Python library file in: ${Python_LIBRARY}")
|
|
ENDIF()
|
|
|
|
# NOTE PYTHONLIBS_FOUND and PYTHONINTERP_FOUND cannot seem to be trusted so
|
|
# we need further checks to see whether the packages were actually found or not.
|
|
FIND_PACKAGE(Python COMPONENTS Development)
|
|
IF(NOT Python_Development_FOUND)
|
|
MESSAGE(FATAL_ERROR "BUILD_IFCPYTHON enabled, but unable to find Python lib or header. Disable BUILD_IFCPYTHON or fix Python paths to proceed.")
|
|
ENDIF()
|
|
|
|
# Ensure version is saved here, from wasm libraries,
|
|
# not from Python interpreter that might be unrelated to pyodide Python version.
|
|
set(_python_libs_version "${Python_VERSION_MAJOR}${Python_VERSION_MINOR}")
|
|
INCLUDE_DIRECTORIES(${Python_INCLUDE_DIRS})
|
|
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
|
|
SET(CMAKE_SWIG_FLAGS ${SWIG_DEFINES})
|
|
# NOTE Workaround for most likely missing debug Python libraries on Windows (requires Python built from the source).
|
|
# Python 3.5 intaller and onwards will have an option to install the debug libraries too.
|
|
# NOTE PYTHON_DEBUG_LIBRARIES appears to be a deprecated variable
|
|
IF (WIN32 AND NOT PYTHON_DEBUG_LIBRARIES)
|
|
MESSAGE(STATUS "PYTHON_DEBUG_LIBRARIES not found, defining SWIG_PYTHON_INTERPRETER_NO_DEBUG workaround for IfcWrap.")
|
|
ADD_DEFINITIONS(-DSWIG_PYTHON_INTERPRETER_NO_DEBUG)
|
|
ENDIF()
|
|
|
|
if (WITH_CGAL)
|
|
set(LIBSVGFILL svgfill)
|
|
endif()
|
|
|
|
SET_SOURCE_FILES_PROPERTIES(IfcPython.i PROPERTIES CPLUSPLUS ON)
|
|
# Rebuild on changes in other .i files.
|
|
SET_PROPERTY(
|
|
SOURCE IfcPython.i
|
|
PROPERTY DEPENDS
|
|
IfcGeomWrapper.i
|
|
IfcParseWrapper.i
|
|
utils/type_conversion.i
|
|
utils/typemaps_in.i
|
|
utils/typemaps_out.i
|
|
)
|
|
|
|
# Debug build on Windows add required `_d` suffix to the resulting .pyd file.
|
|
# If we won't override -interface name,
|
|
# swig py wrapper will try to import `_ifcopenshell_wrapper_d` module and would fail.
|
|
set(SWIG_MODULE_ifcopenshell_wrapper_EXTRA_FLAGS "-interface" "_ifcopenshell_wrapper")
|
|
|
|
swig_add_library(ifcopenshell_wrapper LANGUAGE python SOURCES IfcPython.i)
|
|
SET_PROPERTY(TARGET ${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} PROPERTY SWIG_DEPENDS ${IFCOPENSHELL_LIBRARIES})
|
|
if (WASM_BUILD)
|
|
# SIDE_MODULE=1 - add to .so all symbols from linked archives (default used by pyodide).
|
|
# Since currently libIfcGeom.a seems to be linked twice it results in duplicated symbols and compilation errors.
|
|
# Possibly in the future we can clean up linked libs and try `=1`.
|
|
# SIDE_MODULE=2 - add to .so only explicitly exported functions (`-s EXPORTED_FUNCTIONS).
|
|
# Have to provide it here to override possible `=1` coming from pyodide.
|
|
target_link_options(
|
|
${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME}
|
|
PRIVATE "SHELL:-s EXPORTED_FUNCTIONS=_PyInit__ifcopenshell_wrapper -s SIDE_MODULE=2"
|
|
)
|
|
endif()
|
|
if("$ENV{LDFLAGS}" MATCHES ".undefined.suppress")
|
|
# On osx there is some state in the python dylib. With `-Wl,undefined,suppress` we can ignore the missing symbols at compile time.
|
|
SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${LIBSVGFILL})
|
|
else()
|
|
SWIG_LINK_LIBRARIES(ifcopenshell_wrapper ${IFCOPENSHELL_LIBRARIES} ${Python_LIBRARIES} ${LIBSVGFILL})
|
|
endif()
|
|
if ((NOT WIN32) AND BUILD_SHARED_LIBS)
|
|
SET_INSTALL_RPATHS(${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} "${IFCDIRS};${OCC_LIBRARY_DIR}")
|
|
endif()
|
|
|
|
# Try to find the Python interpreter to get the site-packages
|
|
# directory in which the wrapper can be installed.
|
|
if(NOT ${PYTHON_EXECUTABLE} STREQUAL "")
|
|
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
|
|
MESSAGE(STATUS "Looking for Python interpreter in: ${PYTHON_EXECUTABLE}")
|
|
endif()
|
|
FIND_PACKAGE(Python COMPONENTS Interpreter)
|
|
IF(Python_Interpreter_FOUND OR PYTHON_MODULE_INSTALL_DIR)
|
|
# Python_SOABI example value is 'cp311-win_amd64'.
|
|
if(WASM_BUILD)
|
|
# For WASM we usually don't provide interpreter,
|
|
# so `find_package` couldn't find `Python_SOABI`.
|
|
# So we just hardcode it.
|
|
# .cpython-313-wasm32-emscripten.so
|
|
set(PYTHON_EXTENSION_SUFFIX ".cpython-${_python_libs_version}-wasm32-emscripten.so")
|
|
elseif(WIN32)
|
|
set(PYTHON_EXTENSION_SUFFIX ".${Python_SOABI}.pyd")
|
|
else()
|
|
set(PYTHON_EXTENSION_SUFFIX ".${Python_SOABI}.so")
|
|
endif()
|
|
# On Windows there is '_d' prefix for debug builds - e.g. `_d.cp311-win_amd64.pyd`.
|
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
set_target_properties(
|
|
${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} PROPERTIES
|
|
SUFFIX ${PYTHON_EXTENSION_SUFFIX}
|
|
DEBUG_POSTFIX "_d"
|
|
)
|
|
else()
|
|
set_target_properties(
|
|
${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME} PROPERTIES
|
|
SUFFIX ${PYTHON_EXTENSION_SUFFIX}
|
|
)
|
|
endif()
|
|
|
|
if (PYTHON_MODULE_INSTALL_DIR)
|
|
set(python_package_dir "${PYTHON_MODULE_INSTALL_DIR}")
|
|
else()
|
|
IF (USERSPACE_PYTHON_PREFIX)
|
|
EXECUTE_PROCESS(
|
|
COMMAND ${PYTHON_EXECUTABLE} -c "import sys; import site; sys.stdout.write(site.USER_SITE)"
|
|
OUTPUT_VARIABLE python_package_dir
|
|
)
|
|
ELSE ()
|
|
set(python_package_dir "${Python_SITEARCH}")
|
|
ENDIF()
|
|
if (BUILD_PACKAGE)
|
|
set(python_package_dir ${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_MAJOR}/dist-packages/)
|
|
endif()
|
|
endif()
|
|
IF("${python_package_dir}" STREQUAL "")
|
|
MESSAGE(WARNING "Unable to locate Python site-package directory, unable to install the Python wrapper")
|
|
ELSE()
|
|
message(STATUS "Python wrapper will be installed to '${python_package_dir}'.")
|
|
FILE(GLOB_RECURSE sourcefiles
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/*"
|
|
)
|
|
FOREACH(file ${sourcefiles})
|
|
FILE(RELATIVE_PATH relative "${CMAKE_CURRENT_SOURCE_DIR}/../ifcopenshell-python/ifcopenshell/" "${file}")
|
|
GET_FILENAME_COMPONENT(dir "${relative}" DIRECTORY)
|
|
if(NOT IS_DIRECTORY "${file}")
|
|
INSTALL(FILES "${file}"
|
|
DESTINATION "${python_package_dir}/ifcopenshell/${dir}")
|
|
endif()
|
|
ENDFOREACH()
|
|
INSTALL(FILES "${CMAKE_BINARY_DIR}/ifcwrap/ifcopenshell_wrapper.py"
|
|
DESTINATION "${python_package_dir}/ifcopenshell")
|
|
INSTALL(TARGETS ${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME}
|
|
DESTINATION "${python_package_dir}/ifcopenshell")
|
|
if (MSVC)
|
|
INSTALL(FILES $<TARGET_PDB_FILE:${SWIG_MODULE_ifcopenshell_wrapper_REAL_NAME}> DESTINATION bin OPTIONAL)
|
|
endif()
|
|
ENDIF()
|
|
ELSE()
|
|
MESSAGE(WARNING "No Python interpreter found, unable to install the Python wrapper")
|
|
ENDIF()
|