Does legacy linker not support cli arguments, e.g. with roc dev --linker=legacy -- http://localhost:8080
Arg.list
returns an empty list?
It should do. Also Arg.list should at least return the name of the executable I think.
It does return the name, but with either roc dev or standalone executable args don't seem to get passed.
Legacy linker should have nothing to do with the args
Not sure what is eating the args in this case
I have definitely gotten all args from Args.list
maybe an issue specific to OS?
Weird. I'm on non-WSL Ubuntu ~20. I'll do some more testing tomorrow
Hmm....actually one idea. How does rust initialize args? I have never dug into that. Calling rust from c may not initialize the args. So could be a legacy linker issue due to that.
Could be an issue with this?
On glibc Linux systems, arguments are retrieved by placing a function in .init_array. glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension. This allows std::env::args to work even in a cdylib or staticlib, as it does on macOS and Windows.
From the rust docs: https://doc.rust-lang.org/std/env/fn.args.html
Coming back to this as the issue persists; I needed to create a CLI program that both utilizes Arg.list and roc-json library, and it looks like either way one of them gets broken whether or not you use --linker=legacy :smiling_face_with_tear:
What if you build the program first?
roc build --linker=legacy abc.roc
And then run it passing some args...
abc http://localhost:8080
Karakatiza said:
It does return the name, but with either roc dev or standalone executable args don't seem to get passed.
I see you've tried that... strange
@Luke Boswell does it make sense to work on my own implementation for JSON in Roc just to get things done? Or is there a specific syntax in roc-json code that could be refactored in a fork to avoid the bug it is blocked by without legacy linker?
Do you have an example you can share or are working on?
I wouldn't suggest writing a new implementation
I can try and re-produce on my linux machine later today, I'll have a look now on my mac
Don't have a share-able piece of code, but I simply would like to write a program that uses Arg.list and roc-json library at the same time
I'm working on an example now
Curiously,
This works
main =
args <- Arg.list |> Task.await
Stdout.line "Foo, first: $(Inspect.toStr args)"
But this crashes with panicked at 'called
Option::unwrap() on a
None value', crates/compiler/mono/src/ir.rs:6143:56
main = run |> Task.onErr \err -> Stdout.line "ERROR: $(Inspect.toStr err)"
run =
args <- Arg.list |> Task.await
Stdout.line "Foo, first: $(Inspect.toStr args)"
Does the first program work with --linker=legacy for you?
Yes,
$ roc run --linker=legacy test-arg-json.roc -- blah
Foo, first: ["/var/folders/48/39th9k0n0wdcj18k3yhm_g5c0000gn/T/.tmpfcsKBR/roc_app_binary", "blah"]
So I suspect there is a bug or something strange in the platform
Specifically with Arg
Found the issue
Have a workaround, just making an example with json for you
Oh well, it doesn't work on Ubuntu 22.04.4 LTS with --linker=legacy for me.
The output without --linker=legacy is as expected, Foo, first: ["/proc/self/fd/3", "blah"]
With - Foo, first: []
base-cli 0.8.1
So what I had to do was modify basic-cli and use a local copy. I changed the err type on the Arg.list
in the platform as follows.
## Gives a list of the program's command-line arguments.
# list : Task (List Str) * <-- err type BROKEN
# list : Task (List Str) a <-- err type BROKEN
# list : Task (List Str) _ <-- err type BROKEN
list : Task (List Str) []
list =
Effect.args
|> Effect.map Ok
|> InternalTask.fromEffect
The I used the following program with something like $ roc dev test-arg-json.roc -- "{"field":"value"}"
app "json"
packages {
cli: "../basic-cli/platform/main.roc",
# cli: "https://github.com/roc-lang/basic-cli/releases/download/0.8.1/x8URkvfyi9I0QhmVG98roKBUs_AZRkLFwFJVJ3942YA.tar.br",
json: "https://github.com/lukewilliamboswell/roc-json/releases/download/0.6.3/_2Dh4Eju2v_tFtZeMq8aZ9qw2outG04NbkmKpFhXS_4.tar.br",
}
imports [
cli.Stdout,
cli.Task.{ Task },
cli.Arg,
json.Core.{json},
]
provides [main] to cli
main = run |> Task.onErr \err -> Stdout.line "ERROR: $(Inspect.toStr err)"
run =
firstArgStr <- getArgs |> Task.await
result = parseJson firstArgStr
result
|> Inspect.toStr
|> Stdout.line
getArgs : Task Str _
getArgs =
args <-
Arg.list
|> Task.mapErr UnableToGetArgs
|> Task.await
when args is
[_, first, ..] -> Task.ok first
_ -> Task.err UnableToParseArgs
parseJson : Str -> Result { field: Str } _
parseJson = \str ->
Decode.fromBytes (Str.toUtf8 str) json
|> Result.mapErr \err ->
when err is
Leftover bytes -> Leftover (Str.fromUtf8 bytes)
_ -> JsonErr err
This doesn't parse the json correctly, I'm forgetting how to use roc-json, but it runs and gives an nice error (Err (Leftover (Ok "{field:value}")))
Are you able to test this please?
Could you reproduce my issue, though?
I don't see any difference with using --linker=legacy
, but I'm on my mac
Will have to test your example tomorrow
It seems my issue is a different one, and I do not have the expertise or capacity to debug the Rust implementation you mentioned a while ago in this thread
In case it helps here is the current implementation of Args.list
effect in the platform.
#[no_mangle]
pub extern "C" fn roc_fx_args() -> RocList<RocStr> {
// TODO: can we be more efficient about reusing the String's memory for RocStr?
std::env::args_os()
.map(|os_str| RocStr::from(os_str.to_string_lossy().borrow()))
.collect()
}
I would recommend writing a simple rust program and seeing what the behaviour is just using std::env::args_os()
to see if it is a roc issue or something else.
Mac is always legacy linker
So wouldn't be able to repro linking bugs seen on linux
In my case the bug is reproduced with legacy linker, so that would mean the mac and linux legacy linker behavior is different
Ah, I missed that. Intriguing
I haven't yet tested the above patch to base-cli or a simple Rust program, but it seems like roc-json works as expected without --linker=legacy despite the warning in the docs. I will come back to this thread if I hit a wall
Last updated: Jul 06 2025 at 12:14 UTC