Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ options:
Include as they appear inside a program (eg <pulse/pulseaudio.h>) (may appear more than once)
--include-dir INCLUDE_DIR
Directories to add to the compiler include path.
--soname SONAME Soname of the wrapped library (eg libpulse.so.0)
--soname [MACRO,]SONAME
Soname of the wrapped library (eg libpulse.so.0) (may appear more than once). Additional occurences must include a predefined macro prefix (eg __OpenBSD__,libpulse.so).
--init-name INIT_NAME
Name to use for the initialize function. This will generate an initialize_<init-name> function. (eg pulse)
--output-header OUTPUT_HEADER
Expand All @@ -52,8 +53,8 @@ options:
Ignore all header files not explicitly mentioned

Example usage for wrapping pulse:
generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse.h --output-implementation pulse.c
generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --soname __OpenBSD__,libpulse.so --omit-prefix _pa_ --init-name pulse --output-header pulse.h --output-implementation pulse.c

Example usage for wrapping X:
generate-wrapper.py --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib.h --output-implementation xlib.c
generate-wrapper.py --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --soname __OpenBSD__,libX11.so --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib.h --output-implementation xlib.c
```
6 changes: 3 additions & 3 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ paplay.o: paplay.c pulse-wrap.h sndfile-wrap.h
$(CC) -c -o paplay.o paplay.c

pulse-wrap.c pulse-wrap.h:
../generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-wrap.h --output-implementation pulse-wrap.c
../generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --soname __OpenBSD__,libpulse.so --omit-prefix _pa_ --init-name pulse --output-header pulse-wrap.h --output-implementation pulse-wrap.c

sndfile-wrap.c sndfile-wrap.h:
../generate-wrapper.py --include /usr/include/sndfile.h --sys-include '<sndfile.h>' --soname libsndfile.so.1 --init-name sndfile --output-header sndfile-wrap.h --output-implementation sndfile-wrap.c
../generate-wrapper.py --include /usr/include/sndfile.h --sys-include '<sndfile.h>' --soname libsndfile.so.1 --soname __OpenBSD__,libsndfile.so --init-name sndfile --output-header sndfile-wrap.h --output-implementation sndfile-wrap.c

paplay: paplay.o sndfile-wrap.o pulse-wrap.o
$(CC) paplay.o pulse-wrap.o sndfile-wrap.o -o paplay -ldl
Expand All @@ -25,7 +25,7 @@ xlib.o: xlib.c xlib-wrap.h
$(CC) -c -o xlib.o xlib.c

xlib-wrap.c xlib-wrap.h:
../generate-wrapper.py --ignore-other --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib-wrap.h --output-implementation xlib-wrap.c
../generate-wrapper.py --ignore-other --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --soname __OpenBSD__,libX11.so --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib-wrap.h --output-implementation xlib-wrap.c

xlib: xlib.o xlib-wrap.o
$(CC) xlib.o xlib-wrap.o -o xlib -ldl
Expand Down
38 changes: 33 additions & 5 deletions generate-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def generate_header(sysincludes, functions, initname, implementation_headers):
retval.append("")
return "\n".join(retval)

def write_implementation(filename, soname, sysincludes, initname, functions, sym_definitions, implementation_headers):
def write_implementation(filename, sonames, sysincludes, initname, functions, sym_definitions, implementation_headers):
with open(filename, 'w') as file:
file.write(generate_header(sysincludes, functions, initname, implementation_headers))
file.write("#include <dlfcn.h>\n")
Expand All @@ -165,10 +165,30 @@ def write_implementation(filename, soname, sysincludes, initname, functions, sym
for sym_definition in sym_definitions:
file.write(f"{sym_definition};\n")

first_name = True
fallback_soname = ""
for value in sonames:
if value.count(",") == 0:
fallback_soname = value
continue
macro = value.split(",", 1)[0]
soname = value.split(",", 1)[1]
if first_name:
file.write(f"#ifdef {macro}\n")
first_name = False
else:
file.write(f"#elif defined({macro})\n")
file.write(f"#define SONAME \"{soname}\"\n")
if len(sonames) > 1:
file.write("#else\n")
file.write(f"#define SONAME \"{fallback_soname}\"\n")
if len(sonames) > 1:
file.write("#endif\n")

file.write(f"int initialize_{initname}(int verbose) {{\n")
file.write(" void *handle;\n")
file.write(" char *error;\n")
file.write(f" handle = dlopen(\"{soname}\", RTLD_LAZY);\n")
file.write(" handle = dlopen(SONAME, RTLD_LAZY);\n")
file.write(" if (!handle) {\n")
file.write(" if (verbose) {\n")
file.write(" fprintf(stderr, \"%s\\n\", dlerror());\n")
Expand Down Expand Up @@ -219,16 +239,16 @@ def write_header(filename, sysincludes, initname, functions, sym_definitions):
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=textwrap.dedent('''
Example usage for wrapping pulse:
%(prog)s --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse.h --output-implementation pulse.c
%(prog)s --include /usr/include/pulse/pulseaudio.h --sys-include '<pulse/pulseaudio.h>' --soname libpulse.so.0 --soname __OpenBSD__,libpulse.so --omit-prefix _pa_ --init-name pulse --output-header pulse.h --output-implementation pulse.c

Example usage for wrapping X:
%(prog)s --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib.h --output-implementation xlib.c
%(prog)s --include /usr/include/X11/Xlib.h --include /usr/include/X11/Xutil.h --include /usr/include/X11/XKBlib.h --sys-include '<X11/Xlib.h>' --sys-include '<X11/Xutil.h>' --sys-include '<X11/XKBlib.h>' --soname libX11.so.6 --soname __OpenBSD__,libX11.so --init-name xlib --omit-prefix XkbGetDeviceIndicatorState --omit-prefix XkbAddSymInterpret --output-header xlib.h --output-implementation xlib.c
''')
)
parser.add_argument('--include', action='append', help='Include files to read (may appear more than once)', required=True)
parser.add_argument('--sys-include', action='append', help='Include as they appear inside a program (eg <pulse/pulseaudio.h>) (may appear more than once)', required=True)
parser.add_argument('--include-dir', action='append', help='Directories to add to the compiler include path.', required=False)
parser.add_argument('--soname', help='Soname of the wrapped library (eg libpulse.so.0)', required=True)
parser.add_argument('--soname', action='append', help='Soname of the wrapped library (eg libpulse.so.0) (may appear more than once). Additional occurences must include a predefined macro prefix (eg __OpenBSD__,libpulse.so).', required=True)
parser.add_argument('--init-name', help='Name to use for the initialize function. This will generate an initialize_<init-name> function. (eg pulse)', required=True)
parser.add_argument('--output-header', help='Filename of the header to output', required=True)
parser.add_argument('--implementation-header', action='append', help='Header to add to wrapper implementation (eg <X11/Xlib.h>) (may appear more than once)', required=False)
Expand All @@ -253,5 +273,13 @@ def write_header(filename, sysincludes, initname, functions, sym_definitions):
if item not in sym_definitions:
sym_definitions.append(item)

fallback_count = 0
for value in args.soname:
if value.count(",") == 0:
fallback_count += 1

if fallback_count != 1:
sys.exit("There must be exactly one --soname argument with no predefined macro prefix.")

write_implementation(args.output_implementation, args.soname, args.sys_include, args.init_name, functions, sym_definitions, args.implementation_header)
write_header(args.output_header, args.sys_include, args.init_name, functions, sym_definitions)