Skip to content

Build fail on musl #36

Open
Open

Description

@ProkopRandacek

Hello :D

The compile fails when building under musl libc:

ninja: job failed: clang main/main_driver.c -g -march=haswell -I common -Wall -Werror -Wno-unused -Wno-deprecated -DMI_SKIP_COLLECT_ON_EXIT -DCUIK_ALLOW_THREADS -I mimalloc/include -DTB_USE_MIMALLOC -DCUIK_USE_MIMALLOC -DCUIK_USE_CUIK -O2 -DNDEBUG -DLOG_SUPPRESS -D_GNU_SOURCE -I libCuik/include -I tb/include -DCUIK_USE_TB -MD -MF bin/objs/main_driver.o.d -c -o bin/objs/main_driver.o
In file included from main/main_driver.c:16:
main/spall_perf.h:67:14: error: incompatible pointer to integer conversion initializing 'uint32_t' (aka 'unsigned int') with an expression of type 'pthread_t' (aka 'struct __pthread *') [-Wint-conversion]
   67 |     uint32_t tid = pthread_self();
      |              ^     ~~~~~~~~~~~~~~
main/spall_perf.h:79:14: error: incompatible pointer to integer conversion initializing 'uint32_t' (aka 'unsigned int') with an expression of type 'pthread_t' (aka 'struct __pthread *') [-Wint-conversion]
   79 |     uint32_t tid = pthread_self();
      |              ^     ~~~~~~~~~~~~~~

pthread_self does not return uint32_t but pthread_t which internally is a pointer so i'm concerned with the use of 32bit value on 64bit platforms.

I wrote a naive little patch to fix this:

diff --git a/build.lua b/build.lua
index 8e395dc9..e9c85c28 100644
--- a/build.lua
+++ b/build.lua
@@ -63,7 +63,7 @@ for i = 1, #arg do
 end
 
 local ldflags = ""
-local cflags = " -g -march=haswell -I common -Wall -Werror -Wno-unused -Wno-deprecated -DMI_SKIP_COLLECT_ON_EXIT -DCUIK_ALLOW_THREADS -I mimalloc/include"
+local cflags = " -g -march=haswell -I common -Wall -Werror -Wno-unused -Wno-deprecated -DMI_SKIP_COLLECT_ON_EXIT -DCUIK_ALLOW_THREADS -I mimalloc/include -fdiagnostics-color=always"
 
 if options.asan then
 	cflags = cflags.." -fsanitize=address"
diff --git a/main/spall.h b/main/spall.h
index 724cb4fd..6b37e57d 100644
--- a/main/spall.h
+++ b/main/spall.h
@@ -36,6 +36,7 @@ TODO: Optional Helper APIs:
 #include <stdio.h>
 #include <string.h>
 #include <stdbool.h>
+#include <pthread.h>
 
 #define SPALL_FN static inline SPALL_NOINSTRUMENT
 
@@ -67,9 +68,9 @@ typedef struct SpallBeginEvent {
     uint8_t type; // = SpallEventType_Begin
     uint8_t category;
 
-    uint32_t pid;
-    uint32_t tid;
-    double   when;
+    uint32_t  pid;
+    pthread_t tid;
+    double    when;
 
     uint8_t name_length;
     uint8_t args_length;
@@ -82,10 +83,10 @@ typedef struct SpallBeginEventMax {
 } SpallBeginEventMax;
 
 typedef struct SpallEndEvent {
-    uint8_t  type; // = SpallEventType_End
-    uint32_t pid;
-    uint32_t tid;
-    double   when;
+    uint8_t   type; // = SpallEventType_End
+    uint32_t  pid;
+    pthread_t tid;
+    double    when;
 } SpallEndEvent;
 
 typedef struct SpallPadSkipEvent {
@@ -255,7 +256,7 @@ SPALL_FN size_t spall_build_header(void *buffer, size_t rem_size, double timesta
     header->must_be_0 = 0;
     return header_size;
 }
-SPALL_FN SPALL_FORCEINLINE size_t spall_build_begin(void *buffer, size_t rem_size, const char *name, signed long name_len, const char *args, signed long args_len, double when, uint32_t tid, uint32_t pid) {
+SPALL_FN SPALL_FORCEINLINE size_t spall_build_begin(void *buffer, size_t rem_size, const char *name, signed long name_len, const char *args, signed long args_len, double when, pthread_t tid, uint32_t pid) {
     SpallBeginEventMax *ev = (SpallBeginEventMax *)buffer;
     uint8_t trunc_name_len = (uint8_t)SPALL_MIN(name_len, 255); // will be interpreted as truncated in the app (?)
     uint8_t trunc_args_len = (uint8_t)SPALL_MIN(args_len, 255); // will be interpreted as truncated in the app (?)
@@ -277,7 +278,7 @@ SPALL_FN SPALL_FORCEINLINE size_t spall_build_begin(void *buffer, size_t rem_siz
 
     return ev_size;
 }
-SPALL_FN SPALL_FORCEINLINE size_t spall_build_end(void *buffer, size_t rem_size, double when, uint32_t tid, uint32_t pid) {
+SPALL_FN SPALL_FORCEINLINE size_t spall_build_end(void *buffer, size_t rem_size, double when, pthread_t tid, uint32_t pid) {
     size_t ev_size = sizeof(SpallEndEvent);
     if (ev_size > rem_size) {
         return 0;
@@ -352,7 +353,7 @@ SPALL_FN bool spall_flush(SpallProfile *ctx) {
     return true;
 }
 
-SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, const char *args, signed long args_len, double when, uint32_t tid, uint32_t pid) {
+SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, const char *args, signed long args_len, double when, pthread_t tid, uint32_t pid) {
 #ifdef SPALL_DEBUG
     if (!ctx) return false;
     if (!name) return false;
@@ -363,8 +364,8 @@ SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, Spall
     if (ctx->is_json) {
         char buf[1024];
         int buf_len = snprintf(buf, sizeof(buf),
-                               "{\"ph\":\"B\",\"ts\":%f,\"pid\":%u,\"tid\":%u,\"name\":\"%.*s\",\"args\":\"%.*s\"},\n",
-                               when * ctx->timestamp_unit, pid, tid, (int)(uint8_t)name_len, name, (int)(uint8_t)args_len, args);
+                               "{\"ph\":\"B\",\"ts\":%f,\"pid\":%u,\"tid\":%zu,\"name\":\"%.*s\",\"args\":\"%.*s\"},\n",
+                               when * ctx->timestamp_unit, pid, (uintptr_t)tid, (int)(uint8_t)name_len, name, (int)(uint8_t)args_len, args);
         if (buf_len <= 0) return false;
         if (buf_len >= sizeof(buf)) return false;
         if (!spall__buffer_write(ctx, wb, buf, buf_len)) return false;
@@ -381,7 +382,7 @@ SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, Spall
     return true;
 }
 
-SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_ex(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, double when, uint32_t tid, uint32_t pid) {
+SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_ex(SpallProfile *ctx, SpallBuffer *wb, const char *name, signed long name_len, double when, pthread_t tid, uint32_t pid) {
     return spall_buffer_begin_args(ctx, wb, name, name_len, "", 0, when, tid, pid);
 }
 
@@ -389,7 +390,7 @@ SPALL_FN bool spall_buffer_begin(SpallProfile *ctx, SpallBuffer *wb, const char
     return spall_buffer_begin_args(ctx, wb, name, name_len, "", 0, when, 0, 0);
 }
 
-SPALL_FN SPALL_FORCEINLINE bool spall_buffer_end_ex(SpallProfile *ctx, SpallBuffer *wb, double when, uint32_t tid, uint32_t pid) {
+SPALL_FN SPALL_FORCEINLINE bool spall_buffer_end_ex(SpallProfile *ctx, SpallBuffer *wb, double when, pthread_t tid, uint32_t pid) {
 #ifdef SPALL_DEBUG
     if (!ctx) return false;
     if (!wb) return false;
@@ -398,8 +399,8 @@ SPALL_FN SPALL_FORCEINLINE bool spall_buffer_end_ex(SpallProfile *ctx, SpallBuff
     if (ctx->is_json) {
         char buf[512];
         int buf_len = snprintf(buf, sizeof(buf),
-                               "{\"ph\":\"E\",\"ts\":%f,\"pid\":%u,\"tid\":%u},\n",
-                               when * ctx->timestamp_unit, pid, tid);
+                               "{\"ph\":\"E\",\"ts\":%f,\"pid\":%u,\"tid\":%zu},\n",
+                               when * ctx->timestamp_unit, pid, (uintptr_t)tid);
         if (buf_len <= 0) return false;
         if (buf_len >= sizeof(buf)) return false;
         if (!spall__buffer_write(ctx, wb, buf, buf_len)) return false;
@@ -423,8 +424,8 @@ SPALL_FN SPALL_FORCEINLINE void spall__buffer_profile(SpallProfile *ctx, SpallBu
     // precon: ctx->write
     char temp_buffer_data[2048];
     SpallBuffer temp_buffer = { temp_buffer_data, sizeof(temp_buffer_data) };
-    if (!spall_buffer_begin_ex(ctx, &temp_buffer, name, name_len, spall_time_begin, (uint32_t)(uintptr_t)wb->data, 4222222222)) return;
-    if (!spall_buffer_end_ex(ctx, &temp_buffer, spall_time_end, (uint32_t)(uintptr_t)wb->data, 4222222222)) return;
+    if (!spall_buffer_begin_ex(ctx, &temp_buffer, name, name_len, spall_time_begin, (pthread_t)wb->data, 4222222222)) return;
+    if (!spall_buffer_end_ex(ctx, &temp_buffer, spall_time_end, (pthread_t)wb->data, 4222222222)) return;
     if (ctx->write) ctx->write(ctx, temp_buffer_data, temp_buffer.head);
 }
 
diff --git a/main/spall_perf.h b/main/spall_perf.h
index f9775b76..dd1d14c9 100644
--- a/main/spall_perf.h
+++ b/main/spall_perf.h
@@ -64,7 +64,7 @@ static void spallperf__begin_plot(void* user_data, uint64_t nanos, const char* l
     #if _WIN32
     uint32_t tid = GetCurrentThreadId();
     #else
-    uint32_t tid = pthread_self();
+    pthread_t tid = pthread_self();
     #endif
 
     spall_buffer_begin_args(&ctx, &muh_buffer, label, strlen(label), extra, strlen(extra), nanos, tid, 0);
@@ -76,7 +76,7 @@ static void spallperf__end_plot(void* user_data, uint64_t nanos) {
     #if _WIN32
     uint32_t tid = GetCurrentThreadId();
     #else
-    uint32_t tid = pthread_self();
+    pthread_t tid = pthread_self();
     #endif
 
     spall_buffer_end_ex(&ctx, &muh_buffer, nanos, tid, 0);

after this the project compiles but fails to link:

ninja: job failed: clang bin/objs/static.o bin/objs/main_driver.o bin/objs/common.o bin/objs/perf.o bin/objs/libcuik.o bin/objs/msvc.o bin/objs/gnu.o bin/objs/darwin.o bin/objs/libtb.o bin/objs/x64.o bin/objs/freestanding.o -g -lc -lm  -g -o bin/cuik
/usr/bin/ld: bin/objs/libtb.o: in function `tb_pass_codegen':
/home/prokop/source/Cuik/tb/src/tb.c:81:(.text+0x7e9): undefined reference to `tb_platform_valloc'
/usr/bin/ld: /home/prokop/source/Cuik/tb/src/tb.c:183:(.text+0x821): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_module_destroy':
/home/prokop/source/Cuik/tb/src/tb.c:263:(.text+0xa7a): undefined reference to `tb_platform_vfree'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_free_thread_resources':
/home/prokop/source/Cuik/tb/src/tb.c:529:(.text+0x19a5): undefined reference to `tb_platform_vfree'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_tls_allocate':
/home/prokop/source/Cuik/tb/src/tb.c:536:(.text+0x19e5): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_tls_steal':
/home/prokop/source/Cuik/tb/src/tb.c:549:(.text+0x1a35): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_coff_write_output':
/home/prokop/source/Cuik/tb/src/tb.c:536:(.text+0xaca6): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_jit_begin':
/home/prokop/source/Cuik/tb/src/jit.c:379:(.text+0x10357): undefined reference to `tb_platform_valloc'
/usr/bin/ld: /home/prokop/source/Cuik/tb/src/jit.c:386:(.text+0x1038b): undefined reference to `tb_platform_vprotect'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_jit_end':
/home/prokop/source/Cuik/tb/src/jit.c:392:(.text+0x103b5): undefined reference to `tb_platform_vfree'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_pass_mem2reg':
/home/prokop/source/Cuik/tb/src/tb.c:549:(.text+0x1349e): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_pass_sroa':
/home/prokop/source/Cuik/tb/src/tb.c:549:(.text+0x163a1): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/libtb.o: in function `tb_linker_create':
/home/prokop/source/Cuik/tb/src/linker/linker.c:66:(.text+0x1cc26): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/x64.o: in function `tb_cgemit_reserve':
/home/prokop/source/Cuik/tb/src/x64/../emitter.h:115:(.text+0x4ea6): undefined reference to `tb_platform_valloc'
/usr/bin/ld: /home/prokop/source/Cuik/tb/src/x64/../emitter.h:115:(.text+0x4f43): undefined reference to `tb_platform_valloc'
/usr/bin/ld: bin/objs/x64.o:/home/prokop/source/Cuik/tb/src/x64/../emitter.h:115: more undefined references to `tb_platform_valloc' follow
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: subcommand failed

At this point i gave up and I'm looking for help

Thanks :D

Activity

  1. flysand7 commented on May 23, 2025

    @flysand7
    Contributor

    I think the real issue isn't really musl, it's -Wall -Werror. Any sensible linux build script should not be doing this, because of two reasons:

    • Which warnings get generated and which aren't depends on the platform. More specifically, it depends on the linux distribution used, the compiler toolchain that is used to compile the code, their versions, as well as maybe some compiler settings.
    • Some warnings really don't make sense (especially in C++ with some versions of toolchains actually emitting buggy warnings).

    This problem is much, much worse in C++, I'm not sure about how bad it is in C.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions