These are the steps necessary to add a library to the LSB. Note that this is a compilation of notes from bug 3647; it may be worth consulting that bug for the latest information.
- Add library data to specdb.
- Regenerate build_env to pick up the library and associated data.
- Regenerate elfchk, libchk, and dynchk in misc-test.
- Regenerate devchk.
- Add native support packages to devchk build slaves.
- Add support to specification.
Note that the first run-through of these steps will often not be quite right. For example, libchk will often not build correctly with the new SDK if the database isn't right, and will also fail various symbols on the library. After getting libchk clean, devchk builds should be next; then, use the SDK to build an application which uses the library.
Adding the library to the database
This is documented in other places:
- headertodb2: import new libraries using headers and cpp
- libtodb2: a new set of tools automating import of new libraries into the LSB database
- ImportGotchas: Some specific issues/workarounds encounter in importing libtiff using headertodb2
Besides the input of the data itself, the library has to be "turned on" for the new version of the LSB. This is broadly done by setting the LSB version in which each component appears in. Key locations are:
- ArchLib.ALappearedin for the library itself
- SModLib.SMLappearedin to mark the library as present in a particular submodule
- ArchInt.AIappearedin for functions and global variables (note also ArchInt.AIversion for version tags)
- IntStd.ISappearedin for the documentation link for the interface
- LGInt entry needs to be created, binding Interface to a LibGroup
- ArchType.ATappearedin for basic types
- TypeMember.TMappearedin for the members of a structure defined as a basic type
Also, note that submodules need to be marked as required (they are trial-use by default). This is done in the SubModule.SMmandatorysince field.
This requires regenerating:
- headers, including core_filelist and desktop_filelist ("rm core_filelist; make core_filelist" should do the trick)
- stub libraries, core_filelist* and desktop_filelist* ("rm core_filelist_3.0; make core_filelist_3.0").
- lsbdev_cc - remove and regenerate lsbcc_libs.h
- package - remove and regenerate core_pkglist, desktop_pkglist, update Makefile for new version.
"bzr status" should report a number of new files; many of these will need to be added before committing.
"make distclean; make gensrc" should be done in the elfchk, libchk, and dynchk directories. As with build_env, check "bzr status" and add the appropriate files before committing, and don't forget to update the Makefile with a new package version.
Important: see Other Notes section below for more misc-test details.
dynchk will see a lot of new files, as it makes a library subdirectory, then one file per interface.
In devchk/ts/devchk, run "make distclean; make gensrc" and check "bzr status" for new files.
Add packages to devchk build slaves
The new libraries will need to be checked by devchk against native libraries to detect differences that could introduce bugs. To do this, you need access to the Puppet configuration for the LSB systems. There is a list of packages needed in modules/buildbot/manifests/slavepkgs.pp, in the variable "$devchklist". Note that package names are likely to differ on different distributions; follow the examples in that file for how to set the package name to different values depending on the distribution.
Adding the library to the specification
Really complete details are beyond the scope of this note.
In brief, first find the submodule directory in lsbspec that matches the one the library is assigned to, and figure out how to get it to appear there. In a lot of cases, each library gets a subdirectory in generic. For example, libsane appears like "lsbspec/Scan/generic/sane". Copy some other setup that works, edit, add to the makefile, and try to build there. "make gensrc" does db-generated stuff, then "make all" combines those into the final files. Second, the submodule "intro" directory will need a look. There may be some intro matter to write, and the specification matching the new library will get an entry in the list of specification - this SHOULD happen automatically, but if not, may need to add a stanza to the makefile. Third, step 2 needs to be repeated in the module directory. The intros are used in different places - the submodule intro is used in the submodule book (which will not usually be a formal LSB specification), and the module intro is used in the bigger specification books. For the libsane example, the submodule is Scan, the module is Multimedia.
More complex stuff:
Files which are created by an addition, which are intended to appear in the printed specification, need to get an sgml entity tag added to the "entities" file. Those entities then appear either directly in the book build files, or in contents files in the module of submodule directory. To follow the Sane example again, noting Scan is a whole submodule, not just a single library, we've created in "entities":
<!-- Scanning Chapters --> <!-- Generic --> <!ENTITY scanning-intro SYSTEM "Scan/intro/intro.sgml"> <!ENTITY scanning-lib SYSTEM "Scan/generic/sane/sane.sgml"> <!ENTITY scanning-appA SYSTEM "Scan/generic/appendix/liblist.sgml">
And in Sane/contents:
<!-- these are the entities to include for the LSB_Scanning submodule --> &scanning-lib;
Follow existing examples until you can get your new stuff to appear in a built specification.
Full regeneration in build_env/headers and build_env/stub_libs can be very slow. This is painful if you're making iterative changes trying to get things right. It's possible to speed up the process in both directories.
- To build individual headers, a particular header "foo/bar.h" cane made by removing and making it, or the header with all associated defs files is done with "make foo/bar.h-defs" (don't need to remove the header to make the second one work).
- To build stubs for an individual library (all versions), "make dbfiles-libfoo". To build all stubs for a specific version, say 5.0: "make dbfiles-V5.0".
Partial building is useful during experimention, but at some point a full rebuild should be done to pick up spill-over effects, if any - new types may cause other headers to include a new header, etc.
After the interfaces are added, if you want LSB Navigator to show them as appearing in the version where they were added, the interface cache needs to be reloaded. The following mysql instructions should be sufficient:
DROP TABLE IF EXISTS cache_IntStatus; DROP TABLE IF EXISTS cache_ExtraGenericRecords; CALL regen_cache_IntStatus ();
This is not a crucial step, if the interfaces were otherwise correctly added, everything else will work as expected.
- libchk works by examining libraries. To examine the correct library, libchk needs to know where it is. This is handled using a trick: a small binary is built which does nothing, but links to every LSB library. This is misc-test/libchk/dummy_link. The program known as lsblibchk (if LSB packages are used, this is installed as /opt/lsb/bin/lsblibchk) is actually a shell script which invokes the dynamic linker (called as ldd) on dummy_link, and filters the result to feed it as arguments (actually one argument, a file of paths-to-libraries collected from the ldd run) to the real checker, which is called just libchk. So to make this work, when adding a new library, a reference to some routine in the new library needs to be added to dummy_link.c - the model is easy to see if looking a the source file, it's a bogus prototype at the top and a bogus call, each with no arguments, in the body. this is just so something doesn't optimise away to the reference to the library like "you linked with it, but there's no reference to any routine in it". And the library needs to be added to the link line for dummy_link in the makefile.
- devchk MAY need to add the new library to the link line for the devchk executable (called hdrchk). In devchk/ts/devchk, look for the file mktests which is used to generate the makefile, and make changes there, if needed. When is it needed? Devchk does not care about interfaces in LSB libraries, it never calls them as part of testing. Devchk has to do with data items - structures, defines, headers, etc. The only time it needs an actual library to get information from it is if the library has global data members, and in such a case it needs the library to compare the real size with the one stored in the LSB database. Not all LSB libraries have such. One quick way to check is if the stub for that library contains __asm__ statements, those are only used for global data.