Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/python samples and debugging #1768

Merged
merged 6 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading