diff --git a/src/scanner.c b/src/scanner.c index 1308fc7c..679e0068 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -57,15 +57,23 @@ enum side { SERVER, }; +enum visibility { + PRIVATE, + PUBLIC, +}; + static int usage(int ret) { - fprintf(stderr, "usage: %s [OPTION] [client-header|server-header|code]" + fprintf(stderr, "usage: %s [OPTION] [client-header|server-header|private-code|public-code]" " [input_file output_file]\n", PROGRAM_NAME); fprintf(stderr, "\n"); fprintf(stderr, "Converts XML protocol descriptions supplied on " "stdin or input file to client\n" - "headers, server headers, or protocol marshalling code.\n\n"); + "headers, server headers, or protocol marshalling code.\n\n" + "Use \"public-code\" only if the marshalling code will be public - " + "aka DSO will export it while other components will be using it.\n" + "Using \"private-code\" is strongly recommended.\n\n"); fprintf(stderr, "options:\n"); fprintf(stderr, " -h, --help display this help and exit.\n" " -v, --version print the wayland library version that\n" @@ -1714,9 +1722,11 @@ emit_messages(struct wl_list *message_list, printf("};\n\n"); } + static void -emit_code(struct protocol *protocol) +emit_code(struct protocol *protocol, enum visibility vis) { + const char *symbol_visibility; struct interface *i, *next; struct wl_array types; char **p, *prev; @@ -1730,6 +1740,19 @@ emit_code(struct protocol *protocol) "#include \n" "#include \"wayland-util.h\"\n\n"); + /* When building a shared library symbols must be exported, otherwise + * we want to have the symbols hidden. */ + if (vis == PRIVATE) { + symbol_visibility = "WL_PRIVATE"; + printf("#if defined(__GNUC__) && __GNUC__ >= 4\n" + "#define WL_PRIVATE __attribute__ ((visibility(\"hidden\")))\n" + "#else\n" + "#define WL_PRIVATE\n" + "#endif\n\n"); + } else { + symbol_visibility = "WL_EXPORT"; + } + wl_array_init(&types); wl_list_for_each(i, &protocol->interface_list, link) { emit_types_forward_declarations(protocol, &i->request_list, &types); @@ -1759,10 +1782,10 @@ emit_code(struct protocol *protocol) emit_messages(&i->request_list, i, "requests"); emit_messages(&i->event_list, i, "events"); - printf("WL_EXPORT const struct wl_interface " + printf("%s const struct wl_interface " "%s_interface = {\n" "\t\"%s\", %d,\n", - i->name, i->name, i->version); + symbol_visibility, i->name, i->name, i->version); if (!wl_list_empty(&i->request_list)) printf("\t%d, %s_requests,\n", @@ -1809,6 +1832,8 @@ int main(int argc, char *argv[]) enum { CLIENT_HEADER, SERVER_HEADER, + PRIVATE_CODE, + PUBLIC_CODE, CODE, } mode; @@ -1860,6 +1885,10 @@ int main(int argc, char *argv[]) mode = CLIENT_HEADER; else if (strcmp(argv[0], "server-header") == 0) mode = SERVER_HEADER; + else if (strcmp(argv[0], "private-code") == 0) + mode = PRIVATE_CODE; + else if (strcmp(argv[0], "public-code") == 0) + mode = PUBLIC_CODE; else if (strcmp(argv[0], "code") == 0) mode = CODE; else @@ -1947,8 +1976,17 @@ int main(int argc, char *argv[]) case SERVER_HEADER: emit_header(&protocol, SERVER); break; + case PRIVATE_CODE: + emit_code(&protocol, PRIVATE); + break; case CODE: - emit_code(&protocol); + fprintf(stderr, + "Using \"code\" is deprecated - use " + "private-code or public-code.\n" + "See the help page for details.\n"); + /* fallthrough */ + case PUBLIC_CODE: + emit_code(&protocol, PUBLIC); break; }