1 \chapter{Developer's Section}%
2 \label{cha:developer's_section}
4 \section{How Builds Really Work and Even More Options}
5 \label{sec:builds_really_work_more_options}
6 \index{build!more options}
8 This section describes how builds really work if you want to know more about making changes or understanding the process; probably only for a developer or system administrator.
10 Builds occur in 4 basic steps:
12 \begin{enumerate}[nosep]
13 \item unpack/patch source code
15 \item make build targets
19 So, an example of what happens in 4 steps for a single-user build would be as follows:
21 \begin{enumerate}[nosep]
22 \item unpack/patch source code: \\
23 \texttt{git clone --depth 1 ``git:/{\dots}/target'' cinelerra5} \\
25 \item configure build:\\
26 \texttt{./configure --with-single-user}
27 \item make build targets:\\
28 \texttt{make 2 > \&1 | tee log}
33 A lot of things can be tweaked to change the results. Mostly these changes are parameters to the configure step, which can change important build related items, like the application name, or where and what the target system directories should be. This makes it possible to have several versions at the same time on the same computer if needed. To see what it is that the makefiles use to build \CGG{}, look at the resulting top-level global\_config file which is created by the ./configure step.
35 Building \CGG{} requires many thirdparty libraries, and it is recommended that you use the static build version included in the git repo. Some of them are patched, and fix significant bugs. It is important to note that because system installation historically has been with as many shared objects as possible, the defaults are that any system library detected during configuration setup will be used, when the package is built \textit{-{}-without-single-user}, which is the default build. To build with static thirdparty libraries for system install to the system /usr area, use:
37 \hspace{2em}\texttt{.configure -{}-enable-static-build --prefix=/usr}
39 Sometimes, additional package parameters and variables are needed during thirdparty builds. These optional values occur before and after the \textit{configure} and \textit{make} commands during a build. A presentation of the format of the package qualified variable names and how they appear in the build procedure are:
42 \begin{tabular}{@{}ll}
43 pkg.cfg\_vars & prepended to configure\\
44 pkg.cfg\_params & appended to configure\\
45 pkg.mak\_vars & prepended to make\\
46 pkg.mak\_params & appended to make\\
47 pkg.cflags & added as CFLAGS+=\$(cflags) to pkg.vars\\
48 pkg.cppflags & added as CPPFLAGS+=\$(cppflags) to pkg.vars\\
51 These steps are done for EACH of the packages in the thirdparty build:
53 \hspace{2em}\texttt{<pkg.cfg\_vars> ./configure <pkg.cfg\_params>}
55 \hspace{2em}\texttt{<pkg.mak\_vars> make <pkg.mak\_params>}
57 The thirdparty Makefile has a set of default vars and params used to build each of the needed thirdparty packages, but you can specify new or overriding values for these Makefile substitutions. These thirdparty build config changes are specified in the top-level file: \textit{cin\_config}. By using this file, you can save the configuration changes made for the current build to use the next time you do a new build. For example, to add an include file path to the giflib build, add this line to \textit{cin\_config}:
59 \hspace{2em}\texttt{giflib.cflags := -I/usr/local/include/giflib5}
61 To have a param/var change apply to all thirdparty builds, use:
63 \hspace{2em}\texttt{CFG\_VARS, CFG\_PARAMS, MAK\_VARS, MAK\_PARAMS}
65 CFLAGS, CXXFLAGS and LDFLAGS are forwarded to the thirdparty build environment via:
67 \hspace{2em}\texttt{CFLAGS=-ggdb ./configure -{}-with-single-user}
69 However, there is no guarantee that the thirdparty build will honor the environmental flags.
71 Finally, there are build controls, which enable/disable and set build features.
73 A few of the more useful ./configure -{}-parameters are:
76 -{}-with-jobs=n & where n=number of build jobs; defaults to 1.5*cpus+2\\
77 -{}-enable-static-build & build all 3rd party libs; defaults to yes if single-user, else no\\
78 -{}-with-single-user& build installs to <build\_path>/bin; no system installation\\
82 The ./configure command builds \textit{global\_config}. The global\_config is read by the thirdparty/Makefile to create the recipes and definitions used by the thirdparty build.
84 There are a lot of different options. Thirdparty library build control is available in the configure step of the build. Thirdparty libraries are built on a demand basis. So if you use:
86 \begin{tabular}{l p{11cm}}
87 -{}-enable-libname=auto & the static-build enable, or the lack of a system library causes a build\\
88 -{}-enable-libname=yes & this forces the thirdparty build\\
89 -{}-enable-libname=no & this forces no thirdparty build\\
92 FFmpeg is a \textit{strongly connected} component in the build linkage and widely influences the \CGG{} library demands. It is possible to make small additions to the ffmpeg configuration step using the environment variable \texttt{FFMPEG\_EXTRA\_CFG}. For example, to eliminate the use of libvdpau (an nvidia support library) in the ffmpeg configuration step after you have determined that it is causing an error, use:
94 \begin{itemize}[label={},nosep]
95 \item \texttt{make clean}
96 \item \texttt{autogen.sh}
97 \item \texttt{export FFMPEG\_EXTRA\_CFG=" -{}-disable-vdpau"}
98 \item \texttt{./configure} {\dots}
101 Specific information on using the current ffmpeg GIT repository follows. You have to supply the actual URL location of the ffmpeg git as you can see in this example \texttt{?bld.sh?} script:
103 \begin{lstlisting}[numbers=none]
105 () ./autogen.sh\newline
106 ./configure --with-single-user --with-booby --with-git-ffmpeg=https://git.ffmpeg.org/ffmpeg.git
107 make && make install ) 2>1 | tee log
108 mv Makefile Makefile.cfg
109 cp Makefile.devel Makefile
112 Since the procedure for obtaining the latest ffmpeg version is not always kept up-to-date and the line numbers will always change, you may have to create that patch first. Generally those line numbers are only updated by a developer when a new stable version with worthwhile features is actually included in the \CGG{} build. FFmpeg is constantly changing and many times the git version is not as stable as desired.
114 \section{Configuration Features}
115 \label{sec:configuration_features}
116 \index{build!configuration}
118 A listing of the current configuration features as of January 11, 2020:
121 \fontsize{10pt}{12pt}\selectfont
124 `configure' configures \CGG{} to adapt to many kinds of systems.
126 Usage: ./configure [OPTION]... [VAR=VALUE]...
128 To assign environment variables (e.g., CC, CFLAGS...), specify them as
129 VAR=VALUE. See below for descriptions of some of the useful variables.
131 Defaults for the options are specified in brackets.
134 -h, --help display this help and exit
135 --help=short display options specific to this package
136 --help=recursive display the short help of all the included packages
137 -V, --version display version information and exit
138 -q, --quiet, --silent do not print `checking ...' messages
139 --cache-file=FILE cache test results in FILE [disabled]
140 -C, --config-cache alias for `--cache-file=config.cache'
141 -n, --no-create do not create output files
142 --srcdir=DIR find the sources in DIR [configure dir or `..']
144 Installation directories:
145 --prefix=PREFIX install architecture-independent files in PREFIX
147 --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
150 By default, `make install' will install all the files in
151 `/usr/local/bin', `/usr/local/lib' etc. You can specify
152 an installation prefix other than `/usr/local' using `--prefix',
153 for instance `--prefix=$HOME'.
155 For better control, use the options below.
157 Fine tuning of the installation directories:
158 --bindir=DIR user executables [EPREFIX/bin]
159 --sbindir=DIR system admin executables [EPREFIX/sbin]
160 --libexecdir=DIR program executables [EPREFIX/libexec]
161 --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
162 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
163 --localstatedir=DIR modifiable single-machine data [PREFIX/var]
164 --libdir=DIR object code libraries [EPREFIX/lib]
165 --includedir=DIR C header files [PREFIX/include]
166 --oldincludedir=DIR C header files for non-gcc [/usr/include]
167 --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
168 --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
169 --infodir=DIR info documentation [DATAROOTDIR/info]
170 --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
171 --mandir=DIR man documentation [DATAROOTDIR/man]
172 --docdir=DIR documentation root [DATAROOTDIR/doc/cinelerra]
173 --htmldir=DIR html documentation [DOCDIR]
174 --dvidir=DIR dvi documentation [DOCDIR]
175 --pdfdir=DIR pdf documentation [DOCDIR]
176 --psdir=DIR ps documentation [DOCDIR]
179 --program-prefix=PREFIX prepend PREFIX to installed program names
180 --program-suffix=SUFFIX append SUFFIX to installed program names
181 --program-transform-name=PROGRAM run sed PROGRAM on installed program names
184 --disable-option-checking ignore unrecognized --enable/--with options
185 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
186 --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
187 --enable-silent-rules less verbose build output (undo: "make V=1")
188 --disable-silent-rules verbose build output (undo: "make V=0")
189 --enable-dependency-tracking
190 do not reject slow dependency extractors
191 --disable-dependency-tracking
192 speeds up one-time build
193 --enable-a52dec build a52dec (yes)
194 --enable-djbfft build djbfft (yes)
195 --enable-audiofile build audiofile (no)
196 --enable-encore build encore (no)
197 --enable-esound build esound (no)
198 --enable-ffmpeg build ffmpeg (yes)
199 --enable-fftw build fftw (auto)
200 --enable-flac build flac (auto)
201 --enable-giflib build giflib (yes)
202 --enable-ilmbase build ilmbase (auto)
203 --enable-lame build lame (auto)
204 --enable-libavc1394 build libavc1394 (auto)
205 --enable-libraw1394 build libraw1394 (auto)
206 --enable-libiec61883 build libiec61883 (auto)
207 --enable-libdv build libdv (auto)
208 --enable-libjpeg build libjpeg (auto)
209 --enable-opus build opus (auto)
210 --enable-openjpeg build openjpeg (auto)
211 --enable-libogg build libogg (auto)
212 --enable-libsndfile build libsndfile (auto)
213 --enable-libtheora build libtheora (auto)
214 --enable-libuuid build libuuid (yes)
215 --enable-libvorbis build libvorbis (auto)
216 --enable-mjpegtools build mjpegtools (yes)
217 --enable-openexr build openexr (auto)
218 --enable-tiff build tiff (auto)
219 --enable-twolame build twolame (auto)
220 --enable-x264 build x264 (auto)
221 --enable-x265 build x265 (auto)
222 --enable-libvpx build libvpx (auto)
223 --enable-lv2 build lv2 (auto)
224 --enable-sratom build sratom (auto)
225 --enable-serd build serd (auto)
226 --enable-sord build sord (auto)
227 --enable-lilv build lilv (auto)
228 --enable-suil build suil (auto)
229 --enable-libaom build libaom (auto)
230 --enable-dav1d build dav1d (auto)
231 --enable-libwebp build libwebp (auto)
232 --enable-ffnvcodec build ffnvcodec (auto)
233 --enable-static-build build static ([auto])
234 --enable-x264_hidepth build x264 10bit ([no])
235 --enable-x265_hidepth build x265 10bit ([no])
238 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
239 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
240 --with-jobs parallel build jobs (auto)
241 --with-exec-name binary executable name (cin)
242 --with-single-user to install cin in bin (no)
243 --with-ladspa-build build ladspa library (yes)
244 --with-lv2 lv2 library support (yes)
245 --with-cinlib cinelerra library path (auto)
246 --with-cindat cinelerra share path (auto)
247 --with-plugin-dir plugin install dir (auto)
248 --with-ladspa-dir ladspa install dir (auto)
249 --with-config-dir .bcast config dir ($$HOME/.bcast5)
250 --with-nested-dir nested proxy dir ($$HOME/Videos)
251 --with-browser cin_browser path (firefox)
252 --with-git-ffmpeg git ffmpeg using url (no)
253 --with-noelision use noelision/libpthread (auto)
254 --with-booby window lock trace booby trap (no)
255 --with-libzmpeg build libzmpeg (yes)
256 --with-commercial enable commercial capture (yes)
257 --with-thirdparty use thirdparty build (yes)
258 --with-shuttle shuttle device (yes)
259 --with-wintv usb 2040:826d wintv device (yes)
260 --with-x10tv usb 0bc7:0004 X10 remote device (yes)
261 --with-vaapi video acceleration api (yes)
262 --with-vdpau video decode+presentation api for unix (yes)
263 --with-nv nvenc/nvdec ffnvcodec api (yes)
264 --with-cuda nv cuda plugins (auto)
265 --with-clang use clang instead of gcc/g++ (no)
266 --with-gl use opengl (auto)
267 --with-oss use OSS audio (auto)
268 --with-xft use libXft (auto)
269 --with-alsa use libasound/alsa (auto)
270 --with-firewire use firewire (auto)
271 --with-dv use dv (auto)
272 --with-dvb use dvb (auto)
273 --with-video4linux2 use v4l2 (auto)
274 --with-xxf86vm use xf86vmode (auto)
275 --with-esound use esd (auto)
276 --with-shuttle shuttle dev support (auto)
277 --with-shuttle_usb use libusb-1.0 (auto)
278 --with-lv2 use lv2 (auto)
279 --with-cuda build cuda plugins (auto)
280 --with-dl system has libdl (auto)
281 --with-opencv opencv=sys/sta/dyn,git/tar=url (auto)
282 --with-numa system has libnuma (auto)
283 --with-openexr use openexr (auto)
285 Some influential environment variables:
286 CC C compiler command
287 CFLAGS C compiler flags
288 LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
289 nonstandard directory <lib dir>
290 LIBS libraries to pass to the linker, e.g. -l<library>
291 CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
292 you have headers in a nonstandard directory <include dir>
293 CCAS assembler compiler command (defaults to CC)
294 CCASFLAGS assembler compiler flags (defaults to CFLAGS)
295 CXX C++ compiler command
296 CXXFLAGS C++ compiler flags
298 Use these variables to override the choices made by `configure' or to help
299 it to find libraries and programs with nonstandard names/locations.
301 Report bugs to <mail@lists.cinelerra-gg.org>.
306 \section{Thirdparty Parallel Build}
307 \label{sec:thirdparty_parallel_build}
308 \index{build!thirdparty}
310 The Makefile in the thirdparty build directory employs a set of macros used to create a build rule set of thirdparty library build dependencies. The standard build sequence of [source, config, build] is used to prepare thirdparty products as static libraries. Build package dependency can be specified in the Makefile std-build macro call. These Makefile macro calls define the rules used for each thirdparty build. The expanded rule definitions may be viewed by using:
312 \hspace{2em}\texttt{make -C thirdparty rules}
314 Individual package libraries can be rebuilt, via:
316 \hspace{2em}\texttt{make -C thirdparty <pkg>-clean; make -C thirdparty <pkg>}
318 The rule targets create the set of thirdparty packages which are built from local source archive copies of thirdparty source code and patches, if needed. The build rule set of dependencies allows for compiling multiple thirdparty programs simultaneously using maximum computer resources. This parallel build speeds up the process considerably. For example, these are full static build timings on the production build machine (full build includes building all thirdparty programs as well as all of \CGG{}):
321 \begin{tabular}{@{}rcr}
322 1 cpu & = & 61 mins\\
323 12 cpus & = & 7.5 mins\\
324 24 cpus & = & 2 mins\\
327 \section{Using the very latest Libraries}
328 \label{sec:latest_libraries}
329 \index{build!use latest library}
331 Using the most current libraries can be a challenge for some of the Operating System distros that use
332 stable compilers, assemblers, and their own libraries. Because they are stable, they frequently do
333 not keep up with the very latest of thirdparty libraries. Consequently, some program constructs may
334 not yet be implemented. \CGG{} tries to maintain stability since it is better to have less features
335 and no crashes. The goal is to make \CGG{} widely available on many platforms rather than
336 dependent on advanced tools that are not supported on some distros.
338 \CGG{} attempts to upgrade to the latest releases of many thirdparty libraries about every 3-4
339 months. But it is often difficult to keep some of these thirdparty libraries up to date as their
340 developers switch from tried and true standard tools to newer, less standard tools. As a result
341 in order to build \CGG{} on 2-3 versions of any distro rather than only the most current version,
342 some thirdparty libraries can not be kept up to date and may even be to the point of no further
343 updates. In a lot of cases, the updated releases provide little new capabilities but rather
344 are bug fixes that may not even be relevant to \CGG{}'s use.
346 So as a computer savvy user or a developer, if you would like to build \CGG{} with the latest
347 thirdparty releases for some of the packages here are a few suggestions based on other
348 developer's feedback and experimentation.
351 \begin{description}[noitemsep]
352 \item Status - currently \CGG{} is staying at 0.5. This is disappointing because there
353 may be speed gains in version 0.6 that would be beneficial. However, it is usable for decoding
354 whereas libaom is a lot slower. Unfortunately, it has no effective encoder.
355 \item Problem - 0.6 dav1d requires NASM 2.14 and uses instructions like vgf2p8affineqb,
356 not exactly an "add" instruction. It also uses meson which is not widely available on all
357 distros. The only distros that are built for \CGG{} that are at 2.14 are the latest version
358 of Arch, Debian(10), Gentoo, Tumbleweed, and Fedora(31). The rest are at 2.12 and 2.13 including
359 the most widely used Ubuntu. The NASM requirement apparently provides for using AVX-512
360 instructions (like vgf2p8affineqb, which is more like a whole routine than a simple instruction).
361 \item Workaround already in use by \CGG{} - a Makefile was generated to replace Meson usage
362 but has to be continuously updated for new releases. Dav1d 0.5 requires NASM 2.13 so at this level
363 the newer distros mostly work. The availability of meson and nasm are a significant problem on
364 many systems which are still in wide use.
365 \item Your workaround - Because a request to dav1d developers to consider changes to
366 ensure their library is more widely usable does not appear to be in their future, since it works
367 for them, you can upgrade NASM to 2.14 to stay up to date. Of course, install meson also.
371 \begin{description}[noitemsep]
372 \item Status - currently at latest version
373 \item Problem - the OpenExr tarball is not a single package but is 2 packages instead
374 \item Workaround already in use by \CGG{} - reworked the packages so that it looks like
375 one package with 2 stubs
376 \item Your workaround - perhaps use the same workaround
380 \begin{description}[noitemsep]
381 \item Status - 2 different versions specific for O/S but none for Ubuntu 14, 32 or 64 bit
382 \item Problem - There are really 2 problems here. The first is OpenCV is not really
383 "Open" in that Surf is patented/non-free and there is no actual source available for certain
384 capabilities. The second is that cmake 3.5.1 is required for OpenCV 4.2.
385 \item Workaround already in use by \CGG{} - using 3.4.1 for older distros and 4.2 for newer
386 \item Your workaround - upgrade cmake to 3.5.1 for upgrade to 4.2; add non-free to the
387 compile; and use binaries that you do not know what they contain since no source code to compile.
388 Look into opencv4/opencv2/core/types.hpp:711;27
392 \begin{description}[noitemsep]
393 \item Status - currently at version 1.1.0
394 \item Problem - requires cmake 3.5
395 \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7
396 \item Your workaround - upgrade on those systems to cmake 3.5
400 \begin{description}[noitemsep]
401 \item Status - currently at version 3.0.0 for older O/S and 3.1.1 for newer O/S
402 \item Problem - requires cmake 3.5 at 3.0.0 and 3.6 for 3.1.1
403 \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7
404 \item Your workaround - upgrade on those systems to cmake 3.6
408 \begin{description}[noitemsep]
409 \item Status - this is the x10 TV remote control
410 \item Problem - INPUT\_PROP\_POINTING\_STICK not defined error on older distros
411 \item Workaround already in use by \CGG{} - leaving out of Ubuntu14, Ubuntu, Centos7
412 \item Your workaround - look into /usr/include/linux/input-event-codes.h
416 \begin{description}[noitemsep]
417 \item Status - currently at version 1.8.1
418 \item Problem - when decoding a test file, it failed to correctly load to the timeline
419 \item Workaround already in use by \CGG{} - not upgrading to 1.8.2
420 \item Your workaround - no analysis for a solution has been performed yet
423 \section{Find Lock Problems with Booby Trap}
424 \label{sec:find_lock_problems_booby_trap}
425 \index{build!booby trap}
427 A Booby Trap is used in \CGG{} for setting a trap to catch lock problems that might have been missed. It will trap boobies only if compile by adding \textit{-{}-with-booby} on the configuration command line. This is the default if you compile using \texttt{./bld.sh} from the GIT repository. It should not interfere with normal execution.
429 If you have the time and inclination, enable \textit{-{}-with-booby} and send any trap output that you find. Maybe you will catch some boobies and if you do, send a snapshot of any boobies you find.
431 There are 2 potential traps:
433 \begin{itemize}[nosep]
434 \item If you try to unlock a lock when it is not locked
435 \item If you execute a drawing operation without holding the window lock
438 The trap prints the following in the controlling terminal window:
440 \hspace{2em} \textit{BOOBY! \qquad <backtrace>}
442 An example backtrace is below along with a hint below on how to analyze:
444 \begin{lstlisting}[numbers=none]
445 /home/cin5/bin/./cin(_Z5boobyv+0x3f) [0x557069fa9b2f] /home/cin5/bin/./cin(_ZN13BC_WindowBase9draw_lineEiiiiP9BC_Pixmap+0x3b)0x557069fb9a9b]
446 /home/cin5/bin/./cin(\_ZN10BC_ListBox11draw_borderEi+0x73)[0x557069f7dc73]
447 /home/cin5/bin/./cin(+0x9707fb) [0x557069f7e7fb]
448 /home/cin5/bin/./cin(\ZN10BC\ListBox16center\selectionEv+0x4e)[0x557069f7f2ae]
449 /home/cin5/bin/plugins/video/sketcher.plugin(_ZN17SketcherCurveList6updateEi+0x1a0)[0x7f1b8002a4c0]
450 /home/cin5/bin/plugins/video/sketcher.plugin(_ZN18SketcherCurveColor17handle_done_eventEi+0x76)[0x7f1b8002a5f6]
451 /home/cin5/bin/./cin(_ZN15BC_DialogThread3runEv+0xd8)[0x557069f6fb78]
452 /home/cin5/bin/./cin(_ZN6Thread10entrypointEPv+0x45)[0x557069fc5995]
453 /usr/lib/libpthread.so.0(+0x7a9d) [0x7f1b91b4ea9d]
454 /usr/lib/libc.so.6(clone+0x43) [0x7f1b90accb23]
457 To see which routine is reporting the booby key in:
459 \hspace{2em} \texttt{c++filt}
461 And then the $2^{nd}$ line in the backtrace above:
463 \hspace{2em}\texttt{\_ZN13BC\_WindowBase9draw\_lineEiiiiP9BC\_Pixmap}
465 It comes back with the routine as:
467 \hspace{2em}\texttt{BC\_WindowBase::draw\_line(int, int, int, int, BC\_Pixmap*)}
469 \section{Valgrind Support Level}
470 \label{sec:valgrind_support_level}
471 \index{build!valgrind}
473 Valgrind is a memory mis-management detector. It shows you memory leaks, deallocation errors, mismanaged threads, rogue reads/writes, etc. \CGG{} memory management is designed to work with Valgrind detection methods. This assists in developing reliable code. Use of Valgrind points out problems so that they can be fixed. For example, when this version of \CGG{} shuts down, it deallocates memory instead of just stopping, thus making memory leak detection possible.
475 The best way to compile and run valgrind is to run the developer static build. This takes 2 steps and you must already have gdb and valgrind installed:
477 \begin{enumerate}[nosep]
478 \item The standard static build:\\
479 \texttt{cd /path/cinelerra-5.1}\\
480 \texttt{make clean}\\
482 \item run the incremental rebuild for debug objs:\\
483 \texttt{CFLAGS=-ggdb make -j8 rebuild\_all}
486 If you frequently make mods and changes in \CGG{} or the thirdparty libraries, do not depend on those
487 compiled versions to have the headers updated; so be sure to fully rebuild as shown in the previous 2
488 steps before running valgrind or you will get false errors.
490 Now your \CGG{} obj has all of the debug stuff. Next run valgrind as root for the most useful results:
492 \hspace{2em}\texttt{cd /path/cinelerra-5.1/cinelerra}
494 \hspace{2em}\texttt{valgrind -{}-log-file=/tmp/log -{}-leak-check=full\\
495 -{}-num-callers=32 ./ci}
497 This runs \CGG{} under the control of valgrind, and produces a log file in /tmp which will list information about any leaks, usually clearly identifiable. Be sure to Quit out of \CGG{} normally instead of Ctrl-C or a SEGV otherwise the program does not have a chance to cleanup and there will be some false alarms. But it runs very slowly, and is basically single threaded, which means that race conditions may be impossible to catch$\dots$ like one thread deletes memory that another thread is currently using. But overall it is a big help and if you test any new features, please email the log output. A lot of effort when writing the code was put into trying to be sure that all of the object constructors have matching destructors so that the leaks can be identified. There are already several libraries that create predictable memory leaks and valgrind does a good job for most of these.
499 It is impossible to test everything with valgrind because some things are just too big and slow for a practical test. Occasionally you can find a leak or an illegal memory access. There are several false alarms that are difficult to avoid \textit{Conditional jump} messages, and \textit{unhandled DW\_OP\_}, but anything with the word \textit{illegal} in the message is important. Memory leaks that originate in \CGG{} are good to find and fix, but are usually not
500 deadly. The listing of the memory leaks can be quite voluminous so locating the \textit{LEAK SUMMARY} section
501 towards the end of the report is most useful.
504 \section{CFLAGS has -Wall}
505 \label{sec:cflags_has_-wall}
506 When compiling \CGG{} Infinity a CFLAGS option used is \textit{Wall} where the "W" represents warnings and "all" means all. This causes the compile to check for simple mistakes that can be detected automatically and issue warnings when the code is questionable. It can also detect situations where the compiler will generate incorrect code, like type-punned pointer. By turning on this flag, when new code is vetted for predictable mistakes, the code can be corrected before becoming manifested in the application.
508 \section{Prof2 -- A Profiler}
509 \label{sec:prof2_profiler}
512 Frequently there is a problem with a program running slow and you do not know why. You need a thumbnail analysis of where the program is spending most of its time without all of the overwhelming details. This is when a Profiler comes in handy.
514 There are many different profilers available -- this particular one does not do anything special and is fairly ordinary in that it just characterizes frequency of execution of various regions in the program. However, it has some pretty good strengths as listed next.
516 \begin{enumerate}[nosep]
517 \item It takes very little or no preconditioning, i.e. setup
518 \item The effect it has on the running program is minimal
519 \item It runs almost at full speed, which is really nice
520 \item It is not particularly thread aware
521 \item Reports where it is executing at intervals of 100 times a second
527 This profiler works on x86\_64 systems and you must be root to compile and run it. Also, you must install your operating system's \textit{iberty} -- for example, which would be binutils-devel for Fedora or libiberty-dev for Ubuntu 18.
529 Go to the top level \CGG{} directory.
531 Key in: \qquad \texttt{prof2}
533 Key in: \qquad \texttt{make clean all install}
535 Because \textit{smap} may have to be found in the system if \textit{How to use} below does not work, you will have to do the following:
538 Key in: \qquad \texttt{cp -a smap /usr/local/bin}
541 Later, if you want to remove this from the system,
543 Key in: \qquad \texttt{make uninstall}
545 \subsection{How to use}
546 \label{sub:how_to_use}
548 The program you are profiling should be compiled debuggable with stack frame and symbols enabled.
550 To see help, key in: \qquad \texttt{prof -h}
552 usage: -h [-o path] [-d] [-e] [-p libpath] [-012] [-u \#] cmd args...
555 \begin{tabular}{@{}ll}
556 -o & profile output pathname, -=stdout, -{}-=stderr\\
557 -d & debug otitleutput enabled\\
558 -e & child debug output enabled\\
559 -p & specify path for libprofile.so\\
560 -0 & usr+sys cpu timer intervals (sigprof)\\
561 -1 & usr only cpu timer intervals (sigvtalrm)\\
562 -2 & real time timer intervals (sigalrm)\\
563 -u & profile timer interval in usecs\\
566 To execute the profiler, key in:
568 \hspace{2em}\texttt{prof -o /tmp/prof\_list.txt ./cin}
570 where \texttt{/tmp/prof\_list.txt} is the output file and in this case \texttt{cin} is the \CGG{} binary file. The pid of this command will be displayed on the startup window. This comes in handy in the use case where there is a lot of initial load and possible configuration setup inside of \CGG{} and you want to profile plugins and not necessarily all of the setup steps. Then you can use the following command in another window to continue running \CGG{} and obtain the more useful information:
572 \hspace{2em}\texttt{kill -USR1 pid}
574 Running this command refreshes the memory maps used for profiling. When you are profiling a plugin, you want to run this AFTER the plugin loads.
579 There are 3 sections in the resulting output file of this stochastic quick analysis.
581 \begin{enumerate}[nosep]
582 \item The first section is a histogram of the timer intervals of that sample set. Each function occupies a region of addresses. One hundred times a second, the profiler samples the program address in the region of execution.
583 \item In the second section, there is another histogram of the cumulative frequency of all things in the call stack and this should point out who is the culprit. For example, a codec calls a bunch of subroutines, the cost of the subroutines is accumulated to the codec parent caller. This makes the actual cpu user much more apparent.
584 \item The last section is for the library spaces. Each library occupies a region and the profiler adds up the time spent in each of the libraries by frequency.
587 On the very bottom is a 1 line summary which shows you if there is a bad guy and who it is.
589 \subsection{Sample output}
590 \label{sub:sample_output}
592 \textit{--- profile start ---}
594 \textbf{1020 ticks 43 modules 81412 syms}\\
595 \begin{tabular}{@{}rrp{\linewidth-6em}}
596 0.010s & 0.1\% & Autos::copy(long, long, FileXML*, int, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
597 0.010s & 0.1\% & BinFolders::copy\_from(BinFolders*) /mnt0/build5/cinelerra-5.1/bin/cin\\
598 0.010s & 0.1\% & cstrdup(char const*) /mnt0/build5/cinelerra-5.1/bin/cin\\
599 0.010s & 0.1\% & XMLBuffer::encode\_data(char*, char const*, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
600 0.010s & 0.1\% & XMLBuffer::encoded\_length(char const*, int) /mnt0/build5/cinelerra-5.1/bin/cin\\
601 0.010s & 0.1\% & PluginClient::send\_configure\_change() /mnt0/build5/cinelerra-5.1/bin/cin\\
602 0.010s & 0.1\% & UndoVersion::scan\_lines(UndoHashTable*, char*, char*) /mnt0/.../cin\\
603 0.010s & 0.1\% & UndoStackItem::set\_data(char*) /mnt0/build5/cinelerra-5.1/bin/cin\\
604 0.010s & 0.1\% & UndoStack::load(\_IO\_FILE*) /mnt0/build5/cinelerra-5.1/bin/cin\\
605 0.010s & 0.1\% & BC\_Bitmap::cur\_bfr() /mnt0/build5/cinelerra-5.1/bin/cin\\
606 0.010s & 0.1\% & YUV::init\_tables(int, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*, int*) /mnt0/build5/cinelerra-5.1/bin/cin\\
610 \textit{--- profile calls ---}
612 \begin{tabular}{@{}rrl}
613 0.010s & 0.1\% & AutoConf::save\_xml(FileXML*) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
614 0.010s & 0.1\% & Automation::copy(long, long, FileXML*, int, int) 1.0 /mnt0/.../cin\\
615 0.010s & 0.1\% & AWindow::run() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
616 0.010s & 0.1\% & Canvas::stop\_single() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
617 0.010s & 0.1\% & ColorPicker::new\_gui() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
618 0.010s & 0.1\% & ColorWindow::create\_objects() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
619 0.010s & 0.1\% & PaletteWheel::draw(float, float) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
620 0.010s & 0.1\% & PaletteHex::update() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
621 0.010s & 0.1\% & CWindowGUI::draw\_status(int) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
622 0.010s & \textbf{0.1\%} & CWindowCanvas::status\_event() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
626 \begin{tabular}{@{}rrl}
627 0.990s & \textbf{9.7\%} & BC\_Xfer::xfer\_slices(int) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
628 1.880s & \textbf{18.4\%} & DirectUnit::process\_package(LoadPackage*) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
629 1.880s & \textbf{18.4\%} & DirectUnit::rgba8888() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
630 3.910s & \textbf{38.3\%} & \_\_init\_array\_end 1.1 /mnt0/build5/cinelerra-5.1/bin/cin\\
631 5.450s & \textbf{53.4\%} & LoadClient::run() 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
632 7.890s & \textbf{77.4\%} & Thread::entrypoint(void*) 1.0 /mnt0/build5/cinelerra-5.1/bin/cin\\
633 7.890s & \textbf{77.4\%} & start\_thread 1.0 /lib64/libpthread-2.28.so\\
637 \begin{tabular}{@{}rrl}
638 0.010s & 0.1\%/ 0.0\% & /lib64/libm-2.28.so\\
639 0.010s & 0.1\%/ 0.0\% & /lib64/libexpat.so.1.6.8\\
640 0.020s & 0.2\%/ 0.1\% & /lib64/libXext.so.6.4.0\\
641 0.020s & 0.2\%/ 0.1\% & /lib64/libXft.so.2.3.2\\
642 0.020s & 0.2\%/ 0.1\% & /lib64/libxcb.so.1.1.0\\
643 0.040s & 0.4\%/ 0.2\% & /lib64/ld-2.28.so\\
644 0.050s & 0.5\%/ 0.2\% & /lib64/libpng16.so.16.34.0\\
645 0.130s & 1.3\%/ 0.6\% & /lib64/libX11.so.6.3.0\\
646 0.180s & 1.8\%/ 0.8\% & /lib64/libz.so.1.2.11\\
647 0.200s & 2.0\%/ 0.9\% & /lib64/libfontconfig.so.1.12.0\\
648 0.380s & 3.7\%/ 1.8\% & /lib64/libpthread-2.28.so\\
649 1.660s & 16.3\%/ 7.7\% & /lib64/libc-2.28.so\\
650 7.480s & 73.3\%/34.7\% & /mnt0/build5/cinelerra-5.1/bin/cin\\
653 \textbf{10.200t 0.001u+0.000s 21.566r 47.3\%}\\
654 \textit{--- profile end ---}
656 The summary line above in Bold represents the User time, System time, Real time and the percentage is how much Timer time elapsed over Real time so in this case the measurement covers 47.3\% of time.
658 So why use a Profiler? Because it is the ``ls'' for executable functions!!
660 \section{Working on AppImage}
661 \label{sec:working_on_appimage}
663 You can work on the appimage file to make changes and fix errors, or you can create a new appimage from scratch containing customizations. For example, you can add new rendering presets; update the Context-Help; change libraries that are no longer supported by the current distro; or make other modifications.
665 \subsection{Managing AppImage}
666 \label{sub:managing_appimage}
667 \index{appimage!management}
668 A limitation of using AppImage instead of installing the binary or compiling from git, is that there is only a single file without the ability to browse the directory structure or to look for files to edit or check. So if using \CGG{} leads to some errors, it is not possible to investigate and fix the problem. Which means if you want to add the most up-to-date Context-Help or want to introduce some custom presets, that can not be done.
670 Because the appimage file is nothing more than a compressed file containing the same structure as the installed program plus other libraries that allow the program to run independently from the system, the content can be extracted so that you can work on it as you would have on the normally installed program. To do this you will need the appimage management program.
671 Many Linux distros come with this managment program by default, but others may not. For instance in the case of Arch Linux the \texttt{appimagetool-bin} package from AUR needs to be installed.
673 To work on the appimage, first unpack it using the command\protect\footnote{Example provided by Glitterball3}:
675 \begin{lstlisting}[numbers=none]
676 /{path to appimage}/CinGG-yyyymmdd.AppImage --appimage-extract
679 You will now have a \texttt{squashfs-root} folder containing \texttt{/usr/bin/} as well as other files and directories such as \texttt{/usr/lib} and \texttt{/usr/share}. \texttt{Bin} is the folder similar to the one installed with \CGG{} and contains the files that you can work on. Now it is possible to make changes like adding a custom preset in \texttt{/ffmpeg/video} or replacing a library that no longer works with a more recent version by working in \texttt{/squashfs-root/usr/lib}.
681 To start the unpacked program from the bin folder use the command:
683 \begin{lstlisting}[numbers=none]
684 /{path to appimage}/squashfs-root/usr/bin/./cin
687 After making your changes, to get back to having an appimage file instead of having to run the program from the bin folder, you can take the extra step of recompressing the squashfs-root folder.
688 To do so use linuxdeploy's appimage, a program that can also be useful for creating appimages from scratch (\url{https://github.com/linuxdeploy/linuxdeploy/releases/continuous}).
690 The steps to recreate the appimage are:
693 \item Copy the linuxdeploy appimage to \texttt{/\{path to appimage\}} and make sure it is executable.
694 \item Then use the command:
695 \begin{lstlisting}[numbers=none]
696 ./linuxdeploy-x86_64.AppImage --appdir squashfs-root --output appimage
700 A new appimage will be created like the original but containing the changes.
702 Alternatively, download the \texttt{appimagetool} version from \url{https://github.com/AppImage/AppImageKit/releases} if available for your distro and use the command:
704 \begin{lstlisting}[numbers=none]
705 ./appimagetool --comp /{path to appimage}/squashfs-root /tmpCinGG-yyyymmdd.AppImage
708 Now there will be an appimage called \textit{CinGG-yyyymmdd.AppImage} with the changes that were made.
710 \subsection{Build the CinGG.AppImage from scratch}
711 \label{sub:built_appimage_scratch}
712 \index{appimage!creating}
714 If a developer wants to create an appimage from git, follow these next few steps.
715 An existing automated script is available, \texttt{bld\_appimage.sh}, in the directory \texttt{/\{path to cinelerra-5.1\}/blds}.
716 Start by downloading the \CGG{} source from git:
718 \begin{lstlisting}[numbers=none]
719 git clone --depth 1 "git://git.cinelerra-gg.org/goodguy/cinelerra.git" cinelerra5
722 Then move to the \texttt{/\{path to cinelerra-5.1}/\} folder.
724 Now copy \texttt{/\{path to cinelerra-5.1\}/blds/bld\_appimage.sh} to \texttt{/\{path to cinelerra-5.1\}/} and make it executable:
726 \begin{lstlisting}[numbers=none]
727 chmod x+u bld_appimage.sh
730 Download linuxdeploy appimage from \url{https://github.com/linuxdeploy/linuxdeploy/releases/continuous} and copy it to \texttt{\{path to cinelerra-5.1\}} and make it executable.
731 You can make additions or changes in this script if you want to customize the appimage. Then run the command:
733 \begin{lstlisting}[numbers=none]
737 The first part of the script is used to compile \CGG{}; the second part creates the folder \texttt{/AppDir/usr}, which is the basic structure of an appimage, and then populates it with the contents of \texttt{/\{path to cinelerra-5.1\}/bin}. Finally, the third part of the script starts linuxdeploy and builds the appimage.
738 There will now be an appimage of \CGG{} which can be moved, made executable, and run.
739 If there are problems look for errors in the file \texttt{appimage.log}.
741 \section{How to Create a new Theme}
742 \label{sec:how_create_theme}
743 \index{theme!create new theme}
745 A \textit{Theme} is a base class object that is created and customized as \textit{ThemeName}.
746 It is constructed during program initialization in a theme plugin
747 \texttt{PluginTClient},
748 defined in \texttt{plugins/theme\_name} source directory.
750 \texttt{theme\_name.C} and \texttt{theme\_name.h} are derived \textit{Theme} class object constructors.
752 A \textit{Theme} is constructed during initialization in \texttt{init\_theme} (\texttt{mwindow.C}). The theme plugin is accessed using the \textit{name} from preferences and then the theme plugin is loaded which contains the code to construct the theme. A \textit{Theme} object has functions and data that \CGG{} uses to do a variety of customizations, such as \texttt{default\_window\_positions}, and it can modify GUI defaults like \\
753 \texttt{default\_text\_color} when it is initialized.
755 The theme plugin contains a \textit{new\_theme} function that allocates and constructs a
756 \textit{ThemeName} object with base classes of \textit{BC\_Theme} (gui setup), \textit{Theme} (\CGG{} defaults), and \textit{ThemeName}, with definitions and overrides that create the custom theme. To create a new theme, a new plugin is needed:
758 \begin{lstlisting}[numbers=none]
759 #include "header files.h"
760 PluginClient* new_plugin(PluginServer *server)
762 return new NameMain(server);
765 NameMain::NameMain(PluginServer *server)
766 : PluginTClient(server)
770 NameMain::~NameMain()
773 const char* NameMain::plugin_title() { return N_("Name"); }
775 Theme* NameMain::new_theme()
777 theme = new ThemeName;
778 extern unsigned char _binary_theme_name_data_start[];
779 theme->set_data(_binary_theme_name_data_start);
794 When a theme is constructed by \texttt{NameMain::new\_theme()}, it sets a pointer to a
795 block of data created in the plugin build that contains all of the png data
796 files in the \texttt{plugins/theme\_name/data} directory. These images may define or override the appearance of gui images, such as \textit{ok.png} (the ok button). There are usually a large number of images that need to be defined. The theme plugin adds them to the theme image data in the \texttt{theme $\rightarrow$ initialize()} function. The best list of theme image setup is probably in SUV (\texttt{plugins/theme\_suv/suv}).
798 The easy way to create a new theme is to copy an existing theme and change
799 its name to \textit{ThemeName}, change \texttt{plugin\_title()} to the new name, and then tweak the definitions until you are happy with the results. The file
800 names and Makefile also need to be updated to the new theme name. The source
801 can by manually rebuilt by invoking \textit{make} in the \texttt{plugins/theme\_name}
804 Once the new theme is built into the plugin library, it will automatically be discovered by the plugin probe
805 and it will become an available theme in \textit{Preferences}.
807 If you are ready to add it to the main build, then \textit{theme\_name} should be
808 included in the DIRS targets of the \texttt{plugins/Makefile}, and \texttt{plugin\_defs} needs \textit{theme\_name} in the themes list.
810 Themes usually require considerable time to create from scratch. For
811 example, the SUV theme has over 800 lines in the initialize function, and has over
812 500 png images in the data directory. Most of these images and data values are
813 required to be initialized by the custom theme constructor; very tedious and
814 time consuming work. Creating a new theme is usually a lot of work.
816 \section{How Context Help works in the Program Code}
817 \label{sec:context_help_coding}
820 All class methods related to context help start with the common pattern \texttt{context \_help} in their names. It is easy to get all occurences in the code with the following command (example):
822 \begin{lstlisting}[style=sh]
823 grep -F context_help `find . -name '*.[Ch]' -print`
826 The base functionality is defined in several \textit{BC\_WindowBase} class methods in \\ \texttt{guicast/bcwindowbase.C} (search on \texttt{context\_help}). All BC\_Window's and BC\_SubWindow's inherit these methods.
828 For the simplest case of context help definition, it is sufficient to add the call to \texttt{context\_help\_set\_keyword()} in the most inclusive widget constructor. If \texttt{Alt/h} is pressed with the mouse over this widget's window, its \texttt{keypress\_event()} method (inherited from BC\_WindowBase) will catch this hotkey, fetch the keyphrase defined by \texttt{context\_help\_set\_keyword()} and call the \texttt{doc/ContextManual.pl} script with this keyphrase. Then ContextManual.pl script does the whole processing of the keyphrase given and calls web browser to display the found HTML manual page. The browser is called in the background to prevent from blocking the calling \CGG{} thread.
830 An example from \textit{cinelerra/zoombar.C}:
832 \begin{lstlisting}[style=sh]
833 ZoomBar::ZoomBar(MWindow *mwindow, MWindowGUI *gui)
837 this->mwindow = mwindow;
838 context_help_set_keyword("Zoom Panel");
842 If \texttt{Alt/h} is pressed with the mouse over some subwindow (arbitrary depth) of the \texttt{context\_help\_set\_keyword()} caller, the \texttt{keypress\_event()} method of that subwindow catches the hotkey. Its own context help keyword, probably, will be empty. In this case the whole widget hierarchy is traced up to \textit{top\_level} widget, their context help keywords are checked, and the first nonempty keyword is used for context help.
844 This approach allows us to define the help keyword common to the whole dialog window with a bunch of diverse buttons with a single call to \texttt{context\_help\_set \_keyword()}, without placing such a call into each button constructor. And at the same time, this approach allows to assign different help keywords to GUI elements belonging to the same window but documented in different manual pages.
846 \subsubsection{An example with several different help keywords from cinelerra/mwindowgui.C:}%
847 \label{ssub:exemple_different_help_keywords}
849 \begin{lstlisting}[style=sh]
850 MWindowGUI::MWindowGUI(MWindow *mwindow)
851 : BC_Window(_(PROGRAM_NAME ": Program"), ...)
853 this->mwindow = mwindow;
855 context_help_set_keyword("Program Window");
858 FFMpegToggle::FFMpegToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
861 this->mwindow = mwindow;
862 this->mbuttons = mbuttons;
863 set_tooltip(get_value() ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
864 context_help_set_keyword("FFmpeg Early Probe Explanation");
867 StackButton::StackButton(MWindow *mwindow, int x, int y)
868 : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
870 this->mwindow = mwindow;
871 set_tooltip(_("Close EDL"));
872 context_help_set_keyword("OpenEDL");
875 ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
878 this->mwindow = mwindow;
879 this->mbuttons = mbuttons;
881 context_help_set_keyword("Proxy");
884 If the widget we wish to add context help to, overloads keypress\_event() of the base class with its own method, then it is necessary to introduce a small addition to its keypress\_event() handler: the call to \texttt{context\_help\_check\_and\_show()} has to be added in a suitable place in the handler.
886 An example with \texttt{context\_help\_check\_and\_show()} from \textit{cinelerra/mbuttons.C}:
887 \begin{lstlisting}[style=sh]
888 int MButtons::keypress_event()
892 result = transport->keypress_event();
895 result = context_help_check_and_show();
901 All the keypress handlers are not equal, therefore we provide different variants of the methods context\_help\_check\_and\_show() and context\_help\_show() (the latter for explicit checking on hotkey).
903 An example with context\_help\_show() from cinelerra/editpanel.C:
904 \begin{lstlisting}[style=sh]
905 int EditPanelTcInt::keypress_event()
907 if( get_keypress() == 'h' && alt_down() ) {
908 context_help_show("Align Timecodes");
911 ...further processing...
916 A single example of much more sophisticated keypress\_event() handler can be found in \texttt{cinelerra/trackcanvas.C} (search on context\_help). The problem here was to track the particular object drawn on the canvas to figure out whose context help is to be requested. Another rare example of difficulty may appear when context help is desired for some GUI object which is not subclassed from BC\_WindowBase.
918 \textit{ContextManual.pl} looks for occurence of keyphrases in the following order:
921 \item In \textit{Contents.html}
922 \item In \textit{Index.html}
923 \item In all the \textit{CinelerraGG\_Manual/*.html} files via grep
926 Keyphrase matching is tried first exact and case sensitive, then partially and case insensitive. The special keyword \texttt{TOC} shows Contents, \texttt{IDX} shows Index. If the keyword starts with \texttt{FILE:}, the filename after \textit{FILE:} is extracted and that file is shown. You can look in the ContextManual.pl script text.
928 For debugging purposes the script can be called from command line. For this to work, the environment variable \texttt{\$CIN\_DAT} has to be set to the parent directory of doc.
931 \subsubsection{Providing context help for plugins}%
932 \label{ssub:providing_context_help_plugins}
934 In the simplest case, nothing has to be done at all. The plugin context help functionality introduced in \texttt{cinelerra/pluginclient.C} automatically assigns context help keyword from the plugin's title for all plugins subclassed from \textit{PluginClient}. For this to work, the manual page documenting the plugin must be entitled identically to the programmatic title of the plugin. A special treatment can be necessary in the following cases:
937 \item \textit{Rendered effects} are not subclasses of PluginClient and require an explicit context help definition via \texttt{context\_help\_set\_keyword().}
938 \item Only the main plugin dialog inherits context help functionality from the parent class. If a plugin opens additional dialog windows, they probably require explicit context help definitions.
939 \item If the plugin title differs from its subsection title in the documentation, either its help keyword or the corresponding title in the manual should be renamed. Another possibility can be an addition to the \textit{\%rewrite table} in \texttt{doc/ContextManual.pl}.
940 \item If the plugin title contains some characters special for HTML and/or Perl regular expression syntax, the special characters have to be escaped. For example, the keyphrase corresponding to the title \textit{Crop \& Position (X/Y)} should be converted to:
942 \begin{lstlisting}[style=sh]
943 Crop & Position \\(X\\/Y\\)
946 Such a rewriting can be done either in the C++ code or in ContextManual.pl.
949 One additional explanation about previous user information when plugin tooltips are off. Help for the \textit {selected plugin} is shown because in this case it would be difficult to figure out, without a visual feedback, which particular item is currently under the mouse.
951 \subsection{Manual Maintenance is now Tightly Coupled with the Program Code}
952 \label{sub:manmaintain}
954 If some section of the \CGG{} manual gets renamed and is used for Context Help, the corresponding help keywords should be adjusted too. All the keywords used can be listed via the following example command:
956 \begin{lstlisting}[style=sh]
957 grep -F context_help `find . -name '*.C' -print` | grep -F '"'
961 Note that the keyword does not have to exactly match the section title; it can also be a case insensitive substring of the section title.
963 If some new \CGG{} window or dialog is created and documented, the inclusion of context\_help\_set\_keyword() calls and/or adaptation of keypress\_event() handler (if any) should be included in the program code.
965 If some new \CGG{} plugin is created, it is best to document it in the section entitled exactly equal to that plugin's title. Then probably its context help will work out of the box. Otherwise, some adaptation to its keypress\_event() (if any) or to the %rewrite table in ContextManual.pl may be necessary.
967 Why the local copy of \CGG{} manual should be used?
970 \item For context help keyphrases matching, the local copy of \textit{Contents.html} and \textit{Index.html} is necessary anyway.
971 \item Grepping \textit{CinelerraGG\_Manual/*.html} files of the remote manual from the website cannot work per definition.
972 \item The local copy usage ensures exact matching of the version of the manual to the version of \CGG{}. Otherwise, if one uses for some reason an older version of \CGG{} with the help fetched from the newer version of the website manual, various incompatibilities can be expected.
973 \item Packing the manual into AppImage, the current method of \CGG{} packaging, should be much easier than merging two different git branches when building from source packages, as was done earlier.
976 What about Localization?
978 For now, \CGG{} context help is not localized at all. There is no complete \CGG{} manual in any language except English. But even should the manual be translated to other languages, the context help keywords must remain unlocalized literal string constants. First, because the set of languages known to \CGG{} itself is not the same as the set of languages the manual will be translated to. If some "translated keyword" is fed to the help system, while the manual in this language does not exist, keyword matching cannot succeed. Second, such a help localization with the translation of all keywords can be done and then maintained much easier and much more reliably inside the ContextManual.pl script rather than in the \CGG{} binary.
980 More about ContextManual.pl file?
982 The bin/doc/ContextManual.pl script can be configured further. Look in the script text. You can define your preferable web browser, or redefine it to 'echo' for debug purposes. There are also some predefined HTML pages for Contents and Index, and several explicitly rewritten keyphrases.
984 After the first invocation of context help the system-wide script, bin/doc/ContextManual.pl, copies itself into
985 the user's config directory, \$HOME/.bcast5. If the user needs to modify ContextManual.pl, it should be done
986 on that copy from .bcast5 rather than the system-wide one. On all subsequent context help requests this
987 (possibly modified) .bcast5 version of the script will be called. If later the \CGG{} package gets
988 upgraded containing a newer, not 100\% compatible version of ContextManual.pl script, and/or not compatible
989 structure of the HTML manual itself, the new system-wide version of the script will be copied into .bcast5
990 again to ensure context help functionality. The older version of the script will be backed up (with the .bak
991 suffix) as a reference of the modifications done by the user.