Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling issues with llvm-mingw due to strptime.c #1650

Open
Anutrix opened this issue Sep 4, 2022 · 9 comments
Open

Compiling issues with llvm-mingw due to strptime.c #1650

Anutrix opened this issue Sep 4, 2022 · 9 comments
Labels
bug CI Entries related to continuous integration infrastructure (historically also recipes like Makefiles) cross-builds portability We want NUT to build and run everywhere possible Windows

Comments

@Anutrix
Copy link

Anutrix commented Sep 4, 2022

I tried compiling on WSL2 using llvm-mingw project.

Build failed with following error on make:

...
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../include -I../include -isystem /usr/local/include -g -O2 -Wno-reserved-identifier -Wno-unknown-warning-option -std=gnu99 -Wno-system-headers -Wall -Wextra -Wsign-compare -pedantic -Wno-error -MT strptime.lo -MD -MP -MF .deps/strptime.Tpo -c strptime.c  -fPIC -DPIC -o .libs/strptime.o
strptime.c:59:25: error: expected ';' before 'uint64_t'
   59 | typedef unsigned __int64 uint64_t;
      |                         ^~~~~~~~~
      |                         ;
strptime.c:59:1: warning: useless type name in empty declaration
   59 | typedef unsigned __int64 uint64_t;
      | ^~~~~~~
strptime.c: In function 'strptime':
strptime.c:389:25: warning: implicit declaration of function '_tzset'; did you mean 'tzset'? [-Wimplicit-function-declaration]
  389 |                         _tzset();
      |                         ^~~~~~
      |                         tzset
At top level:
cc1: note: unrecognized command-line option '-Wno-unknown-warning-option' may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option '-Wno-reserved-identifier' may have been intended to silence earlier diagnostics
make[2]: *** [Makefile:603: strptime.lo] Error 1
...

I could make it finish without crashing with following changes:

diff --git a/common/strptime.c b/common/strptime.c
index 1672ded8a..5adb81ebb 100644
--- a/common/strptime.c
+++ b/common/strptime.c
@@ -56,7 +56,7 @@ __weak_alias(strptime,_strptime)
 */
 typedef unsigned char u_char;
 typedef unsigned int uint;
-typedef unsigned __int64 uint64_t;
+// typedef unsigned __int64 uint64_t;
 
 #define	_ctloc(x)		(_CurrentTimeLocale->x)
 
@@ -386,7 +386,7 @@ recurse:
 			continue;
 
 		case 'Z':
-			_tzset();
+			tzset();
 			if (strncasecmp((const char *)bp, gmt, 3) == 0
           || strncasecmp((const char *)bp, utc, 3) == 0) {
 				tm->tm_isdst = 0;

From what I found(brotli, harfbuzz, icu4c, openxr(Khronos Group), vulkan(Khronos Group)), uint64_t needs to be declared only if Visual Studio C++ compiler older than version 1600(Visual Studio 2010) is used, so real fix is:

#if defined(_MSC_VER) && (_MSC_VER < 1600)
    typedef signed   __int8  int8_t;
    typedef unsigned __int8  uint8_t;
    typedef signed   __int16 int16_t;
    typedef unsigned __int16 uint16_t;
    typedef signed   __int32 int32_t;
    typedef unsigned __int32 uint32_t;
    typedef signed   __int64 int64_t;
    typedef unsigned __int64 uint64_t;
#else
    #include <stdint.h>
#endif

I haven't made any PR because I can't test networkupstools/nut well enough. I'm new to it.

I'm not sure about _tzset though. Not fixing it crashed build process with

/usr/bin/ld: ./.libs/libupsclient.so: undefined reference to `_tzset'
@Anutrix
Copy link
Author

Anutrix commented Sep 4, 2022

Also, dumb question, how to run/use/test it after make is done. Where are binaries built if any?

@jimklimov
Copy link
Member

jimklimov commented Sep 4, 2022 via email

@jimklimov
Copy link
Member

For tests, make check-NIT should do it. Maybe needs --enable-NIT or some such in configure script.

@jimklimov
Copy link
Member

jimklimov commented Sep 5, 2022

Also, as for "where are the binaries" - usually in same directories as sources if you build in-tree, or dedicated directories in similar tree structure under the build area if you build out-of-tree. With libtool involved, the binaries in the "same dir as source" (e.g. in drivers/) would be LT-wrappers - special EXEs in case of Windows, scripts in POSIX - which set up discovery of DLL/SO libraries you built against. Final binaries would be in .libs/ subdirectory nearby, but would require that you give them DLLs.

You might be better off with e.g. ./ci_build.sh && make DESTDIR="$(pwd)/.inst" install-win-bundle which should try to auto-configure all features it can enable with dependencies it finds on your system and build for them (and generate Makefiles in maintainer mode so editing any Makefile.am gets its resulting Makefile regenerated as part of later make without you manually calling configure script), and create an installation complete with bundled third-party DLLs in the .inst/ subdirectory of the workspace (you can specify another, e.g. /mnt/c/Temp/nut or some such). Then you can just run Windows binaries from there, the OS should prefer to find DLLs in same dirs as EXEs.
Finding the DLLs recursively to install them takes time, so if you iterate NUT code/recipes with same environment, later do just make DESTDIR=... install to only install NUT build products over the old files.

@jimklimov jimklimov changed the title Compiling issues due to strptime.c Compiling issues with llvm-mingw due to strptime.c Sep 5, 2022
@jimklimov
Copy link
Member

jimklimov commented Sep 5, 2022

Also note, when taming a new toolkit like you do now with llvm-mingw, expect to have more warnings and faults like this. You might have to run ci_build.sh or configure once, and spend a week with repetitive make -s to inch further and further through inconsistencies it finds. To get a broader view of what lies ahead, you can try make -k so it would not abort on first error it sees. Just to gauge if there's a dozen or a thousand warnings to fix.

In the latter case, there will probably be hundreds of instances of same "offense" so when you find once how to address it and replicate that solution, you drastically reduce the amount of errors remaining to fix. For example, you can see many pragmas to hush compiler range-check "faults" around code that does run-time sanity checks for platform-dependently sized integer variables (and/or ints that have a different signedness - and so different maximums - for use in different APIs) roughly like if (val > SIZE_MAX) { fatalx(...) }. First the range-checks appeared to allow responsible casting of sane values; then the pragmas appeared because compilers thought that int-du-jour (or long or short int in another platform) may never exceed INT_MAX :)

Given that Windows part of the codebase so far was built with variants of GCC, and that CLANG's static analysis and similar built-in goodies tends to complain more (and often rightfully), I'd expect this to be a busy adventure.

The NUT configure script options (and ci_buid.sh wrapper) offer a concept of varying "strictness levels" in what it considers the compiler to warn about or turns a blind eye to, as well as whether to require that warnings would be fatal. Current default is "medium" for GCC and CLANG presets, as many warnings were weeded out over an almost two-year effort. With a new toolkit I'd suggest to graduate "minimal" warnings (and outright "apparent" syntax errors like here - probably with some configure scripted detection of current build circumstances and capabilities) first, then the "medium".

The "hard" warnings are not yet solved for the main build scenarios either, see e.g. #1648 for a recent scoop.

@jimklimov
Copy link
Member

jimklimov commented Sep 5, 2022

If it helps a bit, it was not hard to set up for cross-build from Linux (WSL2) indeed:

:; cd /opt
:; wget https://github.com/mstorsjo/llvm-mingw/releases/download/20220802/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64.tar.xz
:; xzcat llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64.tar.xz | tar xf -

:; cd /usr/lib/ccache
:; (cd /opt/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64/bin && ls -1 *mingw*clang*) \
    | while read F ; do ln -s ../../bin/ccache "$F"-11 ; done

Then in NUT workspace (starting in a branch-off from current master) quickly hacked the use of clang for cross-build script:

diff --git a/scripts/Windows/build-mingw-nut.sh b/scripts/Windows/build-mingw-nut.sh
index 30fad9f36..190702e2e 100755
--- a/scripts/Windows/build-mingw-nut.sh
+++ b/scripts/Windows/build-mingw-nut.sh
@@ -87,16 +87,18 @@ if [ "$cmd" == "all64" ] || [ "$cmd" == "b64" ] || [ "$cmd" == "all32" ] || [ "$
        # but this version is very Debian specific!!!
        # FIXME: find something more generic
        BUILD_FLAG="--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE`"
-       export CC="$ARCH-gcc"
-       export CXX="$ARCH-g++"
-       export PATH="/usr/$ARCH/bin:$PATH"
+       export CC="$ARCH-clang"
+       export CXX="$ARCH-clang++"
+       export PATH="/opt/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64/bin:/usr/$ARCH/bin:$PATH"

        # Note: _WIN32_WINNT>=0x0600 is needed for inet_ntop in mingw headers
        # and the value 0xffff is anyway forced into some components at least
        # by netsnmp cflags.
-       export CFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/usr/$ARCH/include/ -D_WIN32_WINNT=0xffff"
-       export CXXFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/usr/$ARCH/include/ -D_WIN32_WINNT=0xffff"
-       export LDFLAGS+=" -L/usr/$ARCH/lib/"
+       export CFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/opt/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64/$ARCH/include/ -D_WIN32_WINNT=0xffff"
+       export CXXFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/opt/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64/$ARCH/include/ -D_WIN32_WINNT=0xffff"
+       #export CFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/usr/$ARCH/include/ -D_WIN32_WINNT=0xffff"
+       #export CXXFLAGS+=" -D_POSIX=1 -D_POSIX_C_SOURCE=200112L -I/usr/$ARCH/include/ -D_WIN32_WINNT=0xffff"
+       #export LDFLAGS+=" -L/opt/llvm-mingw-20220802-msvcrt-ubuntu-18.04-x86_64/$ARCH/lib/ -lmingw32 -L/usr/$ARCH/lib/ "
        # Note: installation prefix here is "/" and desired INSTALL_DIR
        # location is passed to `make install` as DESTDIR below.
        $CONFIGURE_SCRIPT $HOST_FLAG $BUILD_FLAG --prefix=/ \

(note that removing LDFLAGS or at least pointer to /usr/$ARCH/lib part seemed crucial towards passing "compiler executable" checks, otherwise it got lost in mingw objects)

And ran with it:

:; BUILD_TYPE=cross-windows-mingw ./ci_build.sh || ( cd scripts/Windows/nut_build && make -k -s)

There are several screenfulls of messages issued by compiler, most of them repetitive (same complaint, different instance).

Some warnings seem reasonable (e.g. argument-less function declarations without (void) explicitly), or #if HAVE_REALPATH sort of feature macros (which autotools only define if they are set, and do not define at all if not) without check for #ifdef (undef implicitly evaluates to 0, but is an error pedantically); others seem like a mismatch between what the configure script's detection assumed about the build environment (e.g. that it needed fallback inline localtime() vs. what the system headers actually serve - having same method, so declarations conflict) which needs some digging in config.log and hammering the test code or flags it tries to reliably work everywhere including the new toolkit. Some leave me puzzled OTOH, like error: 'fprintf' was marked unused but was used [-Werror,-Wused-but-marked-unused]. And quite a few different types of complaints are indeed about strptime.c fallback.

@jimklimov
Copy link
Member

For kicks, finally got around to try "standard-issue" pre-set environment "MSYS2 MinGW Clang x64" in the semi-native build environment; will follow up that thread in #1651 to keep things neatly aligned :)

@jimklimov
Copy link
Member

Quick update: making use of "MSYS2 MinGW Clang x64" was not a low-hanging fruit after all, so abandoning that effort on my side for now, to focus on other things. Discoveries, ideas and other details posted in #1651.

@jimklimov
Copy link
Member

Quick re-check with current master without hacks, just as... :

  • CC=clang CXX=clang++ ./ci_build.sh : configure fails to find stddef.h
  • CFLAGS="-I/usr/lib/clang/11.0.0/include -I/clang64/include" CC=clang CXX=clang++ ./ci_build.sh: configure tests complain about __attribute__ in system headers

As this was a short "what if?" session, throwing the towel again - assorted fixes for other platforms did not by chance do magic for this combo.

@jimklimov jimklimov added CI Entries related to continuous integration infrastructure (historically also recipes like Makefiles) portability We want NUT to build and run everywhere possible labels Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug CI Entries related to continuous integration infrastructure (historically also recipes like Makefiles) cross-builds portability We want NUT to build and run everywhere possible Windows
Projects
Status: Todo
Development

No branches or pull requests

2 participants