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

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

Related

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.

Problems linking msvc intrinsics using clang on windows

I'm swapping over a large codebase from using msvc to clang for a windows product. This product uses a large number of the msvc compiler intrinsics such as _InterlockedOr etc. If I build a little test program using clang on windows it builds, links and runs just fine, but if I build a library from our product that uses an intrinsics it comes up as a missing symbol.
I've tried compiling both the test code and our product using the --verbose option and can't spot anything different between the two. The only difference in the way they are called is that the large product is built using fastbuild which necessitates the use of -c to prevent the compiler calling the linker as well. Clang obviously adds in some libraries that are missing when I call the linker manually myself, so can anybody let me know what they might be? (I'm already linking in the crt library (libcmt, msvcrt) so it's not that.
I've started writing my own library of intrinsics in assembly which is fun, but shouldn't be necessary. Any one?
As per request, compiling the following code with clang works when using it directly, i.e. clang IntrinsicsTest.cppproduces an exe.
IntrinsicsTest.cpp
#include "stdio.h"
#include "intrin.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned long long r = __rdtsc();
printf("Intrinsic: %llu\n", r);
}
Yet fails to link when called via fastbuild:
FBuild.exe -showcmds -clean IntrinsicsTest_debug_x86
clang.exe "\IntrinsicsTest.cpp" -D_WINDOWS -c -m32 -mfpmath=sse -D_UNICODE -DUNICODE -fno-rtti -fexceptions -E ...\IntrinsicsTest.debug.Win32.lib
lib.exe /NOLOGO /OUT:"...\IntrinsicsTest.debug.Win32.lib" "...\IntrinsicsTest.obj" ...\IntrinsicsTest.debug.Win32.exe
link.exe /NOLOGO /INCREMENTAL:NO /OUT:"...\IntrinsicsTest.debug.Win32.exe" "...\IntrinsicsTest.obj" -defaultlib:libcmt.lib -INCREMENTAL -MANIFEST /MACHINE:X86 /SUBSYSTEM:CONSOLE /OPT:NOICF /OPT:NOREF
IntrinsicsTest.obj : error LNK2019: unresolved external symbol ___rdtsc referenced in function
_wmain ...\IntrinsicsTest.debug.Win32.exe
fatal error LNK1120: 1 unresolved externals
I have resolved the issue. There were several contributing factors all to do with how fastbuild, clang and msvc were interacting.
a/ With Clang on Windows there is no need to specify "system" includes.
In our project we had the include paths as:
-I"C:/Program Files/LLVM/lib/clang/3.8.0/include"
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/include/"
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/atlmfc/include"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/um"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/shared"
-I"C:/Program Files (x86)/Windows Kits/8.1/include/winrt"
The clang version of xmmintrin declares the intrinsics inline and thus if this header is used then the test program compiles fine. The Windows xmmintrin declares the intrinsics as extern functions, hence the program compiles, but doesn't link - where an msvc build gets these symbols from is irrelevant now.
However, even with the clang include path first, when <intrin.h> is included by anything, it pulls in the windows header.
b/ Fastbuild allows you to set up environment variables for the build env. Our scripts have INCLUDE and PATH defined with msvc paths. Removing these helped.
c/ As well as clang, I have several versions of msvc installed on my machine. Clang was picking up on MSVC14 whereas fastbuild was trying to get clang to use MSVC 12. By changing fastbuild to use MSVC14 I was finally able to get past the problem with the intrinsics.
Intrinsics aren't supposed to be function calls, they're supposed to inline to one or a couple instructions. Or in some cases, no instructions (e.g. a compiler memory barrier, like c++'s std::atomic_signal_fence).
MSVC and GNU C are separate flavours of C. clang implements GNU C, and AFAIK doesn't support MSVC intrinsics.
When there's a GNU C __builtin_something equivalent to an MSVC intrinsic, use it via a wrapper function.
mingw-w64 apparently does support _Interlocked???, via <winnt.h>. This mailing list post is a patch that switched over the implementation from inline asm to GNU C __sync_fetch_and_??? functions. IDK if that's shipping with current mingw, or if there's a mingw version of clang. But that's what you should be looking for. I'm sure you're not the first person to want to compile an MSVC codebase using a different compiler.

Forcing Clang to link with C++ runtime

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++)

Minimal executable size after linkage

I link with Qt statically, so can linker or some other tool avoid adding unused binary code (from Qt libraries) to the final executable? I don't think i use all the 10 MB of Qt library code.
If you compile the Qt library yourself at some point and you are using the g++ you should try to use the Link Time Optimisation (LTO) options.
You can do this by adding -flto to all your g++ calls. This lets the g++ add so called GIMPLE code to your object files which corresponds to your source (so it is not completly compiled). In the linking step you should add -fwhole-program or -fuse-linker-plugin. The gcc then reads the Gimple code, and optimises your program as a whole, therby it should be able to get rid of any unused code. However I cannot garantee this works for you.

Is g++ both a c++ compiler and a linker?

I was looking at the output from my build in Eclipse. I'm cross compiling for a ColdFire processor. The compilation line looks like this:
m68k-elf-g++ -O2 -falign-functions=4 -IC:\nburn\include -IC:\nburn\MOD52...
followed by more include file, obvious "compiler" flags and finally the one source file I changed. The next line invokes the same tool again:
m68k-elf-g++ src\main.o src\TouchPanelMediator.o src\Startup.o....
followed by more .o files some .ld files and some .a files. This appears to be linking all the various types of object files together.
In the Gnu family is g++ some uber application that can determine based on arguments whether it needs to compile or link? Does it have both capabilities built-in or is it just dispatching compiling to gcc and linking to ld and my log just doesn't show that?
g++ and gcc are drivers. Usually, they run the preprocessor (cpp), compiler proper (cc1plus for C++ and cc1 for C) and the linker (gold or GNU ld) and all other things necessary. The difference between gcc and g++ is that the latter includes one additional library to link against (libstdc++).
Depending on what type of file they are invoked on, they may omit some steps or do things differently. For .o files, it doesn't need to run the compiler proper or the preprocessor, for example.
If you pass -### to them, you can see it print the tools it invokes in each step of its execution.
Taken from this little GCC guide:
Based on the file extension that you gave your program, it selects the appropriate commands it needs to run to turn the source you gave it into the output file you specified.
With a nice little flowchart of what GCC exactly does, depending on the file extensions:
input extensions runs if output
It dispatches linking to ld.
Also see here:
How to get GCC linker command?