Windows 表示 64 位可执行文件是 "Unsupported 16-Bit Application"
Windows says 64-bit executable is "Unsupported 16-Bit Application"
我有一个 C++ 程序 links Google 的 WebRTC 库,当我以 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;
}
此程序因以下错误而失败:
如果我删除超级 class 程序运行正常。
我该如何调试这样的问题?我很茫然,因为我不能完全调试程序。 dumpbin 似乎认为我的 webrtc 库很好,但对我的可执行文件说 warning LNK4048: Invalid format file; ignored
。
构建过程中有很多步骤,我想我不能把它们都放在这里。我使用带有 ExternalProject_Add 的 CMake 下载和构建 webrtc。我生成 Ninja makefile 来构建我的代码。这是用于 link exe 的忍者规则。
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\bin0183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\bin0183~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~2\MIB055~117\COMMUN~1\VC\Tools\MSVC16~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
它是私有代码,所以我重命名了我构建的可执行文件并将非 webrtc 库替换为 <OTHER LIBARIES>
。
这是我用来构建 webrtc 的 args.gn:
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 文件来将 webrtc 与 Google 的构建系统可以构建的其他库捆绑在一起。
更新
我发现我可以手动 link 我的 obj 文件并制作一个非常好的 exe。然后我开始研究由 CMake 生成的 Ninja Makefile 并使用 linker 规则。我发现如果我从 linker 标志中删除 /debug
那么一切都会很好。当然,我希望能够调试我的调试版本。
我继续尝试使用 clang-cl 和 lld-link 开始构建我的项目,这提供了更多的诊断输出。我开始收到有关 linking 不同版本的 运行 时间库的警告。 MSVC_RUNTIME_LIBRARY 设置正确,我在 CMAKE_CXX_FLAGS 和 CMAKE_LINKER_FLAGS 中有 /MTd 标志,但是通过 运行ning ninja 和详细设置,我可以看到我的标志后面是/MDd 覆盖了之前的 运行 时间设置。最后,我将 /MTd 附加到 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE,现在它是编译器和 link 命令中的最后一个 运行time 标志,从那以后我就没有遇到过这个问题.
我有一个 C++ 程序 links Google 的 WebRTC 库,当我以 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;
}
此程序因以下错误而失败:
我该如何调试这样的问题?我很茫然,因为我不能完全调试程序。 dumpbin 似乎认为我的 webrtc 库很好,但对我的可执行文件说 warning LNK4048: Invalid format file; ignored
。
构建过程中有很多步骤,我想我不能把它们都放在这里。我使用带有 ExternalProject_Add 的 CMake 下载和构建 webrtc。我生成 Ninja makefile 来构建我的代码。这是用于 link exe 的忍者规则。
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\bin0183~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\bin0183~1.0\x64\mt.exe --manifests $MANIFESTS -- C:\PROGRA~2\MIB055~117\COMMUN~1\VC\Tools\MSVC16~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
它是私有代码,所以我重命名了我构建的可执行文件并将非 webrtc 库替换为 <OTHER LIBARIES>
。
这是我用来构建 webrtc 的 args.gn:
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 文件来将 webrtc 与 Google 的构建系统可以构建的其他库捆绑在一起。
更新
我发现我可以手动 link 我的 obj 文件并制作一个非常好的 exe。然后我开始研究由 CMake 生成的 Ninja Makefile 并使用 linker 规则。我发现如果我从 linker 标志中删除 /debug
那么一切都会很好。当然,我希望能够调试我的调试版本。
我继续尝试使用 clang-cl 和 lld-link 开始构建我的项目,这提供了更多的诊断输出。我开始收到有关 linking 不同版本的 运行 时间库的警告。 MSVC_RUNTIME_LIBRARY 设置正确,我在 CMAKE_CXX_FLAGS 和 CMAKE_LINKER_FLAGS 中有 /MTd 标志,但是通过 运行ning ninja 和详细设置,我可以看到我的标志后面是/MDd 覆盖了之前的 运行 时间设置。最后,我将 /MTd 附加到 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE,现在它是编译器和 link 命令中的最后一个 运行time 标志,从那以后我就没有遇到过这个问题.