libstdc++-related problems in log-tests
3 log-tests tests fail to build for me, all due to libstdc++-related problems.
cpp/call2 and cpp/class fail due to a missing symbol from libstdc++.
cpp/call2.bmk : TEST_MODE=MULTI_MODULE_OK
make[3]: Entering directory '/build/source/tests'
/build/source/tests/../bin/fbc -i /build/source/tests/../inc -lang fb -g -w 0 -m cpp/call2-fbc -c cpp/call2-fbc.bas -o cpp/call2-fbc.o
# Pass -m64 to get -m32 or -m64 as required
g++ -c -m64 -Wall -Wno-attributes -o cpp/call2-cpp.o cpp/call2-cpp.cpp
/build/source/tests/../bin/fbc -i /build/source/tests/../inc -g cpp/call2-fbc.o cpp/call2-cpp.o -x cpp/call2-fbc
/nix/store/f0rrfmf8kh5bsiql5bbq7m4h3xgihpnx-binutils-2.38/bin/ld: cpp/call2-cpp.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
make[3]: *** [bmk-make.mk:134: cpp/call2-fbc] Error 1
make[3]: Leaving directory '/build/source/tests'
cpp/call2.bmk : RESULT=FAILED
Seems like they're missing a post-processor command that they need to link to libstdc++ like in cpp/derived-fbc.bas.
https://github.com/freebasic/fbc/blob/42f4f6dfdaafdd5302a647152f16cda78e4ec904/tests/cpp/derived-fbc.bas#L5-L13
After fixing the above, cpp/call2, cpp/class and cpp/derived fail due to a missing linker search path to libstdc++.
cpp/derived.bmk : TEST_MODE=MULTI_MODULE_OK
make[3]: Entering directory '/build/source/tests'
/build/source/tests/../bin/fbc -i /build/source/tests/../inc -lang fb -g -w 0 -m cpp/derived-fbc -c cpp/derived-fbc.bas -o cpp/derived-fbc.o
# Pass -m64 to get -m32 or -m64 as required
g++ -c -m64 -Wall -Wno-attributes -o cpp/derived-cpp.o cpp/derived-cpp.cpp
/build/source/tests/../bin/fbc -i /build/source/tests/../inc -g cpp/derived-fbc.o cpp/derived-cpp.o -x cpp/derived-fbc
/nix/store/f0rrfmf8kh5bsiql5bbq7m4h3xgihpnx-binutils-2.38/bin/ld: cannot find -lstdc++: No such file or directory
make[3]: *** [bmk-make.mk:134: cpp/derived-fbc] Error 1
make[3]: Leaving directory '/build/source/tests'
cpp/derived.bmk : RESULT=FAILED
With Nix, this library is not in the default /usr/lib/libstdc++.so search path (or wherever this usually is, I haven't touched a normal distro in awhile) so ld can't locate it. Our GCC is wrapped to silently add -L/nix/store/<long-hash>-gcc-<version>-lib/lib so this works as expected. Here's where the GCC in the build environment locates its libgcc.a and libstdc++.so (and what else is in their directories):

If this is too weird of a use-case for you then I'll prolly do a custom patch ~ copy-pasting this line & changing it to libstdc++.so, which should have a similar effect afaict?
https://github.com/freebasic/fbc/blob/42f4f6dfdaafdd5302a647152f16cda78e4ec904/src/compiler/fbc.bas#L3787
@OPNA2608, does adding fbcAddLibPathFor( "libstdc++.so" ) work for you? If it does, then at least there is the solution.
It would be weird to require libstdc++ in general for all targets since for the most part, it's not needed except for code on the fringes that tries to interoperate with g++ code. It's nice when fbc works with g++, but I wouldn't say it's a major priority. We are not specifically targeting it.
There's a few of options:
- custom patch
- add a makefile / build-time option to bake in something different to the compiler
- enable the check & add the path always for unix-y based builds. i.e. invoke gcc to find it, and if it is not found no error but the search path is added. This is probably OK for *nix systems since spawning a process is cheap and fast. And it's not needed on windows / dos which is slow to spawn a sub-process.
Adding fbcAddLibPathFor( "libstdc++.so" ) works, I'm using it as a workaround right now and all tests pass with that.
Is there some standard-ish NixOS define or name that can be passed to fbc? like __NIX__ or HOST_NIX? I know, it could be anything, but if something is already commonly used, we could use that. A note going along with fbcAddLibPathFor( "libstdc++.so" ) will also help document if come across again some similar issue on some other build.
I'm not aware of a define specific to us, I can give you some envvars dumps from our build & interactive environments that might help for detecting us though.
nix-build-env.log nix-shell-env.log
But I also assume it's not a problem completely unique to us. The assumption that there's a global directory where libraries can be found in breaks with distros/systems that don't implement the Linux Filesystem Hierarchy Standard for design reasons, of which there are afew: NixOS, GNU Guix, GoboLinux are the ones I know of.
@OPNA2608, See [7985fdce84e080183b28f850f43eaf8d2495f22f], I believe this patch should cover the workarounds.
There wasn't anything that stood out to me in the Nix environment variables that definitively says to me that the target is Nix So I just went ahead and added fbcAddLibPathFor( "libstdc++.so" ) plus the #inclib dependencies in the test files. If it does give any trouble then we might consider makefile to optionally augment or disable it, but they default would be to just leave it in by default.
If this patch seems reasonable I will go ahead and close this issue.
Why does fbc.bas contain those #inclibs?
I think this is a bad idea. If the library is missing then the linker will throw an error. (And on Windows, IIRC FB includes gcc without C++ support.) A problem is that this patch is opinionated about which C++ library you want to link to. Often you have a choice of libc++ vs libstdc++, e.g. dependent on whether you're using g++ or clang++, and which is the standard one is also dependent on OS release e.g. FreeBSD 10 switched to libc++. Also, there's the option to use libsupc++ instead of libstdc++. If you really wanted to link to a C++ standard library it would probably to best to ask the C++ compiler, since the value of CXX will also affect it.
It just seems like opening a can of worms, and inconveniencing ordinary users in order to convenience people who run the FB test cases.
Oops.
https://github.com/freebasic/fbc/blob/7985fdce84e080183b28f850f43eaf8d2495f22f/src/compiler/fbc.bas#L3824
The #inclib s are a copy-paste-didn't-see-it-mistake, sorry. They were not intended to be there, only in some test files.
The only thing that was supposed to be added was to call gcc to query the path for the library. Does the query only seem acceptable? If the library isn't found then no path is added.
Sorry, I didn't read the patch very closely and failed to notice it was calling fbcAddLibPathFor rather than adding libraries. No wonder I was confused when discussing it yesterday.
My package isn't really engineered to handle building arbitrary commits due to the bootstrapping requirement, but I've tested [e9cfdd45be3a4f8959c0fff62ce648db0b583f0b] applied as a patch onto 1.09.0 and it successfully obsoletes the downstream workaround. From my side this LGTM.
@OPNA2608, perfect :) thank-you for testing.
We will consider this issue closed.