Compare commits
16 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0354eb79c0 | ||
|
|
9a2ff2b530 | ||
|
|
ff1556d0f3 | ||
|
|
1843df3521 | ||
|
|
00b7710b7c | ||
|
|
a025f91dc5 | ||
|
|
34b7c9efbe | ||
|
|
a8ebd1b810 | ||
|
|
052ee0cea8 | ||
|
|
bdf952007c | ||
|
|
efb76cb64a | ||
|
|
78f4c97dcd | ||
|
|
b005380ac1 | ||
|
|
b6d8836cb6 | ||
|
|
3e5bed9c18 | ||
|
|
238416a849 |
8 changed files with 325 additions and 0 deletions
45
Dockerfile
Normal file
45
Dockerfile
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
FROM fedora:25
|
||||||
|
MAINTAINER Honza Horak <hhorak@redhat.com>
|
||||||
|
|
||||||
|
LABEL io.k8s.description="Platform for building C and C++ applications" \
|
||||||
|
io.k8s.display-name="Fedora variant of Developer Toolset's C/C++ Toolchain from Software Collections"
|
||||||
|
|
||||||
|
ENV NAME=toolchain VERSION=1 RELEASE=15 ARCH=x86_64
|
||||||
|
|
||||||
|
LABEL com.redhat.component="$NAME" \
|
||||||
|
name="$FGC/$NAME" \
|
||||||
|
version="$VERSION" \
|
||||||
|
release="$RELEASE.$DISTTAG" \
|
||||||
|
architecture="$ARCH"
|
||||||
|
|
||||||
|
RUN INSTALL_PKGS="gcc gcc-c++ gcc-gfortran gdb make" && \
|
||||||
|
dnf install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \
|
||||||
|
rpm -V $INSTALL_PKGS && \
|
||||||
|
dnf clean all -y
|
||||||
|
|
||||||
|
# Use entrypoint so path is correctly adjusted already at the time the command
|
||||||
|
# is searching, so something like docker run IMG gcc runs binary from SCL.
|
||||||
|
COPY contrib/bin/container-entrypoint /usr/bin/container-entrypoint
|
||||||
|
|
||||||
|
# Install the usage script with base image usage informations
|
||||||
|
COPY contrib/bin/usage /usr/bin/usage
|
||||||
|
|
||||||
|
# Copy README.md to the container
|
||||||
|
COPY README.md /help.md
|
||||||
|
|
||||||
|
ENV HOME=/opt/app-root/src \
|
||||||
|
PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
|
RUN mkdir -p ${HOME} && \
|
||||||
|
groupadd -r default -f -g 1001 && \
|
||||||
|
useradd -u 1001 -r -g default -d ${HOME} -s /sbin/nologin \
|
||||||
|
-c "Default Application User" default && \
|
||||||
|
chown -R 1001:1001 /opt/app-root
|
||||||
|
|
||||||
|
USER 1001
|
||||||
|
|
||||||
|
WORKDIR ${HOME}
|
||||||
|
|
||||||
|
# Set the default CMD to print the usage of the language image
|
||||||
|
ENTRYPOINT ["container-entrypoint"]
|
||||||
|
CMD ["usage"]
|
||||||
57
README.md
Normal file
57
README.md
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
Toolchain For Building C and C++ Applications Docker Image
|
||||||
|
==========================================================
|
||||||
|
|
||||||
|
Developer Toolchain is part of the Red Hat Software Collections and the Toolchain is a subset of tools usable for building C and C++ applications. Docker container based on Red Hat Software Collection packages is available as rhscl/devtoolset-6-toolchain-rhel7 in registry.access.redhat.com. Docker container based on CentOS packagess is available as centos/devtoolset-6-toolchain-centos7 in the Docker Hub.
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
Developer Toolset from Red Hat Software Collections provides various tools for C and C++ developers. The Toolchain part of the Developer Toolset contains tools for building such applications (GCC compiler for C and C++, GDB, gfortran compiler, etc.). Perftools part contains then tools for debugging and further analysis of the applications (oprofile, valgrind, systemtap, etc.).
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----------
|
||||||
|
Suppose you have a source for a C application in the `/src/app` directory on the host and that we use the RHEL-based variant (Docker image called rhscl/devtoolset-6-toolchain-rhel7). To build such application you can mount the application sources to the container and run appropriate tools interactively:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -ti --rm -v /src/app:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 bash
|
||||||
|
bash-4.3$ gcc -o foo -ggdb -g2 foo.c
|
||||||
|
```
|
||||||
|
|
||||||
|
That will compile one file from `/src/app` using GCC from container with options `-ggdb -g2`.
|
||||||
|
|
||||||
|
To run `make` non-interactively, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -ti --rm -v $PWD:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 make
|
||||||
|
```
|
||||||
|
|
||||||
|
That will compile the project from current directory using `make` utility.
|
||||||
|
|
||||||
|
In both cases above user must ensure that the directory where GCC will write data into is writable for the user used inside the container (by default UID 1001).
|
||||||
|
|
||||||
|
|
||||||
|
Environment variables and volumes
|
||||||
|
---------------------------------
|
||||||
|
You can set the following mount points by passing the `-v /host:/container` flag to Docker.
|
||||||
|
|
||||||
|
| Volume mount point | Description |
|
||||||
|
| :----------------------- | --------------------------------- |
|
||||||
|
| `/opt/app-root` | Directory for application sources |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
---------------
|
||||||
|
The error log or standard log if container is run non-interactively is available in the container log. The log can be examined by running:
|
||||||
|
|
||||||
|
docker logs <container>
|
||||||
|
|
||||||
|
|
||||||
|
See also
|
||||||
|
--------
|
||||||
|
Dockerfile and other sources for this container image are available on
|
||||||
|
https://github.com/sclorg/devtoolset-container.
|
||||||
|
In that repository, Dockerfile for CentOS is called Dockerfile, Dockerfile
|
||||||
|
for RHEL is called Dockerfile.rhel7.
|
||||||
|
|
||||||
6
contrib/bin/container-entrypoint
Executable file
6
contrib/bin/container-entrypoint
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
cmd="$1"; shift
|
||||||
|
exec $cmd "$@"
|
||||||
|
|
||||||
23
contrib/bin/usage
Executable file
23
contrib/bin/usage
Executable file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
cat <<EOF
|
||||||
|
Developer Toolset from Red Hat Software Collections provides various tools for C and C++ developers. The Toolchain part of the Developer Toolset contains tools for building such applications (GCC compiler for C and C++, GDB, gfortran compiler, etc.).
|
||||||
|
|
||||||
|
|
||||||
|
Basic Usage
|
||||||
|
-----------
|
||||||
|
Suppose you have a source for a C application in the /src/app directory on the host and that we use the RHEL-based variant (Docker image called rhscl/devtoolset-6-toolchain-rhel7). To build such application you can mount the application sources to the container and run appropriate tools interactively:
|
||||||
|
|
||||||
|
docker run -ti --rm -v /src/app:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 bash
|
||||||
|
bash-4.3$ gcc -o foo -ggdb -g2 foo.c
|
||||||
|
|
||||||
|
That will compile one file from /src/app using GCC from container with options -ggdb -g2.
|
||||||
|
|
||||||
|
To run make non-interactively, run:
|
||||||
|
|
||||||
|
docker run -ti --rm -v $PWD:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 make
|
||||||
|
|
||||||
|
That will compile the project from current directory using make utility.
|
||||||
|
|
||||||
|
In both cases above user must ensure that the directory where GCC will write data into is writable for the user used inside the container (by default UID 1001).
|
||||||
|
EOF
|
||||||
|
|
||||||
19
test/expected-usage
Normal file
19
test/expected-usage
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
Developer Toolset from Red Hat Software Collections provides various tools for C and C++ developers. The Toolchain part of the Developer Toolset contains tools for building such applications (GCC compiler for C and C++, GDB, gfortran compiler, etc.).
|
||||||
|
|
||||||
|
|
||||||
|
Basic Usage
|
||||||
|
-----------
|
||||||
|
Suppose you have a source for a C application in the /src/app directory on the host and that we use the RHEL-based variant (Docker image called rhscl/devtoolset-6-toolchain-rhel7). To build such application you can mount the application sources to the container and run appropriate tools interactively:
|
||||||
|
|
||||||
|
docker run -ti --rm -v /src/app:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 bash
|
||||||
|
bash-4.3$ gcc -o foo -ggdb -g2 foo.c
|
||||||
|
|
||||||
|
That will compile one file from /src/app using GCC from container with options -ggdb -g2.
|
||||||
|
|
||||||
|
To run make non-interactively, run:
|
||||||
|
|
||||||
|
docker run -ti --rm -v /opt/app-root/src:/opt/app-root/src:z rhscl/devtoolset-6-toolchain-rhel7 make
|
||||||
|
|
||||||
|
That will compile the project from current directory using make utility.
|
||||||
|
|
||||||
|
In both cases above user must ensure that the directory where GCC will write data into is writable for the user used inside the container (by default UID 1001).
|
||||||
155
test/run
Executable file
155
test/run
Executable file
|
|
@ -0,0 +1,155 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# The 'run' script performs simple tests that verifies usability
|
||||||
|
# of tools, packaged in toolchain image.
|
||||||
|
#
|
||||||
|
# IMAGE_NAME specifies a name of the candidate image used for testing.
|
||||||
|
# The image has to be available before this script is executed.
|
||||||
|
#
|
||||||
|
# DEBUG environment variable, if not empty, makes 'run' to log every step
|
||||||
|
# of testing.
|
||||||
|
#
|
||||||
|
|
||||||
|
THISDIR=$(dirname ${BASH_SOURCE[0]})
|
||||||
|
|
||||||
|
if [ "$DEBUG" != "" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
IMAGE_NAME=${IMAGE_NAME:-rhscl/devtoolset-4-toolchain-rhel7}
|
||||||
|
|
||||||
|
function info () {
|
||||||
|
echo -e "\e[1m[INFO] $@\e[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function pass () {
|
||||||
|
echo -e "\e[1;32m[PASS] $@\e[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function error () {
|
||||||
|
echo -e "\e[1;31m[ERROR] $@\e[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_result() {
|
||||||
|
local label="$1"
|
||||||
|
local result="$2"
|
||||||
|
local expected="$3"
|
||||||
|
|
||||||
|
if [[ "$result" = "$expected" ]]; then
|
||||||
|
pass "$label: PASS"
|
||||||
|
else
|
||||||
|
error "$label: FAIL ($result)"
|
||||||
|
RESULT=1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_docker_run_usage () {
|
||||||
|
info "Testing 'docker run' usage ..."
|
||||||
|
|
||||||
|
docker run --rm $IMAGE_NAME > $TMPDIR/actual-usage
|
||||||
|
check_result "Exit code is zero" $? 0
|
||||||
|
|
||||||
|
diff $THISDIR/expected-usage $TMPDIR/actual-usage &> /dev/null
|
||||||
|
check_result "Usage info matches the expected text" $? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_sanity_gcc_usage () {
|
||||||
|
info "Testing 'gcc -v' usage ..."
|
||||||
|
|
||||||
|
docker run --rm $IMAGE_NAME gcc -v &> $TMPDIR/actual-gcc-v
|
||||||
|
check_result "Exit code is zero" $? 0
|
||||||
|
|
||||||
|
grep 'gcc version ' $TMPDIR/actual-gcc-v &> /dev/null
|
||||||
|
check_result "Output contains gcc version" $? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_sanity_gdb_usage () {
|
||||||
|
info "Testing 'gdb -v' usage ..."
|
||||||
|
|
||||||
|
docker run --rm $IMAGE_NAME gdb -v &> $TMPDIR/actual-gdb-v
|
||||||
|
check_result "Exit code is zero" $? 0
|
||||||
|
|
||||||
|
grep 'GNU gdb (GDB) Fedora ' $TMPDIR/actual-gdb-v &> /dev/null
|
||||||
|
check_result "Output contains gdb version" $? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_gcc_compile () {
|
||||||
|
info "Testing compilation via 'docker run gcc foo.c ..."
|
||||||
|
|
||||||
|
rm -f $TMPDIR/foo $TMPDIR/foo.c
|
||||||
|
|
||||||
|
cat << EOF > $TMPDIR/foo.c
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { printf("Hello world from containerized gcc!\n"); return 0; }
|
||||||
|
EOF
|
||||||
|
|
||||||
|
docker run --rm -v $TMPDIR:$TMPDIR:z $IMAGE_NAME gcc -o $TMPDIR/foo $TMPDIR/foo.c
|
||||||
|
check_result "Exit code is zero" $? 0
|
||||||
|
|
||||||
|
test -e $TMPDIR/foo
|
||||||
|
check_result "Compiled binary exists" $? 0
|
||||||
|
|
||||||
|
$TMPDIR/foo &> $TMPDIR/actual-output
|
||||||
|
check_result "Exit code of compiled binary is zero" $? 0
|
||||||
|
|
||||||
|
grep "Hello world from containerized gcc!" $TMPDIR/actual-output &> /dev/null
|
||||||
|
check_result "Compiled binary works" $? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_gdb_batch_debug () {
|
||||||
|
info "Testing debugging via 'docker run gdb -batch ..."
|
||||||
|
|
||||||
|
rm -f $TMPDIR/foo $TMPDIR/foo.c
|
||||||
|
|
||||||
|
cat << EOF > $TMPDIR/foo.c
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *s = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < INT_MAX; i++)
|
||||||
|
s[i] = 'f';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
docker run --rm -v $TMPDIR:$TMPDIR:z $IMAGE_NAME gcc -o $TMPDIR/foo -ggdb -g2 $TMPDIR/foo.c
|
||||||
|
check_result "Compile test binary" $? 0
|
||||||
|
|
||||||
|
test -e $TMPDIR/foo
|
||||||
|
check_result "Test binary exists" $? 0
|
||||||
|
|
||||||
|
docker run --rm --privileged -v $TMPDIR:$TMPDIR:z $IMAGE_NAME gdb -batch -ex 'run' -ex 'bt' $TMPDIR/foo &> $TMPDIR/actual-output
|
||||||
|
check_result "Exit code is zero" $? 0
|
||||||
|
|
||||||
|
grep -q "Program received signal SIGSEGV, Segmentation fault." $TMPDIR/actual-output &> /dev/null
|
||||||
|
check_result "GDB output informs about segfault" $? 0
|
||||||
|
|
||||||
|
grep -q "s\[i\] = 'f';" $TMPDIR/actual-output &> /dev/null
|
||||||
|
check_result "GDB output prints source line" $? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
TMPDIR=`mktemp -d`
|
||||||
|
chmod a+rwx $TMPDIR
|
||||||
|
|
||||||
|
RESULT=0
|
||||||
|
|
||||||
|
test_docker_run_usage
|
||||||
|
test_sanity_gcc_usage
|
||||||
|
test_sanity_gdb_usage
|
||||||
|
test_gcc_compile
|
||||||
|
test_gdb_batch_debug
|
||||||
|
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
|
||||||
|
if [ "$RESULT" = "0" ]; then
|
||||||
|
info "All tests finished"
|
||||||
|
else
|
||||||
|
error "Some tests failed"
|
||||||
|
exit $RESULT
|
||||||
|
fi
|
||||||
14
test/test-app/Makefile
Normal file
14
test/test-app/Makefile
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -g
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
all: hello
|
||||||
|
|
||||||
|
Hello: hello.c
|
||||||
|
$(CC) $(CFLAGS) -o hello hello.c
|
||||||
|
|
||||||
|
clean veryclean:
|
||||||
|
$(RM) hello
|
||||||
|
|
||||||
6
test/test-app/hello.c
Normal file
6
test/test-app/hello.c
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
printf ("Hello from container!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue