caffe就是个阴间项目。我生气了。

Windows下的配置太恶心,根本没法用,编译出来还能加载DLL失败。

唉,不想多说了。Python也是个阴间玩意,说是说DLL加载失败,可就是打死都不说是哪个。几十年了,没人管管的吗?

我为什么不管?这是我专业吗?要是能靠这吃饭,我早去考虑这个问题了。。

总而言之,还好有人提供了工具: https://github.com/lucasg/Dependencies

这个工具可以解析pyd文件的DLL依赖,感觉和ldd很像。(但是有机率崩掉?)
虽然问题没有直接解决,但是通过这个工具可以对pyd的内部依赖进一步了解,为解决问题提供可能,

主体流程按照文档来就行,先编译Boost.Build,然后用生成的b2来编译剩余的部分。

主要是在编译Boost.Python遇到了问题。虽然在编译时传入--build-type=complete参数也包含了对Python模块的编译,但是仔细阅读文档可以发现,这个complete指的是尽可能完整,也就是说,如果某些模块编译出错了,b2会放弃编译该模块,而不是发出严重错误的警告——“反正我是尽力而为嘛”。恰好在我的情景下,Boost.Python就是其中之一。网上对于如何编译这个库的讨论很少,在StackOverflow上也只是找到了少量的讨论,感觉似乎要么是没人整这些东西,要么人人都是专家= =

后来发现在Boost的文档中提到,有一个配置文件叫user-config.jam,在这里进行Python的配置。先贴一个我的配置:

using python
    : 3.6
    : C:\\Program\ Files\\Python36\\python.exe
    : C:\\Program\ Files\\Python36\\include
    : C:\\Program\ Files\\Python36\\libs
    : <toolset>msvc
    ;

但是这个配置文件的位置有讲究,说是要放在家目录下(参见 https://boostorg.github.io/build/manual/develop/index.html#bbv2.overview.configuration )。如果在Windows下不想配置家目录,那么就需要使用--user-config=参数来显式指定配置文件。有些教程说将这个文件放在编译的根目录下也行(未经尝试)。

编译完成以后,目录结构还是保持了类似源文件的文件夹结构,因而若是要一个个手动添加库文件可以说是一项繁重的工作。这里放一段把所有动态/静态库文件提取出来,放在同一个文件夹下的Python代码片段供参考:

import shutil
import os

dest = './lib'
try:
    shutil.rmtree(dest)
except Exception as e:
    pass
os.makedirs(dest)

def explore(prefix: str):
    if prefix == './lib':
        return

    if os.path.isdir(prefix):
        entries = os.listdir(prefix)
        for entry in entries:
            explore(prefix + '/' + entry)
    elif prefix.split('.')[-1] in ['lib', 'dll'] and ('vc142-mt-x64' in prefix or 'vc142-mt-gd-x64' in prefix):
        shutil.copy2(prefix, dest)

if __name__ == '__main__':
    '''Extract all boost libraries. @Esper'''
    explore('.')

将该代码片段放在libs目录下执行,即可在名为lib的新子目录中找到所有提取的库文件。同时,对于explore函数中的某些判断条件需要进行合适的修改,比如vc版本,编译条件或者系统位数等,还请读者根据实际情况调整。

本来还想玩一下Kaldi的,结果发现门槛太高(指文档看起来比较难受,以及Windows下编译大小>20GiB),而且CUDA支持还有点问题(不知道是不是还是msvc14.25的锅)。再加上例子里给的全是Shell脚本,懒得重新看一遍,就弃坑了。

但是编译过程中遇到少许坑,记录如下:

  1. 不要使用CMake,而是使用windows文件夹中的generate_solution.pl来生成VS的解决方案;
  2. 额外扩展(比如OpenBLAS)等的文件夹结构可以参考tools目录下;
  3. Windows支持做的人估计不多,还是只支持CUDA 7。如果使用CUDA版本不是7的话,可以从自己的CUDA目录中找到一个名字类似cuda_7.0.props(比如CUDA 10.1.props)的文件,替换该文件即可;
  4. 如果使用的是官方openfstportaudio自己编译的话,可能需要修改对应props文件里的库文件位置和名字,其中portaudio可能需要按照windows/INSTALL.md中提供的网址去Steinberg下载ASIO驱动,否则编译会报错;
  5. 使用cmd运行generate-solution.pl,千万不要用MSYS!通过--vsver参数确定VS版本(格式为vs20xx,支持15、17和19三个版本),--enable-openblas使用OpenBLAS而不是Intel MKL,以及--enable-cuda提供CUDA支持。

按照官方文档,使用的是Kolla-Ansible快速配置方案。

  1. 需要一台有两个网络接口的服务器,一个配ip,不要求外网,填给network_interface;另一个不配ip,给neutron_external_interface,用于给虚拟机连接外网;
  2. sudo转化为root用户的正确姿势是sudo -i,表示以root身份登陆Shell,这样才会进行source /etc/profile的工作;
  3. 完成配置,执行precheck命令时,RabbitMQ部分可能会报错,这是因为RabbitMQ不允许有hosts记录解析到本机,到/etc/hosts中删除解析到127.0.0.1::1的记录即可解决该问题;
  4. 默认的用户名和密码在/etc/kolla/admin-openrc.sh里,执行后续操作的时候需要source这个文件;
  5. OpenStack跑起来之后,可能会出现只有英文的情况(即使在设置中将语言设置为了简体中文)。这是因为koala的horizon(OpenStack仪表盘项目的名称)编译的时候,(估计是为了缩小镜像体积)把所有的翻译都删掉了,只留下英语。解决方法是去Github上弄一份horizon项目的源码,把其中openstack_dashboard/locale文件夹使用docker cp命令复制到对应的horizondocker容器中,理论上目标位置是/usr/share/openstack-dashboard/openstack_dashboard/locale;然后在容器中使用django-admin compilemessages编译这些UI消息后,重启该容器,语言设置即可恢复正常。

在命令行使用openstack管理员操作之前,要先source含有管理员用户密码等配置信息的脚本文件。使用Ansible-Kolla方式的配置文件为/etc/kolla/admin-openrc.sh

显示已有镜像

openstack image list

添加镜像

openstack image create --public --disk-format qcow2 CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64.qcow2

重命名在网页端的显示名称(不知道为啥网页端不能直接改)

openstack image set CentOS-8-GenericCloud-8.2.2004-20200611.2.x86_64 --name 'CentOS 8'

update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.3 10
表示注册一个文件位置为/usr/bin/gcc、名叫gcc、目标文件位置为/usr/bin/gcc-4.3、自动模式下优先级为10的条目。

update-alternatives --config gcc
表示修改gcc的默认链接条目。

update-alternatives --get-selections
列出当前所有链接条目。