Windows 编译 yangfengzzz/fluid-engine-OpenVDB

我想将 OpenVDB 接入 doyubkim 的流体引擎

https://github.com/doyubkim/fluid-engine-dev

然后搜到已经有人做过这件事了

https://github.com/yangfengzzz/fluid-engine-OpenVDB

Windows 编译 yangfengzzz/fluid-engine-OpenVDB

但是我是 windows,所以想要编译他这个库还要费一点精力

cmake

首先是,要使用 vcpkg 和 cmake 搭配,要注意配置 DCMAKE_TOOLCHAIN_FILE

@echo off

cls

REM Configure a release build
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=E:/vcpkg/scripts/buildsystems/vcpkg.cmake

REM Actually build the binaries
cmake --build build/ --parallel 4

pause

然后这个仓库的 FindTBB.cmake 似乎有点问题,我就直接从 openvdb 的 cmake 文件夹里面复制所有的 FindXXX.cmake 过来了

他设置 CMAKE_MODULE_PATH 的方式似乎有点问题,直接追加 "../cmake" 的话,似乎不会转换为完整的路径。所以我就把这些都注释掉了

# list(APPEND CMAKE_MODULE_PATH "../cmake")

然后在最外层的 CMakeLists 设置 CMAKE_MODULE_PATH

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

第三方库可以找到了之后,然后是一些错误

attribute

  log_manager.cpp
  marching_cubes.cpp
E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,26): error C2059: syntax error: '(' [E:\repositor
ies\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxproj]
  (compiling source file '../../src.common/log_manager.cpp')

E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,36): error C4430: missing type specifier - int as
sumed. Note: C++ does not support default-int [E:\repositories\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxpro
j]
  (compiling source file '../../src.common/log_manager.cpp')

E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,36): error C2059: syntax error: ')' [E:\repositor
ies\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxproj]
  (compiling source file '../../src.common/log_manager.cpp')

E:\repositories\fluid-engine-OpenVDB\src.common\log_manager.cpp(81,9): error C2352: 'vox::ExceptionFactory::throwExcept
ion': a call of a non-static member function requires an object [E:\repositories\fluid-engine-OpenVDB\build\src.common\
Flex_Common.vcxproj]
  E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,43):
  see declaration of 'vox::ExceptionFactory::throwException'

E:\repositories\fluid-engine-OpenVDB\src.common\log_manager.cpp(118,9): error C2352: 'vox::ExceptionFactory::throwExcep
tion': a call of a non-static member function requires an object [E:\repositories\fluid-engine-OpenVDB\build\src.common
\Flex_Common.vcxproj]
  E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,43):
  see declaration of 'vox::ExceptionFactory::throwException'

  parallel.cpp
E:\repositories\fluid-engine-OpenVDB\src.common\parallel.cpp(14,11): error C1083: Cannot open include file: 'tbb/task_s
cheduler_init.h': No such file or directory [E:\repositories\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxproj]

  vox_exception.cpp
E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,26): error C2059: syntax error: '(' [E:\repositor
ies\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxproj]
  (compiling source file '../../src.common/vox_exception.cpp')

E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,36): error C4430: missing type specifier - int as
sumed. Note: C++ does not support default-int [E:\repositories\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxpro
j]
  (compiling source file '../../src.common/vox_exception.cpp')

E:\repositories\fluid-engine-OpenVDB\src.common\vox_exception.hpp(241,36): error C2059: syntax error: ')' [E:\repositor
ies\fluid-engine-OpenVDB\build\src.common\Flex_Common.vcxproj]
  (compiling source file '../../src.common/vox_exception.cpp')

__attribute__ 的问题,这个写法是 gcc 的,msvc 识别不了

修改为 [[]] 的形式就好了

后面知道属性只能用在定义

error C3829: attribute [[noreturn]] may only be applied to a function declaration

我就干脆把这个属性删了,不想再拆开了

tbb

然后是找不到 tbb 的头文件

看了一下才发现他没有在 CMakeLists 中包含 TBB 的头文件目录

不知道他是怎么编译通过的……

于是我给他两个目标加上了

target_include_directories(Flex_Common PUBLIC ${TBB_INCLUDE_DIRS})
target_include_directories(Flex_VDB PUBLIC ${TBB_INCLUDE_DIRS})

但是从 openvdb 复制过来的 FindTBB.cmake 里面设置的是 Tbb_INCLUDE_DIRS,有点怪

我就从 doyubkim 复制 FindTBB.cmake 过来,结果这个还找不到 tbb 包

于是还是只能用 openvdb 的 FindTBB.cmake

target_include_directories(Flex_Common PUBLIC ${Tbb_INCLUDE_DIRS})
target_include_directories(Flex_VDB PUBLIC ${Tbb_INCLUDE_DIRS})

但是仍然报错说找不到 include 目录

不知道为什么,他把这个 include path 加到了 C/C++ - All Options - Additional Options 里面了,看上去像是命令行参数一样

在这里插入图片描述

之后我才发现,似乎我的 target_include_directories 没有产生效果

但是命令行里面有这个 /external:I "E:/vcpkg/installed/x64-windows/include" 似乎也是一样的

我不知道是哪个东西引出了 /external:I "E:/vcpkg/installed/x64-windows/include",应该是配置 DCMAKE_TOOLCHAIN_FILE 导致的吧

所以这似乎不是 VS 的问题,我看了我 vcpkg 下载的 tbb,还真的没有 task_scheduler_init.h 这个文件

所以这就是 tbb 的版本问题了

搜了一下,确实是 2021 版本的 tbb 删掉了这个头文件

搜到了怎么用 vcpkg 控制版本

https://devblogs.microsoft.com/cppblog/take-control-of-your-vcpkg-dependencies-with-versioning-support/

https://learn.microsoft.com/en-us/vcpkg/consume/lock-package-versions?tabs=inspect-powershell

根据它的说法,我首先在项目根目录创建了一个 vcpkg.json

{
    "dependencies": [
        "tbb",
        "glog",
        "openvdb"
    ],
    "builtin-baseline": "3f6e8e9c09e28a0eae4b37cceb2982ca2518278c",
    "overrides": [
        {
            "name": "tbb",
            "version": "2020.02.0"
        }
    ]
}

然后我直接调用 cmake 构建,vcpkg 对我这个设置的版本没有反应

我已经安装的 tbb 是 2021.10 的,我直接用 cmake 构建,tbb 的版本并没有变化

我把 tbb 和 openvdb 卸载了,然后我再

之后我看到教程里面说,版本控制暂时不适用于通过命令行安装的包

我才知道,原来可以有不通过命令行安装的方法……?

于是我重新看了一下,发现他有一个带有 version 标志的命令行

vcpkg --feature-flags="versions" install

运行了这个命令之后,提示说我这个版本号不正确,并且给出了一些正确的版本号

于是我把 json 改成了

{
    "dependencies": [
        "tbb",
        "glog",
        "openvdb"
    ],
    "builtin-baseline": "3f6e8e9c09e28a0eae4b37cceb2982ca2518278c",
    "overrides": [
        {
            "name": "tbb",
            "version-string": "2020_U3#8"
        }
    ]
}

现在 vcpkg 确实能够识别到我设定的这个版本,但是直接运行 cmake 还是找不到

现在他似乎把东西都下载到了 vcpkg_installed 这个文件夹里面了

比如我现在关心的这个 tbb,在我 vcpkg 的安装目录里面没找到 tbb,但是在工程目录的 vcpkg_installed 里面有

现在一个明显的问题是,我该怎么让 cmake 知道他要找工程目录的这个 vcpkg_installed 文件夹里面?

之后查到,用版本控制的这个方法属于清单模式

确实已经有使用清单模式构建的教程

https://learn.microsoft.com/en-us/vcpkg/consume/manifest-mode?tabs=cmake%2Cbuild-cmake

似乎他也没做什么

但是为什么我这里就找不到包呢,之后我删了 build 重新构建,似乎就行了

所以就是要清理构建缓存的事

uint

然后是 uint 不识别的问题,这不是一个标准的写法,直接替换成 unsigned int

连接不到 Flex_Common.lib

Flex_Common 是作为共享库来生成的,现在 cmake 需要它的 lib 文件,但是实际上没有生成

LINK : fatal error LNK1104: cannot open file '..\src.common\Debug\Flex_Common.lib' [E:\repositories\fluid-engine-OpenVDB\build\src.vdb\Flex_VDB.vcxproj]

查了一下,是因为实际上这个库没有导出符号

可以设置强制导出所有符号,来获得 lib 文件

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)

但是实际上这就是代码结构的问题,为什么你没有用到共享库中的导出函数?

我查了一下,这里面的代码都没有用到 dllexport

所以我就直接改成了 STATIC

这样,终于能够正常编译了

Flex_Common Flex_VDB 两个库都改成 STATIC

单元测试

然后就是编译单元测试和人工测试

他是在代码里面 hardcode 了一个外部的路径,然后 CMakeLists 里面也是 hardcode 的外部路径

所以我把 ../external/gtest/include/gtest 替换成 gtest,把 ../external/gmock/include/gmock 替换成 gmock

然后在 vcpkg.json 里面添加这两个库

在 CMakeLists 里面添加

find_package(GTest)

CMakeLists 中把 gtest gmock 换成 GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main

然后是 Eigen3,删了源文件里面的 ../external/,CMakeLists 里面加上相关的

cg pcg 没有匹配的模板

之前把 uint 改成了 unsigned int,之后发现很多到 size_t 的类型转换的警告,所以又改成了 size_t

但是我只是在 src 里面把 unsigned int 改成 size_t,没有在单元测试里面改

才导致了这个错误

所以我重置了一下代码,只把 uint 换为 unsigned int

就不会有不匹配的情况

M_PI

在 M_PI 报错的那个源文件里面,在所有包括头文件之前定义宏

#define _USE_MATH_DEFINES

之所以在所有 include 之前定义,是为了防止头文件之间互相干扰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值