Dr. Brian Robert Callahan

academic, developer, with an eye towards a brighter techno-social life



[prev]
[next]

2022-12-19
GCC now includes Modula-2 and Rust. Do they work on OpenBSD?

Two new language frontends have been added to GCC: Modula-2 and Rust. I think this is great news on both accounts: having a Wirth language in GCC fills my childhood heart with joy (though I do wish GNU Pascal can one day be revived and mainlined, as Pascal was the first non-BASIC language I learned). And Rust appears here to stay, so having more than just the one official compiler seemed all but inevitable. I think both languages make sense for GCC and am glad to see that they will be making the upcoming GCC 13.1.

Let's see how they fare on OpenBSD.

Building GNU Modula-2

I maintain a vanilla repository of GCC that I build daily on one of my OpenBSD machines. This is because I occasionally do development for and in D and GDC is my preferred D compiler.

Now that Modula-2 and Rust are mainlined, all I had to do was run git pull and my repo was updated with the new languages. I added m2,rust to the --enable-languages configure option, so now it looks like --enable-languages=c,c++,d,fortran,lto,m2,objc,obj-c++,rust and I was ready to go.

During the build, I did have one issue when building Modula-2: there is a plugin called m2rte.so and if you try to build it with GCC's internal libintl, you get a build error because the GCC build system cannot find the internal libintl.h. This was easily fixed with this patch, which I have sent to the GNU Modula-2 developer:

diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index a8bd7fe4d19..c9aacb09f02 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -409,7 +409,7 @@ m2.install-plugin: installdirs
 plugin/m2rte$(exeext).so: $(srcdir)/m2/plugin/m2rte.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2) \
         insn-attr-common.h insn-flags.h $(generated_files)
        test -d plugin || mkdir plugin
-       $(PLUGINCC) $(PLUGINCFLAGS) -fno-rtti -I. -I$(srcdir) -I$(srcdir)/m2 -I$(srcdir)/m2/gm2-gcc -I$(srcdir)/../include -I$(srcdir)/../libcpp/include -Wall $(GMPINC) -Wno-literal-suffix -fPIC -c -o plugin/m2rte.o $(srcdir)/m2/plugin/m2rte.cc
+       $(PLUGINCC) $(PLUGINCFLAGS) -fno-rtti -I. -I$(srcdir) -I$(srcdir)/m2 -I$(srcdir)/m2/gm2-gcc -I$(srcdir)/../include -I$(srcdir)/../libcpp/include -I$(objdir)/../intl -Wall $(GMPINC) -Wno-literal-suffix -fPIC -c -o plugin/m2rte.o $(srcdir)/m2/plugin/m2rte.cc
        $(PLUGINCC) $(PLUGINCFLAGS) $(PLUGINLIBS) -fno-rtti plugin/m2rte.o -shared -o $@


And that's all you need to build GNU Modula-2. Hopefully that fix gets integrated into GCC so there will be no patches needed.

Building GNU Rust

GNU Rust built out-of-the-box with no patches needed.

Running GNU Modula-2

I have to admit that I already knew that GNU Modula-2 would work fine. Long-time readers might remember that I reported about a year and a half ago that I had gotten GM2 working on OpenBSD. I've been hanging around the GM2 community and the mailing list ever since.

Things have gotten easier since then. Let's take a simple Hello world example:

MODULE hello ;

FROM StrIO IMPORT WriteString, WriteLn ;

BEGIN
   WriteString('Hello world from M2!') ; WriteLn
END hello.

All I had to do was run:

$ gm2 hello.mod
$ ./a.out
Hello world from M2!

GNU Modula-2 just works on OpenBSD and that's awesome!

Running GNU Rust

I had already been in contact with the GNU Rust people when I first heard about it just to let them know that I had tried building it and it built fine on OpenBSD. I know, and the team is clear to state, that GNU Rust is still in its alpha stages. Knowing that, I chose to disregard those warnings and tried to build some Rust code anyway.

I used the Hello world program that you can find on the Rust By Example site:

fn main() {
    println!("Hello World!");
}

I then tried to compile it with:

$ gccrs hello.rs

And I got back a very large warning message:

rust1: fatal error: gccrs is not yet able to compile Rust code properly. Most of the errors produced will be gccrs' fault and not the crate you are trying to compile. Because of this, please reports issues to us directly instead of opening issues on said crate's repository.

Our github repository: https://github.com/rust-gcc/gccrs
Our bugzilla tracker: https://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=__open__&component=rust&product=gcc

If you understand this, and understand that the binaries produced might not behave accordingly, you may attempt to use gccrs in an experimental manner by passing the following flag:

`-frust-incomplete-and-experimental-compiler-do-not-use`

or by defining the following environment variable (any value will do)

GCCRS_INCOMPLETE_AND_EXPERIMENTAL_COMPILER_DO_NOT_USE

Forcargo-gccrs, this means passing

GCCRS_EXTRA_FLAGS="-frust-incomplete-and-experimental-compiler-do-not-use"

as an environment variable.
compilation terminated.

So I did the obviously correct thing to do and attempted to recompile with:

$ gccrs -frust-incomplete-and-experimental-compiler-do-not-use hello.rs

And then I got back this error:

hello.rs:2:5: error: unknown macro: [println]
    2 |     println!("Hello World!");
      |     ^

Which I guess I can't be too disappointed about. They did say things will be broken. We will just need to keep it on our radar and try again from time to time. Or, if you know why I got this error and know how to fix it, let me know and I will update this post to include the correct steps.

I then made a more compilable program:

fn main() -> i32 {
    return 42;
}

I was able to successfully compile this program:

$ gccrs -frust-incomplete-and-experimental-compiler-do-not-use hello.rs
$ ./a.out
$ echo $?
42

I also noticed that in addition to the expected a.out file, GNU Rust also left behind a 29-byte hello.rox file that contains this data:

$ hexdump -C hello.rox
00000000  47 52 53 54 d4 1d 8c d9  8f 00 b2 04 e9 80 09 98  |GRST............|
00000010  ec f8 42 7e 24 68 65 6c  6c 6f 24 30 24           |..B~$hello$0$|
0000001d

I'm not sure what this is but I am including it for completeness. If you know what this is, let me know!

Update: I have been told that the rox file has to do with crates. It is written about here.

I also got a working Hello world:

extern "C" {
    fn printf(s: *const i8, ...);
}

unsafe fn main() {
    let a = "Hello world from Rust!\n\0";
    let b = a as *const str;
    let c = b as *const i8;

    printf(c);
}

This indeed works:

$ gccrs -frust-incomplete-and-experimental-compiler-do-not-use hello.rs
$ ./a.out
Hello world from Rust!

Get a pre-built package

If you'd like a pre-built package of GCC including compilers for C, C++, D, Fortran, Modula-2, Objective-C, Objective-C++, and Rust, I have one available for OpenBSD/amd64 -current on GitHub:

$ doas pkg_add -Dunsigned https://github.com/ibara/openbsd-gcc/releases/download/amd64/gcc-devel-13.0.0pl20221218.tgz

This package will install GCC into /usr/local/gnu so that it will not conflict with any other installation of GCC you might have on your system.

Conclusion

I am very excited to see Modula-2 and Rust added to GCC. The fact that they are both ready to go on OpenBSD is a positive reminder of the importance of portability across platforms. I am excited to see the new life breathed into Modula-2 and the continued success of Rust, now that both languages have another open source implementation available to all. I am also excited to see more usage of both languages on the BSDs.

Now if we can only get Pascal added to GCC, my life will be complete!

Top

RSS