This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-27
Channels
- # aleph (1)
- # announcements (39)
- # aws (11)
- # beginners (58)
- # calva (10)
- # cider (7)
- # clj-kondo (65)
- # cljs-dev (5)
- # clojure (90)
- # clojure-dev (48)
- # clojure-europe (23)
- # clojure-madison (1)
- # clojure-norway (1)
- # clojure-uk (40)
- # clojured (11)
- # clojurescript (20)
- # conjure (12)
- # core-async (4)
- # core-logic (4)
- # cursive (3)
- # datalevin (1)
- # emacs (7)
- # events (2)
- # fulcro (48)
- # introduce-yourself (2)
- # lsp (36)
- # malli (11)
- # missionary (1)
- # off-topic (1)
- # other-languages (72)
- # pathom (4)
- # polylith (13)
- # portal (94)
- # re-frame (14)
- # react (5)
- # releases (1)
- # sci (12)
- # shadow-cljs (29)
- # spacemacs (3)
- # vim (4)
- # xtdb (12)
Is there any way of obtaining all the class files produced by the AOT compilation of a namespace? My reading of the code says no, but I’d love to be proved wrong.
sounds like you want to separate the classes produced by aot namespace A from the class files produced by namespace B, which A depends on
For my use case (ensuring that incremental compilation in IntelliJ works) I’d want both, but I can imagine that separating them would also be useful (e.g. I only want to AOT my classes, and I’m happy to have the rest run-time compiled).
clojure basically behaves like some kind of whole program optimizing compiler, despite not doing any of things those do
so like taking apart the output of an optimizing compiler and linking it with something compiled separately is tricky, so is doing that with aot compiled clojure
Right, I’m assuming that if you compile several namespaces, that the dependent classes are re-written each time. I haven’t checked that, though.
no, they're not (answering cfleming's question)
classes that exist are not recompiled because they are not loaded because they've already been loaded
going back to original question, do you mean "including transitively compiled classes"? or just from that namespace
In my case, including transitive classes. When Clojure is AOT compiled in Cursive, I compile a namespace at a time (due to how the IntelliJ compiler framework works). In order for incremental compilation not to get messed up (not just for Clojure but for other compilers that might be working in the same project) I should be able to produce a mapping from source files to output files.
Thinking about the transitive case, that’s tricky because which class files are produced depends on which namespaces have been previously compiled (the not loaded thing).
Currently I just map the source file to the ns initialisation class, which works for detecting which namespaces need to be compiled, but probably leaves lots of crud around in the output directories.
because if a transitive namespace is already loaded, it won't be loaded again when compiling, so no classfiles will be written to disk
why is this different than the Java model it's presumably written for?
Java source files produce N class files and depend on M other classes (which may overlap)
Because when you compile a Java file, you can deterministically figure out which class files will be produced.
so you need this a priori?
Well, Cursive has always done this and no-one has complained, so it’s probably not an urgent problem. I suspect very few people use the AOT compilation feature anyway. But as borkdude mentioned, it would be a useful feature for other cases too, like graalvm.
I understand that it’s a hard problem due to how the Clojure compiler has always worked, though.
like there are a set of name patterns you could look for (foo, foo__init, foo$... etc) but you're right that there is no way to know the actual set of classes until you compile.
For a graalvm plugin I wrote I needed to know every class produced by clojure. I worked around this by collecting all the namespace names and using that as package wildcards, but it's better if you could reliably get the collection of class names.
The thing is, for a particular namespace compilation, it’s not even deterministic which namespace’s files will be created, since the dependency namespaces might have been previously loaded.
But for my AOT case, I probably want to figure out the transitive closure of dependent namespaces for each namespace I compile, and then return all those namespaces’ classes as potentially resulting from the compilation of the original source file.
Since if that namespace is compiled cold with an empty output directory, all those files will be produced.
well, the dependency is really the reverse direction and ideally you'd compile those in the other direction
that's the effect you're getting but via side effects
Ok, I’ll take a look and see if all that is worth it. I’m not keen on scanning the output directory, but it looks like that’s really the only option.
In my case, the set of files to compile is passed to me by the IntelliJ framework, and doesn’t include the dependencies from libraries. So I’ll always be compiling top-down, I can’t compile bottom up.
unless you analyze those files yourself maybe and then figure out the bottom dependencies?
Yes, I could do that, and in order to correctly create the output set I’ll have to do that (i.e. pass the tree of namespace dependencies to the compiler).
oh, guess the discussion is all in slack and not in jira https://clojure.atlassian.net/browse/TBUILD-7