Skip to content

Commit

Permalink
Merge pull request #311 from christian-rauch/test_shared_off
Browse files Browse the repository at this point in the history
enable Python bindings for Windows and macOS
  • Loading branch information
christian-rauch authored Jan 30, 2024
2 parents 9b586ba + 68ab7e3 commit 7a47a11
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 113 deletions.
48 changes: 23 additions & 25 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms
name: CMake

on:
push:
Expand All @@ -13,19 +11,11 @@ jobs:
runs-on: ${{ matrix.os }}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
build_type: [Release]
c_compiler: [gcc, clang, cl]
shared_libs: ['ON', 'OFF']
include:
- os: windows-latest
c_compiler: cl
Expand All @@ -45,20 +35,18 @@ jobs:
- os: macos-latest
c_compiler: clang
cpp_compiler: clang++
- os: macos-latest
c_compiler: gcc
cpp_compiler: g++
exclude:
- os: ubuntu-latest
c_compiler: cl
- os: macos-latest
c_compiler: cl
- os: macos-latest
c_compiler: gcc

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
Expand All @@ -68,23 +56,33 @@ jobs:

- uses: ilammy/msvc-dev-cmd@v1

- uses: actions/setup-python@v5
with:
python-version: '3.10'

- run: pip install numpy

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-G Ninja
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-D CMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-D CMAKE_C_COMPILER=${{ matrix.c_compiler }}
-D CMAKE_BUILD_TYPE=${{ matrix.build_type }}
-D BUILD_SHARED_LIBS=${{ matrix.shared_libs }}
-S ${{ github.workspace }}
- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

- name: Install (Windows)
if: matrix.os == 'windows-latest'
run: Start-Process -Verb RunAs -FilePath cmake "--build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --target install"

- name: Install (sudo)
if: matrix.os != 'windows-latest'
run: sudo cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --target install

- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config ${{ matrix.build_type }}
4 changes: 2 additions & 2 deletions .github/workflows/colcon-workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
strategy:
matrix:
ros_distribution: [noetic, humble]
cmake_shared_libs: ['OFF']
cmake_shared_libs: ['ON', 'OFF']
include:
- ros_distribution: noetic
ros_version: 1
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
strategy:
matrix:
ros_distribution: [humble]
cmake_shared_libs: ['OFF']
cmake_shared_libs: ['ON', 'OFF']

steps:
- uses: actions/checkout@v4
Expand Down
279 changes: 279 additions & 0 deletions CMake/vtkEncodeString.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
#[==[
Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
of any contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#]==]

#[==[
@file vtkEncodeString.cmake
This module contains the @ref vtk_encode_string function which may be used to
turn a file into a C string. This is primarily used within a program so that
the content does not need to be retrieved from the filesystem at runtime, but
can still be developed as a standalone file.
#]==]

set(_vtkEncodeString_script_file "${CMAKE_CURRENT_LIST_FILE}")

#[==[
@brief Encode a file as a C string at build time
Adds a rule to turn a file into a C string. Note that any Unicode characters
will not be replaced with escaping, so it is recommended to avoid their usage
in the input.
~~~
vtk_encode_string(
INPUT <input>
[NAME <name>]
[EXPORT_SYMBOL <symbol>]
[EXPORT_HEADER <header>]
[HEADER_OUTPUT <variable>]
[SOURCE_OUTPUT <variable>]
[ABI_MANGLE_SYMBOL_BEGIN <being>]
[ABI_MANGLE_SYMBOL_END <end>]
[ABI_MANGLE_HEADER <header>]
[BINARY] [NUL_TERMINATE])
~~~
The only required variable is `INPUT`, however, it is likely that at least one
of `HEADER_OUTPUT` or `SOURCE_OUTPUT` will be required to add them to a
library.
* `INPUT`: (Required) The path to the file to be embedded. If a relative path
is given, it will be interpreted as being relative to
`CMAKE_CURRENT_SOURCE_DIR`.
* `NAME`: This is the base name of the files that will be generated as well
as the variable name for the C string. It defaults to the basename of the
input without extensions.
* `EXPORT_SYMBOL`: The symbol to use for exporting the variable. By default,
it will not be exported. If set, `EXPORT_HEADER` must also be set.
* `EXPORT_HEADER`: The header to include for providing the given export
symbol. If set, `EXPORT_SYMBOL` should also be set.
* `HEADER_OUTPUT`: The variable to store the generated header path.
* `SOURCE_OUTPUT`: The variable to store the generated source path.
* `BINARY`: If given, the data will be written as an array of `unsigned char`
bytes.
* `NUL_TERMINATE`: If given, the binary data will be `NUL`-terminated. Only
makes sense with the `BINARY` flag. This is intended to be used if
embedding a file as a C string exceeds compiler limits on string literals
in various compilers.
* `ABI_MANGLE_SYMBOL_BEGIN`: Open a mangling namespace with the given symbol.
If given, `ABI_MANGLE_SYMBOL_END` and `ABI_MANGLE_HEADER` must also be set.
* `ABI_MANGLE_SYMBOL_END`: Close a mangling namespace with the given symbol.
If given, `ABI_MANGLE_SYMBOL_BEGIN` and `ABI_MANGLE_HEADER` must also be set.
* `ABI_MANGLE_HEADER`: The header which provides the ABI mangling symbols.
If given, `ABI_MANGLE_SYMBOL_BEGIN` and `ABI_MANGLE_SYMBOL_END` must also
be set.
#]==]
function (vtk_encode_string)
cmake_parse_arguments(PARSE_ARGV 0 _vtk_encode_string
"BINARY;NUL_TERMINATE"
"INPUT;NAME;EXPORT_SYMBOL;EXPORT_HEADER;HEADER_OUTPUT;SOURCE_OUTPUT;ABI_MANGLE_SYMBOL_BEGIN;ABI_MANGLE_SYMBOL_END;ABI_MANGLE_HEADER"
"")

if (_vtk_encode_string_UNPARSED_ARGUMENTS)
message(FATAL_ERROR
"Unrecognized arguments to vtk_encode_string: "
"${_vtk_encode_string_UNPARSED_ARGUMENTS}")
endif ()

if (NOT DEFINED _vtk_encode_string_INPUT)
message(FATAL_ERROR
"Missing `INPUT` for vtk_encode_string.")
endif ()

if (NOT DEFINED _vtk_encode_string_NAME)
get_filename_component(_vtk_encode_string_NAME
"${_vtk_encode_string_INPUT}" NAME_WE)
endif ()

if (DEFINED _vtk_encode_string_EXPORT_SYMBOL AND
NOT DEFINED _vtk_encode_string_EXPORT_HEADER)
message(FATAL_ERROR
"Missing `EXPORT_HEADER` when using `EXPORT_SYMBOL`.")
endif ()

if (DEFINED _vtk_encode_string_EXPORT_HEADER AND
NOT DEFINED _vtk_encode_string_EXPORT_SYMBOL)
message(WARNING
"Missing `EXPORT_SYMBOL` when using `EXPORT_HEADER`.")
endif ()

if (DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_BEGIN AND
(NOT DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_END OR
NOT DEFINED _vtk_encode_string_ABI_MANGLE_HEADER))
message(WARNING
"Missing `ABI_MANGLE_SYMBOL_END` or `ABI_MANGLE_HEADER` when using "
"`ABI_MANGLE_SYMBOL_BEGIN`.")
endif ()

if (DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_END AND
(NOT DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_BEGIN OR
NOT DEFINED _vtk_encode_string_ABI_MANGLE_HEADER))
message(WARNING
"Missing `ABI_MANGLE_SYMBOL_BEGIN` or `ABI_MANGLE_HEADER` when using "
"`ABI_MANGLE_SYMBOL_END`.")
endif ()

if (DEFINED _vtk_encode_string_ABI_MANGLE_HEADER AND
(NOT DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_BEGIN OR
NOT DEFINED _vtk_encode_string_ABI_MANGLE_SYMBOL_END))
message(WARNING
"Missing `ABI_MANGLE_SYMBOL_BEGIN` or `ABI_MANGLE_SYMBOL_END` when "
"using `ABI_MANGLE_HEADER`.")
endif ()

if (NOT _vtk_encode_string_BINARY AND _vtk_encode_string_NUL_TERMINATE)
message(FATAL_ERROR
"The `NUL_TERMINATE` flag only makes sense with the `BINARY` flag.")
endif ()

set(_vtk_encode_string_header
"${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.h")
set(_vtk_encode_string_source
"${CMAKE_CURRENT_BINARY_DIR}/${_vtk_encode_string_NAME}.cxx")

if (IS_ABSOLUTE "${_vtk_encode_string_INPUT}")
set(_vtk_encode_string_input
"${_vtk_encode_string_INPUT}")
else ()
set(_vtk_encode_string_input
"${CMAKE_CURRENT_SOURCE_DIR}/${_vtk_encode_string_INPUT}")
endif ()

set(_vtk_encode_string_depends_args)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.27")
list(APPEND _vtk_encode_string_depends_args
DEPENDS_EXPLICIT_ONLY)
endif ()

add_custom_command(
OUTPUT ${_vtk_encode_string_header}
${_vtk_encode_string_source}
DEPENDS "${_vtkEncodeString_script_file}"
"${_vtk_encode_string_input}"
COMMAND "${CMAKE_COMMAND}"
"-Dsource_dir=${CMAKE_CURRENT_SOURCE_DIR}"
"-Dbinary_dir=${CMAKE_CURRENT_BINARY_DIR}"
"-Dsource_file=${_vtk_encode_string_input}"
"-Doutput_name=${_vtk_encode_string_NAME}"
"-Dexport_symbol=${_vtk_encode_string_EXPORT_SYMBOL}"
"-Dexport_header=${_vtk_encode_string_EXPORT_HEADER}"
"-Dabi_mangle_symbol_begin=${_vtk_encode_string_ABI_MANGLE_SYMBOL_BEGIN}"
"-Dabi_mangle_symbol_end=${_vtk_encode_string_ABI_MANGLE_SYMBOL_END}"
"-Dabi_mangle_header=${_vtk_encode_string_ABI_MANGLE_HEADER}"
"-Dbinary=${_vtk_encode_string_BINARY}"
"-Dnul_terminate=${_vtk_encode_string_NUL_TERMINATE}"
"-D_vtk_encode_string_run=ON"
-P "${_vtkEncodeString_script_file}"
${_vtk_encode_string_depends_args})

if (DEFINED _vtk_encode_string_SOURCE_OUTPUT)
set("${_vtk_encode_string_SOURCE_OUTPUT}"
"${_vtk_encode_string_source}"
PARENT_SCOPE)
endif ()

if (DEFINED _vtk_encode_string_HEADER_OUTPUT)
set("${_vtk_encode_string_HEADER_OUTPUT}"
"${_vtk_encode_string_header}"
PARENT_SCOPE)
endif ()
endfunction ()

if (_vtk_encode_string_run AND CMAKE_SCRIPT_MODE_FILE)
set(output_source "${binary_dir}/${output_name}.h")

set(license_topfile "// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen\n// SPDX-License-Identifier: BSD-3-Clause\n")
file(WRITE "${output_source}" ${license_topfile})

if (IS_ABSOLUTE "${source_file}")
set(source_file_full "${source_file}")
else ()
set(source_file_full "${source_dir}/${source_file}")
endif ()
set(hex_arg)
if (binary)
set(hex_arg HEX)
endif ()
file(READ "${source_file_full}" original_content ${hex_arg})

if (binary)
if (nul_terminate)
string(APPEND original_content "00")
endif ()
string(LENGTH "${original_content}" output_size)
math(EXPR output_size "${output_size} / 2")

file(APPEND "${output_source}"
"#include \"${output_name}.h\"\n\n")
if (abi_mangle_symbol_begin)
file(APPEND "${output_source}"
"${abi_mangle_symbol_begin}\n\n")
endif ()
file(APPEND "${output_source}"
"const unsigned char ${output_name}[${output_size}] = {\n")
string(REGEX REPLACE "\([0-9a-f][0-9a-f]\)" ",0x\\1" escaped_content "${original_content}")
# Hard line wrap the file.
string(REGEX REPLACE "\(..........................................................................,\)" "\\1\n" escaped_content "${escaped_content}")
# Remove the leading comma.
string(REGEX REPLACE "^," "" escaped_content "${escaped_content}")
file(APPEND "${output_source}"
"${escaped_content}\n")
file(APPEND "${output_source}"
"};\n")
if (abi_mangle_symbol_end)
file(APPEND "${output_source}"
"${abi_mangle_symbol_end}\n")
endif ()
else ()
# Escape literal backslashes.
string(REPLACE "\\" "\\\\" escaped_content "${original_content}")
# Escape literal double quotes.
string(REPLACE "\"" "\\\"" escaped_content "${escaped_content}")
# Turn newlines into newlines in the C string.
string(REPLACE "\n" "\\n\"\n\"" escaped_content "${escaped_content}")

if (abi_mangle_symbol_begin)
file(APPEND "${output_source}"
"${abi_mangle_symbol_begin}\n\n")
endif ()
file(APPEND "${output_source}"
"const char ${output_name}[] =\n")
file(APPEND "${output_source}"
"\"${escaped_content}\";\n")
if (abi_mangle_symbol_end)
file(APPEND "${output_source}"
"\n${abi_mangle_symbol_end}\n")
endif ()
endif ()
endif ()
Loading

0 comments on commit 7a47a11

Please sign in to comment.