aboutsummaryrefslogtreecommitdiffstats
path: root/examples/samplebinding/CMakeLists.txt
diff options
context:
space:
mode:
Diffstat (limited to 'examples/samplebinding/CMakeLists.txt')
-rw-r--r--examples/samplebinding/CMakeLists.txt233
1 files changed, 233 insertions, 0 deletions
diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt
new file mode 100644
index 000000000..03ab85754
--- /dev/null
+++ b/examples/samplebinding/CMakeLists.txt
@@ -0,0 +1,233 @@
+cmake_minimum_required(VERSION 3.1)
+cmake_policy(VERSION 3.1)
+
+# Enable policy to not use RPATH settings for install_name on macOS.
+if(POLICY CMP0068)
+ cmake_policy(SET CMP0068 NEW)
+endif()
+
+# Consider changing the project name to something relevant for you.
+project(SampleBinding)
+
+# ================================ General configuration ======================================
+
+# Set CPP standard to C++11 minimum.
+set(CMAKE_CXX_STANDARD 11)
+
+# The sample library for which we will create bindings. You can change the name to something
+# relevant for your project.
+set(sample_library "libuniverse")
+
+# The name of the generated bindings module (as imported in Python). You can change the name
+# to something relevant for your project.
+set(bindings_library "Universe")
+
+# The header file with all the types and functions for which bindings will be generated.
+# Usually it simply includes other headers of the library you are creating bindings for.
+set(wrapped_header ${CMAKE_SOURCE_DIR}/bindings.h)
+
+# The typesystem xml file which defines the relationships between the C++ types / functions
+# and the corresponding Python equivalents.
+set(typesystem_file ${CMAKE_SOURCE_DIR}/bindings.xml)
+
+# Specify which C++ files will be generated by shiboken. This includes the module wrapper
+# and a '.cpp' file per C++ type. These are needed for generating the module shared
+# library.
+set(generated_sources
+ ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/universe_module_wrapper.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/icecream_wrapper.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/truck_wrapper.cpp)
+
+
+# ================================== Shiboken detection ======================================
+
+
+# Macro to get various pyside / python include / link flags and paths.
+# Uses the not entirely supported utils/pyside2_config.py file.
+macro(pyside2_config option output_var)
+ if(${ARGC} GREATER 2)
+ set(is_list ${ARGV2})
+ else()
+ set(is_list "")
+ endif()
+
+ execute_process(
+ COMMAND python "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" ${option}
+ OUTPUT_VARIABLE ${output_var}
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if ("${${output_var}}" STREQUAL "")
+ message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.")
+ endif()
+ if(is_list)
+ string (REPLACE " " ";" ${output_var} "${${output_var}}")
+ endif()
+endmacro()
+
+# Query for the shiboken path, Python path, include paths and linker flags.
+pyside2_config(--pyside2 pyside2_path)
+pyside2_config(--python-include python_include_dir)
+pyside2_config(--shiboken-include shiboken_include_dir 1)
+pyside2_config(--shiboken-shared-libraries-cmake shiboken_shared_libraries 0)
+pyside2_config(--python-link-cmake python_linking_data 0)
+
+set(shiboken_path "${pyside2_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}")
+if(NOT EXISTS ${shiboken_path})
+ message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}")
+endif()
+
+
+# ==================================== RPATH configuration ====================================
+
+
+# =============================================================================================
+# !!! (The section below is deployment related, so in a real world application you will want to
+# take care of this properly with some custom script or tool).
+# =============================================================================================
+# Enable rpaths so that the built shared libraries find their dependencies.
+set(CMAKE_SKIP_BUILD_RPATH FALSE)
+set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+set(CMAKE_INSTALL_RPATH ${pyside2_path} ${CMAKE_CURRENT_SOURCE_DIR})
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+# =============================================================================================
+# !!! End of dubious section.
+# =============================================================================================
+
+
+# =============================== CMake target - sample_library ===============================
+
+
+# Define the sample shared library for which we will create bindings.
+set(${sample_library}_sources icecream.cpp truck.cpp)
+add_library(${sample_library} SHARED ${${sample_library}_sources})
+set_property(TARGET ${sample_library} PROPERTY PREFIX "")
+
+# Needed mostly on Windows to export symbols, and create a .lib file, otherwise the binding
+# library can't link to the sample library.
+target_compile_definitions(${sample_library} PRIVATE BINDINGS_BUILD)
+
+
+# ====================== Shiboken target for generating binding C++ files ====================
+
+
+# Set up the options to pass to shiboken.
+set(shiboken_options --generator-set=shiboken --enable-parent-ctor-heuristic
+ --enable-return-value-heuristic --use-isnull-as-nb_nonzero
+ --avoid-protected-hack
+ -I${CMAKE_SOURCE_DIR}
+ -T${CMAKE_SOURCE_DIR}
+ --output-directory=${CMAKE_CURRENT_BINARY_DIR}
+ )
+
+set(generated_sources_dependencies ${wrapped_header} ${typesystem_file})
+
+# Add custom target to run shiboken to generate the binding cpp files.
+add_custom_command(OUTPUT ${generated_sources}
+ COMMAND ${shiboken_path}
+ ${shiboken_options} ${wrapped_header} ${typesystem_file}
+ DEPENDS ${generated_sources_dependencies}
+ IMPLICIT_DEPENDS CXX ${wrapped_header}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Running generator for ${typesystem_file}.")
+
+
+# =============================== CMake target - bindings_library =============================
+
+
+# Set the cpp files which will be used for the bindings library.
+set(${bindings_library}_sources ${generated_sources})
+
+# Define and build the bindings library.
+add_library(${bindings_library} MODULE ${${bindings_library}_sources})
+
+# Apply relevant include and link flags.
+target_include_directories(${bindings_library} PRIVATE ${python_include_dir})
+target_include_directories(${bindings_library} PRIVATE ${shiboken_include_dir})
+target_include_directories(${bindings_library} PRIVATE ${CMAKE_SOURCE_DIR})
+
+target_link_libraries(${bindings_library} PRIVATE ${shiboken_shared_libraries})
+target_link_libraries(${bindings_library} PRIVATE ${sample_library})
+
+# Adjust the name of generated module.
+set_property(TARGET ${bindings_library} PROPERTY PREFIX "")
+set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME
+ "${bindings_library}${PYTHON_EXTENSION_SUFFIX}")
+if(WIN32)
+ set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd")
+endif()
+
+# Make sure the linker doesn't complain about not finding Python symbols on macOS.
+if(APPLE)
+ set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
+endif(APPLE)
+
+# Find and link to the python import library only on Windows.
+# On Linux and macOS, the undefined symbols will get resolved by the dynamic linker
+# (the symbols will be picked up in the Python executable).
+if (WIN32)
+ list(GET python_linking_data 0 python_libdir)
+ list(GET python_linking_data 1 python_lib)
+ find_library(python_link_flags ${python_lib} PATHS ${python_libdir} HINTS ${python_libdir})
+ target_link_libraries(${bindings_library} PRIVATE ${python_link_flags})
+endif()
+
+
+# ================================= Dubious deployment section ================================
+
+
+if(WIN32)
+ # =========================================================================================
+ # !!! (The section below is deployment related, so in a real world application you will
+ # want to take care of this properly (this is simply to eliminate errors that users usually
+ # encounter.
+ # =========================================================================================
+ # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link
+ # against a wrong python shared library.
+
+ set(python_versions_list 3 32 33 34 35 36 37 38)
+ set(python_additional_link_flags "")
+ foreach(ver ${python_versions_list})
+ set(python_additional_link_flags
+ "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}_d.lib\"")
+ set(python_additional_link_flags
+ "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}.lib\"")
+ endforeach()
+
+ set_target_properties(${bindings_library}
+ PROPERTIES LINK_FLAGS "${python_additional_link_flags}")
+
+ # Add custom target to hard-link shiboken shared libraries into the build folder, so that
+ # the user doesn't have to set the PATH manually to point to the PySide2 package.
+ foreach(library_path ${shiboken_shared_libraries})
+ string(REGEX REPLACE ".lib$" ".dll" library_path ${library_path})
+ get_filename_component(base_name ${library_path} NAME)
+ file(TO_NATIVE_PATH ${library_path} source_path)
+ file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${base_name}" dest_path)
+ add_custom_command(OUTPUT "${base_name}"
+ COMMAND mklink /H "${dest_path}" "${source_path}"
+ DEPENDS ${library_path}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Creating hardlink to shiboken shared library ${base_name}")
+
+ # Fake target that depends on the previous one, but has special ALL keyword, which means
+ # it will always be executed.
+ add_custom_target("fake_${base_name}" ALL DEPENDS ${base_name})
+ endforeach()
+ # =========================================================================================
+ # !!! End of dubious section.
+ # =========================================================================================
+endif()
+
+# =============================================================================================
+# !!! (The section below is deployment related, so in a real world application you will want to
+# take care of this properly with some custom script or tool).
+# =============================================================================================
+# Install the library and the bindings module into the source folder near the main.py file, so
+# that the Python interpeter successfully imports the used module.
+install(TARGETS ${bindings_library} ${sample_library}
+ LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}
+ RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}
+ )
+# =============================================================================================
+# !!! End of dubious section.
+# =============================================================================================