How to use and configure clang-tidy on windows? - c++

I'm trying to use clang-tidy code analysis so I can check for CppCoreGuidelines. I downloaded LLVM 7.0.0 pre-built binary for Win 7 64 bits. I'm able to successfully compile with clang, I did a basic example compiling this code, I named the source test.cpp:
// test.cpp
#include <iostream>
int main(int argc, char const *argv[])
{
std::cout << "Hello World!" << std::endl;
return 0;
}
Then I ran this in the terminal:
clang test.cpp
I got this output when compiling:
test-c4b051.o : warning LNK4217: locally defined symbol __std_terminate imported in function "int `public: static unsigned __int64 __cdecl std::char_traits<char>::length(char const * const)'::`1'::dtor$2" (?dtor$2#?0??length#?$char_traits#D#std##SA_KQEBD#Z#4HA)
test-c4b051.o : warning LNK4217: locally defined symbol _CxxThrowException imported in function "public: void __cdecl std::ios_base::clear(int,bool)" (?clear#ios_base#std##QEAAXH_N#Z)
But it worked fine printing "Hello World" and everything goes fine until here, but when I want to run clang-tidy I get the following output when I run this, I took the reference from here Extra Clang Tools 8 documentation:
clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "test.cpp"
No compilation database found in C:\Users\uidr8361\Desktop\C++ or any parent directory
fixed-compilation-database: Error while opening fixed database: no such file or directory
json-compilation-database: Error while opening JSON database: no such file or directory
Running without flags.
I read this thread but this seems to apply for clang compilation and I don't know if this also applies for clang extra tools, clang-tidy in particular:
How to compile Clang on Windows

Just put -- (minus minus) on the command line at the end
clang-tidy -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* test.cpp --
You would normally put your cl,gcc,clang arguments afterwards
clang-tidy -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* test.cpp -- -DDEBUG -I./include

Related

LLVM Clang doesn't find Windows.h

Platform: Windows 10 x64,
IDE: text editor
Hello everyone. I am trying to compile a simple code using the Clang compiler, the problem is that when I include the 'Windows.h' header file, Clang cannot compile the code.
To compile, I use this command: clang++ main.cpp -o test.exe
Here is the code:
#include <iostream>
#include <Windows.h>
using namespace std;
int main() {
cout << GetSystemMetrics(SM_CXSCREEN) << endl;
return 0;
}
However, when I use the mingw compiler, the code compiles correctly. Visual Studio versions '17 and '19 are installed on the systems. I get errors like this when compiling:
main-a354a4.o : error LNK2019: unresolved external symbol __imp_GetSystemMetrics referenced in
function main
test.exe : fatal error LNK1120: 1 unresolved externals
clang++: error: linker command failed with exit code 1120 (use -v to see invocation)
So how to compile this code using Clang?

Cannot specify additional link file for clang

I've successfully compiled my main.cpp with clang, specifying additional include path via the command line options as follows: clang++ -I ./Dependencies/GLFW/include/ -S .\main.cpp.
However, when I try to link it by specifying the additional link library by the following command: clang++ -L ./Dependencies/GLFW/lib/glfw3.lib .\main.s it gives me a linker error main-8b7c4e.o : error LNK2019: unresolved external symbol glfwInit referenced in function main.
Any suggestions on what might be wrong? I'm sure that the relative path specified is correct, since the compile command gave me no issues.
main.cpp
#include <iostream>
#include <GLFW/glfw3.h>
int main() {
glfwInit();
std::cout << "Hello world" << std::endl;
return 0;
}
-L is for specifying folders to search for libraries in. The compiler ignores directories that don't exist.
Your command line should be:
clang++ ./Dependencies/GLFW/lib/glfw3.lib .\main.s
Please find below link for more detail about glfw header inclusion.
https://www.glfw.org/docs/latest/build_guide.html

Using Clang on Windows 10 with LLD

Compiling a simple hello world program generates warnings when compiling with clang. I understand that using clang-cl will get rid of the warnings.
On Clang's website, it states: "clang-cl is an alternative command-line interface to Clang, designed for compatibility with the Visual C++ compiler, cl.exe."
I do not want to use Microsoft Visual C++'s tool chain. I want to use Clang as the compiler and LLD as the linker.
What is meant by "compatibility with the Visual C++ compiler"?
How do I know which linker is used by default? Clang's documentation says that LLD is used by default, but, if so, then why is there a warning? And why is clang-cl the recommended solution for this warning?
clang
I compiled:
clang main.cpp
and got warnings:
main-a354e7.o : warning LNK4217: locally defined symbol _CxxThrowException imported in function "class std::num_put<char,class std::ostreambuf_iterator<char,struct std::char_traits<char> > > const & __cdecl std::use_facet<class std::num_put<char,class std::ostreambuf_iterator<char,struct std::char_traits<char> > > >(class std::locale const &)" (??$use_facet#V?$num_put#DV?$ostreambuf_iterator#DU?$char_traits#D#std###std###std###std##YAAEBV?$num_put#DV?$ostreambuf_iterator#DU?$char_traits#D#std###std###0#AEBVlocale#0##Z)
main-a354e7.o : warning LNK4217: locally defined symbol __std_terminate imported in function "int `public: __cdecl std::locale::~locale(void)'::`1'::dtor$6" (?dtor$6#?0???1locale#std##QEAA#XZ#4HA)
It still generated an a.exe file. However, this same command generates no file when run in a Debian terminal (WSL Windows Subsystem for Linux) and has errors.
clang && lld [lld-link]
I tried compiling to object code and then passing this to LLD. It resulted in an error:
clang -c main.cpp -o main.o
lld-link main.o
lld-link: error: could not open libcpmt.lib: no such file or directory
What is this library? Where did it come from? Why is it not found?
main.cpp
#include <iostream>
using namespace std;
int add1(int x);
int main()
{
int a;
a = 1;
cout << a << endl; //prints a and goes to new line
a = add1(a);
return 0; //must return 0 to tell the OS the
//program executed successfully
}
int add1( int x )
{
x = x + 1;
return x;
}
clang is the C compiler, clang++ is the c++ one. So to compile as c++, you need clang -c main.cpp -o main.o
clang-cl on the other end is an alternative driver. If you don't want to use the toolchain, don't bother about it. However, if you are like me and try to compile a project that currently compiles with MSVC and want to also compile it with clang, it's really useful.
The main difference, if you don't play with triples is the platform ABI it links to.
Clang++ links against the mingw standard library while clang-cl uses the Microsoft runtime. As a consequence, the name mangling ... is also MSVC compatible. (Of, and it has a permissive mode in which it allows some invalid code for compatibility)

new c++ error with file

I am 100% new at c++ so bear with me :)
I am getting an error with this file and not sure why. any help is appreciated.
#include <iostream>
using namespace std;
int main()
{
cout << "hi" << endl;
return 0;
}
------------ Build: Debug in 1600 (compiler: GNU GCC Compiler)-------------
g++ -o bin/Debug/1600 obj/Debug/main.o obj/Debug/src/test.o obj/Debug/test03.o
duplicate symbol _main in:
obj/Debug/main.o
obj/Debug/test03.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
From the source files symbols are created. main in the .cpp file becomes _main as a symbol. During linking there can be only one main function, hence only one _main symbol is expected and allowed.
You have three object files that were created:
obj/Debug/main.o which contains main
obj/Debug/src/test.o
obj/Debug/test03.o which also contains main
Probably because you have a .cpp file for each of them and the command line or IDE you are using asked for them all to be compiled.
duplicate symbol _main
The text above is telling you that the linker (trying to make sense of all the compiled object (.o) files) found more than one main.
So the solution is to look at your IDE settings and remove the other files (or at least remove main from the other files) because you are only interested in compiling the one source file.
Its hard to tell what you're running from the question.
Here is how to build a simple C++ program using gcc
In
my_program.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "hi" << endl;
return 0;
}
To compile to object files type
g++ -c my_program.cpp
To link (you'd normally have more files here)
g++ -o my_program my_program.o
So, this isn't very fun so most people use a build system like make, cmake, msbuild or whatever the CLion IDE uses.

Missing CoTaskMemFree when building LLVM example on Windows

I'm attempting to essentially follow the llvm Kaleidoscope example.
I'm on Windows. I built llvm from source per the directions on the site. It took quite a long time but it finally built successfully (no errors at least).
Then with my own code I am running this command:
$ clang-cl main.obj llvm/lib/LLVMCore.lib llvm/lib/LLVMSupport.lib /MDd -o build\test.exe
My main.cpp code has this in it:
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
std::unique_ptr<Module> module = llvm::make_unique<Module>("my cool jit", getGlobalContext());
And I'm not getting any parser errors but I am getting an error from the linker that for the life of me I cannot figure out:
LLVMSupport.lib(Path.obj) : error LNK2019: unresolved external symbol
__imp_CoTaskMemFree referenced in function "bool __cdecl
llvm::sys::path::getKnownFolderPath(struct _GUID,class
llvm::SmallVectorImpl<char> &)" (?
getKnownFolderPath#path#sys#llvm##YA_NU_GUID##AEAV?$SmallVectorImpl#D#3##Z)
build\test.exe : fatal error LNK1120: 1 unresolved externals
Which library do I have to link to for this function to be defined? I can see the implementation in the code I built from. Do I need to build llvm in a particular way for this to be exported?
EDIT:
It turns out that I needed to read the clang-cl documentation a little better where it says:
To enable clang-cl to find system headers, libraries, and the linker when run from the command-line, it should be executed inside a Visual Studio Native Tools Command Prompt or a regular Command Prompt where the environment has been set up using e.g. vcvars32.bat.
It turns out that this solves my problem. I was a little confused because clang-cl seems to resolve the sdk include and tool paths automatically, but not the lib paths. I also don't want to use CMD to drive clang so I was using bash where I can't run vcvar32.bat easily. I solved my problem by essentially duplicating what vcvar32.bat is doing to the $PATH, $INCLUDE, $LIB and $LIBPATH environment variables and adding Ole32.Lib as a parameter to clang-cl. It then works like a charm.
You're missing the CoTaskMemFree symbol. A quick look on the Internet suggests you'll need the Ole32 system library on your link line.
I don't have access to a Windows machine to test on, but on my computer, I can run llvm-config --system-libs and it pulls in the all the necessary things. After adding using namespace llvm; and adding a stub main function, I can easily build this example with (on OSX):
c++ `llvm-config --cxxflags` main.cpp `llvm-config --ldflags --system-libs --libs core support`
I often recommend just specifying --libs rather than guessing what you'll need, but your choice.