This document describes how libmysqlclient was packaged for build2. In particular, this understanding will be useful when upgrading to a new upstream version. The original libmysqlclient library is packaged together with other libraries, the MySQL server, and client utilities. The library source files are spread across several top-level subdirectories. These subdirectories also contain the library-irrelevant files (which we skip) along with examples and tests. The reasonable approach for defining the required source files is to exclude everything you have doubts about and rely on the linker reporting unresolved symbols. We balance between keeping the upstream package directory structure and making sure that the library can be properly imported into a build2 projects. Below are the packaging steps in more detail. 1. Copy include/mysql_version.h.in to mysql/version.h.in, and create mysql/mysql_version.h that includes <mysql/version.h>. 2. Copy config.h.cmake to mysql/config.h.cmake.orig, and use it for creating mysql/my_config.h manually, defining/undefining only those macros that are used in the library source code (see below). Also create mysql/config.h that just includes <mysql/my_config.h>. Note that some macro values can not be easily determined at the preprocessing time. We define them based on the supported platform tests and add mysql/libmysql/assert.c, containing compile-time assertions for the macros in question. Also note that some of the macro values depend on the project configuration. We add such macro definitions into the mysql/version.h.in and include <mysql/version.h> into mysql/my_config.h. We could place them into a separate header template file, but probably there is already enough config and version headers. 3. Copy libbinlogevents/export/binary_log_types.h to mysql/. 4. Part of the upstream package library headers are located under the include/ subdirectory. We will copy it recursively to mysql/, but only those headers that are required by the library source code. We start from an empty mysql/ and add the headers that can't be found by the preprocessor. Note that you need to be careful not to pickup system-installed headers (see below). 5. Recursively copy source files from zlib/, strings/, mysys/, mysys_ssl/, extra/yassl/, vio/, sql/, sql-common/ and libmysql/ to mysql/, preserving the original directory structure, except files not required for the library compilation/linkage (see above). Rename .cc files to .cpp afterwards, using the following command (upstream uses a mixture of extensions which we just not going to bother handling): $ for f in `find . -name '*.cc'`; do mv "$f" "${f%.cc}.cpp"; done Copy the READMEs and licenses for the bundled libraries as well. 6. Copy client/get_password.c to mysql/extra/yassl/src/. 7. Copy upstream package compile-time auto-generated include/mysqld_error.h to mysql/. It is generated from sql/share/errmsg-utf8.txt by the pre-built comp_err utility. The utility also produces some other headers (which we don't use) and localized errmsg.sys files that are not installed with the library. Could we not copy it from a binary or distribution or from Debian/Fedora package? 8. Create mysql/libmysql/libmysql_exports_win32.def to contain a list of the exported names. For that purpose grep through libmysql/CMakeLists.txt to see how the .def file is generated for Windows. The corresponding code normally looks like: MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED} COMPONENT SharedLibraries) If that's the case, collect names that get appended to the CLIENT_API_FUNCTIONS and CLIENT_API_FUNCTIONS_UNDOCUMENTED variables. 9. Copy README to COPYING, and truncate it to contain only the licensing information. 10. Copy COPYING to GPLv2. When merging libmysqlclient build2 package with a new version of the upstream package make sure that all the preprocessor include directives reference the packaged header files, rather than MariaDB or MySQL headers that are installed into the system. It's easy to miss some headers in the package if MariaDB or MySQL development package is installed on the host. We also need to check if the bundled library headers are picked up. To verify the correctness you can build the merged project, concatenate the produced .d files, sort the resulting file removing duplicates and edit the result, leaving only the system headers. Afterwards grep through the remained headers for some patterns: $ cat `find . -name '*.d'` | sort -u >headers $ emacs headers # Edit, leaving system headers only. $ fgrep -e 'mysql' -e 'mariadb' -e 'openssl' -e 'zlib' headers $ for m in `cat mysql/config.h.cmake.orig | sed -n 's/.*#\s*\(define\|cmakedefine\)\s\{1,\}\([_A-Z0-9]\{1,\}\)\(\s.*\)\{0,1\}$/\2/p' | sort -u`; do if grep -q -e "\b$m\b" `find . -name '*.h' -a ! -name 'my_config.h' -a ! -name 'config.h' -o -name '*.c'`; then echo "$m" fi done >used-macros1 $ cat mysql/my_config.h | sed -n 's/#\s*\(define\|undef\)\s\{1,\}\([_A-Z0-9]\{1,\}\)\(\s.*\)\{0,1\}$/\2/p' | sort -u >defined-macros $ diff defined-macros used-macros Also make sure that the macros set in mysql/my_config.h is still up to date. For that purpose obtain the macros that are used in the new source base, then obtain the macros (un)defined in the current mysql/my_config.h and compare the sets. That can be achieved running the following commands in the build2 project root directory: $ for m in `cat mysql/config.h.cmake.orig | sed -n 's/.*#\s*\(define\|cmakedefine\)\s\{1,\}\([_a-zA-Z0-9]\{1,\}\)\(\s.*\)\{0,1\}$/\2/p' | sort -u`; do if grep -q -e "\b$m\b" `find . -name '*.h' -a ! -name 'my_config.h' -a ! -name 'config.h' -o -name '*.c'`; then echo "$m" fi done >used-macros $ cat mysql/my_config.h | sed -n 's/#\s*\(define\|undef\)\s\{1,\}\([_a-zA-Z0-9]\{1,\}\)\(\s.*\)\{0,1\}$/\2/p' | sort -u >defined-macros diff defined-macros used-macros To obtain the pre-defined macros for gcc and clang use following commands: $ gcc -dM -E - < /dev/null $ clang -dM -E - < /dev/null Note that some macro definitions are passed to the preprocessor via the -D command line options. Such macro sets may be specific for source file subdirectories. It makes sense to check that the sets used for the build2 package still match the ones for the new upstream package. For that purpose you can grep the old and new upstream package CMakeList.txt files for ADD_DEFINITIONS() directives and review the changes. If needed, you may also run cmake for the upstream project and view the flags.make files created for the corresponding source directories. Or, as a last resort, you can see the actual compiler and linker command lines running make utility with VERBOSE=1 option. For VC, you need to set output verbosity to Diagnostics level at the 'Tools/Options/Projects and Solutions\Build and Run' dialog tab, change the current directory to the project build directory in CMD console, and run the following command: > devenv MySQL.sln /build >build.log It also makes sense to check for changes in compiler and linker flags. You may grep CMakeList.txt files for the appropriate directives, or you may compile the upstream project in the verbose mode on the platform of interest. To configure the upstream package for the build use the commands like this: $ mkdir out $ cd out $ cmake -DDOWNLOAD_BOOST=1 -DWITH_BOOST=boost -DWITHOUT_SERVER=ON ..