]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/contributor/programming-work.itexi
issue 4491: replace BUILD_DIR with LILYPOND_BUILD_DIR
[lilypond.git] / Documentation / contributor / programming-work.itexi
index 819534b4ad0b23127f1ff304da1e4a56473fa558..99dc79da4a9c6a274aa30ca8e52c68c94ccdc3f2 100644 (file)
@@ -913,17 +913,21 @@ The GNU debugger, gdb, is the principal tool for debugging C++ code.
 @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
@@ -1130,18 +1134,17 @@ in has been declared.  For example, if you are working on routines
 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
@@ -1204,8 +1207,15 @@ number of different platforms:
 
 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
 
@@ -1253,10 +1263,10 @@ dot -Tpdf graphviz.log > graphviz.pdf
 
 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
@@ -1365,7 +1375,7 @@ scripts/auxiliar/update-with-convert-ly.sh
 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
 
 
@@ -1888,55 +1898,8 @@ of a spanner broken at given starting and ending columns.
 
 @node How purity is defined and stored
 @subsection How purity is defined and stored
-Purity can currently be defined two different ways in LilyPond that
-correspond to two types of scenarios.  In one scenario, we know that a
-callback is pure, but we are not necessarily certain what properties
-will use this callback.  In another, we want a property to be pure, but
-we don't want to guarantee that its callback function will be pure in
-all circumstances.
-
-In the first scenario, we register the callback in define-grobs.scm in
-one of four places depending on what the function does.
-
-@itemize
-@item @code{pure-print-functions}: If finding a print function's vertical
-extent does not have any @q{side effects} we register it here. We then
-don't have to set the pure Y-extent property, which will be taken from the
-stencil.
-
-@item @code{pure-print-to-height-conversions}: If a stencil can
-eventually be used to glean a grob's Y-extent but is not pure (meaning
-it will have a different height at different stages of the compilation
-process), we add it to this list along with a function for the pure
-Y-extent.
-
-@item @code{pure-conversions-alist}: This list contains pairs of
-functions and their pure equivalents.  It is onto but not one-to-one.
-
-@item @code{pure-functions}: Like pure-print-functions in that they work
-for both pure and impure values, but they do not return a stencil.
-@end itemize
-
-At all stages of the compilation process, when LilyPond wants the pure
-version of a property, it will consult these lists and see if it can get
-this property for a given Grob.  Note that you do @emph{not} need to
-register the pure property in the grob itself.  For example, there is no
-property @q{pure-Y-extent}.  Rather, by registering these functions as
-defined above, every time LilyPond needs a pure property, it will check
-to see if a Grob contains one of these functions and, if so, will use
-its value.  If LilyPond cannot get a pure function, it will return a
-value of @code{##f} for the property.
-
-LilyPond is smart enough to know if a series of chained functions are
-pure.  For example, if a Y-offset property has four chained functions
-and all of them have pure equivalents, LilyPond will read the four pure
-equivalents when calculating the pure property.  However, if even one is
-impure, LilyPond will not return a pure property for the offset (instead
-returning something like @code{#f} or @code{'()}) and will likely wreak
-havoc on your score.
-
-In the second scenario, we create an unpure-pure-container (unpure is
-not a word, but hey, neither was Lilypond until the 90s).  For example:
+Purity is defined in LilyPond with the creation of an unpure-pure container
+(unpure is not a word, but hey, neither was Lilypond until the 90s).  For example:
 
 @example
 #(define (foo grob)
@@ -1948,23 +1911,8 @@ not a word, but hey, neither was Lilypond until the 90s).  For example:
 \override Stem #'length = #(ly:make-unpure-pure-container foo bar)
 @end example
 
-This is useful if we want to:
-
-@itemize
-@item create overrides that have pure alternatives (should not be used
-in development, but useful for users)
-
-@item use return values that are not functions (i.e. pairs or booleans)
-for either pure or unpure values.
-
-@item allow a function to be considered pure in a limited amount of
-circumstances.  This is useful if we are sure that, when associated with
-one grob a function will be pure but not necessarily with another grob
-that has different callbacks.
-@end itemize
-
-Items can only ever have two pure heights: their actual pure height if
-they are between @q{start} and @q{end}, or an empty interval if they are
+Note that items can only ever have two pure heights: their actual pure height
+if they are between @q{start} and @q{end}, or an empty interval if they are
 not.  Thus, their pure property is cached to speed LilyPond up.  Pure
 heights for spanners are generally not cached as they change depending
 on the start and end values.  They are only cached in certain particular
@@ -2211,7 +2159,7 @@ Test whether the type of @var{s} is [type].
 often than not, the code checks Lilypond specific C++-implemented
 types using
 
-@subsubheading [type *] unsmob_[type] (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
@@ -2609,22 +2557,24 @@ this will display OBJ through GUILE.
 @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
@@ -2638,25 +2588,54 @@ although something gets defined because Scheme apparently recognizes
 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