Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit 27575fb

Browse files
committed
Windows support
1 parent 301a314 commit 27575fb

File tree

4 files changed

+65
-18
lines changed

4 files changed

+65
-18
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[![Build Status](https://travis-ci.org/asottile/setuptools-golang.svg?branch=master)](https://travis-ci.org/asottile/setuptools-golang)
2+
[![Build status](https://ci.appveyor.com/api/projects/status/j4i2pc4o7pby3wdn/branch/master?svg=true)](https://ci.appveyor.com/project/asottile/setuptools-golang/branch/master)
23
[![Coverage Status](https://img.shields.io/coveralls/asottile/setuptools-golang.svg?branch=master)](https://coveralls.io/r/asottile/setuptools-golang)
34

45
setuptools-golang
@@ -13,6 +14,12 @@ This requires golang >= 1.5. It is currently tested against 1.6 and 1.7.
1314
This requires python >= 2.7. It is currently tested against 2.7, 3.5, 3.6,
1415
and pypy.
1516

17+
## Platform Support
18+
19+
- linux
20+
- macos
21+
- win32 (32 bit cpython, 32 bit go 1.10+)
22+
1623
## Usage
1724

1825
Add `setuptools-golang` to the `setup_requires` in your setup.py and

appveyor.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
environment:
2+
matrix:
3+
- PYTHON: 'C:\Python27'
4+
- PYTHON: 'C:\Python36'
5+
6+
install:
7+
- 'SET PATH=%PYTHON%;%PYTHON%\Scripts;C:\MinGW\bin;C:\go-src\bin;%PATH%'
8+
- 'SET GOROOT=C:\go-src'
9+
- 'SET GOROOT_BOOTSTRAP=C:\go19-x86'
10+
- 'git clone --branch=go1.10beta1 --depth=1 https://github.com/golang/go C:\go-src'
11+
- 'cd C:\go-src\src && make.bat'
12+
- 'pip install pytest'
13+
14+
# Not a C# project
15+
build: false
16+
17+
test_script: pytest tests
18+
19+
cache: '%LOCALAPPDATA%\pip\cache'

setuptools_golang.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
from __future__ import unicode_literals
33

44
import contextlib
5+
import copy
56
import io
67
import os
78
import pipes
89
import shutil
10+
import stat
911
import subprocess
1012
import sys
1113
import tempfile
@@ -19,11 +21,16 @@ def _tmpdir():
1921
try:
2022
yield tempdir
2123
finally:
22-
shutil.rmtree(tempdir)
24+
def err(action, name, exc): # pragma: no cover (windows)
25+
"""windows: can't remove readonly files, make them writeable!"""
26+
os.chmod(name, stat.S_IWRITE)
27+
action(name)
28+
29+
shutil.rmtree(tempdir, onerror=err)
2330

2431

2532
def _get_cflags(compiler):
26-
return ' '.join('-I{}'.format(p) for p in compiler.include_dirs)
33+
return str(' ').join(str('-I{}').format(p) for p in compiler.include_dirs)
2734

2835

2936
LFLAG_CLANG = '-Wl,-undefined,dynamic_lookup'
@@ -35,6 +42,12 @@ def _get_ldflags():
3542
"""Determine the correct link flags. This attempts dummy compiles similar
3643
to how autotools does feature detection.
3744
"""
45+
# windows gcc does not support linking with unresolved symbols
46+
if sys.platform == 'win32': # pragma: no cover (windows)
47+
prefix = getattr(sys, 'real_prefix', sys.prefix)
48+
libs = os.path.join(prefix, str('libs'))
49+
return str('-L{} -lpython{}{}').format(libs, *sys.version_info[:2])
50+
3851
cc = subprocess.check_output(('go', 'env', 'CC')).decode('UTF-8').strip()
3952

4053
with _tmpdir() as tmpdir:
@@ -75,7 +88,13 @@ def _raise_error(msg):
7588

7689
# If there are no .go files then the parent should handle this
7790
if not any(source.endswith('.go') for source in ext.sources):
78-
return base.build_extension(self, ext)
91+
# the base class may mutate `self.compiler`
92+
compiler = copy.deepcopy(self.compiler)
93+
self.compiler, compiler = compiler, self.compiler
94+
try:
95+
return base.build_extension(self, ext)
96+
finally:
97+
self.compiler, compiler = compiler, self.compiler
7998

8099
if len(ext.sources) != 1:
81100
_raise_error(
@@ -96,13 +115,13 @@ def _raise_error(msg):
96115
shutil.copytree('.', root_path)
97116
pkg_path = os.path.join(root_path, main_dir)
98117

99-
env = {'GOPATH': tempdir}
118+
env = {str('GOPATH'): tempdir}
100119
cmd_get = ('go', 'get', '-d')
101120
_check_call(cmd_get, cwd=pkg_path, env=env)
102121

103122
env.update({
104-
'CGO_CFLAGS': _get_cflags(self.compiler),
105-
'CGO_LDFLAGS': _get_ldflags(),
123+
str('CGO_CFLAGS'): _get_cflags(self.compiler),
124+
str('CGO_LDFLAGS'): _get_ldflags(),
106125
})
107126
cmd_build = (
108127
'go', 'build', '-buildmode=c-shared',

tests/setuptools_golang_test.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def run(*cmd, **kwargs):
2626
returncode = kwargs.pop('returncode', 0)
2727
proc = subprocess.Popen(cmd, **kwargs)
2828
out, err = proc.communicate()
29-
out = out.decode('UTF-8') if out is not None else None
30-
err = err.decode('UTF-8') if err is not None else None
29+
out = out.decode('UTF-8').replace('\r', '') if out is not None else None
30+
err = err.decode('UTF-8').replace('\r', '') if err is not None else None
3131
if returncode is not None:
3232
if proc.returncode != returncode:
3333
raise AssertionError(
@@ -56,9 +56,10 @@ def venv(tmpdir_factory):
5656
"""A shared virtualenv fixture, be careful not to install two of the same
5757
package into this -- or sadness...
5858
"""
59+
bin = 'Scripts' if sys.platform == 'win32' else 'bin'
5960
venv = tmpdir_factory.mktemp('venv').join('venv')
60-
pip = venv.join('bin/pip').strpath
61-
python = venv.join('bin/python').strpath
61+
pip = venv.join(bin, 'pip').strpath
62+
python = venv.join(bin, 'python').strpath
6263
# Make sure this virtualenv has the same executable
6364
run('virtualenv', venv.strpath, '-p', sys.executable)
6465
# Install this so we can get coverage
@@ -74,9 +75,9 @@ def venv(tmpdir_factory):
7475
@pytest.mark.parametrize(
7576
('pkg', 'mod'),
7677
(
77-
('testing/sum', 'sum'),
78-
('testing/sum_pure_go', 'sum_pure_go'),
79-
('testing/sum_sub_package', 'sum_sub_package.sum'),
78+
(os.path.join('testing', 'sum'), 'sum'),
79+
(os.path.join('testing', 'sum_pure_go'), 'sum_pure_go'),
80+
(os.path.join('testing', 'sum_sub_package'), 'sum_sub_package.sum'),
8081
),
8182
)
8283
def test_sum_integration(venv, pkg, mod):
@@ -90,7 +91,8 @@ def test_sum_integration(venv, pkg, mod):
9091

9192
def test_integration_project_with_c(venv):
9293
test_sum_integration(
93-
venv, 'testing/project_with_c', 'project_with_c_sum.sum',
94+
venv,
95+
os.path.join('testing', 'project_with_c'), 'project_with_c_sum.sum',
9496
)
9597
out = run_output(venv.python, '-c', HELLO_WORLD)
9698
assert out == 'hello world\n'
@@ -100,14 +102,14 @@ def test_integration_project_with_c(venv):
100102

101103

102104
def test_integration_imports_gh(venv):
103-
run(venv.pip, 'install', 'testing/imports_gh')
105+
run(venv.pip, 'install', os.path.join('testing', 'imports_gh'))
104106
out = run_output(venv.python, '-c', RED)
105107
assert out == '\x1b[31mohai\x1b[0m\n'
106108

107109

108110
def test_integration_notfound(venv):
109111
ret = run(
110-
venv.pip, 'install', 'testing/notfound',
112+
venv.pip, 'install', os.path.join('testing', 'notfound'),
111113
returncode=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
112114
)
113115
assert ret.returncode != 0
@@ -119,7 +121,7 @@ def test_integration_notfound(venv):
119121

120122
def test_integration_multidir(venv):
121123
ret = run(
122-
venv.pip, 'install', 'testing/multidir',
124+
venv.pip, 'install', os.path.join('testing', 'multidir'),
123125
returncode=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
124126
)
125127
assert ret.returncode != 0
@@ -133,6 +135,6 @@ def test_integration_multidir(venv):
133135

134136

135137
def test_integration_internal_imports(venv):
136-
run(venv.pip, 'install', 'testing/internal_imports')
138+
run(venv.pip, 'install', os.path.join('testing', 'internal_imports'))
137139
out = run_output(venv.python, '-c', OHAI)
138140
assert out == 'ohai, Anthony\n'

0 commit comments

Comments
 (0)