Is Clang as (or more) portable than gcc for C++? - clang

Suppose I have a C++ project, and I compile it with gcc and with clang. You can assume that the gcc compiled version runs in another linux machine. Will this imply (in normal circumstances) that the clang version will also run on the other linux machine?

Clang binraries are as portable as gcc binaries are, as long as you are linking to the same libraries and you aren't passing flags like -march=native to the compiler.
Clang has one huge advantage over gcc, it can deal with alsmost all libstdc++ versions,
while gcc is bound to its bundled version and often can't parse any older versions.
So the following often happens in production environments:
Install an LTS distro (Ubuntu 12.04 for example)
Keep gcc, glibc and libstdc++ untouched
Install a recent clang version for C++11, etc
Build the release binaries with clang
So (in my specific example) those binaries will work on all
distros with libstdc++ >= 4.6 and glibc >= 2.15.
This may be an interesting read for you.

If the program is a simple Hello world, it should work on the other machine when compiled through Clang.
But when the program is a real program with a lot a lines and compilation units, and calls to many external libs everything is possible depending on the program itself and the compilation options :
hardware requirements (memory) being different (mainly depends on compilation options)
use of different (versions of) libraries between gcc and clang
UB giving expected results in one and not in the other
different usages for implementation defined rules
use of gcc extensions not accepted by clang
For all of the above except 2 first, it should run on other machines it it runs on one

linux programs depend on their build environment. If your glibc version or kernel is different there will be lots of possibilities that the executable will not be able to run. You could use the interpreter language of llvm though, it compiles into bytecode which can be interpreted on various operating systems.

The answer is, well, depends.
The first hard requirement is the same CPU architecture. 64 Bit is not enough of a qualifier. If you compile of x64 you won't have much success running it on 64-Bit ARM.
The next big one is libraries. If you use any libraries in the program, the target system needs to have those libraries. This includes the kernel headers. So if you compile for e.g. a current kernel version, using the most cutting-edge features, then you will have no joy running that program on a very old version of Linux.
The last one is hardware dependencies. If you create a program that e.g. requires 4 GB of RAM and then try to run it on a small embedded device with 256 MB RAM, that won't work either.
To fit better to your changed question: From my experience there shouldn't be much of a difference in portability between Clang and gcc. Also googling didn't turn up anything, so it should basically work. But better always test stuff like that before you publish some binary in production.

Related

runtime clang/clang++ with non-standard gcc install?

Is there a way to get clang/clang++ to use a gcc/g++ installation in a non-standard (i.e. not /usr) place?
I'm trying to get AMD's AOCC 4.0 compiler to work. They provide a pre-compiled version that you just unpack. The problem is that it seems to assume gcc is in /usr/lib/gcc/... In my case I'm on CentOS 7 so that's gcc 4.8.5. I want to use newer gcc's install in /sw/opt (and managed with environment modules) but even if the gcc is in my path, clang only finds that 4.8.5 version in /usr. This is also a problem in that I have a cluster that has no default gcc installed (but many gcc versions installed in /cluster/sw) and I can't get clang to see them.
When I want LLVM I usually just build from scratch and specify GCC_INSTALL_PREFIX but that only seems to be useful at build time and since AMD only provides executables I'm out of luck.
Ideally I'd like to get clang/clang++ to point to another gcc (en mass: include, libs, etc...) or not be dependent on gcc at all.
AOCC seems to be based on 14.0.6 if that matters:
AMD clang version 14.0.6 (CLANG: AOCC_4.0.0-Build#434 2022_10_28) (based on LLVM Mirror.Version.14.0.6)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /sw/opt/aocc-compiler-4.0.0/bin
After more poking around I've discovered that there is a clang option "--gcc-toolchain" that seems to address this. Some clang documentation also lists an option "--gcc-install-dir" but neither the 14.0.6 based version of AOCC nor the 16.0.0 based version of OneAPI (2023.0) seem to recognize it. I don't see it in the output of "clang --help" either so who knows.

Complete and isolated LLVM/musl toolchain

What I'm trying to achieve is to compile an GNU independent and isolated LLVM toolchain using musl as clib.
Recently LLVM 4.0 has been released with lot's of new cool features, including production ready LLD, so also the linking step could be handled by LLVM.
More or less the stack is:
clang
llvm
lld
compiler-rt
libcxx
libcxxabi
musl
Following this, it is actually possible to do so without much patching or such (apart from compiling musl), but sadly, there is no good documentation about that.
Any suggestions?
There is an example of using Clang + Musl together to compile "Hello World" in C here: https://github.com/njlr/portable-cxx
It only requires wget, tar and make to be installed. Clang and Musl are downloaded as part of the build process.
The key is to disable the usual include paths using -nostdinc and then add the Musl ones using -isystem.
I was solving the same problem with my NGTC (Non-GNU toolchain) project. Please take a look at my build scripts and patches.
I used this toolchain to build a small Linux distro without any code from GNU project: nenuzhnix.

Compiling C Source for iOS

I have some existing source code that is written in C that I want to build and include in my iOS project. The entire source package is very large and is built using existing Makefiles and GCC. It is producing static libraries (.a files) that I would love to move over to my iOS project. However, the static libraries the Makefile produces is for x86 processors, which obviously won't work on iOS.
Is there a way I can switch GCC to build for ARMv7/ARM64 instead, without making changes to the existing source (in most cases)? I know there is the -march switch for GCC or you can download ARM specific GCC compilers, so I know the general concept of building for a different architecture than the build machine.
To build for ARM on Mac OS, will I have to download a different GCC compiler or is that capability built into the default GCC?
I'm sorry for the lack of understanding of basic concepts here; I'm primarily a Java and Objective-C developer, so building source for different architectures is a mostly foreign concept to me.
Whilst GCC supports a good many CPU architecture and platforms, it is usually built for a single one. To compile for ARM you generally need an ARM-cross-compiling GCC targeted appropriately.
The default system compiler for MacOSX and iOS for all architectures is clang and has been for some time (the last version of GCC apple shipped in dev tools is creaking and obsolete, and definitely won't support ARMv8).
The usual way of getting clang is to install Xcode (free from the App Store). There's a option in the installer (and in the UI of Xcode) to install the command-line tool package. This installs sym-links in /usr/bin to the compiler, and installs a bunch of other stuff you might expect such as make.
clang is (mostly) command-line compatible with gcc, and furthermore, you'll find that if you run gcc from the command-line on a Mac with dev-tools installed, you in fact get clang.
$ gcc --version
Configured with: -- prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
clang comes with ARMv7, ARMv8, i686, x86_64 on MacOSX, and can be configured to compile for any of these from the command line (See documentation)
Given the above, there's a fair chance your code will compile with minimal changes to compiler-flags using the existing makefile. You might want to read the documentation for lipo - which allows you to produce multi-architecture binaries.

How to configure mono to use more than 4G memory?

I want to run an .NET executable that needs more than 4G RAM on OSX 10.9. I had Xamarin Studio installed but AFAIKT Xamarin doesn't come with a 64-bit mono build, so I decided to make a custom 64-bit mono with "with-large-heap=yes" configuration, and install it in a different location.
git clone https://github.com/mono/mono
cd mono
./configure --prefix=<my-local-dir> --enable-nls=no --with-large-heap=yes
make
make install
(I also built a 64-bit F# and installed in my-local-dir, following "Option 3" in this page.)
However, when I use the 64-bit mono to run the executable (an F# program built with the canonical "fsharpc" in Xamarin), it still crashes with System.OuOtfMemory exception. I tried this:
export PATH=$PATH:<my-local-dir>/bin
MONO_GC_PARAMS=max-heap-size=5g <my-local-dir>/bin/mono <my-executable>
And it gives a warning
Warning: In environment variable `MONO_GC_PARAMS': `max-heap-size` must be an integer.
(this error message is a bit misleading, I think it really means 5g is too large and not supported, because it doesn't complain if I put a "3g" there). And the program still crash with the same exception at the point when it exceeds the memory.
Did I miss any thing important? How do I configure mono to have more than 4G heap size?
You are still running the 32 bit version of mono (check your PATH env var). This also explains the parsing of 5g for max-heap-size (it will work correctly with 64 bit mono).
The default as with your configure command above is to install in /usr/local/bin, so just run your programs with /usr/local/bin/mono program.exe.

How to build os image including gcc g++ tool chain for ARM platform?

I am trying to build an OS image for TI OMAP4 Pandaboard. The downloaded BSP can be built but very limited without gcc g++ compiler. I think it much difficult to add the tool chain in QNX Momentics IDE, because there are so many files to be added. Can I manually modify the buildfile to do it? If possible, please give me an example. Thanks in advance.
No, it is not possible to run g++ on your TI OMAP4 Pandaboard (unless you build g++ from sources for the ARM platform using the existing QNX toolchain running on an X86 platform).
Why not possible: QNX releases their build tools only for X86-based hosts. The currently supported host OS-es include some variants of Windows, Linux and QNX but the precondition is that the host hardware is X86-based.
Likely you do not actually want to build your library on the target hardware; it should not matter where you actually do the build (except in very special cases where you build some source code based on user input, etc.)
What you need to do is build your library on your development host using the ARM toolchain (QCC if you want to use the high-level tools; ntoarmv7-g++ if you want to use the familiar g++ interface). Once you have your binary you can include it in the .ifs file. You just need to include a line in the .build file, similar to the following example:
/path/on/targetfs/yourbinary=/path/on/buildmachine/yourbinary
If your build environment is configured so that mkifs finds your binary then you can omit the "path/on/buildmachine" part.
If you are fine with having the binary on your target under /proc/boot then you can omit the "/path/on/targetfs/ part as well.
For ease of development it would usually be more convenient for you to store your binary on the SD card with a FAT filesystem. Then you can just copy your binary to the SD without having to rebuild the .ifs file.
Finally, once you get experienced you will want to export a part of your host-machine's filesystem via CIFS or NFS and mount it directly from your target. This will save all the trouble of having to copy files (and, possibly, reboot the target) in each build cycle. But this is far off from your original question.
I think you are trying to get the QNX C/C++ compiler to run on your target board. Correct?
If so, rather than installing the Runtime Kit, you install the QNX Software Development Platform and you should be good to go.
You can also use the System Builder to customize your QNX OS, but this is going to be harder than just using the QNX SDP.
One other note: QNX uses qcc for C and QCC for C++ instead of gcc. They both use gcc under the hood, but to compile on QNX, use qcc instead of gcc.

Resources