From 814469eec6a28a0ed80dc0b70126399a67b4e92f Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Wed, 6 Feb 2013 00:37:51 -0600 Subject: Added Linux support to CMakeLists. --- CMakeLists.txt | 12 ++++++++++-- dependencies.cmake.in | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb9e6faa..aa9e39de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ add_executable(MultiMC ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MUL qt5_use_modules(MultiMC Widgets) target_link_libraries(MultiMC quazip patchlib ${MultiMC_LINK_ADDITIONAL_LIBS}) add_dependencies(MultiMC MultiMCLauncher) -install(TARGETS MultiMC RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(TARGETS MultiMC RUNTIME DESTINATION .) IF(WIN32) IF(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -169,7 +169,7 @@ ENDIF() install(FILES "${Qt5_DIR}/plugins/platforms/qwindows${D}.dll" DESTINATION platforms) install(FILES "${Qt5_DIR}/plugins/platforms/qminimal${D}.dll" DESTINATION platforms) -install(FILES "${Qt5_DIR}/bin/libEGL${D}.dll" DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(FILES "${Qt5_DIR}/bin/libEGL${D}.dll" DESTINATION .) install(FILES "${Qt5_DIR}/plugins/imageformats/qsvg${D}.dll" DESTINATION imageformats) install(FILES "${Qt5_DIR}/plugins/imageformats/qico${D}.dll" DESTINATION imageformats) @@ -177,6 +177,14 @@ install(FILES "${Qt5_DIR}/plugins/imageformats/qgif${D}.dll" DESTINATION imagefo install(FILES "${Qt5_DIR}/plugins/imageformats/qjpeg${D}.dll" DESTINATION imageformats) ELSEIF(UNIX) +IF (APPLE) +ELSE() + +install(FILES "${Qt5_DIR}/plugins/platforms/libqlinuxfb.so" DESTINATION platforms) +install(FILES "${Qt5_DIR}/plugins/platforms/libqminimal.so" DESTINATION platforms) +install(FILES "${Qt5_DIR}/plugins/platforms/libqxcb.so" DESTINATION platforms) + +ENDIF() ENDIF() diff --git a/dependencies.cmake.in b/dependencies.cmake.in index 1790b97b..408bb811 100644 --- a/dependencies.cmake.in +++ b/dependencies.cmake.in @@ -11,8 +11,10 @@ message(STATUS "Prerequisites: ${MULTIMC_PREREQS}") FOREACH(PREREQ ${MULTIMC_PREREQS}) GET_FILENAME_COMPONENT(PREREQ_NAME "${PREREQ}" NAME) - GET_FILENAME_COMPONENT(_PREREQ_ACTUAL "${PREREQ}" REALPATH) + GET_FILENAME_COMPONENT(PREREQ_ACTUAL "${PREREQ}" REALPATH) + IF(WIN32) SET(PREREQ_ACTUAL "${Qt5_DIR}/bin/${PREREQ}") + ENDIF() message(STATUS "Adding install prerequisite: ${PREREQ_NAME}") -- cgit v1.2.3 From 5a4b2ad00026f89b05aaa7bcfedd244f948c4376 Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Tue, 12 Feb 2013 10:14:23 -0600 Subject: Linux packaging stuff. --- CMakeLists.txt | 65 +++++++++++++++++++++++++++++++++++++++++++-------- dependencies.cmake.in | 8 ++++++- package/linux/MultiMC | 8 +++++++ 3 files changed, 70 insertions(+), 11 deletions(-) create mode 100755 package/linux/MultiMC diff --git a/CMakeLists.txt b/CMakeLists.txt index f67b8346..15e649e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,31 +175,76 @@ add_executable(MultiMC ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MUL qt5_use_modules(MultiMC Widgets Network) target_link_libraries(MultiMC quazip patchlib ${MultiMC_LINK_ADDITIONAL_LIBS}) add_dependencies(MultiMC MultiMCLauncher) + +IF (WIN32) install(TARGETS MultiMC RUNTIME DESTINATION .) +ELSE() +install(TARGETS MultiMC RUNTIME DESTINATION bin) +ENDIF() + + + +# Extra libs and files to package. + +# Image format plugins. +SET(IMAGE_FORMAT_PLUGINS svg ico gif jpeg) IF(WIN32) + +# Windows + IF(CMAKE_BUILD_TYPE STREQUAL "Debug") SET(D "d") ELSE() SET(D "") ENDIF() -install(FILES "${Qt5_DIR}/plugins/platforms/qwindows${D}.dll" DESTINATION platforms) -install(FILES "${Qt5_DIR}/plugins/platforms/qminimal${D}.dll" DESTINATION platforms) -install(FILES "${Qt5_DIR}/bin/libEGL${D}.dll" DESTINATION .) +# Install platform plugins. +SET(PLATFORM_PLUGINS windows minimal) +FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) + INSTALL(FILES "${Qt5_DIR}/plugins/platforms/q${PLATFORM_PLUGIN}${D}.dll" DESTINATION platforms) +ENDFOREACH() + +# Install image format plugins. +FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) + INSTALL(FILES "${Qt5_DIR}/plugins/imageformats/q${IMGFMT_PLUGIN}${D}.dll" DESTINATION imageformats) +ENDFOREACH() -install(FILES "${Qt5_DIR}/plugins/imageformats/qsvg${D}.dll" DESTINATION imageformats) -install(FILES "${Qt5_DIR}/plugins/imageformats/qico${D}.dll" DESTINATION imageformats) -install(FILES "${Qt5_DIR}/plugins/imageformats/qgif${D}.dll" DESTINATION imageformats) -install(FILES "${Qt5_DIR}/plugins/imageformats/qjpeg${D}.dll" DESTINATION imageformats) +# Additional libs +INSTALL(FILES "${Qt5_DIR}/bin/libEGL${D}.dll" DESTINATION .) ELSEIF(UNIX) IF (APPLE) + +# OS X +# TODO: OS X packaging support + ELSE() -install(FILES "${Qt5_DIR}/plugins/platforms/libqlinuxfb.so" DESTINATION platforms) -install(FILES "${Qt5_DIR}/plugins/platforms/libqminimal.so" DESTINATION platforms) -install(FILES "${Qt5_DIR}/plugins/platforms/libqxcb.so" DESTINATION platforms) +# Linux + +# Install platform plugins. +SET(PLATFORM_PLUGINS linuxfb xcb minimal) +FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) + INSTALL(FILES "${Qt5_DIR}/plugins/platforms/libq${PLATFORM_PLUGIN}.so" DESTINATION platforms) +ENDFOREACH() + +# Install image format plugins. +FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) + INSTALL(FILES "${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" DESTINATION imageformats) +ENDFOREACH() + +# Install ICU libs. +SET(ICU_LIBS data i18n io le lx test tu uc) +FOREACH(ICU_LIB ${ICU_LIBS}) + INSTALL(FILES "/usr/lib/libicu${ICU_LIB}.so.48.1.1" DESTINATION lib) +ENDFOREACH() + +# Install additional libs. +INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) + +# Install the start script. +INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/package/linux/MultiMC" DESTINATION .) ENDIF() ENDIF() diff --git a/dependencies.cmake.in b/dependencies.cmake.in index 408bb811..9d4d1f63 100644 --- a/dependencies.cmake.in +++ b/dependencies.cmake.in @@ -4,6 +4,12 @@ message(STATUS "Running install script...") SET(Qt5_DIR @Qt5_DIR@) +IF(WIN32) +SET(LIB_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) +ELSE() +SET(LIB_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/lib) +ENDIF() + INCLUDE(GetPrerequisites) GET_PREREQUISITES(@BINARY_LOCATION@ MULTIMC_PREREQS 1 1 "" "") @@ -19,7 +25,7 @@ FOREACH(PREREQ ${MULTIMC_PREREQS}) message(STATUS "Adding install prerequisite: ${PREREQ_NAME}") FILE(INSTALL - DESTINATION "${CMAKE_INSTALL_PREFIX}" + DESTINATION "${LIB_INSTALL_PREFIX}" TYPE PROGRAM RENAME "${PREREQ_NAME}" FILES "${PREREQ_ACTUAL}" diff --git a/package/linux/MultiMC b/package/linux/MultiMC new file mode 100755 index 00000000..20ecb6d1 --- /dev/null +++ b/package/linux/MultiMC @@ -0,0 +1,8 @@ +#!/bin/sh +# Basic start script for running MultiMC with the libs packaged with it. + +MMC_DIR = $(dirname "$0") +cd "${MMC_DIR}" + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"./lib" +exec ./bin/MultiMC -- cgit v1.2.3 From 397c0cb5559768e38f15700f1ed155dd06f35bc8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 12 Feb 2013 11:57:18 -0600 Subject: Fixed install to automatically include required DLLs. Suck it, DLL hell! --- CMakeLists.txt | 75 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15e649e3..55645e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,9 +186,39 @@ ENDIF() # Extra libs and files to package. +IF(WIN32) +SET(LIB_INSTALL_PREFIX .) +SET(LIB_INSTALL_PREFIX_ABS ${CMAKE_INSTALL_PREFIX}) +ELSE() +SET(LIB_INSTALL_PREFIX lib) +SET(LIB_INSTALL_PREFIX_ABS ${CMAKE_INSTALL_PREFIX}/lib) +ENDIF() + + # Image format plugins. SET(IMAGE_FORMAT_PLUGINS svg ico gif jpeg) +INCLUDE(GetPrerequisites) + +MACRO(INCLUDE_DLL_DEPS DLL_FILE DEST) +GET_PREREQUISITES(${DLL_FILE} DLL_PREREQS 1 1 "" "") + +INSTALL(FILES ${DLL_FILE} DESTINATION ${DEST}) + +FOREACH(PREREQ ${DLL_PREREQS}) + GET_FILENAME_COMPONENT(PREREQ_NAME "${PREREQ}" NAME) + GET_FILENAME_COMPONENT(PREREQ_ACTUAL "${PREREQ}" REALPATH) + IF(WIN32) + SET(PREREQ_ACTUAL "${Qt5_DIR}/bin/${PREREQ}") + ENDIF() + + MESSAGE(STATUS "Adding install prerequisite: ${PREREQ_NAME}") + + INSTALL(FILES ${PREREQ_ACTUAL} RENAME ${PREREQ_NAME} DESTINATION ${LIB_INSTALL_PREFIX}) +ENDFOREACH() +ENDMACRO() + + IF(WIN32) # Windows @@ -202,17 +232,14 @@ ENDIF() # Install platform plugins. SET(PLATFORM_PLUGINS windows minimal) FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) - INSTALL(FILES "${Qt5_DIR}/plugins/platforms/q${PLATFORM_PLUGIN}${D}.dll" DESTINATION platforms) + INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/platforms/q${PLATFORM_PLUGIN}${D}.dll" platforms) ENDFOREACH() # Install image format plugins. FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) - INSTALL(FILES "${Qt5_DIR}/plugins/imageformats/q${IMGFMT_PLUGIN}${D}.dll" DESTINATION imageformats) + INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/q${IMGFMT_PLUGIN}${D}.dll" imageformats) ENDFOREACH() -# Additional libs -INSTALL(FILES "${Qt5_DIR}/bin/libEGL${D}.dll" DESTINATION .) - ELSEIF(UNIX) IF (APPLE) @@ -226,22 +253,23 @@ ELSE() # Install platform plugins. SET(PLATFORM_PLUGINS linuxfb xcb minimal) FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) - INSTALL(FILES "${Qt5_DIR}/plugins/platforms/libq${PLATFORM_PLUGIN}.so" DESTINATION platforms) + INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/platforms/libq${PLATFORM_PLUGIN}.so" platforms) ENDFOREACH() # Install image format plugins. FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) - INSTALL(FILES "${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" DESTINATION imageformats) + INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" imageformats) ENDFOREACH() +# This stuff *should* be added automatically by the INCLUDE_DLL_DEPS macro. # Install ICU libs. -SET(ICU_LIBS data i18n io le lx test tu uc) -FOREACH(ICU_LIB ${ICU_LIBS}) - INSTALL(FILES "/usr/lib/libicu${ICU_LIB}.so.48.1.1" DESTINATION lib) -ENDFOREACH() +#SET(ICU_LIBS data i18n io le lx test tu uc) +#FOREACH(ICU_LIB ${ICU_LIBS}) +# INSTALL(FILES "/usr/lib/libicu${ICU_LIB}.so.48.1.1" DESTINATION lib) +#ENDFOREACH() # Install additional libs. -INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) +#INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) # Install the start script. INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/package/linux/MultiMC" DESTINATION .) @@ -269,6 +297,25 @@ IF(UNIX) ELSEIF(WIN32) SET(CPACK_GENERATOR "ZIP") ENDIF() -set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) -set(CPACK_PACKAGE_FILE_NAME "MultiMC") +SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) + +SET(CPACK_GENERATOR NSIS) +SET(CPACK_PACKAGE_NAME "MultiMC 5") +SET(CPACK_PACKAGE_VENDOR "") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MultiMC - Minecraft launcher and management tool.") +SET(CPACK_PACKAGE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}") +SET(CPACK_PACKAGE_VERSION_MAJOR ${MultiMC_VERSION_MAJOR}) +SET(CPACK_PACKAGE_VERSION_MINOR ${MultiMC_VERSION_MINOR}) +SET(CPACK_PACKAGE_VERSION_PATCH ${MultiMC_VERSION_REV}) + +IF(CPACK_GENERATOR STREQUAL "NSIS") +SET(CPACK_PACKAGE_FILE_NAME "Setup-MultiMC") +ELSE() +SET(CPACK_PACKAGE_FILE_NAME "MultiMC") +ENDIF() + +IF(WIN32) +SET(CPACK_PACKAGE_INSTALL_DIRECTORY "MultiMC 5") +ENDIF() + INCLUDE(CPack) -- cgit v1.2.3 From 4c5d19a62a7914a8ce77bde4824708d586334108 Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Tue, 12 Feb 2013 12:49:13 -0600 Subject: Fixed Linux install / package support in CMakeLists. Fixed Linux start script. --- CMakeLists.txt | 24 +++++++++++++++++------- package/linux/MultiMC | 3 ++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 55645e3c..c8b6f95b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -200,9 +200,11 @@ SET(IMAGE_FORMAT_PLUGINS svg ico gif jpeg) INCLUDE(GetPrerequisites) +# Includes DLL dependencies for the given file. Does not include installed system DLLs. Recursive. MACRO(INCLUDE_DLL_DEPS DLL_FILE DEST) GET_PREREQUISITES(${DLL_FILE} DLL_PREREQS 1 1 "" "") +MESSAGE(STATUS "Installing ${DLL_FILE} and its prerequisites.") INSTALL(FILES ${DLL_FILE} DESTINATION ${DEST}) FOREACH(PREREQ ${DLL_PREREQS}) @@ -212,12 +214,19 @@ FOREACH(PREREQ ${DLL_PREREQS}) SET(PREREQ_ACTUAL "${Qt5_DIR}/bin/${PREREQ}") ENDIF() - MESSAGE(STATUS "Adding install prerequisite: ${PREREQ_NAME}") + MESSAGE(STATUS "Adding install prerequisite for ${DLL_FILE}: ${PREREQ_NAME}") INSTALL(FILES ${PREREQ_ACTUAL} RENAME ${PREREQ_NAME} DESTINATION ${LIB_INSTALL_PREFIX}) ENDFOREACH() ENDMACRO() +MACRO(INSTALL_SYMLINK_DEST LINK_FILENAME DEST) +GET_FILENAME_COMPONENT(DEST_NAME "${LINK_FILENAME}" NAME) +GET_FILENAME_COMPONENT(DEST_ACTUAL "${LINK_FILENAME}" REALPATH) + +INSTALL(FILES "${DEST_ACTUAL}" RENAME "${DEST_NAME}" DESTINATION "${DEST}") +ENDMACRO() + IF(WIN32) @@ -261,12 +270,14 @@ FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" imageformats) ENDFOREACH() -# This stuff *should* be added automatically by the INCLUDE_DLL_DEPS macro. +# This stuff *should* be added automatically by the INCLUDE_ALL_DLL_DEPS macro. Include them manually just in case. # Install ICU libs. -#SET(ICU_LIBS data i18n io le lx test tu uc) -#FOREACH(ICU_LIB ${ICU_LIBS}) -# INSTALL(FILES "/usr/lib/libicu${ICU_LIB}.so.48.1.1" DESTINATION lib) -#ENDFOREACH() +SET(ICU_LIBS data i18n io le lx test tu uc) +FOREACH(ICU_LIB ${ICU_LIBS}) + INSTALL_SYMLINK_DEST("/usr/lib/libicu${ICU_LIB}.so.48" ${LIB_INSTALL_PREFIX}) +ENDFOREACH() + +INSTALL_SYMLINK_DEST("/usr/lib/libxcb-render-util.so.0" ${LIB_INSTALL_PREFIX}) # Install additional libs. #INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) @@ -299,7 +310,6 @@ ELSEIF(WIN32) ENDIF() SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0) -SET(CPACK_GENERATOR NSIS) SET(CPACK_PACKAGE_NAME "MultiMC 5") SET(CPACK_PACKAGE_VENDOR "") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MultiMC - Minecraft launcher and management tool.") diff --git a/package/linux/MultiMC b/package/linux/MultiMC index 20ecb6d1..235d17c5 100755 --- a/package/linux/MultiMC +++ b/package/linux/MultiMC @@ -1,8 +1,9 @@ #!/bin/sh # Basic start script for running MultiMC with the libs packaged with it. -MMC_DIR = $(dirname "$0") +MMC_DIR=$(dirname "$0") cd "${MMC_DIR}" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"./lib" +export QT_PLUGIN_PATH=$QT_PLUGIN_PATH:"." exec ./bin/MultiMC -- cgit v1.2.3 From 5f8784a62e642e7c79c5dfd94da57d755db2fee3 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 12 Feb 2013 13:25:42 -0600 Subject: More damn libxcb dependencies. DLL hell is not fun. --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8b6f95b..877a9699 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,7 +277,10 @@ FOREACH(ICU_LIB ${ICU_LIBS}) INSTALL_SYMLINK_DEST("/usr/lib/libicu${ICU_LIB}.so.48" ${LIB_INSTALL_PREFIX}) ENDFOREACH() -INSTALL_SYMLINK_DEST("/usr/lib/libxcb-render-util.so.0" ${LIB_INSTALL_PREFIX}) +SET(XCB_LIBS render-util.so.0 image.so.0 icccm.so.4 sync.so.0 xfixes.so.0) +FOREACH(XCB_LIB ${XCB_LIBS}) + INSTALL_SYMLINK_DEST("/usr/lib/libxcb-${XCB_LIB}" ${LIB_INSTALL_PREFIX}) +ENDFOREACH() # Install additional libs. #INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) -- cgit v1.2.3 From b7120b293e3d50345d659fa267e376896a494b59 Mon Sep 17 00:00:00 2001 From: mortu Date: Tue, 12 Feb 2013 13:50:45 -0600 Subject: Successfully build using clang 4.1 on OSX --- CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 877a9699..71c11a27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,16 @@ include_directories(patchlib) # add the java launcher add_subdirectory(launcher) -IF(UNIX) +IF(APPLE) + # assume clang 4.1.0+, add C++0x/C++11 stuff + message(STATUS "Using APPLE CMAKE_CXX_FLAGS") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++") +ELSEIF(UNIX) # assume GCC, add C++0x/C++11 stuff + message(STATUS "Using UNIX CMAKE_CXX_FLAGS") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") ELSEIF(MINGW) + message(STATUS "Using MINGW CMAKE_CXX_FLAGS") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") ENDIF() -- cgit v1.2.3 From d1b1d7e800173cb0e165babc625ddab03ea7e653 Mon Sep 17 00:00:00 2001 From: Andrew Okin Date: Tue, 12 Feb 2013 13:59:15 -0600 Subject: Don't bother installing Qt 5 dependencies. Leave it to the user. Maybe we'll make a debian package or something later. --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 877a9699..a191ea6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,8 +270,10 @@ FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" imageformats) ENDFOREACH() +# This just turns into a mess. It's probably better to leave installing dependencies to the user. +IF(INCLUDE_BULLSHIT_DLLS) # This stuff *should* be added automatically by the INCLUDE_ALL_DLL_DEPS macro. Include them manually just in case. -# Install ICU libs. +# Install ICU libs SET(ICU_LIBS data i18n io le lx test tu uc) FOREACH(ICU_LIB ${ICU_LIBS}) INSTALL_SYMLINK_DEST("/usr/lib/libicu${ICU_LIB}.so.48" ${LIB_INSTALL_PREFIX}) @@ -281,9 +283,7 @@ SET(XCB_LIBS render-util.so.0 image.so.0 icccm.so.4 sync.so.0 xfixes.so.0) FOREACH(XCB_LIB ${XCB_LIBS}) INSTALL_SYMLINK_DEST("/usr/lib/libxcb-${XCB_LIB}" ${LIB_INSTALL_PREFIX}) ENDFOREACH() - -# Install additional libs. -#INSTALL(FILES "${Qt5_DIR}/lib/libQt5DBus.so.5.0.1" DESTINATION lib RENAME libQt5DBus.so.5) +ENDIF() # Install the start script. INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/package/linux/MultiMC" DESTINATION .) -- cgit v1.2.3 From fe452e3ac96699d51d47ecdc43c58778b512d72a Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Feb 2013 10:46:39 -0600 Subject: Added SigList class. --- CMakeLists.txt | 2 + data/siglist.h | 130 ++++++++++++++++++++++++++++++++++++++++++++ data/siglist_imp.h | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+) create mode 100644 data/siglist.h create mode 100644 data/siglist_imp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a191ea6b..dbe86a83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,6 +133,8 @@ data/stdinstance.h data/version.h data/userinfo.h data/loginresponse.h +data/siglist.h +data/siglist_imp.h util/apputils.h util/pathutils.h diff --git a/data/siglist.h b/data/siglist.h new file mode 100644 index 00000000..b6432b6e --- /dev/null +++ b/data/siglist.h @@ -0,0 +1,130 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SIGLIST_H +#define SIGLIST_H + +#include +#include + +// A QList that allows emitting signals when the list changes. +// Since QObject doesn't support templates, to use this class with a +// certain type, you should create a class deriving from SigList and then +// call the DEFINE_SIGLIST_SIGNALS(T) and SETUP_SIGLIST_SIGNALS(T) macros. +template +class SigList : public QList +{ + +public: + explicit SigList() : QList() {} + + virtual void append(const T &value); + virtual void append(const QList &other); + + virtual void clear(); + + virtual void erase(iterator pos); + virtual void erase(iterator first, iterator last); + + virtual void insert(int i, const T &t); + virtual void insert(iterator before, const T &t); + + virtual void move(int from, int to); + + virtual void pop_back() { takeLast(); } + virtual void pop_front() { takeFirst(); } + + virtual void push_back(const T &t) { append(t); } + virtual void push_front(const T &t) { prepend(t); } + + virtual void prepend(const T &t); + + virtual int removeAll(const T &t); + virtual bool removeOne(const T &t); + + virtual void removeAt(int i) { takeAt(i); } + virtual void removeFirst() { takeFirst(); } + virtual void removeLast() { takeLast(); } + + virtual void swap(QList &other); + virtual void swap(int i, int j); + + virtual T takeAt(int i); + virtual T takeFirst(); + virtual T takeLast(); + + virtual QList &operator +=(const QList &other) { append(other); return *this; } + virtual QList &operator +=(const T &value) { append(value); return *this; } + virtual QList &operator <<(const QList &other) { append(other); return *this; } + virtual QList &operator <<(const T &value) { append(value); return *this; } + + virtual QList &operator =(const QList &other); + + + // Signal emitted after an item is added to the list. + // Contains a reference to item and the item's new index. + virtual void onItemAdded(const T &item, int index) = 0; + + // Signal emitted after multiple items are added to the list at once. + // The items parameter is a const reference to a QList of the items that + // were added. + // The firstIndex parameter is the new index of the first item added. + virtual void onItemsAdded(const QList &items, int firstIndex) = 0; + + // Signal emitted after an item is removed to the list. + // Contains a reference to the item and the item's old index. + virtual void onItemRemoved(const T &item, int index) = 0; + + // Signal emitted after multiple items are removed from the list at once. + // The items parameter is a const reference to a QList of the items that + // were added. + // The firstIndex parameter is the new index of the first item added. + virtual void onItemsRemoved(const QList &items, int firstIndex) = 0; + + // Signal emitted after an item is moved to another index. + // Contains the item, the old index, and the new index. + virtual void onItemMoved(const T &item, int oldIndex, int newIndex) = 0; + + // Signal emitted after an operation that changes the whole list occurs. + // This signal should be treated as if all data in the entire list was cleared + // and new data added in its place. + virtual void onInvalidated() = 0; +}; + +// Defines the signals for a SigList +#define DEFINE_SIGLIST_SIGNALS(TYPE) \ + Q_SIGNAL void itemAdded(TYPE const &item, int index);\ + Q_SIGNAL void itemsAdded(const QList &items, int firstIndex);\ + Q_SIGNAL void itemRemoved(TYPE const &item, int index);\ + Q_SIGNAL void itemsRemoved(const QList &items, int firstIndex);\ + Q_SIGNAL void itemMoved(TYPE const &item, int oldIndex, int newIndex);\ + Q_SIGNAL void invalidated(); + +// Overrides the onItem* functions and causes them to emit their corresponding +// signals. +#define SETUP_SIGLIST_SIGNALS(TYPE) \ + virtual void onItemAdded(TYPE const &item, int index)\ + { emit itemAdded(item, index); }\ + virtual void onItemsAdded(const QList &items, int firstIndex)\ + { emit itemsAdded(items, firstIndex); }\ + virtual void onItemRemoved(TYPE const &item, int index)\ + { emit itemRemoved(item, index); }\ + virtual void onItemsRemoved(const QList &items, int firstIndex)\ + { emit itemsRemoved(items, firstIndex); }\ + virtual void onItemMoved(TYPE const &item, int oldIndex, int newIndex)\ + { emit itemMoved(item, oldIndex, newIndex); }\ + virtual void onInvalidated() { emit invalidated(); } + +#endif // SIGLIST_H diff --git a/data/siglist_imp.h b/data/siglist_imp.h new file mode 100644 index 00000000..16ddd9b0 --- /dev/null +++ b/data/siglist_imp.h @@ -0,0 +1,156 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "siglist.h" + +template +void SigList::append(const T &value) +{ + QList::append(value); + onItemAdded(value, length() - 1); +} + +template +void SigList::prepend(const T &value) +{ + QList::prepend(value); + onItemAdded(value, 0); +} + +template +void SigList::append(const QList &other) +{ + int index = length(); + QList::append(other); + onItemsAdded(other, index); +} + +template +void SigList::clear() +{ + QList::clear(); + onInvalidated(); +} + +template +void SigList::erase(QList::iterator pos) +{ + T value = *pos; + int index = indexOf(*pos); + QList::erase(pos); + onItemRemoved(value, index); +} + +template +void SigList::erase(QList::iterator first, QList::iterator last) +{ + QList removedValues; + int firstIndex = indexOf(*first); + + for (QList::iterator iter = first; iter < last; iter++) + { + removedValues << *iter; + QList::erase(iter); + } + + onItemsRemoved(removedValues, firstIndex); +} + +template +void SigList::insert(int i, const T &t) +{ + QList::insert(i, t); + onItemAdded(t, i); +} + +template +void SigList::insert(QList::iterator before, const T &t) +{ + QList::insert(before, t); + onItemAdded(t, indexOf(t)); +} + +template +void SigList::move(int from, int to) +{ + const T &item = at(from); + QList::move(from, to); + onItemMoved(item, from, to); +} + +template +int SigList::removeAll(const T &t) +{ + int retVal = QList::removeAll(t); + onInvalidated(); + return retVal; +} + +template +bool SigList::removeOne(const T &t) +{ + int index = indexOf(t); + if (QList::removeOne(t)) + { + onItemRemoved(t, index); + return true; + } + return false; +} + +template +void SigList::swap(QList &other) +{ + QList::swap(other); + onInvalidated(); +} + +template +void SigList::swap(int i, int j) +{ + const T &item1 = at(i); + const T &item2 = at(j); + QList::swap(i, j); + onItemMoved(item1, i, j); + onItemMoved(item2, j, i); +} + +template +T SigList::takeAt(int i) +{ + T val = QList::takeAt(i); + onItemRemoved(val, i); + return val; +} + +template +T SigList::takeFirst() +{ + return takeAt(0); +} + +template +T SigList::takeLast() +{ + return takeAt(length() - 1); +} + +template +QList &SigList::operator =(const QList &other) +{ + QList::operator =(other); + onInvalidated(); + return *this; +} -- cgit v1.2.3 From d00bd41c92337b0163d9ec024d821ad3138fc3dd Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 18 Feb 2013 12:59:01 -0600 Subject: Switched to BundleUtils and added OS X support. --- CMakeLists.txt | 188 ++++++++++++++++++++++++++------------------------------- MultiMC.icns | Bin 0 -> 177400 bytes 2 files changed, 84 insertions(+), 104 deletions(-) create mode 100644 MultiMC.icns diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b916f87..e1f8edc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,145 +169,125 @@ gui/logindialog.ui gui/taskdialog.ui ) -IF(WIN32) -SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS} -Ws2_32) -ENDIF() +################################ Install ################################ + +################ ICNS File ################ + +IF(APPLE) + SET(MACOSX_BUNDLE_ICON_FILE MultiMC.icns) + SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/MultiMC.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + SET(MULTIMC_SOURCES ${MULTIMC_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/MultiMC.icns) +ENDIF(APPLE) + + +################ Build ################ + +IF (WIN32) + SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS} + Qt5::WinMain + ) +ENDIF (WIN32) SET_SOURCE_FILES_PROPERTIES(resources/MultiMCLauncher.jar GENERATED) QT5_WRAP_UI(MULTIMC_UI ${MULTIMC5_UIS}) QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc) -add_executable(MultiMC ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) +add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) qt5_use_modules(MultiMC Widgets Network) target_link_libraries(MultiMC quazip patchlib ${MultiMC_LINK_ADDITIONAL_LIBS}) add_dependencies(MultiMC MultiMCLauncher) -IF (WIN32) -install(TARGETS MultiMC RUNTIME DESTINATION .) -ELSE() -install(TARGETS MultiMC RUNTIME DESTINATION bin) -ENDIF() +################ Dirs ################ - -# Extra libs and files to package. +SET(PLUGIN_DEST_DIR bin) +SET(QTCONF_DEST_DIR bin) +SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC") IF(WIN32) -SET(LIB_INSTALL_PREFIX .) -SET(LIB_INSTALL_PREFIX_ABS ${CMAKE_INSTALL_PREFIX}) -ELSE() -SET(LIB_INSTALL_PREFIX lib) -SET(LIB_INSTALL_PREFIX_ABS ${CMAKE_INSTALL_PREFIX}/lib) + #SET(PLUGIN_DEST_DIR .) + #SET(QTCONF_DEST_DIR .) + SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC.exe") +ENDIF() +IF(APPLE) + SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS) + SET(QTCONF_DEST_DIR MultiMC.app/Contents/Resources) + SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app") ENDIF() +SET(QT_PLUGINS_DIR ${Qt5_DIR}/plugins) +SET(QT_LIBRARY_DIRS ${Qt5_DIR}/lib) -# Image format plugins. -SET(IMAGE_FORMAT_PLUGINS svg ico gif jpeg) - -INCLUDE(GetPrerequisites) - -# Includes DLL dependencies for the given file. Does not include installed system DLLs. Recursive. -MACRO(INCLUDE_DLL_DEPS DLL_FILE DEST) -GET_PREREQUISITES(${DLL_FILE} DLL_PREREQS 1 1 "" "") - -MESSAGE(STATUS "Installing ${DLL_FILE} and its prerequisites.") -INSTALL(FILES ${DLL_FILE} DESTINATION ${DEST}) - -FOREACH(PREREQ ${DLL_PREREQS}) - GET_FILENAME_COMPONENT(PREREQ_NAME "${PREREQ}" NAME) - GET_FILENAME_COMPONENT(PREREQ_ACTUAL "${PREREQ}" REALPATH) - IF(WIN32) - SET(PREREQ_ACTUAL "${Qt5_DIR}/bin/${PREREQ}") - ENDIF() - - MESSAGE(STATUS "Adding install prerequisite for ${DLL_FILE}: ${PREREQ_NAME}") - - INSTALL(FILES ${PREREQ_ACTUAL} RENAME ${PREREQ_NAME} DESTINATION ${LIB_INSTALL_PREFIX}) -ENDFOREACH() -ENDMACRO() -MACRO(INSTALL_SYMLINK_DEST LINK_FILENAME DEST) -GET_FILENAME_COMPONENT(DEST_NAME "${LINK_FILENAME}" NAME) -GET_FILENAME_COMPONENT(DEST_ACTUAL "${LINK_FILENAME}" REALPATH) +################ OS X Bundle Info ################ -INSTALL(FILES "${DEST_ACTUAL}" RENAME "${DEST_NAME}" DESTINATION "${DEST}") -ENDMACRO() +IF(APPLE) + SET(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC") + SET(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.") + SET(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}") + #SET(MACOSX_BUNDLE_GUI_IDENTIFIER "") + SET(MACOSX_BUNDLE_ICON_FILE MultiMC.icns) +ENDIF(APPLE) +################ Install ################ +# Executable IF(WIN32) - -# Windows - -IF(CMAKE_BUILD_TYPE STREQUAL "Debug") -SET(D "d") +INSTALL(TARGETS MultiMC + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION bin COMPONENT Runtime +) +ENDIF() +IF(UNIX) +IF(APPLE) +INSTALL(TARGETS MultiMC + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION MultiMC.app/Contents/MacOS COMPONENT Runtime +) ELSE() -SET(D "") +INSTALL(TARGETS MultiMC + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION bin COMPONENT Runtime +) +ENDIF() ENDIF() -# Install platform plugins. -SET(PLATFORM_PLUGINS windows minimal) -FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) - INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/platforms/q${PLATFORM_PLUGIN}${D}.dll" platforms) -ENDFOREACH() +# Plugins -# Install image format plugins. -FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) - INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/q${IMGFMT_PLUGIN}${D}.dll" imageformats) -ENDFOREACH() +# Image formats +INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${PLUGIN_DEST_DIR}/plugins COMPONENT Runtime) -ELSEIF(UNIX) -IF (APPLE) +# Platform plugins +INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/platforms" DESTINATION ${PLUGIN_DEST_DIR}/plugins COMPONENT Runtime) -# OS X -# TODO: OS X packaging support +# qtconf +INSTALL(CODE " + FILE(WRITE \"\${CMAKE_INSTALL_PREFIX}/${QTCONF_DEST_DIR}/qt.conf\" \"\") + " COMPONENT Runtime) -ELSE() -# Linux - -# Install platform plugins. -SET(PLATFORM_PLUGINS linuxfb xcb minimal) -FOREACH(PLATFORM_PLUGIN ${PLATFORM_PLUGINS}) - INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/platforms/libq${PLATFORM_PLUGIN}.so" platforms) -ENDFOREACH() - -# Install image format plugins. -FOREACH(IMGFMT_PLUGIN ${IMAGE_FORMAT_PLUGINS}) - INCLUDE_DLL_DEPS("${Qt5_DIR}/plugins/imageformats/libq${IMGFMT_PLUGIN}.so" imageformats) -ENDFOREACH() - -# This just turns into a mess. It's probably better to leave installing dependencies to the user. -IF(INCLUDE_BULLSHIT_DLLS) -# This stuff *should* be added automatically by the INCLUDE_ALL_DLL_DEPS macro. Include them manually just in case. -# Install ICU libs -SET(ICU_LIBS data i18n io le lx test tu uc) -FOREACH(ICU_LIB ${ICU_LIBS}) - INSTALL_SYMLINK_DEST("/usr/lib/libicu${ICU_LIB}.so.48" ${LIB_INSTALL_PREFIX}) -ENDFOREACH() - -SET(XCB_LIBS render-util.so.0 image.so.0 icccm.so.4 sync.so.0 xfixes.so.0) -FOREACH(XCB_LIB ${XCB_LIBS}) - INSTALL_SYMLINK_DEST("/usr/lib/libxcb-${XCB_LIB}" ${LIB_INSTALL_PREFIX}) -ENDFOREACH() -ENDIF() +# Dirs to look for dependencies. +SET(DIRS ${QT_LIBRARY_DIRS}) -# Install the start script. -INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/package/linux/MultiMC" DESTINATION .) +INSTALL(CODE " + file(GLOB_RECURSE QTPLUGINS + \"\${CMAKE_INSTALL_PREFIX}/${PLUGIN_DEST_DIR}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") + include(BundleUtilities) + fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") + " COMPONENT Runtime) -ENDIF() -ENDIF() +#GET_TARGET_PROPERTY(BINARY_LOCATION MultiMC LOCATION) +#CONFIGURE_FILE( +# "${CMAKE_CURRENT_SOURCE_DIR}/dependencies.cmake.in" +# "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake" +# @ONLY +# ) +#INSTALL(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake") -GET_TARGET_PROPERTY(BINARY_LOCATION MultiMC LOCATION) -CONFIGURE_FILE( - "${CMAKE_CURRENT_SOURCE_DIR}/dependencies.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake" - @ONLY - ) -INSTALL(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake") +################ Package ################ # Package with CPack IF(UNIX) diff --git a/MultiMC.icns b/MultiMC.icns new file mode 100644 index 00000000..f96fd5a4 Binary files /dev/null and b/MultiMC.icns differ -- cgit v1.2.3 From b8844e441334db5e9bf90348aa591b63087193c4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 18 Feb 2013 13:33:22 -0600 Subject: Install plugins in the right dir. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e1f8edc4..ed930d3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,10 +256,10 @@ ENDIF() # Plugins # Image formats -INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${PLUGIN_DEST_DIR}/plugins COMPONENT Runtime) +INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime) # Platform plugins -INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/platforms" DESTINATION ${PLUGIN_DEST_DIR}/plugins COMPONENT Runtime) +INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/platforms" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime) # qtconf INSTALL(CODE " -- cgit v1.2.3