Blame project/pyexts.c

e71262
/*******************************************************************/
289419
/*  sbpython2: external configurable build project for Python-2.7. */
e71262
/*  Copyright (C) 2018  Z. Gilboa                                  */
289419
/*  Released under the Standard MIT License; see COPYING.SBPYTHON2.*/
e71262
/*******************************************************************/
e71262
e71262
/*******************************************************************/
e71262
/* pyexts.c: a simple development-time utility for generating      */
e71262
/* make rules for python's extension modules. The utility is       */
289419
/* included with the sbpython2 project for reference only.         */
e71262
/*                                                                 */
e71262
/* cc -std=c99 -D_XOPEN_SOURCE=700 pyexts.c                        */
e71262
/*******************************************************************/
e71262
e71262
#include <stdio.h>
e71262
#include <string.h>
e71262
e71262
#define PYEXT_LIST(...)                   (const char *[]){__VA_ARGS__,0}
e71262
#define PYEXT_SIMPLE(name,...)            {name,PYEXT_LIST(__VA_ARGS__),0,0,0,0}
e71262
e71262
#define PYEXT_COMMON(name,hvar,lvar,...)  {name,PYEXT_LIST(__VA_ARGS__), \
e71262
                                           PYEXT_LIST(hvar),0,           \
e71262
                                           PYEXT_LIST(lvar),0}
e71262
e71262
#define PYEXT_ALTSTD(name,cstd,...)       {name,PYEXT_LIST(__VA_ARGS__), \
e71262
                                           0,PYEXT_LIST(cstd),0,0}
e71262
e71262
struct pyext_meta {
e71262
	const char *	name;
e71262
	const char **	srcs;
e71262
	const char **	hdrs;
e71262
	const char **	cstd;
e71262
	const char **	vars;
e71262
	const char **	deps;
e71262
};
e71262
e71262
static const struct pyext_meta pyexts[] = {
e71262
	PYEXT_SIMPLE("_multibytecodec","cjkcodecs/multibytecodec"),
e71262
	PYEXT_SIMPLE("_codecs_cn",     "cjkcodecs/_codecs_cn"),
e71262
	PYEXT_SIMPLE("_codecs_hk",     "cjkcodecs/_codecs_hk"),
e71262
	PYEXT_SIMPLE("_codecs_jp",     "cjkcodecs/_codecs_jp"),
e71262
	PYEXT_SIMPLE("_codecs_kr",     "cjkcodecs/_codecs_kr"),
e71262
	PYEXT_SIMPLE("_codecs_tw",     "cjkcodecs/_codecs_tw"),
e71262
	PYEXT_SIMPLE("_codecs_iso2022","cjkcodecs/_codecs_iso2022"),
e71262
e71262
	PYEXT_SIMPLE("_bisect",        "_bisectmodule"),
e71262
	PYEXT_SIMPLE("_collections",   "_collectionsmodule"),
e71262
	PYEXT_SIMPLE("_csv",           "_csv"),
e71262
	PYEXT_SIMPLE("_ctypes_test",   "_ctypes/_ctypes_test"),
e71262
	PYEXT_SIMPLE("_functools",     "_functoolsmodule"),
e71262
	PYEXT_SIMPLE("_heapq",         "_heapqmodule"),
e71262
	PYEXT_SIMPLE("_hotshot",       "_hotshot"),
e71262
	PYEXT_SIMPLE("_json",          "_json"),
e71262
	PYEXT_SIMPLE("_locale",        "_localemodule"),
e71262
	PYEXT_SIMPLE("_lsprof",        "_lsprof","rotatingtree"),
e71262
	PYEXT_SIMPLE("_random",        "_randommodule"),
e71262
	PYEXT_SIMPLE("_socket",        "socketmodule","timemodule"),
e71262
	PYEXT_SIMPLE("_struct",        "_struct"),
e71262
	PYEXT_SIMPLE("_testcapi",      "_testcapimodule"),
e71262
e71262
	PYEXT_SIMPLE("array",          "arraymodule"),
e71262
	PYEXT_SIMPLE("audioop",        "audioop"),
e71262
	PYEXT_SIMPLE("binascii",       "binascii"),
e71262
	PYEXT_SIMPLE("cPickle",        "cPickle"),
e71262
	PYEXT_SIMPLE("cStringIO",      "cStringIO"),
e71262
	PYEXT_SIMPLE("cmath",          "cmathmodule","_math"),
e71262
	PYEXT_SIMPLE("crypt",          "cryptmodule"),
e71262
	PYEXT_SIMPLE("datetime",       "datetimemodule","timemodule"),
e71262
	PYEXT_SIMPLE("fcntl",          "fcntlmodule"),
e71262
	PYEXT_SIMPLE("future_builtins","future_builtins"),
e71262
	PYEXT_SIMPLE("grp",            "grpmodule"),
e71262
	PYEXT_SIMPLE("itertools",      "itertoolsmodule"),
e71262
	PYEXT_SIMPLE("math",           "mathmodule","_math"),
e71262
	PYEXT_SIMPLE("mmap",           "mmapmodule"),
e71262
	PYEXT_SIMPLE("operator",       "operator"),
e71262
	PYEXT_SIMPLE("ossaudiodev",    "ossaudiodev"),
e71262
	PYEXT_SIMPLE("parser",         "parsermodule"),
e71262
	PYEXT_SIMPLE("resource",       "resource"),
e71262
	PYEXT_SIMPLE("select",         "selectmodule"),
e71262
	PYEXT_SIMPLE("spwd",           "spwdmodule"),
e71262
	PYEXT_SIMPLE("strop",          "stropmodule"),
e71262
	PYEXT_SIMPLE("syslog",         "syslogmodule"),
e71262
	PYEXT_SIMPLE("termios",        "termios"),
e71262
	PYEXT_SIMPLE("time",           "timemodule"),
e71262
	PYEXT_SIMPLE("unicodedata",    "unicodedata"),
e71262
e71262
	PYEXT_COMMON("_curses",        "$(CFLAGS_NCURSES)", "$(LDFLAGS_NCURSES)",  "_cursesmodule"),
e71262
	PYEXT_COMMON("_curses_panel",  "$(CFLAGS_NCURSES)", "$(LDFLAGS_NCURSES)",  "_curses_panel"),
e71262
	PYEXT_COMMON("_elementtree",   "-UVERSION",         "-lexpat",             "_elementtree"),
e71262
	PYEXT_COMMON("_hashlib",       0,                   "-lssl -lcrypto",      "_hashopenssl"),
e71262
	PYEXT_COMMON("_ssl",           0,                   "-lssl -lcrypto",      "_ssl"),
e71262
	PYEXT_COMMON("bz2",            0,                   "-lbz2",               "bz2module"),
e71262
	PYEXT_COMMON("gdbm",           0,                   "-lgdbm",              "gdbmmodule"),
e71262
	PYEXT_COMMON("readline",       0,                   "-lreadline",          "readline"),
e71262
	PYEXT_COMMON("pyexpat",        0,                   "-lexpat",             "pyexpat"),
e71262
	PYEXT_COMMON("zlib",           0,                   "-lz",                 "zlibmodule"),
e71262
e71262
	PYEXT_COMMON("_ctypes",0,"-lffi",
e71262
	             "_ctypes/_ctypes",
e71262
	             "_ctypes/callbacks",
e71262
	             "_ctypes/callproc",
e71262
	             "_ctypes/stgdict",
e71262
	             "_ctypes/cfield"),
e71262
e71262
	PYEXT_COMMON("_io",0,0,
e71262
	             "_io/bufferedio",
e71262
	             "_io/bytesio",
e71262
	             "_io/fileio",
e71262
	             "_io/iobase",
e71262
	             "_io/_iomodule",
e71262
	             "_io/stringio",
e71262
	             "_io/textio"),
e71262
e71262
	PYEXT_COMMON("_multiprocessing",0,0,
e71262
	             "_multiprocessing/multiprocessing",
e71262
	             "_multiprocessing/socket_connection",
e71262
	             "_multiprocessing/semaphore"),
e71262
e71262
	PYEXT_COMMON("_sqlite3",
e71262
	             "$(CFLAGS_SQLITE)",
e71262
	             "$(LDFLAGS_SQLITE)",
e71262
	             "_sqlite/cache",
e71262
	             "_sqlite/connection",
e71262
	             "_sqlite/cursor",
e71262
	             "_sqlite/microprotocols",
e71262
	             "_sqlite/module",
e71262
	             "_sqlite/prepare_protocol",
e71262
	             "_sqlite/row",
e71262
	             "_sqlite/statement",
e71262
	             "_sqlite/util"),
e71262
e71262
	PYEXT_COMMON("dbm",
e71262
	             "$(CFLAGS_DBM)",
e71262
	             "$(LDFLAGS_DBM)",
e71262
	             "dbmmodule"),
e71262
e71262
	PYEXT_ALTSTD("linuxaudiodev",
e71262
	             "-std=gnu99",
e71262
	             "linuxaudiodev"),
e71262
e71262
	{0,0,0,0,0,0},
e71262
};
e71262
e71262
static void pyext_uppercase(char * buf, const char * name)
e71262
{
e71262
	const char *	src;
e71262
	char *		dst;
e71262
e71262
	src = name;
e71262
	dst = buf;
e71262
e71262
	for (; *src; )
e71262
		*dst++ = ((*src >= 'a') && (*src <= 'z'))
e71262
			? 'A' - 'a' + *src++ : *src++;
e71262
e71262
	*dst = 0;
e71262
}
e71262
f0663f
int main(int argc, char ** argv)
e71262
{
e71262
	const struct pyext_meta *	p;
e71262
	size_t				nlen;
e71262
	const char **			parg;
e71262
	const char *			dtab;
e71262
	const char *			otab;
e71262
	const char *			htab;
e71262
	const char *			stab;
e71262
	const char *			ltab;
e71262
	const char *			rtab;
e71262
	const char *			vtab;
e71262
	const char *			name;
e71262
	char				uname[64];
e71262
f0663f
	if ((argc == 2) && !strcmp(argv[1],"--py-init-func")) {
f0663f
		for (p=pyexts; p->name; p++)
f0663f
			printf("PY_INIT_FUNC(init%s);\n",p->name);
f0663f
f0663f
		return 0;
f0663f
	}
f0663f
f0663f
	if ((argc == 2) && !strcmp(argv[1],"--init-func-ptr")) {
f0663f
		for (p=pyexts; p->name; p++) {
f0663f
			nlen = strlen(p->name);
f0663f
f0663f
			if (nlen <= 3)
f0663f
				dtab = "\t\t\t";
f0663f
f0663f
			else if (nlen <= 11)
f0663f
				dtab = "\t\t";
f0663f
f0663f
			else
f0663f
				dtab = "\t";
f0663f
f0663f
			if (nlen <= 9)
f0663f
				rtab = "\t\t";
f0663f
f0663f
			else
f0663f
				rtab = "\t";
f0663f
f0663f
			printf("\t{\"%s\",%sinit%s},%s\\\n",
f0663f
				p->name,dtab,p->name,rtab);
f0663f
		}
f0663f
f0663f
		return 0;
f0663f
	}
f0663f
e71262
	for (p=pyexts; p->name; p++) {
e71262
		/* init */
e71262
		name = (p->name[0] == '_') ? &p->name[1] : p->name;
e71262
		nlen = strlen(name);
e71262
e71262
		pyext_uppercase(uname,name);
e71262
e71262
		/* pretty */
e71262
		dtab = (nlen <= 4)
e71262
			? "\t\t\t"
e71262
			: (nlen <= 12)
e71262
				? "\t\t" : "\t";
e71262
e71262
		otab = (nlen <= 3)
e71262
			? "\t\t\t"
e71262
			: (nlen <= 11)
e71262
				? "\t\t" : "\t";
e71262
e71262
		ltab = (nlen <= 2)
e71262
			? "\t\t\t"
e71262
			: (nlen <= 10)
e71262
				? "\t\t" : "\t";
e71262
e71262
		rtab = (nlen <= 1)
e71262
			? "\t\t\t"
e71262
			: (nlen <= 9)
e71262
				? "\t\t" : "\t";
e71262
e71262
		vtab = (nlen <= 6)
e71262
			? "\t\t"
e71262
			: (nlen <= 14)
e71262
				? "\t" : "";
e71262
e71262
		htab = (nlen <= 8)
e71262
			? "\t\t" : "\t";
e71262
e71262
		stab = (nlen <= 9)
e71262
			? "\t\t" : "\t";
e71262
e71262
e71262
		/* output */
e71262
		printf("# %s\n",p->name);
e71262
e71262
		for (parg=p->srcs; *parg; parg++)
e71262
			printf("PYEXT_%s_SRCS%s+= "
e71262
				"Modules/%s.c\n",
e71262
				uname,dtab,*parg);
e71262
e71262
		printf("\n");
e71262
		printf("PYEXT_%s_LOBJS%s= $(PYEXT_%s_SRCS:.c=.lo)\n",uname,otab,uname);
e71262
		printf("PYEXT_%s_OBJS%s= $(PYEXT_%s_SRCS:.c=.o)\n",uname,dtab,uname);
e71262
		printf("\n");
e71262
e71262
		for (parg=p->hdrs; parg && *parg; parg++)
e71262
			printf("$(PYEXT_%s_LOBJS):%s"
e71262
				"CFLAGS_CONFIG += %s\n",
e71262
				uname,htab,*parg);
e71262
e71262
		for (parg=p->hdrs; parg && *parg; parg++)
e71262
			printf("$(PYEXT_%s_OBJS):%s"
e71262
				"CFLAGS_CONFIG += %s\n",
e71262
				uname,stab,*parg);
e71262
e71262
		for (parg=p->cstd; parg && *parg; parg++)
e71262
				printf("$(PYEXT_%s_LOBJS):%s"
e71262
					"CFLAGS_LAST += %s\n",
e71262
					uname,otab,*parg);
e71262
e71262
		for (parg=p->cstd; parg && *parg; parg++)
e71262
			printf("$(PYEXT_%s_OBJS):%s"
e71262
				"CFLAGS_LAST += %s\n",
e71262
				uname,dtab,*parg);
e71262
e71262
		if (p->hdrs || p->cstd)
e71262
			printf("\n");
e71262
e71262
		printf("PYEXT_%s_SHARED%s= pyext/%s$(OS_LIB_SUFFIX)\n",uname,ltab,p->name);
e71262
		printf("PYEXT_%s_STATIC%s= pyext/%s$(OS_ARCHIVE_EXT)\n",uname,ltab,p->name);
e71262
		printf("\n");
e71262
e71262
		for (parg=p->vars; parg && *parg; parg++)
e71262
			printf("$(PYEXT_%s_SHARED):%s"
e71262
				"LDFLAGS_DYNEXT += %s\n",
e71262
				uname,vtab,*parg);
e71262
e71262
		for (parg=p->deps; parg && *parg; parg++)
e71262
			printf("$(PYEXT_%s_SHARED):%s%s\n",uname,vtab,*parg);
e71262
e71262
		printf("$(PYEXT_%s_SHARED):%s$(PYEXT_%s_LOBJS)\n",uname,vtab,uname);
e71262
		printf("$(PYEXT_%s_STATIC):%s$(PYEXT_%s_OBJS)\n",uname,vtab,uname);
e71262
e71262
		printf("\n");
e71262
		printf("pyext-%s-shared:%s$(PYEXT_%s_SHARED)\n",name,rtab,uname);
e71262
		printf("pyext-%s-static:%s$(PYEXT_%s_STATIC)\n",name,rtab,uname);
e71262
e71262
		printf("\n");
e71262
		printf("pyext-%s-clean:\n",name);
e71262
		printf("\trm -f $(PYEXT_%s_LOBJS)\n",uname);
e71262
		printf("\trm -f $(PYEXT_%s_OBJS)\n",uname);
e71262
		printf("\trm -f $(PYEXT_%s_SHARED)\n",uname);
e71262
		printf("\trm -f $(PYEXT_%s_STATIC)\n",uname);
e71262
e71262
		printf("\n");
e71262
		printf("clean:\tpyext-%s-clean\n",name);
e71262
e71262
		printf("\n");
e71262
		printf(".PHONY:\tpyext-%s-shared\n",name);
e71262
		printf(".PHONY:\tpyext-%s-static\n",name);
e71262
		printf(".PHONY:\tpyext-%s-clean\n",name);
e71262
		printf("\n\n");
e71262
	}
e71262
e71262
	return 0;
e71262
}