У меня было много ошибок компоновщика в Visual Studio 2008 Express, которые, как я подозревал, были связаны с проблемами, обсуждаемыми в этом вопросе, и в этом . После долгих исследований мне удалось решить проблему, и я подумал, что было бы полезно поделиться знаниями.
В итоге (я приведу более подробно ниже):
ошибки компоновщика происходили из-за того, что значение %WindowsSdkDir%
не было установлено правильно, и поэтому VS не мог найти файлы типа kernel32.lib
,
причина неправильной настройки была удручающе простой: пробел закрался в переменную PATH
прямо перед записью %SystemRoot%\system32
,
это означало, что команда MSDOS reg query
была фактически отключена,
эта команда используется в одном из пакетных файлов VS для установки значений переменных; поэтому пакетный файл в итоге установил %WindowsSdkDir%
не из реестра (все мои записи в реестре были верны), а вместо этого установил его равным значению по умолчанию %VCINSTALLDIR%\PlatformSDK\
, что было неверно для моей настройки.
Очевидно, в моем случае исправить было легко: удалите пробел! Но, конечно, путь к решению действительно интересен ...
Как я уже сказал, первым признаком проблемы было то, что VS выдавал неприятные ошибки компоновщика. Я смог понять из этого, что VS не смог найти файлы типа kernel32.lib
.
Если вы будете искать вокруг этого, вы, вероятно, окажетесь на этом ТАКОМ вопросе . В ответе, набравшем наибольшее количество голосов, упоминается WindowsSdkDir
и предполагается, что проверяющий проверяет, правильно ли на него ссылаются в настройках VS.
Мне было ясно, что мои настройки VS не были проблемой, потому что я уже смог освободить мою установку без ошибок на другом компьютере. Дальнейшие поиски в WindowsSdkDir привели меня к этому вот такому вопросу, и я проверил все предлагаемые записи реестра (здесь и в других местах):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6342Node\Microsoft\Microsoft SDKs\Windows
HKEY_CURRENT_USER\SOFTWARE\Wow6342Node\Microsoft\Microsoft SDKs\Windows
Все они были правильно установлены: значение в реестре значения CurrentInstallFolder
всегда было C:\Program Files\Microsoft SDKs\Windows\v6.0A\
. Я не мог понять, почему переменная %WindowsSdkDir%
была установлена с другим значением.
Еще больше поиска привело меня к таким местам, как this , и я почувствовал, что готов понять, как устанавливается переменная %WindowsSdkDir%
.
Мое лучшее понимание этого процесса:
Файл C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat
является одним из первых запущенных сценариев. (Кстати, вы щелкните правой кнопкой мыши и Edit
, чтобы увидеть его содержимое). Нетрудно было понять, что строка call "%~dp0bin\vcvars32.bat"
выполнена.
%~dp0bin\
интерпретируется как «каталог bin
в текущем каталоге», и, следовательно, следующее место здесь.
В этом каталоге bin
есть ожидаемый vcvars32.bat
, и он содержит только одну команду: "%VS90COMNTOOLS%vsvars32.bat"
.
Чтобы узнать, что означает %VS90COMNTOOLS%
, вы можете открыть командную строку Visual Studio (которую вы найдете в меню «Пуск» в разделе VS) и ввести echo %VS90COMNTOOLS%
. Для меня это расширяется до C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools
.
Итак, я нахожусь в файле C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vcvars32.bat
. Этот файл имеет некоторое реальное содержание, и я смог распознать, что команда @call :GetWindowsSdkDir
- это то место, где происходит действие.
Эта функция определена в этом же файле несколькими строками ниже:
:GetWindowsSdkDir
@call :GetWindowsSdkDirHelper HKLM > nul 2>&1
@if errorlevel 1 call :GetWindowsSdkDirHelper HKCU > nul 2>&1
@if errorlevel 1 set WindowsSdkDir=%VCINSTALLDIR%\PlatformSDK\
@exit /B 0
Эта функция, очевидно, зависит от второй функции в этом же файле:
:GetWindowsSdkDirHelper
@for /F "tokens=1,2*" %%i in ('reg query "%1\SOFTWARE\Microsoft\Microsoft SDKs\Windows" /v "CurrentInstallFolder"') DO (
if "%%i"=="CurrentInstallFolder" (
SET "WindowsSdkDir=%%k"
)
)
@if "%WindowsSdkDir%"=="" exit /B 1
@exit /B 0
Мы почти у цели. Я смог увидеть, как на самом деле доступны значения реестра с помощью команды reg query
, и можно было предположить, что команда возвращала ошибки и возвращалась к настройке по умолчанию.
Когда я попытался вызвать reg query
в ванильной MSDOS cmd
, я получил сообщение, что оно не было распознано.Естественно, в этот момент вы посмотрите на переменную PATH
, и там я наткнулся на это неприятное небольшое место в записи C:\windows\system32\
. Пространство было помещено туда случайно при предыдущем редактировании, представьте себе!
Постскриптум
В процессе написания этого ответа я наткнулся на этот ТАК ответ, который объясняет, как именно переменная PATH
является источником проблемы! Просто отметим, что такой ответ на самом деле указывает на сообщение в блоге здесь
В форме определения функции :GetWindowsSdkDir
можно увидеть, что она сначала смотрит в реестре значения HKLM
, а если не находит их, то смотрит значения HKCU
. Это говорит о том, что Visual Studio 2008 Express не использует записи реестра в ветвях Wow6432Node
.