记 对cmake交叉编译中的误解,和遇到的问题

记 对cmake交叉编译中的误解,和遇到的问题 日常工作在win环境下对交叉编译的需求很弱处于知道交叉编译但未使用过的状态。临时接到一个任务在windows环境vs IDE对llvm做面向arm64的交叉编译编译产出物将运行在arm64环境下。本文仅用于记录对交叉编译误解和一些解决方案。先说明一些背景和我对交叉编译的误解:【1】交叉编译中的host和targethost一般指编译机器环境比如本任务中host即为windows x64环境交叉编译中经常用到的native一般也是指hosttarget则是编译产出物的执行环境比如本任务中 target则是指arm64系统。不涉及交叉编译时一般target和host 为同一套环境以下platform即指代host或target。【2】llvm交叉编译遇到的问题llvm编译的一个重要特点就是编译期间要调用clang-tblgen和llvm-tblgen 处理td文件产生编译期间 前端、后端需要的代码inc此期间tblgen一定工作在host机器上而最终产生的编译产出物则是执行在target机器上的。如何通过cmake配置实现这一点最理想的状态就是cmake某generatorvs或者ninja能直接将tblgen描述为面向win x64的编译其他proj描述为面向arm64的编译。但实际上cmake无论是配合vs还是配合ninja都不能满足这一点换句话说CMake根本无法在初次生成阶段为同一个构建目录下的不同 project预设不同的platform架构这句话存疑希望实际有generator能做到。这也是我对交叉编译最大的误解我原以为可以通过toolchain(本质是对一系列变量setting语句)实现同一个构建目录下不同project使用不同platform做编译。而实际上cmake交叉编译并不能破除cmake对同一个构建路径下的所有projec共享相同的platform限制。交叉编译更擅长做在host机器上通过指定target platform的编译环境c_compiler/cxx_compiler/linker 甚至其更定制化的变量等来让所有的project都能获得指定target platform的编译环境。回到我的任务上在win下用vs对llvm做面向arm64的交叉编译应该是混合platform的交叉编译存疑 不知道业界称什么。有什么方案可以达到这个目的【1】做多阶段、多构建路径编译第一步先手动mkdir build_x64在build_x64下做native编译拿到host机器上可执行的native tblgen工具第二步再先手动mkdir build_arm64编译build_arm64期间调用第一步所产生的native tblgen工具处理td文件产生inc这一步需要llvm cmake支持或者修改cmake文件做支持。以上做法编译步骤会比较冗余改动代码也比较多。如果是自己开发的咪咪项目有类似需求可以考虑用这种做法但对llvm编译来说改动就太大了。【2】甚至!!! llvm有直接提供llvm_create_cross_target build_native_tool来解决以上场景中 对tblgen native编译的问题会在arm64的build过程中在一个独立的构建路径下、通过预设的cmake命令、触发对native tblgen的build通过add_custom_command做,由llvm_create_cross_target触发cmake -G ...由build_native_tool触发cmake -build ...并将arm64 build期间所需要调用的tblgen工具指向前面native build所拿到的tblgen通过这种方式丝滑解决面向arm64的编译期间 对native tblgen的编译和调用。以上做法本质也是多构建路径编译只是被llvm集成到cmake function中了不得不再次膜拜llvm架构的周到细心。附llvm_create_cross_target对native tblgen 的config方案CrossCompiler.cmake附build_native_tool对native tblgen 的build方案CrossCompiler.cmake很想知道是否还有更方便的做法比如ExternalProject来解决这个问题欢迎分享