← Back to team overview

maria-developers team mailing list archive

Patch to add a Windows NSIS based installer

 

Hi everyone,

After a long and intense fight with CPack and NSIS, I finally have a solution that is functional. The one TODO I have before I consider it really good enough is to be able to set up MariaDB as a service. That will come later.

The big problem with the installer was how to handle the database files. If they are just copied to the data dir and used, the uninstaller will silently delete them. This is *bad*. So I spent a long time trying to get around this problem and make the uninstaller ask if the user wants to get rid of these files. I'm now completely convinced this is impossible with the current CPack :(

I have tried several workarounds, that also wouldn't work before I came up with this:

The installer will install the data files to data\clean. At the end of the installer, it checks if there is a file called data\mysql\db.frm (could have been any other file). If the file is there, the user gets a message saying the installer have not written the clean database files to the data directory. If the file isn't there, the installer copies all the files in data\clean to data.

The uninstaller will of course silently delete all the files in data\clean. But it will give the user a message that the database files are not deleted.

So, if you install this package and uninstall it again, the database files are still on the disk. If you reinstall the package, it will use the existing data files.

If you upgrade to a newer version, this will be installed in a different directory (the default directory name contains the version number), and can copy the data files from the old directory in there if you want to. Or you can copy the clean dir somewhere else and modify the ini file to point at it.

IMHO, this is a reasonable solution that doesn't involve patching CMake or some other evil scheme I've been considering.

To generate an installer: Run cmake as usual, build in visual studio, and call "cpack" when the build is done. That's about as simple as possible :)

Can I check this into the 5.2 branch?

Bo Thorsen.
Monty Program AB.

--

MariaDB: MySQL replacement
Community developed. Feature enhanced. Backward compatible.
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt	2010-06-16 10:58:56 +0000
+++ CMakeLists.txt	2010-06-25 12:18:50 +0000
@@ -335,3 +335,78 @@
   ADD_SUBDIRECTORY(libmysqld/examples)
 ENDIF(WITH_EMBEDDED_SERVER)
 ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+
+# Set up the installer
+SET(CPACK_PACKAGE_NAME "MariaDB")
+STRING(REPLACE "-MariaDB" "" CPACK_PACKAGE_VERSION ${VERSION})
+SET(CPACK_PACKAGE_VENDOR "Monty Program AB http://www.montyprogram.com";)
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MariaDB")
+SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING)
+SET(CPACK_GENERATOR NSIS)
+
+# Installer components and grouping
+SET(CPACK_COMPONENT_GROUP_SERVER_DESCRIPTION "The files necessary for running the MariaDB server.")
+SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "Files used in development on the MariaDB server.")
+SET(CPACK_ALL_INSTALL_TYPES Normal Development)
+SET(CPACK_COMPONENT_RUNTIME_DISPLAY_NAME "MariaDB server")
+SET(CPACK_COMPONENT_RUNTIME_DESCRIPTION "The server itself. You want to install this one.")
+SET(CPACK_COMPONENT_RUNTIME_GROUP "Server")
+SET(CPACK_COMPONENT_RUNTIME_INSTALL_TYPES Normal Development)
+SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Development headers")
+SET(CPACK_COMPONENT_HEADERS_DESCRIPTION "Header files for development on MariaDB.")
+SET(CPACK_COMPONENT_HEADERS_DEPENDS runtime)
+SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
+SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Development)
+SET(CPACK_COMPONENT_PERLSCRIPTS_DISPLAY_NAME "Server perl scripts")
+SET(CPACK_COMPONENT_PERLSCRIPTS_DESCRIPTION "Scripts to controll and modify the server. You need a perl installation for these to work.")
+SET(CPACK_COMPONENT_PERLSCRIPTS_DEPENDS runtime)
+SET(CPACK_COMPONENT_PERLSCRIPTS_GROUP "Server")
+SET(CPACK_COMPONENT_PERLSCRIPTS_INSTALL_TYPES Normal Development)
+# TODO: Add debug files
+# TODO: Add embedded server files
+# TODO: Add test files
+# TODO: Add sql-bench
+
+# Add files to the installer
+INSTALL(FILES COPYING EXCEPTIONS-CLIENT DESTINATION .)
+INSTALL(FILES support-files/my-huge.ini support-files/my-innodb-heavy-4G.ini DESTINATION .)
+INSTALL(FILES support-files/my-large.ini support-files/my-medium.ini DESTINATION .)
+INSTALL(FILES support-files/my-small.ini DESTINATION .)
+INSTALL(FILES Docs/INSTALL-BINARY DESTINATION Docs)
+INSTALL(FILES COPYING DESTINATION Docs)
+FILE(GLOB headerfiles "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h")
+INSTALL(FILES ${headerfiles} DESTINATION include COMPONENT headers)
+INSTALL(FILES include/mysql/plugin.h DESTINATION include/mysql COMPONENT headers)
+INSTALL(FILES libmysql/libmysql.def DESTINATION include COMPONENT headers)
+
+# Handle the database files
+FILE(GLOB datafiles "${CMAKE_CURRENT_SOURCE_DIR}/win/data/mysql/*")
+INSTALL(FILES ${datafiles} DESTINATION data/clean/mysql)
+INSTALL(FILES win/data/maria_log.00000001 win/data/maria_log_control DESTINATION data/clean)
+INSTALL(DIRECTORY win/data/test DESTINATION data/clean)
+SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS}
+  IfFileExists '$INSTDIR\\\\data\\\\mysql\\\\db.frm' 0 CopyDatabaseFiles
+    MessageBox MB_OK 'There are already database files present in the data directory. Clean database files are not written to the directory'
+    GoTo EndCopyDatabaseFiles
+  CopyDatabaseFiles:
+    CopyFiles '$INSTDIR\\\\data\\\\clean\\\\*' '$INSTDIR\\\\data'
+  EndCopyDatabaseFiles:")
+SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS}
+  MessageBox MB_OK 'This will not delete the database files in $INSTDIR\\\\data'")
+
+# Files in the share dir
+INSTALL(FILES sql/share/errmsg.txt DESTINATION share COMPONENT runtime)
+FILE(GLOB charsets sql/share/charsets/*)
+INSTALL(FILES ${charsets} DESTINATION share/charsets COMPONENT runtime)
+FILE(GLOB share_dirs sql/share/*)
+FOREACH(SUBDIR ${share_dirs})
+  FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/sql/share ${SUBDIR})
+  IF (EXISTS ${SUBDIR}/errmsg.sys)
+    INSTALL(FILES ${SUBDIR}/errmsg.sys DESTINATION share/${DIRNAME} COMPONENT runtime)
+  ENDIF(EXISTS ${SUBDIR}/errmsg.sys)
+ENDFOREACH(SUBDIR ${share_dirs})
+
+INCLUDE(InstallRequiredSystemLibraries)
+
+# This must always be the last line
+INCLUDE(CPack)

=== modified file 'client/CMakeLists.txt'
--- client/CMakeLists.txt	2010-03-29 15:13:53 +0000
+++ client/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -85,3 +85,5 @@
 
 ADD_DEFINITIONS(-DHAVE_DLOPEN)
 
+INSTALL(TARGETS mysql mysqltest mysqlcheck mysqldump mysqlimport mysql_upgrade mysqlshow
+	mysqlbinlog mysqladmin mysqlslap echo DESTINATION bin COMPONENT runtime)

=== modified file 'extra/CMakeLists.txt'
--- extra/CMakeLists.txt	2009-05-15 12:57:51 +0000
+++ extra/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -53,3 +53,5 @@
 IF(EMBED_MANIFESTS)
   MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
 ENDIF(EMBED_MANIFESTS)
+
+INSTALL(TARGETS comp_err my_print_defaults perror resolveip replace DESTINATION bin COMPONENT runtime)

=== modified file 'libmysql/CMakeLists.txt'
--- libmysql/CMakeLists.txt	2010-03-29 15:13:53 +0000
+++ libmysql/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -130,3 +130,11 @@
 IF(EMBED_MANIFESTS)
   MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
 ENDIF(EMBED_MANIFESTS)
+
+# TODO: Install mysqlclient_notls?
+# TODO: Which component should these be part of, development?
+INSTALL(TARGETS mysqlclient DESTINATION lib/opt COMPONENT runtime)
+INSTALL(TARGETS libmysql DESTINATION lib/opt COMPONENT runtime)
+
+# Also install libmysql.dll to the bin dir
+INSTALL(TARGETS libmysql DESTINATION bin COMPONENT runtime)

=== modified file 'mysys/CMakeLists.txt'
--- mysys/CMakeLists.txt	2009-12-03 11:19:05 +0000
+++ mysys/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -49,4 +49,6 @@
 
 IF(NOT SOURCE_SUBLIBS)
   ADD_LIBRARY(mysys ${MYSYS_SOURCES})
+  
+  INSTALL(TARGETS mysys DESTINATION lib/opt COMPONENT runtime) # TODO: Component?
 ENDIF(NOT SOURCE_SUBLIBS)

=== modified file 'regex/CMakeLists.txt'
--- regex/CMakeLists.txt	2009-10-09 07:53:29 +0000
+++ regex/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -22,4 +22,6 @@
 
 IF(NOT SOURCE_SUBLIBS)
   ADD_LIBRARY(regex ${REGEX_SOURCES})
+  
+  INSTALL(TARGETS regex DESTINATION lib/opt COMPONENT runtime) # TODO: Component
 ENDIF(NOT SOURCE_SUBLIBS)

=== modified file 'scripts/CMakeLists.txt'
--- scripts/CMakeLists.txt	2010-05-12 12:33:10 +0000
+++ scripts/CMakeLists.txt	2010-06-25 08:47:54 +0000
@@ -75,3 +75,8 @@
 
 CONFIGURE_FILE(mysqlhotcopy.sh
                ${CMAKE_BINARY_DIR}/scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY)
+
+INSTALL(FILES mysqldumpslow.pl mysqlhotcopy.pl mysql_config.pl
+	mysql_convert_table_format.pl mysql_install_db.pl
+	mysql_secure_installation.pl mysqld_multi.pl
+	DESTINATION scripts COMPONENT perlscripts)

=== modified file 'server-tools/instance-manager/CMakeLists.txt'
--- server-tools/instance-manager/CMakeLists.txt	2010-04-02 09:20:09 +0000
+++ server-tools/instance-manager/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -36,3 +36,5 @@
 IF(EMBED_MANIFESTS)
   MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker")
 ENDIF(EMBED_MANIFESTS)
+
+INSTALL(TARGETS mysqlmanager DESTINATION bin COMPONENT runtime)

=== modified file 'sql/CMakeLists.txt'
--- sql/CMakeLists.txt	2010-06-01 19:52:20 +0000
+++ sql/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -155,3 +155,8 @@
 ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def)
 ADD_DEPENDENCIES(udf_example strings GenError)
 TARGET_LINK_LIBRARIES(udf_example strings wsock32)
+
+INSTALL(TARGETS mysqld
+	RUNTIME DESTINATION bin COMPONENT runtime
+	LIBRARY DESTINATION lib COMPONENT runtime
+	ARCHIVE DESTINATION lib COMPONENT runtime)

=== modified file 'storage/maria/CMakeLists.txt'
--- storage/maria/CMakeLists.txt	2009-10-14 12:58:53 +0000
+++ storage/maria/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -91,4 +91,7 @@
   MYSQL_EMBED_MANIFEST("maria_pack" "asInvoker")
 ENDIF(EMBED_MANIFESTS)
 
+INSTALL(TARGETS maria_ftdump maria_chk maria_read_log maria_pack maria_dump_log
+	DESTINATION bin COMPONENT runtime)
+
 ENDIF(NOT SOURCE_SUBLIBS)

=== modified file 'storage/myisam/CMakeLists.txt'
--- storage/myisam/CMakeLists.txt	2009-09-07 20:50:10 +0000
+++ storage/myisam/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -70,4 +70,6 @@
     MYSQL_EMBED_MANIFEST("myisampack" "asInvoker")
   ENDIF(EMBED_MANIFESTS)
 
+  INSTALL(TARGETS myisam_ftdump myisamchk myisamlog myisampack DESTINATION bin COMPONENT runtime)
+
 ENDIF(NOT SOURCE_SUBLIBS)

=== modified file 'strings/CMakeLists.txt'
--- strings/CMakeLists.txt	2009-09-15 10:46:35 +0000
+++ strings/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -30,4 +30,6 @@
 
 IF(NOT SOURCE_SUBLIBS)
   ADD_LIBRARY(strings ${STRINGS_SOURCES})
+  
+  INSTALL(TARGETS strings DESTINATION lib/opt COMPONENT runtime) # TODO: Component
 ENDIF(NOT SOURCE_SUBLIBS)

=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt	2008-05-22 22:25:21 +0000
+++ tests/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -25,3 +25,5 @@
 
 ADD_EXECUTABLE(bug25714 bug25714.c)
 TARGET_LINK_LIBRARIES(bug25714 mysqlclient_notls wsock32)
+
+INSTALL(TARGETS mysql_client_test bug25714 DESTINATION bin COMPONENT runtime)

=== modified file 'zlib/CMakeLists.txt'
--- zlib/CMakeLists.txt	2007-08-03 20:57:21 +0000
+++ zlib/CMakeLists.txt	2010-06-25 07:00:42 +0000
@@ -27,4 +27,6 @@
 			zutil.c zutil.h)
 IF(NOT SOURCE_SUBLIBS)
   ADD_LIBRARY(zlib ${ZLIB_SOURCES})
+  
+  INSTALL(TARGETS zlib DESTINATION lib/opt COMPONENT runtime) # TODO: Component
 ENDIF(NOT SOURCE_SUBLIBS)