Hi all, So I've been thinking about how to reduce the breakage that occasionally happens to other bits of software on upgrades of libclamav, and I think I've come up with something that might be of some use. libtool lets you use a version script to (on platforms that support it) hide symbols from being globally visible and version those that are.
The benefits of using this sort of approach is that other applications that try to use libclamav internal functions will fail to link instead of just throwing a compiler warning about an implicit function definition. This will allow the clamav team to make their public API more stable, since it is the only thing other people will be using. The downfall, as I have just found out by setting up a version script, is the the clamav applications fail to link without exporting quite a few symbols that really shouldn't be exported by the library. It also doesn't actually help with API/ABI changing modifications in the public API itself - it just frees you to spend more time making sure that can be left alone while you modify the private functions to your heart's content. This says to me that probably the architecture for some of this shared code is wrong at the moment. One of the following solutions is probably useful, but I'll leave it up to you all as to which one you prefer. 1) these symbols should be useable by all applications linking to libclamav (and they should be cl_ instead of their current naming scheme). 2) These symbols should not be in libclamav at all. They should be code in shared/ which gets turned into a convenience library and linked to all the applications and the library at build time, presumably statically. 3) These symbols should be in a second shared library built from shared/ or elsewhere that is installed on the target system. To discourage use of this private library, it could be installed in a sub directory of $libdir, and an rpath added to all the binaries and libclamav. My personal preference is 2. It incurs some on disk and memory overhead, as these symbols will be loaded once for each application, rather than the normal shared library memory saving techniques. That being said, it is the simplest to manage, and is the most effective at making sure other applications do not link to private functions within the clamav suite that change between releases. Ok, so long preamble over. version script: CLAMAV_0.92 { global: cl_*; cli_calloc; cli_chomp; cli_dbgmsg; cli_errmsg; cli_gentemp; cli_gentempdesc; cli_leavetemps_flag; cli_malloc; cli_md5file; cli_md5stream; cli_memstr; cli_ole2_extract; cli_readn; cli_realloc; cli_rmdirs; cli_rndnum; cli_str2hex; cli_strbcasestr; cli_strdup; cli_strrcpy; cli_strtok; cli_strtokbuf; cli_unlockdb; cli_untgz; cli_utf16toascii; cli_versigpss; cli_warnmsg; cli_writelockdb; html_normalise_fd; ppt_vba_read; sha256_digest; sha256_final; sha256_init; sha256_update; tableCreate; tableDestroy; tableFind; tableInsert; tableIterate; tableRemove; tableUpdate; vba56_dir_read; vba_decompress; wm_decrypt_macro; wm_dir_read; local: *; }; Everything in global: is exported and useable at link time. Everything in local is not. As you can see, you can use wildcards, and you can also chain versions, so that if a symbol is introduced or removed in a later version of the library, it gets versioned correctly. All very nice stuff. The automake patches: Index: libclamav/Makefile.am =================================================================== --- libclamav/Makefile.am (revision 572) +++ libclamav/Makefile.am (working copy) @@ -21,8 +21,10 @@ libclamav_la_LIBADD = @LIBCLAMAV_LIBS@ @THREAD_LIBS@ -libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ -no-undefined +libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ -no-undefined -Wl,[EMAIL PROTECTED]@/libclamav/libclamav.map +EXTRA_DIST = libclamav.map + include_HEADERS = clamav.h libclamav_la_SOURCES = \ Index: libclamav/Makefile.in =================================================================== --- libclamav/Makefile.in (revision 572) +++ libclamav/Makefile.in (working copy) @@ -238,7 +238,8 @@ target_vendor = @target_vendor@ INCLUDES = -I$(top_srcdir) [EMAIL PROTECTED]@/unrar [EMAIL PROTECTED]@/nsis libclamav_la_LIBADD = @LIBCLAMAV_LIBS@ @THREAD_LIBS@ -libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ -no-undefined +libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ -no-undefined -Wl,[EMAIL PROTECTED]@/libclamav/libclamav.map +EXTRA_DIST = libclamav.map include_HEADERS = clamav.h libclamav_la_SOURCES = \ clamav.h \ That's about it. This is against current stable, although rerevving it against svn would be fairly trivial. Is this something people are interested in? If so, how can I help to get the list down to global: cl_*; local: *; ? Happy hacking, -- -------------------------------------------------------------------------- | Stephen Gran | <Joy> that's a Kludge(TM) <knghtbrd> It | | [EMAIL PROTECTED] | Works(tm) <Joy> AIX works(TM) | | http://www.lobefin.net/~steve | <knghtbrd> no it doesn't <knghtbrd> => | --------------------------------------------------------------------------
signature.asc
Description: Digital signature
_______________________________________________ http://lurker.clamav.net/list/clamav-devel.html Please submit your patches to our Bugzilla: http://bugs.clamav.net