Skip to content

Commit fe10bd2

Browse files
committed
Initial commit
0 parents  commit fe10bd2

File tree

11 files changed

+307
-0
lines changed

11 files changed

+307
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Dockerfile to build sine and libsndfile for Amazon Linux 2.
2+
#
3+
# To build:
4+
# docker build -t sine .
5+
#
6+
# To copy the binaries to the host system, run:
7+
# docker create --name sine-build sine:latest
8+
# docker cp sine-build:/usr/local/lib64/libsndfile.so.1.0.29 .
9+
# docker cp sine-build:/usr/local/lib64/libsndfile.so.1 .
10+
# docker cp sine-build:/usr/local/lib64/libsndfile.so .
11+
# docker cp sine-build:/opt/sine/insta//bin/sine .
12+
# docker rm sine-build
13+
#
14+
15+
FROM amazonlinux:2.0.20200406.0
16+
17+
RUN \
18+
yum -q -y groupinstall "Development Tools"
19+
20+
RUN \
21+
yum -q -y install \
22+
cmake3 \
23+
ninja-build \
24+
&& ln -s /usr/bin/cmake3 /usr/bin/cmake
25+
26+
# Build and install libsndfile. Compile as a shared library to conform to LGPL.
27+
#
28+
# libsndfile-devel 1.0.25 is available through the package manager, but that
29+
# version doesn't provide a CMake package configuration file. Therefore, build a
30+
# more recent version.
31+
# TODO: Update when https://github.com/erikd/libsndfile/pull/524 is merged.
32+
ENV LIBSNDFILE_GIT_REF c103c16c972c3c30197ef0da963802ce7c33ad72
33+
ENV LIBSNDFILE_TARBALL_SHA256 17a43830e869987ae2dca7839363f7317b6ce00dfe161d507ef0b73ccc6b4c42
34+
WORKDIR /opt/libsndfile
35+
RUN \
36+
curl -L https://api.github.com/repos/msmolens/libsndfile/tarball/${LIBSNDFILE_GIT_REF} > libsndfile.tar.gz && \
37+
echo "$LIBSNDFILE_TARBALL_SHA256 libsndfile.tar.gz" | sha256sum -c -w --status - && \
38+
mkdir libsndfile && \
39+
tar zxf libsndfile.tar.gz --strip-components=1 && \
40+
mkdir build && \
41+
cd build && \
42+
cmake -G Ninja \
43+
-DCMAKE_BUILD_TYPE:STRING=Release \
44+
-DBUILD_SHARED_LIBS:BOOL=ON \
45+
-DBUILD_PROGRAMS:BOOL=OFF \
46+
-DBUILD_TESTING:BOOL=OFF \
47+
-DENABLE_EXTERNAL_LIBS:BOOL=OFF \
48+
.. && \
49+
cmake --build . --target install
50+
51+
# Build and install the example sine program.
52+
ENV INSTALL_PREFIX /opt/sine/install
53+
WORKDIR /opt/sine/build
54+
COPY sine .
55+
RUN mkdir build && \
56+
cd build && \
57+
cmake -G Ninja \
58+
-DCMAKE_BUILD_TYPE=Release \
59+
-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
60+
.. && \
61+
cmake --build . --target install && \
62+
echo "Shared libraries:" && \
63+
ldd ${INSTALL_PREFIX}/bin/sine && \
64+
strip ${INSTALL_PREFIX}/bin/sine

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Max Smolens
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Makefile to build sine and libsndfile for Amazon Linux 2.
2+
3+
IMAGE = sine
4+
NAME = sine-build
5+
OUTDIR = ./build
6+
7+
.PHONY: all
8+
9+
all: copy
10+
11+
build: Dockerfile
12+
docker build -t $(IMAGE) -f Dockerfile .
13+
14+
copy: build
15+
mkdir -p $(OUTDIR)
16+
docker create --name $(NAME) $(IMAGE)
17+
docker cp $(NAME):/usr/local/lib64/libsndfile.so.1.0.29 $(OUTDIR)
18+
docker cp $(NAME):/usr/local/lib64/libsndfile.so.1 $(OUTDIR)
19+
docker cp $(NAME):/usr/local/lib64/libsndfile.so $(OUTDIR)
20+
docker cp $(NAME):/opt/sine/install/bin/sine $(OUTDIR)
21+
docker rm $(NAME)
22+
23+
clean:
24+
rm -rf $(OUTDIR)
25+
docker rm $(NAME) || true
26+
docker rmi $(IMAGE) || true

README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Compile for AWS Lambda
2+
3+
## Overview
4+
5+
For a native executable to run in an AWS Lambda function, it must be compatible
6+
with the runtime's operating system. This repository is an example of using
7+
Docker to build a custom C++ executable that runs on AWS Lambda.
8+
9+
## Requirements
10+
11+
- [Docker](https://docs.docker.com/)
12+
- [Make](https://www.gnu.org/software/make/)
13+
14+
## Usage
15+
16+
Enter this directory and run `make`:
17+
18+
```console
19+
$ cd /path/to/compile-for-aws-lambda
20+
$ make
21+
```
22+
23+
The `build` directory now contains binaries that can be packaged in the ZIP file
24+
for an AWS Lambda function:
25+
26+
```
27+
$ tree build
28+
build
29+
├── libsndfile.so -> libsndfile.so.1
30+
├── libsndfile.so.1 -> libsndfile.so.1.0.29
31+
├── libsndfile.so.1.0.29
32+
└── sine
33+
```
34+
35+
The example `sine` program generates a sine wave at the specified frequency (Hz)
36+
and writes it as a WAV file:
37+
```console
38+
$ cd build
39+
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
40+
$ ./sine 2600 /tmp/2600.wav
41+
$ file /tmp/2600.wav
42+
2600.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 24 bit, mono 44100 Hz
43+
```
44+
45+
To run the program in a Lambda function, use the
46+
[child_process](https://nodejs.org/docs/latest-v12.x/api/child_process.html)
47+
module in Node.js, or the
48+
[subprocess](https://docs.python.org/3.8/library/subprocess.html) module in
49+
Python.
50+
51+
## Details
52+
53+
From the [Running Arbitrary Executables in AWS
54+
Lambda](https://aws.amazon.com/blogs/compute/running-executables-in-aws-lambda/)
55+
blog post:
56+
57+
> If you compile your own binaries, ensure that they’re either statically linked
58+
> or built for the matching version of Amazon Linux.
59+
60+
The example `sine` program in this repository uses the LGPL-licensed
61+
[libsndfile](https://github.com/erikd/libsndfile) library. To comply with the
62+
LPGL, libsndfile must be used as a shared library; it cannot be statically
63+
linked.
64+
65+
### Dockerfile
66+
67+
To compile binaries that are compatible with Amazon Linux 2, the
68+
[`Dockerfile`](./Dockerfile) starts from an Amazon Linux 2 base image:
69+
70+
```docker
71+
FROM amazonlinux:2.0.20200406.0
72+
```
73+
74+
The Dockerfile then builds and installs `libsndfile` and `sine`.
75+
76+
Binaries compiled in this environment will run on any AWS Lambda runtime that's
77+
based on Amazon Linux 2, such as the Node.js 12 and Python 3.8 runtimes. See
78+
[AWS Lambda
79+
runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) for
80+
a complete list.
81+
82+
### Makefile
83+
84+
The [`Makefile`](./Makefile) creates a container from the Docker image and
85+
copies the built artifacts from the container to the host system.

sine/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cmake_minimum_required(VERSION 3.8)
2+
3+
project(sine LANGUAGES CXX)
4+
5+
find_package(SndFile REQUIRED)
6+
7+
add_subdirectory(src)
8+
add_subdirectory(app)

sine/app/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
add_executable(sine sine.cpp)
2+
3+
target_link_libraries(sine PRIVATE libsine)
4+
5+
install(TARGETS sine
6+
RUNTIME DESTINATION bin)

sine/app/sine.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <libsine/libsine.h>
2+
3+
#include <cstdlib>
4+
#include <iostream>
5+
#include <string>
6+
7+
int main(int argc, char * argv[]) {
8+
if (argc != 3) {
9+
std::cerr << "USAGE: " << argv[0] << " <frequency (Hz)> <filename>" << std::endl;
10+
return 1;
11+
}
12+
13+
// Parse arguments
14+
float frequency = atof(argv[1]);
15+
std::string filename(argv[2]);
16+
17+
// Generate WAV file
18+
auto result = sine::generate_sine(frequency, filename);
19+
20+
return result ? 0 : 1;
21+
}

sine/include/libsine/libsine.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef LIBSINE_H
2+
#define LIBSINE_H
3+
4+
#include <string>
5+
6+
namespace sine
7+
{
8+
9+
// Generate a mono WAV file of a sine function at the specified frequency.
10+
// Returns true on success.
11+
bool generate_sine(float frequency, const std::string & filename);
12+
13+
} // namespace sine
14+
15+
#endif // LIBSINE_H

sine/src/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
add_library(libsine STATIC libsine.cpp ../include/libsine/libsine.h)
2+
3+
target_include_directories(libsine PUBLIC ../include)
4+
5+
target_compile_features(libsine PUBLIC cxx_std_11)
6+
7+
target_link_libraries(libsine PRIVATE SndFile::sndfile)

0 commit comments

Comments
 (0)