From cb1657be17244e3e47e56d4233937d6b145e01c1 Mon Sep 17 00:00:00 2001 From: David G Yu Date: Mon, 12 Sep 2022 17:19:27 -0700 Subject: [PATCH] Implemented alternate Python 'stringify' tool This simplifies build dependencies when cross-compiling or when building multi-architecture binaries. For backward compatibility with earlier releases, the compiled C++ version of this tool is used when no Python interpreter is found. --- CMakeLists.txt | 33 ++++++++-- documentation/CMakeLists.txt | 2 - opensubdiv/CMakeLists.txt | 4 -- .../tools => tools}/stringify/CMakeLists.txt | 0 .../tools => tools}/stringify/main.cpp | 0 tools/stringify/stringify.py | 61 +++++++++++++++++++ 6 files changed, 89 insertions(+), 11 deletions(-) rename {opensubdiv/tools => tools}/stringify/CMakeLists.txt (100%) rename {opensubdiv/tools => tools}/stringify/main.cpp (100%) create mode 100644 tools/stringify/stringify.py diff --git a/CMakeLists.txt b/CMakeLists.txt index f2a15b4a..47bc34a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -394,6 +394,9 @@ else() set(DOXYGEN_EXECUTABLE ) endif() +# Python is used optionally to process source and documentation source files. +find_package(Python COMPONENTS Interpreter) + set(BUILD_SHARED_LIBS "${build_shared_libs}") # Warn about missing dependencies that will cause parts of OpenSubdiv to be @@ -717,18 +720,34 @@ macro(osd_add_doxy_headers headers) endmacro() # Kernel Stringification -# We want to use preprocessor include directives to include GLSL and OpenCL +# We want to use preprocessor include directives to include GLSL, OpenCL, etc. # kernel source files in cpp files, but since the sources contain newline # characters we would need raw string literals from C++11 to do this directly. -# To avoid depending on C++11 we instead use a small tool called "line_quote" +# To avoid depending on C++11 we instead use a small tool called "stringify" # to generate source files that are suitable for direct inclusion. + +# We provide a Python implementation for configurability, e.g. to +# use when cross compiling or building multi-architecture binaries. +# We also provide a C++ binary implementation so that Python is not +# required (for backward compatibility). +if (OPENGL_FOUND OR OPENCL_FOUND OR DXSDK_FOUND OR METAL_FOUND) + if(Python_Interpreter_FOUND) + set(OSD_STRINGIFY_TOOL ${CMAKE_CURRENT_SOURCE_DIR}/tools/stringify/stringify.py) + set(OSD_STRINGIFY ${Python_EXECUTABLE} ${OSD_STRINGIFY_TOOL}) + else() + set(OSD_STRINGIFY_TOOL stringify) + set(OSD_STRINGIFY ${OSD_STRINGIFY_TOOL}) + set(OSD_USES_STRINGIFY_TOOL_BINARY TRUE) + endif() +endif() + function(osd_stringify src_files varname) set(inc_files "") foreach(src_file ${src_files}) - string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}") + string(REGEX REPLACE ".*[.](.*)" "\\1" extension "${src_file}") string(REGEX REPLACE "(.*)[.].*" "\\1.gen.h" inc_file "${src_file}") list(APPEND inc_files "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}") @@ -737,9 +756,9 @@ function(osd_stringify src_files varname) OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}" COMMAND - stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}" + ${OSD_STRINGIFY} "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" "${CMAKE_CURRENT_BINARY_DIR}/${inc_file}" DEPENDS - stringify "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" + ${OSD_STRINGIFY_TOOL} "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}" ) endforeach() @@ -837,6 +856,10 @@ if (NOT NO_OPENGL) add_subdirectory(glLoader) endif() +if (OSD_USES_STRINGIFY_TOOL_BINARY) + add_subdirectory(tools/stringify) +endif() + add_subdirectory(opensubdiv) if (NOT ANDROID) # XXXdyu diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index e990018b..f86f2864 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -54,8 +54,6 @@ else() endif() -find_package(Python COMPONENTS Interpreter) - # ReST - HTML documentation if (DOCUTILS_FOUND AND Python_Interpreter_FOUND) diff --git a/opensubdiv/CMakeLists.txt b/opensubdiv/CMakeLists.txt index a8057ee8..477bc55b 100644 --- a/opensubdiv/CMakeLists.txt +++ b/opensubdiv/CMakeLists.txt @@ -55,10 +55,6 @@ if (NOT NO_LIB) ) endif() - if(OPENGL_FOUND OR OPENCL_FOUND OR DXSDK_FOUND OR METAL_FOUND) - add_subdirectory(tools/stringify) - endif() - if( OPENGL_FOUND ) include_directories(${OPENGL_LOADER_INCLUDE_DIRS}) list(APPEND PLATFORM_GPU_LIBRARIES diff --git a/opensubdiv/tools/stringify/CMakeLists.txt b/tools/stringify/CMakeLists.txt similarity index 100% rename from opensubdiv/tools/stringify/CMakeLists.txt rename to tools/stringify/CMakeLists.txt diff --git a/opensubdiv/tools/stringify/main.cpp b/tools/stringify/main.cpp similarity index 100% rename from opensubdiv/tools/stringify/main.cpp rename to tools/stringify/main.cpp diff --git a/tools/stringify/stringify.py b/tools/stringify/stringify.py new file mode 100644 index 00000000..c32f9c8a --- /dev/null +++ b/tools/stringify/stringify.py @@ -0,0 +1,61 @@ +# +# Copyright 2022 Pixar +# +# Licensed under the Apache License, Version 2.0 (the "Apache License") +# with the following modification; you may not use this file except in +# compliance with the Apache License and the following modification to it: +# Section 6. Trademarks. is deleted and replaced with: +# +# 6. Trademarks. This License does not grant permission to use the trade +# names, trademarks, service marks, or product names of the Licensor +# and its affiliates, except as required to comply with Section 4(c) of +# the License and to reproduce the content of the NOTICE file. +# +# You may obtain a copy of the Apache License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the Apache License with the above modification is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the Apache License for the specific +# language governing permissions and limitations under the Apache License. +# + +from __future__ import print_function +import sys + +def stringify(s): + withinStringConstant = False + + result = "" + for i in range(len(s)-1): + # escape double quotes + if s[i] == '"': + result += '\\' + withinStringConstant = not withinStringConstant + + if s[i] == '\\' and i == len(s)-2: + return '"' + result + '"\n' + + # escape backslash + if withinStringConstant and s[i] == '\\': + result += '\\' + + result += s[i] + + return '"' + result + '\\n"\n' + +def stringifyFile(inputFilename, outputFilename): + with open(inputFilename, "r") as inputFile, \ + open(outputFilename, "w") as outputFile: + for line in inputFile: + outputFile.write(stringify(line)) + outputFile.write('"\\n"\n') + +if len(sys.argv) != 3: + print("Usage: stringify input-file output-file") + sys.exit(1) + +stringifyFile(sys.argv[1], sys.argv[2]) +