Skip to content

Commit

Permalink
Merge 8397a86 into 93aca7b
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Aug 8, 2016
2 parents 93aca7b + 8397a86 commit 6cb595a
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 17 deletions.
76 changes: 59 additions & 17 deletions skbuild/setuptools_wrap.py
Expand Up @@ -11,10 +11,7 @@
from .command import build, install, clean, bdist, bdist_wheel
from .exceptions import SKBuildError

try:
from setuptools import setup as upstream_setup
except ImportError:
from distutils.core import setup as upstream_setup
from setuptools import setup as upstream_setup


def move_arg(arg, a, b, newarg=None, f=lambda x: x, concatenate_value=False):
Expand Down Expand Up @@ -122,33 +119,78 @@ def setup(*args, **kw):
# the data files on the bottom would have been mapped to
# "top.not_a_subpackage" instead of "top", proper -- had such a package been
# specified.
package_prefixes = list(sorted(
(
(package_dir[package].replace('.', '/'), package)
for package in packages
),
key=lambda tup: len(tup[0]),
reverse=True
))
def get_package_prefix(package, package_dir):
"""Return the directory, relative to the top of the source
distribution, where package 'package' should be found
(at least according to the 'package_dir' option, if any).
Modified from Python 2.7.12/3.5.2
distutils.command.build_py:get_package_dir"""

path = package.split('.')

if not package_dir:
if path:
return os.path.join(*path)
else:
return ''
else:
tail = []
while path:
try:
pdir = package_dir['.'.join(path)]
except KeyError:
tail.insert(0, path[-1])
del path[-1]
else:
tail.insert(0, pdir)
return os.path.join(*tail)
else:
# Oops, got all the way through 'path' without finding a
# match in package_dir. If package_dir defines a directory
# for the root (nameless) package, then fallback on it;
# otherwise, we might as well have not consulted
# package_dir at all, as we just use the directory implied
# by 'tail' (which should be the same as the original value
# of 'path' at this point).
pdir = package_dir.get('')
if pdir is not None:
tail.insert(0, pdir)

if tail:
return os.path.join(*tail)
else:
return ''

package_prefixes = []
for package in packages:
prefix = (get_package_prefix(package, package_dir), package)
package_prefixes.append(prefix)
# Add the root (nameless) package
prefix = (get_package_prefix('', package_dir), '')
package_prefixes.append(prefix)
package_prefixes = sorted(package_prefixes,
key=lambda tup: len(tup[0]),
reverse=True)

try:
cmkr = cmaker.CMaker()
cmkr.configure(cmake_args)
cmkr.make(make_args)
except SKBuildError as e:
except SKBuildError as error:
import traceback
print("Traceback (most recent call last):")
traceback.print_tb(sys.exc_info()[2])
print()
sys.exit(e)
sys.exit(error)

_classify_files(cmkr.install(), package_data, package_prefixes, py_modules,
scripts, new_scripts, data_files)

kw['package_data'] = package_data
kw['package_dir'] = {
package: os.path.join(cmaker.CMAKE_INSTALL_DIR, prefix)
for prefix, package in package_prefixes
for package, prefix in package_dir.items()
}

kw['py_modules'] = py_modules
Expand Down Expand Up @@ -178,7 +220,7 @@ def setup(*args, **kw):


def _classify_files(install_paths, package_data, package_prefixes, py_modules,
scripts, new_scripts, data_files):
scripts, new_scripts, data_files):
install_root = os.path.join(os.getcwd(), cmaker.CMAKE_INSTALL_DIR)
for path in install_paths:
found_package = False
Expand All @@ -194,7 +236,7 @@ def _classify_files(install_paths, package_data, package_prefixes, py_modules,
" Project Root : {}\n"
" Violating File: {}\n").format(install_root, test_path))

# peel off the 'skbuild' prefix
# peel off the 'skbuild' prefix
path = os.path.relpath(path, cmaker.CMAKE_INSTALL_DIR)

# check to see if path is part of a package
Expand Down
16 changes: 16 additions & 0 deletions tests/test_root_package.py
@@ -0,0 +1,16 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""test_root_package
----------------------------------
Ensure that skbuild supports the root package, i.e. the nameless top level
"package".
"""

from . import project_setup_py_test


@project_setup_py_test(("unit", "root-package"), ["build"], clear_cache=True)
def test_hello_builds():
pass
11 changes: 11 additions & 0 deletions tests/unit/root-package/CMakeLists.txt
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.5.0)

project(root-package)

enable_testing()

find_package(PythonInterp REQUIRED)
find_package(PythonLibs REQUIRED)
find_package(PythonExtensions REQUIRED)

add_subdirectory(lib)
9 changes: 9 additions & 0 deletions tests/unit/root-package/lib/CMakeLists.txt
@@ -0,0 +1,9 @@
add_library(_hello MODULE _hello.cxx)
python_extension_module(_hello)

add_test(NAME hello
COMMAND ${PYTHON_EXECUTABLE} -m hello
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX})

install(TARGETS _hello LIBRARY DESTINATION "lib")
install(FILES hello.py DESTINATION "lib")
65 changes: 65 additions & 0 deletions tests/unit/root-package/lib/_hello.cxx
@@ -0,0 +1,65 @@

// Python includes
#include <Python.h>

// STD includes
#include <stdio.h>

//-----------------------------------------------------------------------------
static PyObject *hello_example(PyObject *self, PyObject *args)
{
// Unpack a string from the arguments
const char *strArg;
if (!PyArg_ParseTuple(args, "s", &strArg))
return NULL;

// Print message and return None
PySys_WriteStdout("Hello, %s! :)\n", strArg);
Py_RETURN_NONE;
}

//-----------------------------------------------------------------------------
static PyObject *elevation_example(PyObject *self, PyObject *args)
{
// Return an integer
return PyLong_FromLong(21463L);
}

//-----------------------------------------------------------------------------
static PyMethodDef hello_methods[] = {
{
"hello",
hello_example,
METH_VARARGS,
"Prints back 'Hello <param>', for example example: hello.hello('you')"
},

{
"size",
elevation_example,
METH_VARARGS,
"Returns elevation of Nevado Sajama."
},
{NULL, NULL, 0, NULL} /* Sentinel */
};

//-----------------------------------------------------------------------------
#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC init_hello(void)
{
(void) Py_InitModule("_hello", hello_methods);
}
#else /* PY_MAJOR_VERSION >= 3 */
static struct PyModuleDef hello_module_def = {
PyModuleDef_HEAD_INIT,
"_hello",
"Internal \"_hello\" module",
-1,
hello_methods
};

PyMODINIT_FUNC PyInit__hello(void)
{
return PyModule_Create(&hello_module_def);
}
#endif /* PY_MAJOR_VERSION >= 3 */
1 change: 1 addition & 0 deletions tests/unit/root-package/lib/hello.py
@@ -0,0 +1 @@
from ._hello import hello
11 changes: 11 additions & 0 deletions tests/unit/root-package/setup.py
@@ -0,0 +1,11 @@
from skbuild import setup

setup(
name="root-package",
version="1.2.3",
description="a package that populates the root (nameless) package",
author='The scikit-build team',
license="MIT",
package_dir={'': 'lib'},
py_modules=['hello']
)

0 comments on commit 6cb595a

Please sign in to comment.