2019-12-24 11:27:22 +00:00
#!/usr/bin/env python3
import argparse
import os
import re
import subprocess
import tempfile
os . chdir ( os . path . dirname ( __file__ ) + " /.. " )
PATH = " src/ "
CURL_RE = re . compile ( r " \ bcurl_ \ w* " )
def get_curl_calls ( path ) :
names = set ( )
2020-12-02 14:22:26 +00:00
for directory , _ , files in os . walk ( path ) :
2019-12-24 11:27:22 +00:00
for filename in files :
if ( filename . endswith ( " .cpp " ) or
filename . endswith ( " .c " ) or
filename . endswith ( " .h " ) ) :
2022-06-12 11:15:02 +00:00
with open ( os . path . join ( directory , filename ) , encoding = " utf-8 " ) as f :
2019-12-24 11:27:22 +00:00
contents = f . read ( )
names = names . union ( CURL_RE . findall ( contents ) )
return names
def assembly_source ( names ) :
names = sorted ( names )
result = [ ]
for name in names :
2022-06-12 11:15:02 +00:00
result . append ( f " .type { name } ,@function " )
2019-12-24 11:27:22 +00:00
for name in names :
2022-06-12 11:15:02 +00:00
result . append ( f " .global { name } " )
2019-12-24 11:27:22 +00:00
for name in names :
2022-06-12 11:15:02 +00:00
result . append ( f " { name } : " )
2019-12-24 11:27:22 +00:00
return " \n " . join ( result + [ " " ] )
DEFAULT_OUTPUT = " libcurl.so "
DEFAULT_SONAME = " libcurl.so.4 "
def main ( ) :
p = argparse . ArgumentParser ( description = " Create a stub shared object for linking " )
p . add_argument ( " -k " , " --keep " , action = " store_true " , help = " Keep the intermediary assembly file " )
2022-06-12 11:15:02 +00:00
p . add_argument ( " --output " , help = f " Output filename (default: { DEFAULT_OUTPUT } ) " , default = DEFAULT_OUTPUT )
p . add_argument ( " --soname " , help = f " soname of the produced shared object (default: { DEFAULT_SONAME } ) " , default = DEFAULT_SONAME )
2019-12-24 11:27:22 +00:00
p . add_argument ( " --functions " , metavar = " FUNCTION " , nargs = " + " , help = " Function symbols that should be put into the shared object (default: look for curl_* names in the source code) " )
p . add_argument ( " --link-args " , help = " Colon-separated list of additional linking arguments " )
args = p . parse_args ( )
if args . functions is not None :
functions = args . functions
else :
functions = get_curl_calls ( PATH )
extra_link_args = [ ]
if args . link_args :
extra_link_args = args . link_args . split ( " : " )
with tempfile . NamedTemporaryFile ( " w " , suffix = " .s " , delete = not args . keep ) as f :
if args . keep :
2022-06-12 11:15:02 +00:00
print ( f " using { f . name } as temporary file " )
2019-12-24 11:27:22 +00:00
f . write ( assembly_source ( functions ) )
f . flush ( )
subprocess . check_call ( [
" cc " ,
] + extra_link_args + [
" -shared " ,
" -nostdlib " , # don't need to link to libc
2022-06-12 11:15:02 +00:00
f " -Wl,-soname, { args . soname } " ,
2019-12-24 11:27:22 +00:00
" -o " , args . output ,
f . name ,
] )
subprocess . check_call ( [ " strip " , args . output ] )
if __name__ == ' __main__ ' :
main ( )