Skip to content

Commit 71aa1b6

Browse files
authored
Merge pull request #29 from JuliaGeometry/master
use binarybuilder/provider cross compilation
2 parents 1bf969d + f9f50f8 commit 71aa1b6

File tree

11 files changed

+115
-5374
lines changed

11 files changed

+115
-5374
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ test/config
1111
*.exp
1212
*.o
1313
*.so
14+
deps/usr
15+
deps/deps.jl

.travis.yml

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,24 @@
1-
# Documentation: http://docs.travis-ci.com/user/languages/julia/
21
language: julia
32
os:
43
- linux
54
- osx
6-
env:
7-
- CXX=g++-4.8
8-
addons:
9-
apt:
10-
sources:
11-
- ubuntu-toolchain-r-test
12-
packages:
13-
- g++-4.8
14-
sudo: required
15-
install:
16-
- |
17-
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
18-
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20
19-
g++ --version
20-
fi
5+
216
julia:
22-
- 0.5
237
- 0.6
24-
- nightly
8+
- 0.7
9+
10+
matrix:
11+
allow_failures:
12+
- julia: 0.7
13+
2514
notifications:
2615
email: false
27-
# uncomment the following lines to override the default test script
28-
#script:
29-
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
30-
# - julia -e 'Pkg.clone(pwd()); Pkg.build("Clipper"); Pkg.test("Clipper"; coverage=true)'
16+
sudo: false
17+
=======
18+
git:
19+
depth: 99999999
20+
## uncomment the following lines to allow failures on nightly julia
21+
## (tests will run but not make your overall status red)
22+
matrix:
23+
allow_failures:
24+
- julia: nightly

REQUIRE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
@windows WinRPM
2-
julia 0.5
1+
julia 0.6
2+
BinaryProvider

appveyor.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
43
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
54
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
65

6+
## uncomment the following lines to allow failures on nightly julia
7+
## (tests will run but not make your overall status red)
8+
matrix:
9+
allow_failures:
10+
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
11+
712
branches:
813
only:
914
- master
@@ -15,13 +20,13 @@ notifications:
1520
on_build_failure: false
1621
on_build_status_changed: false
1722

18-
os: Visual Studio 2015
19-
platform:
20-
- x64
21-
2223
install:
2324
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
24-
- call "c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
25+
# If there's a newer build queued for the same PR, cancel this one
26+
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
27+
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
28+
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
29+
throw "There are newer queued builds for this pull request, failing early." }
2530
# Download most recent Julia Windows binary
2631
- ps: (new-object net.webclient).DownloadFile(
2732
$env:JULIA_URL,
@@ -36,4 +41,4 @@ build_script:
3641
Pkg.clone(pwd(), \"Clipper\"); Pkg.build(\"Clipper\")"
3742

3843
test_script:
39-
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"Clipper\")"
44+
- C:\projects\julia\bin\julia -e "Pkg.test(\"Clipper\")"

deps/build.jl

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,46 @@
1-
#! /usr/bin/env julia
1+
using BinaryProvider # requires BinaryProvider 0.3.0 or later
22

3-
path = joinpath(dirname(@__FILE__), "..", "src")
3+
# Parse some basic command-line arguments
4+
const verbose = "--verbose" in ARGS
5+
const prefix = Prefix(get([a for a in ARGS if a != "--verbose"], 1, joinpath(@__DIR__, "usr")))
6+
products = [
7+
LibraryProduct(prefix, String["cclipper"], :cclipper),
8+
]
49

5-
if is_windows()
6-
# if success(`where cl.exe`)
7-
# info("Compiling with cl.exe")
8-
# run(`cl.exe /D_USRDLL /D_WINDLL /EHsc /Fo$(path) $(path)cclipper.cpp $(path)clipper.cpp /MT /link /DLL /OUT:$(path)cclipper.dll`)
9-
# else
10-
import WinRPM
11-
info("Compiling with WinRPM gcc-c++")
12-
WinRPM.install("gcc-c++"; yes = true)
13-
WinRPM.install("gcc"; yes = true)
14-
WinRPM.install("headers"; yes = true)
15-
WinRPM.install("winpthreads-devel"; yes = true)
10+
# Download binaries from hosted location
11+
bin_prefix = "https://github.com/SimonDanisch/ClipperBuilder/releases/download/v1.0.0"
1612

17-
gpp = Pkg.dir("WinRPM","deps","usr","x86_64-w64-mingw32","sys-root","mingw","bin","g++")
18-
RPMbindir = Pkg.dir("WinRPM","deps","usr","x86_64-w64-mingw32","sys-root","mingw","bin")
19-
incdir = Pkg.dir("WinRPM","deps","usr","x86_64-w64-mingw32","sys-root","mingw","include")
13+
# Listing of files generated by BinaryBuilder:
14+
download_info = Dict(
15+
Linux(:aarch64, :glibc) => ("$bin_prefix/Clipper.v1.0.0.aarch64-linux-gnu.tar.gz", "8257bdcb54563f2effbd1ea484be39437e245a01bd1badb93706625599019581"),
16+
Linux(:aarch64, :musl) => ("$bin_prefix/Clipper.v1.0.0.aarch64-linux-musl.tar.gz", "2967e0e6a400053f01fcaf6ea3c214342c346c627ef1d11343088d8dae8211d2"),
17+
Linux(:armv7l, :glibc, :eabihf) => ("$bin_prefix/Clipper.v1.0.0.arm-linux-gnueabihf.tar.gz", "a03c2e0455af89eeefcd4f5ca22ed72db47ee5718c7b815a347221ab2692da2a"),
18+
Linux(:armv7l, :musl, :eabihf) => ("$bin_prefix/Clipper.v1.0.0.arm-linux-musleabihf.tar.gz", "49d14834c9817e4d877bd6facd33bf242f394e82af5a6c711c063e4aa225131e"),
19+
Linux(:i686, :glibc) => ("$bin_prefix/Clipper.v1.0.0.i686-linux-gnu.tar.gz", "8bbdf10ba64b039d5172b5362f3048fec329b048c21e385a2c8feea78fc62c11"),
20+
Linux(:i686, :musl) => ("$bin_prefix/Clipper.v1.0.0.i686-linux-musl.tar.gz", "bf1e3a62bbf6cc8ea871b242d89dfa12477313a7ad990c1a930f83e18dd075f5"),
21+
Windows(:i686) => ("$bin_prefix/Clipper.v1.0.0.i686-w64-mingw32.tar.gz", "320ac5a275f33943421df9123e74344c59eeb20bc0c89de73501a83924be1453"),
22+
Linux(:powerpc64le, :glibc) => ("$bin_prefix/Clipper.v1.0.0.powerpc64le-linux-gnu.tar.gz", "ee312d90ceb0ec87092a502014d1d3e56d735186fa728c3cc77088145d6f9ce9"),
23+
MacOS(:x86_64) => ("$bin_prefix/Clipper.v1.0.0.x86_64-apple-darwin14.tar.gz", "0ddc80a5a9d8be456facc92fadddde6755d1aa9d5d9cea8095f69dcc6adec1ba"),
24+
Linux(:x86_64, :glibc) => ("$bin_prefix/Clipper.v1.0.0.x86_64-linux-gnu.tar.gz", "0883bcac9afb68d2ffb822453727ad9fe309a088f9192dd13c26654100d39c57"),
25+
Linux(:x86_64, :musl) => ("$bin_prefix/Clipper.v1.0.0.x86_64-linux-musl.tar.gz", "fd61e7319a79d6a9d32d1c7ad72302d313ca20756472a21a7bae8c41e942d01a"),
26+
FreeBSD(:x86_64) => ("$bin_prefix/Clipper.v1.0.0.x86_64-unknown-freebsd11.1.tar.gz", "39a010ff1d9007641524c276ca9c58ddf68a9f9b4bde98b6fda84950593d385a"),
27+
Windows(:x86_64) => ("$bin_prefix/Clipper.v1.0.0.x86_64-w64-mingw32.tar.gz", "214b2ab0646e2b7fc33376480823a19481a88200a4463a240bb2a747b593a3fd"),
28+
)
2029

21-
push!(Base.Libdl.DL_LOAD_PATH, RPMbindir)
22-
ENV["PATH"] = ENV["PATH"] * ";" * RPMbindir
23-
if success(`$gpp --version`)
24-
cd(path) do
25-
run(`$gpp -c -fPIC -std=c++11 clipper.cpp cclipper.cpp -I $incdir`)
26-
run(`$gpp -shared -o cclipper.dll clipper.o cclipper.o`)
27-
end
28-
else
29-
error("no windows c++ compiler (cl.exe) found, and WinRPM with g++ is failing as well.")
30-
end
31-
# end
32-
end
33-
34-
if is_unix()
35-
cd(path) do
36-
# Note: on Mac OS X, g++ is aliased to clang++.
37-
run(`g++ -c -fPIC -std=c++11 clipper.cpp cclipper.cpp`)
38-
run(`g++ -shared -o cclipper.so clipper.o cclipper.o`)
30+
# Install unsatisfied or updated dependencies:
31+
unsatisfied = any(!satisfied(p; verbose=verbose) for p in products)
32+
if haskey(download_info, platform_key())
33+
url, tarball_hash = download_info[platform_key()]
34+
if unsatisfied || !isinstalled(url, tarball_hash; prefix=prefix)
35+
# Download and install binaries
36+
install(url, tarball_hash; prefix=prefix, force=true, verbose=verbose)
3937
end
38+
elseif unsatisfied
39+
# If we don't have a BinaryProvider-compatible .tar.gz to download, complain.
40+
# Alternatively, you could attempt to install from a separate provider,
41+
# build from source or something even more ambitious here.
42+
error("Your platform $(triplet(platform_key())) is not supported by this package!")
4043
end
44+
45+
# Write out a deps.jl file that will contain mappings for our products
46+
write_deps_file(joinpath(@__DIR__, "deps.jl"), products)

src/Clipper.jl

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
__precompile__()
22
module Clipper
3+
4+
const depsfile = joinpath(@__DIR__, "..", "deps", "deps.jl")
5+
6+
if isfile(depsfile)
7+
include(depsfile)
8+
else
9+
error("Clipper not build correctly. Please run Pkg.build(\"Clipper\")")
10+
end
11+
12+
function __init__()
13+
check_deps()
14+
end
15+
16+
317
export PolyType, PolyTypeSubject, PolyTypeClip,
418
ClipType, ClipTypeIntersection, ClipTypeUnion, ClipTypeDifference, ClipTypeXor,
519
PolyFillType, PolyFillTypeEvenOdd, PolyFillTypeNonZero, PolyFillTypePositive, PolyFillTypeNegative,
@@ -19,43 +33,36 @@ module Clipper
1933

2034
@enum EndType EndTypeClosedPolygon=0 EndTypeClosedLine=1 EndTypeOpenSquare=2 EndTypeOpenRound=3 EndTypeOpenButt=4
2135

22-
@static if is_windows()
23-
const library_path = joinpath(dirname(@__FILE__), "cclipper.dll")
24-
end
25-
26-
@static if is_unix()
27-
const library_path = joinpath(dirname(@__FILE__), "cclipper.so")
28-
end
2936

3037
immutable IntPoint
3138
X::Int64
3239
Y::Int64
3340
end
3441

35-
type PolyNode{T}
42+
mutable struct PolyNode{T}
3643
contour::Vector{T}
3744
hole::Bool
3845
open::Bool
3946
children::Vector{PolyNode{T}}
4047
parent::PolyNode{T}
41-
(::Type{PolyNode{T}}){T}(a,b,c) = new{T}(a,b,c)
42-
function (::Type{PolyNode{T}}){T}(a,b,c,d)
48+
PolyNode{T}(a,b,c) where {T} = new{T}(a,b,c)
49+
function PolyNode{T}(a,b,c,d) where T
4350
p = new{T}(a,b,c,d)
4451
p.parent = p
4552
return p
4653
end
47-
(::Type{PolyNode{T}}){T}(a,b,c,d,e) = new{T}(a,b,c,d,e)
54+
PolyNode{T}(a,b,c,d,e) where {T} = new{T}(a,b,c,d,e)
4855
end
4956

50-
Base.convert{T}(::Type{PolyNode{T}}, x::PolyNode{T}) = x
51-
function Base.convert{S,T}(::Type{PolyNode{S}}, x::PolyNode{T})
57+
Base.convert(::Type{PolyNode{T}}, x::PolyNode{T}) where {T} = x
58+
function Base.convert(::Type{PolyNode{S}}, x::PolyNode{T}) where {S,T}
5259
parent(x) !== x && error("must convert a top-level PolyNode (i.e. a PolyTree).")
5360

5461
pn = PolyNode{S}(convert(Vector{S}, contour(x)), ishole(x), isopen(x))
5562
pn.children = [PolyNode(y,pn) for y in children(x)]
5663
pn.parent = pn
5764
end
58-
function PolyNode{S}(x::PolyNode, parent::PolyNode{S})
65+
function PolyNode(x::PolyNode, parent::PolyNode{S}) where S
5966
pn = PolyNode{S}(contour(x), ishole(x), isopen(x))
6067
pn.children = [PolyNode(y,pn) for y in children(x)]
6168
pn.parent = parent
@@ -118,19 +125,19 @@ module Clipper
118125
# Static functions
119126
#==============================================================#
120127
function orientation(path::Vector{IntPoint})
121-
ccall((:orientation, library_path), Cuchar, (Ptr{IntPoint}, Csize_t),
128+
ccall((:orientation, cclipper), Cuchar, (Ptr{IntPoint}, Csize_t),
122129
path,
123130
length(path)) == 1 ? true : false
124131
end
125132

126133
function area(path::Vector{IntPoint})
127-
ccall((:area, library_path), Float64, (Ptr{IntPoint}, Csize_t),
134+
ccall((:area, cclipper), Float64, (Ptr{IntPoint}, Csize_t),
128135
path,
129136
length(path))
130137
end
131138

132139
function pointinpolygon(pt::IntPoint, path::Vector{IntPoint})
133-
ccall((:pointinpolygon, library_path), Cint, (IntPoint, Ptr{IntPoint}, Csize_t),
140+
ccall((:pointinpolygon, cclipper), Cint, (IntPoint, Ptr{IntPoint}, Csize_t),
134141
pt,
135142
path,
136143
length(path))
@@ -139,19 +146,18 @@ module Clipper
139146
#==============================================================#
140147
# Clipper object
141148
#==============================================================#
142-
type Clip
149+
mutable struct Clip
143150
clipper_ptr::Ptr{Void}
144151

145152
function Clip()
146-
clipper = new(ccall((:get_clipper, library_path), Ptr{Void}, ()))
147-
finalizer(clipper, c -> ccall((:delete_clipper, library_path), Void, (Ptr{Void},), c.clipper_ptr))
148-
153+
clipper = new(ccall((:get_clipper, cclipper), Ptr{Void}, ()))
154+
finalizer(clipper, c -> ccall((:delete_clipper, cclipper), Void, (Ptr{Void},), c.clipper_ptr))
149155
clipper
150156
end
151157
end
152158

153159
function add_path!(c::Clip, path::Vector{IntPoint}, polyType::PolyType, closed::Bool)
154-
ccall((:add_path, library_path), Cuchar, (Ptr{Void}, Ptr{IntPoint}, Csize_t, Cint, Cuchar),
160+
ccall((:add_path, cclipper), Cuchar, (Ptr{Void}, Ptr{IntPoint}, Csize_t, Cint, Cuchar),
155161
c.clipper_ptr,
156162
path,
157163
length(path),
@@ -165,7 +171,7 @@ module Clipper
165171
push!(lengths, length(path))
166172
end
167173

168-
ccall((:add_paths, library_path), Cuchar, (Ptr{Void}, Ptr{Ptr{IntPoint}}, Ptr{Csize_t}, Csize_t, Cint, Cuchar),
174+
ccall((:add_paths, cclipper), Cuchar, (Ptr{Void}, Ptr{Ptr{IntPoint}}, Ptr{Csize_t}, Csize_t, Cint, Cuchar),
169175
c.clipper_ptr,
170176
paths,
171177
lengths,
@@ -177,7 +183,7 @@ module Clipper
177183
function execute(c::Clip, clipType::ClipType, subjFillType::PolyFillType, clipFillType::PolyFillType)
178184
polys = Vector{Vector{IntPoint}}()
179185

180-
result = ccall((:execute, library_path), Cuchar, (Ptr{Void}, Cint, Cint, Cint, Any, Ptr{Void}),
186+
result = ccall((:execute, cclipper), Cuchar, (Ptr{Void}, Cint, Cint, Cint, Any, Ptr{Void}),
181187
c.clipper_ptr,
182188
Int(clipType),
183189
Int(subjFillType),
@@ -191,7 +197,7 @@ module Clipper
191197
function execute_pt(c::Clip, clipType::ClipType, subjFillType::PolyFillType, clipFillType::PolyFillType)
192198
pt = PolyNode{IntPoint}(IntPoint[], false, false, PolyNode{IntPoint}[])
193199

194-
result = ccall((:execute_pt, library_path), Cuchar,
200+
result = ccall((:execute_pt, cclipper), Cuchar,
195201
(Ptr{Void}, Cint, Cint, Cint, Any, Ptr{Void}, Ptr{Void}),
196202
c.clipper_ptr,
197203
Int(clipType),
@@ -205,36 +211,36 @@ module Clipper
205211
end
206212

207213
function clear!(c::Clip)
208-
ccall((:clear, library_path), Void, (Ptr{Void},), c.clipper_ptr)
214+
ccall((:clear, cclipper), Void, (Ptr{Void},), c.clipper_ptr)
209215
end
210216

211-
type IntRect
217+
mutable struct IntRect
212218
left::Int64
213219
top::Int64
214220
right::Int64
215221
bottom::Int64
216222
end
217223

218224
function get_bounds(c::Clip)
219-
ccall((:get_bounds, library_path), IntRect, (Ptr{Void}, ), c.clipper_ptr)
225+
ccall((:get_bounds, cclipper), IntRect, (Ptr{Void}, ), c.clipper_ptr)
220226
end
221227

222228
#==============================================================#
223229
# ClipperOffset object
224230
#==============================================================#
225-
type ClipperOffset
231+
mutable struct ClipperOffset
226232
clipper_ptr::Ptr{Void}
227233

228234
function ClipperOffset(miterLimit::Float64 = 2.0, roundPrecision::Float64 = 0.25)
229-
clipper = new(ccall((:get_clipper_offset, library_path), Ptr{Void}, (Cdouble, Cdouble), miterLimit, roundPrecision))
230-
finalizer(clipper, c -> ccall((:delete_clipper_offset, library_path), Void, (Ptr{Void},), c.clipper_ptr))
235+
clipper = new(ccall((:get_clipper_offset, cclipper), Ptr{Void}, (Cdouble, Cdouble), miterLimit, roundPrecision))
236+
finalizer(clipper, c -> ccall((:delete_clipper_offset, cclipper), Void, (Ptr{Void},), c.clipper_ptr))
231237

232238
clipper
233239
end
234240
end
235241

236242
function add_path!(c::ClipperOffset, path::Vector{IntPoint}, joinType::JoinType, endType::EndType)
237-
ccall((:add_offset_path, library_path), Void, (Ptr{Void}, Ptr{IntPoint}, Csize_t, Cint, Cint),
243+
ccall((:add_offset_path, cclipper), Void, (Ptr{Void}, Ptr{IntPoint}, Csize_t, Cint, Cint),
238244
c.clipper_ptr,
239245
path,
240246
length(path),
@@ -248,7 +254,7 @@ module Clipper
248254
push!(lengths, length(path))
249255
end
250256

251-
ccall((:add_offset_paths, library_path), Void, (Ptr{Void}, Ptr{Ptr{IntPoint}}, Ptr{Csize_t}, Csize_t, Cint, Cint),
257+
ccall((:add_offset_paths, cclipper), Void, (Ptr{Void}, Ptr{Ptr{IntPoint}}, Ptr{Csize_t}, Csize_t, Cint, Cint),
252258
c.clipper_ptr,
253259
paths,
254260
lengths,
@@ -258,13 +264,12 @@ module Clipper
258264
end
259265

260266
function clear!(c::ClipperOffset)
261-
ccall((:clear_offset, library_path), Void, (Ptr{Void},), c.clipper_ptr)
267+
ccall((:clear_offset, cclipper), Void, (Ptr{Void},), c.clipper_ptr)
262268
end
263269

264270
function execute(c::ClipperOffset, delta::Float64)
265271
polys = Vector{Vector{IntPoint}}()
266-
267-
result = ccall((:execute_offset, library_path), Void, (Ptr{Void}, Cdouble, Any, Ptr{Void}),
272+
result = ccall((:execute_offset, cclipper), Void, (Ptr{Void}, Cdouble, Any, Ptr{Void}),
268273
c.clipper_ptr,
269274
delta,
270275
polys,

0 commit comments

Comments
 (0)