Skip to content

Commit

Permalink
WIP: attempt to get Qt-dependent projects building.
Browse files Browse the repository at this point in the history
  • Loading branch information
oursland committed Sep 16, 2024
1 parent d152c00 commit b3f7860
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 2,860 deletions.
23 changes: 11 additions & 12 deletions conda_build_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ c_stdlib_version:
- ${{ "10.14" if osx and x86_64 }}
- ${{ "11.0" if osx and arm64 }}


# # Project overrides
# macos_min_version: # [osx and x86_64]
# - 10.14 # [osx and x86_64]
# macos_machine: # [osx]
# - x86_64-apple-darwin13.4.0 # [osx and x86_64]
# - arm64-apple-darwin20.0.0 # [osx and arm64]
# MACOSX_DEPLOYMENT_TARGET: # [osx]
# - 11.0 # [osx and arm64]
# - 10.14 # [osx and x86_64]
# CONDA_BUILD_SYSROOT:
# - /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk # [osx and arm64]
# Project overrides
macos_min_version: # [osx and x86_64]
- 10.15 # [osx and x86_64]
macos_machine: # [osx]
- x86_64-apple-darwin13.4.0 # [osx and x86_64]
- arm64-apple-darwin20.0.0 # [osx and arm64]
MACOSX_DEPLOYMENT_TARGET: # [osx]
- 11.0 # [osx and arm64]
- 10.15 # [osx and x86_64]
CONDA_BUILD_SYSROOT:
- /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk # [osx and arm64]
249 changes: 249 additions & 0 deletions patch/ros-jazzy-python-qt-binding.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
From c8c554e4b8306ee18e5e1819ef7aacbdd2a0f6ac Mon Sep 17 00:00:00 2001
From: Jacob Oursland <[email protected]>
Date: Mon, 16 Sep 2024 10:15:49 -0700
Subject: [PATCH] X

---
CMakeLists.txt | 1 +
cmake/pyproject.toml.in | 25 ++++++
cmake/sip_configure.py | 1 +
cmake/sip_helper.cmake | 130 ++++++++++++++++++++++++------
src/python_qt_binding/__init__.py | 8 ++
5 files changed, 141 insertions(+), 24 deletions(-)
create mode 100644 cmake/pyproject.toml.in

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 919969e..2bf015a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@ install(FILES
cmake/shiboken_helper.cmake
cmake/sip_configure.py
cmake/sip_helper.cmake
+ cmake/pyproject.toml.in
DESTINATION share/${PROJECT_NAME}/cmake)

if(BUILD_TESTING)
diff --git a/cmake/pyproject.toml.in b/cmake/pyproject.toml.in
new file mode 100644
index 0000000..87c4527
--- /dev/null
+++ b/cmake/pyproject.toml.in
@@ -0,0 +1,27 @@
+[project]
+name = "lib@PROJECT_NAME@"
+
+# Specify sip v5 as the build system for the package.
+[build-system]
+requires = ["PyQt-builder >=1, <2"]
+build-backend = "sipbuild.api"
+
+[tool.sip]
+project-factory = "pyqtbuild:PyQtProject"
+
+[tool.sip.builder]
+qmake = "@QMAKE_EXECUTABLE@"
+
+[tool.sip.project]
+sip-files-dir = "@SIP_FILES_DIR@"
+build-dir = "@SIP_BUILD_DIR@"
+verbose = true
+minimum-macos-version = "@MACOS_MINIMUM_VERSION@"
+
+[tool.sip.bindings.libqt_gui_cpp_sip]
+sip-file = "@SIP_FILE@"
+include-dirs = [@SIP_INCLUDE_DIRS@]
+libraries = [@SIP_LIBARIES@]
+library-dirs = [@SIP_LIBRARY_DIRS@]
+qmake-QT = ["widgets"]
+exceptions = true
diff --git a/cmake/sip_configure.py b/cmake/sip_configure.py
index 5210ee5..7bafe73 100644
--- a/cmake/sip_configure.py
+++ b/cmake/sip_configure.py
@@ -215,6 +215,7 @@ if sys.platform == 'win32':
# The __cplusplus flag is not properly set on Windows for backwards
# compatibilty. This flag sets it correctly
makefile.CXXFLAGS.append('/Zc:__cplusplus')
+ makefile.extra_cxxflags.append('/DROS_BUILD_SHARED_LIBS=1')
else:
makefile.extra_cxxflags.append('-std=c++17')

diff --git a/cmake/sip_helper.cmake b/cmake/sip_helper.cmake
index a5ac3c2..a1f145c 100644
--- a/cmake/sip_helper.cmake
+++ b/cmake/sip_helper.cmake
@@ -31,7 +31,7 @@ execute_process(
if(PYTHON_SIP_EXECUTABLE)
string(STRIP ${PYTHON_SIP_EXECUTABLE} SIP_EXECUTABLE)
else()
- find_program(SIP_EXECUTABLE sip)
+ find_program(SIP_EXECUTABLE NAMES sip sip-build)
endif()

if(SIP_EXECUTABLE)
@@ -42,6 +42,15 @@ else()
set(sip_helper_NOTFOUND TRUE)
endif()

+if(sip_helper_FOUND)
+ execute_process(
+ COMMAND ${SIP_EXECUTABLE} -V
+ OUTPUT_VARIABLE SIP_VERSION
+ ERROR_QUIET)
+ string(STRIP ${SIP_VERSION} SIP_VERSION)
+ message(STATUS "SIP binding generator version: ${SIP_VERSION}")
+endif()
+
#
# Run the SIP generator and compile the generated code into a library.
#
@@ -93,34 +102,107 @@ function(build_sip_binding PROJECT_NAME SIP_FILE)
set(LIBRARY_DIRS ${${PROJECT_NAME}_LIBRARY_DIRS})
set(LDFLAGS_OTHER ${${PROJECT_NAME}_LDFLAGS_OTHER})

- add_custom_command(
- OUTPUT ${SIP_BUILD_DIR}/Makefile
- COMMAND ${Python3_EXECUTABLE} ${sip_SIP_CONFIGURE} ${SIP_BUILD_DIR} ${SIP_FILE} ${sip_LIBRARY_DIR}
- \"${INCLUDE_DIRS}\" \"${LIBRARIES}\" \"${LIBRARY_DIRS}\" \"${LDFLAGS_OTHER}\"
- DEPENDS ${sip_SIP_CONFIGURE} ${SIP_FILE} ${sip_DEPENDS}
- WORKING_DIRECTORY ${sip_SOURCE_DIR}
- COMMENT "Running SIP generator for ${PROJECT_NAME} Python bindings..."
- )
+ if(${SIP_VERSION} VERSION_GREATER_EQUAL "5.0.0")
+ # Since v5, SIP implements the backend per PEP 517, PEP 518
+ # Here we synthesize `pyproject.toml` and run `pip install`

- if(NOT EXISTS "${sip_LIBRARY_DIR}")
+ find_program(QMAKE_EXECUTABLE NAMES qmake REQUIRED)
+
+ file(REMOVE_RECURSE ${SIP_BUILD_DIR})
file(MAKE_DIRECTORY ${sip_LIBRARY_DIR})
- endif()

- if(WIN32)
- set(MAKE_EXECUTABLE NMake.exe)
+ set(SIP_FILES_DIR ${sip_SOURCE_DIR})
+
+ set(SIP_INCLUDE_DIRS "")
+ foreach(_x ${INCLUDE_DIRS})
+ set(SIP_INCLUDE_DIRS "${SIP_INCLUDE_DIRS},\"${_x}\"")
+ endforeach()
+ string(REGEX REPLACE "^," "" SIP_INCLUDE_DIRS ${SIP_INCLUDE_DIRS})
+
+ # SIP expects the libraries WITHOUT the file extension.
+ set(SIP_LIBARIES "")
+ set(SIP_LIBRARY_DIRS "")
+
+ if(APPLE)
+ set(LIBRARIES_TO_LOOP ${LIBRARIES})
+ else()
+ set(LIBRARIES_TO_LOOP ${LIBRARIES} ${PYTHON_LIBRARIES})
+ endif()
+
+ foreach(_x ${LIBRARIES_TO_LOOP})
+ get_filename_component(_x_NAME "${_x}" NAME_WLE)
+ get_filename_component(_x_DIR "${_x}" DIRECTORY)
+ get_filename_component(_x "${_x_DIR}/${_x_NAME}" ABSOLUTE)
+ STRING(REGEX REPLACE "^lib" "" _x_NAME_NOPREFIX ${_x_NAME})
+
+ string(FIND "${_x_NAME_NOPREFIX}" "$<TARGET_FILE" out)
+ string(FIND "${_x_NAME_NOPREFIX}" "::" out2)
+ if("${out}" EQUAL 0)
+ STRING(REGEX REPLACE "\\$<TARGET_FILE:" "" _x_NAME_NOPREFIX ${_x_NAME_NOPREFIX})
+ STRING(REGEX REPLACE ">" "" _x_NAME_NOPREFIX ${_x_NAME_NOPREFIX})
+ if(NOT "${out2}" EQUAL -1)
+ message(STATUS "IGNORE: ${_x_NAME_NOPREFIX}")
+ else()
+ set(SIP_LIBARIES "${SIP_LIBARIES},\"${_x_NAME_NOPREFIX}\"")
+ endif()
+ else()
+ set(SIP_LIBARIES "${SIP_LIBARIES},\"${_x_NAME_NOPREFIX}\"")
+ set(SIP_LIBRARY_DIRS "${SIP_LIBRARY_DIRS},\"${_x_DIR}\"")
+ endif()
+ endforeach()
+ string(REGEX REPLACE "^," "" SIP_LIBARIES ${SIP_LIBARIES})
+
+ foreach(_x ${LIBRARY_DIRS})
+ set(SIP_LIBRARY_DIRS "${SIP_LIBRARY_DIRS},\"${_x}\"")
+ endforeach()
+ string(REGEX REPLACE "^," "" SIP_LIBRARY_DIRS ${SIP_LIBRARY_DIRS})
+ message(WARNING "test lib dir: ${SIP_LIBRARY_DIRS}")
+
+ set(MACOS_MINIMUM_VERSION ${CMAKE_OSX_DEPLOYMENT_TARGET})
+
+ # TODO:
+ # I don't know what to do about LDFLAGS_OTHER
+ # what's the equivalent construct in sip5?
+
+ configure_file(
+ ${__PYTHON_QT_BINDING_SIP_HELPER_DIR}/pyproject.toml.in
+ ${sip_BINARY_DIR}/sip/pyproject.toml
+ )
+ add_custom_command(
+ OUTPUT ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
+ COMMAND ${Python3_EXECUTABLE} -m pip install . --target ${sip_LIBRARY_DIR} --no-deps --verbose --upgrade
+ DEPENDS ${sip_SIP_CONFIGURE} ${SIP_FILE} ${sip_DEPENDS}
+ WORKING_DIRECTORY ${sip_BINARY_DIR}/sip
+ COMMENT "Running SIP-build generator for ${PROJECT_NAME} Python bindings..."
+ )
else()
- find_program(MAKE_PROGRAM NAMES make)
- message(STATUS "Found required make: ${MAKE_PROGRAM}")
- set(MAKE_EXECUTABLE ${MAKE_PROGRAM})
- endif()
+ add_custom_command(
+ OUTPUT ${SIP_BUILD_DIR}/Makefile
+ COMMAND ${Python3_EXECUTABLE} ${sip_SIP_CONFIGURE} ${SIP_BUILD_DIR} ${SIP_FILE} ${sip_LIBRARY_DIR}
+ \"${INCLUDE_DIRS}\" \"${LIBRARIES}\" \"${LIBRARY_DIRS}\" \"${LDFLAGS_OTHER}\"
+ DEPENDS ${sip_SIP_CONFIGURE} ${SIP_FILE} ${sip_DEPENDS}
+ WORKING_DIRECTORY ${sip_SOURCE_DIR}
+ COMMENT "Running SIP generator for ${PROJECT_NAME} Python bindings..."
+ )

- add_custom_command(
- OUTPUT ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
- COMMAND ${MAKE_EXECUTABLE}
- DEPENDS ${SIP_BUILD_DIR}/Makefile
- WORKING_DIRECTORY ${SIP_BUILD_DIR}
- COMMENT "Compiling generated code for ${PROJECT_NAME} Python bindings..."
- )
+ if(NOT EXISTS "${sip_LIBRARY_DIR}")
+ file(MAKE_DIRECTORY ${sip_LIBRARY_DIR})
+ endif()
+
+ if(WIN32)
+ set(MAKE_EXECUTABLE NMake.exe)
+ else()
+ set(MAKE_EXECUTABLE make)
+ endif()
+
+ add_custom_command(
+ OUTPUT ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
+ COMMAND ${MAKE_EXECUTABLE}
+ DEPENDS ${SIP_BUILD_DIR}/Makefile
+ WORKING_DIRECTORY ${SIP_BUILD_DIR}
+ COMMENT "Compiling generated code for ${PROJECT_NAME} Python bindings..."
+ )
+ endif()

add_custom_target(lib${PROJECT_NAME} ALL
DEPENDS ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}
diff --git a/src/python_qt_binding/__init__.py b/src/python_qt_binding/__init__.py
index 1e209de..6b55f35 100644
--- a/src/python_qt_binding/__init__.py
+++ b/src/python_qt_binding/__init__.py
@@ -66,3 +66,11 @@ for module_name, module in QT_BINDING_MODULES.items():
del module

del sys
+
+import os
+from PyQt5.QtGui import QIcon
+current_theme_path = QIcon.themeSearchPaths()
+conda_path = os.environ['CONDA_PREFIX']
+QIcon.setThemeSearchPaths(current_theme_path + [os.path.join(conda_path, 'share/icons/')])
+QIcon.setThemeName('Adwaita')
+del os
--
2.46.1
62 changes: 62 additions & 0 deletions patch/ros-jazzy-qt-gui-cpp.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
diff --git a/src/qt_gui_cpp_sip/CMakeLists.txt b/src/qt_gui_cpp_sip/CMakeLists.txt
index 47c24958..11378b3e 100644
--- a/src/qt_gui_cpp_sip/CMakeLists.txt
+++ b/src/qt_gui_cpp_sip/CMakeLists.txt
@@ -28,7 +28,7 @@ set(qt_gui_cpp_sip_DEPENDENT_FILES

# maintain context for different named target
set(qt_gui_cpp_sip_INCLUDE_DIRS ${qt_gui_cpp_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/../../include")
-set(qt_gui_cpp_sip_LIBRARY_DIRS ${qt_gui_cpp_LIBRARY_DIRS} lib)
+set(qt_gui_cpp_sip_LIBRARY_DIRS ${CMAKE_BINARY_DIR} lib)
set(qt_gui_cpp_sip_LDFLAGS_OTHER ${qt_gui_cpp_LDFLAGS_OTHER})

ament_get_recursive_properties(deps_include_dirs deps_libraries ${pluginlib_TARGETS})
@@ -51,16 +51,22 @@ cmake_minimum_required(VERSION 3.20)
cmake_policy(SET CMP0094 NEW)
set(Python3_FIND_UNVERSIONED_NAMES FIRST)

-find_package(Python3 REQUIRED COMPONENTS Development)
+find_package(Python REQUIRED COMPONENTS Interpreter Development)
+find_package(OpenGL REQUIRED)

set(_qt_gui_cpp_sip_LIBRARIES
${deps_libraries}
- Python3::Python
qt_gui_cpp
+ OpenGL::GL
)

+if(NOT APPLE)
+ set(_qt_gui_cpp_sip_LIBRARIES ${_qt_gui_cpp_sip_LIBRARIES} Python::Python)
+endif()
+
# sip needs libraries to have resolved paths and cannot link to cmake targets
-foreach(_lib_name ${_qt_gui_cpp_sip_LIBRARIES})
+foreach(_lib_name_raw ${_qt_gui_cpp_sip_LIBRARIES})
+ string(REGEX REPLACE "\\.so\\.[0-9,\\.]*" ".so" _lib_name ${_lib_name_raw})
if(TARGET ${_lib_name})
# Use a nifty cmake generator expression to resolve the target location
list(APPEND qt_gui_cpp_sip_LIBRARIES $<TARGET_FILE:${_lib_name}>)
@@ -91,11 +97,20 @@ if(sip_helper_FOUND)
)

if(APPLE)
- set(LIBQT_GUI_CPP_SIP_SUFFIX .so)
+ # Okay-ish hack for now
+ if(${SIP_VERSION} VERSION_GREATER_EQUAL "5.0.0")
+ set(LIBQT_GUI_CPP_SIP_SUFFIX ".cpython-${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-darwin.so")
+ else()
+ set(LIBQT_GUI_CPP_SIP_SUFFIX .so)
+ endif()
elseif(WIN32)
set(LIBQT_GUI_CPP_SIP_SUFFIX .pyd)
else()
- set(LIBQT_GUI_CPP_SIP_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ if(${SIP_VERSION} VERSION_GREATER_EQUAL "5.0.0")
+ set(LIBQT_GUI_CPP_SIP_SUFFIX ".cpython-${Python_VERSION_MAJOR}${Python_VERSION_MINOR}-${CMAKE_HOST_SYSTEM_PROCESSOR}-linux-gnu${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ else()
+ set(LIBQT_GUI_CPP_SIP_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
+ endif()
endif()

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libqt_gui_cpp_sip${LIBQT_GUI_CPP_SIP_SUFFIX}
Loading

0 comments on commit b3f7860

Please sign in to comment.