Skip to content

Commit

Permalink
Merge pull request #6 from mxlgv/master-windows-changes
Browse files Browse the repository at this point in the history
Added Windows support (build via MSYS2 (env MINGW64)
  • Loading branch information
mxlgv authored Mar 18, 2024
2 parents bf9f401 + 75092ca commit c452ac9
Show file tree
Hide file tree
Showing 73 changed files with 2,969 additions and 10 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build-win64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Build for Windows
on: [pull_request, push]

jobs:
build:
runs-on: windows-latest
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: git
- run: git config --global core.autocrlf input
- uses: actions/checkout@v4
- name: Build Dino
run: |
msys2 -c './build-win64.sh --prepare'
msys2 -c './build-win64.sh'
- name: Build Dino Installer
run: |
msys2 -c './build-win64.sh --build-installer'
- name: Upload Dino Installer
uses: actions/upload-artifact@v4
with:
name: dino-installer
path: windows-installer/dino-installer.exe
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ Makefile
.idea
.sqlite3
gschemas.compiled
windows-installer/win64-dist/
*.exe
*.dll
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ endif ()

# Prepare Plugins
set(DEFAULT_PLUGINS omemo;openpgp;http-files;ice;rtp)
if (WIN32)
set(DEFAULT_PLUGINS ${DEFAULT_PLUGINS};win32-fonts;windows-notification)
endif (WIN32)
foreach (plugin ${DEFAULT_PLUGINS})
if ("$CACHE{DINO_PLUGIN_ENABLED_${plugin}}" STREQUAL "")
if (NOT DEFINED DINO_PLUGIN_ENABLED_${plugin}})
Expand Down Expand Up @@ -176,6 +179,11 @@ if (NOT NO_DEBUG)
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} -g")
endif (NOT NO_DEBUG)

if (WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=1")
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} --define=_WIN32")
endif(WIN32)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

Expand Down
56 changes: 56 additions & 0 deletions README-WIN64.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
![Dino (WIN64)](https://dino.im/img/readme_header.svg)
=======

![screenshots](https://dino.im/img/screenshot-main.png)

Build on Windows (x86_64)
------------
- Install and configure the [MSYS2](https://www.msys2.org/) package;
- Go to `MINGW64` environment;
- Clone project:
```sh
git clone https://github.com/mxlgv/dino && cd dino
```
- Run the script to install dependencies:
```sh
./build-win64.sh --prepare
```
- Start the build (the builded distribution is available in the `windows-installer/dist-win64` folder):
```sh
./build-win64.sh
```
Note: the build script has some other options, their description can be found using the `--help`.

Build Windows Installer (NSIS)
------------
Before this, you must build the project according to the instructions above. It's worth making sure that `windows-installer/dist-win64` is not empty.
Now you should run:
```sh
./build-win64.sh --build-installer
```
The builded installer will be available in the directory `windows-installer/dino-installer.exe`.
Resources
---------
- Check out the [Dino website](https://dino.im).
- Join our XMPP channel at `chat@dino.im`.
- The [wiki](https://github.com/dino/dino/wiki) provides additional information.
License
-------
Dino - Modern Jabber/XMPP Client using GTK+/Vala
Copyright (C) 2016-2023 Dino contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
182 changes: 182 additions & 0 deletions build-win64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/bin/bash
set -e

DIST_DIR="$PWD/windows-installer/win64-dist"
JOBS=$NUMBER_OF_PROCESSORS

msg()
{
echo -e "\e[32m$1\e[0m"
}

fatal()
{
echo -e "\e[31m$1\e[0m"
exit 1
}

download_yolort()
{
file_name=cppwinrt-2.0.210122.3+windows-10.0.19041+yolort-835cd4e.zip
yolort_dir="$PWD/plugins/windows-notification/yolort"

rm -rf "$yolort_dir"
mkdir "$yolort_dir"
curl -L -o "$file_name" "https://github.com/LAGonauta/YoloRT/releases/download/v1.0.0/$file_name"
echo "675a6d943c97b4acdbfaa473f68d3241d1798b31a67b5529c8d29fc0176a1707 $file_name" | sha256sum --check --status
unzip -o "$file_name" -d "$yolort_dir"
rm -f "$file_name"
}

prepare()
{
msg "Installing MINGW64 build dependencies"

pacman -S --needed --noconfirm \
mingw64/mingw-w64-x86_64-gcc \
mingw64/mingw-w64-x86_64-cmake \
mingw64/mingw-w64-x86_64-ninja \
mingw64/mingw-w64-x86_64-gtk4 \
mingw64/mingw-w64-x86_64-libadwaita \
mingw64/mingw-w64-x86_64-sqlite3 \
mingw64/mingw-w64-x86_64-openssl \
mingw64/mingw-w64-x86_64-libgcrypt \
mingw64/mingw-w64-x86_64-libgee \
mingw64/mingw-w64-x86_64-vala \
mingw64/mingw-w64-x86_64-gsettings-desktop-schemas \
mingw64/mingw-w64-x86_64-qrencode \
mingw64/mingw-w64-x86_64-ntldd-git \
mingw64/mingw-w64-x86_64-gpgme \
mingw64/mingw-w64-x86_64-fontconfig \
mingw64/mingw-w64-x86_64-iso-codes \
mingw64/mingw-w64-x86_64-gstreamer \
mingw64/mingw-w64-x86_64-gst-plugins-bad \
mingw64/mingw-w64-x86_64-gst-plugins-good \
mingw64/mingw-w64-x86_64-gst-plugins-base \
mingw64/mingw-w64-x86_64-gst-plugins-ugly \
mingw64/mingw-w64-x86_64-nsis \
mingw64/mingw-w64-x86_64-libsignal-protocol-c \
mingw64/mingw-w64-x86_64-icu \
mingw64/mingw-w64-x86_64-webrtc-audio-processing \
git \
make \
unzip \
curl

msg "Successfully installed!"

msg "Download YoloRT headers"
download_yolort
msg "Successfully downloaded!"

}

configure()
{
msg "Running configuration for Windows"
./configure --program-prefix="$DIST_DIR" --no-debug --release --disable-fast-vapi --with-libsoup3
msg "Configured!"
}

build()
{
msg "Started building on $JOBS threads"
make -j"$JOBS"
msg "Successfully builded!"
}

dist_install()
{
msg "Installing Dino in '$DIST_DIR'!"
make install

msg "Copying MINGW64 dependencies"
cp /mingw64/bin/gdbus.exe "$DIST_DIR/bin"
cp /mingw64/bin/gspawn-win64-helper.exe "$DIST_DIR/bin"

cp /mingw64/bin/libcrypto-*-x64.dll "$DIST_DIR/bin/"
cp -r /mingw64/lib/gstreamer-1.0 "$DIST_DIR/lib"
mkdir -p "$DIST_DIR/lib/gdk-pixbuf-2.0/" && cp -r /mingw64/lib/gdk-pixbuf-2.0 "$DIST_DIR/lib/"
mkdir -p "$DIST_DIR/lib/gio/" && cp -r /mingw64/lib/gio "$DIST_DIR/lib/"

list=`find "$DIST_DIR" -type f \( -name "*.exe" -o -name "*.dll" \) -exec \
ntldd -R {} + | \
grep "mingw64" | \
cut -f1 -d "=" | sort | uniq`
for a in $list; do
cp -fv "/mingw64/bin/$a" "$DIST_DIR/bin/"
done

msg "Removing debug information from all EXE and DLL files"
find "$DIST_DIR" -iname "*.exe" -exec strip -s {} +
find "$DIST_DIR" -iname "*.dll" -exec strip -s {} +

find "$DIST_DIR" -iname "*.a" -exec rm {} +

msg "Removing redudant header files"
rm -rf "$DIST_DIR/include"

msg "Copy LICENSE"
cp -f "$PWD/LICENSE" "$DIST_DIR/LICENSE"

msg "Copy icons, themes, locales and fonts"
cp -f "$PWD/main/dino.ico" "$DIST_DIR/dino.ico"
cp -rf "/mingw64/share/xml" "$DIST_DIR/share"
mkdir -p "$DIST_DIR/etc/fonts" && cp -r /mingw64/etc/fonts "$DIST_DIR/etc/"
mkdir -p "$DIST_DIR/share/icons" && cp -r /mingw64/share/icons "$DIST_DIR/share/"
mkdir -p "$DIST_DIR/share/glib-2.0/schemas" && cp -rf /mingw64/share/glib-2.0/schemas "$DIST_DIR/share/glib-2.0/"

msg "Successfully installed!"
}

build_installer()
{
msg "Building an installer for Windows using NSIS"
cd windows-installer
makensis dino.nsi
msg "Installer successfully builded!"
cd ..
}

clean()
{
rm -rf build "$DIST_DIR"
msg "Build artifacts removed successfull!"
}

help()
{
cat << EOF
usage: $0 [OPTION]
--prepare install build dependencies
--configure configure the project
--build build the project
--dist-install install the builded project
--build-installer build installer (using NSIS)
--clean remove build artifacts
--help show this help
Running without parameters is equivalent to running:
'--configure', '--build' and '--dist-install'
EOF
}

if [[ "$(uname)" != "MINGW64_NT"* ]]; then
fatal "This is not a MINGW64 environment!"
fi

case $1 in
"--prepare" ) prepare ;;
"--configure" ) configure ;;
"--build" ) build ;;
"--dist-install" ) dist_install ;;
"--build-installer") build_installer ;;
"--clean" ) clean ;;
"--help" ) help ;;
"" )
configure
build
dist_install
;;
*) fatal "Unknown argument!"
esac
7 changes: 6 additions & 1 deletion cmake/PkgConfigWithFallback.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback name)
# Found via pkg-config, using its result values
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})

if(MINGW)
set(MINGWLIBPATH ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
endif(MINGW)

# Try to find real file name of libraries
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS})
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS} ${MINGWLIBPATH})
mark_as_advanced(${name}_${lib}_LIBRARY)
if(NOT ${name}_${lib}_LIBRARY)
message(${name} ": " ${lib} " library not found")
unset(${name}_FOUND)
endif(NOT ${name}_${lib}_LIBRARY)
endforeach(lib)
Expand Down
7 changes: 6 additions & 1 deletion cmake/PkgConfigWithFallbackOnConfigScript.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback_on_config_script name)
# Found via pkg-config, using it's result values
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})

if(MINGW)
set(MINGWLIBPATH ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
endif(MINGW)

# Try to find real file name of libraries
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS})
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS} ${MINGWLIBPATH})
mark_as_advanced(${name}_${lib}_LIBRARY)
if(NOT ${name}_${lib}_LIBRARY)
message(${name} ": " ${lib} " library not found")
unset(${name}_FOUND)
endif(NOT ${name}_${lib}_LIBRARY)
endforeach(lib)
Expand Down
18 changes: 18 additions & 0 deletions libdino/src/service/avatar_manager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,24 @@ public class AvatarManager : StreamInteractionModule, Object {
return null;
}
}

public string? get_avatar_filepath(Account account, Jid jid_) {
Jid jid = jid_;
if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid_, account)) {
jid = jid_.bare_jid;
}

string? hash = null;
if (user_avatars.has_key(jid)) {
hash = user_avatars[jid];
} else if (vcard_avatars.has_key(jid)) {
hash = vcard_avatars[jid];
}

if (hash == null) return null;

return Path.build_filename(folder, hash);
}
}

}
11 changes: 9 additions & 2 deletions libdino/src/service/file_manager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class FileManager : StreamInteractionModule, Object {
try {
FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
file_transfer.file_name = file_info.get_display_name();
file_transfer.mime_type = file_info.get_content_type();
file_transfer.mime_type = Util.get_content_type(file_info);
file_transfer.size = (int)file_info.get_size();
file_transfer.input_stream = yield file.read_async();

Expand Down Expand Up @@ -259,9 +259,16 @@ public class FileManager : StreamInteractionModule, Object {
file_transfer.input_stream = yield file.read_async();

FileInfo file_info = file_transfer.get_file().query_info("*", FileQueryInfoFlags.NONE);
file_transfer.mime_type = file_info.get_content_type();
file_transfer.mime_type = Util.get_content_type(file_info);

file_transfer.state = FileTransfer.State.COMPLETE;

#if _WIN32 // Add Zone.Identifier so Windows knows this file was downloaded from the internet
var file_alternate_stream = File.new_for_path(Path.build_filename(get_storage_dir(), filename + ":Zone.Identifier"));
var os_alternate_stream = file_alternate_stream.create(FileCreateFlags.REPLACE_DESTINATION);
os_alternate_stream.write("[ZoneTransfer]\r\nZoneId=3".data);
#endif

} catch (Error e) {
warning("Error downloading file: %s", e.message);
file_transfer.state = FileTransfer.State.FAILED;
Expand Down
Loading

0 comments on commit c452ac9

Please sign in to comment.