Using 'crossroad' to compile Windows versions of G'MIC on Linux

So here is the full procedure to build G’MIC! Based on building on a Debian stable (except I target it to Ubuntu users, since @David_Tschumperle is using Ubuntu, so I use sudo for few root-needing commands) .

  1. Install crossroad!
$ git clone git://git.tuxfamily.org/gitroot/crossroad/crossroad.git
$ cd crossroad
$ pip3 install -r requirements.txt
$ ./setup.py build && ./setup.py install

(obviously a --prefix option is available to the install subcommand if preferred)

  1. Just as for a native build, following README.md:
$ git clone https://github.com/dtschump/gmic.git
$ git clone https://github.com/c-koi/gmic-qt.git
$ make -C gmic/src CImg.h gmic_stdlib.h
  1. Let’s make sure we have C and C++ cross-compilers:
$ crossroad -h w64
w64: Setups a cross-compilation environment for Microsoft Windows operating systems (64-bit).

Not available. Some requirements are missing:
- x86_64-w64-mingw32-gcc [package "gcc-mingw-w64-x86-64"] (missing)
- x86_64-w64-mingw32-ld [package "binutils-mingw-w64-x86-64"] (missing)
$ sudo apt install binutils-mingw-w64-x86-64 gcc-mingw-w64-x86-64
[…]
$ crossroad -h w64
w64: Setups a cross-compilation environment for Microsoft Windows operating systems (64-bit).

Installed language list:
- C
Uninstalled language list: 
- Ada                 Common package name providing the feature: gnat-mingw-w64-x86-64
- C++                 Common package name providing the feature: g++-mingw-w64-x86-64
- OCaml               Common package name providing the feature: mingw-ocaml
- Objective C         Common package name providing the feature: gobjc++-mingw-w64-x86-64
- fortran             Common package name providing the feature: gfortran-mingw-w64-x86-64
$ sudo apt install g++-mingw-w64-x86-64
$ crossroad -h w64
[…]
Installed language list:
- C
- C++
[…]
  1. Ok now we have the basics to build for Windows 64-bit. Let’s enter the crossroad environment. I will call it gmic:
$ crossroad w64 gmic
⤫ ccd -y gmic-qt
⤫ crossroad source msys2

Note: you will notice I use a different prompt in my tutorial to show when I am inside crossroad () or not ($).

  1. Finally let’s configure. We will use CMake (Crossroad supports autotools, meson and CMake only, but not qmake, patches accepted!), so it obviously has to be installed as well, if not already (sudo apt install cmake), same for pkg-config (sudo apt install pkg-config). I could just do a one-liner with all crossroad dependencies, but I will take the opportunity to show how the package manager works by discovering the first dependency issue together.
⤫ crossroad cmake /path/to/src/gmic-qt/
[…]
CMake Error at CMakeLists.txt:129 (find_package):
  By not providing "FindQt5.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Qt5", but
  CMake did not find one.

  Could not find a package configuration file provided by "Qt5" (requested
  version 5.2.0) with any of the following names:

    Qt5Config.cmake
    qt5-config.cmake

  Add the installation prefix of "Qt5" to CMAKE_PREFIX_PATH or set "Qt5_DIR"
  to a directory containing one of the above files.  If "Qt5" provides a
  separate development package or SDK, be sure it has been installed.


-- Configuring incomplete, errors occurred!
See also "/home/jehan/.local/share/crossroad/artifacts/w64/gmic/gmic-qt/CMakeFiles/CMakeOutput.log".
⤫ crossroad search --search-files Qt5Config.cmake
[…]
The following packages have files matching the search "Qt5Config.cmake":
	- phonon-qt5
	- qca-qt5
	- qt5
	- qt5-static
	- snorenotify
⤫ crossroad install qt5

Now re-run crossroad cmake /path/to/src/gmic-qt/, check the next dependency error, search the package with crossroad search --search-files, install and so on. Loop on. I will spare you each run. Here is the command to install remaining missing dependencies:

⤫ crossroad install fftw curl gimp

Note: the gimp dependency is for building with GMIC_QT_HOST=gimp (the default, which is the only tested so far) as it requires to link against libgimp. That pulls quite a lot of dependencies, but obviously they won’t be necessary after the build.

  1. Special case: the build needs to call some Qt binaries (moc and rcc) and I have not figured out yet if we can use native ones. But also even if the format is the same, native tools may not be the same version as the used Windows Qt libraries (apparently it’s important as I see that there is a wrapper tool called qtchooser to select the right Qt binary depending on your version/target, etc.). I didn’t want to spend too long figuring out what was what so I just rely on Wine for this and it works fine (no build issue on a Fedora 31 and a Debian stable at least). Therefore I temporarily install Wine as a binfmt_misc interpreter for Windows binaries.
$ sudo apt install wine
$ sudo sh -c "echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register"

Note: I use $ as it doesn’t need to be run from inside the crossroad environment, but whatever. It would work inside as well.

  1. Configure again and now it should be a success!
⤫ crossroad cmake /path/to/src/gmic-qt/
crossroad info: running "cmake -DCMAKE_INSTALL_PREFIX:PATH=$CROSSROAD_PREFIX -DCMAKE_TOOLCHAIN_FILE=$CROSSROAD_CMAKE_TOOLCHAIN_FILE /path/to/src/gmic-qt/"
-- Using CMake version: 3.13.4
Build type is Release
Building for target host application: gimp
G'MIC path: ../gmic/src
LTO is disabled (windows platform)
Found G'MIC repository
Found ../gmic/src/CImg.h
Found ../gmic/src/gmic_stdlib.h
CImg version is [293]
G'MIC version is [293]
-- Correctly found FFTW3
G'Mic: using OpenMP
-- The following OPTIONAL packages have been found:

 * CURL
 * OpenMP, A low-level parallel execution library, <http://openmp.org/wp/>
   Optionally used by gmic-qt

-- The following REQUIRED packages have been found:

 * Qt5Core
 * Qt5Gui
 * Qt5Widgets
 * Qt5Network
 * Qt5 (required version >= 5.2.0)
 * Qt5LinguistTools
 * PNG
 * ZLIB
 * FFTW3

-- Configuring done
-- Generating done
-- Build files have been written to: /home/jehan/.local/share/crossroad/artifacts/w64/gmic/gmic-qt
  1. Now build:
⤫ make
[…]
[100%] Linking CXX executable gmic_gimp_qt.exe
[100%] Built target gmic_gimp_qt
⤫ make install
[  1%] Automatic MOC for target gmic_gimp_qt
[  1%] Built target gmic_gimp_qt_autogen
[100%] Built target gmic_gimp_qt
Install the project...
-- Install configuration: "Release"
-- Installing: /home/jehan/.local/share/crossroad/roads/w64/gmic/lib/gimp/2.0/plug-ins/gmic_gimp_qt.exe

You may take a rest while watching the build, surf the web, watch webcomics or movies, etc. Unlike a native build in a VM, a cross-build won’t take more time that a native Linux build, and won’t kill your resource usage (not more than a native Linux build again; technically it’s exactly the same except that the output format is different, that’s all). On a very non-powerful micro machine, full build took about 20 minutes.

  1. The files will be found under $CROSSROAD_PREFIX. In particular, the GIMP plug-in for instance will be in $CROSSROAD_PREFIX/lib/gimp/2.0/plug-ins/gmic_gimp_qt.exe:
⤫ file $CROSSROAD_PREFIX/lib/gimp/2.0/plug-ins/gmic_gimp_qt.exe
/home/jehan/.local/share/crossroad/roads/w64/gmic/lib/gimp/2.0/plug-ins/gmic_gimp_qt.exe: PE32+ executable (GUI) x86-64 (stripped to external PDB), for MS Windows

Nice we have a Windows binary! Small bonus for packaging: you may look for the library dependencies automatically with x86_64-w64-mingw32-objdump (which come with the binutils-mingw-w64-x86-64 package which we already installed).

⤫ x86_64-w64-mingw32-objdump -p $CROSSROAD_PREFIX/lib/gimp/2.0/plug-ins/gmic_gimp_qt.exe |grep dll
	DLL Name: Qt5Core.dll
	DLL Name: Qt5Gui.dll
	DLL Name: Qt5Network.dll
	DLL Name: Qt5Widgets.dll
	DLL Name: libbabl-0.1-0.dll
	DLL Name: libcurl-4.dll
	DLL Name: libfftw3-3.dll
	DLL Name: libgegl-0.4-0.dll
	DLL Name: libgimp-2.0-0.dll
	DLL Name: libgobject-2.0-0.dll
	DLL Name: libpng16-16.dll
	DLL Name: libgcc_s_seh-1.dll
	DLL Name: libgomp-1.dll
	DLL Name: libstdc++-6.dll
	DLL Name: GDI32.dll
	DLL Name: KERNEL32.dll
	DLL Name: msvcrt.dll
	DLL Name: SHELL32.dll
	DLL Name: USER32.dll
	DLL Name: zlib1.dll

Then recursively do the same thing for each DLL, so that you get the full list of dependencies you need to package. Siril for instance automatized this process with a Python script calling this tool recursively (which is pretty cool so I am planning on using the same thing for GIMP).

  1. You may reset the binfmt_misc configuration to not run Windows binaries by mistake on your pretty Linux box (note that this was not a permanent change anyway and would have been resetted after reboot):
sudo sh -c "echo -1 > /proc/sys/fs/binfmt_misc/DOSWin"
  1. Enjoy G’MIC with a beer, a glass of wine, kir, whisky, schnaps, soda, water, juice… whatever suits you!

Note: a lot of these steps are only to be done once or automatized a bit more. So on next builds, it will be a lot faster.

2 Likes

This doesn’t work.

$ crossroad -h w64
Unknown option for the "help" command: w64
$ crossroad --help w64
Unknown option for the "help" command: w64

The package you mention was indeed not installed. So I’ve installed it.

Trying to compile again…

This is to be run from outside the crossroad environment. There are commands for inside, and others for outside. Actually -h also works inside the crossroad environment, but then it is to get help on target subcommand (for instance crossroad -h install), instead of help on target platforms.

Trying to compile again…

Did you see the tutorial I just posted above your comment? :slightly_smiling_face:

Just seen your comment above, trying to deal with it :slight_smile: Thanks!

Wow, that installs tons of stuffs, and I’m getting out of space on my device.
Will try later then.
Thanks again.

Wait what? This is an echo inside a kernel file (see more about binfmt_misc). It is not supposed to install anything. This is simply a string to tell your kernel how it can execute Windows files (i.e. by running them through Wine).

I was talking about this, it just exploded all my disk space:

  • the qt5 libs.

Ahah yeah. It does install quite a bunch of dependencies, most of them are obviously not even needed (that’s the problem of making big keep-all packages; especially for GIMP, a libgimp package would have been useful for build-only use cases).

Though you were probably already close to a full disk, I would guess, no?

✘du -sh $CROSSROAD_PREFIX
2.3G	/home/jehan/.local/share/crossroad/roads/w64/gmic
✘du -sh $CROSSROAD_HOME
61M	/home/jehan/.local/share/crossroad/artifacts/w64/gmic
✘du -sh ~/.cache/crossroad/
521M	/home/jehan/.cache/crossroad/

The whole build (artifacts, prefix with dependencies and cache included, so basically everything) only takes me ~3GiB. :slightly_smiling_face:

O_o

Ahahah. Well that’s a build from scratch (you had no Windows libraries installed before) and we install a whole bunch of dependencies for it (some of them useless, but that’s how package dependency work), up to the lowest software level. You don’t see such install usage on a new Linux build only because most dependencies are already there. :stuck_out_tongue:

I gave another try today, and indeed the gmic_gimp_qt.exe executable is build.
I get a lot of strange warnings at the beginning, things like:

$ make
Scanning dependencies of target gmic_gimp_qt_autogen
[  1%] Automatic MOC for target gmic_gimp_qt
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
I/O error : Permission denied
I/O error : Permission denied
Failed to write XML file; For permission problems, try rerunning as root
AutoMoc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[  1%] Built target gmic_gimp_qt_autogen
[  2%] Automatic RCC for translations.qrc
AutoRcc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
I/O error : Permission denied
I/O error : Permission denied
Failed to write XML file; For permission problems, try rerunning as root
[  3%] Generating ui_dialogsettings.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
I/O error : Permission denied
I/O error : Permission denied
Failed to write XML file; For permission problems, try rerunning as root
[  4%] Generating ui_filtersview.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[  5%] Generating ui_headlessprogressdialog.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[  6%] Generating ui_inoutpanel.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[  8%] Generating ui_languageselectionwidget.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[  9%] Generating ui_mainwindow.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 10%] Generating ui_multilinetextparameterwidget.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 11%] Generating ui_progressinfowidget.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 12%] Generating ui_progressinfowindow.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 13%] Generating ui_SearchFieldWidget.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 15%] Generating ui_zoomlevelselector.h
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
[ 16%] Automatic RCC for gmic_qt.qrc
AutoRcc: ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object 'libgtk3-nocsd.so.0' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
Scanning dependencies of target gmic_gimp_qt
[ 17%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/ClickableLabel.cpp.obj
[ 18%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/Common.cpp.obj
[ 19%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/OverrideCursor.cpp.obj
[ 20%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/DialogSettings.cpp.obj
[ 22%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/AbstractParameter.cpp.obj
[ 23%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/BoolParameter.cpp.obj
[ 24%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/ButtonParameter.cpp.obj
[ 25%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/ChoiceParameter.cpp.obj
[ 26%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/ColorParameter.cpp.obj
[ 27%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/ConstParameter.cpp.obj
[ 29%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/CustomDoubleSpinBox.cpp.obj
[ 30%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/FileParameter.cpp.obj
[ 31%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/FilterParametersWidget.cpp.obj
[ 32%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/FloatParameter.cpp.obj
[ 33%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/FolderParameter.cpp.obj
[ 34%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/IntParameter.cpp.obj
[ 36%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/LinkParameter.cpp.obj
[ 37%] Building CXX object CMakeFiles/gmic_gimp_qt.dir/src/FilterParameters/MultilineTextParameterWidget.cpp.obj
...

I don’t know why. If you have an idea…

Now, I’ll run my VM and test the executable. More news later :slight_smile:

More news: After having put the .dll files in the right place, the cross-compiled plug-in finally works !
Now, I have two more issues :

  • I’d really like to use the qmake procedure, instead of cmake to compile the plug-in, because this is the way Sébastien compiles it, and I’m sure all optim flags will be set as desired. Also there are possible options to pass to qmake to enable some wip stuffs (e.g. filter translations). Is there a way to deal with qmake inside crossroads ?

  • Similarly, I cannot use cmake inside crossroad to crosscompile the CLI version gmic.exe for Windows, as I get:

CMake 3.14.0 or higher is required.  You are running version 3.13.4

When I try lowering the required version number in the CMakeLists, the compilation fails anyway (which means the required version number is indeed right).
So, I’d prefer to use my own Makefile for compiling gmic.exe. This is the way I’m doing it when I develop, and I’m clearly more familiar with it (and all the options I can set for the compil).
Do you think it’s possible to use the classical Makefile inside crossroad as well ?

Thanks!

Looks like it’s not using the right libraries (it’s a shared object .so not a .dll). I didn’t have these. But really this whole MOC business is new to me. I never developed a software using this process and have no idea even what this does. So I really don’t know if these warnings can be ignored or not.

1 Like

Well, at the end, the plug-in works, so I think they can be safely ignored indeed :slight_smile:

I’m currently trying to update my compilation environment on my VM machine, so at the end, it may happen I won’t finally use crossroads to compile the plug-in. We’ll see.
The fact that the packaging tools are easier to install on Windows, as well as the fact I can test easily on a real Windows environment is something nice.
Thanks for all your help anyway.

1 Like

Not right now as I never looked into how qmake works. But if it’s even just half well-thought, it will have a generic process for cross-compilation then it will be very easy to add support.

As I was saying to someone else on Twitter today: Crossroad is developed on the concept of standard/generic compilation rules (and not per-project recipes like some other tools; that’s how I can use it so easily even on random projects). For instance any meson/autotools/cmake project should be easily cross-compilable by just setting up some common environment or build system variables.

There are actually 2 parts of Crossroad:

  1. It sets up various environment variable and also a few wrappers to common tools (gcc, g++, cpp and pkg-config) which ends up calling the real tools after tweaking a few more variables. Every build system share these variables and tools.

  2. Then there is the build system-specific part, which is mostly “how does the build system discover the tools?” (and sometimes a few more settings). In autotools, it just works with a host/target prefix concept. In meson/cmake, it works with a toolchain file.

Adding a new build system is only about the point 2.
So adding qmake support may just be as simple as adding some CLI options to the qmake call (like in autotools) or adding a small toolchain files (meson, cmake…).
This is assuming there is a standard cross-compilation concept in qmake, as there is in meson, autotools, cmake.

I don’t have too much time to spend on this right now. I would say patches are welcome though. :wink:
Or maybe if some day I am bored, I might get documented a bit about how qmake handles cross-compilation and improve Crossroad. But don’t hold your breath!

  • Similarly, I cannot use cmake inside crossroad to crosscompile the CLI version gmic.exe for Windows, as I get:

Ah well… Crossroad just uses what is available on your native system. If Ubuntu does not even provide a recent CMake, there is not much I can do (my Fedora is nearly 2 versions late and I have CMake 3.17.4. How late is Ubuntu?! 3.13.4 was released 1,5 years ago!). Apart from updating the distribution, or installing CMake independently from the package manager, I can’t really advise you. You set the minimum requirement yourself in your CMakeLists. :stuck_out_tongue:

Do you think it’s possible to use the classical Makefile inside crossroad as well ?

Of course. The point 1. above will still be true while being inside the Crossroad environment. But then you’ll have to do the work yourself to handle the point 2. yourself. Basically you want to build with x86_64-w64-mingw32-gcc | x86_64-w64-mingw32-g++ (use the one inside Crossroad, which is a wrapper which will end up calling the distribution one after updating some environment variables just for the compilation call). And you want to search dependencies with x86_64-w64-mingw32-pkg-config (as you could see, in the patch I contributed yesterday for instance, this is the bug I fixed in gmic-qt CMakeLists which was hardcoding pkg-config instead of using the one auto-detected by CMake) and so on.

Selecting the right compiler, preprocessor or dependency search tool is one of the jobs done by build systems such as autotools, CMake or meson (and likely qmake too). So yeah if you do your own Makefile, it’s still totally possible to use Crossroad (which will still be very helpful because it sets up a lot more behind the scene than just the build system part). Just handle the tool selection appropriately yourself. :slightly_smiling_face:

2 Likes

And this is why I haven’t compiled anything for a decade. Don’t have the time or patience and have a faulty computer. Thanks @David_Tschumperle for supporting Windows. With each new iteration, G’MIC is running better than ever. E.g. my custom guided filters used to take many more minutes to run for a large image.

I cross-compile all the time with qmake through MXE (not Natron, but other projects), so it should work just fine. Have not tried crossroad yet, but will try to dedicate some time this weekend if possible.

One question; Does crossroad only support mingw packages from the distro? I use custom MSYS2 packages for Natron, is it possible to install them, or just zip the MSYS2 folder from Windows and use that on Linux?

@Jehan, I’ve finally succeeded in setting up an up-to-date compilation environment on my Windows VM, with all the latest packages from MSYS2 (particularly the latest compiler gcc version 10), so I think I’ll stick with it for the moment. Having a recent version of the compiler was my major concern.

Right now, I’m building new binary packages for G’MIC 2.9.3_pre for Windows. Hopefully, they will run better than our previous Windows releases :slight_smile:

I used to think that cross-compilation was hard, back 10 years ago. What I realized over the years is that cross-compilation is actually nearly as simple as native compilation. The only annoying part is that the build environment is a bit more messy because you obviously have a mix of native and target tools, libraries and other data. So you indeed have to be a bit more careful on redirecting your build system to the right tool.
But the more I digged in, the more I realized this part could just be automatized, and furthermore even generically since the concepts were the same whatever the project.
All it takes is a project well maintained and using standard tools (often there is just one or two patches to apply to a project build system as the developer didn’t always have genericity in mind when making some custom build rules, but that’s it; then I contribute the patches to the project and done!).

I would have thought so anyway. It’s one of the major build systems, there has to be some genericity built-in. :slightly_smiling_face:
But I am always careful before saying this with certainty as I have the bad experience with scons, which I used years ago (as it was used by at least one software I used to compile, though nowadays, I don’t see it much more fortunately). I realized every feature had to be implemented by a scons-using project, they didn’t try to enforce any kind of “standard rules for scons projects” (and in particular nothing generic for cross-compilation, but not even for native compilation; for instance, if not mistaken, they didn’t even propose a standard prefix syntax, each and every projects had to implement it themselves! :astonished:). So it was impossible to support scons generically in Crossroad. It’s still possible to cross-build scons project, but then you are basically in the same situation as cross-building generic Makefile (without higher-level system such as autotools/cmake) and have to do all the menial work (which crossroad can do for you for meson/autotools/cmake).

No Crossroad supports MSYS2, OpenSUSE and Fedora (30 to 32) repositories. See the crossroad source command inside a Windows Crossroad environment (the command allows you to see possible source and to switch source). Nowadays I mostly use the MSYS2 packages as they provide more software and are often more up-to-date.

And yes, you can fully build all your dependency tree yourself, or just import them manually from some other third-party if you prefer. Just install them inside $CROSSROAD_PREFIX (in the standard FHS structure) so that Crossroad finds them. This is basically what Crossroad itself does when installing dependencies from any of the supported sources.

For information, it is to be noted than normally you should build everything with the same toolchain. In particular, it is advised to build everything with the same compiler (and compiler version). So what we do when we build a software using MSYS2 dependencies while we compile with our distribution cross-compiler is not exactly ideal and link-time failure might happen. Now the DLL format is a bit more robust (according to the same link), and in 8 years of very regular cross-compilation, I had incompatibility issues at link time maybe twice or thrice at most. Anyway using such external source of packages and compiling while not leaving our comfy Linux is such a great convenience that this is absolutely worth it. :slightly_smiling_face:

Ok no problem. What suits you is the best. :slightly_smiling_face:

I use mxe for rawproc, and it Just Works. I stumbled around for a bit with the gcc version (5.5) until I found the plugins for the subsequent versions, and now I’m compiling my Windows targets with gcc 9.3. It also supports the static linking for my critical libs (libraw, lcms2, librtprocess, lensfun, wxWidgets), indeed, my windows executables are entirely static. Some might not think that’s prudent, but I got tired of chasing dependencies I wanted vs the OS.

I went to try crossroad, but I got stymied in the python dependencies. I’m not a python person… :stuck_out_tongue_closed_eyes:

I wen to try dockcross and guess what, their windows containers are based on mxe…

So my rawproc build directories for linux, win64, and win32 (although I’m probably going to dump win32 for 1.0) all sit side-by-side on my Ubuntu box, and are all built for release with a single script. No separate VMs, machines, and even the ./configures only differ with the addition of --host=win_target …