@subheading Compiling LilyPond for use with gdb
In order to use gdb with LilyPond, it is necessary to compile
-LilyPond with debugging information. This is accomplished by running
-the following commands in the main LilyPond source directory.
+LilyPond with debugging information. This is the current default
+mode of compilation. Often debugging becomes more complicated
+when the compiler has optimised variables and function calls away.
+In that case it may be helpful to run the following command in the
+main LilyPond source directory:
@example
-./configure --disable-optimising
+./configure --disable-optimising
make
@end example
-This will create a version of LilyPond containing debugging
-information that will allow the debugger to tie the source code
-to the compiled code.
+This will create a version of LilyPond with minimal optimization
+which will allow the debugger to access all variables and step
+through the source code in-order. It may not accurately reproduce
+bugs encountered with the optimized version, however.
You should not do @var{make install} if you want to use a debugger
with LilyPond. The @var{make install} command will strip debugging
called by @var{print-book-with} in @file{lily-library.scm}:
@example
-(define (print-book-with parser book process-procedure)
- (let* ((paper (ly:parser-lookup parser '$defaultpaper))
- (layout (ly:parser-lookup parser '$defaultlayout))
- (outfile-name (get-outfile-name parser)))
+(define (print-book-with book process-procedure)
+ (let* ((paper (ly:parser-lookup '$defaultpaper))
+ (layout (ly:parser-lookup '$defaultlayout))
+ (outfile-name (get-outfile-name book)))
(process-procedure book paper layout outfile-name)))
-(define-public (print-book-with-defaults parser book)
- (print-book-with parser book ly:book-process))
-
-(define-public (print-book-with-defaults-as-systems parser book)
- (print-book-with parser book ly:book-process-to-systems))
+(define-public (print-book-with-defaults book)
+ (print-book-with book ly:book-process))
+(define-public (print-book-with-defaults-as-systems book)
+ (print-book-with book ly:book-process-to-systems))
@end example
At this point in the code you could add this to set a breakpoint at
In order for the Graphviz tool to work, config.make must be modified.
It is probably a good idea to first save a copy of config.make under
-a different name. Then, edit config.make by removing every occurrence
-of @option{-DNDEBUG}.
+a different name.
+
+In order to have the required functionality available, LilyPond
+needs to be compiled with the option @option{-DDEBUG}. You can
+achieve this by configuring with
+
+@example
+./configure --enable-checking
+@end example
@item Rebuilding LilyPond
The pdf file can then be viewed with any pdf viewer.
-When compiled without @option{-DNDEBUG}, lilypond may run slower
-than normal. The original configuration can be restored by either
-renaming the saved copy of @code{config.make} or rerunning
-@code{configure}. Then rebuild lilypond with
+When compiled with @option{-DDEBUG}, lilypond may run slower
+than normal. The original configuration can be restored by rerunning
+@code{./configure} with @option{--disable-checking}. Then
+rebuild lilypond with
@example
make -C lily clean && make -C lily
If you did an out-of-tree build, pass in the relative path:
@example
-BUILD_DIR=../build-lilypond/ scripts/auxiliar/update-with-convert-ly.sh
+LILYPOND_BUILD_DIR=../build-lilypond/ scripts/auxiliar/update-with-convert-ly.sh
@end example
often than not, the code checks Lilypond specific C++-implemented
types using
-@subsubheading [Type *] Type::unsmob (SCM s)
+@subsubheading [Type *] unsmob<Type> (SCM s)
This tries converting a Scheme object to a pointer of the desired
kind. If the Scheme object is of the wrong type, a pointer value
@subsection Music functions and GUILE debugging
Ian Hulin was trying to do some debugging in music functions, and
-came up with the following question
+came up with the following question (edited and adapted to current
+versions):
HI all,
I'm working on the Guile Debugger Stuff, and would like to try
debugging a music function definition such as:
@example
-conditionalMark = #(define-music-function (parser location) ()
- #@{ \tag #'instrumental-part @{\mark \default@} #@} )
+conditionalMark =
+#(define-music-function () ()
+ #@{ \tag instrumental-part @{\mark \default@} #@} )
@end example
-It appears conditionalMark does not get set up as an
+It appears @code{conditionalMark} does not get set up as an
equivalent of a Scheme
@example
-(define conditionalMark = define-music-function(parser location () ...
+(define conditionalMark = define-music-function () () ...
@end example
@noindent
later on in the file without signalling any Guile errors.
However the breakpoint trap is never encountered as
-define-music-function passed things on to ly:make-music-function,
-which is really C++ code ly_make_music_function, so Guile never
-finds out about the breakpoint.
+@code{define-music-function} passed things on to
+@code{ly:make-music-function}, which is really C++ code
+@code{ly_make_music_function}, so Guile never finds out about the
+breakpoint.
+
+
+The answer in the mailing list archive at that time was less than
+helpful. The question already misidentifies the purpose of
+@code{ly:make-music-function} which is only called once at the
+time of @emph{defining} @code{conditionalMark} but is not involved
+in its later @emph{execution}.
-Han-Wen answered as follows:
+Here is the real deal:
-You can see the definition by doing
+A music function is not the same as a GUILE function. It boxes
+both a proper Scheme function (with argument list and body from
+the @code{define-music-function} definition) along with a call
+signature representing the @emph{types} of both function and
+arguments.
+
+Those components can be reextracted using
+@code{ly:music-function-extract} and
+@code{ly:music-function-signature}, respectively.
+
+When LilyPond's parser encounters a music function call in its
+input, it reads, interprets, and verifies the arguments
+individually according to the call signature and @emph{then} calls
+the proper Scheme function.
+
+While it is actually possible these days to call a music function
+@emph{as if} it were a Scheme function itself, this pseudo-call
+uses its own wrapping code matching the argument list @emph{as a
+whole} to the call signature, substituting omitted optional
+arguments with defaults and verifying the result type.
+
+So putting a breakpoint on the music function itself will still
+not help with debugging uses of the function using LilyPond
+syntax.
+
+However, either calling mechanism ultimately calls the proper
+Scheme function stored as part of the music function, and that is
+where the breakpoint belongs:
@example
-#(display conditionalMark)
+#(set-break! (ly:music-function-extract conditionalMark))
@end example
-noindent
-inside the @file{.ly} file.
-
-The breakpoint failing may have to do with the call sequence. See
-@file{parser.yy}, run_music_function(). The function is called directly from
-C++, without going through the GUILE evaluator, so I think that is why
-there is no debugger trap.
+will work for either calling mechanism.
@node Articulations on EventChord
@subsection Articulations on EventChord