Skip to content

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
staging-refactorfrom
remove-msys
Open

build: Stop using MSYS2 to build OpenRV (ffmpeg still need some binaries from MSYS2)#36
cedrik-fuoco-adsk wants to merge 12 commits into
staging-refactorfrom
remove-msys

Conversation

@cedrik-fuoco-adsk

Copy link
Copy Markdown
Owner

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.

rogernelson and others added 12 commits February 20, 2026 09:42
)

### 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>
@cedrik-fuoco-adsk cedrik-fuoco-adsk changed the title Remove msys build: Stop using MSYS2 to build OpenRV (ffmpeg still need some binaries from MSYS2) Feb 26, 2026
@cedrik-fuoco-adsk cedrik-fuoco-adsk force-pushed the staging-refactor branch 2 times, most recently from d6e4f78 to fc56b22 Compare March 2, 2026 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants