Skip to content
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
43 changes: 35 additions & 8 deletions cmake/macros/rv_lex.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,46 @@
#

INCLUDE(rv_sed)
FIND_PROGRAM(_lex flex NO_CACHE REQUIRED)

EXECUTE_PROCESS(
COMMAND bash "-c" "${_lex} --version | cut -d '.' -f 2"
OUTPUT_VARIABLE _flex_minor_version
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Find the lexer tool: prefer win_flex on Windows, fall back to flex
IF(RV_TARGET_WINDOWS)
FIND_PROGRAM(_lex win_flex NO_CACHE)
IF(NOT _lex)
FIND_PROGRAM(_lex flex NO_CACHE REQUIRED)
ENDIF()
ELSE()
FIND_PROGRAM(_lex flex NO_CACHE REQUIRED)
ENDIF()

# Get flex version using CMake string operations (no bash needed)
EXECUTE_PROCESS(
COMMAND bash "-c" "${_lex} --version | grep Apple | wc -l | ${_sed} 's/ //g'"
OUTPUT_VARIABLE _flex_apple
COMMAND ${_lex} --version
OUTPUT_VARIABLE _flex_version_output
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# Extract minor version: output is like "flex 2.6.4" or "win_flex 2.6.4"
STRING(REGEX MATCH "[0-9]+\\.([0-9]+)" _flex_version_match "${_flex_version_output}")
SET(_flex_minor_version
"${CMAKE_MATCH_1}"
)

# Detect Apple flex (only relevant on macOS)
IF(APPLE)
STRING(FIND "${_flex_version_output}" "Apple" _apple_pos)
IF(_apple_pos GREATER -1)
SET(_flex_apple
1
)
ELSE()
SET(_flex_apple
0
)
ENDIF()
ELSE()
SET(_flex_apple
0
)
ENDIF()

SET(RV_FLEX_MINOR_VERSION
${_flex_minor_version}
Expand Down
10 changes: 5 additions & 5 deletions cmake/macros/rv_sed.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
# SPDX-License-Identifier: Apache-2.0
#

FIND_PROGRAM(_sed sed NO_CACHE REQUIRED)
SET(_apply_sed_script
"${PROJECT_SOURCE_DIR}/cmake/scripts/apply_sed_filter.cmake"
)

#
# 01234567890123456789012345678901234567890123456789012345678901234567890123456789 ! sed_it2 : wraps a call to the 'sed' utility.
Expand Down Expand Up @@ -85,12 +87,10 @@ FUNCTION(sed_it)
MESSAGE(DEBUG "_temp: '${_temp}'")

#
# Actual SED operation
# Actual SED operation via CMake script mode
EXECUTE_PROCESS(
WORKING_DIRECTORY ${arg_OUTPUT_DIR}
COMMAND ${_sed} -f ${arg_INPUT_SED_FILE} ${arg_INPUT_FILE} COMMAND_ECHO STDOUT
OUTPUT_FILE ${_temp}
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND ${CMAKE_COMMAND} -DINPUT_FILE=${arg_INPUT_FILE} -DOUTPUT_FILE=${_temp} -DSED_FILE=${arg_INPUT_SED_FILE} -P ${_apply_sed_script} COMMAND_ECHO STDOUT
RESULT_VARIABLE _result_code COMMAND_ERROR_IS_FATAL ANY
)

Expand Down
14 changes: 5 additions & 9 deletions cmake/macros/rv_stage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -416,16 +416,12 @@ FUNCTION(rv_stage)

SET_DIRECTORY_PROPERTIES(PROPERTIES CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_package_file})

EXECUTE_PROCESS(
COMMAND bash -c "cat ${_package_file} | grep version: | grep --only-matching -e '[0-9.]*'"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _pkg_version
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
IF(_result
AND NOT _result EQUAL 0
FILE(READ "${CMAKE_CURRENT_SOURCE_DIR}/${_package_file}" _package_file_content)
STRING(REGEX MATCH "version:[ \t]*([0-9.]+)" _version_match "${_package_file_content}")
SET(_pkg_version
"${CMAKE_MATCH_1}"
)
IF(NOT _pkg_version)
MESSAGE(FATAL_ERROR "Error retrieving version field from '${_package_file}'")
ELSE()
MESSAGE(DEBUG "Found version for '${arg_TARGET}.rvpkg' package version ${_pkg_version} ...")
Expand Down
11 changes: 9 additions & 2 deletions cmake/macros/rv_yacc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@

FUNCTION(yacc_it)

FIND_PROGRAM(_yacc bison NO_CACHE REQUIRED)
FIND_PROGRAM(_sed sed NO_CACHE REQUIRED)
# Find the parser generator: prefer win_bison on Windows, fall back to bison
IF(RV_TARGET_WINDOWS)
FIND_PROGRAM(_yacc win_bison NO_CACHE)
IF(NOT _yacc)
FIND_PROGRAM(_yacc bison NO_CACHE REQUIRED)
ENDIF()
ELSE()
FIND_PROGRAM(_yacc bison NO_CACHE REQUIRED)
ENDIF()

SET(flags)
SET(args)
Expand Down
133 changes: 133 additions & 0 deletions cmake/scripts/apply_sed_filter.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#
# Copyright (C) 2026 Autodesk, Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

#
# CMake script-mode file for applying sed-style substitutions. Replaces bash+sed and Python-based approaches with pure CMake.
#
# Usage: cmake -DINPUT_FILE=<path> -DOUTPUT_FILE=<path> -DSED_FILE=<path> -P apply_sed_filter.cmake
#
# Supports: - Literal s/PATTERN/REPLACEMENT/ substitutions - PCRE negative lookbehind patterns (?<!PREFIX)MATCH via three-pass workaround - Any single-character
# delimiter after 's'
#

IF(NOT INPUT_FILE)
MESSAGE(FATAL_ERROR "INPUT_FILE not specified")
ENDIF()
IF(NOT OUTPUT_FILE)
MESSAGE(FATAL_ERROR "OUTPUT_FILE not specified")
ENDIF()
IF(NOT SED_FILE)
MESSAGE(FATAL_ERROR "SED_FILE not specified")
ENDIF()

FILE(READ "${INPUT_FILE}" _content)
FILE(READ "${SED_FILE}" _sed_content)

# Protect semicolons before splitting into CMake list (CMake uses ; as list separator)
STRING(REPLACE ";" "@@SEMICOLON@@" _sed_content "${_sed_content}")
STRING(REPLACE "\n" ";" _sed_lines "${_sed_content}")

SET(_placeholder_counter
0
)

FOREACH(
_line IN
LISTS _sed_lines
)
# Restore semicolons within each line
STRING(REPLACE "@@SEMICOLON@@" ";" _line "${_line}")
STRING(STRIP "${_line}" _line)

IF("${_line}" STREQUAL ""
OR "${_line}" MATCHES "^#"
)
CONTINUE()
ENDIF()

# Must start with 's'
STRING(SUBSTRING "${_line}" 0 1 _prefix)
IF(NOT "${_prefix}" STREQUAL "s")
CONTINUE()
ENDIF()

# Detect delimiter (char after 's')
STRING(SUBSTRING "${_line}" 1 1 _delim)
STRING(SUBSTRING "${_line}" 2 -1 _rest)

# Find delimiter separating pattern from replacement
STRING(FIND "${_rest}" "${_delim}" _split_pos)
IF(_split_pos EQUAL -1)
CONTINUE()
ENDIF()
STRING(SUBSTRING "${_rest}" 0 ${_split_pos} _pattern)
MATH(EXPR _repl_start "${_split_pos} + 1")
STRING(SUBSTRING "${_rest}" ${_repl_start} -1 _repl_rest)

# Find trailing delimiter
STRING(FIND "${_repl_rest}" "${_delim}" _end_pos)
IF(_end_pos GREATER -1)
STRING(SUBSTRING "${_repl_rest}" 0 ${_end_pos} _replacement)
ELSE()
SET(_replacement
"${_repl_rest}"
)
ENDIF()

# Check for PCRE negative lookbehind: (?<!PREFIX)MATCH
STRING(FIND "${_pattern}" "(?<!" _lb_pos)
IF(NOT _lb_pos EQUAL -1)
# Extract the lookbehind prefix
MATH(EXPR _prefix_start "${_lb_pos} + 4")
STRING(SUBSTRING "${_pattern}" ${_prefix_start} -1 _after_lb)
STRING(FIND "${_after_lb}" ")" _lb_end)
STRING(SUBSTRING "${_after_lb}" 0 ${_lb_end} _lb_prefix)

# Extract the bare match (after the closing paren)
MATH(EXPR _bare_start "${_lb_end} + 1")
STRING(SUBSTRING "${_after_lb}" ${_bare_start} -1 _bare_pattern)

# Unescape BRE special chars for literal matching
STRING(REPLACE "\\." "." _bare_pattern "${_bare_pattern}")
STRING(REPLACE "\\*" "*" _bare_pattern "${_bare_pattern}")
STRING(REPLACE "\\/" "/" _bare_pattern "${_bare_pattern}")

# Unescape replacement too
STRING(REPLACE "\\." "." _replacement "${_replacement}")
STRING(REPLACE "\\*" "*" _replacement "${_replacement}")
STRING(REPLACE "\\/" "/" _replacement "${_replacement}")

# The already-qualified form is prefix + bare_pattern
SET(_qualified
"${_lb_prefix}${_bare_pattern}"
)

# Three-pass workaround:
SET(_placeholder
"@@RV_SED_PLACEHOLDER_${_placeholder_counter}@@"
)
MATH(EXPR _placeholder_counter "${_placeholder_counter} + 1")

# Pass 1: Protect already-qualified occurrences
STRING(REPLACE "${_qualified}" "${_placeholder}" _content "${_content}")
# Pass 2: Qualify all remaining bare occurrences
STRING(REPLACE "${_bare_pattern}" "${_replacement}" _content "${_content}")
# Pass 3: Restore protected occurrences
STRING(REPLACE "${_placeholder}" "${_qualified}" _content "${_content}")
ELSE()
# Literal replacement — unescape BRE special chars
STRING(REPLACE "\\." "." _pattern "${_pattern}")
STRING(REPLACE "\\*" "*" _pattern "${_pattern}")
STRING(REPLACE "\\/" "/" _pattern "${_pattern}")

STRING(REPLACE "${_pattern}" "${_replacement}" _content "${_content}")
ENDIF()
ENDFOREACH()

FILE(
WRITE "${OUTPUT_FILE}"
"${_content}"
)
5 changes: 3 additions & 2 deletions src/lib/mu/MuQt5/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp
COMMAND
bash -c
"sed -f ${CMAKE_CURRENT_SOURCE_DIR}/signalspy.sed ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp >${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp"
${CMAKE_COMMAND} -DINPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp
-DOUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp -DSED_FILE=${CMAKE_CURRENT_SOURCE_DIR}/signalspy.sed -P
${PROJECT_SOURCE_DIR}/cmake/scripts/apply_sed_filter.cmake
COMMENT "Patching the moc_SignalSpy.cpp file ..."
)

Expand Down
5 changes: 3 additions & 2 deletions src/lib/mu/MuQt6/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,9 @@ ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp
COMMAND
bash -c
"sed -f ${CMAKE_CURRENT_SOURCE_DIR}/signalspy.sed ${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp >${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp"
${CMAKE_COMMAND} -DINPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy.cpp
-DOUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${_target}/generated/moc_SignalSpy_filtered.hpp -DSED_FILE=${CMAKE_CURRENT_SOURCE_DIR}/signalspy.sed -P
${PROJECT_SOURCE_DIR}/cmake/scripts/apply_sed_filter.cmake
COMMENT "Patching the moc_SignalSpy.cpp file ..."
)

Expand Down
Loading