Skip to content

Commit

Permalink
Merge pull request #1611 from networkupstools/Windows-v2.8.0-1
Browse files Browse the repository at this point in the history
Merge Windows support branch based on NUT v2.8.x era code back to master
  • Loading branch information
jimklimov authored Sep 2, 2022
2 parents 532bada + ef527f6 commit 035ae79
Show file tree
Hide file tree
Showing 158 changed files with 11,780 additions and 422 deletions.
17 changes: 17 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Windows script files should be CR+LF always:
*.bat text eol=crlf

# Unix/Linux script files should be LF always:
*.sh text eol=lf
*.m4 text eol=lf
*.ac text eol=lf
*.am text eol=lf
*.hwdb text eol=lf

# Some files are binary always:
*.png bin
*.ico bin

# The rest are assumed text sources with platform-dependent EOL being okay,
# or we let Git guess otherwise:
* text=auto
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Makefile.in
/.ci*.log
/.ci*.log.*
.dirstamp
*.exe

# Python precompiled files
__pycache__/
Expand All @@ -57,6 +58,8 @@ __pycache__/
/NUT*.local.gz
/NUT*.p5i
/NUT*.depot
/*.msi
/*.MSI

# Official dist
/nut-*.tar.gz.md5
Expand Down
75 changes: 75 additions & 0 deletions INSTALL.nut
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,81 @@ using:
where +-u+ specifies the USB bus number and +-a+ specifies the USB device index.


[[Windows]]
Windows
~~~~~~~

Windows binary package
^^^^^^^^^^^^^^^^^^^^^^

[NOTE]
======
NUT binary package built for Windows platform was last issued for
a much older codebase (using NUT v2.6.5 as a baseline). While the current
state of the codebase you are looking at aims to refresh the effort of
delivering NUT on Windows, the aim at the moment is to help developers
build and modernize it after a decade of blissful slumber, and packages
are not being regularly produced yet. Functionality of such builds varies
a lot depending on build environment used. This effort is generally
tracked at https://github.com/orgs/networkupstools/projects/2/views/1
and help would be welcome!

It should currently be possible to build the codebase in native Windows
with MSYS2/MinGW and cross-building from Linux with mingw (preferably
in a Debian/Ubuntu container). Refer to
link:config-prereqs.txt[Prerequisites for building NUT on different OSes]
and link:scripts/Windows/README[scripts/Windows/README file] for respective
build environment preparation instructions.

Note that to use NUT for Windows, non-system dependency DLL files must
be located in same directory as each EXE file that uses them. This can be
accomplished for FOSS libraries (copying them from the build environment)
by calling `make install-win-bundle DESTDIR=/some/valid/location` easily.

Archives with binaries built by recent iterations of continuous integration
jobs should be available for exploration on the respective CI platforms.
======

*Information below may be currently obsolete, but the NUT project wishes
it to become actual and factual again :)*

NUT binary package built for Windows platform comes in a `.msi` file.

If you are using Windows 95, 98 or Me, you should install
link:http://www.microsoft.com/downloads/en/details.aspx?familyid=cebbacd8-c094-4255-b702-de3bb768148f&displaylang=en[Windows Installer 2.0]
from Microsoft site.

If you are using Windows 2000 or NT 4.0, you can
link:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4b6140f9-2d36-4977-8fa1-6f8a0f5dca8f&DisplayLang=en[download it here].

Newer Windows releases should include the Windows Installer natively.

Run `NUT-Installer.msi` and follow the wizard indications.

If you plan to use an UPS which is locally connected to an USB port, you have to install
link:https://sourceforge.net/projects/libusb-win32/files/[libUSB-win32]
on your system. Then you must install your device via libusb's "Inf Wizard".

NOTE: If you intend to build from source, relevant sources may be available at
https://github.com/mcuee/libusb-win32 and keep in mind that it is a variant of
libusb-0.1. Current NUT supports libusb-1.0 as well, and that project should
have Windows support out of the box (but it was not explored for NUT yet).

If you have selected default directory, all configuration files are located in
`C:\Program Files\NUT\ups\etc`

Building for Windows
^^^^^^^^^^^^^^^^^^^^

For suggestions about setting up the NUT build environment variants
for Windows, please see link:docs/config-prereqs.txt and/or
link:scripts/Windows/README files. Note this is rather experimental
at this point.


Runtime configuration
~~~~~~~~~~~~~~~~~~~~~

You are now ready to configure NUT, and start testing and using it.

You can jump directly to the
Expand Down
80 changes: 76 additions & 4 deletions Jenkinsfile-dynamatrix

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ ACLOCAL_AMFLAGS = -I m4
SUBDIRS = include common clients conf data docs drivers tools \
lib scripts server tests

bindir = @bindir@
sbindir = @sbindir@
driverexecdir = @driverexecdir@
cgiexecdir = @cgiexecdir@

# Automatically update the libtool script if it becomes out-of-date
# See https://www.gnu.org/software/libtool/manual/html_node/LT_005fINIT.html
LIBTOOL_DEPS = @LIBTOOL_DEPS@
Expand Down Expand Up @@ -340,6 +345,88 @@ package: dist
*) echo "Unsupported OS for 'make $@' (no recipe bound)" >&2; exit 1;; \
esac

if HAVE_WINDOWS
# Steam-roll over all executables/libs we have placed in DESTDIR and copy over
# any resolved dependencies from the cross-build (or native MSYS2) environment.
# Then hardlink libraries for sbin... (alternative: all bins in one dir)
# TOTHINK: Are there more dirs to consider? So far we cover bindir, sbindir and
# driverexecdir (e.g. some Linux distros place drivers to /lib/nut while tools
# and daemons are in /usr/bin and /usr/sbin), and cgiexecdir; anything else?..
# Note we hold existance of cgiexecdir as optional, but the name is expected to
# be defined. Other dirs are "just assumed" to exist (that we are not packaging
# some NUT build without drivers/tools/daemons). Subject to change if needed.
# Currently this is handled by a CHECKING... step that should fail if it hits
# anything.
install-win-bundle: all
@if test -z "$(DESTDIR)" ; then echo "ERROR: '$@': Bundle may only be installed to some DESTDIR prototype area'" >&2 ; exit 1; fi
$(MAKE) $(AM_MAKEFLAGS) DESTDIR='$(DESTDIR)' install
$(MAKE) $(AM_MAKEFLAGS) DESTDIR='$(DESTDIR)' install-win-bundle-thirdparty

install-win-bundle-thirdparty:
@if test -z "$(DESTDIR)" ; then echo "ERROR: '$@': Bundle may only be installed to some DESTDIR prototype area'" >&2 ; exit 1; fi
@echo "Searching which DLLs need to be bundled with NUT for Windows..." >&2
@if test -z "$$ARCH" ; then \
if test -n "$(target)" ; then \
ARCH='$(target)' \
; else \
if test -n "$(target_triplet)" ; then ARCH='$(target_triplet)' ; fi ; \
fi ; \
fi ; \
if test -n "$$ARCH" ; then export ARCH ; fi ; \
DESTDIR='$(DESTDIR)' ; export DESTDIR ; \
( cd '$(DESTDIR)' || exit ; \
DESTDIR="" '$(abs_top_srcdir)/scripts/Windows/dllldd.sh' dllldddir . \
| while read D ; do \
echo " DLL->bin $$D" 2>&1 ; \
cp -pf "$$D" './$(bindir)/' ; \
done ; \
) || exit ; \
( if test x"$(bindir)" = x"$(sbindir)" ; then exit 0 ; fi ; \
cd '$(DESTDIR)/$(sbindir)' || exit ; \
'$(abs_top_srcdir)/scripts/Windows/dllldd.sh' dllldddir . \
| while read D ; do \
echo " DLL->sbin $$D" 2>&1 ; \
ln -f '$(DESTDIR)/$(bindir)'/"`basename "$$D"`" ./ ; \
done ; \
) || exit ; \
( if test x"$(driverexecdir)" = x"$(bindir)" ; then exit 0 ; fi ; \
if test x"$(driverexecdir)" = x"$(sbindir)" ; then exit 0 ; fi ; \
cd '$(DESTDIR)/$(driverexecdir)' || exit ; \
'$(abs_top_srcdir)/scripts/Windows/dllldd.sh' dllldddir . \
| while read D ; do \
echo " DLL->drv $$D" 2>&1 ; \
ln -f '$(DESTDIR)/$(bindir)'/"`basename "$$D"`" ./ ; \
done ; \
) || exit ; \
( if test -z "$(cgiexecdir)" -o ! -d "$(DESTDIR)/$(cgiexecdir)" ; then exit 0 ; fi ; \
if test x"$(cgiexecdir)" = x"$(bindir)" ; then exit 0 ; fi ; \
if test x"$(cgiexecdir)" = x"$(sbindir)" ; then exit 0 ; fi ; \
if test x"$(driverexecdir)" = x"$(cgiexecdir)" ; then exit 0 ; fi ; \
cd '$(DESTDIR)/$(cgiexecdir)' || exit ; \
'$(abs_top_srcdir)/scripts/Windows/dllldd.sh' dllldddir . \
| while read D ; do \
echo " DLL->cgi $$D" 2>&1 ; \
ln -f '$(DESTDIR)/$(bindir)'/"`basename "$$D"`" ./ ; \
done ; \
) || exit
@echo "CHECKING if any executable files were installed to locations other than those covered by this recipe, so might not have needed DLLs bundled near them" >&2 ; \
relbindir="`echo './$(bindir)/' | sed 's,//*,/,g'`" ; \
relsbindir="`echo './$(sbindir)/' | sed 's,//*,/,g'`" ; \
reldriverexecdir="`echo './$(driverexecdir)/' | sed 's,//*,/,g'`" ; \
relcgiexecdir="`echo './$(cgiexecdir)/' | sed 's,//*,/,g'`" ; \
cd '$(DESTDIR)' || exit ; \
find . -type f | grep -Ei '\.(exe|dll)$$' \
| grep -vE "^($${relbindir}|$${relsbindir}|$${reldriverexecdir}|$${relcgiexecdir})" \
| ( RES=0 ; while IFS= read LINE ; do echo "$$LINE" ; RES=1; done; exit $$RES )

else
install-win-bundle:
@echo "SKIP: '$@' not enabled for current build configuration"

install-win-bundle-thirdparty:
@echo "SKIP: '$@' not enabled for current build configuration"
endif

print-MAINTAINERCLEANFILES print-REALCLEANFILES:
@echo $(MAINTAINERCLEANFILES)

Expand Down
15 changes: 15 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ https://github.com/networkupstools/nut/milestone/8
in the field -- the driver otherwise interpreted the situation as
`ups.status` being `OL OFF` and cut the power supply.

- NUT for Windows:
* Ability to build NUT for Windows, last tackled with a branch based on
NUT v2.6.5 a decade ago, has been revived with the 2.8.x era codebase [#5].
It is known that at this time some features are not complete, for more
details see https://github.com/orgs/networkupstools/projects/2/views/1
* Cross-builds of NUT for Windows using Linux and MinGW (and many custom
built dependency packages, as documented in `scripts/Windows/README`)
are now regularly tested on NUT CI farm with moderate integration via
custom build script `scripts/Windows/build-mingw-nut.sh` [#1489]
* Semi-native NUT for Windows builds with MSYS2/MinGW x64 environment are
now regularly tested on AppVeyor, with the same `ci_build.sh` script and
`Makefile` checks as used across the board for local developer builds,
Linux/illumos/FreeBSD/OpenBSD/... on dedicated NUT CI farm on Fosshost,
and MacOS on CircleCI [#1552]

- snmp-ups IETF MIB mapping updated for data points where negative readings
are invalid [#1558]

Expand Down
10 changes: 10 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ Changes from 2.8.0 to 2.8.1

- PLANNED: Keep track of any further API clean-up?

- Work on NUT for Windows branch led to situation-specific definitions of
what in POSIX code was all "file descriptors" (an `int` type). Now such
entities are named `TYPE_FD`, `TYPE_FD_SER` or `TYPE_FD_SOCK` with some
helper macros to name and determine "invalid" values (closed file, etc.)
Some of these changes happened in NUT header files, and at this time it
was not investigated whether the set of files delivered for third-party
code integration (e.g. C/C++ projects binding with `libnutclient` or
`libupsclient) is consistent or requires additional definitions/files.
If something gets broken by this, it is a bug to address in future [#1556]

- Further revision of public headers delivered by NUT was done, particularly
to address lack of common data types (`size_t`, `ssize_t`, `uint16_t`,
`time_t` etc.) in third-party client code that earlier sufficed to only
Expand Down
132 changes: 132 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#
# Network UPS Tools: AppVeyor CI build recipe: NUT for Windows with MSYS2/MinGW x64
#
# https://www.msys2.org/docs/ci/
# https://www.appveyor.com/docs/appveyor-yml/
# https://www.appveyor.com/docs/build-configuration/
# https://www.appveyor.com/docs/windows-images-software/

version: 2.8.0.{build}-{branch}

# base image
image: Visual Studio 2022

# branches to build
branches:
# whitelist
only:
- master
- /Windows/

platform: x64

# https://www.appveyor.com/docs/build-cache/
environment:
APPVEYOR_SAVE_CACHE_ON_ERROR: true
APPVEYOR_CACHE_ENTRY_ZIP_ARGS: -t7z -m0=lzma -mx=9

# https://github.com/networkupstools/nut/blob/Windows-v2.8.0-1/docs/config-prereqs.txt#L951
# Note: not using `time` in scripts currently - they did upset
# AppVeyor console log scanner with a /^sys.*/ match (apparently)
install:
- cmd: |
REM Do not give pacman cause for complaints:
C:\msys64\usr\bin\bash -lc "mkdir -p /var/cache/pacman/pkg; ls -la /"
- cmd: |
REM Core update (in case any core packages are outdated):
C:\msys64\usr\bin\bash -lc "date -u; pacman --noconfirm -Syuu"
- cmd: |
REM Normal update (same command again):
C:\msys64\usr\bin\bash -lc "date -u; pacman --noconfirm -Syuu"
- cmd: |
REM Prerequisites for NUT per https://github.com/networkupstools/nut/blob/Windows-v2.8.0-1/docs/config-prereqs.txt :
C:\msys64\usr\bin\bash -lc "date -u; pacman --noconfirm -S --needed base-devel mingw-w64-x86_64-toolchain autoconf-wrapper automake-wrapper libtool mingw-w64-x86_64-libltdl gcc ccache mingw-w64-x86_64-ccache git aspell aspell-en python mingw-w64-x86_64-python-pygments mingw-w64-x86_64-winpthreads-git mingw-w64-x86_64-libusb mingw-w64-x86_64-libusb-compat-git mingw-w64-x86_64-neon libneon-devel mingw-w64-x86_64-libmodbus-git mingw-w64-x86_64-libgd mingw-w64-x86_64-cppunit"
- cmd: |
REM Assorted stats after package processing:
C:\msys64\usr\bin\bash -lc "date -u; ls la / ; du -ksx / ; date -u; du -ks /var/cache/pacman/pkg; date -u"
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
C:\msys64\usr\bin\bash -lc 'PATH="/mingw64/bin:$PATH" ; export PATH ; pwd ; ccache -sv || echo "SKIP: Could not query ccache stats"'
build_script:
- cmd: |
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
C:\msys64\usr\bin\bash -lc 'date -u; PATH="/mingw64/bin:$PATH" CI_SKIP_CHECK=true ./ci_build.sh'
after_build:
- cmd: |
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
C:\msys64\usr\bin\bash -lc 'date -u; PATH="/mingw64/bin:$PATH" ; export PATH ; ccache -sv || ccache -s || echo "SKIP: Could not query ccache stats"'
test_script:
- cmd: |
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
C:\msys64\usr\bin\bash -lc 'date -u; PATH="/mingw64/bin:$PATH" make -s check'
after_test:
- cmd: |
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
REM Oh the joys of shell scripting with strings passed through CMD:
REM Note: currently Python installation path with MSYS is buggy [#1584]
C:\msys64\usr\bin\bash -lc 'date -u; if ! rm -rf ".inst" ; then echo "WARNING: Failed to clean away .inst" ; fi ; PATH="/mingw64/bin:$PATH" make -s install-win-bundle DESTDIR="`pwd`/.inst/NUT-for-Windows-x86_64-SNAPSHOT-%APPVEYOR_BUILD_VERSION%" ; ln -fs "NUT-for-Windows-x86_64-SNAPSHOT-%APPVEYOR_BUILD_VERSION%" ./.inst/NUT-for-Windows-x86_64-SNAPSHOT ; ( cd .inst/NUT-for-Windows-x86_64-SNAPSHOT ; find . -ls ; )'
cd .inst
7z a ../NUT-for-Windows-x86_64-SNAPSHOT-%APPVEYOR_BUILD_VERSION%.7z NUT*
- cmd: |
REM Preserve the current working directory:
set CHERE_INVOKING=yes
REM Start a 64 bit Mingw environment:
set MSYSTEM=MINGW64
C:\msys64\usr\bin\bash -lc 'date -u; PATH="/mingw64/bin:$PATH" ; export PATH ; ccache -sv || ccache -s || echo "SKIP: Could not query ccache stats"'
artifacts:
- path: 'NUT-for-Windows*.7z'
name: Bundle of binary files and FOSS dependencies of NUT for Windows

- path: config.log
name: config.log

# Example optional cache (depends on file change):
# - C:\msys64 -> appveyor.yml
cache:
- C:\msys64\home\appveyor\.ccache
- C:\msys64\home\appveyor\ccache # likely missing, no problem - but the name is reported in ccache status
- C:\msys64\var\cache\pacman\pkg

# Below we tried to stash binaries of MSYS2 environment
# so VM deployment is faster on subsequent builds
# (update/install "from scratch" costs about 3 min),
# but unstashing the archive takes comparable time
# and often leads to conflicts in pacman book-keeping,
# while creating/updating the archive costs ~10 min.
#- C:\msys64\var\lib\pacman
#- C:\msys64\var\lib
#- C:\msys64\mingw64
#- C:\msys64\mingw32
#- C:\msys64\ucrt64
#- C:\msys64\clang32
#- C:\msys64\clang64
#- C:\msys64\clangarm64
#- C:\msys64\usr
#- C:\msys64\bin
#- C:\msys64\etc
#- C:\msys64\*.*
#- C:\msys64\installerResources
Loading

0 comments on commit 035ae79

Please sign in to comment.