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

Error when cross compiling using zig cc #289

Open
alliby opened this issue Jan 10, 2025 · 28 comments
Open

Error when cross compiling using zig cc #289

alliby opened this issue Jan 10, 2025 · 28 comments
Labels

Comments

@alliby
Copy link

alliby commented Jan 10, 2025

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
@alliby alliby added the bug label Jan 10, 2025
@stefanos82
Copy link
Contributor

stefanos82 commented Jan 10, 2025

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.

@mbekkomo
Copy link

I think it's your bindings fault, it uses clong instead of clonglong which obviously has fewer limits than clonglong.

@mbekkomo
Copy link

mbekkomo commented Jan 13, 2025

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

@stefanos82
Copy link
Contributor

I think it's your bindings fault, it uses clong instead of clonglong which obviously has fewer limits than clonglong.

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

@mbekkomo
Copy link

mbekkomo commented Jan 13, 2025

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.

@stefanos82
Copy link
Contributor

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?

@mbekkomo
Copy link

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?

gnu is just an ABI in the Zig triple target, so it isn't really matter.

@alliby
Copy link
Author

alliby commented Jan 14, 2025

the weirdest thing is how its still working on linux with no error using the same bindings

@alliby
Copy link
Author

alliby commented Jan 14, 2025

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"
    

@stefanos82
Copy link
Contributor

* 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"

@alliby
Copy link
Author

alliby commented Jan 14, 2025

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)
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@stefanos82
Copy link
Contributor

stefanos82 commented Jan 14, 2025

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"

@alliby
Copy link
Author

alliby commented Jan 14, 2025

Wow,that compile fine

@stefanos82
Copy link
Contributor

what output did it return?

@alliby
Copy link
Author

alliby commented Jan 14, 2025

using wine it return

4294967295

@stefanos82
Copy link
Contributor

Very nice; it's exactly as I have suspected. You were hard coding a number larger than your 32-bit version could handle.

@alliby
Copy link
Author

alliby commented Jan 14, 2025

yeah, but still does not compile for windows 64-bit while working fine for 64-bit linux

@stefanos82
Copy link
Contributor

What is the error message it throws?

@alliby
Copy link
Author

alliby commented Jan 14, 2025

so i'm confused about the default behavior of the compiler, does it allow overflow at compile time or not

@stefanos82
Copy link
Contributor

You mean nelua compiler or zig cc?

@alliby
Copy link
Author

alliby commented Jan 14, 2025

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

@alliby
Copy link
Author

alliby commented Jan 14, 2025

the nelua compiler, C compilers allow that

@stefanos82
Copy link
Contributor

stefanos82 commented Jan 14, 2025

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?

@alliby
Copy link
Author

alliby commented Jan 14, 2025

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.

@stefanos82
Copy link
Contributor

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?

@alliby
Copy link
Author

alliby commented Jan 14, 2025

seriously.
if you read the issue description i mention that the generated c code compiles fine with ZIg.

@stefanos82
Copy link
Contributor

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!

@Andre-LA
Copy link
Contributor

Andre-LA commented Jan 14, 2025

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:

local function get_cc_info(cc, cflags)

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 long is 4 bytes and 8 bytes 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants