lhmouse / nano-win

GNU nano text editor for Windows [WARNING: The master branch is constantly rebased and force-pushed so don't expect it to be steady!! -end WARNING]
https://files.lhmouse.com/nano-win/
GNU General Public License v3.0
210 stars 25 forks source link

SUGGESTION: Streamline the cross compile from linux #46

Open okibcn opened 1 year ago

okibcn commented 1 year ago

It is weird having a cmd file and a shell script when all can be done in linux way faster, even from WSL.

In any Ubuntu just prepare the required packages with:

sudo -E apt update && sudo apt upgrade -y
sudo -E apt install -y autoconf automake autopoint gcc mingw-w64 gettext git groff make pkg-config texinfo  p7zip-full

And then replace the contents of build_nano-win.sh with this:

#!/bin/bash -e

_host="${1:-x86_64}-w64-mingw32"
_pwd="$(cygpath -am $(pwd) || readlink -f $(pwd))"
_nproc="$(nproc)"
_prefix="$(cygpath -au $(pwd) || readlink -f $(pwd))/pkg_${_host}"

wget -c "https://invisible-mirror.net/archives/ncurses/ncurses-6.4.tar.gz"
tar -xzvf ncurses-6.4.tar.gz
patch -p1 < ncurses-6.4.patch
./autogen.sh

mkdir -p "${_pwd}/build_${_host}"
pushd "${_pwd}/build_${_host}"

mkdir -p "ncurses"
pushd "ncurses"
# Build ncurses toolchain for local host 
unset CPPFLAGS CFLAGS LDFLAGS
../../ncurses/configure --prefix="$(pwd)"  \
  --enable-{widec,sp-funcs,termcap,term-driver,interop}  \
  --disable-{shared,database,rpath,home-terminfo,db-install,getcap,echo}  \
  --without-{progs,ada,cxx-binding,manpages,pthread,debug,tests,libtool}
make -j$(($(nproc)*2))

# cross Build ncurses for destination host 
export CFLAGS="-O2 -g3"
unset CPPFLAGS 
export LDFLAGS="-static-libgcc"
../../ncurses/configure --prefix="${_prefix}"  --host="${_host}" \
  --enable-{widec,sp-funcs,termcap,term-driver,interop}  \
  --disable-{shared,database,rpath,home-terminfo,db-install,getcap,echo}  \
  --without-{progs,ada,cxx-binding,manpages,pthread,debug,tests,libtool}
make -j$(($(nproc)*2)) 
make install
popd

mkdir -p "nano"
pushd "nano"
export CFLAGS="-O2 -g3 -flto"
export CPPFLAGS="-D__USE_MINGW_ANSI_STDIO -I\"${_prefix}/include\""
export LDFLAGS="-L\"${_prefix}/lib/\" -static -flto -static-libgcc"
export NCURSESW_CFLAGS="-I\"${_prefix}/include/ncursesw\" -DNCURSES_STATIC"
export NCURSESW_LIBS="-lncursesw"
touch roll-a-release.sh  # enable use of `git describe`
../../configure  --host="${_host}" --prefix="${_prefix}"  \
  --enable-utf8 --disable-{nls,speller}
make -j$(($(nproc)*2)) 
make install-strip
popd

Then the build_package.sh could be as simple as:

#!/bin/bash -e

./build_nano-win.sh x86_64
./build_nano-win.sh i686
./package_nano-win.sh

Or you can just integrate the first two lines into package_nano-win.sh removing the need to create that third file. package_nano-win.sh would be this:

#!/bin/bash -e

./build_nano-win.sh x86_64
./build_nano-win.sh i686

_pkgversion="$(git describe --tags || echo "v0.0.0-0-unknown")"
_revision="$(git rev-list --count HEAD)"

strip -s pkg_{i686,x86_64}-w64-mingw32/bin/nano.exe
cp doc/sample.nanorc.in .nanorc
7z a -aoa -mmt"$(nproc)" --  \
  "nano-win_${_revision}_${_pkgversion}.7z"  \
  pkg_{i686,x86_64}-w64-mingw32/{bin/nano.exe,share/{nano,doc}/}  \
  .nanorc

Consider replacing the slow MSYS2 with a standard ubuntu image that can be easily converted into a GitHub Action.

My two cents. Thanks for the project.

lhmouse commented 1 year ago

The cmd script is for my personal use. The only reason why it exists is that MSYS2 has no multilib environment - the MINGW32 shell can build i686 programs, and the MINGW64 shell can only build x86_64 program due to lack of 32-bit libraries.

I think I can try fixing the sh for use on my Linux Mint.

lhmouse commented 1 year ago

The master branch has been updated and should build fine for x86_64-w64-mingw32. The editor seems to run fine inside Wine.

okibcn commented 1 year ago

Yes, I have just tested those two modified files build_nano-win.sh and package_nano-win.sh, and they both run nicely on Mint too. The resulting package runs fine on Windows 11 (at this time Version 10.0.25272.1000). It also cross compile from Arch Linux. Basically, you can bypass completely the ugly MSYS2. WSL can handle it way better than MSYS2.

lhmouse commented 1 year ago

No, native builds are still preferred to cross builds.

lhmouse commented 1 year ago

Updated a little more. The 64-bit build now links against UCRT instead of MSVCRT and works fluently with UTF-8 text now. The 32-bit build is being held back as there is no UCRT32 environment in MSYS2.

okibcn commented 1 year ago

I don't have any problem compiling for Win32 and Win64 with UTF-8 enabled in any Debian Linux distro (Ubuntu, Mint, etc). Maybe you missed sone flags. I have edited the first post to resemble those I am using.

Actually, my approach uses nano and ncurses from git with minimal changes. That way, for instance, I don't need to patch ncurses at all. I have taken some of your code approach in my script. You can also improve yours. Look at this script: xbuild-4-win.sh.

I am now fighting with the github actions to automate the generation as soon as ncurses or nano gits are updated.

lhmouse commented 1 year ago

I don't have any problem compiling for Win32 and Win64 with UTF-8 enabled in any Debian Linux distro (Ubuntu, Mint, etc). Maybe you missed sone flags. I have edited the first post to resemble those I am using.

See this https://lists.gnu.org/archive/html/bug-ncurses/2023-01/msg00025.html. Also please notice UTF-8 never works with MSVCRT.

Actually my approach is by using nano and ncurses from git with minimal changes. That way, for instance I don't need to patch ncurses at all. I have taken some of your code approach in my script. Maybe you can also improve yours. Just take a look at this script: xbuild-4-win.sh.

If you don't patch ncurses (at least at this moment we speak), echo meow | nano - will be unusable. nano itself requires patching too, because on Windows open() opens files in text mode, so if you save files in Unix format you get MS-DOS linebreaks (CR LF), and if you save files in MS-DOS format you get a redundant CR before CR LF.

okibcn commented 1 year ago

hmmm... you are right. I was too fast thinking that successfully compiling with UTF-8 enabled was enough. It is failing in your implementation, and obviously in mine as it has fewer modifications.

image

At some point in the past, I was thinking of porting it to PDcurses, but since it worked this way, I abandoned that route. Anyway, this stdin situation is a complicated problem.

lhmouse commented 1 year ago

I don't think Ubuntu (or Mint) has UCRT toolchains at this moment.

At some point in the past, I was thinking of porting it to PDcurses, but since it worked this way, I abandoned that route. Anyway, this stdin situation is a complicated problem.

Some key combinations might not work in PDCurses, e.g. Ctrl-Shift-Delete (delete word before cursor) and Alt-Delete (delete selection, or current line in case of no selection). Some of them also do not work in SecureCRT, but mintty supports them very well.

okibcn commented 1 year ago

I´ve seen that getwch() or getwchar() from conio.h or wchar.h doesn´t work in windows. It is a wider issue as, for instance, micro editor, written in go, has the same problem in windows with UTF-8.

lhmouse commented 1 year ago

Some test results about UTF-8 inputs in UTF-8 consoles:

Console Type Mode Input Source Result
Legacy Normal (cmd) IME It is not possible to switch IME. Only ASCII characters can be entered.
Legacy Normal (cmd) Clipboard Chinese characters can be pasted but are misplaced.
Legacy Curses (nano) IME It is not possible to switch IME. Only ASCII characters can be entered.
Legacy Curses (nano) Clipboard Chinese characters can be pasted but are misplaced.
New Normal (cmd) IME There doesn't seem to be any issue so far.
New Normal (cmd) Clipboard There doesn't seem to be any issue so far.
New Curses (nano) IME The console window (conhost) crashes.
New Curses (nano) Clipboard The console window (conhost) crashes.
okibcn commented 1 year ago

UTF-8 works relatively fine when using PDCursesMod — the active development fork of PDCurses. The included demos look very promising. it can handle truecolor on screen and can use the windows clipboard. This is a screenshot of a UTF-8 text file viewer using PDCursesMod:

image

Nano can be built using PDCursesMod without any problem, however, it has the same problem displaying UTF-8 data. This is Nano using PDCursesMod opening the same sample text document:

image

So, maybe, the route to make nano UTF-8 ready in Windows is through PDCursesMod. Note I am using the same toolchain — Debian mingw-w64 package — in both cases, cross-building from Linux and using Windows Terminal for executing the binary. So, it is not a problem with mingw-w64. So, the problem is in ncurses or nano code, or in how they work together.

lhmouse commented 1 year ago

In order to get UTF-8 support I think you will have to link against UCRT.

okibcn commented 1 year ago

Nope, I did it using the very same toolchain cross-building to Windows under Linux, I got UTF'8 working using PDCursesMod. Just see the improvements compared to the last pic above using the same test txt file:

image

I also made the mouse work, and window resizing, more or less, works. Now I am working on integrating the windows clipboard to easily copy and paste to-from other apps. It is clear that the way forward for a successful windows port is by using PDCursesMod.

lhmouse commented 1 year ago

That sounds really great! Does Alt-Delete (delete current line or selection) work for you?

okibcn commented 1 year ago

That depends on the terminal. I don´t have problems using Windows Terminal. Alt+Bksp deletes word by word as default using space as separator. I can program delete line in .nanorc. Actually I have that function assigned to CTRL+D. Just add this:

bind ^D zap main        # CTRL-D - Delete line