* GNAT, shared libraries, building in different directories...madness! @ 2006-09-28 18:54 Lucretia 2006-09-30 6:30 ` vgodunko 2006-09-30 18:07 ` Ludovic Brenta 0 siblings, 2 replies; 15+ messages in thread From: Lucretia @ 2006-09-28 18:54 UTC (permalink / raw) Hi, I just can't see why GNAT can't do this without whining about trying to recompile library sources. All I want to do is to create a simple shared lib, the sources are scattered about in different directories, different builds may use different files. I can create the lib fine, but the test app won't link for various reasons. I have the following directory structure: adael/ adael/src/adael adael/src/adael/common adael/src/adael/generic adael/src/adael/gtk2 adael/src/adael/linux adael/src/samples/ adael/src/samples/test_app adael/build/gnat/linux/ adael/build/gnat/linux/temp/ adael/build/gnat/linux/temp/debug/ adael/build/gnat/linux/temp/release/ adael/build/gnat/linux/debug/ adael/build/gnat/linux/release/ So that for a linux specific build all temporary objects go to temp, executables, ali's, so's go to the debug or release in the linux directory. Can sombody please post an example makefile that can be used to build a library and link the source to an example app without recompiling the library source. I would prefer not to use project files if possible as they just don't provide enough flexibility. Thanks, Luke. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-09-28 18:54 GNAT, shared libraries, building in different directories...madness! Lucretia @ 2006-09-30 6:30 ` vgodunko 2006-09-30 18:07 ` Ludovic Brenta 1 sibling, 0 replies; 15+ messages in thread From: vgodunko @ 2006-09-30 6:30 UTC (permalink / raw) > > Can sombody please post an example makefile that can be used to build a > library and link the source to an example app without recompiling the > library source. I would prefer not to use project files if possible as > they just don't provide enough flexibility. > I have use AutoTools/LibTools for work with dinamic library. I will send an example to you in private mail. If anyone have interest in use Ada with AutoTools framework let me known and I send an example ;) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-09-28 18:54 GNAT, shared libraries, building in different directories...madness! Lucretia 2006-09-30 6:30 ` vgodunko @ 2006-09-30 18:07 ` Ludovic Brenta 2006-10-01 14:44 ` sphinxmoro ` (2 more replies) 1 sibling, 3 replies; 15+ messages in thread From: Ludovic Brenta @ 2006-09-30 18:07 UTC (permalink / raw) Luke wrote: > I have the following directory structure: > > adael/ > adael/src/adael > adael/src/adael/common > adael/src/adael/generic > adael/src/adael/gtk2 > adael/src/adael/linux > adael/src/samples/ > adael/src/samples/test_app > adael/build/gnat/linux/ > adael/build/gnat/linux/temp/ > adael/build/gnat/linux/temp/debug/ > adael/build/gnat/linux/temp/release/ > adael/build/gnat/linux/debug/ > adael/build/gnat/linux/release/ > > So that for a linux specific build all temporary objects go to temp, > executables, ali's, so's go to the debug or release in the linux > directory. > > Can sombody please post an example makefile that can be used to build a > library and link the source to an example app without recompiling the > library source. I would prefer not to use project files if possible as > they just don't provide enough flexibility. Building a library and using it in a program involves the following steps: 1. Building the object and .ali files for the library 2. Linking the object files into a shared libray 3. Copying the .ali files to a "deployment" directory, and making them read-only 4. Building the program, so it sees the .ali files and the .so file but not the .o files for the library. Otherwise, gnatmake will link the library .o files statically into the final executable. Since you've chosen a particularly complex directory structure, your Makefile will be horrendously complex - as you yourself say, "madness". I would really recommend you reconsider your decision not to use project files; contrary to what you say, they can be quite flexible since you can pass variables to them. Here is how I would do it: I would have three project files and one makefile. The first project file would build the library, placing the .o files in the temp directory: project Build_Adael is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/adael", "src/common", "src/generic", "src/gtk2", "src/" & Target); for Object_Dir use "build/" & Compiler & "/" & Target & "/temp/" & Build; package Compiler is for Default_Switches ("Ada") use ("-fPIC", "-g", "-O2", "-gnatVa", "-gntafno"); end Compiler; end Build_Adael; The second project file would use the read-only .ali from the deployment directory, and the source files from the source directory. You would ship this project file with your library. project Adael is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/adael", "src/common", "src/generic", "src/gtk2", "src/" & Target); for Object_Dir use "build/" & Compiler & "/" & Target & "/" & Build; -- no "temp" -- No package Compiler, since we won't compile the library. But -- we can make it convenient for users to link with the shared -- library: Linker_Switches := "-ladael"; package Linker is for Default_Switches ("Ada") use (Linker_Switches); end Linker; end Adael; The third project file would build the samples. You would encourage your users to write similar project files for their own programs. with "adael"; project Adael_Samples is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); for Source_Dirs use ("src/samples/**"); for Object_Dir use "build/" & Compiler & "/" & Target & "/samples/" & Build; for Executable_Dir use "build/" & Compiler & "/" & Target & "/" & Build; package Compiler is for Default_Switches ("Ada") use ("-g", "-O2", "-gnatVa", "-gntafno"); -- no fPIC end Compiler; package Linker renames Adael.Linker; end Adael_Samples; Now, the Makefile would glue them all together, create directories as needed, and simply call gnatmake: # O mighty Emacs, this is a -*- Makefile -*- .SUFFIXES: # You can override these from the command line: COMPILER := gnat TARGET := linux BUILD := debug # Nothing should change past this point lib_dir := build/$(COMPILER)/$(TARGET)/$(BUILD) lib_build_dir := build/$(COMPILER)/$(TARGET)/temp/$(BUILD) samples_build_dir := build/$(COMPILER)/$(TARGET)/samples/$(BUILD) all: $(lib_dir)/libadael.so $(lib_dir)/test_app clean: rm -rf build args := -XCOMPILER=$(COMPILER) -XTARGET=$(TARGET) -XBUILD=$(BUILD) $(lib_dir)/libadael.so: build_adael.gpr | $(lib_dir) $(lib_build_dir) gnatmake -c -Pbuild_adael.gpr $(args) gnatgcc -shared -o $@ $(lib_build_dir)/*.o \ -Wl,-soname,$(notdir $@) -lgnat cp -p $(lib_build_dir)/*.ali $(lib_dir) chmod a=r $(lib_dir)/*.ali ifeq (release,$(BUILD)) strip $@ endif $(lib_dir)/test_app: adael_samples.gpr adael.gpr $(lib_dir)/test_app: $(lib_dir)/libadael.so | $(samples_build_dir) gnatmake -Padael_samples.gpr $(notdir $@) $(args) ifeq (release,$(BUILD)) strip $@ endif $(lib_dir) $(lib_build_dir) $(samples_build_dir): -mkdir -p $@ .PHONY: all clean I think you *could* do away with GNAT project files, but that way lies madness. HTH -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-09-30 18:07 ` Ludovic Brenta @ 2006-10-01 14:44 ` sphinxmoro 2006-10-01 15:41 ` Simon Wright 2006-10-05 12:22 ` Philippe Bertin 2006-10-14 19:13 ` Lucretia 2 siblings, 1 reply; 15+ messages in thread From: sphinxmoro @ 2006-10-01 14:44 UTC (permalink / raw) Hello, 1) I am not quite sure of what you mean whth the flag "-gntafno" Can you explain the meaning of the flag (or is this a typo?) 2) When I have to use a library, ACT suggest to add a path like: package Linker is for Default_Switches ("ada") use ("-g", "--largs", "-Ld:/dev/ada/utils/lib", "-lmyutils"); end Linker; This is working, and in your example you don't specify such a path. What do you think? Thanks ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-01 14:44 ` sphinxmoro @ 2006-10-01 15:41 ` Simon Wright 2006-10-01 16:28 ` Ludovic Brenta 0 siblings, 1 reply; 15+ messages in thread From: Simon Wright @ 2006-10-01 15:41 UTC (permalink / raw) "sphinxmoro" <sphinx.moro@wanadoo.fr> writes: > Hello, > 1) I am not quite sure of what you mean whth the flag > "-gntafno" > Can you explain the meaning of the flag (or is this a typo?) That must be -gnatfno (gnatmake -v will tell you the meanings, though I expect you knew that). > 2) When I have to use a library, ACT suggest to add a path like: > > package Linker is > for Default_Switches ("ada") use ("-g", "--largs", > "-Ld:/dev/ada/utils/lib", "-lmyutils"); > end Linker; > > This is working, and in your example you don't specify such a path. > What do you think? Not a response to your question, but: (a) I thought it was just -largs (one hyphen), (b) -largs is a flag to gnatmake, the flags in package Linker are for gnatlink, (c) it's best to give -g as a flag to package Builder (ie to gnatmake) rather than in the packages for the individual components. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-01 15:41 ` Simon Wright @ 2006-10-01 16:28 ` Ludovic Brenta 0 siblings, 0 replies; 15+ messages in thread From: Ludovic Brenta @ 2006-10-01 16:28 UTC (permalink / raw) Simon Wright writes: > "sphinxmoro" writes: > >> Hello, >> 1) I am not quite sure of what you mean whth the flag >> "-gntafno" >> Can you explain the meaning of the flag (or is this a typo?) > > That must be -gnatfno (gnatmake -v will tell you the meanings, though > I expect you knew that). Actually I meant -gnatafno (a=assertions enabled, f=full errors, n=inlining across units, o=full range checks). Sorry for the typo. You can, of course, adjust compiler options to taste. >> 2) When I have to use a library, ACT suggest to add a path like: >> >> package Linker is >> for Default_Switches ("ada") use ("-g", "--largs", >> "-Ld:/dev/ada/utils/lib", "-lmyutils"); >> end Linker; >> >> This is working, and in your example you don't specify such a path. >> What do you think? I don't like adding "-L" in project files, because that would make them inflexible. Also, remember that the plan is to install the project file in /usr/share/ada/adainclude as part of the library's development package (presumably, libmyutils-dev), and the library in /usr/lib, as part of the run-time library package (presumably, libmyutils0). If the library is in /usr/lib, there is no need for "-L" in the first place. If you build a program that depends on the library before the library has been installed in /usr/lib, the best is to pass "-L" directly to gnatmake, like so: gnatmake -Pfoo -largs -Lbuild where "build" is a directory relative to the Makefile. Maybe I should have explained that better in my first reply. Now, since you seem to be running on an operating system that has no policy as regards library placement, maybe it is necessary to specify a library path at some point. But the OP did mention Linux, and to me this implies the GNU linker and toolchain, and some sort of conformance to the Filesystem Hierarchy Standard. Come to think of it, it is really better not to write the linker path in the project file, because the linker path tends to be system-depedent, whereas the project file is platform-neutal. I prefer to provide the necessary "glue" in the Makefile. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-09-30 18:07 ` Ludovic Brenta 2006-10-01 14:44 ` sphinxmoro @ 2006-10-05 12:22 ` Philippe Bertin 2006-10-05 12:33 ` Ludovic Brenta 2006-10-14 19:13 ` Lucretia 2 siblings, 1 reply; 15+ messages in thread From: Philippe Bertin @ 2006-10-05 12:22 UTC (permalink / raw) While we are at it, is there somewhere a good reference document on the different .gpr options ? As in GPS, one can specify options in the IDE, and see them reflected in GPS' created .gpr file. But then again, I was not aware of gps file's features like <snip from Ludovic Brenta's post> project Build_Adael is Compiler := External ("COMPILER", "gnat"); Target := External ("TARGET", "linux"); Build := External ("BUILD", "release"); ... end Build_Adael; </snip> that can be passed along to gnatmake using the -X option. Are there more of such 'hidden' (?) options/features ? Furthermore, there are 2 environment variables (ADA_INCLUDE_PATH, ADA_OBJECTS_PATH) that can be set for gnatmake's sake; setting these do not necessitate passing to gnatmake the options for gcc and gnatbind (in the case of a project having to use sources/object files in other directories). As an example (supposed one wants to dynamically link against the system's available gtkada library) ADA_INCLUDE_PATH=/usr/local/gtk/include/gtkada ADA_OBJECTS_PATH=/usr/local/gtk/include/gtkada gnatmake window1.adb -largs `gtkada-config --libs` which ends up in a call to gnatlink equivalent to : gnatlink /home/papa/TestProjecten/GladeGUI/src/window1.ali `gtkada-config --libs` But then again, I have not found any such environment variable for gnatlink's sake. Is there any such variable that can be set to avoid this "-largs `gtkada-config --libs`"? Thanks, PhB ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-05 12:22 ` Philippe Bertin @ 2006-10-05 12:33 ` Ludovic Brenta 2006-10-05 15:28 ` Philippe Bertin 0 siblings, 1 reply; 15+ messages in thread From: Ludovic Brenta @ 2006-10-05 12:33 UTC (permalink / raw) Philippe Bertin wrote: > While we are at it, is there somewhere a good reference document on the > different .gpr options ? As in GPS, one can specify options in the IDE, > and see them reflected in GPS' created .gpr file. But then again, I was > not aware of gps file's features like [...] It's in the Secret Documentation, called "GNAT User's Guide", chapter 11: "GNAT Project Manager". If your GPS is properly installed, you should be able to read it from within GPS. Otherwise, you can always point your browser at http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/GNAT-Project-Manager.html#GNAT-Project-Manager [passing linker options with environment variables] > But then again, I have not found any such environment variable for > gnatlink's sake. Is there any such variable that can be set to avoid > this "-largs `gtkada-config --libs`"? Not that I know, but maybe the Secret Documentation has the info you want. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-05 12:33 ` Ludovic Brenta @ 2006-10-05 15:28 ` Philippe Bertin 2006-10-05 16:06 ` Alex R. Mosteo 2006-10-05 20:22 ` Ludovic Brenta 0 siblings, 2 replies; 15+ messages in thread From: Philippe Bertin @ 2006-10-05 15:28 UTC (permalink / raw) Then, after having wrestled (at least partly) through the Dark Dungeons of the Secret Documentation ;-) I think that there are as well possibilities to make a gnatmake "Library Project" (instead of a combination of .gpr files and Makefile's) ? See http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Library-Projects.html#Library-Projects I think I'm correct in this ? Or do you rather prefer not to use this feature for any reason(s) ? PhB ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-05 15:28 ` Philippe Bertin @ 2006-10-05 16:06 ` Alex R. Mosteo 2006-10-05 20:22 ` Ludovic Brenta 1 sibling, 0 replies; 15+ messages in thread From: Alex R. Mosteo @ 2006-10-05 16:06 UTC (permalink / raw) Philippe Bertin wrote: > Then, after having wrestled (at least partly) through the Dark Dungeons > of the Secret Documentation ;-) > I think that there are as well possibilities to make a gnatmake > "Library Project" (instead of a combination of .gpr files and > Makefile's) ? See > http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Library-Projects.html#Library-Projects > > I think I'm correct in this ? Or do you rather prefer not to use this > feature for any reason(s) ? I have used it without problems, but is not a complete replacement for makefiles. Some kinds of automations can not be performed with project files alone. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-05 15:28 ` Philippe Bertin 2006-10-05 16:06 ` Alex R. Mosteo @ 2006-10-05 20:22 ` Ludovic Brenta 2006-10-07 8:21 ` Simon Wright 1 sibling, 1 reply; 15+ messages in thread From: Ludovic Brenta @ 2006-10-05 20:22 UTC (permalink / raw) Philippe Bertin writes: > Then, after having wrestled (at least partly) through the Dark Dungeons > of the Secret Documentation ;-) > I think that there are as well possibilities to make a gnatmake > "Library Project" (instead of a combination of .gpr files and > Makefile's) ? See > http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Library-Projects.html > > I think I'm correct in this ? Or do you rather prefer not to use this > feature for any reason(s) ? You are correct, but this feature was not present in gnat 3.15p (the default Ada compiler in Sarge), so I got used to using "simple" project files. They work well and I have not felt the need for library project files yet. Also, as Alex said, library project files do not do everything that I need in Debian. For one thing, I would need two project files, one for the static library and one for the shared library. For another, I usually need more than one symlink to the library, e.g. /usr/lib/libfoo.so.1.2.3 (with soname libfoo.so.1) /usr/lib/libfoo.so.1 -> libfoo.so.1.2.3 (run-time link) /usr/lib/libfoo.so -> libfoo.so.1.2.3 (development-time link) Finally, Debian requires at least one Makefile (named debian/rules) that does more than building the library; it also has to create the .deb files, clean up, apply patches, occasionally call a preprocessor, etc. But library project files are nice if you don't need all that flexibility. In the most common and simple cases, you can reduce the need for Makefiles, maybe even eliminate them completely. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-05 20:22 ` Ludovic Brenta @ 2006-10-07 8:21 ` Simon Wright 0 siblings, 0 replies; 15+ messages in thread From: Simon Wright @ 2006-10-07 8:21 UTC (permalink / raw) Ludovic Brenta <ludovic@ludovic-brenta.org> writes: > /usr/lib/libfoo.so.1.2.3 (with soname libfoo.so.1) > /usr/lib/libfoo.so.1 -> libfoo.so.1.2.3 (run-time link) > /usr/lib/libfoo.so -> libfoo.so.1.2.3 (development-time link) I thought it was slightly more 'normal' to have libfoo.so link to libfoo.so.1 -- probably makes no difference to the computer, though! ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-09-30 18:07 ` Ludovic Brenta 2006-10-01 14:44 ` sphinxmoro 2006-10-05 12:22 ` Philippe Bertin @ 2006-10-14 19:13 ` Lucretia 2006-10-15 11:00 ` Simon Wright 2 siblings, 1 reply; 15+ messages in thread From: Lucretia @ 2006-10-14 19:13 UTC (permalink / raw) Ludovic Brenta wrote: > project Build_Adael is > Compiler := External ("COMPILER", "gnat"); This isn't needed as gnat *will* be the compiler if using gpr files, so this can be hardcoded. > Target := External ("TARGET", "linux"); > Build := External ("BUILD", "release"); > > for Source_Dirs use ("src/adael", > "src/common", > "src/generic", > "src/gtk2", > "src/" & Target); And there is a major problem with this source directory directive. The generic directory should contain all source for a gui toolkit neutral UI, in a way that wxWidgets does currently. I.e. say that I have a UI element called Some_Gizmo (which does something), on Win32 there exists a native implementation that can be wrapped by AdaEL, GTK+-2.x might not have this and so uses the one from the generic directory. When compiling under MingW32 the compiler is going to have a problem as there will be 2 packages called some_gizmos.ad[sb], 1 in src/generic and 1 in src/win32. So, how do I know which to compile? Now only GNAT can use the package renaming pragmas and only GNAT provides Ada 2005, but other compilers will catch up and it would be nice to be able to say that this library will compile with any Ada 2005 capable compiler. [massive snip - this bit made sense ;-)] > I think you *could* do away with GNAT project files, but that way lies > madness. I think the way that GNAT does things is just wierd, especially when attempting to use it for complex projects like this. Thanks, Luke. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: GNAT, shared libraries, building in different directories...madness! 2006-10-14 19:13 ` Lucretia @ 2006-10-15 11:00 ` Simon Wright 0 siblings, 0 replies; 15+ messages in thread From: Simon Wright @ 2006-10-15 11:00 UTC (permalink / raw) "Lucretia" <lucretia9@lycos.co.uk> writes: > And there is a major problem with this source directory > directive. The generic directory should contain all source for a gui > toolkit neutral UI, in a way that wxWidgets does currently. We build several executables, each with its own set of supporting application-, intermediate- and device-level packages plus a fair bunch of common stuff. We have a main GPR for each executable (which can be extended by anyone who needs to build test programs), which calls up a machine-generated GPR (one for the whole project) which has no associated source code but instead defines lots of names for various sets of paths. These names are what are used by the main GPRs. Each executable can be built in various contexts; variant A or B, runs on the host or on the target, etc. This is managed using case statements in the machine-generated GPR. Host_Network_Path = ("a/b/c", "a/b/d"); Target_Network_Path = ("w/x/y", "w/x/z"); case Platform is when "host" => Network_Path = Host_Network_Path; when "target" => Network_Path = Target_Network_Path; end case; and the main GPR says for Source_Dirs use Network_Path & .... ^ permalink raw reply [flat|nested] 15+ messages in thread
* GNAT, shared libraries, building in different directories...madness! @ 2006-09-28 19:11 Lucretia 0 siblings, 0 replies; 15+ messages in thread From: Lucretia @ 2006-09-28 19:11 UTC (permalink / raw) Hi, I just can't see why GNAT can't do this without whining about trying to recompile library sources. All I want to do is to create a simple shared lib, the sources are scattered about in different directories, different builds may use different files. I can create the lib fine, but the test app won't link for various reasons. I have the following directory structure: adael/ adael/src/adael adael/src/adael/common adael/src/adael/generic adael/src/adael/gtk2 adael/src/adael/linux adael/src/samples/ adael/src/samples/test_app adael/build/gnat/linux/ adael/build/gnat/linux/temp/ adael/build/gnat/linux/temp/debug/ adael/build/gnat/linux/temp/release/ adael/build/gnat/linux/debug/ adael/build/gnat/linux/release/ So that for a linux specific build all temporary objects go to temp, executables, ali's, so's go to the debug or release in the linux directory. Can sombody please post an example makefile that can be used to build a library and link the source to an example app without recompiling the library source. I would prefer not to use project files if possible as they just don't provide enough flexibility. Thanks, Luke. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2006-10-15 11:00 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-09-28 18:54 GNAT, shared libraries, building in different directories...madness! Lucretia 2006-09-30 6:30 ` vgodunko 2006-09-30 18:07 ` Ludovic Brenta 2006-10-01 14:44 ` sphinxmoro 2006-10-01 15:41 ` Simon Wright 2006-10-01 16:28 ` Ludovic Brenta 2006-10-05 12:22 ` Philippe Bertin 2006-10-05 12:33 ` Ludovic Brenta 2006-10-05 15:28 ` Philippe Bertin 2006-10-05 16:06 ` Alex R. Mosteo 2006-10-05 20:22 ` Ludovic Brenta 2006-10-07 8:21 ` Simon Wright 2006-10-14 19:13 ` Lucretia 2006-10-15 11:00 ` Simon Wright -- strict thread matches above, loose matches on Subject: below -- 2006-09-28 19:11 Lucretia
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox