0

I am trying to build a cross-compiler from a x86-64 Linux host (Ubuntu-22.04 in WSL, with GCC 11) to arm-wrs-vxworks, and I'm having some serious trouble doing so. I have very limited experience with cross-compilers and think I may be running into some simple configuration issues.

I've tried using the procedures detailed under Jonathan Wakely's answer and in the community wiki answer at How to install GCC piece by piece with GMP, MPFR, MPC, ELF, without shared libraries?, to no avail.

In particular, doing this yields a compiler error related to the C++17 standard:

tar xzf gcc-4.9.4.tar.gz
cd gcc-4.9.4
./contrib/download_prerequisites
cd ..
mkdir objdir
cd objdir
$PWD/../gcc-4.9.4/configure --prefix=$HOME/GCC-4.9.4 --target=arm-wrs-vxworks
make -j
make install

I tried increasing the target GCC version to 8.1.0 and keeping the host GCC at 11. I also independently tried keeping the target version of 4.9.4 and changing to a host with GCC 7. (Note that I first attempted updating the target GCC to 12.1.0, though it appears versions that recent have dropped VxWorks support.) In both cases, I get past the C++17-related compiler error, but I see the same cannot compute suffix of object files error that several other people have reported (see below).

compiling gcc, configure: error: cannot compute suffix of object files: cannot compile

LibGCC compilation Failed with an error: cannot compute suffix of object files: cannot compile

Gcc compilation "cannot compute suffix of object files: cannot compile"

I have tried messing with the LD_LIBRARY_PATH variable, toggling various configuration options, and more, with no luck. Manually building and installing binutils with target=arm-wrs-vxworks didn't seem to have any effect, either. (Even getting rid of the --target option in the GCC configuration doesn't fix the build completely - I eventually get an error about missing sys/ustat.h instead.)

I also found references to a program called crosstool-NG, which seemed promising. I tried it out, and unfortunately, it appears as though it does not support VxWorks targets at all.

I've also consulted the following documentation:

https://gcc.gnu.org/install/build.html

https://crosstool-ng.github.io/docs/toolchain-construction/

https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/

None of the procedures just seem to work. It's as if half of the versions of these tools have out-of-the-box failures, and the other half are incompatible with what I need.

Is there something obvious I might be missing that would explain this? (If there's any more information I can provide that may help narrow down the problem, please let me know.)

Edit: Looking in objdir/arm-wrs-vxworks/libgcc/config.log, I see an error about WIND_BASE not being defined. Setting it to the prefix path gets past that issue, but then it throws another error of -march=armv4: not found immediately afterwards and suffers from the same ultimate suffix of object files error.

Edit 2: Removing and rebuilding the GCC build folder with WIND_BASE defined as the prefix folder, I see that the suffix of object files issue has finally gone away. However, now it appears to be missing the header <semLib.h>. I'm as-of-yet unsure where that is supposed to come from, but I suspect it's closely related to WIND_BASE.

Edit 3: My hunch was right. Replacing WIND_BASE with the path to the platform headers (a folder containing host and target subfolders) fixed the semLib issue, and a few tweaks to the header files later, I have what seems to be a working arm-wrs-vxworks-gcc. I still do not have any of the standard C++ headers (like <cstdio>) or a working arm-wrs-vxworks-g++, since it cannot find libstdc++.

4
  • gcc 4.9.4 ??? That is years, if not decades, obsolete. I'm not sure that arm was even a thing when that compiler came out. Current gcc is 12.x.y (or 13.x.y?). Look in gcc/config.gcc. Try: arm-wrs-vxworks7 as the comment says: We only support VxWorks 7 now on ARM You could try the source from the gcc repo: git://gcc.gnu.org/git/gcc.git Commented Jul 8 at 18:40
  • @CraigEstey Yeah, I know. You're preaching to the choir on this one. :'( Unfortunately, this is meant for VxWorks 5.5, so I can't use the latest GCC versions for the target. Anything would be an upgrade to the GCC 2.9 I'm using now. I'm currently focusing on the combination of GCC 11 on the host and GCC 8.1.0 on the target, since that seems to be the most promising avenue so far. If I can move up the GCC version further, I will, but as I mentioned in the post, I know that >=12.1.0 doesn't seem to support VxWorks 5.5. Commented Jul 8 at 18:44
  • For cross-devel, I'm not sure what you mean by gcc 8.1.0 on the target unless you mean the version of libgcc*.a? To my mind, only some runtime libraries on VxWorks itself (i.e. no gcc native port so that you run gcc on VxWorks itself) Commented Jul 8 at 19:33
  • Apologies, I can see why my wording was confusing. What I meant is that the host has GCC 11 installed, as is the default for WSL with Ubuntu 22.04. Then, I am grabbing the GCC 8.1.0 source from online and trying to use that to build a cross-compiler for the VxWorks target platform. Does that help clear things up? Commented Jul 8 at 19:35

1 Answer 1

0

Alright, I finally got it working. The following procedure is sufficient for it to work right, though not necessarily minimal. There may be an extra step here or there - I haven't yet tried cutting it down or optimizing the order.

Edit: There's still a problem - it turns out the libstdc++ built this way is for the x86-64 host and causes a linker error once the compilation errors are resolved if you try and actually use any of the symbols within. Still unclear on what caused this or how to fix it.

I also believe that something may still be wrong that causes compatibility issues with the standard library headers later on. I would welcome any feedback if someone knows about that kind of thing. (In particular, I see things like Standard library issue when cross-compiling and Cross-compilation error | '_Float128' does not name a type; did you mean '_Float32x'?)

  • Set up WIND_BASE environment variable to point to platform header folder (containing host and target folders)
  • Download and extract binutils-2.42.tar.gz
  • Go to binutils-2.42, then run ./configure --prefix=/opt/cross --target=arm-wrs-vxworks, make -j, and make install
  • Leave binutils-2.42
  • Download and extract gcc-8.1.0.tar.gz
  • Go to gcc-8.1.0 and run ./contrib/download_prerequisites
  • Leave gcc-8.1.0
  • Make a folder build-gcc
  • Go to build-gcc and run ../gcc-8.1.0/configure --prefix=/opt/cross --target=arm-wrs-vxworks --enable-languages=c,c++ --disable-multilib, make -j, and make install
  • Leave build-gcc
  • Make a folder build-cpp
  • Go to build-cpp and run ../gcc-8.1.0/libstdc++-v3/configure --prefix=/opt/cross --target=arm-wrs-vxworks --disable-multilib, make -j, and make install
  • Download and extract glibc-2.30.tar.xz
  • Make a folder build-glibc
  • Go to build-glibc and run ../glibc-2.30/configure --prefix=/opt/cross --target=arm-wrs-vxworks --disable-werror --disable-multilib, make -j, and make install

Note that the platform headers may need to be changed slightly for compatibility with the GCC headers.

From here, a file can be compiled using

/opt/cross/bin/arm-wrs-vxworks-g++
    -L/opt/cross/lib64
    -D__x86_64__
    -I/opt/cross/include
    -I/opt/cross/include/c++/8.1.0
    -I/opt/WIND_BASE/target/h
    file.cpp

and it should be able to compile and link successfully.

To address the original problems I was seeing:

  • The suffix of object files issue was actually caused by the WIND_BASE issue. After fixing that, I only needed to make a single change to the VxWorks platform headers, and then it worked. (See https://gcc.gnu.org/wiki/FAQ#configure_suffix for more info on debugging that problem.)
  • The inability to find libstdc++ was fixed with the -L flag at compile-time. It turns out the compiler does not search lib64 by default.
  • An issue with missing stubs-32.h (see https://gcc.gnu.org/wiki/FAQ#gnu_stubs-32.h) was fixed with the -D flag at compile-time.
  • The inability to find the C++ headers was fixed with the -I flags at compile-time. The C++ headers are apparently not part of the built-in include paths for g++.
12
  • The standard c++ library is going to be VxWorks specific, a component supplied as part of WindRiver's Tornado development environment? Such a library is specific to the OS after all as it has to call the OS's system interface to get things done. Also, if all you're doing is adding a new object file to a running VxWorks system, you're linking at load time and not as part of the compilation. So you'd not link against libtstdc++ anyway, that'd just be another .o to load (if not already loaded). If you're building a whole OS + app image, I think you need Tornado and a developer license?
    – bazza
    Commented Jul 9 at 20:11
  • Thank you, you may be on to something there. I can get the g++ command to succeed if I pass -nostdlib, but then I see missing symbols at load time. Unfortunately, updating the OS may not be an option for me here, so that may be a dead end. Part of what I don't understand here is that the -lgcc part of the linking stage worked just fine, and -lstdc++ is the only part causing problems. It seems like if I could resolve the libstdc++ architecture issue, I'd at least have a path forward, though maybe I'm wrong. Commented Jul 9 at 20:44
  • Thinking on it some more, I think I actually may have a way to switch out the libstdc++ file being used by the VxWorks OS. In any case, it will still require being able to build it for 32-bit ARM instead of x86-64, so that remains my primary goal for now. Commented Jul 9 at 21:19
  • So, when compiling an application it's not linked against libstdc++ (the -nostdlib flag is used). There are libstdc++.a libraries distributed as part of the Tornado distribution. The linking happens when you load the .o on the target, and I think the target needs to have been built with libstdc++ as part of the OS image. There's no "file" for libstdc++ on the target, as it's part of the OS. So, if you need to change libstdc++ on the target, I'm fairly sure you're having to re-build the whole target, which will require WindRiver's tool chain and proprietary binaries for the OS kernel, etc.
    – bazza
    Commented Jul 10 at 6:16
  • 1
    It seems that, when configuring an OS image, C++ runtime support was fragmented into a number of selectable options. For example, parts of the standard C++ library you could include / exclude was string i/o, strings, iostreams (core or full), complex numbers, and STL. That's about it. I suspect that at that time only a subset of libstdc++ was supported. That might be why you're getting compile errors. The C++ compiler didn't know about names spaces, though it accepted and ignored std::
    – bazza
    Commented Jul 11 at 19:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.