Skip to content

Commit

Permalink
[python] Reenable Python debugging from Visual Studio (#1768)
Browse files Browse the repository at this point in the history
Move samples to lang/python folder and generate all pyproj files from CMake.
  • Loading branch information
KerstinKeller authored Oct 23, 2024
1 parent 1036657 commit e54d371
Show file tree
Hide file tree
Showing 69 changed files with 292 additions and 1,269 deletions.
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ========================= eCAL LICENSE =================================
#
# Copyright (C) 2016 - 2019 Continental Corporation
# Copyright (C) 2016 - 2024 Continental Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -117,6 +117,14 @@ set(ECAL_CORE_TRANSPORT_UDP
set(ECAL_CORE_TRANSPORT_TCP ON)
set(ECAL_CORE_TRANSPORT_SHM ON)

# -----------------------
# eCAL Python configuration
# -----------------------
set(ECAL_PYTHON_BUILD_SAMPLES ${BUILD_SAMPLES})
set(ECAL_PYTHON_BUILD_TESTS ${BUILD_ECAL_TESTS})
set(ECAL_PYTHON_HAS_HDF5 ${HAS_HDF5})


# This should be ON, unless build ecal hdf5 for Matlab usage
option(ECAL_LINK_HDF5_SHARED "Link shared libs of HDF5" ON)

Expand Down
108 changes: 107 additions & 1 deletion lang/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ========================= eCAL LICENSE =================================
#
# Copyright (C) 2016 - 2019 Continental Corporation
# Copyright (C) 2016 - 2024 Continental Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,98 @@ cmake_minimum_required(VERSION 3.18...3.26)
project(ecal_python)
find_package(Python REQUIRED COMPONENTS Development.Module Interpreter)

option(ECAL_PYTHON_BUILD_SAMPLES "Includes the python samples" ON)
option(ECAL_PYTHON_BUILD_TESTS "Includes the python tests" ON)
option(ECAL_PYTHON_HAS_HDF5 "Enables eCAL application cmd line interfaces" ON)

set(ECAL_PYTHON_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})

# This function takes a list of python files to be copied to the package directory
# and associates the files with a given python extension target
# Using this function allows to create the whole python package editable in place
# Arguments:
# TARGET Python extension target with which to associate the files
# PYTHON_CODE_ROOT Root folder for Python files, to keep folder structure
# PYTHON_FILES Python files associated with target
function(copy_python_code)
set(singleValueArgs TARGET PYTHON_CODE_ROOT)
set(multiValueArgs PYTHON_FILES)
cmake_parse_arguments(ARGUMENTS
""
"${singleValueArgs}"
"${multiValueArgs}" ${ARGN} )

cmake_path(
ABSOLUTE_PATH ARGUMENTS_PYTHON_CODE_ROOT
OUTPUT_VARIABLE absolute_path_python_code_root
)

foreach (python_file ${ARGUMENTS_PYTHON_FILES})
cmake_path(
ABSOLUTE_PATH python_file
OUTPUT_VARIABLE absolute_path_python_file
)

cmake_path(
RELATIVE_PATH absolute_path_python_file
BASE_DIRECTORY ${absolute_path_python_code_root}
OUTPUT_VARIABLE relative_path)


# Now we actually copy the file to the correct directory
set(origin_file ${absolute_path_python_file})
set(destination_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/python/${relative_path})
file(
GENERATE
OUTPUT ${destination_file}
INPUT ${origin_file}
)

endforeach()
endfunction()

# Function to set the correct output directory for the python targets, so that they can be debugged properly
function(ecal_python_set_output_directory TARGET_NAME)
set_target_properties(${TARGET_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY $<IF:$<BOOL:${WIN32}>,${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/python/ecal,${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/python/ecal>
)
endfunction()

# Function to add a python file as a sample to a Visual Studio Solution
# It can then be started / debugged directly from within Visual Studio
# Other generators are not supported at this time.
function(ecal_python_add_sample)
set(singleValueArgs PY_FILE TARGET_NAME)
cmake_parse_arguments(ARGUMENTS
""
"${singleValueArgs}"
"" ${ARGN} )

set(ECAL_PYPROJ_FILE ${ARGUMENTS_PY_FILE})
string(UUID ECAL_PYPROJ_GUID NAMESPACE 8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942 NAME ${ARGUMENTS_TARGET_NAME}
TYPE MD5)
get_target_property(ECAL_PYPROJ_INTERPRETER_DEBUG Python::Interpreter LOCATION)
get_target_property(ECAL_PYPROJ_INTERPRETER_RELEASE Python::Interpreter LOCATION)

set(ECAL_PYPROJ_NAME ${ARGUMENTS_TARGET_NAME})
cmake_path(GET ECAL_PYPROJ_INTERPRETER_RELEASE PARENT_PATH ECAL_PYPROJ_PYTHON_ROOT)
set(ECAL_PYPROJ_PYTHON_VERSION ${Python_VERSION})
set(ECAL_PYPROJ_SEARCH_PATH_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/python)
set(ECAL_PYPROJ_SEARCH_PATH_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/python)
set(ECAL_PYPROJ_SEARCH_PATH_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/RelWithDebInfo/python/ecal)

set(generated_pyproj_path ${CMAKE_CURRENT_BINARY_DIR}/${ARGUMENTS_TARGET_NAME}.pyproj)

# Generate the .pyproj file from the template
configure_file(
${ECAL_PYTHON_DIRECTORY}/sample.pyproj.in
${generated_pyproj_path}
@ONLY
)

include_external_msproject(${ARGUMENTS_TARGET_NAME} ${generated_pyproj_path})
endfunction()

# Convenience target to have all Python targets buildable via one name
add_custom_target(${PROJECT_NAME})

Expand All @@ -47,3 +139,17 @@ else()
message(WARNING "Building Python bindings without HDF5 support")
endif()

if (ECAL_PYTHON_BUILD_SAMPLES)
add_subdirectory(samples)
endif()

# This is a custom target to copy the eCAL core dll to the output directory of the Python extensions.
# Without this copying step, debugging would not be possible.
if (WIN32)
add_custom_target(copy_ecal_core_dll ALL
COMMAND cmake -E copy_if_different "$<TARGET_FILE:eCAL::core>" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>/python/ecal"
COMMENT "Copy eCAL Core DLL to python directory"
DEPENDS eCAL::core
)
set_property(TARGET copy_ecal_core_dll PROPERTY FOLDER lang/python/core)
endif()
51 changes: 41 additions & 10 deletions lang/python/core/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ========================= eCAL LICENSE =================================
#
# Copyright (C) 2016 - 2019 Continental Corporation
# Copyright (C) 2016 - 2024 Continental Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -18,33 +18,64 @@

project(_ecal_core_py)

######
# build
######
python_add_library(${PROJECT_NAME} MODULE WITH_SOABI
src/ecal_clang.cpp
src/ecal_clang.h
src/ecal_wrap.cxx
)

set(python_files
ecal/__init__.py
ecal/core/__init__.py
ecal/core/core.py
ecal/core/publisher.py
ecal/core/service.py
ecal/core/subscriber.py
ecal/proto/__init__.py
ecal/proto/helper.py
)

target_sources(${PROJECT_NAME}
PUBLIC
FILE_SET ecal_core_python_files
TYPE HEADERS
BASE_DIRS .
FILES
${python_files}
)

target_link_libraries(${PROJECT_NAME}
PRIVATE
eCAL::core
)

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14)

set_target_properties(${PROJECT_NAME} PROPERTIES
FOLDER lang/python/core
)

########
# installation
########
install(TARGETS ${PROJECT_NAME} core
RUNTIME DESTINATION ecal COMPONENT python EXCLUDE_FROM_ALL
LIBRARY DESTINATION ecal COMPONENT python EXCLUDE_FROM_ALL NAMELINK_SKIP
)

if(ECAL_INCLUDE_PY_SAMPLES)
if(WIN32)

include_external_msproject(ecal_core_py ${CMAKE_CURRENT_SOURCE_DIR}/ecal_core_py.pyproj)
set_property(TARGET ecal_core_py PROPERTY FOLDER lang/python/core)
##############
# IDE appearance
##############
set_target_properties(${PROJECT_NAME} PROPERTIES
FOLDER lang/python/core
)
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Python Files" FILES ${python_files})


##########
# IDE Debugging / Runtime
###########
copy_python_code(TARGET ${PROJECT_NAME} PYTHON_FILES ${python_files} PYTHON_CODE_ROOT .)

endif()
endif()
ecal_python_set_output_directory(${PROJECT_NAME})
47 changes: 36 additions & 11 deletions lang/python/ecalhdf5/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ========================= eCAL LICENSE =================================
#
# Copyright (C) 2016 - 2019 Continental Corporation
# Copyright (C) 2016 - 2024 Continental Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -18,21 +18,39 @@

project(_ecal_hdf5_py)

######
# build
######
python_add_library(${PROJECT_NAME} MODULE WITH_SOABI
src/ecalhdf5_wrap.cxx
)

set(python_files
ecal/measurement/hdf5.py
ecal/measurement/measurement.py
ecal/measurement/writer.py
ecal/measurement/__init__.py
)

target_sources(${PROJECT_NAME}
PUBLIC
FILE_SET ecal_hdf5_python_files
TYPE HEADERS
BASE_DIRS .
FILES
${python_files}
)

target_link_libraries(${PROJECT_NAME}
PRIVATE
eCAL::hdf5
)

target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14)

set_target_properties(${PROJECT_NAME} PROPERTIES
FOLDER lang/python/hdf5
)

########
# installation
########
if(TARGET hdf5-shared)
install(TARGETS ${PROJECT_NAME} hdf5-shared
RUNTIME DESTINATION ecal COMPONENT python EXCLUDE_FROM_ALL
Expand All @@ -44,11 +62,18 @@ install(TARGETS ${PROJECT_NAME}
DESTINATION ecal COMPONENT python EXCLUDE_FROM_ALL
)

if(ECAL_INCLUDE_PY_SAMPLES)
if(WIN32)

include_external_msproject(ecal_hdf5_py ${CMAKE_CURRENT_SOURCE_DIR}/ecal_hdf5_py.pyproj)
set_property(TARGET ecal_hdf5_py PROPERTY FOLDER lang/python/hdf5)
##############
# IDE appearance
##############
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" PREFIX "Python Files" FILES ${python_files})
set_target_properties(${PROJECT_NAME} PROPERTIES
FOLDER lang/python/hdf5
)

##########
# IDE Debugging / Runtime
###########
copy_python_code(TARGET ${PROJECT_NAME} PYTHON_FILES ${python_files} PYTHON_CODE_ROOT .)

endif()
endif()
ecal_python_set_output_directory(${PROJECT_NAME})
50 changes: 50 additions & 0 deletions lang/python/sample.pyproj.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == 'Release' "></Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>@ECAL_PYPROJ_GUID@</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>@ECAL_PYPROJ_FILE@</StartupFile>
<SearchPath>@ECAL_PYPROJ_SEARCH_PATH_RELEASE@</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<Name>@ECAL_PYPROJ_NAME@</Name>
<RootNamespace>@ECAL_PYPROJ_NAME@</RootNamespace>
<InterpreterId>MSBuild|debugging-env|$(MSBuildProjectFullPath)</InterpreterId>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'RelWithDebInfo' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
<ItemGroup>
<Compile Include="@ECAL_PYPROJ_FILE@" />
</ItemGroup>
<ItemGroup>
<Interpreter Include="@ECAL_PYPROJ_PYTHON_ROOT@">
<Id>debugging-env</Id>
<Version>0.0</Version>
<Description>eCAL Debugging Environment (Python @ECAL_PYPROJ_PYTHON_VERSION@ )</Description>
<InterpreterPath>@ECAL_PYPROJ_INTERPRETER_RELEASE@</InterpreterPath>
<WindowsInterpreterPath>@ECAL_PYPROJ_INTERPRETER_RELEASE@</WindowsInterpreterPath>
<PathEnvironmentVariable>PYTHONPATH</PathEnvironmentVariable>
<Architecture>X64</Architecture>
</Interpreter>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" />
<!-- Uncomment the CoreCompile target to enable the Build command in
Visual Studio and specify your pre- and post-build commands in
the BeforeBuild and AfterBuild targets below. -->
<!--<Target Name="CoreCompile" />-->
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
</Project>
Loading

0 comments on commit e54d371

Please sign in to comment.