Forcing Clang to link with C++ runtime - c++

I have a project containing a mixture of C and C++ source. It currently builds with GCC on OS X. The project has bespoke build scripts which invoke the gcc command to compile both the C and C++ source, and separately invoke the linker.
I am now trying to get it building with Clang.
Invoking clang does compile the source files correctly; it distinguishes between .c and .cpp source files, and compiles for the appropriate language in each case. I have problems at link time, though. When the linker is invoked as clang, the C++ runtime libraries are not linked in, causing a build error due to missing symbols.
I can link successfully when I set clang++ as the build tool, but this then causes compile-time errors and warnings; it really doesn't like compiling C source with the C++ compiler.
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
...
/usr/include/stdio.h:250:49: error: redefinition of parameter 'restrict'
I have to specify a single tool for the build scripts to use as the compiler/linker, so I need to do a simple substitution of clang in place of gcc.
Is there any way I can persuade clang (not clang++) to link with the C++ runtime libraries?
Options such as -stdlib=libc++ don't work.

You should just be able to use the normal linker flag, same as you'd do for gcc: clang -lc++ or clang -lstdc++ depending on which implementation you want. (and you should want libc++)

Related

How to run linker after emitting LLVM object file

I wrote a simple toy language compiler frontend that generates LLVM IR using llvm-sys (Rust bindings for LLVM's C library). I then generated an object file by creating a LLVMTargetMachine based on the machine's target triple then calling LLVMTargetMachineEmitToFile, which successfully generates an executable. However, running the executable produces zsh: exec format error: ./a.out.
I figured out that I had to run ld -lSystem ./a.out after generating the executable to make it work. How should I automatically call the linker in code?
Currently using LLVM 9.0 on macOS Catalina.
Indeed, LLVMTargetMachineEmitToFile produces an object file that still needs to be linked - either into an executable or shared library.
You need a linker for this, which is not, strictly speaking, a part of LLVM. LLVM's integrated linker operates on LLVM IR, not native machine code.
However, just like there is a LLVM-related C compiler, Clang, there also is a LLVM-related native linker called LLD. AFAIK, it can be used as a library, so you can imbue your compiler with integrated linked.
It worth noting that native compilers follow "pipeline" architecture, where the compiler itself and linker (and sometimes assembler too) are completely decoupled one from other. In such architecture, the compiler executable (like clang or g++) is actually a driver program that invokes other programs (cc1, the real compiler and ld, the linker) to produce the final binary.

Bazel, protobuf 3.6.1.3, -Wall, and an unhappy gcc 9.1.1

Is there a way to pass compiler options to protocol buffer libraries in Bazel?
In my Bazel C++ project, I'm compiling everything with -Wall, and after upgrading to C++ I'm running into problems with GCC 9.1.1 and protobufs.
GCC is upset with some of the members in the generated protobuf code, because of the generated code calls memset with values that reach outside the bounds of the referenced subobjects. I'd like to add -Wno-array-bounds to remove the warning, but ONLY for the protobuf code. The Bazel cc_proto_library rule doesn't provide any way to pass options to the compiler -- is there another way to do this?

How to make static linking with C++ standard library?

i am has an object file(a.obj) and i am need to get executable(a.exe) file via linker call from command line.
I am received a.obj file from this program:
#include "stdio.h"
int main(){
puts("Hello world");
}
and i am used clang compiler for generating a.obj file with follow up arguments: "clang.exe -c a.cpp".
My problem is using the "puts" method, which is defined in the standard library(may be libvcruntime.lib) and I don't know which arguments to use for linked to the standard library.
My linker this is Microsoft link.exe and me also available the lld linker, from llvm project(it is more preferables).
My global target - this is to get executable file from llvm ir and call lld linker from code but theis other history :)
If you're building for Windows with Clang, and you want to use Visual C++'s standard libraries, I suggest you use clang-cl, which is a driver that converts a Visual C++ cl command line options into clang's native options.
You said you're writing:
clang -c a.cpp
The -c option asks the compiler to just produce and object file and stop (rather than sending the object file to the linker). It sounds like you want clang to call the linker, so you should omit the -c.
To use the static version of the standard library, specify /MT (or /MTd if you want the debug version of the standard library).
Putting it all together, this should work for you:
clang-cl /MT a.cpp
clang-cl will translate the /MT to the equivalent option(s) for clang and then run clang. When clang finishes compiling the object file, it'll then automatically call lld (the LLVM linker) with options compatible with the ones used for compiling, which should result in a working executable file.
For a while, when using clang to compile for Windows, you needed to use Microsoft's LINK instead of lld. But recent versions can use lld, and, in fact, will use lld by default.
Visual Studio
Specify /MT(d) instead of /MD(d) in project config. docs
clang
-static-libstdc++ -static-libgcc. docs

why use gcc and g++ compiler drivers for c and c++

I have ported a project to an arm cortex M7 chip, and am mucking around with makefiles for the first time, im using the gnu-gcc compiler collection.
Is it advisable to compile "c" code with the gcc driver and, compile the "c++" (app) code with the g++ driver, and then link. The c code is all low level (header files)register access addresses etc and contains no functions (yet) or attached source files.
Or can i compile all with the g++ compiler if the header files can be modified to compile with g++ if needed.
I have it set so gcc is compiling the c files, and g++ is compiling c++ and linking.
The only differences between gcc and g++ are that:
when the driver is used to invoke the linker, g++ causes libstdc++ to be linked as part of "stdlibs", while gcc will link only libc.
g++ will compile .c, .h and .i files as C++ unless the -x option is specified.
Both drivers will compile C or C++ depending on either the filename extension, or command-line switches. If you invoke the compiler-driver for compilation only and invoke the linker (ld) directly, using gcc or g++ -x, it makes no difference which you use.
Equally, if you invoke the gcc driver for C++ code and explicitly link stdlibc++ it also makes no difference - so long as your crt0.o is not C-only - a C++ runtime start-up must invoke global static constructors before main()) - this is likely to already be the case.
The definitive word from the documentation:
3.3 Compiling C++ Programs
C++ source files conventionally use one of the suffixes ‘.C’, ‘.cc’, ‘.cpp’, ‘.CPP’, ‘.c++’, ‘.cp’, or ‘.cxx’;
C++ header files often use ‘.hh’, ‘.hpp’, ‘.H’, or (for shared
template code) ‘.tcc’; and preprocessed C++ files use the suffix
‘.ii’. GCC recognizes files with these names and compiles them as C++
programs even if you call the compiler the same way as for compiling C
programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program
that calls GCC and automatically specifies linking against the C++
library. It treats ‘.c’, ‘.h’ and ‘.i’ files as C++ source files
instead of C source files unless -x is used. This program is also
useful when precompiling a C header file with a ‘.h’ extension for use
in C++ compilations. On many systems, g++ is also installed with the
name c++.
When you compile C++ programs, you may specify many of the same
command-line options that you use for compiling programs in any
language; or command-line options meaningful for C and related
languages; or options that are meaningful only for C++ programs. See
Options Controlling C Dialect, for explanations of options for
languages related to C. See Options Controlling C++ Dialect, for
explanations of options that are meaningful only for C++ programs.
If you want to use just one, I suggest you use gcc and separately invoke the linker or explicitly link -libstdc++. That way the compilation mode will be dependent on the filename extension. Using g++ -x to compile C code is just going to cause confusion.

How can I suppress g++ deprecation warnings in OCaml compilation when linking with C++ libraries?

When compiling an OCaml project which links against libraries requiring the C++ standard library (e.g. LLVM's OCaml bindings) using the -cc g++ argument to ocamlc with GCC >= 4.4 generates extremely verbose warning spew of the form:
warning: deprecated conversion from string constant to ‘char*’
How is it possible to remove these warnings?
The problem stems from ocamlc generating intermediate C code which triggers warnings when compiled in C++ mode by newer versions of GCC. But this generated code need not be compiled as C++. The only reason to pass -cc g++ for this common case of building against a wrapped C++ library is to ensure that the C++ standard library dependencies are built. The simpler solution, which avoids using the C++ front-end for compiling the ocamlc intermediate code, is simply:
-cclib -lstdc++
which forces linking the generated C code with libstdc++, while still compiling it in plain C mode.
I think you can just do
#pragma GCC diagnostic ignored "-Wwrite-strings"
In the C++ to suppress this.