Unable to compile

Hello,
Total noob here. I’m writing some Julia code and I wanted to make sure I can compile it (I’ll need to ship it in the future and can’t guarantee a local install).
I can’t get the compiler to work. The latest error I managed to get was:
/tmp/ccxwbUfj.o: In function main': CPU.c:(.text.startup+0xd7): undefined reference to julia_main’
collect2: error: ld returned 1 exit status

Even though I am declaring julia_main.
Code (mostly copied from the manual):

CPU.jl:

module CPU
using LinearAlgebra
Base.@ccallable function julia_main()::Cint
    try
        real_main()
    catch
        Base.invokelatest(Base.display_error, Base.catch_stack())
        return 1
    end
    return 0
end

function real_main()
    A=rand(3,3);
    B=rand(3);
    C=A\B;
end

if abspath(PROGRAM_FILE) == @__FILE__
    real_main()
end
end

CPU.c:

#include <string.h>
#include <stdint.h>
#include "uv.h"
#include "julia.h"
JULIA_DEFINE_FAST_TLS()
int julia_main();
int main(int argc, char *argv[])
{
        uv_setup_args(argc, argv);
        libsupport_init();
        jl_options.image_file = JULIAC_PROGRAM_LIBNAME;
        julia_init(JL_IMAGE_JULIA_HOME);
        jl_set_ARGS(argc, argv);
        jl_set_global(jl_base_module, jl_symbol("PROGRAM_FILE"), (jl_value_t*)jl_cstr_to_string(argv[0]));
        jl_array_t *ARGS = (jl_array_t*)jl_get_global(jl_base_module, jl_symbol("ARGS"));
        jl_array_grow_end(ARGS, argc - 1);
        for (int i = 1; i < argc; i++) {
                jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]);
                jl_arrayset(ARGS, s, i - 1);
        }
        int ret = julia_main();
        jl_atexit_hook(ret);
        return ret;
}

custom_sysimage.jl:

Base.reinit_stdio()
Base.init_depot_path()
Base.init_load_path()
using LinearAlgebra
@eval Module() begin
    Base.include(@__MODULE__, "CPU.jl")
    for (pkgid, mod) in Base.loaded_modules
        if !(pkgid.name in ("Main", "Core", "Base"))
            eval(@__MODULE__, :(const $(Symbol(mod)) = $mod))
        end
    end
    for statement in readlines("app_precompile.jl")
        try
            Base.include_string(@__MODULE__, statement)
        catch
            # See julia issue #28808
            Core.println("failed to compile statement: $statement")
        end
    end
end # module
empty!(LOAD_PATH)
empty!(DEPOT_PATH)

What I run:
julia --startup-file=no --trace-compile=app_precompile.jl CPU.jl
→ app_precompile.jl gets written
julia --startup-file=no -J"/path/julia-1.5.3/lib/julia/sys.so" --output-o sys.o custom_sysimage.jl
→ sys.o gets written
gcc -shared -o sys.so -fPIC -Wl,--whole-archive sys.o -Wl,--no-whole-archive -L"/path/julia-1.5.3/lib" -ljulia
→ sys.so gets written

gcc -DJULIAC_PROGRAM_LIBNAME=\"sys.so\" -o CPU CPU.c sys.so -O2 -fPIE \
    -I'/path/julia-1.5.3/include/julia' \
    -L'/path/julia-1.5.3/lib' \
    -ljulia \
    -Wl,-rpath,'/path/julia-1.5.3/lib:$ORIGIN'

→ /tmp/ccxwbUfj.o: In function main': CPU.c:(.text.startup+0xd7): undefined reference to julia_main’
collect2: error: ld returned 1 exit status

I’d really appreciate some help! Thanks a lot!

1 Like

Hello Ribeiro and welcome to the Julia community!

It’s hard to help, since code that you show has nothing in common with typical julia code. What are you trying to achieve and what manual you referring to?

Also it is easier to read code if it is properly formatted and wrapped with ```

For example

println("Hello world")

Thanks, Skoffer.
The manual I mentioned is the PackageCompiler one (https://julialang.github.io/PackageCompiler.jl/dev/devdocs/binaries_part_2/)
The Julia part of the code is super simple:

using LinearAlgebra
A=rand(3,3);
B=rand(3);
C=A\B;

Everything else I posted was done to get it to compile. Am I doing it wrong?
Thanks a lot!

EDIT: thanks for teaching me how to quote code… couldn’t figure it out on my own.

@ianshmean any chance you can chime in?
I’m thinking I’m missing something on the gcc flags. I’m on CentOS8, gcc (GCC) 9.2.1 20191120 (Red Hat 9.2.1-2)
Thanks a lot!