Problems linking msvc intrinsics using clang on windows - c++

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.

Related

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

Compile Microsoft Visual Studio Windows libraries using GCC or Clang

I have 2 sets of C++ files, one set which I only have the .o files from GCC but no source code, while the other set in Microsoft Visual Studio 2015 which I have the full source code - this set includes various VS libraries such as the Windows SDK. For deployment I would prefer to have one single EXE only (no DLLs), so I would like to link the .o files to the .obj files generated by Microsoft Visual Studio. The .o format seems incompatible with the .obj format, neither one can be converted to the other, and no linker seems to be capable of linking these two types of files together to produce 1 single EXE. Hence, my only option is to compile the set of files under Microsoft VS into .o format. I tried using GCC but even after quite some modifications to the Microsoft library source codes GCC still won't compile - there are a lot of C++ templates that the GCC compiler rejects. This would be too difficult for me to figure out how to modify.
(Edit: statement above seems not completely correct, I missed this earlier, Stack Overflow suggested to me, .o files and .obj files can be converted between them although I have yet to test out the tools and would need more research to determine how reliable this approach is: Converting C++ object file from linux .o to Windows .obj. I believe the .o files from GCC in Windows are the same as those it generates in Linux. Also, I was not clearer earlier, that although the files are C++, the intercommunication between the 2 sets, the VS set and the non-VS set, only needs to be done in C code i.e. .obj will communicate with .obj files in C++ but will communicate with .o files only using C calls. Still, given this approach seems not widely used, I would still prefer compiling VS source files with GCC since as long as I understand the modifications needed for the source files, I can be confident that the end result is reliable.)
I looked into Clang to compile to .o, but the Clang websites seems to indicate that it cannot compile all of the Microsoft Windows libraries either:
http://llvm.org/docs/GettingStartedVS.html
I looked into the Intel C++ compiler too, which can compile Microsoft libraries, but I couldn't figure out how to make it output .o instead of .obj under Windows.
Are there any guides on how to modify the Microsoft libraries (included in VS2015) to be compiled under GCC/Clang? The closest I have found online is this: http://www.transmissionzero.co.uk/computing/win32-apps-with-mingw/, which I tested to work on MinGW, but it uses MinGW's own set of (modified?) Windows libraries which excludes all of the ATL files.
(Edit: after exploring a bit more, not 100% sure but quite convinced GCC probably cannot compile MS VS libraries, might just have to wait for a later version of Clang instead. Syntax issues can be fixed, like changing i64 suffixes to LL, getting rid of throw(...) in function declarations, etc., but things like __ptr32, __ptr64, __vectorcall, missing in GCC, not really sure if can be just dummy-ed out, and things like __getcallerseflags seems quite likely no simple workaround, if at all possible. Pasting my GCC command line switches here in case anyone wants to try: -std="gnu++14" -nostdinc -Wmissing-include-dirs -fpermissive -fms-extensions -D "__ptr64 =" -D "__ptr32 =" -D "__vectorcall = __fastcall" -D "__unaligned = " -D "__forceinline = inline" -D "__nullptr = nullptr" -D "__pragstr(X) = _Pragma( #X )" -D "__pragma(X) = __pragstr(X)" -D _M_AMD64 -D _M_X64 -D _WIN64 -D "_MSC_VER = 1400" -D "__int64 = long long" -D _WINSOCK_DEPRECATED_NO_WARNINGS .... -I include the MS VS folders)
I am afraid you are out of luck. You see every compiler mangles method names differently in c++. In the object code a method in a class has to be encoded with parameters, return type and membership. The best approach I think would be to build a DLL via GCC then use that in VS. Clang on Windows is still a headache.

Use of MSVC-compiled Boost binaries in a MinGW-compiled project

I've downloaded Boost Binaries from here. My project depends on boost_system and boost_filesystem, and builds correctly if I add the proper dependencies to Linker Options when using Visual Studio for compilation, but I'm now trying to compile under Code::Blocks (MinGW compiler) and running into the following:
"directve `/FAILIFMISMATCH:"_MSC_VER=1800" /FAILIFMISMATCH:"_ITERATOR_DEBUG_LEVEL=0" /FAILIFMISMATCH:"RuntimeLibrary=MD_DynamicRelease" /DEFAULTLIB:"msvcprt" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" "
Though that's a warning, it keeps me from finding the dependencies, because my project fails to build with undefined reference to 'boost::system::generic_category()' and plenty of other related undefined references.
Question: Should I compile Boost from source using MinGW, in order to solve my problem?
Of course, I'm using the proper libraries for my build configuration (Release, dynamic runtime library).
I'm making an answser based on the comments posted below my question, just to make things proper.
So, building boost from the source code using the same compiler (I used TDM-GCC with gcc 4.8.1) did solve the linking issues.
As noted by Rup, one "can't mix C++ compiled with GCC and Visual Studio: they have different C++ ABI implementations, and generate different 'manglings' of identifier names so that linker symbols won't match up."
Additional reference: Interoperability of Libraries Created by Different Compiler Brands

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

Which MinGW file to use as a C++ compiler

I have just installed MinGW and in the bin folder I can see 7 .exe files that compile my program:
c++.exe
g++.exe
mingw32-c++.exe
mingw32-g++.exe
gcc.exe
mingw32-gcc.exe
mingw32-gcc-4.4.1.exe
My small program (testprog.cpp) compiles correctly with each of them; the a.exe file is generated in the bin folder and it runs correctly.
What's the difference between them and which one should I use?
Also, what can I do to change the name of the output file from a.exe to testprog.exe automatically upon each successful compile?
These follow gcc naming conventions.
c++.exe is a traditional name for the system c++ compiler
g++.exe and gcc.exe are the names for the gcc compilers that compile for the "current system"
mingw32-* versions are the names for the compilers that cross-compile to the "mingw" target. In this case this is the same as the system target.
An then mingw32-gcc-4.1.exe is "gcc for mingw target version 4.1"
You should typically compile C code with a "gcc" variant, and c++ code with a "g++" variant.
Use -o filename in order to specify the output filename, the default is a.exe
It's quite possible that they are all the same; either exact copies or symbolic links to one another. Try using the --version flag on each to see what you've got. On my MingGW installation here, each of those binaries differs (checked with diff), but they all output the same version information (with the exception of the first bit, which is the filename):
gcc.exe (GCC) 3.4.5 (mingw-vista special r3)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Use the -o flag to change the output file name:
gcc -o testprog.exe testprog.cpp
In unix they'd mostly by symbolic links. The only major difference is between the 'cc' vs. '++' ones. You should notice a difference between these two if you use any part of the standard C++ library. The '++' versions link to that lib automatically. The 'cc' ones are C compilers and so don't...though you can use them as C++ compilers by just adding -lstdc++ or whatever.
While I was searching around the web for instructions in making some DLLs, I ran into a C++ compilation process that, from what I saw, used g++ to compile c++ the same way as using gcc.
I used "g++.exe"
Then in my IDE, VSCode, I also had to change the "IntelliSense mode" to "windows-gcc-x64" to get rid of the warning