Неразрешенные символы при связывании без C-runtime с VS2010 - PullRequest
3 голосов
/ 14 сентября 2011

Я работаю над проектом с ограничениями размера, поэтому я не хочу ссылаться на среду выполнения Visual Studio C.Я делаю это с помощью Static Runtime (/ MT) и флагов / NODEFAULTLIB: LIBCMT.Я выяснил большинство вещей, проверив источники времени выполнения, которые поставляются с VS.Однако компилятор по-прежнему генерирует некоторые неразрешенные внешние символы:

_chkstk: генерируется для проверки стека функции размером более 4 КБ.Могу ли я отключить это или предоставить фиктивную функцию?

__libm_sse2_pow и другие вызовы SSE: я могу избежать этого, отключив генерацию кода SSE, но я хотел бы иметь их, если это возможно.Эти символы, похоже, взяты из библиотеки Intel (libmmd.lib?).В любом случае, почему эта часть среды выполнения C?

_ftol2_sse: конвертировать float в long.Я все еще получаю это, несмотря на отключение генерации кода SSE.

_CIpow: еще одна функция Пау.Интересно, почему компилятор генерирует это вместо SEE.

Существуют ли какие-либо настройки, макросы препроцессора или прагмы, управляющие генерацией этого кода?Я также пытался использовать msvcrt.lib из Visual Studio 6.0 SP6, но некоторые функции, которые я использую, не работают с компилятором VS2010.

edit:

_chkstk можно отключить, поставив #pragma check_stack(off) перед соответствующими функциями. можно найти в источнике CRT, поставляемом с Visual Studio.

_CIpow немного сложнее.Это внутренняя версия pow, которая использует специальное соглашение о вызовах.Я не нашел способа выключить его, поэтому я сам переопределил его на ассемблере.Я получил некоторое вдохновение здесь: Как: Pow (настоящий, настоящий) в x86 .Я давно не делал ассемблер, и это первый раз, когда я делаю это на x86.Я не проверял это для всех случаев, так что никаких гарантий!Если у вас есть предложения по улучшению или вы нашли ошибку, пожалуйста, дайте мне знать.

void __cdecl _CIpow(void)
{
    // implementation of pow function as 2^(y*log2(x)). this is the 
    // intrinsic version so base and exponent are already on the fpu 
    // stack ST0 and ST1. the result is pushed to ST0.
    // note that earlier rounding for fist was set to truncate
    int temp;
    __asm {
        // values are repushed, cause fyl2x will overwrite them both
        fld     st(0)           // push ST0 to ST0
        fld     st(2)           // push ST2 (ex ST1) to ST0
        fyl2x                   // ST1 = ST1*log2(ST0), pop ST0
        fist    temp            // assumes truncate rouning
        fisub   temp            // S0 = S0 - temp
        f2xm1                   // ST0 = (2^ST0)-1
        fld1                    // push 1 to ST0
        faddp   st(1),st(0)     // ST1 = ST1 + ST0, pop ST0
        fild    temp            // push temp to ST0
        fxch                    // swap ST0 and ST1
        fscale                  // ST0 = inc exp of ST0 by ST1
        fxch                    // put reslut in ST1
        fstp    st(0)           // pop ST0
    }
}

Ответы [ 2 ]

3 голосов
/ 16 сентября 2011

Вот что мне пришлось изменить в проекте Win32 по умолчанию в VS2010:

Debug

  • C / C ++ - генерация кода - базовые проверки времени выполнения = по умолчанию
  • C / C ++ - Генерация кода - Библиотека времени выполнения = Многопоточная отладка (/ MTd)
  • Линкер - Ввод - Игнорировать определенные библиотеки по умолчанию = libcmtd.lib

Release

  • Общее - Оптимизация всей программы = Нет Оптимизация всей программы
  • C / C ++ - Оптимизация - Оптимизация всей программы = Нет
  • C / C ++ - Генерация кода - Библиотека времени выполнения = Многопоточная (/ MT)
  • Линкер - Ввод - Игнорировать определенные библиотеки по умолчанию = libcmt.lib

Пришлось сделать еще несколько вещей для обработки вещей с плавающей запятой:

  • C / C ++ - Командная строка = / QIfist (также SetFloatingPointRoundingToTruncate; см. Ссылку ниже)
  • extern "C" int _fltused = 1; // глобальный компилятор определяет для загрузки некоторые вещи с плавающей точкой

Я наткнулся на интересное сообщение в блоге о создании минималистических программ с VS, где я нашел часть этой информации; может иметь дополнительные советы, если у вас все еще есть проблемы.

Благодаря всем этим настройкам я могу скомпилировать и связать программу, которая преобразует float в long и вызывает некоторые функции pow (). Сборка выпуска составляет всего 3,5 КБ, включая встроенный манифест.

2 голосов
/ 15 сентября 2011

Я также работал над проектом, который был скомпилирован с Visual Studio (.NET 2003) без использования CRT.Более поздние версии VS были более сложными в использовании, и мы обнаружили, что не стоит взламывать, чтобы заставить его работать.

Вместо этого вы можете захотеть взглянуть на minicrt / lictiny .Google использует это в Омахе - автообновление для Chrome и Google Earth.

Вы также можете попробовать цепочку инструментов MinGW , так как это может ссылаться на MSVCRT.DLL, которая является системным компонентомне должно распространяться вашим приложением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...