Windows говорит, что 64-битный исполняемый файл является «неподдерживаемым 16-битным приложением» - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть программа C ++, которая связывает библиотеку Google WebRT C, которая компилируется и успешно работает, когда я нацеливаюсь на 32-разрядную версию, но совсем не работает, когда я нацеливаюсь на 64-разрядную версию. После некоторых проб и ошибок я создал следующую программу:

#include <media/base/adapted_video_track_source.h>

class AdaptedVideoTrackSource : rtc::AdaptedVideoTrackSource
{
public:
  void AddRef() const {}
  rtc::RefCountReleaseStatus Release() const { return rtc::RefCountReleaseStatus::kDroppedLastRef; }
  bool is_screencast() const {return false;}
  absl::optional<bool> needs_denoising() const {return false;}
  bool GetStats(webrtc::VideoTrackSourceInterface::Stats* stats) {return false;}
  webrtc::MediaSourceInterface::SourceState state() const {return webrtc::MediaSourceInterface::kLive;}
  bool remote() const {return false;}
};

int main() {
  AdaptedVideoTrackSource source;
}

Эта программа завершается с ошибкой: enter image description here Если я удаляю суперкласс, программа работает нормально.

Как именно я могу отладить такую ​​проблему? Я в растерянности, так как не могу точно отладить программу. Похоже, что dumpbin думает, что моя библиотека webrt c в порядке, но для моего исполняемого файла написано warning LNK4048: Invalid format file; ignored.

В процессе сборки много шагов, и я не думаю, что смогу поместить их все здесь. Я использую CMake с ExternalProject_Add для загрузки и сборки webrt c. Я создаю make-файлы Ninja для создания своего кода. Вот правила ниндзя, используемые для ссылки на исполняемый файл.

rule CXX_EXECUTABLE_LINKER__Test
  command = cmd.exe /C "$PRE_LINK && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=$OBJECT_DIR --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~2\MIB055~1\2017\COMMUN~1\VC\Tools\MSVC\1416~1.270\bin\Hostx64\x64\link.exe /nologo $in  /out:$TARGET_FILE /implib:$TARGET_IMPLIB /pdb:$TARGET_PDB /version:0.0  $LINK_FLAGS $LINK_PATH $LINK_LIBRARIES && $POST_BUILD"
  description = Linking CXX executable $TARGET_FILE
  restat = $RESTAT

build utest\Test.exe: CXX_EXECUTABLE_LINKER__Test utest\CMakeFiles\Test.dir\main.cpp.obj | <OTHER LIBARIES> || <OTHER LIBARIES>
  FLAGS = /DWIN32 /D_WINDOWS /GR /EHsc /bigobj /Zi /Ob0 /Od /RTC1 -MTd
  LINK_FLAGS = /machine:x64 /debug /INCREMENTAL /subsystem:console
  LINK_LIBRARIES = <OTHER LIBARIES> webrtc_bundle.lib <OTHER LIBRARIES>
  LINK_PATH = -LIBPATH:D:\Folder\install64\lib
  OBJECT_DIR = utest\CMakeFiles\Test.dir
  POST_BUILD = cd .
  PRE_LINK = cd .
  TARGET_COMPILE_PDB = utest\CMakeFiles\Test.dir\
  TARGET_FILE = utest\Test.exe
  TARGET_IMPLIB = utest\Test.lib
  TARGET_PDB = utest\Test.pdb

Это закрытый код, поэтому я переименовал созданный мной исполняемый файл и заменил библиотеки non webrt c на <OTHER LIBARIES>.

Это args.gn, который я использую для сборки webrt c:

target_cpu="x64"
rtc_enable_protobuf=true
is_official_build=false
rtc_build_examples=false
rtc_include_tests=false
enable_iterator_debugging=true
is_clang=false

Кроме того, я написал свой собственный файл BUILD.gn для объединения webrt c с другими библиотеками, которые может собрать система сборки Google.

ОБНОВЛЕНИЕ

Я обнаружил, что могу вручную связать свои файлы obj и сделать совершенно хороший exe. Затем я начал изучать Makefile-ниндзя, сгенерированный CMake, и поиграться с правилами компоновщика. Я обнаружил, что если я удаляю /debug из флагов компоновщика, то все прекрасно работает. Конечно, я хочу иметь возможность отлаживать мои отладочные сборки.

1 Ответ

0 голосов
/ 27 февраля 2020

Я пошел дальше и попытался начать сборку моего проекта с помощью clang-cl и lld-link, что обеспечило немного больше диагностики c. Я начал получать предупреждения о связывании разных версий библиотеки времени выполнения. MSVC_RUNTIME_LIBRARY был установлен правильно, и у меня был флаг / MTd в CMAKE_CXX_FLAGS и CMAKE_LINKER_FLAGS, но при запуске ниндзя с подробной настройкой я мог видеть, что за моими флагами следовал / MDd, который перезаписывал предыдущую настройку времени выполнения. В конце концов я добавил / MTd к CMAKE_CXX_FLAGS_DEBUG и CMAKE_CXX_FLAGS_RELEASE, и теперь это последний флаг времени выполнения в командах компилятора и ссылки, и с тех пор у меня не было этой проблемы.

...