If you generate code with the JIT which references outside symbols there is currently no way to have a self-contained DSO created. The command line to invoke the linker is fixed.
The patch below would change that. It builds upon the existing framework to specify options for the compiler. The linker optimization flag fits fully into the existing functionality. For additional files to link with I had to extend the mechanism a bit since it is not just one string that needs to be remembered. I've also added the set_str_option member function to the C++ interface of the library. That must have been an oversight. What do you think? gcc/ChangeLog: 2014-12-05 Ulrich Drepper <drep...@gmail.com> * jit/libgccjit++.h (context): Add missing set_str_option member function. * jit/libgccjit.h (gcc_jit_int_option): Add GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL. (gcc_jit_str_option): Add GCC_JIT_STR_OPTION_LINKFILE. * jit/jit-playback.c (convert_to_dso): Use auto_vec instead of fixed-sized array for arguments. Define ADD_ARG macro to add to it. Adjust existing code. Additionally add optimization level and additional link files to the list. * jit/jit-playback.h (context::get_linkfiles): New member function. * jit/jit-recording.c (recording::context:set_str_option): Handle GCC_JIT_STR_OPTION_LINKFILE. * jit/jit-recording.h (recording::context:set_str_option): Add get_linkfiles member function. diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index ecdae80..9c4e45f 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -1726,18 +1726,19 @@ convert_to_dso (const char *ctxt_progname) TV_ASSEMBLE. */ auto_timevar assemble_timevar (TV_ASSEMBLE); const char *errmsg; - const char *argv[7]; + auto_vec <const char *> argvec; +#define ADD_ARG(arg) argvec.safe_push (arg) int exit_status = 0; int err = 0; const char *gcc_driver_name = GCC_DRIVER_NAME; - argv[0] = gcc_driver_name; - argv[1] = "-shared"; + ADD_ARG (gcc_driver_name); + ADD_ARG ("-shared"); /* The input: assembler. */ - argv[2] = m_path_s_file; + ADD_ARG (m_path_s_file); /* The output: shared library. */ - argv[3] = "-o"; - argv[4] = m_path_so_file; + ADD_ARG ("-o"); + ADD_ARG (m_path_so_file); /* Don't use the linker plugin. If running with just a "make" and not a "make install", then we'd @@ -1746,17 +1747,39 @@ convert_to_dso (const char *ctxt_progname) libto_plugin is a .la at build time, with it becoming installed with ".so" suffix: i.e. it doesn't exist with a .so suffix until install time. */ - argv[5] = "-fno-use-linker-plugin"; + ADD_ARG ("-fno-use-linker-plugin"); + + /* Linker int options. */ + switch (get_int_option (GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL)) + { + default: + add_error (NULL, + "unrecognized linker optimization level: %i", + get_int_option (GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL)); + return; + + case 0: + break; + + case 1: + ADD_ARG ("-Wl,-O"); + break; + } + + const char *elt; + const auto_vec<const char *>& linkfiles = get_linkfiles(); + for (unsigned ix = 0; linkfiles.iterate(ix, &elt); ++ix) + ADD_ARG (elt); /* pex argv arrays are NULL-terminated. */ - argv[6] = NULL; + ADD_ARG (NULL); /* pex_one's error-handling requires pname to be non-NULL. */ gcc_assert (ctxt_progname); errmsg = pex_one (PEX_SEARCH, /* int flags, */ gcc_driver_name, - const_cast<char * const *> (argv), + const_cast <char *const *> (argvec.address ()), ctxt_progname, /* const char *pname */ NULL, /* const char *outname */ NULL, /* const char *errname */ @@ -1783,6 +1806,7 @@ convert_to_dso (const char *ctxt_progname) getenv ("PATH")); return; } +#undef ADD_ARG } /* Top-level hook for playing back a recording context. diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 02f08ba..2726347 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -175,6 +175,12 @@ public: return m_recording_ctxt->get_bool_option (opt); } + const auto_vec <const char *>& + get_linkfiles () const + { + return m_recording_ctxt->get_linkfiles (); + } + builtins_manager *get_builtins_manager () const { return m_recording_ctxt->get_builtins_manager (); diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 82ec399..a6d64f9 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -827,7 +827,17 @@ recording::context::set_str_option (enum gcc_jit_str_option opt, "unrecognized (enum gcc_jit_str_option) value: %i", opt); return; } + + switch (opt) + { + default: m_str_options[opt] = value; + break; + + case GCC_JIT_STR_OPTION_LINKFILE: + m_linkfiles.safe_push (value); + break; + } } /* Set the given integer option for this context, or add an error if diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 31fb304..4b21248 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -209,6 +209,12 @@ public: return m_bool_options[opt]; } + const auto_vec<const char *>& + get_linkfiles (void) const + { + return m_linkfiles; + } + result * compile (); @@ -249,6 +255,7 @@ private: const char *m_str_options[GCC_JIT_NUM_STR_OPTIONS]; int m_int_options[GCC_JIT_NUM_INT_OPTIONS]; bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS]; + auto_vec <const char *> m_linkfiles; /* Recorded API usage. */ auto_vec<memento *> m_mementos; @@ -1584,4 +1591,3 @@ private: } // namespace gcc #endif /* JIT_RECORDING_H */ - diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index 67ed5d5..232bb0f 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -99,6 +99,9 @@ namespace gccjit void dump_to_file (const std::string &path, bool update_locations); + void set_str_option (enum gcc_jit_str_option opt, + const char *value); + void set_int_option (enum gcc_jit_int_option opt, int value); @@ -535,6 +538,14 @@ context::dump_to_file (const std::string &path, } inline void +context::set_str_option (enum gcc_jit_str_option opt, + const char *value) +{ + gcc_jit_context_set_str_option (m_inner_ctxt, opt, value); + +} + +inline void context::set_int_option (enum gcc_jit_int_option opt, int value) { diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index ed6390e..da3a2bf 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -139,6 +139,11 @@ enum gcc_jit_str_option messages to stderr. If NULL, or default, "libgccjit.so" is used. */ GCC_JIT_STR_OPTION_PROGNAME, + /* Additional files added to the link command line. To be used to + name libraries needed to satisfy dependencies in the generated + code. */ + GCC_JIT_STR_OPTION_LINKFILE, + GCC_JIT_NUM_STR_OPTIONS }; @@ -152,6 +157,11 @@ enum gcc_jit_int_option The default value is 0 (unoptimized). */ GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + /* Optimization level for the linker. + + The default value is 0 (unoptimized). */ + GCC_JIT_INT_OPTION_LINK_OPTIMIZATION_LEVEL, + GCC_JIT_NUM_INT_OPTIONS };