Skip to content

Commit b38845b

Browse files
committed
all: add Windows CI support
Fixes sbinet#32.
1 parent 53a27e0 commit b38845b

File tree

4 files changed

+177
-2
lines changed

4 files changed

+177
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ go-python
22
=========
33

44
[![Build Status](https://drone.io/github.com/sbinet/go-python/status.png)](https://drone.io/github.com/sbinet/go-python/latest)
5+
[![Build status](https://ci.appveyor.com/api/projects/status/n0ujg8no487a89vo/branch/master?svg=true)](https://ci.appveyor.com/project/sbinet/go-python/branch/master)
56

67
Naive `go` bindings towards the C-API of CPython-2.
78

appveyor.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
build: off
2+
3+
clone_folder: c:\gopath\src\github.com\sbinet\go-python
4+
5+
cache:
6+
- '%LocalAppData%\\go-build'
7+
- '%LocalAppData%\\pip'
8+
9+
branches:
10+
only:
11+
- master
12+
13+
environment:
14+
GOPATH: c:\gopath
15+
GOPY_APPVEYOR_CI: '1'
16+
GODEBUG: 'cgocheck=0'
17+
GOTRACEBACK: 'crash'
18+
PYTHONUNBUFFERED: "1"
19+
CPYTHON2DIR: "C:\\Python27-x64"
20+
PATH: '%GOPATH%\bin;%CPYTHON2DIR%;%CPYTHON2DIR%\\Scripts;C:\msys64\mingw64\bin;C:\msys64\usr\bin\;%PATH%'
21+
22+
stack: go 1.11
23+
24+
build_script:
25+
- "%CPYTHON2DIR%\\python --version"
26+
- go get -v -t ./...
27+
28+
test_script:
29+
- go test ./...

cgoflags_windows.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
package python
44

5-
// #cgo CFLAGS: -IC:/Python27/include
6-
// #cgo LDFLAGS: -LC:/Python27/libs -lpython27
5+
// #cgo 386 CFLAGS: -I C:/Python27/include
6+
// #cgo amd64 CFLAGS: -I C:/Python27-x64/include
7+
// #cgo amd64 CFLAGS: -D MS_WIN64
8+
// #cgo 386 LDFLAGS: -L C:/Python27/libs -lpython27
9+
// #cgo amd64 LDFLAGS: -L C:/Python27-x64/libs -lpython27
10+
//
711
// #include "go-python.h"
812
import "C"

gen-cgoflags.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// +build ignore
2+
3+
// simple command to generate CGOFLAGS for a given python VM
4+
package main
5+
6+
import (
7+
"bytes"
8+
"encoding/json"
9+
"flag"
10+
"fmt"
11+
"io/ioutil"
12+
"log"
13+
"os"
14+
"os/exec"
15+
"runtime"
16+
"strings"
17+
18+
"github.com/pkg/errors"
19+
)
20+
21+
func main() {
22+
vm := flag.String("vm", "python", "path to a python VM")
23+
flag.Parse()
24+
25+
if *vm == "" {
26+
log.Fatalf("need a python VM")
27+
}
28+
29+
cfg, err := getPythonConfig(*vm)
30+
if err != nil {
31+
log.Fatalf("could not infer python configuration: %v", err)
32+
}
33+
34+
oname := "cgoflags_unix.go"
35+
switch runtime.GOOS {
36+
case "windows":
37+
oname = "cgoflags_windows.go"
38+
}
39+
40+
err = ioutil.WriteFile(oname, []byte(fmt.Sprintf(tmpl,
41+
cfg.cflags,
42+
cfg.ldflags,
43+
runtime.GOOS,
44+
)), 0644)
45+
if err != nil {
46+
log.Fatalf("could not write %q: %v", oname, err)
47+
}
48+
}
49+
50+
// getPythonConfig returns the needed python configuration for the given
51+
// python VM (python, python2, python3, pypy, etc...)
52+
func getPythonConfig(vm string) (pyconfig, error) {
53+
code := `import sys
54+
import distutils.sysconfig as ds
55+
import json
56+
print(ds.get_config_vars())
57+
print(ds.get_python_lib())
58+
print(json.dumps({
59+
"version": sys.version_info.major,
60+
"prefix": ds.get_config_var("prefix"),
61+
"incdir": ds.get_python_inc(),
62+
"libdir": ds.get_config_var("LIBDIR"),
63+
"libdest": ds.get_config_var("LIBDEST"),
64+
"libpy": ds.get_config_var("LIBRARY"),
65+
"shlibs": ds.get_config_var("SHLIBS"),
66+
"syslibs": ds.get_config_var("SYSLIBS"),
67+
"shlinks": ds.get_config_var("LINKFORSHARED"),
68+
"DLLs": ds.get_config_var("DLLLIBRARY"),
69+
}))
70+
`
71+
72+
var cfg pyconfig
73+
bin, err := exec.LookPath(vm)
74+
if err != nil {
75+
return cfg, errors.Wrapf(err, "could not locate python vm %q", vm)
76+
}
77+
78+
buf := new(bytes.Buffer)
79+
cmd := exec.Command(bin, "-c", code)
80+
cmd.Stdin = os.Stdin
81+
cmd.Stdout = buf
82+
cmd.Stderr = os.Stderr
83+
err = cmd.Run()
84+
if err != nil {
85+
return cfg, errors.Wrap(err, "could not run python-config script")
86+
}
87+
88+
log.Printf("distutils:\n%s", buf.String())
89+
90+
var raw struct {
91+
Version int `json:"version"`
92+
IncDir string `json:"incdir"`
93+
LibDir string `json:"libdir"`
94+
LibPy string `json:"libpy"`
95+
ShLibs string `json:"shlibs"`
96+
SysLibs string `json:"syslibs"`
97+
}
98+
err = json.NewDecoder(buf).Decode(&raw)
99+
if err != nil {
100+
return cfg, errors.Wrapf(err, "could not decode JSON script output")
101+
}
102+
103+
if strings.HasSuffix(raw.LibPy, ".a") {
104+
raw.LibPy = raw.LibPy[:len(raw.LibPy)-len(".a")]
105+
}
106+
if strings.HasPrefix(raw.LibPy, "lib") {
107+
raw.LibPy = raw.LibPy[len("lib"):]
108+
}
109+
110+
cfg.version = raw.Version
111+
cfg.cflags = strings.Join([]string{
112+
"-I " + raw.IncDir,
113+
}, " ")
114+
cfg.ldflags = strings.Join([]string{
115+
"-L " + raw.LibDir,
116+
"-l " + raw.LibPy,
117+
raw.ShLibs,
118+
raw.SysLibs,
119+
}, " ")
120+
121+
return cfg, nil
122+
}
123+
124+
type pyconfig struct {
125+
version int
126+
cflags string
127+
ldflags string
128+
}
129+
130+
const tmpl = `// Automatically generated. Do not edit.
131+
132+
// +build %[3]s
133+
134+
package python
135+
136+
// #cgo %[3]s CFLAGS: %[1]s
137+
// #cgo %[3]s LDFLAGS: %[2]s
138+
//
139+
// #include "go-python.h"
140+
import "C"
141+
`

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy