diff --git a/cli/loader.h b/cli/loader.h index 5b1c10abc9998..f044e63e9e382 100644 --- a/cli/loader.h +++ b/cli/loader.h @@ -21,6 +21,8 @@ #define realloc loader_realloc #endif +#include + #ifdef _OS_WINDOWS_ #define WIN32_LEAN_AND_MEAN #include @@ -105,3 +107,5 @@ int wchar_to_utf8(const wchar_t * wstr, char *str, size_t maxlen); int utf8_to_wchar(const char * str, wchar_t *wstr, size_t maxlen); void setup_stdio(void); #endif + +#include "../src/jloptions.h" diff --git a/cli/loader_lib.c b/cli/loader_lib.c index 414400c6d26dd..014fc36a34dbe 100644 --- a/cli/loader_lib.c +++ b/cli/loader_lib.c @@ -177,6 +177,10 @@ __attribute__((constructor)) void jl_load_libjulia_internal(void) { for (unsigned int symbol_idx=0; jl_exported_func_names[symbol_idx] != NULL; ++symbol_idx) { (*jl_exported_func_addrs[symbol_idx]) = lookup_symbol(libjulia_internal, jl_exported_func_names[symbol_idx]); } + + // jl_options must be initialized very early, in case an embedder sets some + // values there before calling jl_init + ((void (*)(void))jl_init_options_addr)(); } // Load libjulia and run the REPL with the given arguments (in UTF-8 format) diff --git a/src/Makefile b/src/Makefile index 503366a86fabd..abc512ce005d8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -88,7 +88,7 @@ SRCS += $(RUNTIME_SRCS) # headers are used for dependency tracking, while public headers will be part of the dist UV_HEADERS := HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_internal.h options.h timing.h) -PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_gcext.h) +PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_gcext.h jloptions.h) ifeq ($(USE_SYSTEM_LIBUV),0) UV_HEADERS += uv.h UV_HEADERS += uv/*.h diff --git a/src/jl_exported_data.inc b/src/jl_exported_data.inc index 3526896ab1c75..3fe6474c50f1a 100644 --- a/src/jl_exported_data.inc +++ b/src/jl_exported_data.inc @@ -121,4 +121,5 @@ // Data symbols that are defined inside the public libjulia #define JL_EXPORTED_DATA_SYMBOLS(XX) \ - XX(jl_n_threads, int) + XX(jl_n_threads, int) \ + XX(jl_options, jl_options_t) diff --git a/src/jl_exported_funcs.inc b/src/jl_exported_funcs.inc index c80d4139f058e..560d1e7491538 100644 --- a/src/jl_exported_funcs.inc +++ b/src/jl_exported_funcs.inc @@ -380,6 +380,7 @@ XX(jl_init_restored_modules) \ XX(jl_init__threading) \ XX(jl_init_with_image__threading) \ + XX(jl_init_options) \ XX(jl_install_sigint_handler) \ XX(jl_instantiate_type_in_env) \ XX(jl_instantiate_unionall) \ diff --git a/src/jloptions.c b/src/jloptions.c index 1beea6f30f5c3..f341094d7745c 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -28,55 +28,64 @@ JL_DLLEXPORT const char *jl_get_default_sysimg_path(void) } -jl_options_t jl_options = { 0, // quiet - -1, // banner - NULL, // julia_bindir - NULL, // julia_bin - NULL, // cmds - NULL, // image_file (will be filled in below) - NULL, // cpu_target ("native", "core2", etc...) - 0, // nthreads - 0, // nprocs - NULL, // machine_file - NULL, // project - 0, // isinteractive - 0, // color - JL_OPTIONS_HISTORYFILE_ON, // history file - 0, // startup file - JL_OPTIONS_COMPILE_DEFAULT, // compile_enabled - 0, // code_coverage - 0, // malloc_log - 2, // opt_level +static int jl_options_initialized = 0; + +JL_DLLEXPORT void jl_init_options(void) +{ + if (jl_options_initialized) + return; + jl_options = + (jl_options_t){ 0, // quiet + -1, // banner + NULL, // julia_bindir + NULL, // julia_bin + NULL, // cmds + NULL, // image_file (will be filled in below) + NULL, // cpu_target ("native", "core2", etc...) + 0, // nthreads + 0, // nprocs + NULL, // machine_file + NULL, // project + 0, // isinteractive + 0, // color + JL_OPTIONS_HISTORYFILE_ON, // history file + 0, // startup file + JL_OPTIONS_COMPILE_DEFAULT, // compile_enabled + 0, // code_coverage + 0, // malloc_log + 2, // opt_level #ifdef JL_DEBUG_BUILD - 2, // debug_level [debug build] + 2, // debug_level [debug build] #else - 1, // debug_level [release build] + 1, // debug_level [release build] #endif - JL_OPTIONS_CHECK_BOUNDS_DEFAULT, // check_bounds - JL_OPTIONS_DEPWARN_OFF, // deprecation warning - 0, // method overwrite warning - 1, // can_inline - JL_OPTIONS_POLLY_ON, // polly - NULL, // trace_compile - JL_OPTIONS_FAST_MATH_DEFAULT, - 0, // worker - NULL, // cookie - JL_OPTIONS_HANDLE_SIGNALS_ON, - JL_OPTIONS_USE_SYSIMAGE_NATIVE_CODE_YES, - JL_OPTIONS_USE_COMPILED_MODULES_YES, - NULL, // bind-to - NULL, // output-bc - NULL, // output-unopt-bc - NULL, // output-o - NULL, // output-asm - NULL, // output-ji - NULL, // output-code_coverage - 0, // incremental - 0, // image_file_specified - JL_OPTIONS_WARN_SCOPE_ON, // ambiguous scope warning - 0, // image-codegen - 0, // rr-detach -}; + JL_OPTIONS_CHECK_BOUNDS_DEFAULT, // check_bounds + JL_OPTIONS_DEPWARN_OFF, // deprecation warning + 0, // method overwrite warning + 1, // can_inline + JL_OPTIONS_POLLY_ON, // polly + NULL, // trace_compile + JL_OPTIONS_FAST_MATH_DEFAULT, + 0, // worker + NULL, // cookie + JL_OPTIONS_HANDLE_SIGNALS_ON, + JL_OPTIONS_USE_SYSIMAGE_NATIVE_CODE_YES, + JL_OPTIONS_USE_COMPILED_MODULES_YES, + NULL, // bind-to + NULL, // output-bc + NULL, // output-unopt-bc + NULL, // output-o + NULL, // output-asm + NULL, // output-ji + NULL, // output-code_coverage + 0, // incremental + 0, // image_file_specified + JL_OPTIONS_WARN_SCOPE_ON, // ambiguous scope warning + 0, // image-codegen + 0, // rr-detach + }; + jl_options_initialized = 1; +} static const char usage[] = "julia [switches] -- [programfile] [args...]\n"; static const char opts[] = diff --git a/src/jloptions.h b/src/jloptions.h new file mode 100644 index 0000000000000..b1efa4908088c --- /dev/null +++ b/src/jloptions.h @@ -0,0 +1,55 @@ +// This file is a part of Julia. License is MIT: https://julialang.org/license + +#ifndef JL_JLOPTIONS_H +#define JL_JLOPTIONS_H + +// NOTE: This struct needs to be kept in sync with JLOptions type in base/options.jl + +typedef struct { + int8_t quiet; + int8_t banner; + const char *julia_bindir; + const char *julia_bin; + const char **cmds; + const char *image_file; + const char *cpu_target; + int32_t nthreads; + int32_t nprocs; + const char *machine_file; + const char *project; + int8_t isinteractive; + int8_t color; + int8_t historyfile; + int8_t startupfile; + int8_t compile_enabled; + int8_t code_coverage; + int8_t malloc_log; + int8_t opt_level; + int8_t debug_level; + int8_t check_bounds; + int8_t depwarn; + int8_t warn_overwrite; + int8_t can_inline; + int8_t polly; + const char *trace_compile; + int8_t fast_math; + int8_t worker; + const char *cookie; + int8_t handle_signals; + int8_t use_sysimage_native_code; + int8_t use_compiled_modules; + const char *bindto; + const char *outputbc; + const char *outputunoptbc; + const char *outputo; + const char *outputasm; + const char *outputji; + const char *output_code_coverage; + int8_t incremental; + int8_t image_file_specified; + int8_t warn_scope; + int8_t image_codegen; + int8_t rr_detach; +} jl_options_t; + +#endif diff --git a/src/julia.h b/src/julia.h index 9bd41f639a20c..c368e8a5a9d26 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1899,55 +1899,11 @@ JL_DLLEXPORT void jlbacktrace(void) JL_NOTSAFEPOINT; JL_DLLEXPORT void jl_(void *jl_value) JL_NOTSAFEPOINT; // julia options ----------------------------------------------------------- -// NOTE: This struct needs to be kept in sync with JLOptions type in base/options.jl -typedef struct { - int8_t quiet; - int8_t banner; - const char *julia_bindir; - const char *julia_bin; - const char **cmds; - const char *image_file; - const char *cpu_target; - int32_t nthreads; - int32_t nprocs; - const char *machine_file; - const char *project; - int8_t isinteractive; - int8_t color; - int8_t historyfile; - int8_t startupfile; - int8_t compile_enabled; - int8_t code_coverage; - int8_t malloc_log; - int8_t opt_level; - int8_t debug_level; - int8_t check_bounds; - int8_t depwarn; - int8_t warn_overwrite; - int8_t can_inline; - int8_t polly; - const char *trace_compile; - int8_t fast_math; - int8_t worker; - const char *cookie; - int8_t handle_signals; - int8_t use_sysimage_native_code; - int8_t use_compiled_modules; - const char *bindto; - const char *outputbc; - const char *outputunoptbc; - const char *outputo; - const char *outputasm; - const char *outputji; - const char *output_code_coverage; - int8_t incremental; - int8_t image_file_specified; - int8_t warn_scope; - int8_t image_codegen; - int8_t rr_detach; -} jl_options_t; - -extern JL_DLLEXPORT jl_options_t jl_options; + +#include "jloptions.h" + +extern JL_DLLIMPORT jl_options_t jl_options; + JL_DLLEXPORT ssize_t jl_sizeof_jl_options(void); // Parse an argc/argv pair to extract general julia options, passing back out diff --git a/test/embedding/embedding.c b/test/embedding/embedding.c index 205b8a7450211..43463b75c1c3c 100644 --- a/test/embedding/embedding.c +++ b/test/embedding/embedding.c @@ -32,6 +32,9 @@ jl_value_t *checked_eval_string(const char* code) int main() { + // check that setting options works + jl_options.opt_level = 1; + jl_init(); { @@ -40,6 +43,12 @@ int main() checked_eval_string("println(sqrt(2.0))"); } + if (jl_options.opt_level != 1) { + jl_printf(jl_stderr_stream(), "setting jl_options didn't work\n"); + jl_atexit_hook(1); + exit(1); + } + { // Accessing the return value