Не удается открыть файл предкомпилированный заголовок
Precompiled headers can reduce your compilation times significantly. They’ve worked reliably for millions of developers since they were introduced 25 years ago to speed up builds of MFC apps. Precompiled headers are widely used: they are enabled by default for new Visual C++ projects created in the IDE and similarly provide substantial performance wins in our intellisense architecture.
How do precompiled headers speed up your build? For a given project, most source files share a common set of header files (especially software built for Windows). Many of those header files don’t change frequently. Precompiled headers allow the compiler to save the result of compiling a group of headers into a PCH file that can be used in place of those header files in subsequent compilations. If you want to learn more, this document talks about the benefits of precompiled headers and how to use them in your projects.
Precompiled headers work great as a “set it and forget it” feature. They rarely need attention when upgrading compilers, for example. However, due to their nature there are rare situations where things can go wrong, and it can be difficult to figure out why. This article will help you get past some recent issues customers have run into while using precompiled headers with the Visual C++ compiler.
Third-party library issues and vcpkg
If you see this error when you are trying to configure a third-party library as part of your build, consider using vcpkg, a C++ package manager, to install and build the library. vcpkg supports a large and growing list of third-party libraries, and sets all the configuration properties and dependencies required for successful builds as part of your project.
Overview
You might see intermittent build failures with these error codes and messages when creating or using PCH files with the MSVC compiler:
- fatal error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of ‘-ZmXXX’ or greater
- fatal error C1076: compiler limit: internal heap reached; use /Zm to specify a higher limit
- fatal error C1083: Cannot open include file: ‘xyzzy’: No such file or directory
There are multiple reasons why the compiler might be failing with these diagnostics. All these failures are the result of some kind of memory pressure in virtual memory space that is exhibited when the compiler tries to reserve and allocate space for PCH files at specific virtual memory addresses.
One of the best things you can do if you’re experiencing errors with PCH files is to move to a newer Visual C++ compiler. We have fixed many PCH memory pressure bugs in VS 2015 and VS 2017. Visual Studio 2017 contains the compiler toolset from VS 2015.3 as well as the toolset from VS 2017 so it’s an easy migration path to Visual Studio 2017. The compiler that ships in the 2017 version 15.3 provides improved diagnostics to help you understand what’s happening if you encounter these intermittent failures.
Even with the latest compilers, as developers move to build machines with large numbers of physical cores they still encounter occasional failures to commit memory from the OS when using PCH files. As your PCH files grow in size, it’s important to optimize for the robustness of your build as well as build speed. Using a 64-bit hosted compiler can help, as well as adjusting the number of concurrent compiles using the /MP compiler switch and MSBuild’s /maxcpucount: switch.
Overview
You might see intermittent build failures with these error codes and messages when creating or using PCH files with the MSVC compiler:
- fatal error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of ‘-ZmXXX’ or greater
- fatal error C1076: compiler limit: internal heap reached; use /Zm to specify a higher limit
- fatal error C1083: Cannot open include file: ‘xyzzy’: No such file or directory
There are multiple reasons why the compiler might be failing with these diagnostics. All these failures are the result of some kind of memory pressure in virtual memory space that is exhibited when the compiler tries to reserve and allocate space for PCH files at specific virtual memory addresses.
One of the best things you can do if you’re experiencing errors with PCH files is to move to a newer Visual C++ compiler. We have fixed many PCH memory pressure bugs in VS 2015 and VS 2017. Visual Studio 2017 contains the compiler toolset from VS 2015.3 as well as the toolset from VS 2017 so it’s an easy migration path to Visual Studio 2017. The compiler that ships in the 2017 version 15.3 provides improved diagnostics to help you understand what’s happening if you encounter these intermittent failures.
Even with the latest compilers, as developers move to build machines with large numbers of physical cores they still encounter occasional failures to commit memory from the OS when using PCH files. As your PCH files grow in size, it’s important to optimize for the robustness of your build as well as build speed. Using a 64-bit hosted compiler can help, as well as adjusting the number of concurrent compiles using the /MP compiler switch and MSBuild’s /maxcpucount: switch.
Заключение
Как вы увидели, ничего сложного в precompiled headers нет. Все «многочисленные глюки компилятора», с которыми сталкивается программист при их использовании, на самом деле, являются непониманием принципов работы. Надеюсь, эта статья поможет устранить непонимание.
Precompiled headers являются очень полезным механизмом, позволяющим существенно увеличить скорость компиляции проектов.
Fatal error C1083: Cannot open precompiled header file: 'Debug\project.pch': No such file or directory
- Файл stdafx.cpp не компилировался и, как следствие, *.pch файл ещё не создан. Такое может быть, если, например, в начале очистить проект (Clean Solution), а потом попробовать скомпилировать один *.cpp файл (Compile Ctrl-F7). Решение: скомпилируйте проект целиком или как минимум файл stdafx.cpp.
- В настройках ни указано ни одного файла, из которого должен генерироваться *.pch файл. Речь идёт о ключе компиляции /Yc. Как правило, такая ситуация возникает у начинающих, которые захотели использовать precompiled headers для своего проекта. Как это сделать описано выше в разделе «Как использовать Precompiled Headers».
Если это невозможно, то следует не использовать precompiled header для этого *.c/*.cpp файла. Уберите ключ /Yu.
The specified file name is wrong
The name of a file may be mistyped. For example,
Проблемы с библиотекой сторонних производителей и vcpkg
если вы видите эту ошибку при попытке настроить библиотеку стороннего производителя в рамках сборки, рассмотрите возможность использования vcpkg, диспетчера пакетов C++ для установки и сборки библиотеки. vcpkg поддерживает большой и растущей список библиотек сторонних производителейи задает все свойства конфигурации и зависимости, необходимые для успешной сборки в рамках проекта.
Example
The following example generates a C1083 error when the header file "test.h" does not exist in the source directory or on the include search path.
For information about how to build C/C++ projects in the IDE or on the command line, and information about setting environment variables, see Projects and build systems.
Статья рассчитана на людей, которые знакомятся со средой Visual Studio и пытаются компилировать в ней свои Си++-проекты. В незнакомой среде всё кажется странным и непонятным. Особенно новичков раздражает файл stdafx.h, из-за которого возникают странные ошибки во время компиляции. Очень часто всё заканчивается тем, что новичок долгое время везде старательно отключает Precompiled Headers. Чтобы помочь людям разобраться что к чему, и была написана эта статья.
Предкомпилированные заголовки еще не скомпилированы
Если проект настроен для использования предварительно скомпилированных заголовков, необходимо создать соответствующие .pch файлы, чтобы можно было скомпилировать файлы, использующие содержимое заголовка. например, pch.cpp файл ( stdafx.cpp в Visual Studio 2017 и более ранних версий) автоматически создается в каталоге проекта для новых проектов. Сначала необходимо скомпилировать этот файл, чтобы создать предкомпилированные файлы заголовков. В типичном проекте процесса сборки это выполняется автоматически. Дополнительные сведения см. в разделе Создание предкомпилированных файлов заголовков.
Включена неправильная версия имени файла
Указано неверное имя файла
При вводе имени файла допущена ошибка. Например, примененная к объекту директива
может не найти файл, который вы хотели. Большинство файлов заголовков стандартной библиотеки C++ не имеют расширения h. . Чтобы устранить эту проблему, убедитесь, что указано правильное имя файла, как в следующем примере:
Из-за precompiled header компилятор глючит
Содержимое файла «my.h» не будет использоваться. В результате, нельзя будет использовать функции, объявленные в этом файле. Такое поведение очень сбивает программистов с толку. Они «лечат» его полным отключением precompiled headers и потом рассказывают байки о глючности Visual C++. Запомните, компилятор — это один из наиболее редко глючащих инструментов. В 99.99% случаев надо не злиться на компилятор, а искать ошибку у себя (Proof).
Ещё один вариант — используйте Forced Included File. См. выше раздел «Life hack».
Предкомпилированные заголовки еще не скомпилированы
Если проект настроен для использования предварительно скомпилированных заголовков, необходимо создать соответствующие .pch файлы, чтобы можно было скомпилировать файлы, использующие содержимое заголовка. например, pch.cpp файл ( stdafx.cpp в Visual Studio 2017 и более ранних версий) автоматически создается в каталоге проекта для новых проектов. Сначала необходимо скомпилировать этот файл, чтобы создать предкомпилированные файлы заголовков. В типичном проекте процесса сборки это выполняется автоматически. Дополнительные сведения см. в разделе Создание предкомпилированных файлов заголовков.
Включена неправильная версия имени файла
Возможно, файл заблокирован или используется
Если для изменения или доступа к файлу используется другая программа, файл может быть заблокирован. Попробуйте закрыть файл в другой программе. иногда другая программа может быть Visual Studio сама по себе при использовании параметров параллельной компиляции. Если отключить параметр параллельной сборки, то эта ошибка исчезнет, а это проблема. Эта проблема также может быть вызвана другими системами параллельной сборки. Будьте внимательны при задании зависимостей файлов и проектов, чтобы порядок сборки был правильным. В некоторых случаях рекомендуется создать промежуточный проект для принудительного создания последовательности зависимостей для общего файла, который может быть создан несколькими проектами. Иногда антивирусные программы временно блокируют недавно измененные файлы для проверки. Если возможно, рассмотрите возможность исключения каталогов сборки проекта из антивирусного сканера.
Не задана среда командной строки INCLUDE или LIB
Если компилятор вызывается из командной строки, для указания путей поиска часто используются переменные среды. Если путь поиска, описанный в переменной среды include или lib , задан неправильно, может быть сформирована ошибка C1083. Мы настоятельно рекомендуем использовать ярлык командной строки разработчика, чтобы задать базовую среду для сборок с командной строкой. Дополнительные сведения см. в разделе сборка C/C++ в командной строке. Дополнительные сведения об использовании переменных среды см. в разделе инструкции. Использование переменных среды в сборке.
Как работают Precompiled Headers
Файл, который содержит precompiled headers, имеет расширение ".pch". Имя файла обычно совпадает с названием проекта. Естественно, это и другие используемые имена можно изменить в настройках. Файл может быть весьма большим и зависит от того, как много заголовочных файлов в нём раскрыто. Например, в проекте PVS-Studio он занимает около 3 мегабайт.
В файле «stdafx.h» находится самое интересное. Сюда нужно включить заголовочные файлы, которые будут заранее препроцессироваться. В качестве примера, вот файл stdafx.h, используемый нами в PVS-Studio (файл сокращён для статьи):
Теперь во все файлы *.c/*.cpp следует включить «stdafx.h». Заодно стоит удалить из этих файлов заголовки, которые уже включаются с помощью «stdafx.h».
Достаточно сделать один precompiled header, в котором будут раскрыты , и . Выигрыш от того, что при препроцессировании не надо читать множество файлов и вставлять их друг друга намного больше, чем потери на синтаксический анализ лишних фрагментов кода.
The command line INCLUDE or LIB environment is not set
When the compiler is invoked on the command line, environment variables are often used to specify search paths. If the search path described by the INCLUDE or LIB environment variable is not set correctly, a C1083 error can be generated. We strongly recommend using a developer command prompt shortcut to set the basic environment for command line builds. For more information, see Build C/C++ on the Command Line. For more information about how to use environment variables, see How to: Use Environment Variables in a Build.
Файл находится в проекте, но не в пути поиска включаемых файлов
Чтобы устранить эту проблему, исправьте путь, используемый компилятором для поиска включаемого или импортируемого файла. В новом проекте используются пути поиска include по умолчанию. Может потребоваться изменить путь поиска include, чтобы добавить каталог для проекта. При компиляции в командной строке добавьте путь к переменной среды include или /I параметр компилятора, чтобы указать путь к файлу.
чтобы задать путь к каталогу включения в Visual Studio, откройте диалоговое окно страницы свойств проекта. выберите VC++ каталоги в разделе свойства конфигурации в левой области, а затем измените свойство включаемые каталоги . дополнительные сведения о каталогах для отдельных пользователей и проектов, поиск которых выполняется компилятором в Visual Studio, см. в разделе страница свойств VC++ directories. Дополнительные сведения о параметре компилятора см. в /I разделе /I (дополнительные каталоги включаемых данных).
Типовые ошибки при использовании Precompiled Headers
Прочитав внимательно материал выше, вы сможете понять и устранить ошибки, связанные с stdafx.h. Но давайте ещё раз пройдёмся по типовым ошибкам компиляции и разберём их причины. Повторенье — мать ученья.
Life hack
Есть вариант, как использовать precompiled headers легко и просто. Способ подойдёт не везде и всегда, но мне он часто помогал.
Идём на вкладку настроек «Advanced». Выбираем все конфигурации. В поле «Forced Included File» пишем:
Теперь «stdafx.h» автоматически будет включаться в начало ВСЕХ компилируемых файлов. PROFIT!
The file is in your project, but not the include search path
To fix this issue, correct the path that the compiler uses to search for the included or imported file. A new project uses default include search paths. You may have to modify the include search path to add a directory for your project. If you are compiling on the command line, add the path to the INCLUDE environment variable or the /I compiler option to specify the path to the file.
To set the include directory path in Visual Studio, open the project’s Property Pages dialog box. Select VC++ Directories under Configuration Properties in the left pane, and then edit the Include Directories property. For more information about the per-user and per-project directories searched by the compiler in Visual Studio, see VC++ Directories Property Page. For more information about the /I compiler option, see /I (Additional Include Directories).
The precompiled headers are not yet precompiled
When a project is configured to use precompiled headers, the relevant .pch files have to be created so that files that use the header contents can be compiled. For example, the pch.cpp file ( stdafx.cpp in Visual Studio 2017 and earlier) is automatically created in the project directory for new projects. Compile that file first to create the precompiled header files. In the typical build process design, this is done automatically. For more information, see Creating Precompiled Header Files.
Areas affecting PCH memory issues
Build Failures related to PCH use typically have one of the following causes:
- Fragmentation of the virtual memory address range(s) required by the PCH before CL.EXE is able to load it into memory.
- Failure of the Windows OS under heavy loads to increase the pagefile size within a certain time threshold.
Failure to automatically increase the pagefile size
Some developers utilizing many-core (32+) machines have reported seeing the above intermittent error messages during highly parallel builds with dozens of CL.EXE processes active. This is more likely to happen when using the /maxcpucount ( /m ) option to MSBUILD.EXE in conjunction with the /MP option to CL.EXE. These two options, used simultaneously, can multiply the number of CL.EXE processes running at once.
The underlying issue is a potential file system bottleneck that is being investigated by Windows. In some situations of extreme resource contention, the OS will fail to increase the virtual memory pagefile size even though there is sufficient disk space to do so. Such resource contention can be achieved in a highly parallelized build scenario with many dozens of CL.EXE processes running simultaneously. If PCHs are being used, each CL.EXE process will make several calls to VirtualAlloc() , asking it to commit large chunks of virtual memory for loading the PCH components. If the system page file is being automatically managed, the OS may time out before it can service all the VirtualAlloc() calls. If you see the above error messages in this scenario, manually managing the pagefile settings may resolve the problem.
Manually managing the Windows pagefile
Here’s how you adjust the virtual memory settings on Windows 10 (the procedure is similar for older versions of Windows.) The goal is to set the pagefile settings so that they are large enough to handle the size of all simultaneous VirtualAlloc() calls made by every CL.EXE process that is trying to load a PCH. You can do a back-of-the-envelope calculation by multiplying the size of the largest PCH file in the build by the number of CL.EXE processes observed in the task manager during a build. Be sure to set the initial size equal to the maximum size so that Windows never has to resize the pagefile.
- Open the Control Panel
- Select System and Security
- Select System
- In the Advanced tab of the System Properties dialog, select the Performance “Settings” button
- Select the Virtual Memory “Change” button on the Advanced tab
- Turn off “Automatically manage paging file size for all drives” and set the Custom size. Note that you should set both the “initial size” and “maximum size” to the same value, and you should set them to be large enough to avoid the OS exhausting the page file limit.
Most problems with memory usage and precompiled headers come from large PCH files being used in multiple CL.EXE processes running simultaneously. These suggestions will help you adjust the compiler architecture and processor usage so that you can use an appropriate amount of memory for the size of the PCH being used.
Changing the compiler’s host architecture
If your PCH file is large (250 MB or more) and you’re receiving the above out-of-memory error messages when using the x86-hosted compiler, consider changing to the x64-hosted compiler. The x64-hosted compiler can use more (physical and virtual) memory than the x86-hosted compiler. You can produce apps for any architecture with x64-hosted tools.
To change from the compiler’s host architecture from the command line, just run the appropriate command environment shortcut (e.g., “x64 Native Tools Command Prompt”.) You can verify that you’ve got the right environment by typing cl /Bv on the command line.
If you’re using MSBuild from the command line you can pass /p:PreferredToolArchtecture=x64 to MSBuild. If you’re building with MSBuild from within Visual Studio, you can edit your .vcxproj file to include a PropertyGroup containing this property. There are instructions on how to add the PropertyGroup under the section “Using MSBuild with the 64-bit Compiler and Tools” on this page.
If you’re using the /Zm switch on your compile command line, remove it. That flag is no longer required to accommodate large PCH files in Visual Studio 2015 and forward.
Changing the number of processors used in compilation
When the /MP compiler option is used, the compiler will build with multiple processes. Each process will compile one source file (or “translation unit”) and will load its respective PCH files and compiler DLLs into the virtual memory space reserved by that process. On a machine with many cores this can quickly cause the OS to run out of physical memory. For example, on a 64-core machine with a large PCH file (e.g., 250 MB) the consumed physical memory (not the virtual memory) can easily exceed 16 GB. When physical memory is exhausted the OS must start swapping process memory to the page file, which (if automatically managed) may need to be grown to handle the requests. When the number of simultaneous “grow” requests reaches a tipping point, the file system will fail all requests it cannot service within a certain threshold.
The generally stated advice is that you should not exceed the number of physical cores when you parallelize your compile across processes. Although you may achieve better performance by oversubscribing, you should be aware of the potential for these memory errors and dial back the amount of parallelism you use if you see the above errors during builds.
The default setting of /MP is equal to the number of physical cores on the machine, but you can throttle it back by setting it to a lower number. For example, if your build is parallelized in two worker processes on a 64-core machine you may want to set /MP32 to use 32 cores for each worker process. Note that the MSBuild /maxcpucount (or /m ) setting refers to the number of MSBuild processes. Its value is effectively multiplied by the number of processes specified by the compiler’s /MP switch. If you have /maxcpucount:32 and /MP defaulting to 32 on a 32-core machine, you will have up to 1024 instances of the compiler running concurrently.
Throttling back the number of concurrent compiler processes may help with the intermittent fatal errors described above.
Reducing the size of your PCH
The larger your PCH file, the more memory it consumes in every instance of the compiler that runs during your build. It is common for PCH files to contain many headers files that aren’t even referenced. You may also find that your PCH files grow when you upgrade to a new compiler toolset. As the library headers grow in size from version to version, PCH files that include them grow as well.
Note that while PCH files up to 2 GB in size are theoretically possible, any PCH over 250 MB should be considered large, and thus more likely to contain unused header files and impede scaling to large build machines.
Ignoring the /Zm flag
Проблемы с библиотекой сторонних производителей и vcpkg
если вы видите эту ошибку при попытке настроить библиотеку стороннего производителя в рамках сборки, рассмотрите возможность использования vcpkg, диспетчера пакетов C++ для установки и сборки библиотеки. vcpkg поддерживает большой и растущей список библиотек сторонних производителейи задает все свойства конфигурации и зависимости, необходимые для успешной сборки в рамках проекта.
Как использовать Precompiled Headers
При создании нового проекта Wizard в Visual Studio создаёт два файла: stdafx.h и stdafx.cpp. Именно с помощью них и реализуется механизм precompiled headers.
На самом деле, эти файлы могут называться, как угодно. Важно не название, а параметры компиляции в настройках проекта.
В *.c/*.cpp файле можно использовать только один precompiled header. Однако, в одном проекте может присутствовать несколько разных precompiled headers. Пока будем считать, что он у нас только один.
Итак, если вы воспользовались wizard-ом, то у вас уже есть файлы stdafx.h и stdafx.cpp. Плюс выставлены все необходимые ключи компиляции.
- Во всех конфигурациях для всех *.c/*.cpp файлов включаем использование precompiled headers. Это делается на вкладке «Precompiled Header»:
- Выставляем для параметра «Precompiled Header» значение «Use (/Yu)».
- Для параметра «Precompiled Header File» указываем «stdafx.h».
- Для параметра «Precompiled Header Output File» указываем "$(IntDir)$(TargetName).pch".
Заголовочный файл «stdafx.h» должен включаться в *.c/*.cpp файл самым первым. Обязательно! Иначе всё равно возникнут ошибки компиляции.
Если подумать, в этом есть логика. Когда файл «stdafx.h» находится в самом начале, то можно подставить уже препроцессированный текст. Этот текст всегда одинаков и ни от чего не зависит.
Что включать в stdafx.h
Это очень важный момент. Бездумное включение в «stdafx.h» всего подряд не только не ускорит компиляцию, но и наоборот замедлит её.
Все файлы, включающие «stdafx.h», зависят от его содержимого. Пусть в «stdafx.h» включен файл «X.h». Если вы поменяете хоть что-то в «X.h», это может повлечь полную перекомпиляцию всего проекта.
Правило. Включайте в «stdafx.h» только те файлы, которые никогда не изменяются или меняются ОЧЕНЬ редко. Хорошими кандидатами являются заголовочные файлы системных и сторонних библиотек.
Если включаете в «stdafx.h» собственные файлы из проекта, соблюдайте двойную бдительность. Включайте только те файлы, которые меняются очень-очень редко.
Если какой-то *.h файл меняется раз в месяц, это уже слишком часто. Как правило, редко удаётся сделать все правки в h-файле с первого раза. Обычно требуется 2-3 итерации. Согласитесь, 2-3 раза полностью перекомпилировать весь проект — занятие неприятное. Плюс полная перекомпиляция потребуется всем вашим коллегам.
Не увлекайтесь с неизменяемыми файлами. Включайте только то, что действительно часто используется. Нет смысла включать , если это нужно только в двух местах. Там, где нужно, там и подключите этот заголовочный файл.
Пример
В следующем примере создается ошибка C1083, если файл "test.h" заголовка не существует в исходном каталоге или в пути поиска include.
Сведения о том, как создавать проекты C/C++ в интегрированной среде разработки или в командной строке, а также сведения о настройке переменных среды см. в разделе проекты и сборки систем.
The compiler generates a C1083 error when it can’t find a file it requires. There are many possible causes for this error. An incorrect include search path or missing or misnamed header files are the most common causes, but other file types and issues can also cause C1083. Here are some of the common reasons why the compiler generates this error.
Future Improvements
We are working to make PCH files more robust in the face of resource contention failures and to make the errors emitted more actionable. In Visual Studio 2017 version 15.3 the compiler emits a detailed message that provides more context for compiler error C3859. For example, here’s what one such failure will look like:
Творится что-то непонятное
Иногда может возникнуть ситуация, что вы поправили код, а ошибка не исчезает. Отладчик показывает непонятные вещи.
Причиной может быть *.pch файл. Как-то так получилось, что компилятор не замечает изменения в одном из заголовочных файлов и не перестраивает *.pch файл. В результате, подставляется старый код. Возможно, это происходило из-за каких-то сбоев, связанных с временем модификации файлов.
Это ОЧЕНЬ редкая ситуация. Но она возможна и про неё надо знать. Я за многие годы программирования сталкивался с ней только 2-3 раза. Помогает полная перекомпиляция проекта.
Несколько Precompiled Headers
Зачем в одном проекте может понадобиться несколько precompiled headers? Действительно, это нужно не часто. Но приведу пару примеров.
В проекте используются одновременно *.c и *.cpp файлы. Для них нельзя использовать единый *.pch файл. Компилятор выдаст ошибку.
Нужно создать два *.pch файла. Один должен получаться при компилировании C-файла (xx.c), а другой при компилировании C++-файла (yy.cpp). Соответственно, в настройках надо указать, чтобы в С-файлах использовался один precompiled header, а в С++-файлах — другой.
Примечание. Не забудьте указать разные имена для *.pch файлов. Иначе один файл будет перетирать другой.
Другая ситуация. Одна часть проекта использует одну большую библиотеку, а другая часть другую большую библиотеку.
Естественно, не стоит всем участкам кода знать про обе библиотеки. В (неудачных) библиотеках могут пересекаться имена каких-то сущностей.
Логично сделать два precompiled headers и использовать их в разных участках программы. Как уже отмечалось, можно задать произвольные имена файлов, из которых генерируются *.pch файлы. Да и имя *.pch файла тоже можно изменить. Всё это, конечно, требуется делать аккуратно, но ничего сложного в использовании двух precompiled headers нет.
Файл не включен в путь поиска включаемых файлов
Это указывает компилятору искать файл в том же каталоге, который содержит исходный файл, а затем искать в других местах, заданных средой сборки. Если кавычки содержат абсолютный путь, компилятор выполняет поиск файла только в этом расположении. Если кавычки содержат относительный путь, компилятор выполняет поиск файла в каталоге относительно исходного каталога.
Если имя заключено в угловые скобки,
Если включаемые файлы находятся в другом каталоге относительно исходного каталога и в директивах Include используется относительный путь, то вместо угловых скобок следует использовать двойные кавычки. Например, если файл myheader.h заголовка находится в подкаталоге именованных заголовков проекта, в этом примере не удается найти файл и вызывается C1083:
но этот пример работает:
Проект, использующий precompiled headers не удаётся проверить с помощью PVS-Studio
Это наиболее частая ситуация, с которой к нам обращаются в поддержку. Подробности изложены в документации: "Устранение неисправностей при работе PVS-Studio". Здесь опишу ситуацию кратко.
Если решение (solution) компилируется, это вовсе не значит, что оно правильно устроено. Часто одно решение (solution) содержит множество проектов. В каждом проекте используются свои precompiled headers (имеется свой stdafx.h и stdafx.cpp).
И, какой из stdafx.h подхватится, это интересный вопрос. Но раз программа компилируется — программисту везёт.
К сожалению, нам сложно повторить поведение, которое возникает при использовании *.pch файла. «Честный» препроцессор работает по-другому.
В том, что solution, на самом деле, устроен не верно, можно убедиться, временно отключив precompiled headers. Сразу может вылезти масса интересных ошибок, и программист будет искренне удивляться, каким же чудом компилировался его проект.
За подробностями вновь делаю отсылку к документации. Плюс, если что-то всё равно не ясно, мы подскажем в поддержке.
Указано неверное имя файла
При вводе имени файла допущена ошибка. Например, примененная к объекту директива
может не найти файл, который вы хотели. Большинство файлов заголовков стандартной библиотеки C++ не имеют расширения h. . Чтобы устранить эту проблему, убедитесь, что указано правильное имя файла, как в следующем примере:
The file is not included in the include search path
this tells the compiler to look for the file in the same directory that contains the source file first, and then look in other locations specified by the build environment. If the quotation marks contain an absolute path, the compiler only looks for the file at that location. If the quotation marks contain a relative path, the compiler looks for the file in the directory relative to the source directory.
If the name is enclosed by angle brackets,
If your include files are in another directory relative to your source directory, and you use a relative path in your include directives, you must use double quotes instead of angle brackets. For example, if your header file myheader.h is in a subdirectory of your project sources named headers, then this example fails to find the file and causes C1083:
but this example works:
Для чего нужны Precompiled Headers
Precompiled headers предназначены для ускорения сборки проектов. Обычно программисты начинают знакомиться с Visual C++, используя крошечные проекты. На них сложно заметить выигрыш от precompiled headers. Что с ними, что без них, на глаз программа компилируется одинаковое время. Это добавляет путаницы. Человек не видит для себя пользы от этого механизма и решает, что он для специфичных задач и ему никогда не понадобится. И иногда считает так многие годы.
На самом деле, precompiled headers весьма полезная технология. Пользу от него можно заметить, даже если в проекте всего несколько десятков файлов. Особенно выигрыш становится заметен, если используются такие тяжёлые библиотеки как boost.
Если посмотреть *.cpp файлы в проекте, то можно заметить, что во многие включаются одни и те-же наборы заголовочных файлы. Например, , , . В свою очередь, эти файлы включают другие заголовочные файлы и так далее.
Можно существенно сократить объем работы, которую должен проделать препроцессор при компиляции проекта. Идея в том, чтобы заранее препроцессировать группу файлов и затем просто подставлять готовый фрагмент текста.
На самом деле, делается ещё ряд шагов. Можно хранить не просто текст, а более обработанную информацию. Я не знаю, как именно устроено в Visual C++. Но, например, можно хранить текст уже разбитый на лексемы. Это ещё больше ускорит процесс компиляции.
Дополнительные причины
Вы установили пакет SDK или библиотеку стороннего производителя, но после установки пакета SDK или библиотеки не открывали новое окно командной строки разработчика. Если пакет SDK или библиотека добавляет файлы в путь поиска включаемых файлов, может потребоваться открыть новое окно командной строки разработчика, чтобы получить эти изменения переменных среды.
Файл использует управляемый код, но параметр /clr компилятора не указан. Дополнительные сведения см. в разделе /clr (компиляция среды CLR).
Файл компилируется с использованием другого /analyze параметра компилятора, чем используется для предварительной компиляции заголовков. При предварительной компиляции заголовков для проекта все должны использовать одни и те же /analyze Параметры. дополнительные сведения см. в разделе /analyze (Code Analysis).
файл или каталог был создан подсистема Windows для Linux, учитывается регистр в каждом каталоге, и указанный регистр пути или файла не соответствует регистру пути или файла на диске.
Файл, каталог или диск доступен только для чтения.
Visual Studio или средства командной строки не имеют достаточных разрешений для чтения файла или каталога. это может произойти, например, когда файлы проекта имеют разные права владения, чем процесс, выполняемый Visual Studio или программ командной строки. иногда эту ошибку можно устранить, запустив Visual Studio или командную строку разработчика от имени администратора.
Недостаточно дескрипторов файлов. Закройте часть приложений и повторите компиляцию. Эта ситуация маловероятна в обычных условиях. Однако она может возникать при построении крупных проектов на компьютере с ограниченной физической памятью.
Файл не включен в путь поиска включаемых файлов
Это указывает компилятору искать файл в том же каталоге, который содержит исходный файл, а затем искать в других местах, заданных средой сборки. Если кавычки содержат абсолютный путь, компилятор выполняет поиск файла только в этом расположении. Если кавычки содержат относительный путь, компилятор выполняет поиск файла в каталоге относительно исходного каталога.
Если имя заключено в угловые скобки,
Если включаемые файлы находятся в другом каталоге относительно исходного каталога и в директивах Include используется относительный путь, то вместо угловых скобок следует использовать двойные кавычки. Например, если файл myheader.h заголовка находится в подкаталоге именованных заголовков проекта, в этом примере не удается найти файл и вызывается C1083:
но этот пример работает:
The wrong version of a file name is included
The file may be locked or in use
If you are using another program to edit or access the file, it may have the file locked. Try closing the file in the other program. Sometimes the other program can be Visual Studio itself, if you are using parallel compilation options. If turning off the parallel build option makes the error go away, then this is the problem. Other parallel build systems can also have this issue. Be careful to set file and project dependencies so build order is correct. In some cases, consider creating an intermediate project to force build dependency order for a common file that may be built by multiple projects. Sometimes antivirus programs temporarily lock recently changed files for scanning. If possible, consider excluding your project build directories from the antivirus scanner.
Fatal error C1853: 'project.pch' precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)
В проекте присутствуют как C (*.c), так и C++ (*.cpp) файлы. Для них нельзя использовать единый precompiled header (*.pch файл).
- Отключить для всех Си-файлов использование precompiled headers. Как показывает практика, *.с файлы препроцессируются в несколько раз быстрее, чем *.cpp файлы. Если *.c файлов не очень много, то, отключив precompiled headers для них, вы ничего не потеряете
- Завести два precompiled headers. Первый должен создаваться из stdafx_cpp.cpp, stdafx_cpp.h. Второй из stdafx_c.c, stdafx_c.h. Соответственно, в *.c и *.cpp файлах следует использовать разные precompiled headers. Имена *.pch файлов естественно тоже должны различаться.
Возможно, файл заблокирован или используется
Если для изменения или доступа к файлу используется другая программа, файл может быть заблокирован. Попробуйте закрыть файл в другой программе. иногда другая программа может быть Visual Studio сама по себе при использовании параметров параллельной компиляции. Если отключить параметр параллельной сборки, то эта ошибка исчезнет, а это проблема. Эта проблема также может быть вызвана другими системами параллельной сборки. Будьте внимательны при задании зависимостей файлов и проектов, чтобы порядок сборки был правильным. В некоторых случаях рекомендуется создать промежуточный проект для принудительного создания последовательности зависимостей для общего файла, который может быть создан несколькими проектами. Иногда антивирусные программы временно блокируют недавно измененные файлы для проверки. Если возможно, рассмотрите возможность исключения каталогов сборки проекта из антивирусного сканера.
Additional causes
You have installed an SDK or third-party library, but you have not opened a new developer command prompt window after the SDK or library is installed. If the SDK or library adds files to the INCLUDE path, you may need to open a new developer command prompt window to pick up these environment variable changes.
The file uses managed code, but the compiler option /clr is not specified. For more information, see /clr (Common Language Runtime Compilation).
The file is compiled by using a different /analyze compiler option setting than is used to precompile the headers. When the headers for a project are precompiled, all should use the same /analyze settings. For more information, see /analyze (Code Analysis).
The file or directory was created by the Windows Subsystem for Linux, per-directory case sensitivity is enabled, and the specified case of a path or file does not match the case of the path or file on disk.
The file, the directory, or the disk is read-only.
Visual Studio or the command line tools do not have sufficient permissions to read the file or the directory. This can happen, for example, when the project files have different ownership than the process running Visual Studio or the command line tools. Sometimes this issue can be fixed by running Visual Studio or the developer command prompt as Administrator.
There are not enough file handles. Close some applications and then recompile. This condition is unusual under typical circumstances. However, it can occur when large projects are built on a computer that has limited physical memory.
Не задана среда командной строки INCLUDE или LIB
Если компилятор вызывается из командной строки, для указания путей поиска часто используются переменные среды. Если путь поиска, описанный в переменной среды include или lib , задан неправильно, может быть сформирована ошибка C1083. Мы настоятельно рекомендуем использовать ярлык командной строки разработчика, чтобы задать базовую среду для сборок с командной строкой. Дополнительные сведения см. в разделе сборка C/C++ в командной строке. Дополнительные сведения об использовании переменных среды см. в разделе инструкции. Использование переменных среды в сборке.
Пример
В следующем примере создается ошибка C1083, если файл "test.h" заголовка не существует в исходном каталоге или в пути поиска include.
Сведения о том, как создавать проекты C/C++ в интегрированной среде разработки или в командной строке, а также сведения о настройке переменных среды см. в разделе проекты и сборки систем.
Компилятор создает ошибку C1083, когда не удается найти требуемый файл. Эта ошибка имеет несколько возможных причин. Наиболее распространенными причинами являются неверный путь поиска include или отсутствующие или неправильно именованные файлы заголовков, но другие типы файлов и проблемы могут также вызвать C1083. Ниже приведены некоторые распространенные причины, по которым компилятор создает эту ошибку.
Из-за precompiled headers проект постоянно перекомпилируется целиком
В stdafx.h включён файл, который регулярно редактируется. Или случайно включён автогенерируемый файл.
Внимательно проверьте содержимое файла «stdafx.h». В него должны входить только заголовочные файлы, которые не изменяются или изменяются крайне редко. Учтите, что включённые файлы могут не меняться, но внутри они ссылаются на другие изменяющиеся *.h файлы.
Файл находится в проекте, но не в пути поиска включаемых файлов
Чтобы устранить эту проблему, исправьте путь, используемый компилятором для поиска включаемого или импортируемого файла. В новом проекте используются пути поиска include по умолчанию. Может потребоваться изменить путь поиска include, чтобы добавить каталог для проекта. При компиляции в командной строке добавьте путь к переменной среды include или /I параметр компилятора, чтобы указать путь к файлу.
чтобы задать путь к каталогу включения в Visual Studio, откройте диалоговое окно страницы свойств проекта. выберите VC++ каталоги в разделе свойства конфигурации в левой области, а затем измените свойство включаемые каталоги . дополнительные сведения о каталогах для отдельных пользователей и проектов, поиск которых выполняется компилятором в Visual Studio, см. в разделе страница свойств VC++ directories. Дополнительные сведения о параметре компилятора см. в /I разделе /I (дополнительные каталоги включаемых данных).
In closing
Thank you to the hundreds of people who provide feedback and help us improve the C++ experience in Visual Studio. Most of the issues and suggestions covered in this blog post result from conversations we had because you reached out to our team.
Компилятор создает ошибку C1083, когда не удается найти требуемый файл. Эта ошибка имеет несколько возможных причин. Наиболее распространенными причинами являются неверный путь поиска include или отсутствующие или неправильно именованные файлы заголовков, но другие типы файлов и проблемы могут также вызвать C1083. Ниже приведены некоторые распространенные причины, по которым компилятор создает эту ошибку.
Дополнительные причины
Вы установили пакет SDK или библиотеку стороннего производителя, но после установки пакета SDK или библиотеки не открывали новое окно командной строки разработчика. Если пакет SDK или библиотека добавляет файлы в путь поиска включаемых файлов, может потребоваться открыть новое окно командной строки разработчика, чтобы получить эти изменения переменных среды.
Файл использует управляемый код, но параметр /clr компилятора не указан. Дополнительные сведения см. в разделе /clr (компиляция среды CLR).
Файл компилируется с использованием другого /analyze параметра компилятора, чем используется для предварительной компиляции заголовков. При предварительной компиляции заголовков для проекта все должны использовать одни и те же /analyze Параметры. дополнительные сведения см. в разделе /analyze (Code Analysis).
файл или каталог был создан подсистема Windows для Linux, учитывается регистр в каждом каталоге, и указанный регистр пути или файла не соответствует регистру пути или файла на диске.
Файл, каталог или диск доступен только для чтения.
Visual Studio или средства командной строки не имеют достаточных разрешений для чтения файла или каталога. это может произойти, например, когда файлы проекта имеют разные права владения, чем процесс, выполняемый Visual Studio или программ командной строки. иногда эту ошибку можно устранить, запустив Visual Studio или командную строку разработчика от имени администратора.
Недостаточно дескрипторов файлов. Закройте часть приложений и повторите компиляцию. Эта ситуация маловероятна в обычных условиях. Однако она может возникать при построении крупных проектов на компьютере с ограниченной физической памятью.
Читайте также: