Use clang-tidy on CUDA source files - c++

Several static analysis tools designed for C/C++ exist, but they are not particularly useful for testing CUDA sources.
Since clang version 6 is able to compile CUDA, I wanted to check what are my options with using clang-tidy, which does not seem to have option for switching architectures.
Is there a way to make it work? For example compile time switch for turning on CUDA parser, extension in form of custom check, or is it maybe planned feature?

One of the problem with the clang-based tools is that they are not parsing the files in exactly the same way as clang does.
The first problem is that unlike C/C++ compilation, CUDA compilation compiles the source multiple times. By default clang creates multiple compilation jobs when you give it a CUDA file and that trips many tools that expect only one compilation. In order to work that around you need to pass --cuda-host-only option to clang-tidy.
You may also need to pass --cuda-path=/path/to/your/CUDA/install/root so clang can find CUDA headers.
Another problem you may run into would be related to include paths. Clang-derived tools do not have the same default include paths that clang itself uses and that occasionally causes weird problems. At the very least clang-tidy needs to find __clang_cuda_runtime_wrapper.h which is installed along with clang. If you run clang-tidy your-file.c -- -v it will print clang's arguments and include search paths it uses. Compare that to what clang -x c /dev/null -fsyntax-only -vprints. You may need to give clang-tidy extra include paths to match those used by clang itself. Note that you should not explicitly add the path to the CUDA includes here. It will be added in the right place automatically by --cuda-path=....
Once you have it all in place, clang-tidy should work on CUDA files.
Something like this:
clang-tidy your-file.cu -- --cuda-host-only --cuda-path=... -isystem /clang/includes -isystem /extra/system/includes

Related

How does CMake's dependency extraction work?

I noticed that the recent version of CMake release notes has a line about a new feature:
Makefile Generators, for some toolchains, now use the compiler to extract implicit dependencies while compiling source files.
This sounds like a cool feature, but I couldn't figure out how to actually use it. A quick search didn't return any obvious documentation. Does anyone here know more about how to use it?
This is referring to implicit header dependencies. GCC, Clang, and several other compilers have a flag for writing files listing these dependencies during the first compile. CMake then points the generated build systems to these files so they can load the extra dependencies during incremental builds.
This is all automatic with CMake and requires no special action on your part. It can, however be disabled by setting a special variable to FALSE, CMAKE_DEPENDS_USE_COMPILER.
Here is the merge request that introduced this feature: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/5528
For further reading, see the documentation for the -MMD flag on GCC: https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html

How can I configure cmake to compile a file twice with two different compilers?

I'm adding a SYCL/OpenCL kernel to a parallel C++ program which is built with cmake. Using SYCL means I need to get cmake to compile my C++ source file twice: once with the SYCL compiler, and once with the project's default compiler, which is GCC. Both compilations produce outputs which need to be included when linking.
I'm completely new to cmake. I've added the GCC compile and link steps to the project's CMakeLists.txt, but what's the best way to add the SYCL compile step? I'm currently trying the "add_custom_command" option with "PRE_BUILD", but the command which is run doesn't seem to know about the paths which are provided to the normal compile and link steps: the current working directory, include directories, source directories, etc. I'm having to specify all of these manually, and I'm having to figure some of them out first.
It feels like I'm doing this the hard way. Is there a recommended (or at least better) way to get cmake to compile a file twice with two different compilers?
Also, there used to be a SYCL tag, but it's disappeared. Can someone recreate it, please?
Be aware that PRE_BUILD only works as PRE_BUILD in Visual Studio 7, for other targets is just PRE_LINK.
If you need to use two compilers on the same source file, just add a dependency from the GCC compile and link to the custom target you are using, so the GCC is executed after the SYCL compiler.
I can think of a couple other ways to do it.
Generate two build configurations
Write a script to call both compilers
The first method is probably the easiest. You might need to maintain two seperate CMakeLists.txt files, or possibly just parameterize the compiler and options and pass them arguments to Cmake when you generate (CC=gcc, CXX=g++, CFLAGS/CXXFLAGS, etc...). You might be able to do the same with the underlying build system (e.g. make) and just run it twice.
The second method is a bit more complicated. Write a simple script that accepts both sets of compiler options and compile each file using the compilers in sequence. Then the script could be then configured as CC/CXX.
So, the command options would look something like this...
--cc1 sycl --cc2 gcc --cc1opts ... --cc2opts ...
I'm not familiar with SYCL though, so I don't know how it's normally used.

Why does cmake ignore ADD(SYSTEM) header files when CXX is defined?

I've bumped into the following annoying issue. I installed g++ via macports on OSX, everything works fine. However, cmake still detects clang++ as the cpp compiler. Therefore, I end up putting
export CXX=/opt/local/bin/g++
in my profile. Now, cmake correctly detects g++ as the compiler. The problem is that all the system headers that I include with
INCLUDE_DIRECTORIES(SYSTEM "/path/to/system/header)
are included as regular headers. In other words, I am getting a whole bunch of warnings (-Wall) which I'd very much like to suppress, since I don't care about warnings in system headers like Boost or Eigen.
Any idea how to address this issue? It's driving me crazy, and I am completely puzzled why adding CXX in the profile results in this behaviour. If I remove the export CXX from my profile and manually set CMAKE_CXX_COMPILER to g++ in the CMakeLists.txt then everything is fine, no more warnings for system files.
I finally figured out a solution, from a somehow randomly found post: http://www.cmake.org/pipermail/cmake/2011-June/044769.html. For some reason, the SYSTEM directive was ignored. Setting
SET(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")
solves it, no more warnings generated for system files.
This is a very peculiar issue that appears only on OS X. On all other systems I tested, INCLUDE_DIRECTORIES(SYSTEM "/path/to/system/header") adds the headers as system headers, without any need to use the SET above.
Using export CXX=/opt/local/bin/g++ with several other system variables not adapted seems a little bit unorthodox, so the weird behavior is maybe not surprising.
I suggest you configure from scratch (=from a clean build directory) your project from cmake-gui, the menu allows you to specify the path to the compiler(s) you want to use. You can also use a custom tool-chain file. I suggest you use cmake-gui, it offers a couple of choice that might solve your problem.
Once you get it right, you can document the equivalent command line instruction for other people building your project.

Is Visual C++ as powerful as gcc?

My definition of powerful is ability to customize.
I'm familiar with gcc I wanted to try MSVC. So, I was searching for gcc equivalent options in msvc. I'm unable to find many of them.
controlling kind of output
Stop after the preprocessing stage; do not run the compiler proper.
gcc: -E
msvc: ???
Stop after the stage of compilation proper; do not assemble.
gcc: -S
msvc: ???
Compile or assemble the source files, but do not link.
gcc: -c
msvc:/c
Useful for debugging
Print (on standard error output) the commands executed to run the stages of compilation.
gcc: -v
msvc: ???
Store the usual “temporary” intermediate files permanently;
gcc: -save-temps
msvc: ???
Is there some kind of gcc <--> msvc compiler option mapping guide?
gcc Option Summary lists more options in each section than Compiler Options Listed by Category. There are hell lot of important and interesting things missing in msvc. Am I missing something or msvc is really less powerful than gcc.
MSVC is an IDE, gcc is just a compiler. CL (the MSVC compiler) can do most of the steps that you are describing from gcc's point of view. CL /? gives help.
E.g.
Pre-process to stdout:
CL /E
Compile without linking:
CL /c
Generate assembly (unlike gcc, though, this doesn't prevent compiling):
CL /Fa
CL is really just a compiler, if you want to see what commands the IDE generates for compiling and linking the easiest thing to look at the the command line section of the property pages for an item in the IDE. CL doesn't call a separate preprocessor or assembler, though, so there are no separate commands to see.
For -save-temps, the IDE performs separate compiling and linking so object files are preserved anyway. To preserve pre-processor output and assembler output you can enable the /P and /Fa through the IDE.
gcc and CL are different but I wouldn't say that the MSVC lacks "a hell lot" of things, certainly not the outputs that you are looking for.
For the equivalent of -E, cl.exe has /P (it doesn't "stop after preprocessing stage" but it outputs the preprocessor output to a file, which is largely the same thing).
For -S, it's a little murkier, since the "compilation" and "assembling" steps happen in multiple places depending on what other options you have specified (for example, if you have whole program optimization turned on, then machine code is not generated until the link stage).
For -v, Visual C++ is not the same as GCC. It executes all stages of compilation directly in cl.exe (and link.exe) so there are no "commands executed" to display. Similarly for -save-temps: because everything happens inside cl.exe and link.exe directly, the only "temporary" files are the .obj files that cl.exe produces and they're always saved anyway.
At the end of the day, though, GCC is an open source project. That means anybody with an itch to scratch can add whatever command-line options they like with relatively little resistance. For Visual C++, a commercial closed-source product, every option needs to have a business case, design meetings, test plans and so on. Every new feature starts with minus 100 points.
Both compilers have a plethora of options for modifying... everything. I suspect that any option not present in either is an option for something not worth doing in the first place. Most "normal" users don't find a use for most of those options anyway.
If you're looking purely at the number of available options as a measure of "power" or "flexibility" then you'll probably find gcc to be the winner, simply because gcc handles many platforms other than Windows and has specific options for many of those platforms that you obviously won't find in MSVC. gcc (well, the gcc toolchain) also compiles a whole lot of languages beyond C and C++; I recently used it for Objective-C, for example.
EDIT: I'm with Dean in questioning the validity of your question. Yes, MSVC (cl) has options for the equivalent of many of gcc's options, but no, the number of options doesn't really mean much.
In short: Unless you're doing something very special, you'll find MSVC easily "powerful enough" on the Windows platform that you will likely not be missing any gcc options.

How to tell what optimizations bjam is using to build boost

I'm building the boost libraries with bjam for both the intel compiler and vs2008, and I can't tell what optimizations are being passed to the compiler from bjam. For one of the compiler's gcc, I can see some optimizations in one of the bjam files, but I can't find the optimization flags for the compilers I care about. So, my questions are -
Does anyone know where the default optimization flags are located?
If they're declared within bjam, does anyone know how I can override them?
If you are interested in looking at the entire set of options that are passed to invoke the compiler when building you can run bjam with the -n -a options and the rest of the building options to give you the complete set of commands invoked, and any response files generated (see Boost Jam Options). Also you can look at the Boost Build sources directly and see what the specified features are translated into (see Boost Build Tools Files). For example:
For GCC see gcc.jam
For MSVC see msvc.jam
You can likely figure out the same for other compilers by just looking through the sources as they are fairly self explanatory. And you can just search for "<optimization>" and "<inlining>" in the *.jam sources.
You can override them in the command line by specifying the feature=value option in the command line when building. The options match the <feature>value specifications you see in the toolset files. For example, to override the optimizations feature you would specify in the command line some like "optimization=speed". If you want more fine grained control you would have to delve into Boost Build specifications and likely have to create a variant of your own to define specific options and features to build with.