Blame project/pyexts.c

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