diff --git a/.drone.yml b/.drone.yml index b8f8c67b2..6babff051 100644 --- a/.drone.yml +++ b/.drone.yml @@ -6,7 +6,7 @@ build: - if [ $$arch = 32 ]; then target=i686; fi - if [ $$arch = 64 ]; then target=x86_64; fi - echo -e "[librepilot-mingw]\nSigLevel = Optional TrustAll\nServer = http://download.librepilot.org/repo/mingw" >> /etc/pacman.conf - - pacman -Syu --noconfirm --noprogressbar --needed git unzip tar mingw-w64-${target}-toolchain mingw-w64-${target}-ccache mingw-w64-${target}-qt5 mingw-w64-${target}-SDL mingw-w64-${target}-mesa mingw-w64-${target}-openssl mingw-w64-${target}-gdal-minimal mingw-w64-${target}-OpenSceneGraph mingw-w64-${target}-osgearth + - pacman -Syu --noconfirm --noprogressbar --needed git unzip tar mingw-w64-${target}-toolchain mingw-w64-${target}-ccache mingw-w64-${target}-ntldd mingw-w64-${target}-qt5 mingw-w64-${target}-SDL mingw-w64-${target}-mesa mingw-w64-${target}-openssl mingw-w64-${target}-gdal-minimal mingw-w64-${target}-OpenSceneGraph mingw-w64-${target}-osgearth - mingw32-make all_sdk_install - git config core.filemode false - mingw32-make build-info && cat build/build-info.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f3f11e01..b4fbef76f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ Add the following lines at the end of your /etc/pacman.conf file: Start a MinGW-w64 Win64 Shell or a MinGW-w64 Win32 Shell. pacman -Sy - pacman -S --needed git unzip tar mingw-w64-i686-toolchain mingw-w64-i686-ccache mingw-w64-i686-qt5 mingw-w64-i686-SDL mingw-w64-i686-mesa mingw-w64-i686-openssl mingw-w64-i686-gdal-minimal mingw-w64-i686-OpenSceneGraph mingw-w64-i686-osgearth + pacman -S --needed git unzip tar mingw-w64-i686-toolchain mingw-w64-i686-ccache mingw-w64-i686-ntldd mingw-w64-i686-qt5 mingw-w64-i686-SDL mingw-w64-i686-mesa mingw-w64-i686-openssl mingw-w64-i686-gdal-minimal mingw-w64-i686-OpenSceneGraph mingw-w64-i686-osgearth Optionally install debug packages: @@ -52,7 +52,7 @@ Optionally install debug packages: Start a MinGW-w64 Win64 Shell. pacman -Sy - pacman -S --needed git unzip tar mingw-w64-x86_64-toolchain mingw-w64-x86_64-ccache mingw-w64-x86_64-qt5 mingw-w64-x86_64-SDL mingw-w64-x86_64-mesa mingw-w64-x86_64-openssl mingw-w64-x86_64-gdal-minimal mingw-w64-x86_64-OpenSceneGraph mingw-w64-x86_64-osgearth + pacman -S --needed git unzip tar mingw-w64-x86_64-toolchain mingw-w64-x86_64-ccache mingw-w64-x86_64-ntldd mingw-w64-x86_64-qt5 mingw-w64-x86_64-SDL mingw-w64-x86_64-mesa mingw-w64-x86_64-openssl mingw-w64-x86_64-gdal-minimal mingw-w64-x86_64-OpenSceneGraph mingw-w64-x86_64-osgearth Optionally install debug packages: diff --git a/ground/gcs/copydata.pro b/ground/gcs/copydata.pro index e2fc81a67..c0133a7d8 100644 --- a/ground/gcs/copydata.pro +++ b/ground/gcs/copydata.pro @@ -87,35 +87,11 @@ win32 { Qt5MultimediaWidgets$${DS}.dll \ Qt5Quick$${DS}.dll \ Qt5QuickWidgets$${DS}.dll \ - Qt5Qml$${DS}.dll \ - libicuin57.dll \ - libicudt57.dll \ - libicuuc57.dll \ - libstdc++-6.dll \ - libwinpthread-1.dll \ - libpcre-1.dll \ - libpcre16-0.dll \ - zlib1.dll \ - libharfbuzz-0.dll \ - libgraphite2.dll \ - libfreetype-6.dll \ - libbz2-1.dll \ - libpng16-16.dll \ - libjpeg-8.dll \ - libglib-2.0-0.dll \ - libintl-8.dll \ - libiconv-2.dll - - contains(QT_ARCH, i386) { - QT_DLLS += \ - libgcc_s_dw2-1.dll - } else { - QT_DLLS += \ - libgcc_s_seh-1.dll - } + Qt5Qml$${DS}.dll for(dll, QT_DLLS) { addCopyFileTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) + win32:addCopyDependenciesTarget($${dll},$$[QT_INSTALL_BINS],$${GCS_APP_PATH}) } # copy OpenSSL DLLs @@ -141,6 +117,7 @@ win32 { for(plugin, QT_PLUGINS) { addCopyFileTarget($${plugin},$$[QT_INSTALL_PLUGINS],$${GCS_QT_PLUGINS_PATH}) + win32:addCopyDependenciesTarget($${plugin},$$[QT_INSTALL_PLUGINS],$${GCS_APP_PATH}) } # Copy QtQuick2 complete directories diff --git a/ground/gcs/gcs.pri b/ground/gcs/gcs.pri index cb25cd54f..f36f6290e 100644 --- a/ground/gcs/gcs.pri +++ b/ground/gcs/gcs.pri @@ -33,19 +33,46 @@ defineTest(addCopyFileTarget) { src = $$2/$$1 dest = $$3/$$1 - $${file}.target = $$dest - $${file}.depends = $$src + target = $${file} + $${target}.target = $$dest + $${target}.depends = $$src # create directory. Better would be an order only dependency - $${file}.commands = -@$(MKDIR) \"$$dirname(dest)\" $$addNewline() - $${file}.commands += $(COPY_FILE) \"$$src\" \"$$dest\" + $${target}.commands = -@$(MKDIR) \"$$dirname(dest)\" $$addNewline() + $${target}.commands += $(COPY_FILE) \"$$src\" \"$$dest\" - QMAKE_EXTRA_TARGETS += $$file - POST_TARGETDEPS += $$eval($${file}.target) + QMAKE_EXTRA_TARGETS += $$target + POST_TARGETDEPS += $$eval($${target}.target) - export($${file}.target) - export($${file}.depends) - export($${file}.commands) + export($${target}.target) + export($${target}.depends) + export($${target}.commands) + export(QMAKE_EXTRA_TARGETS) + export(POST_TARGETDEPS) + + return(true) +} + +defineTest(addCopyDependenciesTarget) { + file = $$1 + src = $$2/$$1 + dest = $$3 + + target_file = $${OUT_PWD}/deps/$${file}.deps + + target = $${file}_deps + $${target}.target = $$target_file + $${target}.depends = $$src + + $${target}.commands = -@$(MKDIR) \"$$dirname(target_file)\" $$addNewline() + $${target}.commands += $$(PYTHON) $$(ROOT_DIR)/make/copy_dependencies.py --dest \"$$dest\" --files \"$$src\" --excludes OPENGL32.DLL > \"$$target_file\" + + QMAKE_EXTRA_TARGETS += $$target + POST_TARGETDEPS += $$eval($${target}.target) + + export($${target}.target) + export($${target}.depends) + export($${target}.commands) export(QMAKE_EXTRA_TARGETS) export(POST_TARGETDEPS) @@ -57,22 +84,23 @@ defineTest(addCopyDirTarget) { src = $$2/$$1 dest = $$3/$$1 - $${dir}.target = $$dest - $${dir}.depends = $$src + target = $${dir} + $${target}.target = $$dest + $${target}.depends = $$src # Windows does not update directory timestamp if files are modified - win32: $${dir}.depends += FORCE + win32:$${target}depends += FORCE - $${dir}.commands = @rm -rf \"$$dest\" $$addNewline() + $${target}.commands = @rm -rf \"$$dest\" $$addNewline() # create directory. Better would be an order only dependency - $${dir}.commands += -@$(MKDIR) \"$$dirname(dest)\" $$addNewline() - $${dir}.commands += $(COPY_DIR) \"$$src\" \"$$dest\" + $${target}.commands += -@$(MKDIR) \"$$dirname(dest)\" $$addNewline() + $${target}.commands += $(COPY_DIR) \"$$src\" \"$$dest\" - QMAKE_EXTRA_TARGETS += $$dir - POST_TARGETDEPS += $$eval($${dir}.target) + QMAKE_EXTRA_TARGETS += $$target + POST_TARGETDEPS += $$eval($${target}.target) - export($${dir}.target) - export($${dir}.depends) - export($${dir}.commands) + export($${target}.target) + export($${target}.depends) + export($${target}.commands) export(QMAKE_EXTRA_TARGETS) export(POST_TARGETDEPS) diff --git a/ground/gcs/src/libs/osgearth/copydata.pro b/ground/gcs/src/libs/osgearth/copydata.pro index b4d89a487..89e018726 100644 --- a/ground/gcs/src/libs/osgearth/copydata.pro +++ b/ground/gcs/src/libs/osgearth/copydata.pro @@ -44,39 +44,7 @@ linux|macx { } osg:win32 { - # osg & osgearth dependencies - - # curl - OSG_LIBS = \ - libcurl-4.dll \ - libidn-11.dll \ - librtmp-1.dll \ - libgmp-10.dll \ - libgnutls-30.dll \ - libunistring-2.dll \ - libp11-kit-0.dll \ - libffi-6.dll \ - libtasn1-6.dll \ - libssh2-1.dll \ - libnghttp2-14.dll - - equals(OSG_VERSION, "3.5.1") { - OSG_LIBS += \ - libhogweed-4-2.dll \ - libnettle-6-2.dll - } else { - OSG_LIBS += \ - libhogweed-4.dll \ - libnettle-6.dll - } - - # other - OSG_LIBS += \ - libjpeg-8.dll \ - libfreetype-6.dll \ - libpng16-16.dll \ - libiconv-2.dll \ - zlib1.dll + # osg and osgearth dependencies # osg libraries OSG_LIBS += \ @@ -103,6 +71,7 @@ osg:win32 { for(lib, OSG_LIBS) { addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin,$${GCS_APP_PATH}) + win32:addCopyDependenciesTarget($${lib},$${OSG_SDK_DIR}/bin,$${GCS_APP_PATH}) } # osg plugins @@ -183,6 +152,7 @@ osg:win32 { for(lib, OSG_PLUGINS) { addCopyFileTarget($${lib},$${OSG_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_LIBRARY_PATH}/osg/osgPlugins-$${OSG_VERSION}) + win32:addCopyDependenciesTarget($${lib},$${OSG_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_APP_PATH}) } } @@ -193,23 +163,18 @@ osgearth:win32 { libosgEarthAnnotation$${DS}.dll \ libosgEarthFeatures$${DS}.dll \ libosgEarthSymbology$${DS}.dll \ - libosgEarthUtil$${DS}.dll \ - libprotobuf.dll + libosgEarthUtil$${DS}.dll - # gdal + # loaded dynamically (probably by an osg plugin, need to find by which) OSGEARTH_LIBS += \ - libgdal-20.dll \ - libgeos_c.dll \ - libgeos.dll \ - libopenjp2-7.dll \ - libtiff-5.dll \ - liblzma-5.dll + libopenjp2-7.dll osgearthQt:OSGEARTH_LIBS += \ libosgEarthQt$${DS}.dll for(lib, OSGEARTH_LIBS) { addCopyFileTarget($${lib},$${OSGEARTH_SDK_DIR}/bin,$${GCS_APP_PATH}) + win32:addCopyDependenciesTarget($${lib},$${OSGEARTH_SDK_DIR}/bin,$${GCS_APP_PATH}) } # osgearth plugins @@ -261,5 +226,6 @@ osgearth:win32 { for(lib, OSGEARTH_PLUGINS) { addCopyFileTarget($${lib},$${OSGEARTH_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_LIBRARY_PATH}/osg/osgPlugins-$${OSG_VERSION}) + win32:addCopyDependenciesTarget($${lib},$${OSGEARTH_SDK_DIR}/bin/osgPlugins-$${OSG_VERSION},$${GCS_APP_PATH}) } } diff --git a/make/copy_dependencies.py b/make/copy_dependencies.py new file mode 100644 index 000000000..413c16ab0 --- /dev/null +++ b/make/copy_dependencies.py @@ -0,0 +1,92 @@ +#!/usr/bin/python2 + + ############################################################################### + # + # The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017. + # Script to find and copy dependencies (msys2 only). + # ./copy_dependencies.py -h for usage. + # + ############################################################################### + +import argparse +import glob +import os +import re +import shutil +import subprocess +import sys + +def cygpath(file): + return subprocess.check_output(["cygpath", "-m", file]).strip() + +# ldd does not work well on Windows 10 and is not supported on mingw32 +# ntldd seems to be more reliable but is not recursive (so recursion needs to be done here) +def ldd(file): + ldd_output = subprocess.check_output(["ntldd", file]) + # sanitize output + ldd_output = ldd_output.strip() + ldd_output = ldd_output.replace('\\', '/') + # split output into lines + ldd_lines = ldd_output.split('\n') + # parse lines that match this format : ==> () + file_pattern = ".*/mingw../bin/.*" + pattern = "(.*) => (" + file_pattern + ") \((.*)\)"; + regex = re.compile(pattern) + dependencies = {m.group(2).strip() for m in [regex.match(line) for line in ldd_lines] if m} + return dependencies + +def find_dependencies(file, visited): + print "Analyzing " + file + visited.add(file) + dependencies = ldd(file) + # recurse + for f in dependencies.copy(): + if f in visited: + continue + if args.excludes and os.path.basename(f) in args.excludes: + print "Ignoring " + f + dependencies.remove(f) + continue + dependencies = dependencies | find_dependencies(f, visited) + return dependencies + +parser = argparse.ArgumentParser(description='Find and copy dependencies to a destination directory.') +parser.add_argument('-n', '--no-copy', action='store_true', help='don\'t copy dependencies to destination dir') +parser.add_argument('-v', '--verbose', action='store_true', help='enable verbose mode') +parser.add_argument('-d', '--dest', type=str, default='.', help='destination directory (defaults to current directory)') +parser.add_argument('-s', '--source', type=str, default='.', help='source directory (defaults to current directory)') +parser.add_argument('-f', '--files', metavar='FILE', nargs='+', required=True, help='a file') +parser.add_argument('-e', '--excludes', metavar='FILE', nargs='+', help='a file') + +args = parser.parse_args() + +# check that args.dest exists and is a directory +if not os.path.isdir(args.dest): + print "Error: destination " + str(args.dest) + " is not a directory." + exit(1) + +# find dependencies +dependencies = set() +visited = set() +for file in args.files: + file = os.path.join(args.source, file) + files = glob.glob(file) + for f in files: + dependencies = dependencies | find_dependencies(f, visited) +print "Found " + str(len(dependencies)) + " dependencies." + +# no copy, exit now +if args.no_copy: + exit(0) + +# copy dependencies to destination dir +copy_count = 0 +for file in dependencies: + dest_file = args.dest + "/" + os.path.basename(file) + if not os.path.isfile(dest_file): + print "Copying " + file + " to " + args.dest + shutil.copy2(file, args.dest) + copy_count += 1 +print "Copied " + str(copy_count) + " dependencies to '" + str(args.dest) + "'." + +exit(0)