summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2014-02-14 09:09:11 +0000
committerNanang Izzuddin <nanang@teluu.com>2014-02-14 09:09:11 +0000
commitd5b0dee29b910ae8f4867638542463e87bcf8348 (patch)
tree72831ab8978bd14da329f6e15af3ba0d5b631f92
parent10503f79d172614a7d646c320bf24a78c6194755 (diff)
More pjsua2 API (re #1519): added simple tool to check and remove-if-necessary deprecated gcc option '-mno-cygwin' in building pjsua2 python binding on MinGW.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4744 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/swig/python/Makefile10
-rw-r--r--pjsip-apps/src/swig/python/cc_mingw.c154
-rw-r--r--pjsip-apps/src/swig/python/helper.mak4
-rw-r--r--pjsip-apps/src/swig/python/setup.py4
4 files changed, 169 insertions, 3 deletions
diff --git a/pjsip-apps/src/swig/python/Makefile b/pjsip-apps/src/swig/python/Makefile
index 80af9bf9..651ea3f7 100644
--- a/pjsip-apps/src/swig/python/Makefile
+++ b/pjsip-apps/src/swig/python/Makefile
@@ -3,6 +3,9 @@ PYTHON_SO=_pjsua2.so
#PYTHON_SETUP_FLAGS = --inplace
ifeq ($(OS),Windows_NT)
PYTHON_SETUP_FLAGS += --compiler=mingw32
+ GCC_EXE=gcc.exe
+else
+ GCC_EXE=
endif
SWIG_FLAGS += -w312
@@ -11,14 +14,19 @@ SWIG_FLAGS += -w312
all: $(PYTHON_SO)
-$(PYTHON_SO): pjsua2_wrap.cpp setup.py
+$(PYTHON_SO): pjsua2_wrap.cpp setup.py $(GCC_EXE)
python setup.py build $(PYTHON_SETUP_FLAGS)
+gcc.exe: cc_mingw.c
+ gcc -o gcc.exe cc_mingw.c
+ cp gcc.exe g++.exe
+
pjsua2_wrap.cpp: ../pjsua2.i ../symbols.i Makefile $(SRCS)
swig $(SWIG_FLAGS) -python -o pjsua2_wrap.cpp ../pjsua2.i
clean distclean realclean:
rm -rf $(PYTHON_SO) pjsua2_wrap.cpp pjsua2_wrap.h pjsua2.py build *.pyc
+ rm -f gcc.exe g++.exe
install:
python setup.py install --user
diff --git a/pjsip-apps/src/swig/python/cc_mingw.c b/pjsip-apps/src/swig/python/cc_mingw.c
new file mode 100644
index 00000000..b4cf6eab
--- /dev/null
+++ b/pjsip-apps/src/swig/python/cc_mingw.c
@@ -0,0 +1,154 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2014 Teluu Inc. (http://www.teluu.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* A simple proxy application for gcc/g++ to remove '-mno-cygwin' option
+ * when the gcc/g++ doesn't support it. Note that the option seems to be
+ * deprecated and causing compile error since gcc 4.7, while the option is
+ * auto-generated by Python distutils module (up to Python 2.7) in building
+ * Python extension.
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Find gcc executable from env var PATH but omitting current dir */
+const char* find_gcc(const char *gcc_exe)
+{
+ static char fname[256];
+ char spath[1024 * 10];
+ char *p;
+
+ p = getenv("PATH");
+ if (strlen(p) >= sizeof(spath)) {
+ printf("Error: find_gcc() not enough buffer 1\n");
+ return NULL;
+ }
+
+ strncpy(spath, p, sizeof(spath));
+ p = strtok(spath, ";");
+ while (p) {
+ int len;
+
+ /* Skip current dir */
+ if (strcmp(p, ".") == 0) {
+ p = strtok(NULL, ":");
+ continue;
+ }
+
+ len = snprintf(fname, sizeof(fname), "%s\\%s", p, gcc_exe);
+ if (len < 0 || len >= sizeof(fname)) {
+ printf("Error: find_gcc() not enough buffer 2\n");
+ return NULL;
+ }
+
+ if (access(fname, F_OK | X_OK) != -1) {
+ return fname;
+ }
+
+ p = strtok(NULL, ";");
+ }
+
+ return NULL;
+}
+
+int check_gcc_reject_mno_cygwin(const char *gcc_path)
+{
+ FILE *fp;
+ char tmp[1024];
+ const char *p;
+ int ver;
+
+ snprintf(tmp, sizeof(tmp), "%s -mno-cygwin 2>&1", gcc_path);
+ fp = popen(tmp, "r");
+ if (fp == NULL) {
+ printf("Error: failed to run gcc\n" );
+ return -1;
+ }
+
+ while (fgets(tmp, sizeof(tmp), fp) != NULL) {
+ if (strstr(tmp, "unrecognized") && strstr(tmp, "-mno-cygwin"))
+ return 1;
+ }
+
+ pclose(fp);
+ return 0;
+}
+
+int main(int argc, const char const **argv)
+{
+ const char *app = "python cc_mingw.py";
+ char cmd[1024 * 8], *p;
+ int i, len, sz;
+ int ret = 0;
+ const char *spath, *gcc_exe;
+ int remove_mno_cygwin;
+
+ if (strstr(argv[0], "gcc") || strstr(argv[0], "GCC")) {
+ gcc_exe = "gcc.exe";
+ } else if (strstr(argv[0], "g++") || strstr(argv[0], "G++")) {
+ gcc_exe = "g++.exe";
+ } else {
+ printf("Error: app name not gcc/g++\n");
+ return -10;
+ }
+
+ /* Resolve GCC path from PATH env var */
+ gcc_exe = find_gcc(gcc_exe);
+ if (!gcc_exe) {
+ printf("Error: real gcc/g++ not found\n");
+ return -20;
+ }
+
+ /* Check if GCC rejects '-mno-cygwin' option */
+ remove_mno_cygwin = check_gcc_reject_mno_cygwin(gcc_exe);
+ if (remove_mno_cygwin < 0)
+ return -30;
+
+ len = snprintf(cmd, sizeof(cmd), "%s", gcc_exe);
+ p = cmd + len;
+ sz = sizeof(cmd) - len;
+ for (i = 1; i < argc && sz > 0; ++i) {
+
+ if (remove_mno_cygwin && strcmp(argv[i], "-mno-cygwin") == 0) {
+ printf("Removed option '-mno-cygwin'.\n");
+ continue;
+ }
+
+ len = snprintf(p, sz, " %s", argv[i]);
+ if (len < 0 || len >= sz) {
+ ret = E2BIG;
+ break;
+ }
+ p += len;
+ sz -= len;
+ }
+
+ if (!ret) {
+ //printf("cmd = %s\n", cmd);
+ ret = system(cmd);
+ }
+
+ if (ret) {
+ printf("Error: %s\n", strerror(ret));
+ }
+
+ return ret;
+}
diff --git a/pjsip-apps/src/swig/python/helper.mak b/pjsip-apps/src/swig/python/helper.mak
index 41baf2b2..dafdb284 100644
--- a/pjsip-apps/src/swig/python/helper.mak
+++ b/pjsip-apps/src/swig/python/helper.mak
@@ -2,12 +2,12 @@ include ../../../../build.mak
lib_dir:
@for token in `echo $(APP_LDFLAGS)`; do \
- echo $$token | grep L | sed 's/-L//'; \
+ echo $$token | grep \\-L | sed 's/-L//'; \
done
inc_dir:
@for token in `echo $(APP_CFLAGS)`; do \
- echo $$token | grep I | sed 's/-I//'; \
+ echo $$token | grep \\-I | sed 's/-I//'; \
done
libs:
diff --git a/pjsip-apps/src/swig/python/setup.py b/pjsip-apps/src/swig/python/setup.py
index b475fb1b..ace24d31 100644
--- a/pjsip-apps/src/swig/python/setup.py
+++ b/pjsip-apps/src/swig/python/setup.py
@@ -98,6 +98,10 @@ if platform.system() == 'Darwin':
if platform.mac_ver()[0].startswith("10.7"):
extra_link_args += ["-framework", "AudioUnit"]
+# MinGW specific action: put current working dir to PATH, so Python distutils
+# will invoke our dummy gcc/g++ instead, which is in the current working dir.
+if platform.system()=='Windows' and os.environ["MSYSTEM"].find('MINGW')!=-1:
+ os.environ["PATH"] = "." + os.pathsep + os.environ["PATH"]
setup(name="pjsua2",
version=pj_version,