Skip to content

Commit

Permalink
Updating the build process of the Python module (#866)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoconni authored Mar 26, 2023
1 parent 8748f38 commit bac11b1
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 227 deletions.
11 changes: 6 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.1)
cmake_minimum_required (VERSION 3.15)

################################################################################
# Project description #
Expand Down Expand Up @@ -71,16 +71,17 @@ option(INSTALL_JSBSIM_PYTHON_MODULE "Set to ON to install the Python module for

if (BUILD_PYTHON_MODULE)
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/python/CMakeModules)
cmake_policy(SET CMP0094 NEW) # makes FindPython3 prefer activated virtualenv Python to the latest version
find_package(Python3 COMPONENTS Interpreter Development)
find_package(Cython)

if (CYTHON_FOUND)
find_package(PythonLibs)
if (PYTHONLIBS_FOUND)
if (Python3_Development_FOUND)
enable_testing()
add_subdirectory(tests)
add_subdirectory(python)
endif(PYTHONLIBS_FOUND)
elseif(NOT PYTHONLIBS_FOUND)
endif(Python3_Development_FOUND)
elseif(NOT Python3_Development_FOUND)
message(WARNING "JSBSim Python module and test suite will not be built")
endif(CYTHON_FOUND)
endif(BUILD_PYTHON_MODULE)
Expand Down
40 changes: 14 additions & 26 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ include(UseCython)
string(TIMESTAMP THIS_YEAR "%Y")

# Declare JSBSim as a C++ project
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(JSBSIM_PYX ${CMAKE_CURRENT_BINARY_DIR}/_jsbsim.pyx)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jsbsim.pyx.in ${JSBSIM_PYX})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/jsbsim.pxd ${CMAKE_CURRENT_BINARY_DIR}/_jsbsim.pxd COPYONLY)
Expand All @@ -15,7 +17,7 @@ set_source_files_properties(${JSBSIM_PYX} PROPERTIES CYTHON_IS_CXX TRUE
if(DOXYGEN_FOUND AND BUILD_DOCS)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxy2PyDocStrings.py
doxy2pydocs.py)
execute_process(COMMAND ${PYTHON_EXECUTABLE} python/doxy2pydocs.py
execute_process(COMMAND ${Python3_EXECUTABLE} python/doxy2pydocs.py
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

# Prepare the sphinx build files
Expand All @@ -29,14 +31,6 @@ endif(DOXYGEN_FOUND AND BUILD_DOCS)
compile_pyx(_jsbsim _JSBSIM_CXX ${JSBSIM_PYX})
file(RELATIVE_PATH JSBSIM_CXX ${CMAKE_CURRENT_BINARY_DIR} ${_JSBSIM_CXX})

# Check if we are using Visual Studio msbuild
if(MSVC)
string(TOUPPER CMAKE_GENERATOR _GENERATOR)
if(NOT (_GENERATOR STREQUAL NINJA))
set(USING_MSBUILD 1)
endif()
endif(MSVC)

# Build the package directory
set(JSBSIM_PACKAGE_DIR ${CMAKE_CURRENT_BINARY_DIR}/jsbsim)
file(MAKE_DIRECTORY ${JSBSIM_PACKAGE_DIR})
Expand Down Expand Up @@ -108,27 +102,21 @@ endforeach(_FILE)
# been built.
file(RELATIVE_PATH BUILD_ROOT_PATH ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR})

set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
configure_file(setup.py.in ${SETUP_PY})
configure_file(setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py)

execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/findModuleFileName.py _jsbsim OUTPUT_VARIABLE PYTHON_MODULE_NAME)
set(JSBSIM_PYTHON_MODULE ${JSBSIM_TEST_PACKAGE_DIR}/${PYTHON_MODULE_NAME})
python3_add_library(_jsbsim MODULE ${JSBSIM_CXX} ${CMAKE_CURRENT_SOURCE_DIR}/ExceptionManagement.h)
target_include_directories(_jsbsim PRIVATE ${PROJECT_SOURCE_DIR}/src)
target_link_libraries(_jsbsim PRIVATE libJSBSim)
set_target_properties(_jsbsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${JSBSIM_TEST_PACKAGE_DIR})

# setup.py build_ext is called with --force because dependencies and time stamps
# are managed by CMake so we don't want setup.py to check them as well.
add_custom_command(OUTPUT ${JSBSIM_PYTHON_MODULE}
DEPENDS ${SETUP_PY} ${JSBSIM_CXX} ${CMAKE_CURRENT_SOURCE_DIR}/ExceptionManagement.h $<TARGET_FILE:libJSBSim>
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build_ext -b ${JSBSIM_TEST_DIR} --force
$<$<BOOL:${USING_MSBUILD}>:--config> $<$<BOOL:${USING_MSBUILD}>:$<CONFIG>>
$<$<BOOL:${BUILD_SHARED_LIBS}>:--sharedlibs>
$<$<BOOL:${MINGW}>:--compiler> $<$<BOOL:${MINGW}>:mingw32>
COMMENT "Building Python module...")
# Output directories for MSVC
set_target_properties(_jsbsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${JSBSIM_TEST_PACKAGE_DIR})
set_target_properties(_jsbsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${JSBSIM_TEST_PACKAGE_DIR})
set_target_properties(_jsbsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${JSBSIM_TEST_PACKAGE_DIR})
set_target_properties(_jsbsim PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${JSBSIM_TEST_PACKAGE_DIR})

add_subdirectory(fpectl)

add_custom_target(PythonJSBSim ALL DEPENDS ${JSBSIM_PYTHON_MODULE})
add_dependencies(PythonJSBSim libJSBSim)

# Windows needs the DLL to be copied locally for unit tests to run.
if(WIN32 AND BUILD_SHARED_LIBS)
add_custom_command(OUTPUT ${JSBSIM_TEST_PACKAGE_DIR}/JSBSim.dll
Expand All @@ -141,7 +129,7 @@ endif(WIN32 AND BUILD_SHARED_LIBS)

# Install the JSBSim Python module
if (INSTALL_JSBSIM_PYTHON_MODULE)
execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/findInstallDir.py OUTPUT_VARIABLE PYTHON_INSTALL_DIR)
execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/findInstallDir.py OUTPUT_VARIABLE PYTHON_INSTALL_DIR)
file(MAKE_DIRECTORY ${PYTHON_INSTALL_DIR}/jsbsim)
install(DIRECTORY ${JSBSIM_TEST_PACKAGE_DIR} DESTINATION ${PYTHON_INSTALL_DIR} COMPONENT pymodules)
endif()
7 changes: 4 additions & 3 deletions python/CMakeModules/FindCython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
#
# Bertrand Coconnier 2023/03/25 - Rely on CMake FindPython3 to locate the Python executable

# Use the Cython executable that lives next to the Python executable
# if it is a local installation.
find_package( PythonInterp )
if( PYTHONINTERP_FOUND )
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
if(Python3_Interpreter_FOUND)
get_filename_component( _python_path ${Python3_EXECUTABLE} PATH )
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat
HINTS ${_python_path}
Expand Down
10 changes: 5 additions & 5 deletions python/CMakeModules/UseCython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#
# Bertrand Coconnier 2019/02/16 - Commented out the addition of include directories from the *.pyx path.
# Bertrand Coconnier 2020/11/12 - Added the extraction of include directories from the *.pyx file.
# Bertrand Coconnier 2023/03/25 - Rely on CMake FindPython3 to locate the Python executable

# Configuration options.
set( CYTHON_ANNOTATE OFF
Expand All @@ -75,7 +76,6 @@ set( CYTHON_FLAGS "" CACHE STRING
mark_as_advanced( CYTHON_ANNOTATE CYTHON_NO_DOCSTRINGS CYTHON_FLAGS )

find_package( Cython REQUIRED )
find_package( PythonLibs REQUIRED )

set( CYTHON_CXX_EXTENSION "cxx" )
set( CYTHON_C_EXTENSION "c" )
Expand Down Expand Up @@ -243,12 +243,12 @@ function( cython_add_module _name )
endif()
endforeach()
compile_pyx( ${_name} generated_file ${pyx_module_sources} )
include_directories( ${PYTHON_INCLUDE_DIRS} )
include_directories( ${Python3_INCLUDE_DIRS} )
python_add_module( ${_name} ${generated_file} ${other_module_sources} )
if( APPLE )
set_target_properties( ${_name} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" )
else()
target_link_libraries( ${_name} ${PYTHON_LIBRARIES} )
target_link_libraries( ${_name} ${Python3_LIBRARIES} )
endif()
endfunction()

Expand All @@ -260,7 +260,7 @@ function( cython_add_standalone_executable _name )
set( other_module_sources "" )
set( main_module "" )
cmake_parse_arguments( cython_arguments "" "MAIN_MODULE" "" ${ARGN} )
include_directories( ${PYTHON_INCLUDE_DIRS} )
include_directories( ${Python3_INCLUDE_DIRS} )
foreach( _file ${cython_arguments_UNPARSED_ARGUMENTS} )
if( ${_file} MATCHES ".*\\.py[x]?$" )
get_filename_component( _file_we ${_file} NAME_WE )
Expand All @@ -286,5 +286,5 @@ function( cython_add_standalone_executable _name )
set( CYTHON_FLAGS ${CYTHON_FLAGS} --embed )
compile_pyx( "${main_module_we}_static" generated_file ${main_module} )
add_executable( ${_name} ${generated_file} ${pyx_module_sources} ${other_module_sources} )
target_link_libraries( ${_name} ${PYTHON_LIBRARIES} ${pyx_module_libs} )
target_link_libraries( ${_name} ${Python3_LIBRARIES} ${pyx_module_libs} )
endfunction()
10 changes: 0 additions & 10 deletions python/findModuleFileName.py

This file was deleted.

30 changes: 15 additions & 15 deletions python/fpectl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ option(FPECTL_DISPLAY_STACK_TRACE "Set to ON to display the stack trace when a f
if (APPLE)
file(COPY fpectl.py DESTINATION ${CMAKE_BINARY_DIR}/tests)
else()
python3_add_library(fpectl MODULE ${PROJECT_SOURCE_DIR}/python/ExceptionManagement.h
fpectlmodule.h
fpectlmodule.cpp)
set_target_properties(fpectl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)

# Output directories for MSVC
set_target_properties(fpectl PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/tests)
set_target_properties(fpectl PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/tests)
set_target_properties(fpectl PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR}/tests)
set_target_properties(fpectl PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_BINARY_DIR}/tests)

if(FPECTL_DISPLAY_STACK_TRACE)
find_package(Backward)
if(BACKWARD_FOUND)
set(FPECTL_INCLUDE_DIRS '${BACKWARD_INCLUDE_DIR}')
target_include_directories(fpectl PRIVATE ${BACKWARD_INCLUDE_DIR})
target_compile_definitions(fpectl PRIVATE BACKWARD_FOUND)
if(LIBBFD_FOUND)
set(FPECTL_LIBRARIES 'bfd')
target_link_libraries(fpectl PRIVATE bfd)
target_compile_definitions(fpectl PRIVATE LIBBFD_FOUND)
endif(LIBBFD_FOUND)
endif(BACKWARD_FOUND)
endif(FPECTL_DISPLAY_STACK_TRACE)

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fpectl_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/fpectl_config.h)
set(SETUP_PY ${CMAKE_CURRENT_BINARY_DIR}/setup.py)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in ${SETUP_PY})
execute_process(COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/python/findModuleFileName.py fpectl OUTPUT_VARIABLE FPECTL_MODULE_NAME)
set(FPECTL_PYTHON_MODULE ${CMAKE_BINARY_DIR}/tests/${FPECTL_MODULE_NAME})

add_custom_command(OUTPUT ${FPECTL_PYTHON_MODULE}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/fpectlmodule.h ${CMAKE_CURRENT_SOURCE_DIR}/fpectlmodule.cpp ${PROJECT_SOURCE_DIR}/python/ExceptionManagement.h
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build_ext -b ${CMAKE_BINARY_DIR}/tests
COMMENT "Building fpectl module...")

add_custom_target(fpectl ALL DEPENDS ${FPECTL_PYTHON_MODULE})
endif(APPLE)
6 changes: 0 additions & 6 deletions python/fpectl/fpectl_config.h.in

This file was deleted.

4 changes: 3 additions & 1 deletion python/fpectl/fpectlmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@
** Added the display of stack trace: July 11, 2021. Bertrand Coconnier
*/

#include "fpectl_config.h"
#ifdef LIBBFD_FOUND
#define BACKWARD_HAS_BFD 1
#endif
#ifdef BACKWARD_FOUND
#include "backward.hpp"
#endif
Expand Down
82 changes: 0 additions & 82 deletions python/fpectl/setup.py.in

This file was deleted.

Loading

0 comments on commit bac11b1

Please # to comment.