tools-build 2024-06-07

do I need to delete the :class-dir before building a jar? will stale class files influence the built jar?

✅ 1
Alex Miller (Clojure team) 2024-06-07T16:24:23.940449Z

I think it's a good idea to clean as part of building

👍 1

I have a problem where if I run a build, any subprocess spawned uses x86 native apps instead of arm64. So if I run in terminal:

cc -v
I get
Apple clang version 15.0.0 (clang-1500.1.0.2.5)
Target: arm64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
But if I stick this same call into a clojure build script I get: x86_64-apple-darwin23.5.0 as target. So if I put this in my build script and run clj -T:build compile
(println (System/getProperty "os.arch"))
      (println (sh/sh "cc" "-v"))
I get:
aarch64
{:exit 0, :out , :err Apple clang version 15.0.0 (clang-1500.1.0.2.5)
Target: x86_64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
}
So my JVM architecture is arm64 (aarch64), but the spawned process picks up the x86 version of every executable.

what about (System/getProperty "java.home")

/Library/Java/JavaVirtualMachines/graalvm-jdk-17.0.11+7.1/Contents/Home

Alex Miller (Clojure team) 2024-06-07T18:53:04.708629Z

how does cc determine the target architecture?

Ok, I have created this java class: https://gist.github.com/RokLenarcic/ee0bbb9c7b3d4310efb16b662bf22ecc When I run it:

Apple clang version 15.0.0 (clang-1500.1.0.2.5)
Target: arm64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Hello world!

but if I do clj in a folder with no deps, then I do the same via sh call, then I get x86

how it picks which to use is based on some sort of context

and what about java.home from the java class?

as far as I understand if process runs in x86, then subprocesses all chose x86

my vague working theory is some how clj is picking a x86_64 jvm, and somehow that context bleeds through

so you can check if the java clj is running is the same as the java you get by just calling java

So Java run also has Java home: /Library/Java/JavaVirtualMachines/graalvm-jdk-17.0.11+7.1/Contents/Home

I suspect something like Git it uses switches context to Rosetta

Alex Miller (Clojure team) 2024-06-07T18:59:11.956899Z

that is, I think you're on the right track with considering something else that's causing the rosetta switch

Alex Miller (Clojure team) 2024-06-07T18:59:32.266219Z

I think java and git are the only things tools.build itself ever shells out for

Alex Miller (Clojure team) 2024-06-07T18:59:54.298619Z

and by default it's just assuming "java" and "git" on the path

roklenarcic@Roks-MBP-2 production % which git        
/usr/bin/git
roklenarcic@Roks-MBP-2 production % file /usr/bin/git
/usr/bin/git: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/git (for architecture x86_64):	Mach-O 64-bit executable x86_64
/usr/bin/git (for architecture arm64e):	Mach-O 64-bit executable arm64e

git is dual executable

Alex Miller (Clojure team) 2024-06-07T19:00:44.235419Z

same as clang I assume

roklenarcic@Roks-MBP-2 production % file /usr/bin/cc
/usr/bin/cc: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/cc (for architecture x86_64):	Mach-O 64-bit executable x86_64
/usr/bin/cc (for architecture arm64e):	Mach-O 64-bit executable arm64e

will clj always run git?

Alex Miller (Clojure team) 2024-06-07T19:03:32.542629Z

no

Alex Miller (Clojure team) 2024-06-07T19:03:44.011739Z

it runs it if you use a git dep

Alex Miller (Clojure team) 2024-06-07T19:04:29.459789Z

if you export GITLIBS_DEBUG=true it will print any git commands it's running (and if you see nothing, then it's none)

hm ok but I just ran raw clj in an empty folder and (sh/sh "cc" "-v") still printed x86 and (println (System/getProperty "os.arch")) returns arm.

Alex Miller (Clojure team) 2024-06-07T19:04:59.171369Z

you can also export GITLIBS_COMMAND to specify a different path to git if needed

Alex Miller (Clojure team) 2024-06-07T19:08:08.673179Z

tools.build is not using sh/sh btw (which is Runtime.getRuntime().exec(), it's using the Java process API ProcessBuilder.start() etc

Alex Miller (Clojure team) 2024-06-07T19:08:32.939139Z

I do not know if those differ in the jdk impl

Alex Miller (Clojure team) 2024-06-07T19:11:14.403739Z

seems like Runtime.exec() calls ProcessBuilder, so shouldn't be fundamentally different (other than the narrower feature set of Runtime.exec())

Hm does nobody else experience this?

I think the issue is that a lot of apps got carried over from my intel mac when I restored from a backup

I have to replace all my homebrew apps and also remove homebrew

Alex Miller (Clojure team) 2024-06-07T19:16:36.280049Z

I did similar migration recently from intel to m3. I manually reinstalled all of my Java installations to use the correct arch. I reinstalled a few homebrew things, but don't think I had to remove / reinstall everything

doesn’t x86 homebrew automatically pull everything in x86?

Alex Miller (Clojure team) 2024-06-07T19:17:29.033429Z

¯\(ツ)/¯

I lived through the Apple 68000 -> RISC swap and the RISC -> Intel swap and it always amazed me how much "just worked" but I know they did all sorts of weird stuff under the hood and I was never trying to build binaries for deployment elsewhere back then so I could most ignore the weirdness. Maybe something here will help you "persuade" it to use the version you want? https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary

hm a dependency of clojure in brew is rlwrap and that one is x86 on my system

a reinstall of clojure fixed this

Alex Miller (Clojure team) 2024-06-07T21:13:05.262719Z

interesting

Alex Miller (Clojure team) 2024-06-07T21:13:39.630929Z

probably could have deduced by comparing behavior between clj (uses rlwrap) and clojure (doesn't)