Как передать параметры компоновщика в `cl` через командную строку MSVS 2017 x64? - PullRequest
0 голосов
/ 08 октября 2018

У меня есть небольшая программа, которую я хочу выполнить через командную строку.Я запускаю его изнутри IDE, и он работает нормально.Я копирую всю команду компиляции и вставляю ее в командную строку MSVS, и получаю неразрешенные ошибки компоновщика символов (я делал это раньше на некоторых программах, которые не требовали передачи опций компоновщика).

У меня естьпрочитайте из документации, которую мне нужно указать /link linker-options (из здесь ).Но когда я это делаю, я получаю другие ошибки.Затем, в соответствии с инструкциями, я отправил сюда , в котором должно быть указано, как мне указать параметры компоновщика.Но это не так, это просто справка из них для link.exe.Нужно ли передавать cl команду на link.exe, нужно ли ее выполнять после cl?Я тоже не могу найти пример.

Просто для тестирования простая программа main.cpp выглядит следующим образом:

#include <iostream>
#include <Windows.h>
#include <string>

int main()
{
    DWORD pid;
    HWND hwnd = FindWindow(0, L"Calculator");
    GetWindowThreadProcessId(hwnd, &pid);
    if (hwnd) {
        std::cout << "Window is open, id = " << pid;
    }
    else {
        std::cout << "Window not found" << '\n';
    }
    system("Pause");
}

Она правильно работает внутри IDE.Теперь, как я уже упоминал, я копирую полные команды из раздела компилятора MSVS 2017: /JMC /permissive- /we"4239" /GS /Zc:rvalueCast /W3 /Zc:wchar_t /ZI /Gm- /Od /Fd"x64\Debug\vc141.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++17 /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\GetProcessByName.pch" /diagnostics:classic

и компоновщика: /OUT:"J:\nik\Documents\Visual_Studio_Projects\GetProcess\x64\Debug\GetProcessByName.exe" /MANIFEST /NXCOMPAT /PDB:"J:\nik\Documents\Visual_Studio_Projects\GetProcess\x64\Debug\GetProcessByName.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /INCREMENTAL /PGD:"J:\nik\Documents\Visual_Studio_Projects\GetProcess\x64\Debug\GetProcessByName.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\GetProcessByName.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1

и, как сказал Майк, я объединяю их следующим образом cl [compile-options] main.cpp /link [linker-options] и выполните эту команду из каталога, где находится main.cpp.

Вывод: c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.1 5.26726\include\xlocale(319): warning C4530: C++ exception handler used, but unw ind semantics are not enabled. Specify /EHsc C:\Users\nik\documents\Visual_Studio_Projects\GetProcess\GetProcessByName\m ain.cpp : fatal error C1083: Cannot open compiler generated file: 'x64\Debug" /E Hsc /nologo /Fox64\Debug".asm': Invalid argument

Как правильно "передать" / указать параметры компоновщика для сборки программы из командной строки и ее запуска?

1 Ответ

0 голосов
/ 11 октября 2018

Ошибка, которую вы видите, является ошибкой разбора оболочки в опциях компиляции.Таким образом, команда не доходит до фактической компиляции, не говоря уже о связывании, и если на самом деле будут какие-то проблемы, возникающие из-за ваших опций связывания, вопрос не показывает нам, что они собой представляют.

Ошибка разбора, которую мы видим, вызвана параметром:

/Fa"x64\Debug\"

Документация /Fa предусматривает, что при использовании формы:

/Fa directory\

,чтобы указать выходной каталог для списков сборок, должен присутствовать конечный \, чтобы отличать эту форму опции от:

/Fa filename

Вы сделали это, и поместили каталогимя в кавычках - "x64\Debug\".

Когда оболочка Windows (cmd), с которой вы выполняете вашу команду, анализирует командную строку, она обрабатывает \ в цитате "..." как escape символ.

Таким образом, завершающий \ избегает закрытия " из "x64\Debug\" и параметра directory\ из /Fa продолжается с помощью последующих параметров командыпока, наконец, сотрудничествоmpiler идентифицирует форму:

/Fa filename

и безуспешно пытается открыть список сборок с именем:

'x64\Debug" /E Hsc /nologo /Fox64\Debug".asm'

Эту ошибку синтаксического анализа можно избежать любым из следующих способов:

Избегайте обратной косой черты в указанных путевых именах

Измените:

/Fa"x64\Debug\"

на:

/Fa"x64\\Debug\\"

и аналогично для других путейв параметрах командной строки.

Удалите кавычки

Измените:

/Fa"x64\Debug\"

на:

/Fax64\Debug\

Цитатыобходные пути нужны только в том случае, если в путевых именах есть встроенные пробелы, так что оболочка будет анализировать одну строку вместо двух или более.У вас нет встроенных пробелов ни в одном из имен путей ни в одном из параметров командной строки, поэтому вы можете удалить кавычки из всех них.

Используйте / вместо \ какразделитель пути

Измените:

/Fa"x64\Debug\"

на:

/Fa"x64/Debug/"

и аналогично для других путей в командной строке.Windows - единственная операционная система, которая использует \ в качестве разделителя пути.Другие используют /, и Windows приняла оба в последних версиях.

Если это приводит к какой-либо визуальной путанице между /, используемым в качестве разделителя пути ("x64/Debug/") и /, используемым в качестве опции-prefix (/Fa), cl также позволит вам использовать опции в стиле Unix, например, -Fa вместо /Fa.

И, конечно, вы также можете удалить кавычки и используйте / в качестве разделителя пути.

Если вы используете одно из этих решений только , чтобы исправить ошибку разбора в:

/Fa"x64\Debug\"

тогда та же самая ошибка синтаксического анализа будет вызвана следующей опцией:

/Fo"x64\Debug\"

Поэтому примените выбранное решение последовательно ко всей командной строке.

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