Android Studio 3.2.1 上 vuh 库使用的例子,首先使用 基于Vulkan的GPGPU计算框架Vuh 编译出 Android 版本的动态库,然后依照如下步骤建立工程。
Python - os.walk忽略隐藏文件
Python中进行文件夹遍历的时候,使用os.walk是非常方便的,但是os.walk会把隐藏文件一起遍历,我们有时候需要忽略隐藏文件,可以用如下方法忽略隐藏文件以及文件夹
|
1 2 3 4 5 6 7 8 9 10 |
import os path = '.' for root, dirs, files in os.walk(path): files = [f for f in files if not f[0] == '.'] dirs[:] = [d for d in dirs if not d[0] == '.'] # use files and dirs for file_name in files: print(os.path.join(root, file_name)) |
参考链接
macOS Mojave(10.14.2)配置OpenVPN软件Tunnelblick 3.7.8(客户端)
macOS Mojave (10.14.2)配置连接在OpenVPN服务器实现加密上网或者翻墙。这里我们使用在Tunnelblick 3.7.8实现我们需要的功能。继续阅读macOS Mojave(10.14.2)配置OpenVPN软件Tunnelblick 3.7.8(客户端)
使用ccache加速编译Android NDK项目
如果使用cmake构建项目,配置如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# macOS `brew install ccache` ubuntu `apt-get install ccache` $ export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk-bundle $ cmake .. \ -DNDK_CCACHE=ccache \ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_ABI="armeabi-v7a" \ -DCMAKE_BUILD_TYPE=Release \ -DANDROID_STL=c++_static \ -DANDROID_NATIVE_API_LEVEL=android-24 \ -DANDROID_TOOLCHAIN=clang $ make -j4 |
也就是定义NDK_CCACHE=ccache。
如果使用ndk-build构建项目,配置如下:
|
1 2 3 4 5 6 7 |
# macOS `brew install ccache` ubuntu `apt-get install ccache` $ export NDK_CCACHE=ccache $ export USE_CCACHE=1 $ ndk-build |
也就是增加两个环境变量。
不指定缓存目录的情况下,缓存文件的目录一般在当前用户名下的.ccache目录下,时间长了,可能会产生很多的缓存文件,需要定时清理,当然也可以限制缓存的最大大小,让ccache根据需要进行淘汰。
参考链接
macOS Mojave(10.14.2)系统上编译LunarG/VulkanTools工程的Android版本
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
$ cd ~ $ git clone https://github.com/LunarG/VulkanTools.git $ cd VulkanTools $ cd build-android $ export ANDROID_SDK_HOME=~/Library/Android/sdk $ export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk-bundle # 当前的版本需要Android SDK 23.0.0,但是需要Java 11以下版本的Java才能执行SDK里面的sdkmanager # 显示可以安装的Java版本号信息,需要检出这个内容 $ brew tap caskroom/versions $ brew search "java*" ==> Formulae app-engine-java javarepl libreadline-java google-java-format jslint4java ==> Casks charles-applejava java-beta netbeans-java-se eclipse-java java6 oracle-jdk-javadoc eclipse-javascript java8 yourkit-java-profiler java netbeans-java-ee ==> Did you mean to perform a regular expression search? Surround your query wit # 可以看到上面存在Java8可以安装,我们安装Java8 $ brew cask install java8 # 指定默认的Java版本 $ export JAVA_HOME=`/usr/libexec/java_home -v 1.8` $ $ANDROID_SDK_HOME/tools/bin/sdkmanager --update # 目前的代码需要android-23的SDK $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "platforms;android-23" $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "platforms;android-24" $ $ANDROID_SDK_HOME/tools/bin/sdkmanager "build-tools;24.0.3" # 可选安装 # $ANDROID_SDK_HOME/tools/bin/sdkmanager "platform-tools" "platforms;24.0.3" # 需要Android 7.0以上才支持Vulkan,因此,我们需要更高版本的编译工具 $ export PATH=$ANDROID_NDK_HOME:$ANDROID_SDK_HOME/build-tools/24.0.3/:$PATH # 启用 ccache 减少二次编译的时间 $ brew install ccache $ export NDK_CCACHE=ccache $ export USE_CCACHE=1 $ export VULKAN_HEADERS_INSTALL_DIR=./third_party/Vulkan-Headers $ bash build_all.sh # 编译完成后,执行 bash test_APK.sh 测试功能,不过话说,这个工具是做什么的,有点看不懂了 # 难不成是厂家测试驱动用的? $ bash test_APK.sh |
参考链接
- Failed to install android-sdk: “java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema”
- 使用新版android sdk tool 的 sdkmanager 安装 android sdk 组件
- Failed to run sdkmanager --list (Android SDK) with Java 9
- How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9
- Android SDK is not installed or is not configured properly, environment looks ok #3139
- Installing specific major Java JDK versions on OS X via Homebrew
- Vulkan 设置
OpenCL代码编译成Vulkan代码的工具clspv
最近接到个任务,就是把OpenCL的.cl代码编译成Vulkan程序。
使用Google开源的工具clspv实现这个功能即可。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ git clone https://github.com/google/clspv.git $ cd clspv $ python utils/fetch_sources.py $ mkdir build $ cd build $ cmake .. $ make -j8 |
编译完成后,在 bin 目录下生成 clspv 这个可执行程序。
使用的时候参考项目的文档 OpenCL C 1.2 Language on Vulkan 。
只是需要注意的是,如果使用了 image 类型,比如image2d_t 则需要提供 -samplermap 这个参数,这个参数指向一个文件,文件内容可能如下:
|
1 2 |
CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST, CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR |
具体的定义跟在 OpenCL 中调用 read_image/write_image 函数时候指定的 sampler 参数一致即可。
参考链接
macOS Mojave(10.14.2) 编译KhronosGroup/SPIR项目的spir_12分支(llvm-3.2编译)
官方提供了一个名为 KhronosGroup/SPIR 的开源项目,支持OpenCL编译成SPIR代码的功能
注意: Vulkan使用SPIR-V也就是 spirv-1.0 分支,不使用此分支。本文实际上可以作为 llvm-3.2 在最新的 macOS Mojave(10.14.2) 上的编译指南。
这个工具使用的LLVM的版本非常古老,编译的时候问题多多。
这个工具在 macOS Mojave(10.14.2) 系统上使用 gcc 8.2.0 的编译流程如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
$ cd ~ $ git clone http://llvm.org/git/llvm.git llvm $ cd llvm $ git checkout --track -b release_32 remotes/origin/release_32 $ cd llvm/tools $ git clone https://github.com/KhronosGroup/SPIR clang $ cd clang # 官方要求检出 spir_12 分支,但是貌似执行完成 clone 之后,就已经在这个分支上了 # git checkout --track -b spir_12 remotes/origin/spir_12 $ cd ../.. $ mkdir build $ cd build # 只能使用GCC编译,不能使用自带的LLVM编译 $ brew install gcc $ brew unlink gcc $ brew cleanup $ brew link gcc # 指定路径 $ export PATH=$(brew --prefix)/bin:$PATH # 重定向编译工具到我们安装的GCC版本,版本号从brew的命令行中查询得到,如果安装了多个版本,请手工指定这个参数 $ export GCC_VER=$(brew list --versions | grep gcc | sed 's/\([0-9]\).*/\1/g' | tr -cd "[0-9]") $ export CC="$(brew --prefix)/bin/gcc-$GCC_VER" $ export CXX="$(brew --prefix)/bin/g++-$GCC_VER" # 链接库目录 $ export CMAKE_LIBRARY_PATH=$(brew --prefix)/lib $ export CMAKE_INCLUDE_PATH=$(brew --prefix)/include # 不能使用 GCC 引入的 ar,ranlib 这两个程序,这两个程序处理的库不能被ld正常链接,我们需要使用macOS官方提供的 ar,ranlib # 出现这个问题的原因在于macOS上的GCC并没有提供ld,其实即使提供ld也不能正常执行,原因在于macOS与GNU格式不兼容,无法正常链接 # 因此只能使用系统自带的链接工具,链接工具只认识系统自带的 ar,ranlib 转换后文件的格式 $ mv /usr/local/bin/ranlib /usr/local/bin/ranlib2 $ ln -s /usr/bin/ranlib /usr/local/bin/ranlib $ mv /usr/local/bin/ar /usr/local/bin/ar2 $ ln -s /usr/bin/ar /usr/local/bin/ar # 不能编译成动态库,原因在于这个版本的代码存在循环依赖的问题,动态库无法成功编译,只能编译成静态库 $ cmake .. -DBUILD_SHARED_LIBS=OFF # 多线程同时编译,提高编译速度 $ make -j8 |
如果使用 Xcode Version 10.1 (10B61) 编译会报告如下错误:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
[ 14%] Building CXX object lib/Analysis/CMakeFiles/LLVMAnalysis.dir/LazyValueInfo.cpp.o llvm/lib/Analysis/LazyValueInfo.cpp:998:14: error: no matching member function for call to 'insert' worklist.insert(worklist.end(), succ_begin(ToUpdate), succ_end(ToUpdate)); ~~~~~~~~~^~~~~~ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/vector:713:14: note: candidate function not viable: no known conversion from 'llvm::succ_iterator' (aka 'SuccIterator<llvm::TerminatorInst *, llvm::BasicBlock>') to 'std::__1::vector<llvm::BasicBlock *, std::__1::allocator<llvm::BasicBlock *> >::size_type' (aka 'unsigned long') for 2nd argument iterator insert(const_iterator __position, size_type __n, const_reference __x); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/vector:724:9: note: candidate template ignored: requirement '!__is_forward_iterator<SuccIterator<TerminatorInst *, BasicBlock> >::value' was not satisfied [with _InputIterator = llvm::SuccIterator<llvm::TerminatorInst *, llvm::BasicBlock>] insert(const_iterator __position, _InputIterator __first, _InputIterator __last); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/vector:734:9: note: candidate template ignored: requirement 'is_constructible<value_type, typename iterator_traits<SuccIterator<TerminatorInst *, BasicBlock> >::reference>::value' was not satisfied [with _ForwardIterator = llvm::SuccIterator<llvm::TerminatorInst *, llvm::BasicBlock>] insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/vector:705:14: note: candidate function not viable: requires 2 arguments, but 3 were provided iterator insert(const_iterator __position, const_reference __x); ^ 1 error generated. make[2]: *** [lib/Analysis/CMakeFiles/LLVMAnalysis.dir/LazyValueInfo.cpp.o] Error 1 make[1]: *** [lib/Analysis/CMakeFiles/LLVMAnalysis.dir/all] Error 2 make: *** [all] Error 2 |
上述错误产生的原因在于 macOS 官方提供的 C++ 标准库中增加了校验 is_constructible (要求模版中的类必须明确构造函数和析构函数)这个逻辑,这个功能貌似在 C++ 14 中才加入的,显然这个校验有些操之过急了。
如果编译的时候出现如下错误信息:
|
1 2 3 4 5 6 7 8 |
ld: warning: ignoring file ../../lib/libLLVMTableGen.a, file was built for archive which is not the architecture being linked (x86_64): ../../lib/libLLVMTableGen.a ld: warning: ignoring file ../../lib/libLLVMSupport.a, file was built for archive which is not the architecture being linked (x86_64): ../../lib/libLLVMSupport.a ................................... ld: symbol(s) not found for architecture x86_64 ................................... |
则说明编译的时候,没有指定使用 macOS 官方提供的 ar , ranlib ,链接这两个程序到Xcode提供的即可。
如果编译的时候出现如下错误信息:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[ 78%] Building CXX object tools/clang/lib/Sema/CMakeFiles/clangSema.dir/AnalysisBasedWarnings.cpp.o In file included from llvm/tools/clang/include/clang/Sema/DeclSpec.h:26, from llvm/tools/clang/include/clang/Sema/Sema.h:22, from llvm/tools/clang/include/clang/Sema/SemaInternal.h:18, from llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp:17: llvm/tools/clang/include/clang/Sema/AttributeList.h: In constructor 'clang::VecTypeHintAttributeList::VecTypeHintAttributeList(clang::IdentifierInfo*, clang::SourceRange, clang::IdentifierInfo*, clang::SourceLocation, clang::IdentifierInfo*, clang::SourceLocation, clang::ParsedType, clang::AttributeList::Syntax)': llvm/tools/clang/include/clang/Sema/AttributeList.h:360:75: error: use of deleted function 'clang::AttributeList::~AttributeList()' argumentKindLoc, NULL, 0, syntaxUsed), VecType(vecType) {} ^ In file included from llvm/tools/clang/include/clang/Sema/DeclSpec.h:26, from llvm/tools/clang/include/clang/Sema/Sema.h:22, from llvm/tools/clang/include/clang/Sema/SemaInternal.h:18, from llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp:17: llvm/tools/clang/include/clang/Sema/AttributeList.h:209:3 note: declared here ~AttributeList() LLVM_DELETED_FUNCTION; ^ make[2]: *** [tools/clang/lib/Sema/CMakeFiles/clangSema.dir/AnalysisBasedWarnings.cpp.o] Error 1 make[1]: *** [tools/clang/lib/Sema/CMakeFiles/clangSema.dir/all] Error 2 make: *** [all] Error 2 |
这是由于llvm/tools/clang/include/clang/Sema/AttributeList.h这个文件中的 ~AttributeList() LLVM_DELETED_FUNCTION; 这句话造成的,按理说这个析构函数不应该被调用到才对,但是代码中仍然有地方隐式调用了,我们需要做的就是去掉这行代码的 LLVM_DELETED_FUNCTION 属性即可。
|
1 2 |
# macOS 下面的sed相当的蛋痛 $ sed -i "" "s/^[ \t]*~AttributeList()[ \t]*LLVM_DELETED_FUNCTION;/~AttributeList() ;/g" llvm/tools/clang/include/clang/Sema/AttributeList.h |
编译完成后的使用方式如下:
|
1 2 3 4 5 6 |
$ cd ~ # for opencl_spir.h $ git clone https://github.com/KhronosGroup/SPIR-Tools.git $ ~/llvm/build/bin/clang -cc1 -emit-llvm-bc -triple <triple> <OpenCL compile options> -cl-spir-compile-options "<OpenCL compile options>" -include ~/SPIR-Tools/headers/opencl_spir.h -o <output> <input> |
<triple>: for 32 bit SPIR use spir-unknown-unknown, for 64 bit SPIR use spir64-unknown-unknown.- Note:
<OpenCL compile options>appears twice. The command line option-cl-spir-compile-options "<OpenCL compile options>"specifies the compile options that occur in the SPIR metadata. - <opencl_spir.h>: download opencl_spir.h from https://github.com/KhronosGroup/SPIR-Tools/blob/master/headers/opencl_spir.h
- -O: -O0 (default) is the only tested option value at the moment. It's assumed by design that all optimizations are executed by SPIR consumer.
参考链接
- Vulkan, SPIR-V and OpenCL 2.1 - Khronos Group
- OpenCl -> Vulkan: A Porting Guide - Duskborn
- KhronosGroup/SPIR
- LLVM/SPIR-V Bi-Directional Translator
- Not Compiling on macOS
- llvm @3.2 build failure
- llvm-3.2 Build Error in CodeExtractor.cpp:751
- [LLVMdev] error compiling llvm 2.9/3.2 from source on macosx (possibly stdlibc++ issue)
- 修改mac默认的gcc到自己安装的gcc
- brew list should show version numbers #245
- shell命令,从字符串中提取数字
- CMake 指定gcc编译版本
- 六、如何使用外部共享库和头文件
- Static library built for archive which is not the architecture being linked (x86_64)
- Cannot link librsvg static library #23772
- Linker problem: file was built for archive which is not the architecture being linked #11
- 题 具有非公共析构函数的类型的std :: is_constructible
- Is constructible?
- Build failure on Mac OS X: file was built for archive which is not the architecture being linked (x86_64)
- CMake Multiarchitecture Compilation
- Static library link issue with Mac OS X: symbol(s) not found for architecture x86_64
macOS Mojave(10.14.2)使用"sed -i"命令时报错'sed: 1: "xxx": extra characters at the end of l command"'
最近在 macOS Mojave(10.14.2)使用"sed -i"命令时报错,类似如下:
|
1 2 |
$ sed -i "s/^[ \t]*~AttributeList()[ \t]*LLVM_DELETED_FUNCTION;/~AttributeList() ;/g" llvm/tools/clang/include/clang/Sema/AttributeList.h sed: 1: "llvm/tools/clang/includ ...": extra characters at the end of l command |
刚刚遇到这个问题,百思不得其解。后来搜索了一下,才找到解释。
如下:
|
1 2 3 4 5 6 7 8 9 10 |
$ man sed .................................................. -i extension Edit files in-place, saving backups with the specified extension. If a zero-length extension is given, no backup will be saved. It is not recommended to give a zero-length extension when in-place editing files, as you risk corruption or partial content in situations where disk space is exhausted, etc. ................................................... |
sed -i 需要带一个字符串,用来备份源文件,这个字符串会加在源文件名后面组成备份的文件名。
如果这个字符串长度为 0,就是说是个空串,那么不备份。
|
1 |
$ sed -i "_nima" 's/xx/python/g' example.txt |
这样 sed 不仅会修改文件,并且会生成一个 example.txt_nima 的备份文件。
如果不想备份修改前的内容,可以直接给个空参数,如下:
|
1 |
$ sed -i "" 's/xx/python/g' example.txt |
所以,上面的命令,我们需要修改成如下方式:
|
1 |
$ sed -i "" "s/^[ \t]*~AttributeList()[ \t]*LLVM_DELETED_FUNCTION;/~AttributeList() ;/g" llvm/tools/clang/include/clang/Sema/AttributeList.h |
蛮扯淡的。
参考链接
OpenCL代码编译成Vulkan代码(SPIR-V)的工具
最近接到个任务,就是把OpenCL的.cl代码编译成Vulkan程序。
请使用 OpenCL代码编译成Vulkan代码的工具clspv 实现这部分功能,官方提供的转换库,目前看来暂时没办法使用。
根据官方文档,Vulkan 1.0支持OpenCL 1.0/2.1的代码直接编译成Vulkan程序。
官方提供了一个名为 KhronosGroup/SPIR 的开源项目,支持OpenCL编译成SPIR-V代码的功能(Vulkan使用SPIR-V)。
这个工具在 macOS Mojave(10.14.2) 系统上使用 Xcode Version 10.1 (10B61) 编译流程如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ cd ~ $ git clone -b khronos/spirv-3.6.1 https://github.com/KhronosGroup/SPIRV-LLVM.git llvm $ cd llvm/tools # 默认分支要求检出 spir_12 分支,但是貌似执行完成 clone 之后,就已经在这个分支上了 # git checkout --track -b spir_12 remotes/origin/spir_12 # 默认是 SPIR 的编译,Vulkan 需要 SPIR-V 两者是不同的 # Vulkan 需要编译 SPIR-V 我们需要手工切换到 spirv-1.0 分支上 $ git clone -b spirv-1.0 https://github.com/KhronosGroup/SPIR clang $ cd .. $ mkdir build $ cd build $ cmake .. # 多线程同时编译,提高编译速度 $ make -j8 |
编译完成后的使用方式如下:
|
1 2 3 4 |
$ ~/llvm/build/bin/clang -cc1 -emit-spirv -triple <triple> -cl-std=<CLversion> -include opencl.h -x cl -o <output> <input> # 反汇编查看编译结果 $ spirv-dis <output> |
<triple>: for 32 bit SPIR-V use spir-unknown-unknown, for 64 bit SPIR-V use spir64-unknown-unknown.- -D: to enable support for extension. e.g. -Dcl_khr_fp16 compile option will enable half support.
- -O: -O0 (default) is the only tested option value at the moment. It's assumed by design that all optimizations are executed by SPIR-V consumer.
比如:
|
1 2 3 4 5 |
# 编译kernel.cl 到 kernel.spir $ ~/llvm/build/bin/clang -cc1 -emit-spirv -triple=spir-unknown-unknown -cl-std=CL2.0 -include opencl.h kernel.cl -o kernel.spir # 反汇编查看编译结果 $ spirv-dis kernel.spir |
继续阅读OpenCL代码编译成Vulkan代码(SPIR-V)的工具
null值在in/not in的陷阱
背景
在某个项目统计数据时,发现以外丢掉了部分数据,仔细查找,是null值在in/not in出现了判断问题。
问题
在统计数据时,需要去除某些值,使用了not in逻辑。
select null not in ('1', '2')
这行代码,要完成的逻辑是,null 不属于 '1' 或者 '2'。
想当然认为应该返回 true,实际上返回了null,null值映射为false。
最终统计丢失了这一部分null值。
继续测试
继续测试了各种null使用in/not in的例子
该问题的详细原理可以参考这篇文章 http://www.itpub.net/thread-1325582-1-1.html
小结
null值不应该参与in/not in逻辑判断。