CMake 3.18; VS 2019;
I'm learning CMake and to check my results I'm trying to generate visual studio project.
My current problem is precompiled header option.
What I want to achieve is that VS project will have "/use" or "/create" precompiled headers option with correct file name.
In my project folder I already have ugpch.h & ugpch.cpp files, which stands for precompiled headers.
I've tryied to use target_precompile_headers(UGame PRIVATE Source/ugpch.h) instruction in my cmakelists, but that has no effect on my visual studio precompiled header option.
What is the correct way to do this?
Edit: I've updated my cmake to 3.18 version, but still no effect that I expected in my generated visual studio project.
Instead I found new folder "Precompile header files" with cmake_pch.cxx file.. It looks like target_precompile_headers did something totally different from what I expected
The command target_precompile_headers has been added in CMake 3.16.
You'll either have to upgrade your CMake distribution (The one shipped inside VS2019 is quite up to date) or install the latest from the installer.
Otherwise, you'll have to use cotire for precompiled header, but my recommendation would be to upgrade since it's usually quite easy to do, and you probably already have an up to date version on your computer shipped with visual studio.
Since you updated your question.
The command target_precompile_headers is not doing what you think. You don't provide your PCH there, you provide what header should be part of the generated PCH. If the file ugpch.h contains includes for headera.h, headerb.h and headerc.h, then your precompiled header command should look like this:
target_precompile_headers(UGame PRIVATE headera.h headerb.h headerc.h)
The actual precompiled header will be generated by CMake.
Of course, you can still use ugpch.h as your precompiled header. CMake will simply use it to generate its own. As you observed.
After that, remove manual inclusion of the header. It will be included automatically.
From the CMake documentation:
The list of header files is used to generate a header file named cmake_pch.h|xx which is used to generate the precompiled header file (.pch, .gch, .pchi) artifact. The cmake_pch.h|xx header file will be force included (-include for GCC, /FI for MSVC) to all source files, so sources do not need to have #include "pch.h".
Why does it work like that you ask? CMake support PUBLIC precompiled header. If you link to multiple target that each have public precompiled headers, then your target inherit all of them. Since compilers usually accept one precompiled header, CMake has to generate agglomerated headers for that to work.
Using an older version of cmake...
i've used the /Yc and /Yu compiler flag with visual studio.
It is not as universal as target_precompile_headers(UGame PRIVATE Source/ugpch.h) but should do the trick :)
Actually I'm trying to compile a c/c++ project with mingw. The same project is actually compiled with visual studio compiler. For this purpose, I have written a makefile and everything works so far.
During compiling I get error regarding functions which are declared withing string.h and stdio.h like memcpy() , printf()..., with following error:
error: 'memcpy' was not declared in this scope
That's because the compiler didn't find the functions. When compiling within visual studio, this error didn't appear, logically, because of compiler include paths like:
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\
My question now is:
What should I do in my makefile to tell the compiler to use the "string.h" and "stdio.h" functions from the mingw. I tried to put the include path in the makefile, like:
INCLUDE_DIRS =\
C:\MinGW\include
but it has no effect.
And also, there is a difference between the string.h and stdio.h from visual studio and string.h and stdio.h used by gcc. Can this be a problem?
The correct way would be to add these includes to the source files where you use methods which are defined in them.
But if you insist to include it through the makefile, you can use force include.
Visual studio link.
To set this compiler option in the Visual Studio development
environment Open the project's Property Pages dialog box.
Open Project Property Pages.
Click the C/C++ folder.
Click the Advanced property page.
Modify the Force Includes property.
or use -include path_to_the_header for gcc
Just add this option to the compilation command line. Good luck.
Here is the code I am using.
#include "stdafx.h"
#include <iostream>
int main() {
std::cout << "hi";
return 0;
}
When I create simple c++ console application and try to build it, this error occurs:
cannot open include file 'stdio.h': No such file or directory
Why? Shouldn't stdio.h be included as a standard library? What can I do to get it back?
edit: I have just looked into C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include directory. There is no stdio.h or stdafx.h . I really am not sure why. How can I get them back?
That's because Visual studio changed the path to C headers.
There you have the info about that: https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/
What i did to solve this is:
Go to Project->Properties->. In Configuraton Properties->VC++ Diretories->Library Directories add a path to C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\(Choose your architecture)
And in C/C++->General->Additional include directories add a path to:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt
Note: The 10.0.10150.0 may vary depending on your version.
I had a similar problem upgrading an existing C project from Visual Studio 2013 to VS2017 (I'd skipped VS2015); none of the standard headers were found there either.
The accepted answer (by Cezar Azevedo de Faveri) did work for me, but it's inelegant to just jam an absolute path in the settings, especially considering someone can change the install path of both Visual Studio and the SDKs; I'd like to write code that "just works" where possible.
So I spent a little time studying how VS2017 generates a new project, and I eventually found an answer, which is that when VS2017 upgrades an existing C project, it forgets to upgrade one critical project value, and that incorrect value — the Windows SDK Version — makes the headers unable to be found:
By default, VS2017 installs the headers only for the Windows 10 UWP SDK, but it doesn't change the "Windows SDK Version" in any projects it upgrades to a version of the SDK that was actually installed! Mine were set to "8.1" after the upgrade, and there are no headers installed for Windows 8.1
So if you're upgrading an existing project, you'll have to change this setting manually to whichever version of the headers you actually have: In my case, that was by explicitly adding 10.0.14393.0 to the list (that's the version number for the Windows 10 UWP SDK headers that come with VS2017).
(The list of installed versions can be found in the C:\Program Files (x86)\Windows Kits\10\Include folder, and in the similar folders near it.)
I know I am a bit late to this but instead of messing with the path settings, in Visual Studio 2017 you can
right-click the project
select retarget projects
select the latest or any new version of windows SDK and click OK
This will automatically take care of all include paths and libraries.
#include "stdafx.h"
There is a well-known difference between the <...> and "..." includes: briefly, that the former is for library includes and the latter is for local includes.
You mention that you were looking around for stdafx.h but couldn't find it in the compiler installation. This suggests that:
You think stdafx.h is a library file (it is not, unless it's some MS-specific extension, which I doubt, although it is traditionally used as a default filename for precompiled headers by the same--if you have made one, which you almost certainly haven't).
Because of 1., you haven't made a local file stdafx.h, and therefore this include directive should fail. If it hasn't, then something fishy is happening.
As to your actual problem, I have some notes:
<stdio.h> is the C header, not the C++ one. If you're including from a C++ file (extension .cpp, probably, for MSVC), then you should use the C++ header <cstdio>. However, this shouldn't actually cause the problem.
You aren't using the stdio anyway (at least not directly). You're using iostream, which you're properly including. If that include is the one that's causing the error, then iostream is trying to include it, can't, and your compiler installation is borked.
Try the similar program:
#include <iostream>
int main() {
std::cout << "hi" << std::endl;
return 0;
}
I have just checked myself that this compiles and executes properly under Visual Studio 2015 Professional.
If this program does not compile, I suggest reinstalling Visual Studio. In my experience, this often fixes these tricky setup issues.
I faced the same issue , it got resolved when I ran vcvarsall.bat which is present at C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
Above there is provided solution is per project.
But if you don't want to reinstall VS from scratch or set the include directories and libraries on every solution you can modify Toolset.props found in:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\Win32\PlatformToolsets\v140\Toolset.props
<PropertyGroup>
....................
<IncludePath Condition="'$(IncludePath)' == ''">$(VC_IncludePath);$(WindowsSDK_IncludePath);**C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt**</IncludePath>
.......................
<LibraryPath Condition="'$(LibraryPath)' == ''">$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;**C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10150.0\ucrt\**</LibraryPath>
...........................
</PropertyGroup>
I had this error on VS2017 after upgrading from VS2015. I tried a clean + reinstall and it did not fix the error. The problem that I found was two-fold:
$(VC_IncludePath);$(WindowsSDK_IncludePath); was not in the default include path.
$(VC_IncludePath);$(WindowsSDK_IncludePath); was actually EXCLUDED in the default properties (how did this happen?!)
To fix for new projects:
Manually edit the following files:
%LOCALAPPDATA%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props
%LOCALAPPDATA%\Microsoft\MSBuild\v4.0\Microsoft.Cpp.x64.user.props
Make sure that $(VC_IncludePath);$(WindowsSDK_IncludePath); is in the IncludePath and NOT in the ExcludePath.
To fix for old projects (that don't just inherit from the above files):
Manually edit your project properties in the Solution Explorer and make sure that $(VC_IncludePath);$(WindowsSDK_IncludePath); is in the IncludePath and NOT in the ExcludePath.
I had the same problem in Visual Studio Community 2015 after installing the current Windows SDK and as Signa already wrote earlier, this can be fixed for all projects within a "Toolset.props" file (at least for VS2015) and I find this to be the most convenient solution, because this has to be done only once. I've got a few side notes, because there is something to watch out for.
For each build platform there is an own "Toolset.props" file, so both need to be modified if you want to build for 32 and 64 bit targets:
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\Win32\PlatformToolsets\v140\Toolset.props
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Platforms\x64\PlatformToolsets\v140\Toolset.props
The files are write-protected and you need to remove the write protection before you can change those files (remember to put it back on after you're done).
As of now the current SDK version is "10.0.15063.0" and you need to adjust that to the version you want to use (or to the SDK version you have installed).
Look out for the IncludePath and LibraryPath lines in those props files and add the following paths to them:
IncludePath: $(ProgramFiles)\Windows Kits\10\Include\10.0.15063.0\ucrt
LibraryPath: $(ProgramFiles)\Windows Kits\10\Lib\10.0.15063.0\ucrt\$(PlatformTarget)
Here a sample how this looks like for the 32 bit version:
// ... some XML before that ...
<PropertyGroup>
// ... executable path .....
<IncludePath Condition="'$(IncludePath)' == ''">$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProgramFiles)\Windows Kits\10\Include\10.0.15063.0\ucrt;</IncludePath>
// ... reference path ...
<LibraryPath Condition="'$(LibraryPath)' == ''">$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86;$(ProgramFiles)\Windows Kits\10\Lib\10.0.15063.0\ucrt\$(PlatformTarget);</LibraryPath>
// ... more XML ...
</PropertyGroup>
// ... even more XML ....
After running in similar problems once more with VS2017 I took a closer look at what caused all this. And the main reason was that I was still using modified user.props files. Which was for a while a solution to add global include and library paths to all projects. But this feature is deprecated by Microsoft and the content of those files should be reset.
The files I'm talking about are the user.props files in C:\Users\your_name\AppData\Local\Microsoft\MSBuild\v4.0
For testing you can simply rename (or delete if you like risks) them and restart VS. It will create empty files for those now. And if you are on Windows 10 then in most cases this is already enough to fix all your problems. Even in older VS versions (I tested with VS2010-VS2017, for even older VS versions the troubles tend to involve registry keys and don't involve this props files). Windows/VS has become now really good at finding all the system libraries (including DirectX which was the main reason we had to modify those files in the past) and adding them in the correct include order.
Also a warning as I've seen other people recomment that. Do not change any .prop installed by the SDK. If you really need to work with props then create and add your own property sheets (which can overwrite any defaults) to your project. And don't worry, those will not be checked in to source-control so you can still distribute your project to others.
If you are still on an older Windows it might not be as easy as in Windows 10, but I'll try to give some hints:
What you are missing for that concrete error is the new $UniversalCRT_IncludePath. No need to hardcode that path, that macro should contain the correct one. So add $(UniversalCRT_IncludePath); to the IncludePath in your own property which you add then to the project.
And for LibraryPath add the correct path per platform-file, like $(UniversalCRT_LibraryPath_x64); for .x64. and $(UniversalCRT_LibraryPath_x86); for .Win32.
What also might be useful when trying to fix this: You can find out the values of all the $(MACRO) variables used in the build system inside VisualStudio. They are just very well hidden: Go in properties - custom build steps - click on command line - then don't type anything but click the down button to get "edit..." - you click that - you get a dialog which has a "Macros>>" button. And that contains a list with all macro values.
Installing Visual Studio 2015 Update 3 solves this issue, both for new projects and for existing projects created before the update.
https://www.visualstudio.com/news/releasenotes/vs2015-update3-vs
Can someone please help me understand how to build the open source Docfrac C++ Eclipse project with Visual Studio 2012?
Docfrac
UPDATE 1:
When building project in VS 2012, I get:
Unexpected end of file while looking for precompiled header. Did you forget to add '#include "pch.h"' to your source?
UPDATE 2: Got past above issues thanks to Rowland.
Now i get, could not open #include vcl.h. No such file or directory.
CLOSING COMMENTS:
Unfortunately, what I wanted to achieve is not directly possible. Thanks to Rowland for pointing me in the right direction.
For the error relating to precompiled headers, select the source code files (.cpp or .c) that you added to the project in the Solution Explorer. Then right-click, choose Properties. Then in the C/C++ section under Precompiled Headers, select the option that says "Not using precompiled headers". Rebuild and bingo.
Alternatively, you can right-click the project itself and set it for all files.
I'm working one a Visual Studio solution which was generated using CMake (not sure if this is relevant).
In this solution there a c file, I wanted to change it into a cpp file, so I renamed it and changed the extension.
However, Visual Studio still treats it like a c file and gives compiler errors whenever I add any c++ style code.
I'm stuck, any advice would be much appreciated.
Project Properties, Configuration, C/C++, Advanced, change "Compile As".