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
9 changes: 0 additions & 9 deletions .github/workflows/ci-scons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,6 @@ jobs:
run-tests: false
cache-name: windows-x86_64-msvc

- name: 🏁 Windows (x86_64, MinGW)
os: windows-2022
platform: windows
artifact-name: redot-cpp-linux-mingw-x86_64-release
artifact-path: bin/libredot-cpp.windows.template_release.x86_64.a
flags: use_mingw=yes
run-tests: false
cache-name: windows-x86_64-mingw

- name: 🍎 macOS (universal)
os: macos-latest
platform: macos
Expand Down
45 changes: 45 additions & 0 deletions tools/linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,49 @@ def exists(env):
return True


def configure(env):
import subprocess

Comment thread
coderabbitai[bot] marked this conversation as resolved.
def mySubProcess(cmdline, env):
import shlex

kwargs = {}
args = shlex.split(cmdline)

proc = subprocess.Popen(
args,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
stdin=subprocess.PIPE,
shell=False,
env=env,
**kwargs,
)
rv = proc.wait()
return rv

def mySpawn(sh, escape, cmd, args, env):
rv = 0
if len(args) > 512 and cmd.endswith("ar"):
cmdline = cmd + " " + args[1] + " " + args[2] + " "
for i in range(3, len(args), 510):
batch = args[i : i + 510]
line = cmdline + " ".join(batch)
print(line)
rv = mySubProcess(line, env)
if rv:
break
else:
newargs = " ".join(args[1:])
cmdline = cmd + " " + newargs
if cmd.endswith("ar"):
print(cmdline)
rv = mySubProcess(cmdline, env)

return rv

env["SPAWN"] = mySpawn
env.Replace(ARFLAGS=["q"])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

fd -t f "linux.py" --path "*/tools/*"

Repository: Redot-Engine/redot-cpp

Length of output: 300


🏁 Script executed:

cat -n tools/linux.py | head -80

Repository: Redot-Engine/redot-cpp

Length of output: 2998


🏁 Script executed:

rg -i "batch.*ar|ar.*batch" tools/linux.py -B 2 -A 2

Repository: Redot-Engine/redot-cpp

Length of output: 308


🏁 Script executed:

wc -l tools/linux.py

Repository: Redot-Engine/redot-cpp

Length of output: 85


🏁 Script executed:

cat -n tools/linux.py

Repository: Redot-Engine/redot-cpp

Length of output: 3805


🏁 Script executed:

rg "use_llvm" tools/linux.py -B 3 -A 3

Repository: Redot-Engine/redot-cpp

Length of output: 447


🏁 Script executed:

rg "ARFLAGS|ar\.command|\bAR\b" tools/linux.py -B 2 -A 2

Repository: Redot-Engine/redot-cpp

Length of output: 127


🏁 Script executed:

git log --oneline tools/linux.py | head -20

Repository: Redot-Engine/redot-cpp

Length of output: 136


🏁 Script executed:

git diff HEAD~5 tools/linux.py

Repository: Redot-Engine/redot-cpp

Length of output: 255


🏁 Script executed:

fd -t f "\.py$" tools/ | xargs rg -l "batch.*ar|ar.*batch" 2>/dev/null

Repository: Redot-Engine/redot-cpp

Length of output: 81


🏁 Script executed:

rg -i "batch.*ar|ar.*batch|archived.*batch" --type py

Repository: Redot-Engine/redot-cpp

Length of output: 123


🏁 Script executed:

rg "ar\.command|ARFLAGS" --type py -B 3 -A 3

Repository: Redot-Engine/redot-cpp

Length of output: 906


🏁 Script executed:

find . -name "*.gn" -o -name "*.gni" | head -20

Repository: Redot-Engine/redot-cpp

Length of output: 48


🏁 Script executed:

rg "ARFLAGS|ar_command|ar\.command" --type gn --type gni -B 2 -A 2 2>/dev/null | head -50

Repository: Redot-Engine/redot-cpp

Length of output: 48


🏁 Script executed:

rg -i "batch" --type gn | head -20

Repository: Redot-Engine/redot-cpp

Length of output: 215


🏁 Script executed:

cat tools/linux.py

Repository: Redot-Engine/redot-cpp

Length of output: 3105


🌐 Web query:

GNU ar command q flag behavior replace update

💡 Result:

In GNU ar, the q (quick append) flag is designed to add files to the end of an archive without checking for existing members with the same name [1][2][3]. Because it skips this check, it is faster than the r (replace) operation [1][4]. Key behaviors of the q flag include: 1. No Replacement: It does not replace existing members; it simply appends new files to the end of the archive [1][2]. 2. Placement: Modifiers such as a, b, or i, which are used to specify the position of new members, do not affect the q operation; new members are always placed at the end [1][3]. 3. Symbol Table: Historically, q did not update the archive's symbol table index to maintain speed [1][2]. However, because many systems expect the index to be current, GNU ar will rebuild the symbol table even when using q [2]. 4. Compatibility Note: GNU ar treats the command qs as a synonym for r, meaning it will replace existing files and append new ones [2][4][3]. 5. Incompatibility with u: The u (update) modifier, which only inserts files newer than those already in the archive, is not allowed with q because checking timestamps would negate the speed advantage of the quick append operation [1][4][3].

Citations:


🌐 Web query:

llvm-ar q flag quick append behavior duplicates

💡 Result:

The q (quick append) flag in llvm-ar is used to append files to the end of an archive without checking for or removing duplicates [1][2]. Because it does not perform any deduplication, it is generally faster than the r (replace) operation, which must scan the archive to identify and replace existing members with the same name [1][2]. If the specified archive does not exist, llvm-ar will create it [1][2].

Citations:


🏁 Script executed:

rg "use_llvm|ARFLAGS" tools/ -B 5 -A 5

Repository: Redot-Engine/redot-cpp

Length of output: 7173


Fix global ARFLAGS setting.

The q flag applies globally to all ar invocations on Linux, but only the batched path (lines 44-50) requires special handling to work around command-line length limits. Both GNU ar and llvm-ar implement q as quick append without deduplication, so the concern about incompatible behavior across toolchains is unfounded. However, forcing q globally still affects all archive operations; if needed, apply it conditionally only within the batched path to avoid unintended side effects elsewhere.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/linux.py` at line 57, The global env.Replace(ARFLAGS=["q"]) should be
removed and the ARFLAGS=["q"] setting applied only inside the batched ar
handling path (the code block that implements the batched/concatenated ar
invocation), so that other archive operations are unaffected; locate the batched
path in tools/linux.py (the block that builds the batched ar command) and set
ARFLAGS or pass the "q" flag locally there before invoking ar, leaving the
global env.ARFLAGS unchanged.



def generate(env):
if env["use_llvm"]:
clang.generate(env)
Expand Down Expand Up @@ -49,3 +92,5 @@ def generate(env):
env["lto"] = "full"

common_compiler_flags.generate(env)

configure(env)
27 changes: 17 additions & 10 deletions tools/my_spawn.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,11 @@ def mySubProcess(cmdline, env):
proc = subprocess.Popen(
cmdline,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
startupinfo=startupinfo,
shell=False,
env=env,
)
data, err = proc.communicate()
rv = proc.wait()
if rv:
print("=====")
print(err.decode("utf-8"))
print("=====")
return rv

def mySpawn(sh, escape, cmd, args, env):
Expand All @@ -37,9 +30,23 @@ def mySpawn(sh, escape, cmd, args, env):

rv = 0
if len(cmdline) > 32000 and cmd.endswith("ar"):
cmdline = cmd + " " + args[1] + " " + args[2] + " "
for i in range(3, len(args)):
rv = mySubProcess(cmdline + args[i], env)
cmdline_base = cmd + " " + args[1] + " " + args[2] + " "

i = 3
while i < len(args):
batch_args = []
current_len = len(cmdline_base)

while i < len(args) and current_len + len(args[i]) + 1 < 32000:
batch_args.append(args[i])
current_len += len(args[i]) + 1
i += 1

if not batch_args: # Should not happen unless a single arg is > 32000
batch_args.append(args[i])
i += 1

rv = mySubProcess(cmdline_base + " ".join(batch_args), env)
if rv:
break
else:
Expand Down
Loading