Skip to content

Instantly share code, notes, and snippets.

@haxpor
Last active August 9, 2021 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haxpor/62147313816282b6352b8313f20560f6 to your computer and use it in GitHub Desktop.
Save haxpor/62147313816282b6352b8313f20560f6 to your computer and use it in GitHub Desktop.
Guideline to cross-compile CMake that also includes ccmake for Windows on Ubuntu Linux

There are 3 attempts used

  1. Cross-compile CMake with mingw64 + pre-built mingw64 ncurses - See cmake_crosscompile_mingw64_ncurses.md
  2. Cross-compile both CMake and pdcurses with mingw64 - See cmake_crosscompile_mingw64_pdcurses.md (Recommended)
  3. Natively compile CMake and pdcurses with MSVC - See cmake_native_cmake_pdcurses.md

All above 3 attempts shared the common steps but still listing such shared content in each of its own guide for reference and clear guideline.

Problem

You work on CMake Windows-based project on Windows machine through WSL.

Although on Windows, you can already use cmake-gui.exe. But you prefer to use command line based solution to configure or generate the project, or quickly adjust options from generated CMake project without a need to incrementally execute cmake.exe with bunch of options and lots of flags here and there. It's clear, you crave for ccmake which is available only on Unix/Linux based platform.

The core question is how can we make ccmake also available on Windows ?

Solution

There are 2 categories

  1. Cross-compile CMake for Windows on Linux with mingw64, then work with either curses/ncurses or PDCurses
  2. Natively compile both CMake and PDCurses with MSVC

If cross-compile, we use mingw64 to do so.

In either approach, some effort is needed to make CMake compatible to be compiled via mingw64, or tweak dependency like PDCurses. But I provide all patches needed to do so. Just make sure you checkout a specific correct version I listed in this guide.

Cross-compile CMake with mingw64 and ncurses

Result

Able to launch but functionality to configure and generate a CMake project are broken. It's stuck in Configuring... after hit c key to start configuring, most of the times the rendering is broken as well. You have to manually kill the process to quit the process.

Verdict: Small changes make it compilable, but not usable. Still approaches can be used as reference for cross-compiling.


Pre-requisite

  • mingw64 - install via package manager on Linux (for Debian/Ubuntu, use sudo apt install mingw-w64)
  • cmake - install by downloading Windows version of v3.20.5 (download here)
  • Upstream CMake source code (via git)
  • Pre-built mingw64 version of ncurses - download here look at MinGW Port section and most likely 64-bit)
  • mingw-std-threads (via git) - mingw64 still misses thread header library
  • CMake toolchain for cross-compile with mingw64- download here
  • My CMake patch for building with mingw64

How to

Separate into two phases.

  1. Preparation phase
  2. Finalize phase

1. Preparation Phase

Prepare CMake

  • git clone git@github.com:Kitware/CMake.git
  • git checkout v3.20.5 - specific version must be the same version our cmake patch bases on
  • git apply cmake_mingw64_v3.20.5.patch (get from my patch above)

Prepare mingw-std-threads

  • cd /usr/x86_64-w64-mingw32/include - this is the include directory that mingw64 toolchain will search for
  • git clone git@github.com:meganz/mingw-std-threads.git - you might need sudo. This will patch in threads and concurrency primitives which are missing from mingw64 itself.

Prepare ncurses

  • Download it here, assume you saved to ~/Download/ncurses-prebuilt
  • Copy all those library binaries in lib/ into /usr/x86_64-w64-mingw32/lib

Prepare CMake toolchain file for building with mingw64

  • Download toolchain file from here - thanks to ebraminio, and (originally) peterspackman
  • Change the line set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) to be set(TOOLCHAIN_PREFIX /usr/bin/x86_64-w64-mingw32)

2. Finalize Phase

  1. Go to CMake source directory
  2. cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake -G Ninja -B _build -S . - assume that you put your toolchain file at your home directory
  3. You should notice the line saying -- Found Curses: /usr/x86_64-w64-mingw32/lib/libncursesw.dll.a;/usr/x86_64-w64-mingw32/lib/libformw.dll.a which means it found NCurses to link against.
  4. ninja -C _build
  5. cp -av ~/Downloads/ncurses-prebuilt/bin/* <CMake-src-dir>/_build/bin/
  6. cp -av /mnt/c/Program\ Files/CMake/share <CMake-src-dir>/_build/
  7. <CMake-src-dir>/_build/bin/cmake.exe --help. You should see no errors. Bunch of help texts should show up.
  8. Test it against generated CMake project by using ccmake.exe "C:\Path\To\Your\Target wheres the path is where your generated CMake project located.
  9. Done

Cross-compile CMake with mingw64 and ncurses

Result

PDCurses is regarded as curses/ncurses alternative that works on Windows. It lives up to that promise although still need a particular tweak on arrow keys code for it to detect through WSL. Usable and works fine. Anyway, a small penalty of performance hit as we can actually go with native compilation with MSVC. So it might make this approach less attractive to persue.

Verdict: Compilable, able to launch and functionality works although with a single tweak towards arrow key codes on PDCurses.


Pre-requisite

  • mingw64 - install via package manager on Linux (for Debian/Ubuntu, use sudo apt install mingw-w64)
  • cmake - install by downloading Windows version of v3.20.5 (download here)
  • Upstream CMake source code (via git)
  • Upstream PDCurses source (vid git) - use 3.9 release tag
  • mingw-std-threads (via git) - mingw64 still misses thread header library
  • CMake toolchain for cross-compile with mingw64- download here
  • My CMake and PDCurses patch here

How to

Separate into two phases.

  1. Preparation phase
  2. Finalize phase

1. Preparation Phase

Prepare CMake

  • git clone git@github.com:Kitware/CMake.git
  • git checkout v3.20.5 - specific version must be the same version our cmake patch bases on
  • git apply cmake_v3.20.5_pdcurses.patch (get from my patch above)

Prepare mingw-std-threads

  • cd /usr/x86_64-w64-mingw32/include - this is the include directory that mingw64 toolchain will search for
  • git clone git@github.com:meganz/mingw-std-threads.git - you might need sudo. This will patch in threads and concurrency primitives which are missing from mingw64 itself.

Prepare PDCurses

  • git clone git@github.com:wmcbrine/PDCurses.git
  • git checkout 3.9
  • git apply pdcurses_mingw64.patch (get from my patch above)
  • cd wincon
  • make DLL=Y
  • cp -av pdcurses.a pdcurses.dll /usr/x86_64-w64-mingw32/lib/
  • cd ..
  • cp -av curses.h curspriv.h panel.h wincon/pdcwin.h /usr/x86_64-w64-mingw32/include/

Prepare CMake toolchain file for building with mingw64

  • Download toolchain file from here - thanks to ebraminio, and (originally) peterspackman
  • Change the line set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) to be set(TOOLCHAIN_PREFIX /usr/bin/x86_64-w64-mingw32)

2. Finalize Phase

  1. Go to CMake source directory
  2. cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake -G Ninja -B _build -S . - assume that you put your toolchain file at your home directory
  3. You should notice the line saying -- Found Curses: /usr/x86_64-w64-mingw32/lib/libncursesw.dll.a;/usr/x86_64-w64-mingw32/lib/libformw.dll.a which means it found NCurses to link against.
  4. ninja -C _build
  5. Go to PDCurse source directory
  6. cp -av wincon/pdcurses.dll <CMake-src-dir>/_build/bin/
  7. cp -av /mnt/c/Program\ Files/CMake/share <CMake-src-dir>/_build/
  8. <CMake-src-dir>/_build/bin/cmake.exe --help. You should see no errors. Bunch of help texts should show up.
  9. Test by using ccmake.exe -S "C:\Path\To\Your\SourceDir" -B "C:\Path\To\Your\BuildDir"
  10. Done

Natively compile CMake and PDCurses with MSVC

Result

First thought is that this MSVC-based version would be faster as it's natively compiled and use on target host which is Windows in this case. But it is not the case!

I can feel it's slower like 3-4 times compared to mingw64 cross-compiled of ccmake.exe. The project is newly configured much faster for mingw64 version. You will be clearly notice.

How to

Pre-requisite

  • cmake - install by downloading Windows version of v3.20.5 (download here)
  • Upstream CMake source code (via git)
  • Upstream PDCurses source (vid git) - use 3.9 release tag
  • My CMake and PDCurses patch here

How to

Separate into two phases.

  1. Preparation phase
  2. Finalize phase

1. Preparation Phase

Prepare CMake

  • git clone git@github.com:Kitware/CMake.git
  • git checkout v3.20.5 - specific version must be the same version our cmake patch bases on
  • git apply cmake_v3.20.5_pdcurses.patch (get from my patch above)

Prepare PDCurses

  • git clone git@github.com:wmcbrine/PDCurses.git
  • git checkout 3.9
  • git apply pdcurses_mingw64.patch (get from my patch above)
  • cd wincon
  • nmake -f Makefile.vc

Prepare CMake toolchain file for building with mingw64

  • Download toolchain file from here - thanks to ebraminio, and (originally) peterspackman
  • Change the line set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) to be set(TOOLCHAIN_PREFIX /usr/bin/x86_64-w64-mingw32)

2. Finalize Phase

  1. Go to CMake source directory
  2. cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake -G Ninja -B _build -S . - assume that you put your toolchain file at your home directory
  3. You should notice the line saying -- Found Curses: /usr/x86_64-w64-mingw32/lib/libncursesw.dll.a;/usr/x86_64-w64-mingw32/lib/libformw.dll.a which means it found NCurses to link against.
  4. ninja -C _build
  5. Go to PDCurse source directory
  6. cp -av wincon/pdcurses.dll <CMake-src-dir>/_build/bin/
  7. cp -av /mnt/c/Program\ Files/CMake/share <CMake-src-dir>/_build/
  8. <CMake-src-dir>/_build/bin/cmake.exe --help. You should see no errors. Bunch of help texts should show up.
  9. Test by using ccmake.exe -S "C:\Path\To\Your\SourceDir" -B "C:\Path\To\Your\BuildDir"
  10. Done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment