elliotchance / c2go

⚖️ A tool for transpiling C to Go.
MIT License
2.06k stars 151 forks source link

docker container for c2go #888

Open tijeco opened 2 years ago

tijeco commented 2 years ago

I was wondering if someone has worked on a docker container for c2go. I see in a few issues that it can be sensitive to changes in clang. Is there any way to have a docker container with the exact version of clang that is known to work correctly on the test files?

elliotchance commented 2 years ago

Not that I know of, but it’s a good idea.

tijeco commented 2 years ago

@elliotchance Gotcha! I can take a stab at it, though I'm far from a docker expert. Are there particular versions of clang that you use on your system that you know for sure work with the test examples?

elliotchance commented 2 years ago

It been so long since I've worked on c2go that I don't remember which versions I was using.

drpaneas commented 2 years ago

At the moment the project seems to not be working with recent versions of clang. Even a simple helloworld.c fails to transpile:

Source C

$ cat main.c
#include <stdio.h>
int main() {
   // printf() displays the string inside quotation
   printf("Hello, World!");
   return 0;
}

**Run the command to convert it into Go code:***

c2go transpile main.c

Error ...

panic: unknown node type: 'ColdAttr 0x7f9fe58af708 <col:42>'

goroutine 76 [running]:
github.com/elliotchance/c2go/ast.Parse({0xc00032893a, 0x20})
    /Users/drpaneas/gocode/pkg/mod/github.com/elliotchance/c2go@v0.26.10/ast/ast.go:294 +0x22d4
main.convertLinesToNodes({0xc000333d40, 0xe, 0x0})
    /Users/drpaneas/gocode/pkg/mod/github.com/elliotchance/c2go@v0.26.10/main.go:89 +0x115
main.convertLinesToNodesParallel.func1.2({0xc000333d40, 0x0, 0x0}, 0x0)
    /Users/drpaneas/gocode/pkg/mod/github.com/elliotchance/c2go@v0.26.10/main.go:121 +0x39
created by main.convertLinesToNodesParallel.func1
    /Users/drpaneas/gocode/pkg/mod/github.com/elliotchance/c2go@v0.26.10/main.go:119 +0x2da

After a couple hours of debugging I found out that the most recent supported version of clang seems to be:

11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c)

Since I don't want to mess up my system with different clang versions, I took a docker image that comes with clang 11 (see https://hub.docker.com/r/silkeh/clang/tags) and then I've installed Go and c2go on top. In that way it works in any machine, without worrying about the local system dependencies (well, you need docker obviously).

The dockerfile:

FROM docker.io/silkeh/clang:11

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes && \
    apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -q -y --force-yes \
    && apt-get install golang-go -q -y --force-yes \
    && mkdir -p ~/go/{bin,src,pkg} \
    && mkdir /code && mkdir /gocode

ENV GOPATH="$HOME/go"
ENV GOBIN="$GOPATH/bin"
ENV GO111MODULE="on"
ENV PATH=$PATH:$GOBIN

RUN go get -u github.com/elliotchance/c2go \
    && echo "#!/usr/bin/env bash" > /gocode/script.sh \
    && echo "\$GOBIN/c2go transpile /code/\$1" >> /gocode/script.sh \
    && echo "NAME=\$(basename \$1 .c)"  >> /gocode/script.sh \
    && echo "cat /\$NAME.go"  >> /gocode/script.sh \
    && chmod +x /gocode/script.sh

ENTRYPOINT [ "/gocode/script.sh" ]

You can run it like this:

 $ docker run --rm -it -v $PWD:/code docker.io/drpaneas/c2go:v0.26.0 main.c

The output now works fine, e.g. see the main() function of the helloworld example (the one that failed earlier):

// removed C types for brevity (it produces a long file)
func main() {
    noarch.Printf((&[]byte("Hello, World!\x00")[0]))
    return
}
func init() {
    stdin = noarch.Stdin
    stdout = noarch.Stdout
    stderr = noarch.Stderr
}

For shortcut (so you don't have to remember the long train-like docker command) you can put a function in our bash/zshell like this (e.g. vim ~/.zshenv or vim ~/.bashrc):

c2go() {
  docker run --rm -it -v $PWD:/code docker.io/drpaneas/c2go:v0.26.0 $1
}

then source your file (e.g. source ~/.zshenv or source ~/.bashrc) and try again passing only the filename you want to transpile: c2go main.c or `c2go main.c > main.go (if you want to put it into a file)

Now it works like a charm :)

tijeco commented 2 years ago

@drpaneas you are an absolute hero! I may finally be able to play around with this tool!

marvjone commented 2 years ago

@drpaneas I'm kinda new to docker. My question is how did you get go and then have c2go install in your container ? any help on this. I really would like to get c2go to work.

drpaneas commented 2 years ago

The answer is the Dockerfile which I have posted earlier. You can just copy paste it and build it locally. I've literally described the whole process in my previous step.

marvjone commented 2 years ago

@drpaneas thanks for the reply. I did the process you described and got the following error. like I said I'm new to docker. but will love to learn:

=> ERROR [2/3] RUN apt-get update && apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes && apt-get -o Dpkg::Options::="- 3.7s


[2/3] RUN apt-get update && apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes && apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -q -y --force-yes && apt-get install golang-go -q -y --force-yes && mkdir -p ~/go/{bin,src,pkg} && mkdir /code && mkdir /gocode:

5 0.342 Hit:1 http://deb.debian.org/debian bullseye InRelease

5 0.342 Get:2 http://security.debian.org/debian-security bullseye-security InRelease [44.1 kB]

5 0.365 Hit:3 http://deb.debian.org/debian bullseye-updates InRelease

5 0.654 Fetched 44.1 kB in 0s (103 kB/s)

5 0.654 Reading package lists...

5 1.152 Reading package lists...

5 1.629 Building dependency tree...

5 1.772 Reading state information...

5 1.798 Calculating upgrade...

5 1.984 W: --force-yes is deprecated, use one of the options starting with --allow instead.

5 1.984 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

5 1.997 Reading package lists...

5 2.473 Building dependency tree...

5 2.614 Reading state information...

5 2.643 Calculating upgrade...

5 2.872 W: --force-yes is deprecated, use one of the options starting with --allow instead.

5 2.873 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

5 2.885 Reading package lists...

5 3.365 Building dependency tree...

5 3.504 Reading state information...

5 3.693 W: --force-yes is deprecated, use one of the options starting with --allow instead.

5 3.693 golang-go is already the newest version (2:1.15~1).

5 3.693 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

5 3.698 mkdir: cannot create directory '/code': File exists


executor failed running [/bin/sh -c apt-get update && apt-get -o Dpkg::Options::="--force-confold" upgrade -q -y --force-yes && apt-get -o Dpkg::Options::="--force-confold" dist-upgrade -q -y --force-yes && apt-get install golang-go -q -y --force-yes && mkdir -p ~/go/{bin,src,pkg} && mkdir /code && mkdir /gocode]: exit code: 1