On Thu, 2015-06-25 at 13:16 -0600, Jeff Law wrote: > On 06/25/2015 01:13 PM, David Malcolm wrote: > > > > * It extends the libgccjit API. It's not clear to me yet how to > > manage extensions of the libgccjit API: should I use symbol maps > > and versioning, or bump the SONAME? I'm thinking of providing > > precanned feature macros within libgccjit.h e.g: > > > > #define LIBGCCJIT_HAVE_SWITCH_STATEMENT > Seems to me you should use a symbol map and bump the version.
Thanks. By "the version", do you mean the version within the symbol map? I've read Uli Drepper's "How To Write Shared Libraries" guide: http://www.akkadia.org/drepper/dsohowto.pdf and in particular section 3: "Maintaining APIs and ABIs", which suggests versioned DSOs (though this presumably implies the use of GNU ld). I attempted to use the symbol map to segregate the new symbols into their own version; attached is a patch which does that (on top of the "add switch statements" patch). Is that the kind of thing you had in mind? My first attempt was to keep the existing syms in an anonymous tag but I got: /usr/bin/ld: anonymous version tag cannot be combined with other version tags (which comes from binutils ld/ldlang.c:lang_register_vers_node) Hence I put the existing symbols into a LIBGCCJIT_ABI_1 version. With the above change, using "eu-readelf -s" I see a client program linked against libgccjit goes from having e.g.: GLOBAL DEFAULT UNDEF gcc_jit_context_compile to having: GLOBAL DEFAULT UNDEF gcc_jit_context_compile@@LIBGCCJIT_ABI_1 and one using the new symbols has: GLOBAL DEFAULT UNDEF gcc_jit_context_compile@LIBGCCJIT_ABI_1 (2) GLOBAL DEFAULT UNDEF gcc_jit_block_end_with_switch@LIBGCCJIT_ABI_2 (4) Presumably I'd need to bump the SONAME to accommodate the introduction of using symbol versioning? Am I right in hoping that with the introduction to using symbol versioning that I'd never need to bump the SONAME again? Running: objdump -p client-binary-using-just-old-symbols gives (amongst other output): Version References: required from libc.so.6: 0x09691a75 0x00 03 GLIBC_2.2.5 required from libgccjit.so.0: 0x00824161 0x00 02 LIBGCCJIT_ABI_1 whereas: objdump -p client-binary-using-some-new-symbols gives: Version References: required from libc.so.6: 0x09691a75 0x00 03 GLIBC_2.2.5 required from libgccjit.so.0: 0x00824162 0x00 04 LIBGCCJIT_ABI_2 0x00824161 0x00 02 LIBGCCJIT_ABI_1 FWIW objdump -p is used by /usr/lib/rpm/find-requires, so presumably these entries would show up in rpm metadata, so that binaries using the new symbols get flagged at the RPM level as needing a more up-to-date libgccjit rpm. Hopefully other packaging systems handle symbol versioning in similar ways. Does this approach look sane? I'd probably add a page about ABI to the docs, and list the ABIs there. This doesn't cover the addition of new values to the various options enums; I'm not sure how to handle capturing *that* within the binary metadata without bumping the SONAME. Maybe bump the gcc_jit_context_set_FOO_option entrypoints into new version tags each time we add a new value to the corresponding option enum? Would it be sane to go to a feature-based naming scheme for tags, rather than pure numbers? e.g. LIBGCCJIT_ABI_INITIAL LIBGCCJIT_ABI_WITH_SWITCH_STATEMENTS LIGCCCJIT_ABI_WITH_BOOL_OPTION_ERROR_ON_UNREACHABLE_BLOCKS etc (how long can they be, and is there a cost? can they include lower case?) Dave
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 93b19e8..7bf89f2 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -17,6 +17,9 @@ # You should have received a copy of the GNU General Public License # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. */ + +# The initial release of the library. +LIBGCCJIT_ABI_1 { global: # Keep this list sorted alphabetically: @@ -29,9 +32,7 @@ gcc_jit_block_end_with_jump; gcc_jit_block_end_with_return; gcc_jit_block_end_with_void_return; - gcc_jit_block_end_with_switch; gcc_jit_block_get_function; - gcc_jit_case_as_object; gcc_jit_context_acquire; gcc_jit_context_add_option; gcc_jit_context_compile; @@ -49,7 +50,6 @@ gcc_jit_context_new_binary_op; gcc_jit_context_new_call; gcc_jit_context_new_call_through_ptr; - gcc_jit_context_new_case; gcc_jit_context_new_cast; gcc_jit_context_new_child_context; gcc_jit_context_new_comparison; @@ -109,4 +109,12 @@ gcc_jit_type_get_volatile; local: *; -}; \ No newline at end of file +}; + +# Add support for switch statements. +LIBGCCJIT_ABI_2 { + global: + gcc_jit_block_end_with_switch; + gcc_jit_case_as_object; + gcc_jit_context_new_case; +} LIBGCCJIT_ABI_1;