Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add swig/4.0.1 #1717

Merged
merged 7 commits into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions recipes/swig/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sources:
"4.0.1":
url: "https://github.com/swig/swig/archive/rel-4.0.1.tar.gz"
sha256: "2eaf6fb89d071d1be280bf995c63360b3729860c0da64948123b5d7e4cfb6cb7"
patches:
"4.0.1":
- base_path: "source_subfolder"
patch_file: "patches/0001-swig-linux-library-path.patch"
- base_path: "source_subfolder"
patch_file: "patches/0002-do-not-define-SWIG_LIB_WIN_UNIX.patch"
129 changes: 129 additions & 0 deletions recipes/swig/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from conans import ConanFile, tools, AutoToolsBuildEnvironment
from contextlib import contextmanager
import os


class SwigConan(ConanFile):
name = "swig"
description = "SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages."
url = "https://github.com/conan-io/conan-center-index"
homepage = "http://www.swig.org"
license = "GPL-3.0-or-later"
topics = ("conan", "swig", "python", "java", "wrapper")
exports_sources = "patches/**"
settings = "os", "arch", "compiler"
madebr marked this conversation as resolved.
Show resolved Hide resolved

_autotools = None

@property
def _source_subfolder(self):
return "source_subfolder"

def configure(self):
del self.settings.compiler.libcxx
del self.settings.compiler.cppstd

def build_requirements(self):
if tools.os_info.is_windows and not tools.get_env("CONAN_BASH_PATH") \
and tools.os_info.detect_windows_subsystem() != "msys2":
self.build_requires("msys2/20190524")
if tools.os_info.is_windows:
self.build_requires("winflexbison/2.5.22")
else:
self.build_requires("bison/3.5.3")
self.build_requires("automake/1.16.2")

def requirements(self):
self.requires("pcre/8.41")

def source(self):
tools.get(**self.conan_data["sources"][self.version])
os.rename("swig-rel-{}".format(self.version), self._source_subfolder)

@contextmanager
def _build_context(self):
if self.settings.compiler == "Visual Studio":
with tools.vcvars(self.settings):
env = {
"CC": "{} cl -nologo".format(tools.unix_path(self.deps_user_info["automake"].compile)),
"CXX": "{} cl -nologo".format(tools.unix_path(self.deps_user_info["automake"].compile)),
"AR": "{} link".format(self.deps_user_info["automake"].ar_lib),
"LD": "link",
}
with tools.environment_append(env):
yield
else:
yield

def _configure_autotools(self):
if self._autotools:
return self._autotools

self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows)
deps_libpaths = self._autotools.library_paths
deps_libs = self._autotools.libs
deps_defines = self._autotools.defines
if self.settings.os == "Windows" and self.settings.compiler != "Visual Studio":
self._autotools.link_flags.append("-static")

libargs = list("-L\"{}\"".format(p) for p in deps_libpaths) + list("-l\"{}\"".format(l) for l in deps_libs)
args = [
"PCRE_LIBS={}".format(" ".join(libargs)),
"PCRE_CPPFLAGS={}".format(" ".join("-D{}".format(define) for define in deps_defines)),
"--host={}".format(self.settings.arch),
"--with-swiglibdir={}".format(self._swiglibdir),
]
if self.settings.compiler == "Visual Studio":
self.output.warn("Visual Studio compiler cannot create ccache-swig. Disabling ccache-swig.")
args.append("--disable-ccache")
self._autotools.flags.append("-FS")

self._autotools.libs = []
self._autotools.library_paths = []

self._autotools.configure(args=args, configure_dir=self._source_subfolder)
return self._autotools

def _patch_sources(self):
for patch in self.conan_data["patches"][self.version]:
tools.patch(**patch)

def build(self):
self._patch_sources()
with tools.chdir(os.path.join(self._source_subfolder)):
self.run("./autogen.sh", win_bash=tools.os_info.is_windows)
with self._build_context():
autotools = self._configure_autotools()
autotools.make()

def package(self):
self.copy(pattern="LICENSE*", dst="licenses", src=self._source_subfolder)
self.copy(pattern="COPYRIGHT", dst="licenses", src=self._source_subfolder)
with self._build_context():
autotools = self._configure_autotools()
autotools.install()

if self.settings.compiler != "Visual Studio":
with tools.chdir(os.path.join(self.package_folder, "bin")):
strip = tools.get_env("STRIP") or tools.which("strip")
ext = ".exe" if tools.os_info.is_windows else ""
if strip:
self.run("{} swig{}".format(strip, ext), win_bash=tools.os_info.is_windows)
self.run("{} ccache-swig{}".format(strip, ext), win_bash=tools.os_info.is_windows)

@property
def _swiglibdir(self):
return os.path.join(self.package_folder, "bin", "swiglib").replace("\\", "/")

def package_id(self):
# Verilator is a executable-only package, so the compiler version does not matter
del self.info.settings.compiler.version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very interesting ...

Copy link
Contributor Author

@madebr madebr Jun 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this recipe needs the same treatment as cmake: #1783

madebr marked this conversation as resolved.
Show resolved Hide resolved

def package_info(self):
# FIXME: Don't set cmake_find_package name because conan cmake generators do not define SWIG_EXECUTABLE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this <PKG-NAME>_EXECUTABLE something standard in CMake? What happens if the sources provide more than one executable? Asking this just to know if it makes sense to add this as a feature in the CMake generators

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I's quite common:

Also, some provide more than one _EXECUTABLE variable:

But there are exceptions:

Also, it would be interesting to provide these as targets:

# self.cpp_info.names["cmake_find_package"] = "SWIG"
# self.cpp_info.names["cmake_find_package_multi"] = "SWIG"

bindir = os.path.join(self.package_folder, "bin")
self.output.info("Appending PATH environment variable: {}".format(bindir))
self.env_info.PATH.append(bindir)
43 changes: 43 additions & 0 deletions recipes/swig/all/patches/0001-swig-linux-library-path.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--- Source/Modules/main.cxx
+++ Source/Modules/main.cxx
@@ -879,6 +879,23 @@
}
}

+#if defined(HAVE_UNISTD_H)
+#include <libgen.h>
+#include <unistd.h>
+
+static String *get_exe_path(void) {
+ char buffer[PATH_MAX];
+ ssize_t nb = readlink("/proc/self/exe", buffer, PATH_MAX);
+ if (nb != -1) {
+ buffer[nb] = '\0';
+ dirname(buffer);
+ strcat(buffer, "/swiglib");
+ return NewStringWithSize(buffer, strlen(buffer));
+ }
+ return NewString(SWIG_LIB);
+}
+#endif
+
int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
char *c;

@@ -938,13 +953,15 @@
char buf[MAX_PATH];
char *p;
if (!(GetModuleFileName(0, buf, MAX_PATH) == 0 || (p = strrchr(buf, '\\')) == 0)) {
*(p + 1) = '\0';
- SwigLib = NewStringf("%sLib", buf); // Native windows installation path
+ SwigLib = NewStringf("%sswiglib", buf); // Native windows installation path
} else {
SwigLib = NewStringf(""); // Unexpected error
}
if (Len(SWIG_LIB_WIN_UNIX) > 0)
SwigLibWinUnix = NewString(SWIG_LIB_WIN_UNIX); // Unix installation path using a drive letter (for msys/mingw)
+#elif defined(HAVE_UNISTD_H)
+ SwigLib = get_exe_path();
#else
SwigLib = NewString(SWIG_LIB);
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- configure.ac
+++ configure.ac
@@ -2728,7 +2728,7 @@
*-*-cygwin*) SWIG_LIB_WIN_UNIX=`cygpath --mixed "$SWIG_LIB"`;;
*) SWIG_LIB_WIN_UNIX="";;
esac
-AC_DEFINE_UNQUOTED(SWIG_LIB_WIN_UNIX, ["$SWIG_LIB_WIN_UNIX"], [Directory for SWIG system-independent libraries (Unix install on native Windows)])
+AC_DEFINE_UNQUOTED(SWIG_LIB_WIN_UNIX, [""], [Directory for SWIG system-independent libraries (Unix install on native Windows)])

SWIG_LIB_PREINST=$ABS_SRCDIR/Lib
AC_SUBST(SWIG_LIB_PREINST)
16 changes: 16 additions & 0 deletions recipes/swig/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 2.8.12)
project(PackageTest C)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

find_package(SWIG REQUIRED)
include(UseSWIG)

swig_add_library(${PROJECT_NAME}
TYPE MODULE
LANGUAGE python
SOURCES
test.i
test_package.c
)
31 changes: 31 additions & 0 deletions recipes/swig/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from conans import CMake, ConanFile, tools
from conans.errors import ConanException
import os


class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"

# # FIXME: cpython is not available on CCI (yet)
# def build(self):
# cmake = CMake(self)
# cmake.configure(args=["--trace", "--trace-expand"])
# cmake.build()
#
# def build_requirements(self):
# self.build_requires("cpython/3.8.3")
#
# def requirements(self):
# self.requires("cpython/3.8.3")

def test(self):
if not tools.cross_building(self.settings):
# # FIXME: cpython is not available on CCI (yet)
# with tools.chdir("lib"):
# self.run("python -c \"import sys; import _PackageTest; gcd = _PackageTest.gcd(12, 16); print('gcd =', gcd); sys.exit(0 if gcd == 4 else 1)\"", run_environment=True)
# self.run("python -c \"import sys; import _PackageTest; foo = _PackageTest.cvar.foo; print('foo =', foo); sys.exit(0 if foo == 3.14159265359 else 1)\"", run_environment=True)
testdir = os.path.dirname(os.path.realpath(__file__))
self.run("swig -python -outcurrentdir %s" % os.path.join(testdir, "test.i"))
if not os.path.isfile("example.py"):
raise ConanException("example.py is not created by swig")
7 changes: 7 additions & 0 deletions recipes/swig/all/test_package/test.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* File : example.i */
%module example

%inline %{
extern int gcd(int u, int v);
extern double foo;
%}
30 changes: 30 additions & 0 deletions recipes/swig/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Source: https://en.wikipedia.org/wiki/Binary_GCD_algorithm#Recursive_version_in_C
int gcd(int u, int v) {
// simple cases (termination)
if (u == v)
return u;

if (u == 0)
return v;

if (v == 0)
return u;

// look for factors of 2
if (~u & 1) // u is even
if (v & 1) // v is odd
return gcd(u >> 1, v);
else // both u and v are even
return gcd(u >> 1, v >> 1) << 1;

if (~v & 1) // u is odd, v is even
return gcd(u, v >> 1);

// reduce larger argument
if (u > v)
return gcd((u - v) >> 1, v);

return gcd((v - u) >> 1, u);
}

double foo = 3.14159265359;
3 changes: 3 additions & 0 deletions recipes/swig/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"4.0.1":
folder: "all"