This question already has answers here:
How does CMake specify "Platform Toolset" for a Visual Studio 2015 project?
(4 answers)
Closed 4 years ago.
We're using CMake for our C++ project. On Windows we generate a Visual Studio project from our CMakeLists.txt. This works nicely, however we need to set an Intel Compiler specific option called BasePlatformToolset.
The option can be set in Visual Studio's GUI, after which an entry is added to the .vcxproj file. However every time we generate the project again from CMakeLists.txt the option is of course reset to the default value.
Is there a way to specify this option from the CMakeLists.txt file?
To clarify: this is not the same as setting the platform toolset. Since we're using the Intel compiler and not the default compiler, the platform toolset is specified as "Intel C++ Compiler 17.0". "Base Platform Toolset" is then an Intel compiler specific setting.
You should be able to use a generator expression that drops in for your compiler id:
target_compile_options(yourTarget
PRIVATE
$<$<CXX_COMPILER_ID:Intel>:/p:BasePlatformToolset=v120>)
Related
Here is the final desired result in Visual Studio 2019 for any C/C++ project:
The key part that I am looking for are the top 2 lines in this MSVC project properties dialog:
"Output Directory": $(Configuration)-$(PlatformArchitecture)\
"Intermediate Directory": $(Configuration)-$(PlatformArchitecture)\$(ProjectName)\
As you can see, both use Visual Studio $(xyz) macros to define the target paths.
The question(s) that I've been struggling with:
How can I make CMake spit out these strings instead of already expanded paths into the generated vcxproj files?
If I want this to happen to multiple (or all) generated MSVC C/C++ project files (libraries, executables, etc.), where do I set this up then? Do I need to patch template files or can this be done via commandline or configuration file settings, which then override the CMakeLists.txt internally defined values?
Anything special I need to mind / watch out for, if I want this setting for all vcxproj build targets as shown in the screenshot?
(in my case that's generally Debug+Release for both x86 and x64, so 2 Configurations and 2 Platforms in Visual Studio speak)
The other questions on SO (at least the ones I dug up) do not address this at all AFAICT as they replace one 'hardcoded' path with another using CMake (just using different CMake variables, but all expand to absolute paths before the vcxproj is produced).
At time of writing (CMake 3.20 and below), it is not possible to set the intermediate directory in Visual Studio. This was requested a long time ago, but no progress has been made. See: https://gitlab.kitware.com/cmake/cmake/-/issues/14999
Note that a single CMake build can only target one architecture, so the resulting Visual Studio solution will only ever let you pick the configuration, not the platform. Writing $(PlatformArchitecture) would work (returning 64 or 32 appropriately), but it would be pointlessly non-portable. Also, CMake gives you portable access to $(Configuration) in multi-config generators via the CMAKE_CFG_INTDIR variable.
So the best thing to do is to set CMAKE_*_OUTPUT_DIRECTORY in your top-level CMakeLists.txt.
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (is_multi_config)
# Compute the bitness of the target, same as VS's $(PlatformArchitecture)
math(EXPR PlatformArchitecture "8 * ${CMAKE_SIZEOF_VOID_P}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}-${PlatformArchitecture}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}-${PlatformArchitecture}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}-${PlatformArchitecture}")
endif ()
This checks if the generator is multi-config (like Visual Studio, Xcode, or Ninja Multi-Config) and, if so, adjusts the output paths. This will give you the option later of switching away from Visual Studio to Ninja Multi-Config if you want faster builds.
Finally, you might want to use if (WIN32 AND is_multi_config) instead, if you only want to adjust the output paths on Windows (and not macOS or Linux).
After installing Intel Performance Library (IPP) on Windows 10 a new option appears in Visual Studio -> Properties called Intel Performance Libraries. This makes it very easy to add IPP to a project.
Is there a way to adjust settings here with Cmake?
To enable IPP in VS project you can use the built-in property VS_GLOBAL_UseIntelIPP of a target.
You can define the following macro and use it for all the targets:
macro(setup_intel_ipp_windows TARGET_NAME)
if(MSVC)
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_UseIntelIPP "Sequential") # Parallel_Static
endif(MSVC)
endmacro(setup_intel_ipp_windows)
Visual Studio 2017 RC includes much tighter CMake integration, allowing one to skip the intermediate step of generating project/solution files and use CMake effectively as the project file itself. There is sufficient documentation from Microsoft for using these features with regular C++ files, and there is sufficient documentation on this website (example) for making CUDA and Cmake play nicely, when it comes to linking CUDA code to C++ code.
What I can't find information on is how to make CMake, Visual Studio 2017 RC, and CUDA 8.0 all play nicely. This is a difficult problem, because 2017RC has no integration for the CUDA SDK anyways, and I was hoping to use 2017RC so that my C++ interface to the CUDA code could use C++14 and/or C++17. I'm working on the beginning of a large project that will primarily involve writing a static CUDA library that is accessed through C++: so, I'd like to get the CMake to take care of compiling my CUDA sources into a static library, and for it to help with feeding the linking information to Visual Studio. So far, I haven't had any success with using FindCUDA's various features to accomplish this, but I'm assuming that's due to a misunderstanding on my part. I've read through the documentation on separable compilation from Nvidia, but that wasn't helpful for figuring out CMake.
Further, whenever I try to use CMake in VS2017RC, I still end up with the various vcxproj files that CMake likes to spit out. Is this due to an error on my part? How do I edit the build command arguments, or CMakeLists.txt, to get the functionality demonstrated here to work?
The very short (and only at the time of writing) answer is that you can't. CUDA 8 doesn't support VS2017. Only VS2015 is presently supported.
You can always find the compiler/IDE versions which the release version of CUDA supports here
Edit to add that the CUDA 9 release will add official support for VS2017.
All you need to do is set the CUDA_HOST_COMPILER variable to a supported compiler for example the visual studio 2015 compiler.
In my case this is:
C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe
As both runtime libraries are binary compatible you can use the 2015 compiler within CUDA and compile all the rest of the application with the 2017 compiler.
Direct Question: How do I create a simple hello world CUDA project within visual studio 2010?
Background: I've written CUDA kernels. I'm intimately familiar with the .vcproj files from Visual Studio 2005 -- tweaked several by hand. In VS 2005, if I want to build a CUDA kernel, I add a custom build rule and then explicitly define the nvcc call to build the files.
I have migrated to Win 7, and VS 2010 because I really want to try out nSight. I have nSight 1.5 installed. But this is where I'm totally lost. If I proceed as before, nvcc reports that it only supports msvc 8.0 & 9.0. But the website clearly states that it supports VS 2010.
I read somewhere else that I need to have VS 2008 (msvc 9.0) also installed -- my word. Doing so now.
But I'm guessing that at least part of my problems stem from the homegrown custom build tool specifications. Several websites talk about adding a *.rules file to the build, but I've gathered that this is only applicable to VS 2008. Under "Build Customizations" I see CUDA 3.1 and 3.2, but when I add kernels to the project they aren't built. Another website proclaims that the key is three files: Cuda.props Cuda.xml Cuda.targets, but it doesn't say how or where to add these files -- or rather I'll gamble that I just don't understand the notes referenced in the website.
So does anyone know how to create a simple project in VS 2010 which builds a CUDA kernel -- using either the nSight 1.5 setup or the NvCudaRuntimeApi.v3.2.rules file which ships with the CUDA 3.2 RC?
Thanks in advance! I'd offer a bounty, but I only have 65 points total.
CUDA TOOLKIT 4.0 and later
The build customisations file (installed into the Program Files\MSBuild\Microsoft.Cpp\v4.0\BuildCustomizations directory) "teaches" Visual Studio how to compile and link any .cu files in your project into your application. If you chose to skip installing the customisations, or if you installed VS2010 after CUDA, you can add them later by following the instructions in Program Files\NVIDIA GPU Computing Toolkit\CUDA\v4.0\extras\visual_studio_integration.
Create a new project using the standard MS wizards (e.g. an empty console project)
Implement your host (serial) code in .c or .cpp files
Add the NVIDIA build customisation (right click on the project, Build customizations, tick the relevant CUDA box)
See note 1 if using CUDA 4.0
Implement your wrappers and kernels in .cu files
If you added .cu files before the build customisations, then you'll need to set the type of the .cu files to CUDA C/C++ (right-click on the file, Properties, set Item Type)
Add the CUDA runtime library (right click on the project and choose Properties, then in Linker -> Input add cudart.lib to the Additional Dependencies)
Then just build your project and the .cu files will be compiled to .obj and added to the link automatically
Incidentally I would advocate avoiding cutil if possible, instead roll your own checking. Cutil is not supported by NVIDIA, it's just used to try to keep the examples in the SDK focussed on the actual program and algorithm design and avoid repeating the same things in every example (e.g. command line parsing). If you write your own then you will have much better control and will know what is happening. For example, the cutilSafeCall wrapper calls exit() if the function fails - a real application (as opposed to a sample) should probably handle the failure more elegantly!
NOTE
For CUDA 4.0 only you may need to apply this fix to the build customisations. This patch fixes the following message:
The result "" of evaluating the value "$(CudaBuildTasksPath)" of the "AssemblyFile" attribute in the element is not valid
This answer applies to CUDA 3.2, from 4.0 onwards CUDA supports the VC 10 compiler directly, see other answers for more information
You need either VS 2008 or the 6.1 Windows SDK installed. That's because NSight 1.5 RC or the CUDA 3.2 SDK use the VC 9 compiler under the hood. I've got this working successfully with 2008 installed and am told it should work with the SDK but haven't tried.
With NSight 1.5 and/or the CUDA 3.2 SDK you shouldn't need to muck with any custom build rules. I've been there and it's painful. With the latest builds all that goes away:
Create your VC++ project.
Add a .CU file to it.
Select the project file in the Solution Explorer.
Open Project | Build Customizations...
Check the "CUDA 3.2 (.targets,
.props)" customization.
Select a .CU file in your project and hit Alt-Enter to show it's properties.
Make sure it's Item Type is set to "CUDA C/C++"
It should just build. Let me know if this helps and if you run into problems as this is from memory.
The good news it getting CUDA working with VS 2010 just got much easier.
Ade
BTW: I'll update my blog post.
Another Good tutorial here:
http://www.stevenmarkford.com/installing-nvidia-cuda-with-visual-studio-2010/
if you get an error about '<' note this step (from a previous answer):
If you added .cu files before the build customisations, then you'll need to set the type of the .cu files to CUDA C/C++ (right-click on the file, Properties, set Item Type)
But if you follow their steps, it should work!
I'm using Visual Studio 2008 on my main build system. I've been playing with Visual Studio 2010 on another one. It appears that the tool still only wants to use one core when compiling unless you specify the /MP switch in the compiler switches (see How do I turn on multi-CPU/Core C++ compiles in the Visual Studio IDE (2008)?). I have to do this for every project. Is there a way to make VS always do this?
Create environment variable "CL" and set it to "/MP". Microsofts compiler cl.exe always prepend command line flags with this variable.
Some compiler features and options like #import aren't compatible with /MP flag. You will need to add /MP1 to projects used #import in a code. This will disable /MP for those projects.
Your can create a property sheet that all of your projects include, and set the /MP flag in that property sheet.
In Visual Studio 2010, you could put it in the Microsoft.Cpp.Win32.user property sheet, which is included in new projects by default (it has the old Visual C++ directories and other default settings defined in it). I don't know that modifying the default property sheet is really a good idea, but it's certainly an option.