/*******************************************************************/ /* sbpython3: external configurable build project for Python-3.x. */ /* Copyright (C) 2018 Z. Gilboa */ /* Released under the Standard MIT License; see COPYING.SBPYTHON3.*/ /*******************************************************************/ /*******************************************************************/ /* pyexts.c: a simple development-time utility for generating */ /* make rules for python's extension modules. The utility is */ /* included with the sbpython3 project for reference only. */ /* */ /* cc -std=c99 -D_XOPEN_SOURCE=700 pyexts.c */ /*******************************************************************/ #include #include #define PYEXT_LIST(...) (const char *[]){__VA_ARGS__,0} #define PYEXT_SIMPLE(name,...) {name,PYEXT_LIST(__VA_ARGS__),0,0,0,0} #define PYEXT_COMMON(name,hvar,lvar,...) {name,PYEXT_LIST(__VA_ARGS__), \ PYEXT_LIST(hvar),0, \ PYEXT_LIST(lvar),0} #define PYEXT_ALTSTD(name,cstd,...) {name,PYEXT_LIST(__VA_ARGS__), \ 0,PYEXT_LIST(cstd),0,0} struct pyext_meta { const char * name; const char ** srcs; const char ** hdrs; const char ** cstd; const char ** vars; const char ** deps; }; static const struct pyext_meta pyexts[] = { PYEXT_SIMPLE("_multibytecodec", "cjkcodecs/multibytecodec"), PYEXT_SIMPLE("_codecs_cn", "cjkcodecs/_codecs_cn"), PYEXT_SIMPLE("_codecs_hk", "cjkcodecs/_codecs_hk"), PYEXT_SIMPLE("_codecs_jp", "cjkcodecs/_codecs_jp"), PYEXT_SIMPLE("_codecs_kr", "cjkcodecs/_codecs_kr"), PYEXT_SIMPLE("_codecs_tw", "cjkcodecs/_codecs_tw"), PYEXT_SIMPLE("_codecs_iso2022", "cjkcodecs/_codecs_iso2022"), PYEXT_SIMPLE("_asyncio", "_asynciomodule"), PYEXT_SIMPLE("_bisect", "_bisectmodule"), PYEXT_SIMPLE("_crypt", "_cryptmodule"), PYEXT_SIMPLE("_csv", "_csv"), PYEXT_SIMPLE("_ctypes_test", "_ctypes/_ctypes_test"), PYEXT_SIMPLE("_datetime", "_datetimemodule"), PYEXT_SIMPLE("_elementtree", "_elementtree"), PYEXT_SIMPLE("_heapq", "_heapqmodule"), PYEXT_SIMPLE("_json", "_json"), PYEXT_SIMPLE("_md5", "md5module"), PYEXT_SIMPLE("_opcode", "_opcode"), PYEXT_SIMPLE("_pickle", "_pickle"), PYEXT_SIMPLE("_posixsubprocess", "_posixsubprocess"), PYEXT_SIMPLE("_random", "_randommodule"), PYEXT_SIMPLE("_sha1", "sha1module"), PYEXT_SIMPLE("_sha256", "sha256module"), PYEXT_SIMPLE("_sha3", "_sha3/sha3module"), PYEXT_SIMPLE("_sha512", "sha512module"), PYEXT_SIMPLE("_socket", "socketmodule"), PYEXT_SIMPLE("_struct", "_struct"), PYEXT_SIMPLE("_testbuffer", "_testbuffer"), PYEXT_SIMPLE("_testcapi", "_testcapimodule"), PYEXT_SIMPLE("_testimportmultiple", "_testimportmultiple"), PYEXT_SIMPLE("_testmultiphase", "_testmultiphase"), PYEXT_SIMPLE("array", "arraymodule"), PYEXT_SIMPLE("audioop", "audioop"), PYEXT_SIMPLE("fcntl", "fcntlmodule"), PYEXT_SIMPLE("grp", "grpmodule"), PYEXT_SIMPLE("mmap", "mmapmodule"), PYEXT_SIMPLE("ossaudiodev", "ossaudiodev"), PYEXT_SIMPLE("parser", "parsermodule"), PYEXT_SIMPLE("resource", "resource"), PYEXT_SIMPLE("select", "selectmodule"), PYEXT_SIMPLE("spwd", "spwdmodule"), PYEXT_SIMPLE("syslog", "syslogmodule"), PYEXT_SIMPLE("termios", "termios"), PYEXT_SIMPLE("unicodedata", "unicodedata"), PYEXT_SIMPLE("xxlimited", "xxlimited"), PYEXT_SIMPLE("_blake2", "_blake2/blake2module", "_blake2/blake2b_impl", "_blake2/blake2s_impl"), PYEXT_SIMPLE("_lsprof", "_lsprof", "rotatingtree"), PYEXT_SIMPLE("_multiprocessing", "_multiprocessing/multiprocessing", "_multiprocessing/semaphore"), PYEXT_SIMPLE("cmath", "cmathmodule", "_math"), PYEXT_SIMPLE("math", "mathmodule", "_math"), PYEXT_COMMON("_bz2",0,"-lbz2", "_bz2module"), PYEXT_COMMON("_ctypes",0,"-lffi", "_ctypes/_ctypes", "_ctypes/callbacks", "_ctypes/callproc", "_ctypes/stgdict", "_ctypes/cfield"), PYEXT_COMMON("_curses", "$(CFLAGS_NCURSES)", "$(LDFLAGS_NCURSES)", "_cursesmodule"), PYEXT_COMMON("_curses_panel", "$(CFLAGS_NCURSES)", "$(LDFLAGS_NCURSES)", "_curses_panel"), PYEXT_COMMON("_decimal", "-I$(SOURCE_DIR)/Modules/_decimal/libmpdec -DUNIVERSAL", 0, "_decimal/_decimal", "_decimal/libmpdec/basearith", "_decimal/libmpdec/constants", "_decimal/libmpdec/context", "_decimal/libmpdec/convolute", "_decimal/libmpdec/crt", "_decimal/libmpdec/difradix2", "_decimal/libmpdec/fnt", "_decimal/libmpdec/fourstep", "_decimal/libmpdec/io", "_decimal/libmpdec/memory", "_decimal/libmpdec/mpdecimal", "_decimal/libmpdec/numbertheory", "_decimal/libmpdec/sixstep", "_decimal/libmpdec/transpose"), PYEXT_COMMON("_dbm", "$(CFLAGS_DBM)", "$(LDFLAGS_DBM)", "_dbmmodule"), PYEXT_COMMON("_gdbm",0,"-lgdbm", "_gdbmmodule"), PYEXT_COMMON("_hashlib",0,"-lssl -lcrypto", "_hashopenssl"), PYEXT_COMMON("_lzma",0,"-llzma", "_lzmamodule"), PYEXT_COMMON("_sqlite3", "$(CFLAGS_SQLITE)", "$(LDFLAGS_SQLITE)", "_sqlite/cache", "_sqlite/connection", "_sqlite/cursor", "_sqlite/microprotocols", "_sqlite/module", "_sqlite/prepare_protocol", "_sqlite/row", "_sqlite/statement", "_sqlite/util"), PYEXT_COMMON("_ssl",0,"-lssl -lcrypto", "_ssl"), PYEXT_COMMON("_tkinter", "$(CFLAGS_TCLTK)", "$(LDFLAGS_TCLTK)", "_tkinter", "tkappinit"), PYEXT_COMMON("binascii",0,"-lz", "binascii"), PYEXT_COMMON("pyexpat",0,"-lexpat", "pyexpat"), PYEXT_COMMON("readline",0,"-lreadline", "readline"), PYEXT_COMMON("zlib",0,"-lz", "zlibmodule"), {0,0,0,0,0,0}, }; static void pyext_uppercase(char * buf, const char * name) { const char * src; char * dst; src = name; dst = buf; for (; *src; ) *dst++ = ((*src >= 'a') && (*src <= 'z')) ? 'A' - 'a' + *src++ : *src++; *dst = 0; } int main(int argc, char ** argv) { const struct pyext_meta * p; size_t nlen; const char ** parg; const char * dtab; const char * otab; const char * htab; const char * stab; const char * ltab; const char * rtab; const char * vtab; const char * name; char fmt[64]; char uname[64]; if ((argc == 2) && !strcmp(argv[1],"--py-init-func")) { for (p=pyexts; p->name; p++) printf("PY_INIT_FUNC(%s);\n",p->name); return 0; } if ((argc == 2) && !strcmp(argv[1],"--init-func-ptr")) { for (p=pyexts; p->name; p++) { nlen = strlen(p->name); sprintf(fmt,"\t{\"%%s\",%%-%zusPyInit_%%s},%%-%zus\\\n", 20-nlen,23-nlen); printf(fmt,p->name," ",p->name," "); } return 0; } for (p=pyexts; p->name; p++) { /* init */ name = (p->name[0] == '_') ? &p->name[1] : p->name; nlen = strlen(name); pyext_uppercase(uname,name); /* pretty */ dtab = (nlen <= 4) ? "\t\t\t" : (nlen <= 12) ? "\t\t" : "\t"; otab = (nlen <= 3) ? "\t\t\t" : (nlen <= 11) ? "\t\t" : "\t"; ltab = (nlen <= 2) ? "\t\t\t" : (nlen <= 10) ? "\t\t" : "\t"; rtab = (nlen <= 1) ? "\t\t\t" : (nlen <= 9) ? "\t\t" : "\t"; vtab = (nlen <= 6) ? "\t\t" : (nlen <= 14) ? "\t" : ""; htab = (nlen <= 8) ? "\t\t" : "\t"; stab = (nlen <= 9) ? "\t\t" : "\t"; /* output */ printf("# %s\n",p->name); for (parg=p->srcs; *parg; parg++) printf("PYEXT_%s_SRCS%s+= " "pyext/obj/%s.c\n", uname,dtab,*parg); printf("\n"); printf("PYEXT_%s_LOBJS%s= $(PYEXT_%s_SRCS:.c=.lo)\n",uname,otab,uname); printf("PYEXT_%s_OBJS%s= $(PYEXT_%s_SRCS:.c=.o)\n",uname,dtab,uname); printf("\n"); for (parg=p->hdrs; parg && *parg; parg++) printf("$(PYEXT_%s_LOBJS):%s" "CFLAGS_CONFIG += %s\n", uname,htab,*parg); for (parg=p->hdrs; parg && *parg; parg++) printf("$(PYEXT_%s_OBJS):%s" "CFLAGS_CONFIG += %s\n", uname,stab,*parg); for (parg=p->cstd; parg && *parg; parg++) printf("$(PYEXT_%s_LOBJS):%s" "CFLAGS_LAST += %s\n", uname,otab,*parg); for (parg=p->cstd; parg && *parg; parg++) printf("$(PYEXT_%s_OBJS):%s" "CFLAGS_LAST += %s\n", uname,dtab,*parg); if (p->hdrs || p->cstd) printf("\n"); printf("PYEXT_%s_SHARED%s= pyext/%s$(PYTHON_SOEXT)\n",uname,ltab,p->name); printf("PYEXT_%s_STATIC%s= pyext/%s$(OS_ARCHIVE_EXT)\n",uname,ltab,p->name); printf("\n"); for (parg=p->vars; parg && *parg; parg++) printf("$(PYEXT_%s_SHARED):%s" "LDFLAGS_DYNEXT += %s\n", uname,vtab,*parg); for (parg=p->deps; parg && *parg; parg++) printf("$(PYEXT_%s_SHARED):%s%s\n",uname,vtab,*parg); printf("$(PYEXT_%s_SHARED):%s$(PYEXT_%s_LOBJS)\n",uname,vtab,uname); printf("$(PYEXT_%s_STATIC):%s$(PYEXT_%s_OBJS)\n",uname,vtab,uname); printf("\n"); printf("pyext-%s-shared:%s$(PYEXT_%s_SHARED)\n",name,rtab,uname); printf("pyext-%s-static:%s$(PYEXT_%s_STATIC)\n",name,rtab,uname); printf("\n"); printf("pyext-%s-clean:\n",name); printf("\trm -f $(PYEXT_%s_LOBJS)\n",uname); printf("\trm -f $(PYEXT_%s_OBJS)\n",uname); printf("\trm -f $(PYEXT_%s_SHARED)\n",uname); printf("\trm -f $(PYEXT_%s_STATIC)\n",uname); printf("\n"); printf("clean:\tpyext-%s-clean\n",name); printf("\n"); printf(".PHONY:\tpyext-%s-shared\n",name); printf(".PHONY:\tpyext-%s-static\n",name); printf(".PHONY:\tpyext-%s-clean\n",name); printf("\n\n"); } return 0; }