diff --git a/Makefile b/Makefile deleted file mode 100644 index 79439f3de197fe82cdaeb9138b116b5a73a2b4dd..0000000000000000000000000000000000000000 --- a/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# This makefile provides recipes to build a "portable" version of scrcpy. -# -# Here, "portable" means that the client and server binaries are expected to be -# anywhere, but in the same directory, instead of well-defined separate -# locations (e.g. /usr/bin/scrcpy and /usr/share/scrcpy/scrcpy-server.jar). -# -# In particular, this implies to change the location from where the client push -# the server to the device. -# -# "make release-portable" builds a zip containing the client and the server. -# -# On Windows with MSYS2/mingw64, execute: -# GRADLE="$PWD/gradlew" mingw32-make release-portable -# -# This is a simple Makefile because Meson is not flexible enough to execute some -# arbitrary commands. - -.PHONY: default clean build-portable release-portable dist-portable dist-portable-zip sums test check - -GRADLE ?= ./gradlew - -PORTABLE_BUILD_DIR := build-portable -DIST := dist -TARGET_DIR := scrcpy - -VERSION := $(shell git describe --tags --always) -TARGET := $(TARGET_DIR)-$(VERSION).zip - -default: - @echo 'You must specify a target. Try: make release-portable' - -clean: - $(GRADLE) clean - rm -rf "$(PORTABLE_BUILD_DIR)" "$(DIST)" - -build-portable: - [ -d "$(PORTABLE_BUILD_DIR)" ] || ( mkdir "$(PORTABLE_BUILD_DIR)" && \ - meson "$(PORTABLE_BUILD_DIR)" \ - --buildtype release --strip -Db_lto=true \ - -Doverride_server_path=scrcpy-server.jar ) - ninja -C "$(PORTABLE_BUILD_DIR)" - -release-portable: clean dist-portable-zip sums - @echo "Release created in $(DIST)/." - -dist-portable: build-portable - mkdir -p "$(DIST)/$(TARGET_DIR)" - cp "$(PORTABLE_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(TARGET_DIR)/" - cp "$(PORTABLE_BUILD_DIR)"/app/scrcpy "$(DIST)/$(TARGET_DIR)/" - -dist-portable-zip: dist-portable - cd "$(DIST)"; \ - zip -r "$(TARGET)" "$(TARGET_DIR)" - -sums: - cd "$(DIST)"; \ - sha256sum *.zip > SHA256SUM.txt - -test: build-portable - $(GRADLE) test - ninja -C "$(PORTABLE_BUILD_DIR)" test - -check: build-portable - $(GRADLE) check - ninja -C "$(PORTABLE_BUILD_DIR)" test diff --git a/Makefile.CrossWindows b/Makefile.CrossWindows new file mode 100644 index 0000000000000000000000000000000000000000..3d6bc59eb295d5c408ea804564eaaa43b4d52ee1 --- /dev/null +++ b/Makefile.CrossWindows @@ -0,0 +1,106 @@ +# This makefile provides recipes to build a "portable" version of scrcpy for +# Windows. +# +# Here, "portable" means that the client and server binaries are expected to be +# anywhere, but in the same directory, instead of well-defined separate +# locations (e.g. /usr/bin/scrcpy and /usr/share/scrcpy/scrcpy-server.jar). +# +# In particular, this implies to change the location from where the client push +# the server to the device. + +.PHONY: default clean \ + build-server \ + prepare-deps-win32 prepare-deps-win64 \ + build-win32 build-win64 \ + dist-win32 dist-win64 \ + zip-win32 zip-win64 \ + sums release + +GRADLE ?= ./gradlew + +SERVER_BUILD_DIR := build-server +WIN32_BUILD_DIR := build-win32 +WIN64_BUILD_DIR := build-win64 + +DIST := dist +WIN32_TARGET_DIR := scrcpy-win32 +WIN64_TARGET_DIR := scrcpy-win64 + +VERSION := $(shell git describe --tags --always) +WIN32_TARGET := $(WIN32_TARGET_DIR)-$(VERSION).zip +WIN64_TARGET := $(WIN64_TARGET_DIR)-$(VERSION).zip + +release: clean zip-win32 zip-win64 sums + @echo "Release created in $(DIST)/." + +clean: + $(GRADLE) clean + rm -rf "$(SERVER_BUILD_DIR)" "$(WIN32_BUILD_DIR)" "$(WIN64_BUILD_DIR)" "$(DIST)" + +build-server: + [ -d "$(SERVER_BUILD_DIR)" ] || ( mkdir "$(SERVER_BUILD_DIR)" && \ + meson "$(SERVER_BUILD_DIR)" \ + --buildtype release -Dbuild_app=false ) + ninja -C "$(SERVER_BUILD_DIR)" + +prepare-deps-win32: + -$(MAKE) -C prebuilt-deps prepare-win32 + +build-win32: prepare-deps-win32 + [ -d "$(WIN32_BUILD_DIR)" ] || ( mkdir "$(WIN32_BUILD_DIR)" && \ + meson "$(WIN32_BUILD_DIR)" \ + --cross-file cross_win32.txt \ + --buildtype release --strip -Db_lto=true \ + -Dbuild_server=false \ + -Doverride_server_path=scrcpy-server.jar ) + ninja -C "$(WIN32_BUILD_DIR)" + +prepare-deps-win64: + -$(MAKE) -C prebuilt-deps prepare-win64 + +build-win64: prepare-deps-win64 + [ -d "$(WIN64_BUILD_DIR)" ] || ( mkdir "$(WIN64_BUILD_DIR)" && \ + meson "$(WIN64_BUILD_DIR)" \ + --cross-file cross_win64.txt \ + --buildtype release --strip -Db_lto=true \ + -Dbuild_server=false \ + -Doverride_server_path=scrcpy-server.jar ) + ninja -C "$(WIN64_BUILD_DIR)" + +dist-win32: build-server build-win32 + mkdir -p "$(DIST)/$(WIN32_TARGET_DIR)" + cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN32_TARGET_DIR)/" + cp "$(WIN32_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avutil-56.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avcodec-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/avformat-58.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win32-shared/bin/swresample-3.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + cp prebuilt-deps/SDL2-2.0.8/i686-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN32_TARGET_DIR)/" + +dist-win64: build-server build-win64 + mkdir -p "$(DIST)/$(WIN64_TARGET_DIR)" + cp "$(SERVER_BUILD_DIR)"/server/scrcpy-server.jar "$(DIST)/$(WIN64_TARGET_DIR)/" + cp "$(WIN64_BUILD_DIR)"/app/scrcpy.exe "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avutil-56.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avcodec-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/avformat-58.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/ffmpeg-4.0-win64-shared/bin/swresample-3.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/adb.exe "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/AdbWinApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/platform-tools/AdbWinUsbApi.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + cp prebuilt-deps/SDL2-2.0.8/x86_64-w64-mingw32/bin/SDL2.dll "$(DIST)/$(WIN64_TARGET_DIR)/" + +zip-win32: dist-win32 + cd "$(DIST)"; \ + zip -r "$(WIN32_TARGET)" "$(WIN32_TARGET_DIR)" + +zip-win64: dist-win64 + cd "$(DIST)"; \ + zip -r "$(WIN64_TARGET)" "$(WIN64_TARGET_DIR)" + +sums: + cd "$(DIST)"; \ + sha256sum *.zip > SHA256SUM.txt diff --git a/app/meson.build b/app/meson.build index 88c26db7f19754cbc6ca406750380a29daab5e14..ab3cbd0d48bf17f134b0eb670f31a4745a72e4ac 100644 --- a/app/meson.build +++ b/app/meson.build @@ -19,12 +19,54 @@ src = [ 'src/tinyxpm.c', ] -dependencies = [ - dependency('libavformat'), - dependency('libavcodec'), - dependency('libavutil'), - dependency('sdl2'), -] +if not meson.is_cross_build() + + # native build + dependencies = [ + dependency('libavformat'), + dependency('libavcodec'), + dependency('libavutil'), + dependency('sdl2'), + ] + +else + + # cross-compile mingw32 build (from Linux to Windows) + cc = meson.get_compiler('c') + + prebuilt_sdl2 = meson.get_cross_property('prebuilt_sdl2') + sdl2_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2 + '/bin' + sdl2_lib_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_sdl2 + '/lib' + sdl2_include_dir = '../prebuilt-deps/' + prebuilt_sdl2 + '/include' + + sdl2 = declare_dependency( + dependencies: [ + cc.find_library('SDL2', dirs: sdl2_bin_dir), + cc.find_library('SDL2main', dirs: sdl2_lib_dir), + ], + include_directories: include_directories(sdl2_include_dir) + ) + + prebuilt_ffmpeg_shared = meson.get_cross_property('prebuilt_ffmpeg_shared') + prebuilt_ffmpeg_dev = meson.get_cross_property('prebuilt_ffmpeg_dev') + ffmpeg_bin_dir = meson.current_source_dir() + '/../prebuilt-deps/' + prebuilt_ffmpeg_shared + '/bin' + ffmpeg_include_dir = '../prebuilt-deps/' + prebuilt_ffmpeg_dev + '/include' + ffmpeg = declare_dependency( + dependencies: [ + cc.find_library('avcodec-58', dirs: ffmpeg_bin_dir), + cc.find_library('avformat-58', dirs: ffmpeg_bin_dir), + cc.find_library('avutil-56', dirs: ffmpeg_bin_dir), + ], + include_directories: include_directories(ffmpeg_include_dir) + ) + + dependencies = [ + ffmpeg, + sdl2, + cc.find_library('mingw32') + ] + +endif cc = meson.get_compiler('c') diff --git a/cross_win32.txt b/cross_win32.txt new file mode 100644 index 0000000000000000000000000000000000000000..8cb650aa78b4e6f9bab4bd4c4b4ba23b17d6f2ba --- /dev/null +++ b/cross_win32.txt @@ -0,0 +1,20 @@ +# apt install mingw-w64 mingw-w64-tools + +[binaries] +name = 'mingw' +c = '/usr/bin/i686-w64-mingw32-gcc' +cpp = '/usr/bin/i686-w64-mingw32-g++' +ar = '/usr/bin/i686-w64-mingw32-ar' +strip = '/usr/bin/i686-w64-mingw32-strip' +pkgconfig = '/usr/bin/i686-w64-mingw32-pkg-config' + +[host_machine] +system = 'windows' +cpu_family = 'x86' +cpu = 'i686' +endian = 'little' + +[properties] +prebuilt_ffmpeg_shared = 'ffmpeg-4.0-win32-shared' +prebuilt_ffmpeg_dev = 'ffmpeg-4.0-win32-dev' +prebuilt_sdl2 = 'SDL2-2.0.8/i686-w64-mingw32' diff --git a/cross_win64.txt b/cross_win64.txt new file mode 100644 index 0000000000000000000000000000000000000000..0110d5bb3766a3571c7fa76f0ac2b6c683655e22 --- /dev/null +++ b/cross_win64.txt @@ -0,0 +1,20 @@ +# apt install mingw-w64 mingw-w64-tools + +[binaries] +name = 'mingw' +c = '/usr/bin/x86_64-w64-mingw32-gcc' +cpp = '/usr/bin/x86_64-w64-mingw32-g++' +ar = '/usr/bin/x86_64-w64-mingw32-ar' +strip = '/usr/bin/x86_64-w64-mingw32-strip' +pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config' + +[host_machine] +system = 'windows' +cpu_family = 'x86' +cpu = 'x86_64' +endian = 'little' + +[properties] +prebuilt_ffmpeg_shared = 'ffmpeg-4.0-win64-shared' +prebuilt_ffmpeg_dev = 'ffmpeg-4.0-win64-dev' +prebuilt_sdl2 = 'SDL2-2.0.8/x86_64-w64-mingw32' diff --git a/prebuilt-deps/.gitignore b/prebuilt-deps/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..934bc04c19e9e0227621f2df87aa1791798b5c77 --- /dev/null +++ b/prebuilt-deps/.gitignore @@ -0,0 +1,4 @@ +* +!/.gitignore +!/Makefile +!/prepare-dep diff --git a/prebuilt-deps/Makefile b/prebuilt-deps/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..557cc675fa9b2e242fd6baffe34de2b2b4231f42 --- /dev/null +++ b/prebuilt-deps/Makefile @@ -0,0 +1,40 @@ +.PHONY: prepare-win32 prepare-win64 \ + prepare-ffmpeg-shared-win32 \ + prepare-ffmpeg-dev-win32 \ + prepare-ffmpeg-shared-win64 \ + prepare-ffmpeg-dev-win64 \ + prepare-sdl2 \ + prepare-adb + +prepare-win32: prepare-sdl2 prepare-ffmpeg-shared-win32 prepare-ffmpeg-dev-win32 prepare-adb +prepare-win64: prepare-sdl2 prepare-ffmpeg-shared-win64 prepare-ffmpeg-dev-win64 prepare-adb + +prepare-ffmpeg-shared-win32: + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-4.0-win32-shared.zip \ + 530c92df0ca14c35901b4b681847d62da3c50a0cc9b7ced37b04968f6b5c243d \ + ffmpeg-4.0-win32-shared + +prepare-ffmpeg-dev-win32: + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-4.0-win32-dev.zip \ + e2f5200b5e73c4d0abb9b89c4ffc0438f92a0aadc54c81cf57e18c81a9f11c6b \ + ffmpeg-4.0-win32-dev + +prepare-ffmpeg-shared-win64: + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/shared/ffmpeg-4.0-win64-shared.zip \ + 8fe2d344463dbefc2db4239a4203a55ed0324faceaae57276a40c4fabda84c37 \ + ffmpeg-4.0-win64-shared + +prepare-ffmpeg-dev-win64: + @./prepare-dep https://ffmpeg.zeranoe.com/builds/win64/dev/ffmpeg-4.0-win64-dev.zip \ + facced738eabfc53fa92834dea8b24426f64db61298688fed480145945be07fa \ + ffmpeg-4.0-win64-dev + +prepare-sdl2: + @./prepare-dep https://libsdl.org/release/SDL2-devel-2.0.8-mingw.tar.gz \ + ffff7305d634aff5e1df5b7bb935435c3a02c8b03ad94a1a2be9169a558a7961 \ + SDL2-2.0.8 + +prepare-adb: + @./prepare-dep https://dl.google.com/android/repository/platform-tools_r27.0.1-windows.zip \ + 880662adfb0d6911ff250b9e13930ae1a4110fc36d5866afd4f8f56d935f7939 \ + platform-tools diff --git a/prebuilt-deps/prepare-dep b/prebuilt-deps/prepare-dep new file mode 100755 index 0000000000000000000000000000000000000000..7da3781163b89b5b9582efad8686a9acff853aa1 --- /dev/null +++ b/prebuilt-deps/prepare-dep @@ -0,0 +1,58 @@ +#!/bin/bash +set -e +url="$1" +sum="$2" +dir="$3" + +checksum() { + local file="$1" + local sum="$2" + echo "$file: verifying checksum..." + echo "$sum $file" | sha256sum -c +} + +get_file() { + local url="$1" + local file="$2" + local sum="$3" + if [[ -f "$file" ]] + then + echo "$file: found" + else + echo "$file: not found, downloading..." + wget "$url" -O "$file" + fi + checksum "$file" "$sum" +} + +extract() { + local file="$1" + echo "Extracting $file..." + if [[ "$file" == *.zip ]] + then + unzip -q "$file" + elif [[ "$file" == *.tar.gz ]] + then + tar xf "$file" + else + echo "Unsupported file: $file" + return 1 + fi +} + +get_dep() { + local url="$1" + local sum="$2" + local dir="$3" + local file="${url##*/}" + if [[ -d "$dir" ]] + then + echo "$dir: found" + else + echo "$dir: not found" + get_file "$url" "$file" "$sum" + extract "$file" + fi +} + +get_dep "$1" "$2" "$3"