Неразрешенная ошибка WinMain в приложении Unicode MFC, созданном с помощью CMake с использованием Ninja

#c #cmake #mfc #ninja

#c #cmake #mfc #ninja

Вопрос:

Вот минимальный проект, который показывает эту проблему. Он состоит из двух файлов: CMakeLists.txt и hellomfc.cpp .

CMakeLists.txt

 cmake_minimum_required(VERSION 3.18)
project(HelloMFC)
set(CMAKE_MFC_FLAG 2)
add_executable(HelloMFC WIN32 hellomfc.cpp)
target_compile_definitions(HelloMFC PRIVATE _AFXDLL _UNICODE UNICODE)
  

hellomfc.cpp

 #include <afxwin.h>

class CMainFrame : public CFrameWnd {
public:
  CMainFrame() { Create(NULL, _T("Windows App")); }
};
class CApp : public CWinApp {
  CMainFrame *Frame;
  BOOL InitInstance() {
    Frame = new CMainFrame();
    m_pMainWnd = Frame;

    Frame->ShowWindow(SW_SHOW);
    Frame->UpdateWindow();

    return TRUE;
  }
};

CApp theApp;
  

В этом примере я запускаю CMake из командной строки разработчика для Visual Studio 2019.

Создание этого с использованием генератора Visual Studio 2019 работает без проблем:

 C:UsersrdeterreDocumentshello-mfcbuild-vs>cmake ..
-- Building for: Visual Studio 16 2019
-- The C compiler identification is MSVC 19.27.29111.0
-- The CXX compiler identification is MSVC 19.27.29111.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/rdeterre/Documents/hello-mfc/build-vs

C:UsersrdeterreDocumentshello-mfcbuild-vs>cmake --build .
Microsoft (R) Build Engine version 16.7.0 b89cb5fde for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

  Checking Build System
  Building Custom Rule C:/Users/rdeterre/Documents/hello-mfc/CMakeLists.txt
  hellomfc.cpp
  _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
  HelloMFC.vcxproj -> C:UsersrdeterreDocumentshello-mfcbuild-vsDebugHelloMFC.exe
  Building Custom Rule C:/Users/rdeterre/Documents/hello-mfc/CMakeLists.txt
  

Но использование генератора ninja завершается ошибкой «неразрешенный символ _WinMain @ 16»:

 C:UsersrdeterreDocumentshello-mfcbuild-ninja>cmake .. -GNinja
-- The C compiler identification is MSVC 19.27.29111.0
-- The CXX compiler identification is MSVC 19.27.29111.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.29110/bin/Hostx86/x86/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.27.29110/bin/Hostx86/x86/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/rdeterre/Documents/hello-mfc/build-ninja

C:UsersrdeterreDocumentshello-mfcbuild-ninja>cmake --build .
[1/2] Building CXX object CMakeFilesHelloMFC.dirhellomfc.cpp.obj
_WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
[2/2] Linking CXX executable HelloMFC.exe
FAILED: HelloMFC.exe
cmd.exe /C "cd . amp;amp; C:Usersrdeterrescoopappscmake3.18.1bincmake.exe -E vs_link_exe --intdir=CMakeFilesHelloMFC.dir --rc=C:PROGRA~2WI3CF2~110bin100190~1.0x86rc.exe --mt=C:PROGRA~2WI3CF2~110bin100190~1.0x86mt.exe --manifests  -- C:PROGRA~2MICROS~12019PROFES~1VCToolsMSVC1427~1.291binHostx86x86link.exe /nologo CMakeFilesHelloMFC.dirhellomfc.cpp.obj  /out:HelloMFC.exe /implib:HelloMFC.lib /pdb:HelloMFC.pdb /version:0.0 /machine:X86 /debug /INCREMENTAL /subsystem:windows  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib amp;amp; cd ."
LINK Pass 1: command "C:PROGRA~2MICROS~12019PROFES~1VCToolsMSVC1427~1.291binHostx86x86link.exe /nologo CMakeFilesHelloMFC.dirhellomfc.cpp.obj /out:HelloMFC.exe /implib:HelloMFC.lib /pdb:HelloMFC.pdb /version:0.0 /machine:X86 /debug /INCREMENTAL /subsystem:windows kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFilesHelloMFC.dir/intermediate.manifest CMakeFilesHelloMFC.dir/manifest.res" failed (exit code 1120) with the following output:
msvcrtd.lib(exe_winmain.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)
HelloMFC.exe : fatal error LNK1120: 1 unresolved externals
ninja: build stopped: subcommand failed.
  

Обратите внимание, что сборка работает с обоими генераторами при извлечении _UNICODE UNICODE определений компиляции. Однако для этого конкретного проекта требуется сборка unicode.

Комментарии:

1. Почему вы публикуете здесь? Вы не задали вопрос. Если вы чувствуете, что в CMake есть ошибка, не следует ли вам сообщить об этом по адресу gitlab.kitware.com/cmake/cmake/-/issues ?

2. К вашему сведению, в CMAKE_MFC_FLAG документации указано Enables the use of the Microsoft Foundation Classes (MFC). It should be set to 1 for the static MFC library, and 2 for the shared MFC library. This is used in Visual Studio project files. .

3. Спасибо, я сообщу об этом в CMake issue tracker. Я думаю, вопрос должен был быть «Возможно ли создать приложение unicode MFC с генератором ninja?». Что касается CMAKE_MFC_FLAG , удивительно, что он работает с Ninja в сборках, отличных от unicode, учитывая, что говорится в документации.

4. Вот ссылка на проблему CMake для справки: gitlab.kitware.com/cmake/cmake/-/issues/21202

Ответ №1:

Возможно, это ошибка в CMake, но вы можете явно указать точку входа приложения:

 # CMakeLists.txt

...

target_link_options(${PROJECT_NAME} PRIVATE "/entry:wWinMainCRTStartup")
  

Итак, это должно исправить вашу ошибку.

Комментарии:

1. Se также gitlab.kitware.com/cmake/cmake/-/issues/21202