MinGW 编译 2D物理引擎库 Box2D

C/C++第三方开源库的介绍和相关讨论
头像
paktc
渐入佳境
渐入佳境
帖子: 52
注册时间: 2016年07月21日 20:34
拥有现金: 锁定
储蓄: 锁定
Has thanked: 6 times
Been thanked: 5 times
联系:

MinGW 编译 2D物理引擎库 Box2D

帖子 #1 paktc » 2016年11月20日 08:50

环境 Win7 64
MinGW / gcc version 6.1.0

主页:http://box2d.org/

我所下载的版本已经上传到网盘:http://pan.baidu.com/s/1hrQxZRQ

目录结构
Box2D-master 下有两个目录,Contributions (这个暂时不管) 和 Box2D

而Box2D下又分多个目录,

    \Box2D-master\Box2D\Box2D
    \Box2D-master\Box2D\Build
    \Box2D-master\Box2D\Documentation
    \Box2D-master\Box2D\glew
    \Box2D-master\Box2D\glfw
    \Box2D-master\Box2D\HelloWorld
    \Box2D-master\Box2D\imgui
    \Box2D-master\Box2D\Testbed
其中 \Box2D-master\Box2D\Box2D 才是主要的库代码
Documentation 是文档,
Testbed 是演示程序项目文件,
glew、glfw、imgui 都是 Testbed 编译时需要用到的库。

所以单独编译 Box2D 的话,以下两句就够了。和 Box2D 无关的错误可以无视

$ cmake -G "MinGW Makefiles" .
$ make

关于各种错误的修改尝试请看2楼(还是不要浪费时间了),

演示程序 - Testbed 的手动编译方法请看3楼 MinGW g++ 单独编译 Box2d 示例程序 Testbed

头像
paktc
渐入佳境
渐入佳境
帖子: 52
注册时间: 2016年07月21日 20:34
拥有现金: 锁定
储蓄: 锁定
Has thanked: 6 times
Been thanked: 5 times
联系:

MinGW 编译 2D物理引擎库 Box2D 笔记

帖子 #2 paktc » 2016年11月20日 08:51

此楼尝试 cmake + mingw 编译整个项目,以 testbed 项目编译失败告终

根据以往的经验

cmake -G "MinGW Makefiles" .

出现好几个问题

You have called ADD_LIBRARY for library glfw without any source files. This typi
cally indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error at Testbed/CMakeLists.txt:84 (add_executable):
Cannot find source file:

Framework/imgui.h


Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx

CMake Error: Cannot determine link language for target "glfw".
CMake Error: CMake can not determine linker language for target: glfw


先尝试解决 glfw 相关的两个问题:
    找到 Box2D-master\Box2D\glfw\CMakeLists.txt

    搜索ADD_LIBRARY,跳到 60 行:

    原因是 ${glfw_SOURCES} 未定义,再往前探索,这一段:

      Code: [全选] [展开/收缩] [Download] (Untitled.cmake)
      1. if (_GLFW_COCOA)
      2.     set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h iokit_joystick.h
      3.                      posix_tls.h)
      4.     set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m
      5.                      cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c)
      6. elseif (_GLFW_WIN32)
      7.     set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h
      8.                      winmm_joystick.h)
      9.     set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c
      10.                      win32_tls.c win32_window.c winmm_joystick.c)
      11. elseif (_GLFW_X11)
      12.     set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
      13.                      linux_joystick.h posix_time.h posix_tls.h)
      14.     set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
      15.                      xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c)
      16. elseif (_GLFW_WAYLAND)
      17.     set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
      18.                      posix_time.h posix_tls.h xkb_unicode.h)
      19.     set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
      20.                      linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c)
      21. elseif (_GLFW_MIR)
      22.     set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
      23.                      posix_time.h posix_tls.h xkb_unicode.h)
      24.     set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c
      25.                      linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c)
      26. endif()
    猜测是 _GLFW_WIN32 分支下的代码块没有执行,把 if - endif 语句块整个去掉,留下:

      Code: [全选] [展开/收缩] [Download] (Untitled.cmake)
      1. set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h
      2.                  winmm_joystick.h)
      3. set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c
      4.                  win32_tls.c win32_window.c winmm_joystick.c)
    再次cmake,提示:

    CMake Error at glfw/CMakeLists.txt:40 (add_library):
    Cannot find source file:

    /src/glfw_config.h

    Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
    .hxx .in .txx

    原因:

      Code: [全选] [展开/收缩] [Download] (Untitled.cmake)
      1. set(common_HEADERS internal.h
      2.                    "${GLFW_BINARY_DIR}/src/glfw_config.h"
      3.                    "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
      4.                    "${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
    这3个路径明显不存在,改为

      Code: [全选] [展开/收缩] [Download] (Untitled.cmake)
      1. set(common_HEADERS internal.h
      2.                    "./glfw_config.h"
      3.                    "./glfw3.h"
      4.                    "./glfw3native.h")

这个时候库已经能用了,第二个问题是关于示例程序 Testbed 项目下的错误提示
CMake Error at Testbed/CMakeLists.txt:84 (add_executable):
Cannot find source file: Framework/imgui.h

    打开 Box2D-master\Box2D\Testbed\CMakeLists.txt

      Code: [全选] [展开/收缩] [Download] (Untitled.cmake)
      1. # Define the framework files.
      2. set(Testbed_Framework_SRCS
      3.     Framework/DebugDraw.cpp
      4.     Framework/DebugDraw.h
      5.     Framework/imgui.h
      6.     Framework/imgui.cpp
      7.     Framework/Main.cpp
      8.     Framework/RenderGL3.cpp
      9.     Framework/RenderGL3.h
      10.     Framework/Test.cpp
      11.     Framework/Test.h
      12. )
    原因是 Framework 目录下根本没有 imgui.h imgui.cpp 等文件,将 Box2D-master\Box2D\imgui 下的文件复制到
    Framework 目录下(或者修改上面的路径),注意:RenderGL3.cpp,RenderGL3.h 这两项文件名也不对,应改为
    Framework/imgui_impl_glfw_gl3.cpp, Framework/imgui_impl_glfw_gl3.h

    make,1%-90% 没问题,卡在最后一步也是够呛

    [ 91%] Linking CXX executable Testbed.exe
    CMakeFiles\Testbed.dir/objects.a(imgui.cpp.obj):imgui.cpp:(.text+0x56ab): undefi
    ned reference to `ImDrawList::Clear()'

    后面有大量类似的错误,通过 grep 工具查到 ImDrawList::Clear() 位于image_draw.cpp,应该是编译链接部分出了问题,
    找到 cmakefiles\link.txt
    C:\MinGW\bin\g++.exe 后面插入 ./Framework/imgui_draw.cpp
    再次 make

    In file included from ./Framework/imgui.h:12:0,
    from ./Framework/imgui_draw.cpp:15:
    ./Framework/imconfig.h:33:33: fatal error: Box2D/Common/b2Math.h: No such file o
    r directory
    #include <Box2D/Common/b2Math.h>

    C:\MinGW\bin\g++.exe 后面插入 -I../

    再次 make,提示

    CMakeFiles\Testbed.dir/objects.a(imgui.cpp.obj):imgui.cpp:(.text+0x25c5f): undef
    ined reference to `ImmGetContext'
    CMakeFiles\Testbed.dir/objects.a(imgui.cpp.obj):imgui.cpp:(.text+0x25c8d): undef
    ined reference to `ImmSetCompositionWindow'


    C:\MinGW\bin\g++.exe 命令的最后追加 -limm32

    1. C:\MinGW\bin\g++.exe ../glfw/wgl_context.c ./framework/imgui_draw.cpp -I../  -Wl,--whole-archive CMakeFiles\Testbed.dir/objects.a -Wl,--no-whole-archive  -o Testbed.exe -Wl,--out-implib,libTestbed.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\Testbed.dir\linklibs.rsp -limm32
后来也还是各种问题,弃 :sweating2 ,手动编译请看3楼

头像
paktc
渐入佳境
渐入佳境
帖子: 52
注册时间: 2016年07月21日 20:34
拥有现金: 锁定
储蓄: 锁定
Has thanked: 6 times
Been thanked: 5 times
联系:

MinGW g++ 单独编译 Box2d 示例程序 Testbed

帖子 #3 paktc » 2016年11月20日 11:25

MinGW g++ 单独编译 Box2d 示例程序 Testbed

在1楼的基础上继续编译 Testbed 演示程序,box2d 静态库位于 Box2D-master\Box2D\Box2D\libBox2D.a
考虑到2楼因项目自带的 glfw 引起的各种编译失败,所以建议 glew 和 glfw 库单独到官网下载编译,
配置过程参考:MinGW+OpenGL+freeglut+glew+glfw 环境配置

进入 Box2D-master\Box2D\Testbed\Framework
g++ 编译指令

g++ -std=c++11 -o testbed.exe Main.cpp imgui.cpp imgui_demo.cpp imgui_draw.cpp ^
imgui_impl_glfw_gl3.cpp DebugDraw.cpp test.cpp ../Tests/TestEntries.cpp ^
-I. -I../../ -L../../box2d/ ^
-ID:\Lib\glfw-3.1.1\include ^
-LD:\Lib\glfw-3.1.1\lib ^
-ID:\Lib\glew-2.0.0\include ^
-LD:\Lib\glew-2.0.0\lib ^
-lglew32 -lglfw3 -lopengl32 -lbox2d -lgdi32 -limm32

我也实在懒得写出错和修改的过程,概括一下,-lgdi32 和 -limm32 等大部分链接参数都是根据错误提示逐个追加上去的,
imgui 库比较简单,全部源文件 和 main.cpp 叠在一起编译。缺什么补什么。

编译无误,终端执行 testbed.exe 提示:
testbed.exe - 系统错误
无法启动此程序,因为计算机中丢失 glew32.dll

找到 glew32.dll 复制到运行环境,再次执行,弹窗,终端提示:

OpenGL 4.5.0 NVIDIA 353.62, GLSL 4.50 NVIDIA
Assertion failed!

Program: C:\Users\Vulkan\Desktop\box2d comp1\Box2D\Testbed\Framework\testbed.exe

File: imgui_draw.cpp, Line 1171

Expression: 0

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

找到对应文件位置

    Code: [全选] [展开/收缩] [Download] (Untitled.cpp)
    1. ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
    2. {
    3.     int data_size = 0;
    4.     void* data = ImLoadFileToMemory(filename, "rb", &data_size, 0);
    5.     if (!data)
    6.     {
    7.         IM_ASSERT(0); // Could not load file.
    8.         return NULL;
    9.     }
通过 grep 往上追溯:

$ grep -R "AddFontFromFileTTF" *
Framework/Main.cpp: ImGui::GetIO().Fonts->AddFontFromFileTTF(fontPath, 15.f);

$ grep -R "fontPath" *
Framework/Main.cpp: const char* fontPath = "../Data/DroidSans.ttf";

原因是未找到对应字体文件,将 Box2D-master\Box2D\Build\Data 目录复制到 Box2D-master\Box2D\Testbed

运行程序:


回到 “扩展库”

在线用户

用户浏览此论坛: 没有注册用户 和 1 访客