Compile FreeFileSync 10.1 on Fedora

How to compile FreeFileSync 10.1 on Fedora

Tested on Fedora 28

1. Install build dependencies.

dnf install -y boost-devel compat-wxGTK3-gtk2-devel gcc-c++ gtk+-devel gtk3-devel wxGTK-devel wxGTK3-devel

2. Fetch and extract source

wget --user-agent 'Firefox 60.0 (GNU/Linux) X11' -L
mkdir 10.1
pushd 10.1; unzip ../; popd

3. Prepare patch required to compile on Fedora.

cat <<'EOF' > "${pfile}"
diff -x '*.orig' -x '*.rej' -Naur 10.1/FreeFileSync/Source/Makefile 10.1-0/FreeFileSync/Source/Makefile
--- 10.1/FreeFileSync/Source/Makefile	2018-06-03 04:27:00.000000000 -0400
+++ 10.1-0/FreeFileSync/Source/Makefile	2018-06-07 22:44:44.919899060 -0400
@@ -5,15 +5,15 @@
-CXXFLAGS  = -std=c++17 -pipe -DWXINTL_NO_GETTEXT_MACRO -I../.. -I../../zenXml -isystem../../boost -include "zen/i18n.h" -include "zen/warn_static.h" \
+CXXFLAGS  = -std=c++17 -pipe -DWXINTL_NO_GETTEXT_MACRO -I../.. -I../../zenXml -isystem/usr/include/boost -include "zen/i18n.h" -include "zen/warn_static.h" \
 -Wall -Wfatal-errors -Wmissing-include-dirs -Wswitch-enum -Wcast-align -Wshadow -Wnon-virtual-dtor \
 -O3 -DNDEBUG `wx-config --cxxflags --debug=no` -pthread
-LINKFLAGS = -s -no-pie `wx-config --libs std, aui --debug=no` -pthread
+LINKFLAGS = -s -no-pie `wx-config --libs std, aui --debug=no` -lz -pthread
 #Gtk - support recycler/icon loading/no button border/grid scrolling
-CXXFLAGS  += `pkg-config --cflags gtk+-2.0`
-LINKFLAGS += `pkg-config --libs   gtk+-2.0`
+CXXFLAGS  += `pkg-config --cflags gtk+-3.0`
+LINKFLAGS += `pkg-config --libs   gtk+-3.0`
 #support for SELinux (optional)
 SELINUX_EXISTING=$(shell pkg-config --exists libselinux && echo YES)
@@ -125,5 +125,5 @@
 	mkdir -p $(DOCSHAREDIR)
-	cp ../Build/Changelog.txt $(DOCSHAREDIR)/changelog
+	cp ../../Changelog.txt $(DOCSHAREDIR)/changelog
 	gzip $(DOCSHAREDIR)/changelog
diff -x '*.orig' -x '*.rej' -Naur 10.1/FreeFileSync/Source/RealTimeSync/Makefile 10.1-0/FreeFileSync/Source/RealTimeSync/Makefile
--- 10.1/FreeFileSync/Source/RealTimeSync/Makefile	2018-06-03 04:27:00.000000000 -0400
+++ 10.1-0/FreeFileSync/Source/RealTimeSync/Makefile	2018-06-07 22:20:59.043383931 -0400
@@ -6,11 +6,11 @@
 -Wall -Wfatal-errors -Wmissing-include-dirs -Wswitch-enum -Wcast-align -Wshadow -Wnon-virtual-dtor \
 -O3 -DNDEBUG `wx-config --cxxflags --debug=no` -pthread
-LINKFLAGS = -s -no-pie `wx-config --libs std, aui --debug=no` -pthread
+LINKFLAGS = -s -no-pie `wx-config --libs std, aui --debug=no` -lz -pthread
 #Gtk - support "no button border"
-CXXFLAGS  += `pkg-config --cflags gtk+-2.0`
-LINKFLAGS += `pkg-config --libs   gtk+-2.0`
+CXXFLAGS  += `pkg-config --cflags gtk+-3.0`
+LINKFLAGS += `pkg-config --libs   gtk+-3.0`
diff -x '*.orig' -x '*.rej' -Naur 10.1/FreeFileSync/Source/ui/main_dlg.cpp 10.1-0/FreeFileSync/Source/ui/main_dlg.cpp
--- 10.1/FreeFileSync/Source/ui/main_dlg.cpp	2018-06-03 04:27:02.000000000 -0400
+++ 10.1-0/FreeFileSync/Source/ui/main_dlg.cpp	2018-06-07 22:25:32.856972097 -0400
@@ -11,6 +11,7 @@
 #include <zen/thread.h>
 #include <zen/shell_execute.h>
 #include <zen/perf.h>
+/* #include <zen/warn_static.h>  REMOVED FOR TESTING. Add back on any failures. */
 #include <wx/clipbrd.h>
 #include <wx/wupdlock.h>
 #include <wx/sound.h>
@@ -4844,7 +4845,7 @@
         globalCfg_.gui.lastUpdateCheck = 0; //reset to GlobalSettings.xml default value!
+    /*
     if (shouldRunAutomaticUpdateCheck(globalCfg_.gui.lastUpdateCheck))
         flashStatusInformation(_("Searching for program updates..."));
@@ -4852,6 +4853,7 @@
         automaticUpdateCheckEval(this, globalCfg_.gui.lastUpdateCheck, globalCfg_.gui.lastOnlineVersion,
+    */
@@ -4859,7 +4861,7 @@
     //execute just once per startup!
     Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainDialog::OnRegularUpdateCheck), nullptr, this);
+    /*
     if (shouldRunAutomaticUpdateCheck(globalCfg_.gui.lastUpdateCheck))
         flashStatusInformation(_("Searching for program updates..."));
@@ -4873,6 +4875,7 @@
                                      resultAsync.get()); //run on main thread:
+    */
diff -x '*.orig' -x '*.rej' -Naur 10.1/FreeFileSync/Source/ui/small_dlgs.cpp 10.1-0/FreeFileSync/Source/ui/small_dlgs.cpp
--- 10.1/FreeFileSync/Source/ui/small_dlgs.cpp	2018-06-03 04:27:02.000000000 -0400
+++ 10.1-0/FreeFileSync/Source/ui/small_dlgs.cpp	2018-06-07 22:20:59.050384125 -0400
@@ -970,7 +970,8 @@
-    m_textCtrlOfflineActivationKey->ForceUpper();
+    // Fedora 27 does not have wxWidgets 3.1.1 yet.
+    //m_textCtrlOfflineActivationKey->ForceUpper();
     m_textCtrlLastError           ->ChangeValue(lastErrorMsg);
     m_textCtrlManualActivationUrl ->ChangeValue(manualActivationUrl);
diff -x '*.orig' -x '*.rej' -Naur 10.1/FreeFileSync/Source/ui/version_check_impl.h 10.1-0/FreeFileSync/Source/ui/version_check_impl.h
--- 10.1/FreeFileSync/Source/ui/version_check_impl.h	2018-06-03 04:27:02.000000000 -0400
+++ 10.1-0/FreeFileSync/Source/ui/version_check_impl.h	2018-06-07 22:20:59.051384152 -0400
@@ -14,7 +14,7 @@
 namespace fff
 time_t getVersionCheckInactiveId()
     //use current version to calculate a changing number for the inactive state near UTC begin, in order to always check for updates after installing a new version
@@ -38,7 +38,6 @@
 time_t getVersionCheckCurrentTime()
     return std::time(nullptr);
diff -x '*.orig' -x '*.rej' -Naur 10.1/wx+/grid.cpp 10.1-0/wx+/grid.cpp
--- 10.1/wx+/grid.cpp	2018-06-03 04:27:02.000000000 -0400
+++ 10.1-0/wx+/grid.cpp	2018-06-07 22:30:02.202436428 -0400
@@ -1169,7 +1169,9 @@
                 if (overlapPix != 0)
-                    const double scrollSpeed = wnd_.ToDIP(overlapPix) * mouseDragSpeedIncScrollU; //unit: [scroll units / sec]
+                    // Fedora 28 does not have wxGTK 3.1.1 yet. This probably breaks HiDPI usage
+                    //const double scrollSpeed = wnd_.ToDIP(overlapPix) * mouseDragSpeedIncScrollU; //unit: [scroll units / sec]
+                    const double scrollSpeed = overlapPix * mouseDragSpeedIncScrollU; //unit: [scroll units / sec]
                     toScroll += scrollSpeed * deltaSecs;

A summary of what this patch does:

  • Ensure using the system boost library. It appears the source looks for a locally-bundled boost lib, which was not included with the 10.1 code.
  • Link to zlib because previous versions use to, and without I could not compile.
  • Compile against gtk+3 instead of gtk+2 because I could not get it to compile against gtk2.
  • Place the changelog text file where the Makefile expects.
  • Disable the check for updates and lines related to activation, particularly a few based on a newer version of wxWidgets which Fedora 28 does not have yet (wxWidgets 3.1.1).
  • Revert to an older version of the scrollSpeed calculation because wxWidgets 3.1.1 is not in Fedora yet.

4. Apply patch

cd 10.1
patch -p1 < ../FreeFileSync-10.1-1.fc28.patch

5. Compile and install

cd FreeFileSync/Source
make && sudo make install

Next steps

Build an rpm for FreeFileSync (gitlab)



  1. How-to: Build 10.* from Source (Linux Mint) (FreeFileSync forum)
  2. Compiling FreeFileSync 10.0 on Fedora (this blog)
  3. Compiling FreeFileSync on Fedora (this blog)
  4. AUR (en) – freefilesync

Convert m4a to mp3 while preserving audio quality

If you have a set of m4a files and want to automatically convert them to mp3 so you can tag them the right way, use a snippet I wrote.

See the code in its proper formatting at

# reference:

logfile="/mnt/bgstack15/log/m4a-to-mp3.$( date -u "+%FT%H%M%SZ" ).log"

func() {
for word in "$@" ;
   echo "Entering item ${word}";
   outdir="${word}/mp3" ; mkdir "${outdir}" || exit 1 ;
   find "${word}" -type f \( -regex '.*M4A' -o -regex '.*m4a' \) | while IFS='\0' read infile ;
      test -f "${infile}" && echo "Found file: \"${infile}\"" || echo "INVALID! ${infile}"
      outfile="$( echo "${infile}" | sed -r -e "s/\.m4a/\.mp3/i" )"
      echo  ffmpeg -i \"${infile}\" -codec:v copy -codec:a libmp3lame -q:a 2 \"${outfile}\"
      yes | ffmpeg -i "${infile}" -codec:v copy -codec:a libmp3lame -q:a 2 -y "${outfile}" ; test -n "${outdir}" && /bin/mv -f "${outfile}" "${outdir}/" ;
      sleep 2 ;

time func "$@" | tee -a "${logfile}"

TIL #6: Top 10 Commands That You Use On Your Command-line Terminal

When you get bored, generate a histogram of your common commands.

history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl |  head -n10
     1  212  21.2%  ansible
     2  207  20.7%  ansible-playbook
     3  94   9.4%   cd
     4  69   6.9%   ll
     5  58   5.8%   cat
     6  55   5.5%   vim
     7  52   5.2%   ssh
     8  39   3.9%   vi
     9  35   3.5%   time
    10  33   3.3%   exit

Shekhar Gulati

I found a command that you can use to list down top commands that you use in your terminal

Following is my list

gdw is shortcut for Gradle wrapper.

View original post

A few useful keybindings for Window Manager in Xfce

xfce4-keyboard-shortcuts /xfwm4/custom/Down             tile_down_left_key
xfce4-keyboard-shortcuts /xfwm4/custom/Left             tile_up_left_key
xfce4-keyboard-shortcuts /xfwm4/custom/Right            tile_down_right_key
xfce4-keyboard-shortcuts /xfwm4/custom/Up               tile_up_right_key
xfce4-keyboard-shortcuts /xfwm4/custom/Down                  tile_down_key
xfce4-keyboard-shortcuts /xfwm4/custom/Left                  tile_left_key
xfce4-keyboard-shortcuts /xfwm4/custom/Right                 tile_right_key
xfce4-keyboard-shortcuts /xfwm4/custom/Up                    tile_up_key

I found that by having these values, I can use the keyboard to control the window placement with almost identical functionality as Cinnamon. This was one of the key differences (no pun intended) for me between Xfce and Cinnamon.

To import these settings with that input as is, check out I describe it here on the blog at xfconf-query save and load from file

Migrating GitHub gists to gitlab

Gitlab, as far as I know, does not have a quick-and-dirty area for snippets in the fashion of Gists on GitHub. My choice was to stick all my gists in a single repository. Here is how I got it done.

This script saves to the current directory all your gists, each to its named folder with an additional file “description” with the gist description since I couldn’t find it inside the git repo for a gist.

#!/usr/bin/env python
# Filename:
# Location: gitlab, probably
# Author: Chris Arndt (stackoverflow uid 39275), bgstack15
# Startdate: 2018-06-05 21:49
# Title: Script That Downloads GitHub Gists in a Nice Format
# Purpose: To facilitate my departure from GitHub
# History:
# Usage: ./ bgstack15
# Reference:
#    copied from
# Improve:
# -*- coding: utf-8 -*-
"""Clone all gists of GitHub username given on the command line."""

import subprocess
import sys
import requests

if len(sys.argv) > 1:
   gh_user = sys.argv[1]
   print("Usage: ")

req = requests.get('' % gh_user)

for gist in req.json():

   # get attributes
   name = gist['files'].keys()[0]
   descrip = gist['description']

   # debugging
   print name + ": " + descrip

   # clone the repo
   ret =['git', 'clone', gist['git_pull_url'], name])
   if ret != 0:
      print("ERROR cloning gist %s. Please check output." % gist['id'])

   # save description
   with open(name + "/" + "description", "w") as text_file:

Once I had all my gist directories there, I cleaned up their .git directories, and made a new git repo and uploaded it to gitlab.

rm -rf */.git/
git init
git add . -m 'initial retrieval from github gists'
git remote add origin
git push --set-upstream origin master

Migrating github projects to gitlab

For the projects that have issues, wikis, and all those nice addons, use the GitLab GitHub importer tool.

For simple projects, you can just call them from the command line. See



func() {
   git clone --mirror "${username}/${repo}" "./${repo}"
   pushd "${repo}"
   git remote add gitlab "${username}/${repo}.git"
   git push gitlab --mirror

time func ;

#Now if you have a locally cloned repository that you want to keep using with the new remote, just run the following commands* there:
#git remote remove origin
#git remote add origin "${username}/${repo}.git"
#git fetch --all



Meme about github and ms

I do not use social media, unless github, gitlab, or count. But, here is my hashtag for the week: #movingtogitlab.

With the disheartening news about a week ago of a malevolent force taking over the community darling, I have decided to move my projects to gitlab. Plus, I was awakened to the fact that github’s value-added bits are closed source. Well, what an interesting situation! And I was just getting a few stars on some of my repositories too.

Check out the traffic of the gitlab github importer:

I will be sharing over the next few posts some tools I used to facilitate this process. I had some help with the gist one, and I used a simple tool for the git repos.

Someday I may even run my own instance of gitlab.

Notes for git log

git log --graph --oneline --all
* 5240127 fix the tluid=tduid check syntax
* 9a4afe3 fix comments about branch in metadata of various files
*   93893b0 Merge remote-tracking branch 'origin/master' into work1
* \   7ba8d7e Merge branch 'master' of into work1
|\ \  
* | | 476f863 add cladu and bump to 1.3-4
* | | abbb687 userinfo: add chage
* | | 3c87f21 fix work1 branch again
* | | b9caef9 update %files core in spec

Git log output