Skip to content

Commit 8bae127

Browse files
authored
Merge branch 'master' into trim-experimental
2 parents 8a4a6a4 + 2bd37fb commit 8bae127

File tree

13 files changed

+107
-49
lines changed

13 files changed

+107
-49
lines changed

contrib/juliac-buildscript.jl

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# Script to run in the process that generates juliac's object file output
22

3-
inputfile = ARGS[1]
4-
output_type = ARGS[2]
5-
add_ccallables = ARGS[3] == "true"
6-
73
# Run the verifier in the current world (before modifications), so that error
84
# messages and types print in their usual way.
95
Core.Compiler._verify_trim_world_age[] = Base.get_world_counter()
@@ -189,13 +185,37 @@ end
189185

190186
import Base.Experimental.entrypoint
191187

192-
let mod = Base.include(Base.__toplevel__, inputfile)
193-
if !isa(mod, Module)
194-
mod = Main
195-
end
188+
# for use as C main if needed
189+
function _main(argc::Cint, argv::Ptr{Ptr{Cchar}})::Cint
190+
args = ccall(:jl_set_ARGS, Any, (Cint, Ptr{Ptr{Cchar}}), argc, argv)::Vector{String}
191+
return Main.main(args)
192+
end
193+
194+
let mod = Base.include(Main, ARGS[1])
196195
Core.@latestworld
197-
if output_type == "--output-exe" && isdefined(mod, :main) && !add_ccallables
198-
entrypoint(mod.main, ())
196+
if ARGS[2] == "--output-exe"
197+
have_cmain = false
198+
if isdefined(Main, :main)
199+
for m in methods(Main.main)
200+
if isdefined(m, :ccallable)
201+
# TODO: possibly check signature and return type
202+
have_cmain = true
203+
break
204+
end
205+
end
206+
end
207+
if !have_cmain
208+
if Base.should_use_main_entrypoint()
209+
if hasmethod(Main.main, Tuple{Vector{String}})
210+
entrypoint(_main, (Cint, Ptr{Ptr{Cchar}}))
211+
Base._ccallable("main", Cint, Tuple{typeof(_main), Cint, Ptr{Ptr{Cchar}}})
212+
else
213+
error("`@main` must accept a `Vector{String}` argument.")
214+
end
215+
else
216+
error("To generate an executable a `@main` function must be defined.")
217+
end
218+
end
199219
end
200220
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{Base.SubString{String}, 1}, String))
201221
#entrypoint(join, (Base.GenericIOBuffer{Memory{UInt8}}, Array{String, 1}, Char))
@@ -204,7 +224,7 @@ let mod = Base.include(Base.__toplevel__, inputfile)
204224
entrypoint(Base.wait_forever, ())
205225
entrypoint(Base.trypoptask, (Base.StickyWorkqueue,))
206226
entrypoint(Base.checktaskempty, ())
207-
if add_ccallables
227+
if ARGS[3] == "true"
208228
ccall(:jl_add_ccallable_entrypoints, Cvoid, ())
209229
end
210230
end

contrib/print_sorted_stdlibs.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ function check_flag(flag)
1212
end
1313

1414
if check_flag("--help") || check_flag("-h")
15-
println("Usage: julia print_sorted_stdlibs.jl [stdlib_dir] [--exclude-jlls] [--exclude-sysimage]")
15+
println("Usage: julia print_sorted_stdlibs.jl [stdlib_dir] [--exclude-jlls] [--exclude-sysimage] [--only-sysimg]")
1616
end
1717

1818
# Allow users to ask for JLL or no JLLs
1919
exclude_jlls = check_flag("--exclude-jlls")
2020
exclude_sysimage = check_flag("--exclude-sysimage")
21+
only_sysimage = check_flag("--only-sysimg")
2122

2223
# Default to the `stdlib/vX.Y` directory
2324
STDLIB_DIR = get(ARGS, 1, joinpath(@__DIR__, "..", "usr", "share", "julia", "stdlib"))
@@ -81,9 +82,19 @@ if exclude_jlls
8182
filter!(p -> !endswith(p, "_jll"), sorted_projects)
8283
end
8384

84-
if exclude_sysimage
85-
loaded_modules = Set(map(k->k.name, collect(keys(Base.loaded_modules))))
86-
filter!(p->!in(p, loaded_modules), sorted_projects)
85+
if only_sysimage && exclude_sysimage
86+
println(stderr, "Warning: --only-sysimg and --exclude-sysimage are mutually exclusive. Prioritizing --only-sysimg.")
87+
exclude_sysimage = false
88+
end
89+
90+
if only_sysimage || exclude_sysimage
91+
loaded_modules_set = Set(map(k->k.name, collect(keys(Base.loaded_modules))))
92+
93+
if only_sysimage
94+
filter!(p -> in(p, loaded_modules_set), sorted_projects)
95+
else
96+
filter!(p -> !in(p, loaded_modules_set), sorted_projects)
97+
end
8798
end
8899

89100
# Print out sorted projects, ready to be pasted into `sysimg.jl`
@@ -92,6 +103,9 @@ println(" # Stdlibs sorted in dependency, then alphabetical, order by contrib
92103
if exclude_jlls
93104
println(" # Run with the `--exclude-jlls` option to filter out all JLL packages")
94105
end
106+
if only_sysimage
107+
println(" # Run with the `--only-sysimg` option to filter for only packages included in the system image")
108+
end
95109
if exclude_sysimage
96110
println(" # Run with the `--exclude-sysimage` option to filter out all packages included in the system image")
97111
end

doc/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ deps: $(SRCCACHE)/UnicodeData-$(UNICODE_DATA_VERSION).txt
3434
$(JLCHECKSUM) "$<"
3535
cp "$<" UnicodeData.txt
3636

37+
alldeps: deps
38+
$(JULIA_EXECUTABLE) --color=yes $(call cygpath_w,$(SRCDIR)/make.jl) deps
39+
3740
checksum-unicodedata: $(SRCCACHE)/UnicodeData-$(UNICODE_DATA_VERSION).txt
3841
$(JLCHECKSUM) "$<"
3942

doc/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ $ make -C doc doctest=true
2727
```
2828

2929
from the root directory.
30+
31+
## Customizing Doctest Execution
32+
33+
By default, doctests are run using the in-tree Julia executable.
34+
This behavior can be changed by setting the `JULIA_EXECUTABLE` Makefile variable.
35+
36+
> [!WARNING]
37+
> Using a custom `JULIA_EXECUTABLE` will not pick up changes to docstrings for Base or any standard library built into the system image. To see the list of standard libraries that are part of the system image, you can run the `contrib/print_sorted_stdlibs.jl` script (e.g., `julia contrib/print_sorted_stdlibs.jl --only-sysimg`).

doc/make.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ push!(DEPOT_PATH, abspath(Sys.BINDIR, "..", "share", "julia"))
88
using Pkg
99
Pkg.instantiate()
1010

11+
if "deps" in ARGS
12+
exit()
13+
end
14+
1115
using Documenter
1216
import LibGit2
1317

src/gf.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4642,8 +4642,6 @@ JL_DLLEXPORT void jl_extern_c(jl_value_t *name, jl_value_t *declrt, jl_tupletype
46424642
jl_error("@ccallable: function object must be a singleton");
46434643

46444644
// compute / validate return type
4645-
if (!jl_is_concrete_type(declrt) || jl_is_kind(declrt))
4646-
jl_error("@ccallable: return type must be concrete and correspond to a C type");
46474645
if (!jl_type_mappable_to_c(declrt))
46484646
jl_error("@ccallable: return type doesn't correspond to a C type");
46494647

src/jlapi.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,28 @@ JL_DLLEXPORT int jl_is_initialized(void)
5050
* @param argc The number of command line arguments.
5151
* @param argv Array of command line arguments.
5252
*/
53-
JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv)
53+
JL_DLLEXPORT jl_value_t *jl_set_ARGS(int argc, char **argv)
5454
{
55-
if (jl_core_module != NULL) {
56-
jl_array_t *args = (jl_array_t*)jl_get_global(jl_core_module, jl_symbol("ARGS"));
57-
if (args == NULL) {
58-
args = jl_alloc_vec_any(0);
59-
JL_GC_PUSH1(&args);
55+
jl_array_t *args = NULL;
56+
jl_value_t *vecstr = NULL;
57+
JL_GC_PUSH2(&args, &vecstr);
58+
if (jl_core_module != NULL)
59+
args = (jl_array_t*)jl_get_global(jl_core_module, jl_symbol("ARGS"));
60+
if (args == NULL) {
61+
vecstr = jl_apply_array_type((jl_value_t*)jl_string_type, 1);
62+
args = jl_alloc_array_1d(vecstr, 0);
63+
if (jl_core_module != NULL)
6064
jl_set_const(jl_core_module, jl_symbol("ARGS"), (jl_value_t*)args);
61-
JL_GC_POP();
62-
}
63-
assert(jl_array_nrows(args) == 0);
64-
jl_array_grow_end(args, argc);
65-
int i;
66-
for (i = 0; i < argc; i++) {
67-
jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]);
68-
jl_array_ptr_set(args, i, s);
69-
}
7065
}
66+
assert(jl_array_nrows(args) == 0);
67+
jl_array_grow_end(args, argc);
68+
int i;
69+
for (i = 0; i < argc; i++) {
70+
jl_value_t *s = (jl_value_t*)jl_cstr_to_string(argv[i]);
71+
jl_array_ptr_set(args, i, s);
72+
}
73+
JL_GC_POP();
74+
return (jl_value_t*)args;
7175
}
7276

7377
JL_DLLEXPORT void jl_init_with_image_handle(void *handle) {

src/julia.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2579,7 +2579,7 @@ uint64_t parse_heap_size_hint(const char *optarg, const char *option_name);
25792579

25802580
// Set julia-level ARGS array according to the arguments provided in
25812581
// argc/argv
2582-
JL_DLLEXPORT void jl_set_ARGS(int argc, char **argv);
2582+
JL_DLLEXPORT jl_value_t *jl_set_ARGS(int argc, char **argv);
25832583

25842584
JL_DLLEXPORT int jl_generating_output(void) JL_NOTSAFEPOINT;
25852585

src/staticdata.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,12 +2638,12 @@ static void jl_prune_module_bindings(jl_module_t * m) JL_GC_DISABLED
26382638
jl_gc_wb(m, jl_atomic_load_relaxed(&bindingkeyset2));
26392639
}
26402640

2641-
static void strip_slotnames(jl_array_t *slotnames)
2641+
static void strip_slotnames(jl_array_t *slotnames, int n)
26422642
{
26432643
// replace slot names with `?`, except unused_sym since the compiler looks at it
26442644
jl_sym_t *questionsym = jl_symbol("?");
2645-
int i, l = jl_array_len(slotnames);
2646-
for (i = 0; i < l; i++) {
2645+
int i;
2646+
for (i = 0; i < n; i++) {
26472647
jl_value_t *s = jl_array_ptr_ref(slotnames, i);
26482648
if (s != (jl_value_t*)jl_unused_sym)
26492649
jl_array_ptr_set(slotnames, i, questionsym);
@@ -2662,7 +2662,7 @@ static jl_value_t *strip_codeinfo_meta(jl_method_t *m, jl_value_t *ci_, jl_code_
26622662
else {
26632663
ci = (jl_code_info_t*)ci_;
26642664
}
2665-
strip_slotnames(ci->slotnames);
2665+
strip_slotnames(ci->slotnames, jl_array_len(ci->slotnames));
26662666
ci->debuginfo = jl_nulldebuginfo;
26672667
jl_gc_wb(ci, ci->debuginfo);
26682668
jl_value_t *ret = (jl_value_t*)ci;
@@ -2736,7 +2736,11 @@ static int strip_all_codeinfos__(jl_typemap_entry_t *def, void *_env)
27362736
}
27372737
jl_array_t *slotnames = jl_uncompress_argnames(m->slot_syms);
27382738
JL_GC_PUSH1(&slotnames);
2739-
strip_slotnames(slotnames);
2739+
int tostrip = jl_array_len(slotnames);
2740+
// for keyword methods, strip only nargs to keep the keyword names at the end for reflection
2741+
if (jl_tparam0(jl_unwrap_unionall(m->sig)) == jl_typeof(jl_kwcall_func))
2742+
tostrip = m->nargs;
2743+
strip_slotnames(slotnames, tostrip);
27402744
m->slot_syms = jl_compress_argnames(slotnames);
27412745
jl_gc_wb(m, m->slot_syms);
27422746
JL_GC_POP();

test/cmdlineargs.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,3 +1258,13 @@ end
12581258
timeout = 120
12591259
@test parse(Int,read(`$exename --timeout-for-safepoint-straggler=$timeout -E "Base.JLOptions().timeout_for_safepoint_straggler_s"`, String)) == timeout
12601260
end
1261+
1262+
@testset "--strip-metadata" begin
1263+
mktempdir() do dir
1264+
@test success(pipeline(`$(Base.julia_cmd()) --strip-metadata -t1,0 --output-o $(dir)/sys.o.a -e 0`, stderr=stderr, stdout=stdout))
1265+
if isfile(joinpath(dir, "sys.o.a"))
1266+
Base.Linking.link_image(joinpath(dir, "sys.o.a"), joinpath(dir, "sys.so"))
1267+
@test readchomp(`$(Base.julia_cmd()) -t1,0 -J $(dir)/sys.so -E 'hasmethod(sort, (Vector{Int},), (:dims,))'`) == "true"
1268+
end
1269+
end
1270+
end

test/trimming/basic_jll.jl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
module MyApp
2-
31
using Libdl
42
using Zstd_jll
53

6-
Base.@ccallable function main()::Cint
4+
function @main(args::Vector{String})::Cint
75
println(Core.stdout, "Julia! Hello, world!")
86
fptr = dlsym(Zstd_jll.libzstd_handle, :ZSTD_versionString)
97
println(Core.stdout, unsafe_string(ccall(fptr, Cstring, ())))
108
println(Core.stdout, unsafe_string(ccall((:ZSTD_versionString, libzstd), Cstring, ())))
119
return 0
1210
end
13-
14-
end

test/trimming/hello.jl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
module MyApp
2-
31
world::String = "world!"
42
const str = OncePerProcess{String}() do
53
return "Hello, " * world
64
end
75

8-
Base.@ccallable function main()::Cint
6+
function @main(args::Vector{String})::Cint
97
println(Core.stdout, str())
8+
foreach(x->println(Core.stdout, x), args)
109
return 0
1110
end
12-
13-
end

test/trimming/trimming.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ bindir = dirname(ARGS[1])
66
let exe_suffix = splitext(Base.julia_exename())[2]
77

88
hello_exe = joinpath(bindir, "hello" * exe_suffix)
9-
@test readchomp(`$hello_exe`) == "Hello, world!"
9+
@test readchomp(`$hello_exe arg1 arg2`) == "Hello, world!\n$hello_exe\narg1\narg2"
1010
@test filesize(hello_exe) < 2_000_000
1111

1212
basic_jll_exe = joinpath(bindir, "basic_jll" * exe_suffix)

0 commit comments

Comments
 (0)