Фон
Я использую CL
и LINK
из командной строки для создания проекта, состоящего из собственного C ++, смешанного C ++ / CLI и безопасного C ++ / CLI. Мне нужно ориентироваться на .NET Framework 2.0-3.5, поэтому я использую набор инструментов VC90 (у меня VS2010, но я установил VS2008 C ++ Express и SDK для Windows 7 и .NET 3.5 SP1, чтобы получить полный набор инструментов VC90).
Если я попробую свой сценарий с набором инструментов VS100, он будет работать нормально, но нацелен на .NET v4.0. Если я не использую /GL
для моего собственного и смешанного кода, это работает. Я знаю об этих решениях, поэтому не предлагайте их. Я пытаюсь понять, почему это происходит.
Задача
Если я использую /GL
и /LTCG
, я получаю много следующих предупреждений в собственном коде:
xxx.cpp (###): предупреждение C4748: /GS
не может защитить параметры и локальные переменные от переполнения локального буфера, поскольку оптимизации отключены в функции
И следующая ошибка в смешанном коде:
c: \ program files (x86) \ microsoft visual studio 9.0 \ vc \ include \ vcclr.h (47): ошибка C4801: возврат по ссылке невозможен: определение возвращенного локального не найдено в базовом блоке
Второй - для PtrToStringChars из заголовочного файла Microsoft, который позволяет использовать String^
как const wchar_t*
и является функцией, которая ДОЛЖНА быть встроена (и отмечена как встроенная). «Возврат по ссылке» на самом деле не будет возвратом, если он встроен, поэтому нет ошибки.
Проблема в том, что я использую оптимизации при компиляции! Я использую стандарт /O2
, который имеет самый высокий уровень встраивания (/Ob2
) и обычно позволяет /GS
.
Сценарий
Вот мой сокращенный скрипт компиляции
set TARGET=x86
call "%VS90COMNTOOLS%\..\..\VC\vcvarsall.bat" %TARGET%
set CL=/nologo /Zl /Zi /W4 /O2 /Oy- /GL /GS /EHa /MP /D NDEBUG /D _UNICODE /D UNICODE /D INTEGRATED /Fdout\ /Foout\
set LINK=/nologo /LTCG /CLRIMAGETYPE:IJW /MACHINE:%TARGET% /SUBSYSTEM:WINDOWS,6.0 /OPT:REF /OPT:ICF /DEFAULTLIB:msvcrt.lib /DEFAULTLIB:msvcmrt.lib
set CSC=/nologo /w:4 /d:INTEGRATED /o+ /target:module
set CL_NATIVE=/c /FI"stdafx-native.h"
set CL_MIXED=/c /clr /LN /FI"stdafx-mixed.h"
set CL_PURE=/c /clr:safe /LN /GL /FI"stdafx-pure.h"
set NATIVE=a.cpp b.cpp ...
set MIXED=c.cpp d.cpp ...
set PURE=e.cpp f.cpp ...
cl %CL_NATIVE% %NATIVE%
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
cl %CL_MIXED% %MIXED%
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
cl %CL_PURE% %PURE%
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
link /LTCG /NOASSEMBLY /DLL /OUT:"out\x.netmodule" out\*.obj
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%