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

Build fails on OpenBSD 7.2 #1111

Open
carmiker opened this issue Dec 11, 2022 · 11 comments
Open

Build fails on OpenBSD 7.2 #1111

carmiker opened this issue Dec 11, 2022 · 11 comments
Labels
bug Unexpected behavior / crashes; to be fixed ASAP! builds This affects the build process or release artifacts meta This isn't related to the tools directly: repo organization, maintainership...

Comments

@carmiker
Copy link

This seems potentially related to: #1091

This will fix the problem, but I think there may be a better way, and someone more familiar with the codebase may have a better solution:

diff --git a/Makefile b/Makefile
index d39906ba..18f01279 100644
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ CXXFLAGS      ?= -O3 -flto -DNDEBUG
 REALCFLAGS     := ${CFLAGS} ${WARNFLAGS} -std=gnu11 -I include \
                   -D_POSIX_C_SOURCE=200809L -D_ISOC11_SOURCE
 REALCXXFLAGS   := ${CXXFLAGS} ${WARNFLAGS} -std=c++17 -I include \
-                  -D_POSIX_C_SOURCE=200809L -fno-exceptions -fno-rtti
+                  -fno-exceptions -fno-rtti
 # Overridable LDFLAGS
 LDFLAGS                ?=
 # Non-overridable LDFLAGS

Full build output:

DEFS=-Dlr.type=ielr -Dparse.lac=full -Dparse.error=verbose -Dparse.error=detailed -Dapi.token.raw=true
src/link/object.c:672:14: warning: result of comparison of constant 1152921504606846975 with expression of type 'unsigned int' is always false [-Wtautological-constant-out-of-range-compare]
        if (nbFiles > SIZE_MAX / sizeof(*nodes))
            ~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
In file included from src/gfx/main.cpp:16:
In file included from /usr/include/c++/v1/fstream:188:
In file included from /usr/include/c++/v1/istream:163:
In file included from /usr/include/c++/v1/ostream:140:
In file included from /usr/include/c++/v1/locale:218:
/usr/include/c++/v1/__bsd_locale_fallbacks.h:122:17: error: use of undeclared identifier 'vasprintf'; did you mean 'vsprintf'?
    int __res = vasprintf(__s, __format, __va);
                ^
/usr/include/c++/v1/cstdio:124:9: note: 'vsprintf' declared here
using ::vsprintf _LIBCPP_USING_IF_EXISTS;
        ^
In file included from src/gfx/main.cpp:16:
In file included from /usr/include/c++/v1/fstream:188:
In file included from /usr/include/c++/v1/istream:163:
In file included from /usr/include/c++/v1/ostream:140:
In file included from /usr/include/c++/v1/locale:218:
/usr/include/c++/v1/__bsd_locale_fallbacks.h:122:27: error: cannot initialize a parameter of type 'char *' with an lvalue of type 'char **'
    int __res = vasprintf(__s, __format, __va);
                          ^~~
/usr/include/stdio.h:269:21: note: passing argument to parameter here
int      vsprintf(char *, const char *, __va_list);
                        ^
src/gfx/main.cpp:351:31: warning: result of comparison of constant 256 with expression of type 'std::array<unsigned char, 2>::value_type' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
                        if (options.baseTileIDs[0] >= 256) {
                            ~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~
src/gfx/main.cpp:367:31: warning: result of comparison of constant 256 with expression of type 'std::array<unsigned char, 2>::value_type' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
                        if (options.baseTileIDs[1] >= 256) {
                            ~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~
src/gfx/main.cpp:482:27: warning: result of comparison of constant 256 with expression of type 'uint8_t' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare]
                        if (options.nbPalettes > 256) {
                            ~~~~~~~~~~~~~~~~~~ ^ ~~~
3 warnings and 2 errors generated.
*** Error 1 in /home/rupert/src/rgbds (Makefile:169 'src/gfx/main.o': @c++ -O2 -pipe  -Wall -pedantic -std=c++17 -I include  -D_POSIX_C_SOURCE...)
@ISSOtm
Copy link
Member

ISSOtm commented Dec 11, 2022

This is a problem internal to the OpenBSD standard library, since it tries to use a function that it does not define. (To be precise, their implementation of a certain function in <locale> relies on vasprintf, but the header supposed to declare it doesn't because of _POSIX_C_SOURCE.)

I don't know what C++ library FreeBSD nor OpenBSD uses, so I can't troubleshoot this myself. Any links would be appreciated.

@Rangi42 Rangi42 added bug Unexpected behavior / crashes; to be fixed ASAP! meta This isn't related to the tools directly: repo organization, maintainership... labels Dec 12, 2022
@orbea
Copy link
Contributor

orbea commented Dec 12, 2022

If I understand correctly OpenBSD is hiding features that are not posix (vasprintf) when the posix define (-D_POSIX_C_SOURCE=200809L) is used. I am not sure if this is a bug or intentional behavior?

For the rgbds side perhaps the define should not be set except for platforms its required? Otherwise maybe avoiding non-posix features such as vasprintf?

There are a few other places this issue seems to have occurred before.

WebAssembly/wabt#1360
google/flatbuffers#6205

@ISSOtm
Copy link
Member

ISSOtm commented Dec 12, 2022

This does look similar to at least the latter issue, and also feels like a repeat of #789, where non-POSIX but C11 features were withheld, until an _ISO_C11_SOURCE escape hatch was agreed upon.
In this case, however, the problem is out of our hands, as we are not using e.g. vasprintf directly, but instead it's used in an implementation in some C++ standard library header.

Omitting _POSIX_C_SOURCE is not good IMO, as it means that C++ code may find itself unable to use some POSIX APIs; we currently do not do this, but if I was to rewrite RGBASM in C++, we'd want a C++ program that calls mmap.

Considering that fact, I am tempted to say the issue in on BSD and not us; however, discussion on #789 also started like that but became more nuanced. Thus, I think a bug report should be opened (by you or by us, whichever you think is better), and a solution agreed upon.

The solution (on their side) that I see right now, would be making __cplusplus trigger the same kind of behaviour that _ISO_C11_SOURCE currently does, and not hide features outside of C99.
But maybe there will be objections.

@bentley
Copy link
Contributor

bentley commented Dec 13, 2022

If I understand correctly OpenBSD is hiding features that are not posix (vasprintf) when the posix define (-D_POSIX_C_SOURCE=200809L) is used. I am not sure if this is a bug or intentional behavior?

That is intentional behavior. I believe it might required by the standard too.

However, this particular error is due to a bug in the OpenBSD headers. It should not be worked around in RGBDS.

@ISSOtm
Copy link
Member

ISSOtm commented Dec 13, 2022

That is intentional behavior. I believe it might required by the standard too.

Well, we had the same argument in #789: we want POSIX APIs and C11 ones, when the POSIX standard more or less says "the following APIs shall be provided, and nothing else". Here, we want POSIX APIs and C++ ones... but the C++ implementation relies on some non-POSIX APIs, which sounds like a clash between user-space and library-space? Augh.

However, this particular error is due to a bug in the OpenBSD headers. It should not be worked around in RGBDS.

If I may, what kind of fix is planned?

@bentley
Copy link
Contributor

bentley commented Dec 13, 2022

Well, we had the same argument in #789: we want POSIX APIs and C11 ones, when the POSIX standard more or less says "the following APIs shall be provided, and nothing else".

Yes, exposing POSIX and C11 APIs at the same time is inherently contradictory. The correct thing for RGBDS to do in that situation is to declare the needed C11 prototypes and symbols manually. The implementation (i.e., the operating system) does not have that option except by willfully flouting the standard.

Here, we want POSIX APIs and C++ ones... but the C++ implementation relies on some non-POSIX APIs, which sounds like a clash between user-space and library-space?

As I said, this is a bug in the headers (which are part of LLVM’s libc++—OpenBSD happens to expose it because the error is in a codepath only taken by systems that omit xlocale, which is nonstandard). It will affect everything that includes iostream after declaring _POSIX_C_SOURCE. So obviously the best solution is to fix the headers. In the meantime, OpenBSD users can work around it by unsetting _POSIX_C_SOURCE. RGBDS has the option to put in some sort of workaround too, but doing that seems kind of silly.

If I may, what kind of fix is planned?

There’s a patch floating around. I’ll do what I can to get it committed.

@ISSOtm
Copy link
Member

ISSOtm commented Dec 13, 2022

Yes, exposing POSIX and C11 APIs at the same time is inherently contradictory.

That's a stance I could never fully understand: extensions to the standards exist, so why couldn't the C11 features be treated as an extension to the POSIX standard?

The correct thing for RGBDS to do in that situation is to declare the needed C11 prototypes and symbols manually.

That seems incorrect, as declaring functions ourselves implies that suitable symbols will exist at link time, but the actual implementation may decide instead to have another link name and to alias it via a macro or another mechanism. (I have things like this in mind, for example.)

@bentley
Copy link
Contributor

bentley commented Dec 13, 2022

To reply to a comment from the old thread:

I'm not aware of any C11 behavior conflicting with POSIX-mandated C99 behavior, and so believe that C11 + POSIX 2008 is a valid combination.

I’m aware of a conflicting behavior. Here is a C program:

#include <assert.h>
int
main()
{
    int static_assert;
    return 0;
}

static_assert is not a reserved identifier in C99, which means this is a perfectly conforming C99 (and POSIX) program, though not a conforming C11 program. A conforming C99 compiler must be able to successfully build this program; the standard prohibits the implementation from declaring any symbol that would change the behavior of a C99 program, including this one. An assert.h that exposed static_assert to any __STDC_VERSION__ prior to 201112 would thus violate an explicit requirement of ISO C99. That in turn would violate POSIX.

Compilers happily expose most things by default, or allow you to request them by declaring a nonstandard symbol in the namespace reserved to the implementation, because understandably most people don’t know or care about the finer details of C revisions. But if you explicitly request the behavior of a formal standard by defining the symbol specifically provided for the purpose, the compiler expects that you want that standard, and properly exposes only what that standard provides.

That's a stance I could never fully understand: extensions to the standards exist, so why couldn't the C11 features be treated as an extension to the POSIX standard?

Because they would clobber the namespace reserved to users, and that’s expressly prohibited. Of course, all bets are off if the implementation chooses to come up with an option like _ISO_C11_SOURCE, but other implementations can’t reasonably be expected to provide such a thing.

That seems incorrect, as declaring functions ourselves implies that suitable symbols will exist at link time

Yes, I suppose you would have to provide your own function implementations as well. Still, though, you could #define static_assert _Static_assert and get what you intend.

freebsd-git pushed a commit to freebsd/freebsd-ports that referenced this issue Mar 28, 2023
- yank _POSIX_C_SOURCE because it breaks the build

See also:	gbdev/rgbds#1091
		gbdev/rgbds#1111
Reported by:	danfe, gerald
@Rangi42 Rangi42 added the builds This affects the build process or release artifacts label Dec 8, 2023
@Rangi42
Copy link
Contributor

Rangi42 commented Mar 22, 2024

Do we even still need -D_POSIX_C_SOURCE=200809L? All the programs are now fully in C++, and apparently g++ provides POSIX APIs without this flag. If it's repeatedly caused problems on BSD and isn't needed for Linux, then go ahead and remove it?

@ISSOtm
Copy link
Member

ISSOtm commented Mar 24, 2024

A further comment in that thread notes that this is only an implementation detail of libstdc++, whose C++ headers define _GNU_SOURCE.

I'm not sure that's portable to other C++ libraries?

@Rangi42
Copy link
Contributor

Rangi42 commented Mar 24, 2024

If it's portable enough to build on Windows, macOS, Ubuntu/Mint/Elementary/etc, Arch/Manjaro/etc, and even OpenBSD/FreeBSD, I'd say that's fine. Worth trying out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected behavior / crashes; to be fixed ASAP! builds This affects the build process or release artifacts meta This isn't related to the tools directly: repo organization, maintainership...
Projects
None yet
Development

No branches or pull requests

5 participants