feat: build without libopusfile using go build tag

This patch introduces a new build tag `nolibopusfile` that conditionally
compiles out the code that imports `libopusfile`. This enables a static
binary build on Alpine Linux, which doesn’t have a static `libopusfile`.

Tests still work:

```sh
go test -tags nolibopusfile ./...
go test ./...
```

We could also have moved all libopusfile related code (i.e. Stream) into
a separate sub-package, but that would break backwards compatibility.
This feature is too unpopular to justify introducing a new major
version.

See also: https://github.com/hraban/opus/pull/24
This commit is contained in:
Randy Reddig 2019-08-13 14:31:57 -07:00 committed by Hraban Luyat
parent 558c065b07
commit 25a249fbd5
7 changed files with 105 additions and 65 deletions

View file

@ -117,7 +117,7 @@ Note regarding Forward Error Correction (FEC):
> Note also that in order to use this feature the encoder needs to be configured > Note also that in order to use this feature the encoder needs to be configured
> with `SetInBandFEC(true)` and `SetPacketLossPerc(x)` options. > with `SetInBandFEC(true)` and `SetPacketLossPerc(x)` options.
### Streams (and files) ### Streams (and Files)
To decode a .opus file (or .ogg with Opus data), or to decode a "Opus stream" To decode a .opus file (or .ogg with Opus data), or to decode a "Opus stream"
(which is a Ogg stream with Opus data), use the `Stream` interface. It wraps an (which is a Ogg stream with Opus data), use the `Stream` interface. It wraps an
@ -162,7 +162,7 @@ https://www.opus-codec.org/docs/opus_api-1.1.3/
For more examples, see the `_test.go` files. For more examples, see the `_test.go` files.
## Build & installation ## Build & Installation
This package requires libopus and libopusfile development packages to be This package requires libopus and libopusfile development packages to be
installed on your system. These are available on Debian based systems from installed on your system. These are available on Debian based systems from
@ -180,6 +180,25 @@ Mac:
brew install pkg-config opus opusfile brew install pkg-config opus opusfile
``` ```
### Building Without `libopusfile`
This package can be built without `libopusfile` by using the build tag `nolibopusfile`.
This enables the compilation of statically-linked binaries with no external
dependencies on operating systems without a static `libopusfile`, such as
[Alpine Linux](https://pkgs.alpinelinux.org/contents?branch=edge&name=opusfile-dev&arch=x86_64&repo=main).
**Note:** this will disable all file and `Stream` APIs.
To enable this feature, add `-tags nolibopusfile` to your `go build` or `go test` commands:
```sh
# Build
go build -tags nolibopusfile ...
# Test
go test -tags nolibopusfile ./...
```
### Using in Docker ### Using in Docker
If your Dockerized app has this library as a dependency (directly or If your Dockerized app has this library as a dependency (directly or

View file

@ -1,3 +1,5 @@
// +build !nolibopusfile
// Copyright © Go Opus Authors (see AUTHORS file) // Copyright © Go Opus Authors (see AUTHORS file)
// //
// License for use of this code is detailed in the LICENSE file // License for use of this code is detailed in the LICENSE file

View file

@ -9,9 +9,8 @@ import (
) )
/* /*
#cgo pkg-config: opus opusfile #cgo pkg-config: opus
#include <opus.h> #include <opus.h>
#include <opusfile.h>
*/ */
import "C" import "C"
@ -35,64 +34,3 @@ const (
func (e Error) Error() string { func (e Error) Error() string {
return fmt.Sprintf("opus: %s", C.GoString(C.opus_strerror(C.int(e)))) return fmt.Sprintf("opus: %s", C.GoString(C.opus_strerror(C.int(e))))
} }
type StreamError int
var _ error = StreamError(0)
// Libopusfile errors. The names are copied verbatim from the libopusfile
// library.
const (
ErrStreamFalse = StreamError(C.OP_FALSE)
ErrStreamEOF = StreamError(C.OP_EOF)
ErrStreamHole = StreamError(C.OP_HOLE)
ErrStreamRead = StreamError(C.OP_EREAD)
ErrStreamFault = StreamError(C.OP_EFAULT)
ErrStreamImpl = StreamError(C.OP_EIMPL)
ErrStreamInval = StreamError(C.OP_EINVAL)
ErrStreamNotFormat = StreamError(C.OP_ENOTFORMAT)
ErrStreamBadHeader = StreamError(C.OP_EBADHEADER)
ErrStreamVersion = StreamError(C.OP_EVERSION)
ErrStreamNotAudio = StreamError(C.OP_ENOTAUDIO)
ErrStreamBadPacked = StreamError(C.OP_EBADPACKET)
ErrStreamBadLink = StreamError(C.OP_EBADLINK)
ErrStreamNoSeek = StreamError(C.OP_ENOSEEK)
ErrStreamBadTimestamp = StreamError(C.OP_EBADTIMESTAMP)
)
func (i StreamError) Error() string {
switch i {
case ErrStreamFalse:
return "OP_FALSE"
case ErrStreamEOF:
return "OP_EOF"
case ErrStreamHole:
return "OP_HOLE"
case ErrStreamRead:
return "OP_EREAD"
case ErrStreamFault:
return "OP_EFAULT"
case ErrStreamImpl:
return "OP_EIMPL"
case ErrStreamInval:
return "OP_EINVAL"
case ErrStreamNotFormat:
return "OP_ENOTFORMAT"
case ErrStreamBadHeader:
return "OP_EBADHEADER"
case ErrStreamVersion:
return "OP_EVERSION"
case ErrStreamNotAudio:
return "OP_ENOTAUDIO"
case ErrStreamBadPacked:
return "OP_EBADPACKET"
case ErrStreamBadLink:
return "OP_EBADLINK"
case ErrStreamNoSeek:
return "OP_ENOSEEK"
case ErrStreamBadTimestamp:
return "OP_EBADTIMESTAMP"
default:
return "libopusfile error: %d (unknown code)"
}
}

View file

@ -2,6 +2,8 @@
// //
// License for use of this code is detailed in the LICENSE file // License for use of this code is detailed in the LICENSE file
// +build !nolibopusfile
package opus package opus
import ( import (

75
stream_errors.go Normal file
View file

@ -0,0 +1,75 @@
// Copyright © 2015-2017 Go Opus Authors (see AUTHORS file)
//
// License for use of this code is detailed in the LICENSE file
// +build !nolibopusfile
package opus
/*
#cgo pkg-config: opusfile
#include <opusfile.h>
*/
import "C"
// StreamError represents an error from libopusfile.
type StreamError int
var _ error = StreamError(0)
// Libopusfile errors. The names are copied verbatim from the libopusfile
// library.
const (
ErrStreamFalse = StreamError(C.OP_FALSE)
ErrStreamEOF = StreamError(C.OP_EOF)
ErrStreamHole = StreamError(C.OP_HOLE)
ErrStreamRead = StreamError(C.OP_EREAD)
ErrStreamFault = StreamError(C.OP_EFAULT)
ErrStreamImpl = StreamError(C.OP_EIMPL)
ErrStreamInval = StreamError(C.OP_EINVAL)
ErrStreamNotFormat = StreamError(C.OP_ENOTFORMAT)
ErrStreamBadHeader = StreamError(C.OP_EBADHEADER)
ErrStreamVersion = StreamError(C.OP_EVERSION)
ErrStreamNotAudio = StreamError(C.OP_ENOTAUDIO)
ErrStreamBadPacked = StreamError(C.OP_EBADPACKET)
ErrStreamBadLink = StreamError(C.OP_EBADLINK)
ErrStreamNoSeek = StreamError(C.OP_ENOSEEK)
ErrStreamBadTimestamp = StreamError(C.OP_EBADTIMESTAMP)
)
func (i StreamError) Error() string {
switch i {
case ErrStreamFalse:
return "OP_FALSE"
case ErrStreamEOF:
return "OP_EOF"
case ErrStreamHole:
return "OP_HOLE"
case ErrStreamRead:
return "OP_EREAD"
case ErrStreamFault:
return "OP_EFAULT"
case ErrStreamImpl:
return "OP_EIMPL"
case ErrStreamInval:
return "OP_EINVAL"
case ErrStreamNotFormat:
return "OP_ENOTFORMAT"
case ErrStreamBadHeader:
return "OP_EBADHEADER"
case ErrStreamVersion:
return "OP_EVERSION"
case ErrStreamNotAudio:
return "OP_ENOTAUDIO"
case ErrStreamBadPacked:
return "OP_EBADPACKET"
case ErrStreamBadLink:
return "OP_EBADLINK"
case ErrStreamNoSeek:
return "OP_ENOSEEK"
case ErrStreamBadTimestamp:
return "OP_EBADTIMESTAMP"
default:
return "libopusfile error: %d (unknown code)"
}
}

View file

@ -2,6 +2,8 @@
// //
// License for use of this code is detailed in the LICENSE file // License for use of this code is detailed in the LICENSE file
// +build !nolibopusfile
package opus package opus
import ( import (

View file

@ -2,6 +2,8 @@
// //
// License for use of this code is detailed in the LICENSE file // License for use of this code is detailed in the LICENSE file
// +build !nolibopusfile
package opus package opus
import ( import (