build: Stop using MSYS2 to build OpenRV (ffmpeg still need some binaries from MSYS2)#36
Open
cedrik-fuoco-adsk wants to merge 12 commits into
Open
build: Stop using MSYS2 to build OpenRV (ffmpeg still need some binaries from MSYS2)#36cedrik-fuoco-adsk wants to merge 12 commits into
cedrik-fuoco-adsk wants to merge 12 commits into
Conversation
) ### Build faster with ccache (or scache on Windows). ### Summarize your change. The branch adds ccache (or scache for Windows) to the build system if its installed on the user's machine. If they do not have it installed, it will simply not be used (they will receive a message in the shell though that it is disabled and how they can install it). I also updated the docs with first time setup instructions on how to install the cache. Note that I modified the CICD to install ccache and scache so we can take advantage of it there. I also added check that the user will be warned when their cache is more than 90% full to either clean it or increase its size or disable the caching. The goal of this is to speed up builds. The cache will store object files such that when they have not changed since they were last cached, we do not need to rebuild them. From my benchmarking on a Mac M4 Pro with OS 26.2 the build time for a clean build went from 25 minutes to 12 when nothing changes. ### Describe the reason for the change. Build faster ### Describe what you have tested and on which operating system. Building on OS 26.2 --------- Signed-off-by: Roger Nelson <roger.nelson@autodesk.com>
On Windows, use a Python script (apply_sed.py) instead of the sed binary for applying .sed filter scripts during configure. The Python re module natively supports PCRE lookbehinds used in flexfilter.sed. Non-Windows platforms continue using sed unchanged.
… (Phase 1.2) On Windows, try win_flex before falling back to flex (for MSYS2 backward compat). Replace bash one-liners for version detection and Apple flex detection with CMake STRING(REGEX) and STRING(FIND) operations that work on all platforms without bash.
On Windows, try win_bison before falling back to bison (for MSYS2 backward compat). Remove the FIND_PROGRAM(_sed sed) call which was dead code — SED_IT() uses the _sed from rv_sed.cmake module scope.
Replace bash -c "cat | grep | grep" pipeline for extracting package versions from .rvpkg files with CMake FILE(READ) + STRING(REGEX MATCH). This is an unconditional cross-platform improvement.
Replace bash -c "sed -f signalspy.sed ..." with a CMake script-mode file (apply_signalspy_filter.cmake) that parses the sed file and applies literal STRING(REPLACE) substitutions. Works on all platforms without requiring bash or sed.
Signed-off-by: Cédrik Fuoco <cedrik.fuoco@autodesk.com>
…n Windows (Phase 2) PCRE2: Switch from autotools (sh ./autogen.sh, sh ./configure, make) to CMake-based ExternalProject_Add using the standard macro helpers. Update library naming from MinGW format (libpcre2-8-0.dll, .dll.a) to MSVC format (pcre2-8.dll, pcre2-8.lib). Handle PCRE2's internal debug postfix 'd' for Debug builds (pcre2-8d.dll, pcre2-8d.lib). Atomic Ops: Add Windows-specific CMake build path with -Denable_gpl=OFF (equivalent of --disable-gpl). Keep autotools for Linux/macOS. Use portable library naming via CMAKE_STATIC_LIBRARY_PREFIX/SUFFIX. Both changes are backward-compatible with MSYS2-based CI.
…ows (Phase 3) FFmpeg requires bash (for ./configure) and make, which previously came from MSYS2. Add a Python wrapper script that finds bash from Git for Windows (with MSYS2 fallback) and handles Windows-to-Unix path conversion for PKG_CONFIG_PATH, removing the hard MSYS2 dependency. The CMake side now delegates configure/build/install commands through the wrapper on Windows while keeping Unix paths completely untouched.
The Windows path in RV_COPY_LIB_BIN_FOLDERS used POST_BUILD on the dependency target plus ADD_CUSTOM_TARGET(DEPENDS file). This creates a broken dependency chain: the stage-target has no build-order dependency on the actual build target, so MSBuild can evaluate the staging before the build/install completes, or skip it entirely when the target is considered up-to-date. Switch to the same OUTPUT+DEPENDS pattern used on non-Windows, which creates a proper chain: stage-target -> output file -> copy commands -> depends on build target. Also add make_directory before copy_directory as a safety net for edge cases where the install step doesn't create the expected lib/ or bin/ directories. Fixes intermittent OIIO staging failure on CY2024 Windows Release.
Add rvcmds.ps1 as the PowerShell equivalent of rvcmds.sh, enabling Windows developers to configure, build, and test OpenRV without MSYS2. Includes rvcmds.bat as a thin CMD wrapper for non-PowerShell users.
Replace MSYS2 shell and packages with native Windows tools: - CI: choco install winflexbison3/nasm/make/ninja/pkgconfiglite, pip install meson, add Git usr/bin to PATH for patch/touch/true - Convert all shell: msys2 steps to PowerShell syntax - Use short TEMP path (D:\t) to avoid Windows MAX_PATH errors - Inline Qt path via GitHub Actions expressions - FFmpeg build: run make directly with SHELL=<bash> override so recipes execute through bash (fixes awk quoting in ffbuild/common.mak) - Update docs/build_system/config_windows.md with new prerequisites - Add rvcmds.cmd batch script for Windows build orchestration
cedrik-fuoco-adsk
pushed a commit
that referenced
this pull request
Feb 26, 2026
…ftwareFoundation#1122) ### Fix crash calling sourcesAtFrame at session clear. ### Summarize your change. If sourcesAtFrame is called in an event from which the graph is cleared (`graph-node-inputs-changed` in my case, but it could be anything that clears the graph), RV will crash with a stack resembling the below: ``` * thread #1, name = 'RV Main', queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x793bcc0f30f4744a) * frame #0: 0x00000001003e8688 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a96080780, c=0x000000016fdf6290, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31 frame #1: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a96080a00, context=0x000000016fdf6290, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #2: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a96074000, context=0x000000016fdf6290, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #3: 0x00000001007d5eb0 RV`IPCore::RetimeIPNode::metaEvaluate(this=0x0000000a96074000, context=0x000000016fdf6378, visitor=0x000000016fdf6c40) at RetimeIPNode.cpp:661:17 frame #4: 0x00000001007e1790 RV`IPCore::StackIPNode::metaEvaluate(this=0x0000000a94a2f100, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at StackIPNode.cpp:791:25 frame #5: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a9320d500, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #6: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf2080, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25 frame #7: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94774a00, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31 frame #8: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94cf8c80, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31 frame #9: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0500, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25 frame #10: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a8cd01500, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #11: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a95bf0280, context=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #12: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0a00, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25 frame #13: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a94cf8780, c=0x000000016fdf67f0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31 frame #14: 0x00000001003f4a40 RV`IPCore::DisplayStereoIPNode::metaEvaluate(this=0x0000000a95437480, context=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at DisplayStereoIPNode.cpp:393:20 frame #15: 0x00000001003e8690 RV`IPCore::AdaptorIPNode::metaEvaluate(this=0x0000000a947bd180, c=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at AdaptorIPNode.cpp:92:31 frame #16: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a95b96800, context=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #17: 0x000000010040cefc RV`IPCore::GroupIPNode::metaEvaluate(this=0x0000000a95bf0f00, c=0x000000016fdf69d0, visitor=0x000000016fdf6c40) at GroupIPNode.cpp:114:25 frame #18: 0x00000001003ee27c RV`IPCore::DisplayGroupIPNode::metaEvaluate(this=0x0000000a93e41500, context=0x000000016fdf6bb8, visitor=0x000000016fdf6c40) at DisplayGroupIPNode.cpp:425:21 frame #19: 0x000000010027b920 RV`IPCore::IPNode::metaEvaluate(this=0x0000000a94774780, context=0x000000016fdf6bb8, visitor=0x000000016fdf6c40) at IPNode.cpp:408:23 frame #20: 0x00000001006ce2b4 RV`IPMu::sourcesAtFrame(node_=0x000000013a849440, thread_=0x0000000117748e00) at CommandsModule.cpp:1937:28 frame #21: 0x0000000100e7a890 RV`Mu::DynamicArrayType::nodeEval(this=0x00000001176fcdc0, n=0x000000013a849440, thread=0x0000000117748e00) const at DynamicArrayType.cpp:78:90 frame #22: 0x0000000100076e80 RV`Mu::Node::eval(this=0x000000013a849440, t=0x0000000117748e00) const at Node.cpp:142:62 frame #23: 0x00000001000a92ac RV`Mu::Thread::call(this=0x0000000117748e00, f=0x0000000117e86d20, args=size=1, returnArguments=false) at Thread.cpp:422:23 frame #24: 0x00000001001d2e2c RV`TwkApp::MuSymbol_call(_self=0x000000011b52a7f0, args=0x000000030a0d8bb0, kwds=0x0000000000000000) at PyMuSymbolType.cpp:389:48 frame #25: 0x0000000108d17350 libpython3.11.dylib`_PyObject_MakeTpCall(tstate=0x00000001090a3c30, callable=0x000000011b52a7f0, args=<unavailable>, nargs=<unavailable>, keywords=0x0000000000000000) at call.c:214:18 [opt] frame #26: 0x0000000108d17850 libpython3.11.dylib`PyObject_Vectorcall [inlined] _PyObject_VectorcallTstate(tstate=<unavailable>, callable=<unavailable>, args=<unavailable>, nargsf=<unavailable>, kwnames=<unavailable>) at pycore_call.h:90:16 [opt] [artificial] frame #27: 0x0000000108df4dc0 libpython3.11.dylib`_PyEval_EvalFrameDefault(tstate=<unavailable>, frame=0x000000010a6f01d8, throwflag=<unavailable>) at ceval.c:0 [opt] frame #28: 0x0000000108df05fc libpython3.11.dylib`_PyEval_Vector [inlined] _PyEval_EvalFrame(tstate=0x00000001090a3c30, frame=0x000000010a6f01d8, throwflag=0) at pycore_ceval.h:73:16 [opt] frame #29: 0x0000000108df05ec libpython3.11.dylib`_PyEval_Vector(tstate=0x00000001090a3c30, func=<unavailable>, locals=<unavailable>, args=<unavailable>, argcount=<unavailable>, kwnames=<unavailable>) at ceval.c:6434:24 [opt] frame #30: 0x0000000108d19f24 libpython3.11.dylib`method_vectorcall [inlined] _PyObject_VectorcallTstate(tstate=0x00000001090a3c30, callable=0x000000013792e7a0, args=0x000000016fdf7ab0, nargsf=<unavailable>, kwnames=0x0000000000000000) at pycore_call.h:92:11 [opt] frame #31: 0x0000000108d19efc libpython3.11.dylib`method_vectorcall(method=<unavailable>, args=0x000000030a0d8268, nargsf=<unavailable>, kwnames=0x0000000000000000) at classobject.c:89:18 [opt] frame #32: 0x00000001001cf9d4 RV`TwkApp::PyFunctionAction::execute(this=0x0000000a8fade490, d=0x0000000a912c6000, event=0x000000016fdf7f28) const at PyFunctionAction.cpp:58:17 frame #33: 0x00000001006612a8 RV`TwkApp::Document::executeAction(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Document.cpp:486:20 frame #34: 0x0000000100661b7c RV`TwkApp::Document::receiveEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Document.cpp:613:9 frame #35: 0x000000010066fc38 RV`TwkApp::EventNode::propagateEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at EventNode.cpp:71:13 frame #36: 0x00000001001ecd94 RV`IPCore::Session::propagateEvent(this=0x0000000a912c6000, event=0x000000016fdf7f28) at Session.cpp:4644:43 frame #37: 0x000000010066fca8 RV`TwkApp::EventNode::propagateEvent(this=0x0000000a909c9800, event=0x000000016fdf7f28) at EventNode.cpp:82:24 frame #38: 0x000000010066fc00 RV`TwkApp::EventNode::sendEvent(this=0x0000000a909c9800, event=0x000000016fdf7f28) at EventNode.cpp:60:16 frame #39: 0x000000010038b604 RV`IPCore::IPGraph::inputsChanged(this=0x0000000a909c9800, n=0x0000000a8d8b2800) at IPGraph.cpp:3449:13 frame #40: 0x000000010027af8c RV`IPCore::IPNode::setInputs(this=0x0000000a8d8b2800, nodes=size=0) at IPNode.cpp:303:26 frame #41: 0x0000000100279c4c RV`IPCore::IPNode::removeInput(this=0x0000000a8d8b2800, n=0x0000000a94a30500) at IPNode.cpp:166:13 frame #42: 0x000000010027984c RV`IPCore::IPNode::~IPNode(this=0x0000000a94a30500) at IPNode.cpp:57:32 frame #43: 0x000000010040c900 RV`IPCore::GroupIPNode::~GroupIPNode(this=0x0000000a94a30500) at GroupIPNode.cpp:48:5 frame #44: 0x0000000100807490 RV`IPCore::SwitchGroupIPNode::~SwitchGroupIPNode(this=0x0000000a94a30500) at SwitchGroupIPNode.cpp:42:5 ``` Notice the destructors are triggering a sourcesAtFrame call, which then tries to access those same objects being destroyed resulting in a use-after-free crash. To fix this, we'll set a guard when the graph is being cleared, and if sourcesAtFrame is called when the guard is set, we'll return an empty array. This is the as what would happen if you called sourcesAtFrame when there were no sources (ie after the graph was cleared). So we'll just return the eventual result early, which is likely what the users want anyway, and this will protect python events from crashing RV. ### Describe the reason for the change. Prevent crashes ### Describe what you have tested and on which operating system. Mac OS 26.2 --------- Signed-off-by: Roger Nelson <roger.nelson@autodesk.com>
d6e4f78 to
fc56b22
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issues
Summarize your change.
Describe the reason for the change.
Describe what you have tested and on which operating system.
Add a list of changes, and note any that might need special attention during the review.
If possible, provide screenshots.