avrdudes / avarice

AVaRICE is a program for interfacing the Atmel JTAG ICE to GDB to allow users to debug their embedded AVR target.
GNU General Public License v2.0
39 stars 12 forks source link

Add native Windows / MinGW compilability #96

Open maxgerhardt opened 1 year ago

maxgerhardt commented 1 year ago

Using a MSys2/MinGW64 environment with these packages installed

pacman -S git make mingw-w64-x86_64-toolchain mingw-w64-x86_64-autotools msys/autoconf-wrapper automake cmake mingw-w64-x86_64-binutils

and these build steps, compilation fails at these two types of errors:

In file included from devdescr.cc:29:
jtag.h:29:10: fatal error: termios.h: No such file or directory
   29 | #include <termios.h>
      |          ^~~~~~~~~~~
compilation terminated.
g++ -DHAVE_CONFIG_H -I.  -Wall -Wextra -DENABLE_TARGET_PROGRAMMING=0   -g -O2  -MT jtag3rw.o -MD -MP -MF .deps/jtag3rw.Tpo -c -o jtag3rw.o jtag3rw.cc
jtag2usb.cc:35:10: fatal error: sys/socket.h: No such file or directory
   35 | #include <sys/socket.h>
      |          ^~~~~~~~~~~~~~

It would be nice to not have to go through MSYS2/MSYS emulation, which does allow this program to build (see #95), but it's not as "native" as it could be.

There are forks who have adapted this to compile with MCSV (https://github.com/walx666/avarice/tree/main/src/msvc), but the termios.h implementation is all stubbed. And looking at this it appears to me it would be better to not try and search for an exact substitute for termios.h / sys/socket.h but compile-time switch in the real Windows implementation. I'm sure avrdudes/avrdude already does something like this.

dl8dtl commented 1 year ago

Well, AVaRICE has been written with the POSIX API straight from the beginning. That's not a big surprise, given that Atmel has always been supporting Windows natively through their various Studio versions, so the main pupose was to allow using the JTAGICE (and later, its successors) in unixoid environments.

I'm afraid, porting it natively to the Windows API basically requires a large rewrite. Given the rather small niche it covers (ARMs and other larger MCUs are well covered by OpenOCD), I wouldn't see anyone willing to spend much effort.

It should always be possible to use it under Cygwin, as that emulates the POSIX API.

maxgerhardt commented 1 year ago

I'm afraid, porting it natively to the Windows API basically requires a large rewrite.

I was hoping it would really only be the serial port and sys/socket.h that need a very slight rewrite, and looking at avrdude there already is an abstraction layer written by you with ser_win32.c and ser_posix.c giving a standardized struct serial_device object. I would have to look and experiment in the code whether that's mostly what it needs or whether there's other POSIX calls that require more rewriting.

Can we leave this issue open until some experimentation / PR has been done that checks these things out?

Atmel has always been supporting Windows natively

But not with an open-source debugging toolchain like GDB, they have their proprietary Atmel Studio. I'm specifically thinking about this.

dl8dtl commented 1 year ago

Sure, we can leave it open.

I suspect pthreads to also be a big roadblock on the path to WinAPI.

maxgerhardt commented 1 year ago

MinGW handles pthreads without problems, testing the source code from here

$ gcc -o pthread_test pthread_test.c -lpthread
pthread_test.c:7:1: warning: return type defaults to 'int' [-Wimplicit-int]
    7 | main()
      | ^~~~

Max@DESKTOP-KF7FNFU MINGW64 ~
$ ./pthread_test.exe
Thread 1
Thread 2
Thread 1 returns: 0
Thread 2 returns: 0
$ ldd pthread_test
        ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7fff5f8d0000)
        KERNEL32.DLL => /c/Windows/System32/KERNEL32.DLL (0x7fff5db10000)
        KERNELBASE.dll => /c/Windows/System32/KERNELBASE.dll (0x7fff5d230000)
        msvcrt.dll => /c/Windows/System32/msvcrt.dll (0x7fff5e820000)
        libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ffedc1b0000)
dl8dtl commented 1 year ago

Ok.

There's also a fork() in main.cc, albeit it's only needed for daemon mode.

mcuee commented 1 year ago

@maxgerhardt and @dl8dtl

BTW, I think the following step for the Windows is a hack and not so correct. I am not so sure how good it will work.

https://github.com/avrdudes/avarice/blob/main/.github/workflows/build.yml#L50

cp /mingw64/bin/libusb-1.0.dll avarice_installed/usr/bin/.

By right the binary should depend on the built libusb-1.0.dll for MSYS (/usr/bin/msys-usb-1.0.dll) and not the build for MinGW64.

But apparently there is a issue with libusb-compat-0.1 build under MSYS.

$ make install
Making install in scripts
make[1]: Entering directory '/c/work/avr/avarice/scripts'
make[2]: Entering directory '/c/work/avr/avarice/scripts'
 /usr/bin/mkdir -p '/usr/bin'
 /usr/bin/install -c start-avarice kill-avarice ice-gdb ice-insight '/usr/bin'
 /usr/bin/mkdir -p '/usr/share/avarice'
 /usr/bin/install -c -m 644 gdb-avarice-script '/usr/share/avarice'
make[2]: Leaving directory '/c/work/avr/avarice/scripts'
make[1]: Leaving directory '/c/work/avr/avarice/scripts'
Making install in src
make[1]: Entering directory '/c/work/avr/avarice/src'
make[2]: Entering directory '/c/work/avr/avarice/src'
 /usr/bin/mkdir -p '/usr/bin'
  /usr/bin/install -c avarice.exe '/usr/bin'
make[2]: Nothing to be done for 'install-data-am'.
make[2]: Leaving directory '/c/work/avr/avarice/src'
make[1]: Leaving directory '/c/work/avr/avarice/src'
Making install in doc
make[1]: Entering directory '/c/work/avr/avarice/doc'
make[2]: Entering directory '/c/work/avr/avarice/doc'
make[2]: Nothing to be done for 'install-exec-am'.
 /usr/bin/mkdir -p '/usr/share/man/man1'
 /usr/bin/install -c -m 644 ice-gdb.1 ice-insight.1 avarice.1 start-avarice.1 kill-avarice.1 '/usr/share/man/man1'
make[2]: Leaving directory '/c/work/avr/avarice/doc'
make[1]: Leaving directory '/c/work/avr/avarice/doc'
make[1]: Entering directory '/c/work/avr/avarice'
make[2]: Entering directory '/c/work/avr/avarice'
make[2]: Nothing to be done for 'install-exec-am'.
make[2]: Nothing to be done for 'install-data-am'.
make[2]: Leaving directory '/c/work/avr/avarice'
make[1]: Leaving directory '/c/work/avr/avarice'

$ ldd /usr/bin/avarice.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffba84b0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffba83a0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffba5ef0000)
        msys-hidapi-0.dll => /usr/bin/msys-hidapi-0.dll (0x522210000)
        msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
        msys-usb-0-1-4.dll => /usr/bin/msys-usb-0-1-4.dll (0x5705a0000)
        msys-gcc_s-seh-1.dll => /usr/bin/msys-gcc_s-seh-1.dll (0x5e8160000)
        msys-stdc++-6.dll => /usr/bin/msys-stdc++-6.dll (0x526840000)

$ ldd /usr/bin/msys-usb-0-1-4.dll
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffba84b0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffba83a0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffba5ef0000)
        msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffba6480000)
        msys-usb-0-1-4.dll => /usr/bin/msys-usb-0-1-4.dll (0x5705a0000)
        msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
        libusb-1.0.dll => not found

The following is another hack which may works better.

$ cp /usr/bin/msys-usb-1.0.dll /usr/bin/libusb-1.0.dll

$ ldd /usr/bin/msys-usb-0-1-4.dll
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffba84b0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffba83a0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffba5ef0000)
        msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffba6480000)
        msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
        libusb-1.0.dll => /usr/bin/libusb-1.0.dll (0x54f690000)
        advapi32.dll => /c/WINDOWS/System32/advapi32.dll (0x7ffba6920000)
        sechost.dll => /c/WINDOWS/System32/sechost.dll (0x7ffba7e60000)
        RPCRT4.dll => /c/WINDOWS/System32/RPCRT4.dll (0x7ffba7d20000)
        CRYPTBASE.DLL => /c/WINDOWS/SYSTEM32/CRYPTBASE.DLL (0x7ffba5110000)
        bcryptPrimitives.dll => /c/WINDOWS/System32/bcryptPrimitives.dll (0x7ffba58f0000)

$ ldd /usr/bin/avarice.exe
        ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffba84b0000)
        KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffba83a0000)
        KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffba5ef0000)
        msys-hidapi-0.dll => /usr/bin/msys-hidapi-0.dll (0x522210000)
        msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
        msys-usb-0-1-4.dll => /usr/bin/msys-usb-0-1-4.dll (0x5705a0000)
        msys-gcc_s-seh-1.dll => /usr/bin/msys-gcc_s-seh-1.dll (0x5e8160000)
        msys-stdc++-6.dll => /usr/bin/msys-stdc++-6.dll (0x526840000)
        libusb-1.0.dll => /usr/bin/libusb-1.0.dll (0x54f690000)