Skip to content

Commit 9f6f571

Browse files
committed
InstallWizard macOS: full rewrite of runMac, prefer brew for gcc, clean flow
1 parent d407f79 commit 9f6f571

2 files changed

Lines changed: 67 additions & 84 deletions

File tree

mode/CppMode.jar

-56 Bytes
Binary file not shown.

src/java/InstallWizard.java

Lines changed: 67 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -423,122 +423,105 @@ private boolean runMac(java.util.List<String> missing) {
423423
if (missing.contains("glew")) missingLibs.add("glew");
424424

425425
Thread worker = new Thread(() -> {
426-
if (needsCompiler) {
427-
setStep("Installing: g++ (Xcode Command Line Tools)");
428-
try {
429-
new ProcessBuilder("xcode-select", "--install").start();
430-
} catch (Exception e) {
431-
appendLog("Could not launch the installer: " + e.getMessage());
432-
finishDialog(false, "Couldn't start the Xcode Command Line Tools installer.");
433-
return;
434-
}
435-
436-
// Poll for completion since xcode-select --install returns
437-
// immediately while the GUI installer runs separately.
438-
boolean installed = false;
439-
for (int i = 0; i < 180; i++) { // up to ~15 minutes
440-
if (cancelled.get()) return;
441-
try { Thread.sleep(5000); } catch (InterruptedException ignored) {}
442-
if (commandExists("xcrun", "-find", "g++")) { installed = true; break; }
443-
}
444-
445-
if (!installed) {
446-
finishDialog(false,
447-
"Still waiting on Xcode Command Line Tools — finish the install, then try again.");
448-
return;
449-
}
450-
}
451-
452-
if (cancelled.get()) return;
453-
454-
if (missingLibs.isEmpty()) {
455-
finishDialog(true, "Setup complete.");
456-
return;
457-
}
458-
459-
// Check for brew at known locations -- Processing may launch without
426+
// Resolve brew at known locations first -- Processing may launch without
460427
// /opt/homebrew/bin in PATH on Apple Silicon Macs.
461428
String brewExe = null;
462429
if (new File("/opt/homebrew/bin/brew").exists()) brewExe = "/opt/homebrew/bin/brew";
463430
else if (new File("/usr/local/bin/brew").exists()) brewExe = "/usr/local/bin/brew";
464431
else if (commandExists("brew", "--version")) brewExe = "brew";
432+
433+
// ── Step 1: compiler ────────────────────────────────────────────────
434+
if (needsCompiler) {
435+
if (brewExe != null) {
436+
// Homebrew present: install gcc fully in-app, no GUI popup needed.
437+
setStep("Installing: g++ (via Homebrew)");
438+
appendLog("Installing gcc via Homebrew...");
439+
try {
440+
ProcessBuilder pb = new ProcessBuilder(brewExe, "install", "gcc");
441+
pb.redirectErrorStream(true);
442+
Process proc = pb.start();
443+
streamToLog(proc);
444+
int code = proc.waitFor();
445+
if (cancelled.get()) return;
446+
if (code != 0) { finishDialog(false, "Failed to install gcc — see log above."); return; }
447+
} catch (Exception e) {
448+
finishDialog(false, "Couldn't run Homebrew: " + e.getMessage()); return;
449+
}
450+
} else {
451+
// No Homebrew: fall back to Xcode Command Line Tools GUI.
452+
setStep("Installing: g++ (Xcode Command Line Tools)");
453+
appendLog("Opening the Xcode Command Line Tools installer...");
454+
appendLog("Please complete the popup window, then wait here.");
455+
try { new ProcessBuilder("xcode-select", "--install").start(); }
456+
catch (Exception e) { finishDialog(false, "Couldn't start Xcode CLT installer."); return; }
457+
boolean installed = false;
458+
for (int i = 0; i < 180; i++) {
459+
if (cancelled.get()) return;
460+
try { Thread.sleep(5000); } catch (InterruptedException ignored) {}
461+
appendLog("Waiting for Xcode CLT... (" + ((i+1)*5) + "s)");
462+
if (commandExists("xcrun", "-find", "g++")) { installed = true; break; }
463+
}
464+
if (!installed) {
465+
finishDialog(false, "Xcode CLT not detected — finish the install and try again.");
466+
return;
467+
}
468+
}
469+
}
470+
if (cancelled.get()) return;
471+
if (missingLibs.isEmpty()) { finishDialog(true, "Setup complete."); return; }
472+
473+
// ── Step 2: GLFW / GLEW ─────────────────────────────────────────────
465474
if (brewExe == null) {
475+
// Still no Homebrew -- install it now.
466476
setStep("Installing Homebrew...");
467-
appendLog("Homebrew not found — installing it now.");
468-
appendLog("This downloads and runs the official Homebrew installer.");
469-
appendLog("You may be asked for your password in a separate prompt.");
477+
appendLog("Homebrew not found — installing it now (you may be asked for your password).");
470478
try {
471-
// Official Homebrew install script -- same as what brew.sh runs.
472-
// We pipe it to /bin/bash so no browser or manual step is needed.
473-
String installScript =
474-
"/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"";
475-
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", installScript);
479+
String script = "/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"";
480+
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", script);
476481
pb.redirectErrorStream(true);
477-
// Homebrew installer needs a real HOME and USER to set up paths.
478-
pb.environment().put("NONINTERACTIVE", "1"); // skip interactive prompts
479-
Process brewInstall = pb.start();
480-
streamToLog(brewInstall);
481-
int brewCode = brewInstall.waitFor();
482+
pb.environment().put("NONINTERACTIVE", "1");
483+
Process proc = pb.start();
484+
streamToLog(proc);
485+
int code = proc.waitFor();
482486
if (cancelled.get()) return;
483-
if (brewCode != 0) {
484-
finishDialog(false, "Homebrew installation failed — see log above.");
487+
if (code != 0) { finishDialog(false, "Homebrew installation failed — see log above."); return; }
488+
if (new File("/opt/homebrew/bin/brew").exists()) brewExe = "/opt/homebrew/bin/brew";
489+
else if (new File("/usr/local/bin/brew").exists()) brewExe = "/usr/local/bin/brew";
490+
if (brewExe == null) {
491+
finishDialog(false, "Homebrew installed but not found — restart Processing and try again.");
485492
return;
486493
}
487-
// Homebrew on Apple Silicon installs to /opt/homebrew; add to PATH.
488-
String brewPath = new File("/opt/homebrew/bin/brew").exists()
489-
? "/opt/homebrew/bin" : "/usr/local/bin";
490-
pb.environment().put("PATH", brewPath + ":" + System.getenv("PATH"));
491-
appendLog("Homebrew installed successfully.");
492494
} catch (Exception e) {
493-
appendLog("Error installing Homebrew: " + e.getMessage());
494-
finishDialog(false, "Couldn't install Homebrew — see log above.");
495-
return;
495+
finishDialog(false, "Couldn't install Homebrew: " + e.getMessage()); return;
496496
}
497-
// Verify brew is now available after install
498-
if (!new File("/opt/homebrew/bin/brew").exists()
499-
&& !new File("/usr/local/bin/brew").exists()
500-
&& !commandExists("brew", "--version")) {
501-
finishDialog(false,
502-
"Homebrew was installed but couldn't be found. Please restart Processing and try again.");
503-
return;
504-
}
505-
// Re-resolve brewExe after install
506-
if (new File("/opt/homebrew/bin/brew").exists()) brewExe = "/opt/homebrew/bin/brew";
507-
else if (new File("/usr/local/bin/brew").exists()) brewExe = "/usr/local/bin/brew";
508497
}
509498

510499
setStep("Installing: " + String.join(", ", missingLibs));
511500
try {
512-
java.util.List<String> brewCmd = new java.util.ArrayList<>();
513-
// Resolve brew path explicitly for Apple Silicon
514-
brewCmd.add(brewExe); brewCmd.add("install");
515-
brewCmd.addAll(missingLibs);
516-
ProcessBuilder brewPb = new ProcessBuilder(brewCmd);
517-
String brewPath = System.getenv("PATH");
518-
if (brewPath != null && !brewPath.contains("/opt/homebrew/bin"))
519-
brewPb.environment().put("PATH", "/opt/homebrew/bin:/usr/local/bin:" + brewPath);
520-
brewPb.redirectErrorStream(true);
521-
Process p = brewPb.start();
522-
streamToLog(p);
523-
int code = p.waitFor();
501+
java.util.List<String> cmd = new java.util.ArrayList<>();
502+
cmd.add(brewExe); cmd.add("install"); cmd.addAll(missingLibs);
503+
ProcessBuilder pb = new ProcessBuilder(cmd);
504+
pb.redirectErrorStream(true);
505+
Process proc = pb.start();
506+
streamToLog(proc);
507+
int code = proc.waitFor();
524508
if (cancelled.get()) return;
525509
if (code == 0) {
526-
finishDialog(true, "Setup complete.");
510+
finishDialog(true, "Setup complete! Restart Processing if needed.");
527511
} else {
528512
finishDialog(false, "Homebrew install exited with code " + code + " — see log above.");
529513
}
530514
} catch (Exception e) {
531-
appendLog("Error: " + e.getMessage());
532-
finishDialog(false, "Couldn't run Homebrew — see log above.");
515+
finishDialog(false, "Couldn't run Homebrew: " + e.getMessage());
533516
}
534517
});
535518
worker.setDaemon(true);
536519
worker.start();
537-
538520
showDialogAndWaitForClose();
539521
return succeeded.get();
540522
}
541523

524+
542525
// ── Linux ──────────────────────────────────────────────────────────────
543526

544527
// Package manager -> install command, matching CppBuild's existing

0 commit comments

Comments
 (0)