Skip to content

Commit 4ba6d50

Browse files
committed
Overhaul Python structure, better support Python 2+3 builds (master)
* Copy in CMake 3.16 Python CMake scripts, does the work for us * Fix OS X Monterey issue * Closes #380 * See: pothosware/homebrew-pothos#59
1 parent 9836913 commit 4ba6d50

File tree

13 files changed

+3199
-649
lines changed

13 files changed

+3199
-649
lines changed

.github/workflows/ci.yml

+144-84
Large diffs are not rendered by default.

swig/CMakeLists.txt

+1-13
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,4 @@ add_subdirectory(csharp)
1111
########################################################################
1212
# Python support (optional)
1313
########################################################################
14-
message(STATUS "")
15-
message(STATUS "#############################################")
16-
message(STATUS "## Begin configuration for Python support...")
17-
message(STATUS "#############################################")
18-
message(STATUS "Enabling optional Python bindings if possible...")
19-
add_subdirectory(python)
20-
21-
message(STATUS "")
22-
message(STATUS "#############################################")
23-
message(STATUS "## Begin configuration for Python3 support...")
24-
message(STATUS "#############################################")
25-
message(STATUS "Enabling optional Python3 bindings if possible...")
26-
add_subdirectory(python3)
14+
add_subdirectory(python)

swig/python/CMakeLists.txt

+92-122
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
########################################################################
22
# Project setup
33
########################################################################
4-
cmake_minimum_required(VERSION 2.8)
4+
cmake_minimum_required(VERSION 3.3)
55
project(SoapySDRPython CXX)
66
enable_testing()
77

@@ -14,68 +14,12 @@ find_package(SWIG)
1414
message(STATUS "SWIG_FOUND: ${SWIG_FOUND} - ${SWIG_VERSION}")
1515

1616
########################################################################
17-
# Find python interp
17+
# Find Python
1818
########################################################################
19-
find_package(PythonInterp)
20-
message(STATUS "PYTHONINTERP_FOUND: ${PYTHONINTERP_FOUND} - ${PYTHON_VERSION_STRING}")
21-
message(STATUS "PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}")
22-
23-
#help find_package(PythonLibs) by setting Python_ADDITIONAL_VERSIONS from PYTHON_VERSION_STRING
24-
if(PYTHONINTERP_FOUND AND DEFINED PYTHON_VERSION_STRING AND NOT DEFINED Python_ADDITIONAL_VERSIONS)
25-
string(SUBSTRING "${PYTHON_VERSION_STRING}" 0 3 Python_ADDITIONAL_VERSIONS)
26-
endif()
27-
28-
########################################################################
29-
# Determine install directory
30-
########################################################################
31-
execute_process(
32-
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/get_python_lib.py" "${CMAKE_INSTALL_PREFIX}"
33-
OUTPUT_STRIP_TRAILING_WHITESPACE
34-
OUTPUT_VARIABLE PYTHON_INSTALL_DIR_SYSCONF
35-
)
36-
set(PYTHON_INSTALL_DIR "${PYTHON_INSTALL_DIR_SYSCONF}" CACHE STRING "python install prefix")
37-
message(STATUS "PYTHON_INSTALL_DIR: \${prefix}/${PYTHON_INSTALL_DIR}")
38-
39-
########################################################################
40-
# Find Python libs
41-
########################################################################
42-
option(USE_PYTHON_CONFIG "use python-config to locate development files" TRUE)
43-
set(PYTHON_CONFIG_EXECUTABLE ${PYTHON_EXECUTABLE}-config
44-
CACHE FILEPATH "Path to python-config executable")
45-
if (USE_PYTHON_CONFIG AND EXISTS ${PYTHON_CONFIG_EXECUTABLE})
46-
execute_process(
47-
COMMAND ${PYTHON_CONFIG_EXECUTABLE} --includes
48-
OUTPUT_STRIP_TRAILING_WHITESPACE
49-
OUTPUT_VARIABLE PYTHON_INCLUDE_DIRS)
50-
string(REGEX REPLACE "^[-I]" "" PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
51-
string(REGEX REPLACE "[ ]-I" " " PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
52-
separate_arguments(PYTHON_INCLUDE_DIRS)
53-
execute_process(
54-
COMMAND ${PYTHON_CONFIG_EXECUTABLE} --ldflags
55-
OUTPUT_STRIP_TRAILING_WHITESPACE
56-
OUTPUT_VARIABLE PYTHON_LIBRARIES)
57-
string(STRIP "${PYTHON_LIBRARIES}" PYTHON_LIBRARIES)
58-
set(PYTHONLIBS_VERSION_STRING ${PYTHON_VERSION_STRING})
59-
set(PYTHONLIBS_FOUND TRUE)
60-
else()
61-
find_package(PythonLibs)
62-
endif()
63-
64-
message(STATUS "PYTHONLIBS_FOUND: ${PYTHONLIBS_FOUND} - ${PYTHONLIBS_VERSION_STRING}")
65-
message(STATUS "PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}")
66-
message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}")
67-
68-
#on windows, we require a pythonxx_d.lib in debug mode
69-
#require that the PYTHON_DEBUG_LIBRARY flag is set
70-
#or the build assumes that the debug library DNE
71-
set(PYTHON_DEBUG_OK TRUE)
72-
if(WIN32 AND NOT PYTHON_DEBUG_LIBRARY AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
73-
message(WARNING "WIN32 Debug mode requires PYTHON_DEBUG_LIBRARY")
74-
set(PYTHON_DEBUG_OK FALSE)
75-
endif()
19+
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
7620

7721
########################################################################
78-
# Python version check
22+
## set the swig flags
7923
########################################################################
8024
set(PYTHON_VERSION_MATCH TRUE)
8125
if (PYTHON_VERSION_STRING AND PYTHONLIBS_VERSION_STRING)
@@ -88,7 +32,7 @@ endif()
8832
########################################################################
8933
## set the swig flags - shared with python3 build
9034
########################################################################
91-
set(CMAKE_SWIG_FLAGS -c++ -threads -I${SoapySDR_INCLUDE_DIRS} -I${CMAKE_CURRENT_SOURCE_DIR}/..)
35+
set(CMAKE_SWIG_FLAGS -threads -I${SoapySDR_INCLUDE_DIRS} -I${CMAKE_CURRENT_SOURCE_DIR}/..)
9236

9337
#check for size_t issue on arm 32-bit platforms
9438
include(CheckCXXSourceCompiles)
@@ -102,80 +46,106 @@ if (SIZE_T_IS_UNSIGNED_INT)
10246
list(APPEND CMAKE_SWIG_FLAGS -DSIZE_T_IS_UNSIGNED_INT)
10347
endif (SIZE_T_IS_UNSIGNED_INT)
10448

105-
########################################################################
106-
## Export variables for python3 subdirectory
107-
########################################################################
108-
109-
#this directory used as a stand-alone build since the library is pulled in externally
110-
#set ENABLE_LIBRARY for cmake_dependent_option() used in the feature setup below
111-
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
112-
set(ENABLE_LIBRARY ${SoapySDR_FOUND})
113-
114-
#otherwise export enable and swig variables used in the python3 directory
115-
else ()
116-
117-
#set once we know that executable and libs are found and match
118-
#this tells the parent scope to build python3 when this is python2
119-
if(PYTHON_VERSION_STRING AND "${PYTHON_VERSION_STRING}" VERSION_LESS "3.0")
120-
set(BUILD_PYTHON3 TRUE PARENT_SCOPE)
121-
endif()
122-
123-
#or enable search for python3 when this directory failed to find
124-
#a full set of python interpreter and devel files of any version
125-
if(NOT PYTHONINTERP_FOUND OR NOT PYTHONLIBS_FOUND)
126-
set(BUILD_PYTHON3 TRUE PARENT_SCOPE)
127-
endif()
128-
129-
set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_FLAGS} PARENT_SCOPE)
130-
131-
endif ()
132-
13349
########################################################################
13450
## Feature registration
13551
########################################################################
13652
include(FeatureSummary)
13753
include(CMakeDependentOption)
138-
cmake_dependent_option(ENABLE_PYTHON "Enable python bindings" ON "ENABLE_LIBRARY;SWIG_FOUND;PYTHONINTERP_FOUND;PYTHONLIBS_FOUND;PYTHON_DEBUG_OK;PYTHON_VERSION_MATCH" OFF)
139-
add_feature_info(Python ENABLE_PYTHON "python bindings v${PYTHON_VERSION_STRING}")
140-
if (NOT ENABLE_PYTHON)
141-
return()
54+
55+
# Note: for build script compatibility, still use ENABLE_PYTHON for Python 2
56+
message(STATUS "")
57+
message(STATUS "#############################################")
58+
message(STATUS "## Begin configuration for Python 2 support...")
59+
message(STATUS "#############################################")
60+
message(STATUS "Enabling optional Python 2 bindings if possible...")
61+
find_package(Python2 COMPONENTS Interpreter Development)
62+
if(${Python2_FOUND})
63+
message(STATUS " * Interpreter: ${Python2_EXECUTABLE} (${Python2_INTERPRETER_ID})")
64+
message(STATUS " * Include: ${Python2_INCLUDE_DIRS}")
65+
message(STATUS " * Library: ${Python2_LIBRARIES}")
66+
endif()
67+
cmake_dependent_option(ENABLE_PYTHON "Enable Python2 bindings" ON "ENABLE_LIBRARY;SWIG_FOUND;Python2_FOUND" OFF)
68+
add_feature_info(Python2 ENABLE_PYTHON "Python2 bindings v${Python2_VERSION}")
69+
70+
message(STATUS "")
71+
message(STATUS "#############################################")
72+
message(STATUS "## Begin configuration for Python 3 support...")
73+
message(STATUS "#############################################")
74+
message(STATUS "Enabling optional Python 3 bindings if possible...")
75+
find_package(Python3 COMPONENTS Interpreter Development)
76+
if(${Python3_FOUND})
77+
message(STATUS " * Interpreter: ${Python3_EXECUTABLE} (${Python3_INTERPRETER_ID})")
78+
message(STATUS " * Include: ${Python3_INCLUDE_DIRS}")
79+
message(STATUS " * Library: ${Python3_LIBRARIES}")
14280
endif()
81+
cmake_dependent_option(ENABLE_PYTHON3 "Enable Python3 bindings" ON "ENABLE_LIBRARY;SWIG_FOUND;Python3_FOUND" OFF)
82+
add_feature_info(Python3 ENABLE_PYTHON3 "Python3 bindings v${Python3_VERSION}")
14383

14484
########################################################################
145-
# Build Module
85+
# Build and install module
14686
########################################################################
14787
include(UseSWIG)
88+
set(SOAPYSDR_PYTHON_DIR ${CMAKE_CURRENT_SOURCE_DIR})
89+
90+
function(BUILD_PYTHON_MODULE PYTHON_VERSION)
91+
configure_file(
92+
${SOAPYSDR_PYTHON_DIR}/SoapySDR.in.i
93+
${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i
94+
@ONLY)
95+
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i PROPERTIES CPLUSPLUS ON)
96+
97+
if(${CMAKE_VERSION} VERSION_LESS "3.8")
98+
SWIG_ADD_MODULE(SoapySDR${PYTHON_VERSION} python ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i)
99+
else()
100+
SWIG_ADD_LIBRARY(SoapySDR${PYTHON_VERSION} LANGUAGE python SOURCES ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i)
101+
endif()
148102

149-
configure_file(
150-
SoapySDR.in.i
151-
${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i
152-
@ONLY)
103+
set(python_includes ${SoapySDR_INCLUDE_DIRS})
104+
set(python_libraries SoapySDR Python${PYTHON_VERSION}::Module)
153105

154-
message(STATUS "CMAKE_SWIG_FLAGS=${CMAKE_SWIG_FLAGS}")
155-
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i PROPERTIES CPLUSPLUS ON)
106+
set_target_properties(${SWIG_MODULE_SoapySDR${PYTHON_VERSION}_REAL_NAME} PROPERTIES OUTPUT_NAME _SoapySDR)
156107

157-
if(${CMAKE_VERSION} VERSION_LESS "3.8")
158-
SWIG_ADD_MODULE(SoapySDR python ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i)
159-
else()
160-
SWIG_ADD_LIBRARY(SoapySDR LANGUAGE python SOURCES ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.i)
161-
endif()
108+
if(MINGW)
109+
# https://stackoverflow.com/a/50792585
110+
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
111+
target_compile_definitions(${SWIG_MODULE_SoapySDR${PYTHON_VERSION}_REAL_NAME} PRIVATE -DMS_WIN64=1)
112+
else()
113+
target_compile_definitions(${SWIG_MODULE_SoapySDR${PYTHON_VERSION}_REAL_NAME} PRIVATE -DMS_WIN32=1)
114+
endif()
162115

163-
if(APPLE)
164-
list(APPEND PYTHON_LIBRARIES "-undefined dynamic_lookup")
165-
endif()
116+
# As of Python 3.8, DLL dependencies are no longer searched for in the PATH, so statically link against
117+
# the GCC runtime so we don't have to worry about that.
118+
list(APPEND python_libraries -static-libgcc -static-libstdc++)
119+
endif()
166120

167-
target_include_directories(${SWIG_MODULE_SoapySDR_REAL_NAME} PRIVATE ${PYTHON_INCLUDE_DIRS})
168-
SWIG_LINK_LIBRARIES(SoapySDR SoapySDR ${PYTHON_LIBRARIES})
121+
target_include_directories(${SWIG_MODULE_SoapySDR${PYTHON_VERSION}_REAL_NAME} PRIVATE ${python_includes})
122+
SWIG_LINK_LIBRARIES(SoapySDR${PYTHON_VERSION} ${python_libraries})
169123

170-
########################################################################
171-
# Install Module
172-
########################################################################
173-
install(
174-
TARGETS ${SWIG_MODULE_SoapySDR_REAL_NAME}
175-
DESTINATION ${PYTHON_INSTALL_DIR}
176-
)
177-
178-
install(
179-
FILES ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.py
180-
DESTINATION ${PYTHON_INSTALL_DIR}
181-
)
124+
execute_process(
125+
COMMAND ${Python${PYTHON_VERSION}_EXECUTABLE} ${SOAPYSDR_PYTHON_DIR}/get_python_lib.py ${CMAKE_INSTALL_PREFIX}
126+
OUTPUT_STRIP_TRAILING_WHITESPACE
127+
OUTPUT_VARIABLE PYTHON_INSTALL_DIR)
128+
129+
install(
130+
TARGETS ${SWIG_MODULE_SoapySDR${PYTHON_VERSION}_REAL_NAME}
131+
DESTINATION ${PYTHON_INSTALL_DIR}
132+
)
133+
134+
install(
135+
FILES ${CMAKE_CURRENT_BINARY_DIR}/SoapySDR.py
136+
DESTINATION ${PYTHON_INSTALL_DIR}
137+
)
138+
endfunction()
139+
140+
# TODO: Windows has full Python installations in different directories, so all Python
141+
# versions install file in the same subpaths. CMake doesn't catch this for some reason,
142+
# so should we error out if both Python versions are detected or prioritize one over the
143+
# other with a warning?
144+
145+
if(ENABLE_PYTHON)
146+
add_subdirectory(python2)
147+
endif()
148+
149+
if(ENABLE_PYTHON3)
150+
add_subdirectory(python3)
151+
endif()

swig/python/apps/SimpleSiggen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def siggen_app(
3939
sdr = SoapySDR.Device(args)
4040
#set clock rate first
4141
if clock_rate is not None:
42-
sdr.setMasterclock_rate(clock_rate)
42+
sdr.setMasterClockRate(clock_rate)
4343

4444
#set sample rate
4545
sdr.setSampleRate(SOAPY_SDR_TX, tx_chan, rate)

0 commit comments

Comments
 (0)