Compare commits
1 commit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c38100380 |
14 changed files with 423 additions and 0 deletions
1
7-toolchain
Symbolic link
1
7-toolchain
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
.
|
||||
45
Dockerfile
Normal file
45
Dockerfile
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
FROM registry.fedoraproject.org/f27/s2i-core:latest
|
||||
|
||||
ENV SUMMARY="Fedora variant of Red Hat Developer Toolset's C/C++ Toolchain from Software Collections" \
|
||||
DESCRIPTION="Platform for building C and C++ applications" \
|
||||
NAME=toolchain \
|
||||
VERSION=1 \
|
||||
ARCH=x86_64
|
||||
|
||||
LABEL com.redhat.component="$NAME" \
|
||||
name="$FGC/$NAME" \
|
||||
version="$VERSION" \
|
||||
architecture="$ARCH" \
|
||||
summary="$SUMMARY" \
|
||||
description="$DESCRIPTION" \
|
||||
io.k8s.description="$DESCRIPTION" \
|
||||
io.k8s.display-name="Fedora variant of Developer Toolset's C/C++ Toolchain from Software Collections" \
|
||||
usage="docker run -ti -v /src/app:/opt/app-root/src:z $FGC/$NAME bash" \
|
||||
help="docker run IMAGE cat /help.1 | /usr/bin/groff -t -man -ETascii" \
|
||||
maintainer="SoftwareCollections.org <sclorg@redhat.com>"
|
||||
|
||||
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
|
||||
|
||||
# Copy extra files to the image.
|
||||
COPY ./root/ /
|
||||
|
||||
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 && \
|
||||
usermod -g default default && \
|
||||
chown -R 1001:1001 /opt/app-root /usr/bin/container-entrypoint /usr/bin/usage && \
|
||||
chmod u+x /usr/bin/usage && \
|
||||
rpm-file-permissions
|
||||
|
||||
USER 1001
|
||||
|
||||
WORKDIR ${HOME}
|
||||
|
||||
# Set the default CMD to print the usage of the language image
|
||||
ENTRYPOINT ["container-entrypoint"]
|
||||
CMD ["usage"]
|
||||
1
Dockerfile.fedora
Symbolic link
1
Dockerfile.fedora
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
Dockerfile
|
||||
76
README.md
Normal file
76
README.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
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-7-toolchain-rhel7 in registry.access.redhat.com. Docker container based on CentOS packagess is available as centos/devtoolset-7-toolchain-centos7 in the Docker Hub.
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
Developer Toolset from Red Hat Software Collections provides various tools for C and C++ developers, so they are able to use the Developer Toolset tools without needing to be running a RHEL host. 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-7-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-7-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-7-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.
|
||||
|
||||
**`/opt/app-root`**
|
||||
Directory for application sources
|
||||
|
||||
|
||||
|
||||
|
||||
Missing dependencies
|
||||
--------------------
|
||||
It may happen that the program combiled in the container won't have all the dependencies available. In that case, the Developer Toolset Container Image is supposed to be used as a starting point for users, so they do not need to spin their own container from scratch. Creating a new layer on top of the existing container image can be done by writing a new Dockerfile, that will use this image in the FROM clause. For example to install `boost-devel` library as a dependency, create the following Dockerfile:
|
||||
|
||||
```
|
||||
FROM rhscl/devtoolset-7-toolchain-rhel7
|
||||
|
||||
USER 0
|
||||
RUN yum install -y --setopt=tsflags=nodocs boost-devel && yum clean all -y
|
||||
USER 1001
|
||||
```
|
||||
|
||||
Then, build the Dockerfile like this (you need a subscribed RHEL-7 machine to install additional RPMs into the RHEL-based container image):
|
||||
|
||||
```
|
||||
docker build -t myorg/devtoolset-7-toolchain-rhel7 .
|
||||
```
|
||||
|
||||
|
||||
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.
|
||||
|
||||
1
help.md
Symbolic link
1
help.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
README.md
|
||||
101
root/help.1
Normal file
101
root/help.1
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
.TH Toolchain For Building C and C++ Applications Docker Image
|
||||
.PP
|
||||
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\-7\-toolchain\-rhel7 in registry.access.redhat.com. Docker container based on CentOS packagess is available as centos/devtoolset\-7\-toolchain\-centos7 in the Docker Hub.
|
||||
|
||||
.SH Description
|
||||
.PP
|
||||
Developer Toolset from Red Hat Software Collections provides various tools for C and C++ developers, so they are able to use the Developer Toolset tools without needing to be running a RHEL host. 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.).
|
||||
|
||||
.SH Usage
|
||||
.PP
|
||||
Suppose you have a source for a C application in the \fB\fC/src/app\fR directory on the host and that we use the RHEL\-based variant (Docker image called rhscl/devtoolset\-7\-toolchain\-rhel7). To build such application you can mount the application sources to the container and run appropriate tools interactively:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
docker run \-ti \-\-rm \-v /src/app:/opt/app\-root/src:z rhscl/devtoolset\-7\-toolchain\-rhel7 bash
|
||||
bash\-4.3$ gcc \-o foo \-ggdb \-g2 foo.c
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
That will compile one file from \fB\fC/src/app\fR using GCC from container with options \fB\fC\-ggdb \-g2\fR\&.
|
||||
|
||||
.PP
|
||||
To run \fB\fCmake\fR non\-interactively, run:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
docker run \-ti \-\-rm \-v $PWD:/opt/app\-root/src:z rhscl/devtoolset\-7\-toolchain\-rhel7 make
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
That will compile the project from current directory using \fB\fCmake\fR utility.
|
||||
|
||||
.PP
|
||||
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).
|
||||
|
||||
.SH Environment variables and volumes
|
||||
.PP
|
||||
You can set the following mount points by passing the \fB\fC\-v /host:/container\fR flag to Docker.
|
||||
|
||||
.PP
|
||||
\fB\fB\fC/opt/app\-root\fR\fP
|
||||
.br
|
||||
Directory for application sources
|
||||
|
||||
.SH Missing dependencies
|
||||
.PP
|
||||
It may happen that the program combiled in the container won't have all the dependencies available. In that case, the Developer Toolset Container Image is supposed to be used as a starting point for users, so they do not need to spin their own container from scratch. Creating a new layer on top of the existing container image can be done by writing a new Dockerfile, that will use this image in the FROM clause. For example to install \fB\fCboost\-devel\fR library as a dependency, create the following Dockerfile:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
FROM rhscl/devtoolset\-7\-toolchain\-rhel7
|
||||
|
||||
USER 0
|
||||
RUN yum install \-y \-\-setopt=tsflags=nodocs boost\-devel \&\& yum clean all \-y
|
||||
USER 1001
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
Then, build the Dockerfile like this (you need a subscribed RHEL\-7 machine to install additional RPMs into the RHEL\-based container image):
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
docker build \-t myorg/devtoolset\-7\-toolchain\-rhel7 .
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SH Troubleshooting
|
||||
.PP
|
||||
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:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
docker logs <container>
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SH See also
|
||||
.PP
|
||||
Dockerfile and other sources for this container image are available on
|
||||
|
||||
\[la]https://github.com/sclorg/devtoolset-container\[ra]\&.
|
||||
In that repository, Dockerfile for CentOS is called Dockerfile, Dockerfile
|
||||
for RHEL is called Dockerfile.rhel7.
|
||||
6
root/opt/app-root/etc/scl_enable
Normal file
6
root/opt/app-root/etc/scl_enable
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# IMPORTANT: Do not add more content to this file unless you know what you are
|
||||
# doing. This file is sourced everytime the shell session is opened.
|
||||
#
|
||||
# This will make scl collection binaries work out of box.
|
||||
unset BASH_ENV PROMPT_COMMAND ENV
|
||||
source scl_source enable devtoolset-7
|
||||
6
root/usr/bin/container-entrypoint
Executable file
6
root/usr/bin/container-entrypoint
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
cmd="$1"; shift
|
||||
exec $cmd "$@"
|
||||
|
||||
8
root/usr/bin/usage
Normal file
8
root/usr/bin/usage
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
cat <<EOF
|
||||
This is a devtoolset-7-toolchain base image.
|
||||
|
||||
Sample invocation:
|
||||
docker run -ti devtoolset-7-toolchain-rhel7 /bin/bash
|
||||
EOF
|
||||
|
||||
0
sources
0
sources
4
test/expected-usage
Normal file
4
test/expected-usage
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
This is a devtoolset-7-toolchain base image.
|
||||
|
||||
Sample invocation:
|
||||
docker run -ti devtoolset-7-toolchain-rhel7 /bin/bash
|
||||
154
test/run
Executable file
154
test/run
Executable file
|
|
@ -0,0 +1,154 @@
|
|||
#!/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.
|
||||
#
|
||||
|
||||
if [ "$DEBUG" != "" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
IMAGE_NAME=${IMAGE_NAME:-rhscl/devtoolset-7-toolchain-rhel7}
|
||||
THISDIR=$(dirname ${BASH_SOURCE[0]})
|
||||
|
||||
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)' $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