nelua-lang
nelua-lang copied to clipboard
Error when cross compiling using zig cc
i tried to cross compile nelua code from my linux machine to windows using zig cc and mingw
using both these commands
nelua test.nelua --cc="zig cc -target x86-windows"
nelua test.nelua --cc="x86_64-w64-mingw32-gcc"
for this code:
## pragma{nogc=true}
##[[
-- Compile GLAD
--------------------------------------------------
cinclude "glad/glad.h"
cfile "glad/src/glad.c"
cincdir "glad/include"
-- generate bindings for glad
local nldecl = require 'nelua.plugins.nldecl'
if not fs.isfile('glad/init.nelua') then
nldecl.generate_bindings_file{
include_dirs = { 'glad/include' },
output_file = 'glad/init.nelua',
parse_includes = {'glad/glad.h'},
}
end
--------------------------------------------------
]]
-- Include GLAD
require "glad"
give the same error for the generated glad bindings:
test.nelua:1:1: from: AST node Block
## pragma{nogc=true}
^~~~~~~~~~~~~~~~~~~~
init.nelua:1:1: from: AST node Block
global gladGLversionStruct: type <cimport,nodecl,ctypedef'gladGLversionStruct'> = @record{
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
init.nelua:7541:8: error: in variable 'INT_FAST16_MAX' declaration: constant value `9223372036854775807` for type `clong` is out of range, the minimum is `-2147483648` and maximum is `2147483647`
global INT_FAST16_MAX: clong <comptime> = 9223372036854775807
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a workaround for this is manually compiling the generated c code from nelua using the appropriate c compiler
nelua version:
λ ~ nelua -v
Nelua 0.2.0-dev
Build number: 1629
Git date: 2024-12-14 11:06:09 -0300
Git hash: a69a12d1e1e5ee0bfab299350e5d707ff7b2e744
Semantic version: 0.2.0-dev.1629+a69a12d1
Copyright (C) 2019-2025 Eduardo Bart (https://nelua.io/)
my environment
OS: Void x86_64
Kernel: Linux 6.12.6_3
CPU: 12th Gen Intel(R) Core(TM) i5-1245U (12) @ 4.40 GHz
~~Your pragma syntax is wrong; here's the correct one: ## pragmas.nogc = true~~
Actually, I have navigated in Nelua's internals some external libraries and have found this syntax. I have never seen this kind of syntax before.
I think it's your bindings fault, it uses clong instead of clonglong which obviously has fewer limits than clonglong.
Also, zig cc will still works as a C compiler for Nelua.
komo @ /tmp
└─╴🞂 nixs nixpkgs/nixos-unstable#{zig_0_13,nelua}
source: Error encountered while sourcing file '/nix/store/nwpfzclhxd3fnmszd173fjj2ngpba1gi-source/dotfiles/etc/lscolors.fish':
source: No such file or directory
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
komo @ /tmp
└─╴🞂 nelua -v
Nelua 0.2.0-dev
Build number: 0
Git date: 2024-12-14
Git hash: a69a12d1e1e5ee0bfab299350e5d707ff7b2e744
Semantic version: 0.2.0-dev.0+a69a12d1
Copyright (C) 2019-2025 Eduardo Bart (https://nelua.io/)
komo @ /tmp
└─╴🞂 zig version
0.13.0
komo @ /tmp
└─╴🞂 nelua -V -i "local a = 9223372036854775807; print(a)" --cc "zig cc"
generated /home/komo/.cache/nelua/eval_EePzfW6tFYR.c
zig cc -x c "/home/komo/.cache/nelua/eval_EePzfW6tFYR.c" -x none -Wno-unused-command-line-argument -fwrapv -fno-strict-aliasing -g -o "/home/komo/.cache/nelua/eval_EePzfW6tFYR"
/home/komo/.cache/nelua/eval_EePzfW6tFYR
9223372036854775807
I think it's your bindings fault, it uses
clonginstead ofclonglongwhich obviously has fewer limits thanclonglong.
Now that you have mentioned it, I've just noticed this nelua test.nelua --cc="zig cc -target x86-windows".
Can we presume it generated a 32-bit C version behind the scenes this way?
To verify it we can run it with --print-code flag:
nelua test.nelua --cc="zig cc -target x86-windows" --print-code
With Nelua command: nelua -i "local a = 9223372036854775807; print(a)" --cc "zig cc -target x86-windows" --print-code
The result
/* ------------------------------ DIRECTIVES -------------------------------- */
/* Disable some warnings that the generated code can trigger. */
#if defined(__clang__) && __clang_major__ >= 3
#pragma clang diagnostic ignored "-Wtype-limits"
#pragma clang diagnostic ignored "-Wwrite-strings"
#pragma clang diagnostic ignored "-Wunused"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wparentheses-equality"
#pragma clang diagnostic ignored "-Wtautological-compare"
#pragma clang diagnostic ignored "-Wmissing-braces"
#ifndef __cplusplus
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#pragma clang diagnostic error "-Wimplicit-function-declaration"
#pragma clang diagnostic error "-Wimplicit-int"
#else
#pragma clang diagnostic ignored "-Wnarrowing"
#pragma clang diagnostic ignored "-Wc99-designator"
#endif
#elif defined(__GNUC__) && __GNUC__ >= 5
#pragma GCC diagnostic ignored "-Wtype-limits"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-value"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wmissing-braces"
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
#pragma GCC diagnostic error "-Wimplicit-function-declaration"
#pragma GCC diagnostic error "-Wimplicit-int"
#else
#pragma GCC diagnostic ignored "-Wnarrowing"
#endif
#endif
#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
/* Macro used to perform compile-time checks. */
#if __STDC_VERSION__ >= 201112L
#define NELUA_STATIC_ASSERT _Static_assert
#elif __cplusplus >= 201103L
#define NELUA_STATIC_ASSERT static_assert
#else
#define NELUA_STATIC_ASSERT(x, y)
#endif
/* Macro used to get alignment of a type. */
#if __STDC_VERSION__ >= 201112L
#define NELUA_ALIGNOF _Alignof
#elif __cplusplus >= 201103L
#define NELUA_ALIGNOF alignof
#elif defined(__GNUC__)
#define NELUA_ALIGNOF __alignof__
#elif defined(_MSC_VER)
#define NELUA_ALIGNOF __alignof
#else
#define NELUA_ALIGNOF(x)
#endif
/* Checks if Nelua and C agrees on pointer size. */
NELUA_STATIC_ASSERT(sizeof(void*) == 4 && NELUA_ALIGNOF(void*) == 4, "Nelua and C disagree on pointer size or alignment");
/* Enable 64 bit offsets for stdio APIs. */
#if !defined(_FILE_OFFSET_BITS) && __SIZEOF_LONG__ >= 8
#define _FILE_OFFSET_BITS 64
#endif
/* Enable POSIX APIs in included headers. */
#if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) && !defined(_DEFAULT_SOURCE)
#if defined(__gnu_linux__)
#define _GNU_SOURCE
#else
#define _XOPEN_SOURCE 600
#endif
#endif
#include <stdint.h>
#include <stdio.h>
/* ------------------------------ DECLARATIONS ------------------------------ */
static int64_t eval_EePzfW6tFYR_a = 9223372036854775807LL;
static void nelua_print_1(int64_t a1);
static int nelua_main(int argc, char** argv);
/* ------------------------------ DEFINITIONS ------------------------------- */
void nelua_print_1(int64_t a1) {
fprintf(stdout, "%lli", (long long)a1);
fputs("\n", stdout);
fflush(stdout);
}
int nelua_main(int argc, char** argv) {
nelua_print_1(eval_EePzfW6tFYR_a);
return 0;
}
int main(int argc, char** argv) {
return nelua_main(argc, argv);
}
Note: Zig CC is basically just an LLVM Clang frontend embedded into Zig toolchain.
Another interesting thing is that the target is listed in Zig documentation as x86-windows-gnu, not as x86-windows; do you think it matters?
Another interesting thing is that the target is listed in Zig documentation as
x86-windows-gnu, not asx86-windows; do you think it matters?
gnu is just an ABI in the Zig triple target, so it isn't really matter.
the weirdest thing is how its still working on linux with no error using the same bindings
For example:
-
This works:
nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" -
This does not work:
nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86-windows"
* This works: ``` nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" ``` * This does not work: ``` nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86-windows" ```
Interesting...can you try
nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86_64-windows"
the same error
λ ~ nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86_64-windows"
eval_HzkndbMsuES:1:1: from: AST node Block
local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eval_HzkndbMsuES:1:7: error: in variable 'INT_FAST16_MAX' declaration: constant value `9223372036854775807` for type `clong` is out of range, the minimum is `-2147483648` and maximum is `2147483647`
local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Seems like it throws an error as expected: On a 32-bit computer, clong is of size 32-bit signed, thus the error
out of range, the minimum is `-2147483648` and maximum is `2147483647`
You are trying to assign it with a number larger than the variable type's size.
To verify what I am saying, can you try:
nelua -i "local INT_FAST16_MAX: culong <comptime> = (@culong)(-1); print(INT_FAST16_MAX)" --cc="zig cc -target x86-windows"
Wow,that compile fine
what output did it return?
using wine it return
4294967295
Very nice; it's exactly as I have suspected. You were hard coding a number larger than your 32-bit version could handle.
yeah, but still does not compile for windows 64-bit while working fine for 64-bit linux
What is the error message it throws?
so i'm confused about the default behavior of the compiler, does it allow overflow at compile time or not
You mean nelua compiler or zig cc?
the same error
λ ~ nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86_64-windows" eval_HzkndbMsuES:1:1: from: AST node Block local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eval_HzkndbMsuES:1:7: error: in variable 'INT_FAST16_MAX' declaration: constant value `9223372036854775807` for type `clong` is out of range, the minimum is `-2147483648` and maximum is `2147483647` local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the same as i mentioned earlier
the nelua compiler, C compilers allow that
I think you are tired, because what you are doing is rather funny.
You are HARDCODING a huge number of signed 64-bit, this part here local INT_FAST16_MAX: clong <comptime> = 9223372036854775807 and you expect it to run on 32-bit!
Obviously, as we both know 2 ^ 32 - 1 is 4294967295 for unsigned 32-bit integer, but if we are using a signed integer (the case of clong that fallbacks to 31-bit signed integer), then we get -2147483648 as minimum and 2147483647 as maximum.
Do you understand now where's the issue?
Yes i understand the issue correctly. you can try to assign this big number to an integer in C and it would compile with some overflow warnings, even for 32-bit version.
But that not the main problem here. i'm just using the bindings for glad using the nldecl plugin, i'm not HARDCODING it.
and it compiles for x86_64-linux and not for x86_64-windows which is weird.
About hardcoding, I was referring at this code:
λ ~ nelua -i "local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)" --cc="zig cc -target x86_64-windows"
eval_HzkndbMsuES:1:1: from: AST node Block
local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
eval_HzkndbMsuES:1:7: error: in variable 'INT_FAST16_MAX' declaration: constant value `9223372036854775807` for type `clong` is out of range, the minimum is `-2147483648` and maximum is `2147483647`
local INT_FAST16_MAX: clong <comptime> = 9223372036854775807; print(INT_FAST16_MAX)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here it's hardcoded, obviously.
About the x86_84-windows target issue, I guess it's a Zig issue?
seriously. if you read the issue description i mention that the generated c code compiles fine with ZIg.
and it compiles for x86_64-linux and not for x86_64-windows which is weird.
I thought it was Zig's responsibility to emit a 64-bit windows version target output, which fails for some reason as you say, so...excuse my confusion!
I'll need to look more in depth later, but I believe nelua is being misinformed by the compiler (in this situation of cross-compiling, since zig cc alone seems to work fine from what I read here).
When compiling, Nelua will invoke the C compiler (like gcc, zig cc, etc) and get all the information about the C environment (like the size of types), see get_cc_info:
https://github.com/edubart/nelua-lang/blob/a69a12d1e1e5ee0bfab299350e5d707ff7b2e744/lualib/nelua/ccompiler.lua#L202
I believe the compiler is not giving the right information to Nelua.
About working on Linux but not on Windows in this case:
Reading here on Cpp Reference (which also covers standard C), it's shown that long has different sizes between Windows and Unix:
| Type specifier | C standard | LP32 | ILP32 | LLP64 | LP64 |
|---|---|---|---|---|---|
| long | at least 32 | 32 | 32 | 32 | 64 |
[!NOTE] On the same page, on "Data models", it says that on 64-bit systems, Win64 API uses LLP64 while Unix uses LP64, where
longis4bytes and8bytes respectively.
Source: https://en.cppreference.com/w/c/language/arithmetic_types
TL;DR: I believe the cross-compilation to Windows on Zig CC is messing up the ccinfo data that Nelua uses.
Seems to be fixed with latest Zig. Can't reproduce on Gentoo Linux (host toolchain: x86_64-pc-linux-musl).
~ $ zig version
0.15.0-dev.919+044ccf413
~ $ nelua -v
Nelua 0.2.0-dev
Build number: 1635
Git date: 2025-06-24 16:22:08 -0300
Git hash: a58450563e2d2ec49bff499865c8b5cfdf6ff81a
Semantic version: 0.2.0-dev.1635+a5845056
Copyright (C) 2019-2025 Eduardo Bart (https://nelua.io/)
Steps to reproduce:
git clone https://github.com/nitrix/glad.gitnelua test.nelua --cc="zig cc -target x86-windows"
~/.cache/nelua $ file test.exe
test.exe: PE32 executable for MS Windows 6.00 (console), Intel i386, 7 sections
~/.cache/nelua $ ./test.exe
bash: ./test.exe: cannot execute binary file: Exec format error