clasp-developers / clasp

clasp Common Lisp environment
https://clasp-developers.github.io/
2.57k stars 145 forks source link

Build failure on Linux (musl) #1428

Open echawk opened 1 year ago

echawk commented 1 year ago

Not entirely sure why the build is failing, since Linux CI is working. The build occurs in a git checkout, not from a release tarball.

I'm thinking that the build failure is musl specific, at least in regards to:

error: cannot assign to variable 'stdin' with const-qualified type 'FILE *const' (aka '_IO_FILE *const')

Build Env:

Build Script:

#!/bin/sh -e

export CC=clang
export CXX=clang++

sbcl --script koga \
    --reproducible-build \
    --broken-stdlib \
    --package-path="$1" \
    --bin-path=/usr/bin \
    --share-path=/usr/share/clasp/ \
    --lib-path=/usr/lib/clasp

ninja -C build
ninja -C build install

Build Log:

[376/543] Compiling ../src/gctools/exposeFunctions1.cc
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++17 -Wno-c++20-extensions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/gctools/mpsGarbageCollection.o.d -oboehmprecise/src/gctools/mpsGarbageCollection.o ../src/gctools/mpsGarbageCollection.cc
In file included from ../src/gctools/mpsGarbageCollection.cc:67:
../include/clasp/core/lispStream.h:60:48: error: unknown type name 'mode_t'; did you mean 'Code_S'?
int safe_open(const char *filename, int flags, clasp_mode_t mode);
                                               ^~~~~~~~~~~~
                                               Code_S
../include/clasp/core/lispStream.h:57:22: note: expanded from macro 'clasp_mode_t'
#define clasp_mode_t mode_t
                     ^
../include/clasp/gctools/pointer_tagging.h:65:9: note: 'Code_S' declared here
  class Code_S;
        ^
1 error generated.
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++17 -Wno-c++20-extensions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/gctools/snapshotSaveLoad.o.d -oboehmprecise/src/gctools/snapshotSaveLoad.o ../src/gctools/snapshotSaveLoad.cc
../src/gctools/snapshotSaveLoad.cc:2582:11: error: cannot assign to variable 'stdin' with const-qualified type 'FILE *const' (aka '_IO_FILE *const')
    stdin = freopen(NULL,"r",stdin);
    ~~~~~ ^
/usr/include/stdio.h:62:20: note: variable 'stdin' declared const here
extern FILE *const stdin;
~~~~~~~~~~~~~~~~~~~^~~~~
1 error generated.
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++17 -Wno-c++20-extensions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/gctools/gcFunctions.o.d -oboehmprecise/src/gctools/gcFunctions.o ../src/gctools/gcFunctions.cc
In file included from ../src/gctools/gcFunctions.cc:25:
In file included from ../include/clasp/core/bformat.h:31:
../include/clasp/core/lispStream.h:60:48: error: unknown type name 'mode_t'; did you mean 'Code_S'?
int safe_open(const char *filename, int flags, clasp_mode_t mode);
                                               ^~~~~~~~~~~~
                                               Code_S
../include/clasp/core/lispStream.h:57:22: note: expanded from macro 'clasp_mode_t'
#define clasp_mode_t mode_t
                     ^
../include/clasp/gctools/pointer_tagging.h:65:9: note: 'Code_S' declared here
  class Code_S;
        ^
1 error generated.
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++17 -Wno-c++20-extensions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/gctools/boehmGarbageCollection.o.d -oboehmprecise/src/gctools/boehmGarbageCollection.o ../src/gctools/boehmGarbageCollection.cc
In file included from ../src/gctools/boehmGarbageCollection.cc:31:
../include/clasp/core/lispStream.h:60:48: error: unknown type name 'mode_t'; did you mean 'Code_S'?
int safe_open(const char *filename, int flags, clasp_mode_t mode);
                                               ^~~~~~~~~~~~
                                               Code_S
../include/clasp/core/lispStream.h:57:22: note: expanded from macro 'clasp_mode_t'
#define clasp_mode_t mode_t
                     ^
../include/clasp/gctools/pointer_tagging.h:65:9: note: 'Code_S' declared here
  class Code_S;
        ^
1 error generated.
ninja: subcommands failed

Full Log: https://0x0.st/Hsew.okHoiK

yitzchak commented 1 year ago

First off, these probably won't fix your problem, but

  1. The environment variables CC and CXX have no effect on koga
  2. You probably need a -- after --script koga
  3. You can remove --broken-stdlib for llvm15
  4. bin-path and lib-path need a trailing slash
echawk commented 1 year ago

Removing --broken-stdlib fixes all of the erros I've encountered so far except for the stdin error.

yitzchak commented 1 year ago

Ok, apparently one is not supposed to use freopen to assign to stdin, so this is a bug.

echawk commented 1 year ago

Seems like the build gets a little farther before erroring out again, now it's upset about the use of NETDB_INTERNAL:

[394/543] Compiling ../src/llvmo/clbindLlvmExpose.cc
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++20 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/sockets/sockets.o.d -oboehmprecise/src/sockets/sockets.o ../src/sockets/sockets.cc
../src/sockets/sockets.cc:930:84: error: use of undeclared identifier 'NETDB_INTERNAL'
  _sym__PLUS_NETDB_INTERNAL_PLUS_->defconstant(core::Integer_O::create((gc::Fixnum)NETDB_INTERNAL));
                                                                                   ^
../src/sockets/sockets.cc:932:83: error: use of undeclared identifier 'NETDB_SUCCESS'
  _sym__PLUS_NETDB_SUCCESS_PLUS_->defconstant(core::Integer_O::create((gc::Fixnum)NETDB_SUCCESS));
                                                                                  ^
2 errors generated.
ninja: subcommand failed

Here's a little patch that gets past this error:

diff --git a/src/sockets/sockets.cc b/src/sockets/sockets.cc
index 684201f..346fa20 100644
--- a/src/sockets/sockets.cc
+++ b/src/sockets/sockets.cc
@@ -926,6 +926,10 @@ void initialize_sockets_globals() {
   SYMBOL_EXPORT_SC_(SocketsPkg, _PLUS_ENETUNREACH_PLUS_);
   _sym__PLUS_ENETUNREACH_PLUS_->defconstant(core::Integer_O::create((gc::Fixnum)ENETUNREACH));

+#ifndef __GLIBC__
+#define NETDB_INTERNAL -1
+#define NETDB_SUCCESS 0
+#endif
   SYMBOL_EXPORT_SC_(SocketsPkg, _PLUS_NETDB_INTERNAL_PLUS_);
   _sym__PLUS_NETDB_INTERNAL_PLUS_->defconstant(core::Integer_O::create((gc::Fixnum)NETDB_INTERNAL));
   SYMBOL_EXPORT_SC_(SocketsPkg, _PLUS_NETDB_SUCCESS_PLUS_);
echawk commented 1 year ago

This also looks like a musl error.

[411/543] Compiling ../src/asttooling/asttoolingPackage.cc
ninja: job failed: /usr/bin/clang++ -Iboehmprecise -Iboehmprecise/generated -O3 -g -fPIC -ffile-prefix-map=boehmprecise/generated=/usr/share/clasp/generated -ffile-prefix-map=boehmprecise/lib=/usr/lib/clasp -Wno-macro-redefined -Wno-deprecated-declarations -Wno-deprecated-register -Wno-expansion-to-defined -Wno-return-type-c-linkage -Wno-invalid-offsetof -Wno-#pragma-messages -Wno-inconsistent-missing-override -Wno-error=c++11-narrowing -Wno-c++11-narrowing -Wno-deprecated-enum-enum-conversion -Wno-deprecated-anon-enum-enum-conversion -std=c++20 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fno-stack-protector -stdlib=libstdc++ -I/usr/include -ffile-prefix-map=..=/usr/share/clasp -I.. -I../src/bdwgc -I../src/bdwgc/include -I../src/libatomic_ops/src -I../include -I../include/clasp/main -c -MD -MF boehmprecise/src/llvmo/link_intrinsics.o.d -oboehmprecise/src/llvmo/link_intrinsics.o ../src/llvmo/link_intrinsics.cc
../src/llvmo/link_intrinsics.cc:260:3: error: use of undeclared identifier 'va_start'
  va_start(va, len);
  ^
../src/llvmo/link_intrinsics.cc:263:40: error: 'T_O' does not refer to a value
    cons->rplaca(core::T_sp(va_arg(va, T_O*)));
                                       ^
../include/clasp/core/object.h:400:9: note: declared here
  class T_O : public RootClass {
        ^
../src/llvmo/link_intrinsics.cc:263:44: error: expected expression
    cons->rplaca(core::T_sp(va_arg(va, T_O*)));
                                           ^
../src/llvmo/link_intrinsics.cc:657:3: error: use of undeclared identifier 'va_start'
  va_start(args, nargs);
  ^
../src/llvmo/link_intrinsics.cc:660:56: error: 'T_O' does not refer to a value
    T_O* tagged_obj = ENSURE_VALID_OBJECT(va_arg(args, T_O*));
                                                       ^
../include/clasp/core/object.h:400:9: note: declared here
  class T_O : public RootClass {
        ^
../src/llvmo/link_intrinsics.cc:660:60: error: expected expression
    T_O* tagged_obj = ENSURE_VALID_OBJECT(va_arg(args, T_O*));
                                                           ^
../src/llvmo/link_intrinsics.cc:663:3: error: use of undeclared identifier 'va_end'
  va_end(args);
  ^
../src/llvmo/link_intrinsics.cc:1150:3: error: use of undeclared identifier 'va_start'
  va_start(argp, numCells);
  ^
../src/llvmo/link_intrinsics.cc:1154:52: error: expected '(' for function-style cast or type construction
    p = ENSURE_VALID_OBJECT(va_arg(argp, core::T_O *));
                                         ~~~~~~~~~ ^
../include/clasp/gctools/memoryManagement.h:1223:32: note: expanded from macro 'ENSURE_VALID_OBJECT'
#define ENSURE_VALID_OBJECT(x) x
                               ^
../src/llvmo/link_intrinsics.cc:1154:53: error: expected expression
    p = ENSURE_VALID_OBJECT(va_arg(argp, core::T_O *));
                                                    ^
../src/llvmo/link_intrinsics.cc:1158:3: error: use of undeclared identifier 'va_end'
  va_end(argp);
  ^
11 errors generated.
ninja: subcommand failed

The va_* errors are because the stdarg.h header file wasn't included.

diff --git a/src/llvmo/link_intrinsics.cc b/src/llvmo/link_intrinsics.cc
index b30845c..372dc0e 100644
--- a/src/llvmo/link_intrinsics.cc
+++ b/src/llvmo/link_intrinsics.cc
@@ -33,6 +33,7 @@ extern "C" {
 #endif
 #include <dlfcn.h>
 #include <typeinfo>
+#include <stdarg.h>
 #include <clasp/core/foundation.h>
 #include <clasp/core/common.h>
 #include <clasp/core/commandLineOptions.h>
diff --git a/src/core/foundation.cc b/src/core/foundation.cc
index f32f629..a51ad8d 100644
--- a/src/core/foundation.cc
+++ b/src/core/foundation.cc
@@ -32,6 +32,7 @@ THE SOFTWARE.

 #include <csignal>
 #include <dlfcn.h>
+#include <stdarg.h>

 #include <clasp/core/foundation.h>
 #include <clasp/core/object.h>

musl doesn't define RTLD_DL_SYMENT, or dladdr1.

diff --git a/src/core/foundation.cc b/src/core/foundation.cc
index f32f629..3d41ed0 100644
--- a/src/core/foundation.cc
+++ b/src/core/foundation.cc
@@ -1669,7 +1669,7 @@ void maybe_register_symbol_using_dladdr_ep(void *functionPointer, size_t size, c
         return; // This means it's a virtual method.
       global_pointerCount++;
       Dl_info info;
-#if defined(_TARGET_OS_LINUX)
+#if defined(_TARGET_OS_LINUX) && defined(__GLIBC__)
       const Elf64_Sym *extra_info;
       int ret = dladdr1(functionPointer, &info, (void **)&extra_info,
RTLD_DL_SYMENT);
 #else

musl also doesn't define pthread_yield(), so call sched_yield() instead:

diff --git a/src/core/hashTable.cc b/src/core/hashTable.cc
index 7751ff5..b6fddba 100644
--- a/src/core/hashTable.cc
+++ b/src/core/hashTable.cc
@@ -1005,7 +1005,11 @@ KeyValuePair* HashTable_O::rehash_upgrade_write_lock(bool expandTable, T_sp find
 #ifdef _TARGET_OS_DARWIN
     pthread_yield_np();
 #else
+#ifdef __GLIBC__
     pthread_yield();
+#else
+    sched_yield();
+#endif
 #endif
     goto tryAgain;
   } else {

I'm not sure if koga has a way of discerning between glibc & musl, so this patch is only for musl.

diff --git a/src/koga/units.lisp b/src/koga/units.lisp
index 808cebd..5145888 100644
--- a/src/koga/units.lisp
+++ b/src/koga/units.lisp
@@ -44,6 +44,7 @@
     (append-ldlibs configuration (run-program-capture (list llvm-config "--system-libs")))
     (append-ldlibs configuration (run-program-capture (list llvm-config "--libs")))
     #+freebsd (append-ldlibs configuration "-lexecinfo")
+    #+linux   (append-ldlibs configuration "-lexecinfo")
     (when (ld configuration)
       (append-ldflags configuration (format nil "-fuse-ld=~(~a~)" (ld
configuration))))
     (append-ldflags configuration "-pthread -fvisibility=default -rdynamic")))
echawk commented 1 year ago

Now I'm stuck - I'm not sure why this build error occurs:

https://0x0.st/Hs2S.ANOBfl

yitzchak commented 1 year ago

gitlab.common-lisp.net is finicky, If you already have a clone you can add --skip-sync to koga

echawk commented 1 year ago

@yitzchak Even when the dependencies are cached, the built still errors out. I'm pretty sure it's bdwgc - the mach_dep.c file is missing an include I think. Is there a way to build clasp with a bdwgc that is provided by the system?

yitzchak commented 1 year ago

It doesn't appear that musl has getcontext. Not sure what the solution is.

echawk commented 1 year ago

musl does have getcontext: https://git.musl-libc.org/cgit/musl/tree/include/ucontext.h#n17

echawk commented 1 year ago

I'm working on trying to fix musl support on my own fork here: https://github.com/ehawkvu/clasp/tree/musl

It has all of the fixes currently mentioned in this issue already, easily cherry-pickable.

echawk commented 1 year ago

Just had a successful build - I'll update this issue with the steps required.

Admittedly, there are a couply hacky parts of the build, since there is some inflexibility in parts of the build system, but nothing that isn't more than a 2 line diff.

echawk commented 1 year ago

Here is the build script that I am using:

(also available here)

#!/bin/sh

if kiss list musl; then
    sed '/#+freebsd/a#+linux (append-ldlibs configuration "-lexecinfo")' \
        src/koga/units.lisp > _
    mv -f _ src/koga/units.lisp
fi

sbcl --script koga \
    --reproducible-build \
    --package-path="$1" \
    --bin-path=/usr/bin/ \
    --share-path=/usr/share/clasp/ \
    --lib-path=/usr/lib/clasp/

# This is an admittedly hacky fix, but it does work.
sed "s/stdio.h>/stdio.h>\n#define NO_GETCONTEXT/" src/bdwgc/mach_dep.c > _
mv -f _ src/bdwgc/mach_dep.c

# This is done to respect the system linker.
sed "s/-fuse-ld=gold//" build/build.ninja > _
mv -f _ build/build.ninja

ninja -C build
ninja -C build install

Please ignore the parts that reference the kiss executable, those are for my linux distribution.

The only parts of the script that I'm not sure how to integrate into the build system, is the addition of the libexecinfo flags, as well as properly configuring bdwgc, which is still odd to me, since I am able to build it without issues (8.2.4).