I am currently trying to get a grasp on asdf, but sadly (but apparently not uncommonly) the standard user guide is not really of any help, as it does explain (I guess) the relevant parts but misses to distribute some extended examples containing comments, so a newbie can see those commands in action.
I am especially interested in the usage of :defsystem-depends-on and the :components
part of the defsystem syntax.
Therefore the question is: Is there a more sophisticated and newbie-friendly user guide for asdf out there than the standard user guide?
I don't have time to write a comprehensive tutorial (and I don't have a comprehensive understanding), but I can provide a link & copy from a project I have.
(asdf:defsystem #:cl-yahoo-finance
:depends-on ( #:drakma #:babel #:cl-csv #:yason #:url-rewrite)
:components ((:file "cl-yahoo-finance")) ;;cl-yahoo-finance is cl-yahoo-finance.lisp, in the same directory.
:name "cl-yahoo-finance"
:version "3.2"
:maintainer "Paul Nathan"
:author "Paul Nathan"
:licence "LLGPL"
:description "CL interface to Yahoo's finance API"
:long-description "Common Lisp interface to Yahoo's finance API, available over the web. See usage.lisp for example code.")
https://github.com/pnathan/cl-yahoo-finance/blob/master/cl-yahoo-finance.asd
Do you have any specific questions?
:defsystem-depends-on is just some systems which must be loaded before the system definition is processed. From the grammar you can see that a system name is either a string or a symbol.
:components - many uses are relatively simple. For example it would list a bunch of files.
See also the grammar of ASDF DEFSYSTEM.
Related
I know about using :modules, but what about when systems get nested? Suppose I have the following structure, relative to some unknown user directory:
foo/
-foo.asd
-bar/
--bar.asd
This could arise, for example, when using Git submodules. How shall I configure the (defsystem) call in foo.asd to load bar as a dependency, without modifying a config file outside of foo/ or demanding particular placement for the foo/ tree itself? Feels like it should be simple.
3 Feb. 2020: From #Svante's answer, it sounds like my question is really 'How do I dynamically ensure that foo/ and bar/ both get into the *source-registry*?' The ASDF manual makes me think this should do the trick:
(asdf:initialize-source-registry
'(:source-registry
(:tree "«absolute-path-to-foo»/")
:inherit-configuration))
though I have not seen an example of that usage.
26 Mar. 2020: The technique above seems to work fine, so I'm closing this question. ASDF 3 is excellent.
ASDF doesn't care about relative locations of .asd files. ASDF systems and their dependencies are completely orthogonal to file/directory structure and oblivious to any source version control.
It just looks in several locations for .asd files. Each such file then may contain definitions for systems. It will generally recurse into the configured folders, so any .asd file in a git submodule would usually also be found.
The definitions, e. g. of components, inside of an .asd file then work relatively from the location of that file.
In your example, if you give a :depends-on ("bar") option to the "foo" system, it would just work, no matter where bar.asd resides (as long as it is somewhere where ASDF finds it).
A bit more awareness would be required if you have several versions of a library. This might happen if you work on "foo" and "bar" at the same time, while a stable version of "bar" is also available, e. g. in a quicklisp dist. Then the lookup order comes into play, but usually your “personal” directories have precedence over “system” directories, so again, it would just work. For more control, you might want to look into qlot.
So, in the asdf manual/documentation in section 6.5 of the package-inferred-system extension, the example uses an all.lisp file for determining packages (which I/we will assume will contain all of the function and package information for that respective subdirectoty).
What I want to know is what would be the "proper" way of including all of the function and package declarations in this all.lisp file. Would I do something like including all of the function declarations for that subdirectory in the all.lisp file, and then use the register-system-packages function in the asdf file. Or could I omit the all.lisp file, and let the compiler infer the packages from the files (but would I have to then use the register-system-packages function for every single file I add to this system).
I'm just wondering more about the specifics of using this system and the files and declarations that have to be made when adding a new file to the system.
Sorry for the opacity of the question; I can't seem to grasp the specifics of this system
1- See how it's done in lisp-interface-library/*/all.lisp, using uiop:define-package and its :use-reexport clause.
See for instance pure/all.lisp:
(uiop:define-package :lil/pure/all
(:nicknames :pure)
(:import-from :lil/interface/all)
(:use :closer-common-lisp)
(:mix :fare-utils :uiop :alexandria)
(:use-reexport
:lil/interface/base
:lil/interface/eq
:lil/interface/order
:lil/interface/group
:lil/pure/empty
:lil/pure/collection
:lil/pure/iterator
:lil/pure/map
:lil/pure/set
:lil/pure/alist
:lil/pure/tree
:lil/pure/hash-table
:lil/pure/fmim
:lil/pure/encoded-key-map
:lil/pure/queue
:lil/pure/iterator-implementation
:lil/pure/map-implementation
:lil/pure/set-implementation
:lil/pure/alist-implementation
:lil/pure/tree-implementation
:lil/pure/hash-table-implementation
:lil/pure/fmim-implementation
:lil/pure/encoded-key-map-implementation
:lil/pure/queue-implementation
))
2- These days, I recommend use requiring asdf 3.1 and not using asdf-package-system. For maximal backward incompatibility, use
#-asdf3.1 (error "<my system> requires ASDF 3.1 or later. Please upgrade your ASDF.")
And then in your defsystem, :class :package-inferred-system
3- I do not follow this forum closely. ASDF questions find a quicker answer on the asdf-devel mailing-list.
As I interpret that, you would simply have the package defined in all.lisp depend on the packages defined in the other files of that system. It is then, in a way, an entry point for the dependency graph into that system. I would expect all.lisp to contain high level entry definitions that naturally depend on the other files.
For example, if you build a system that has a (sub-)system for exposing a web interface, the webinterface/all.lisp file/package would contain functions for configuring, starting, and stopping the web server. These functions would depend on the handler definitions in other files/packages which in turn would depend on other files/packages that provide the data or do the meat of request processing.
For the AFP entry Dijkstra's Shortest Path Algorithm, both the proof outline and proof document were nonexistent *. Unfortunately, I did not find an IsaMakefile either to build those documents locally. What is the best way to get those documents?
Another question, as the Dijkstra.thy depends on a lot of other theories, is there a way to load everything faster?
*) It is fixed now.
(There seems to be something broken at AFP right now, please tell the editors about it.)
In general, you can download the sources of AFP entries and produce the documents yourself like this:
Get and unpack all AFP sources -- downloading separate entries is offered as well, but then you have to disentangle dependencies manually.
Invoke isabelle build like this:
isabelle build -d afp-2013-03-02 -o document=pdf -v Dijkstra_Shortest_Path
Here afp-2013-03-02 is the directory that was obtained by unpacking the current AFP sources.
See also the Isabelle System manual about "Isabelle sessions and build management", which is all new in Isabelle2013.
See isabelle build -b there to make things load faster, by producing persistent heap images from sessions.
The links in the AFP entry were indeed broken and should now be fixed again, sorry about that.
As Makarius writes, the AFP new uses Isabelle's new build system, i.e. has a ROOT file for each entry that can be used to check the associated theories and build the document.
Makarius' answer is pretty much the official way to do it, although I would additionally recommend setting up the AFP as a component. This gives you the following steps:
Download the AFP to e.g. ~/afp
Set it up as component e.g. by adding ~/afp to ~/.isabelle/Isabelle2013/components (see also AFP as a component)
build the entry with
isabelle afp_build Dijkstra_Shortest_Path
You can also have jEdit build the heap image for you. If the AFP is setup as a component (see the other answers for that), just start jEdit with
isabelle jedit -d '$AFP' -l Dijkstra_Shortest_Path
and jEdit will select Dijkstra_Shortest_Path as base logic and (re)build it if necessary.
If you make regular use of the AFP, it might be useful to add the AFP path by default. For this, create a file ROOTS in $ISABELLE_HOME_USER with the line $AFP in it (or add this line, if the file already exists).
Ada is still new to me, so I am trying to find my way around the GPS IDE. I asked another question earlier, but I think this problem has precedence over that one, and may be at the root of my trouble.
When I compile, I am getting a long list of *warning: source file ... not found"
In my .gpr file, I have listed all of the spec and body source files and use the following naming scheme:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
end Naming;
What is odd it the error messages all look either like this:
warning: source file "xxx_b.adb" not found
or this
warning: source file "xxx.adb" not found
Note that neither of these (xxxb.adb or xxx.adb) conform to the file specs, which should end with .ada.
Can someone explain what is going on here?
I'm 99% sure that the problem is one of the ones I mentioned in answer to your other question: GNAT does not normally support more than one compilation unit in a file. I got exactly the behaviour you describe with GPS and these files:
james_s.ada:
with Jane;
package James is
end James;
jim_s.ada:
package Jim is
end Jim;
package Jane is
end Jane;
The error message on compiling james_s.ada says it can't find Jane_s.ada, but when I ask GPS to go to the declaration of Jane it takes me to the "correct" line in jim_s.ada.
You could use gnatchop to split jim_s.ada, but it doesn't understand project files or naming conventions; you probably want to keep the existing names for the code that works, so you'd rename gnatchop's output as required.
However! to my great surprise, it turns out that GNAT does support having more than one compilation unit in a file, provided package Naming in the project file tells it about each unit in the file:
package Naming is
for Casing use "mixedcase";
for Dot_Replacement use ".";
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
for Spec ("Jim") use "jim_s.ada" at 1;
for Spec ("Jane") use "jim_s.ada" at 2;
end Naming;
It's up to you whether to do this or to bite the bullet and use gnatchop, either on the multi-unit files or on the whole source tree.
First off, this isn't an Ada problem, its a Gnat problem. Other Ada compilers have no problem with the file names you are using.
However, Gnat is rather unique in that it expects there to be only one program unit (package body, package spec, stand-alone routine, etc) per source file. This is because it is also rather unique in that it expects to be able to find the source code for any program unit just by knowing that unit's Ada intentifier. Most other Ada compilers maintain some kind of library file that maps file names to program units, and you have to register all your files into it. (Whereas your typcial C compiler just leaves the problem of finding files for all your code up to the user entirely).
Generally the easiest thing to do with Gnat, the way that will cause you the least trouble, is to just use its default file naming convention (and of course don't put multiple program units in a single file.
If you already have some existing Ada code (perhaps developed for another compiler), the easiest way to import it into Gnat is typically to run the gnatchop tool on it all. So that's what I'd suggest you try.
From GPRbuild User's Guide:
Strings are used for values of attributes or as indexes for these attributes. They are in general case sensitive, except when noted otherwise [...]
Based on this, I believe you have to use "Ada" instead of "ada" as index for Spec_Suffix and Body_Suffix. I currently do not have access to the tools for testing this, so I suggest to just try it out.
What's the story behind our massive repitition of ./foo and cd ... Where do these two . and .. come from? Where could they be seen as a way of navigating a file system tree for the first time?
Excerpt from an interview with Ken Thompson (9-6-89):
Every time we made a directory, by
convention we put it in another
directory called directory -
directory, which was dd. Its name was
dd and that all the users directories
and in fact most other directories,
users maintain their own directory
systems, had pointers back to dd, and
dd got shortened into ‘dot-dot,’ and
dd was for directory-directory.
I'm sorry I can't answer properly, but I can recommend these links:
The Evolution of the Unix Time-sharing System and
A Brief history of the BSD Fast File System
for some interesting historical notes on early file systems and their use.
Other than that, the earliest reference I've found is the 1974 paper "The UNIX Time-Sharing System" by Dennis Ritchie and Ken Thompson. The precursor of UNIX, Multics, also had hierarchical file systems and the notion of relative paths, but according to "Introduction to MULTICS" it used another notation for that.
I believe it was invented by Dennis Ritchie at Bell Labs in the early years of Unix.