精华内容
下载资源
问答
  • 交叉编译Clang/LLVM

    2021-03-04 20:23:22
    交叉编译Clang/LLVM 所谓交叉编译,指的是我们能够在一个平台(例如x86)编译并构建二进制文件,而在另一个平台(例如ARM)运行。编译二进制文件的机器称为主机(host),而运行生成的二进制文件的平台我们称为目标...
  • 使用clang进行交叉编译

    万次阅读 2016-12-10 21:17:12
    Cross-compilation using Clang Introduction This document will guide you in choosing the right Clang options for cross-compiling your code to a different architecture. It assumes you already know

    Cross-compilation using Clang

    Introduction

    This document will guide you in choosing the right Clang options for cross-compiling your code to a different architecture. It assumes you already know how to compile the code in question for the host architecture, and that you know how to choose additional include and library paths.

    However, this document is not a “how to” and won’t help you setting your build system or Makefiles, nor choosing the right CMake options, etc. Also, it does not cover all the possible options, nor does it contain specific examples for specific architectures. For a concrete example, the instructions for cross-compiling LLVM itselfmay be of interest.

    After reading this document, you should be familiar with the main issues related to cross-compilation, and what main compiler options Clang provides for performing cross-compilation.

    Cross compilation issues

    In GCC world, every host/target combination has its own set of binaries, headers, libraries, etc. So, it’s usually simple to download a package with all files in, unzip to a directory and point the build system to that compiler, that will know about its location and find all it needs to when compiling your code.

    On the other hand, Clang/LLVM is natively a cross-compiler, meaning that one set of programs can compile to all targets by setting the -target option. That makes it a lot easier for programmers wishing to compile to different platforms and architectures, and for compiler developers that only have to maintain one build system, and for OS distributions, that need only one set of main packages.

    But, as is true to any cross-compiler, and given the complexity of different architectures, OS’s and options, it’s not always easy finding the headers, libraries or binutils to generate target specific code. So you’ll need special options to help Clang understand what target you’re compiling to, where your tools are, etc.

    Another problem is that compilers come with standard libraries only (like compiler-rtlibcxxlibgcclibm, etc), so you’ll have to find and make available to the build system, every other library required to build your software, that is specific to your target. It’s not enough to have your host’s libraries installed.

    Finally, not all toolchains are the same, and consequently, not every Clang option will work magically. Some options, like --sysroot (which effectively changes the logical root for headers and libraries), assume all your binaries and libraries are in the same directory, which may not true when your cross-compiler was installed by the distribution’s package management. So, for each specific case, you may use more than one option, and in most cases, you’ll end up setting include paths (-I) and library paths (-L) manually.

    To sum up, different toolchains can:
    • be host/target specific or more flexible
    • be in a single directory, or spread out across your system
    • have different sets of libraries and headers by default
    • need special options, which your build system won’t be able to figure out by itself

    General Cross-Compilation Options in Clang

    Target Triple

    The basic option is to define the target architecture. For that, use -target <triple>. If you don’t specify the target, CPU names won’t match (since Clang assumes the host triple), and the compilation will go ahead, creating code for the host platform, which will break later on when assembling or linking.

    The triple has the general format  <arch><sub>-<vendor>-<sys>-<abi>, where:
    • arch = x86armthumbmips, etc.
    • sub = for ex. on ARM: v5v6mv7av7m, etc.
    • vendor = pcapplenvidiaibm, etc.
    • sys = nonelinuxwin32darwincuda, etc.
    • abi = eabignuandroidmachoelf, etc.

    The sub-architecture options are available for their own architectures, of course, so “x86v7a” doesn’t make sense. The vendor needs to be specified only if there’s a relevant change, for instance between PC and Apple. Most of the time it can be omitted (and Unknown) will be assumed, which sets the defaults for the specified architecture. The system name is generally the OS (linux, darwin), but could be special like the bare-metal “none”.

    When a parameter is not important, it can be omitted, or you can choose unknown and the defaults will be used. If you choose a parameter that Clang doesn’t know, like blerg, it’ll ignore and assume unknown, which is not always desired, so be careful.

    Finally, the ABI option is something that will pick default CPU/FPU, define the specific behaviour of your code (PCS, extensions), and also choose the correct library calls, etc.

    CPU, FPU, ABI

    Once your target is specified, it’s time to pick the hardware you’ll be compiling to. For every architecture, a default set of CPU/FPU/ABI will be chosen, so you’ll almost always have to change it via flags.

    Typical flags include:
    • -mcpu=<cpu-name>, like x86-64, swift, cortex-a15
    • -mfpu=<fpu-name>, like SSE3, NEON, controlling the FP unit available
    • -mfloat-abi=<fabi>, like soft, hard, controlling which registers to use for floating-point

    The default is normally the common denominator, so that Clang doesn’t generate code that breaks. But that also means you won’t get the best code for your specific hardware, which may mean orders of magnitude slower than you expect.

    For example, if your target is arm-none-eabi, the default CPU will be arm7tdmi using soft float, which is extremely slow on modern cores, whereas if your triple is armv7a-none-eabi, it’ll be Cortex-A8 with NEON, but still using soft-float, which is much better, but still not great.

    Toolchain Options

    There are three main options to control access to your cross-compiler: --sysroot-I, and -L. The two last ones are well known, but they’re particularly important for additional libraries and headers that are specific to your target.

    There are two main ways to have a cross-compiler:

    1. When you have extracted your cross-compiler from a zip file into a directory, you have to use --sysroot=<path>. The path is the root directory where you have unpacked your file, and Clang will look for the directories binlibinclude in there.

      In this case, your setup should be pretty much done (if no additional headers or libraries are needed), as Clang will find all binaries it needs (assembler, linker, etc) in there.

    2. When you have installed via a package manager (modern Linux distributions have cross-compiler packages available), make sure the target triple you set is alsothe prefix of your cross-compiler toolchain.

      In this case, Clang will find the other binaries (assembler, linker), but not always where the target headers and libraries are. People add system-specific clues to Clang often, but as things change, it’s more likely that it won’t find than the other way around.

      So, here, you’ll be a lot safer if you specify the include/library directories manually (via -I and -L).

    Target-Specific Libraries

    All libraries that you compile as part of your build will be cross-compiled to your target, and your build system will probably find them in the right place. But all dependencies that are normally checked against (like libxml or libz etc) will match against the host platform, not the target.

    So, if the build system is not aware that you want to cross-compile your code, it will get every dependency wrong, and your compilation will fail during build time, not configure time.

    Also, finding the libraries for your target are not as easy as for your host machine. There aren’t many cross-libraries available as packages to most OS’s, so you’ll have to either cross-compile them from source, or download the package for your target platform, extract the libraries and headers, put them in specific directories and add -I and -L pointing to them.

    Also, some libraries have different dependencies on different targets, so configuration tools to find dependencies in the host can get the list wrong for the target platform. This means that the configuration of your build can get things wrong when setting their own library paths, and you’ll have to augment it via additional flags (configure, Make, CMake, etc).

    Multilibs

    When you want to cross-compile to more than one configuration, for example hard-float-ARM and soft-float-ARM, you’ll have to have multiple copies of your libraries and (possibly) headers.

    Some Linux distributions have support for Multilib, which handle that for you in an easier way, but if you’re not careful and, for instance, forget to specify -ccc-gcc-namearmv7l-linux-gnueabihf-gcc (which uses hard-float), Clang will pick the armv7l-linux-gnueabi-ld (which uses soft-float) and linker errors will happen.

    The same is true if you’re compiling for different ABIs, like gnueabi and androideabi, and might even link and run, but produce run-time errors, which are much harder to track down and fix.

    展开全文
  • 交叉编译入门

    2020-02-25 22:15:55
    通过这篇文章了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时(编译android可用的库),清楚的了解应该传递什么参数,怎么传递参数给编译器,各个参数的意义是什么,从而为后面音视频的深入学习...

    通过这篇文章了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时(编译android可用的库),清楚的了解应该传递什么参数,怎么传递参数给编译器,各个参数的意义是什么,从而为后面音视频的深入学习编译ffmpeg做好准备工作。

    交叉编译

    交叉编译就是程序的编译环境和实际运行环境不一致,即在一个平台上生成另一个平台上的可执行代码。
    比如NDK,你在Mac、Win或者Linux上生成的C/C++的代码要在Android平台上运行,就需要使用到交叉编译了。
    通俗点说就是你的电脑和手机使用的CPU不同,所以CPU的指令集就不同,比如arm的指令集在X86上就不能运行。

    常用的编译工具链

    gcc
    GNU C编译器。原本只能处理C语言,很快扩展,变得可处理C++。(GNU计划,又称革奴计划。目标是创建一套完全自由的操作系统)

    Android在NDK r18之后彻底移除了gcc,默认使用clang编译,所以使用不同版本的ndk对ffmpeg进行交叉编译时会出现同样的脚本在旧版的ndk能编译通过,但是旧版的就不编译不通过的问题。

    笔者会在后面的学习过程中使用最新的ndk对最新版的ffmpeg进行交叉编译,并且会通过文章记录学习过程,感兴趣的同学可以持续关注。

    g++
    GNU c++编译器

    gcc和g++都能够编译c/c++,但是编译时候行为不同。

    对于gcc与g++会有以下区别:

    • 后缀为.c的源文件,gcc把它当作是C程序,而g++当作是C++程序;后缀为.cpp的,两者都会认为是c++程序

    • g++会自动链接c++标准库stl,gcc不会

    • gcc不会定义__cplusplus宏,而g++会

    clang
    clang 是一个C、C++、Object-C的轻量级编译器。基于LLVM (LLVM是以C++编写而成的构架编译器的框架系统,可以说是一个用于开发编译器相关的库)

    对比gcc,clang具有编译速度更快、编译产出更小等优点,但是某些软件在使用clang编译时候因为源码中内容的问题会出现错误。

    另外clang++也是一个编译器,clang++与clang就相当于gcc与g++的区别。

    静态库和动态库

    • 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。Linux中后缀名为”.a”。

    • 动态库则与静态库相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库。Linux中后缀名为”.so”。gcc在编译时默认使用动态库。

    总结起来就是静态库节省运行时间,动态库节省运行空间,典型的时间换空间,在开发过程中可根据情况自行选择。

    Java中在不经过封装的情况下只能直接使用动态库。

    编译器过程

    一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)、和连接(linking)才能变成可执行文件。

    我们以最简单的一个c语言程序来做一个例子:

    #include <stdio.h>
    
    int main(){
        printf("hello c world\r\n");
        return 0;
    }
    
    1. 预处理

    ​ gcc -E main.c -o main.i

    -E的作用是让gcc在预处理结束后停止编译。

    ​ 预处理阶段主要处理include和define等。它把#include包含进来的.h 文件插入到#include所在的位置,把源程序中使用到的用#define定义的宏用实际的字符串代替。

    1. 编译阶段

    ​ gcc -S main.i -o main.s

    -S的作用是编译后结束,编译生成了汇编文件。

    ​ 在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。

    1. 汇编阶段

    ​ gcc -c main.s -o main.o

    汇编阶段把 .s文件翻译成二进制机器指令文件.o,这个阶段接收.c, .i, .s的文件都没有问题。

    1. 链接阶段

    ​ gcc -o main main.s

    ​ 链接阶段,链接的是函数库。在main.c中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明。系统把这些函数实现都被做到名为libc.so的动态库。

    一步到位:

    gcc main.c -o main

    到这里我们成功的在 mac 平台生成了可执行文件,运行./main即可看到输出。试想一下我们可以将这个可执行文件拷贝到安卓手机上执行吗?

    肯定是不行的,主要原因是两个平台的 CPU 指令集不一样,根本就无法识别指令,这时候交叉编译就排上用场了。

    如果你不信可以把 main 可执行文件 push 到手机 /data/local/tmp 里面执行验证一下能否正确输出。

    也不一定必须要是/data/local/tmp这个路径,push到任意一个有可读可写可执行的权限的目录下测试均可。

    交叉编译实验

    下面我们使用ndk来对main.c进行交叉编译,看看编译后的可执行文件是不是真的能在Android上运行。

    笔者这里以armeabi为例,在mac平台上进行交叉编译。

    既然是gcc被移除了,那我们使用clang来进行交叉编译。

    1. 首先找到clang工具链
    NDK路径/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi19-clang
    
    1. 执行命令
    NDK路径/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi19-clang -o main main.c
    

    在mac平台能能正常生成可执行文件main,我们将可执行文件用push到/data/local/tmp这个目录下,然后使用adb执行./main即可看到输出hello c world。说明我们的交叉编译成功了。

    如果不使用clang,如何gcc进行交叉编译呢?

    首先也是先找到gcc的工具链

    NDK路径/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc
    

    然后执行gcc编译命令

    NDK路径/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc -o main main.c
    

    我们发现报错了
    找不到stdio.h头文件
    这种错误是说在我们编的时候编译器找不到我们引入的 stdio.h 头文件,那怎么告诉编译器 stdio.h 头文件在哪里呢? 下面知识点说明怎么指定这些报错的头文件

    我们通过参数告诉gcc工具链到那个目录下去寻找头文件,传递参数进去再次试一下

    NDK路径/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc --sysroot=NDK路径/platforms/android-21/arch-arm -isystem NDK路径/sysroot/usr/include -pie -o main main.c
    

    还是报错
    找不到types.h头文件
    因为找不到<asm/types.h>头文件,我们进去-isystem配置的头文件查找目录中发现aarch64-linux-android和arm-linux-androideabi都存在asm的子目录,所以编译器就不知道用那个了,我们再指定一下即可。

    NDK路径/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc --sysroot=NDK路径/platforms/android-21/arch-arm -isystem NDK路径/sysroot/usr/include -isystem NDK路径/sysroot/usr/include/arm-linux-androideabi -pie -o main main.c
    

    终于成功了,我们将可执行文件push到手机的/data/local/tmp这个目录下,然后使用adb执行./main即可看到输出hello c world

    在这里我们使用了clang和gcc进行了交叉编译发现clang更加的简单,直接找到工具链的路径即可进行编译了,但是gcc就比较复杂了,需要指定多个参数。

    这里需要需要我们明白每个参数的意思是什么:

    --sysroot=XX  
        使用xx作为这一次编译的头文件与库文件的查找目录,查找下面的 usr/include usr/lib目录  
    -isysroot XX  
        头文件查找目录,覆盖--sysroot ,查找 XX/usr/include  
    -isystem XX  
        指定头文件查找路径(直接查找根目录)  
    -IXX  
        头文件查找目录  
    优先级:  
        -I -> -isystem -> sysroot  (前面的优先级更高)    
    

    例如 gcc --sysroot=目录1 -isysroot 目录2 -isystem 目录3 -I目录4 main.c
    的意思就是 查找 目录1/usr/lib 的库文件、
    查找目录2 /usr/include 的头文件、
    查找 目录3 下的头文件、
    查找 目录4 下的头文件。

    -L:XX    
        指定库文件查找目录  
    -lxx.so  
        指定需要链接的库名   
    

    例如:
    gcc -L目录1 -l库名
    链接ndk的日志库:
    gcc -LC:NDK路径\platforms\android-21\arch-arm\usr\lib
    -llog -lGLESv2
    或者是
    gcc --sysroot=NDK路径\platforms\android-21\arch-arm
    -llog -lGLESv2

    生成动态库

    gcc -fPIC -shared main.c -o libTest.so
    或者
    clang -fPIC -shared main.c -o libTest.so

    即使不加-fPIC也可以生成.so文件,但是对于源文件有要求,
    因为不加fPIC编译的so必须要在加载到用户程序的地址空间时重定向所有目标地址,所以在它里面不能引用其它地方的代码。
    要想验证编译出来的so动态库能不能正常使用,通过JNI调用测试即可。

    最后如果你对音视频开发感兴趣可扫码关注,后续我们共同探讨,共同进步。

    展开全文
  • 使用 Clang 交叉编译1. 介绍2. 交叉编译问题(Cross compilation issues)3. Clang中的一般交叉编译选项(General Cross-Compilation Options in Clang)3.1 Target Triple3.2 CPU、FPU、ABI3.3 工具链选项4. 特定目标的...


    本文为译文,点击 此处查看原文。

    1. 介绍

    本文档将指导您选择正确的 Clang 选项,以便将代码交叉编译到不同的体系结构。它假定您已经知道如何为主机体系结构编译相关代码,并且知道如何选择附加的include和库路径。
    然而,这个文档不是一个“如何做”的文档,也不会帮助您设置build系统或Makefiles,也不会帮助您选择正确的 CMake 选项,等等。此外,它没有涵盖所有可能的选项,也没有包含特定架构的特定示例。对于一个具体的例子,交叉编译LLVM本身的说明可能会很有趣。
    阅读本文之后,您应该熟悉与交叉编译相关的主要问题,以及 Clang 为执行交叉编译提供了哪些主要编译器选项。

    2. 交叉编译问题(Cross compilation issues)

    在 GCC 世界中,每个主机/目标(host/target)组合都有自己的一组二进制文件、头文件、库等。因此,通常很容易下载一个包含所有文件的包,解压缩到一个目录,然后将build系统指向该编译器,该编译器将知道其位置,并在编译代码时找到所需的所有内容。

    另一方面,Clang/LLVM 本质上是一个交叉编译器,这意味着一组程序可以通过设置-target选项编译到所有目标。对于希望编译到不同平台和体系结构的程序员,对于只需要维护一个build系统的编译器开发人员,对于OS发布,只需要一组main包,这使得编译变得容易得多。

    但是,与任何交叉编译器一样,考虑到不同体系结构、操作系统和选项的复杂性,要找到头文件、库或binutils来生成目标特定的代码并不总是那么容易。因此,您需要指定选项(options)来帮助 Clang 了解您要编译的目标、工具的位置等等。

    另一个问题是编译器只附带标准库(如compiler-rtlibcxxlibgcclibm等),因此您必须找到并提供给构建系统,以及构建软件所需的每个特定于您的目标(target)的其他库。仅仅安装主机(host)的库是不够的。

    最后,并不是所有的工具链(toolchains)都是相同的,因此,并不是每个 Clang 选项都能神奇地工作。有些选项,比如--sysroot(它可以有效地更改头文件和库的逻辑根),假设所有二进制文件和库都在同一个目录中,当发行版的包管理安装了交叉编译器时,这可能不是真的。因此,对于每个特定的情况,您可以使用多个选项,并且在大多数情况下,您最终将手动设置include paths (-I)library paths (-L)

    综上所述,不同的工具链可能:

    • 特定于 host/target 或更灵活
    • 放在一个目录中,或者分散在整个系统中
    • 默认情况下有不同的库集和头文件集
    • 需要特殊的选项,这是您的构建系统无法自己解决的

    3. Clang中的一般交叉编译选项(General Cross-Compilation Options in Clang)

    3.1 Target Triple

    基本选项是定义目标体系结构。为此,使用-target <triple>。如果不指定目标,CPU 名称将不匹配(因为 Clang 假设host triple),编译将继续进行,为主机平台创建代码,稍后在汇编或链接时代码将中断。

    triple 的一般格式为<arch><sub>-<vendor>-<sys>-<abi>,其中:

    • arch = x86_64i386armthumbmips等。
    • sub = v5, v6m, v7a, v7m等。
    • vendor = pc, apple, nvidia, ibm,等。
    • sys = none, linux, win32, darwin, cuda等。
    • abi = eabi, gnu, android, macho, elf等。

    当然,sub体系结构选项对于它们自己的体系结构是可用的,所以“x86v7a”没有意义。只有在发生相关更改时才需要指定vendor,例如在PC和Apple之间。大多数情况下,可以忽略它(并且未知),这将为指定的体系结构设置默认值。system名称通常是OS (linux, darwin),但也可以像裸金属“none”一样特殊。
    当一个参数不重要时,可以省略它,或者您可以选择unknown并使用缺省值。如果您选择一个 Clang 不知道的参数,比如blerg,它将忽略并假设未知,这并不总是需要的,所以要小心。
    最后,ABI选项将选择默认的CPU/FPU,定义代码的特定行为(pc、扩展),并选择正确的库调用,等等。

    3.2 CPU、FPU、ABI

    一旦指定了目标,就到了选择要编译到的硬件的时候了。对于每种体系结构,都会选择一组默认的CPU/FPU/ABI,因此您几乎总是必须通过flag更改它。
    典型的flag包括:

    • -mcpu=<cpu-name>,如x86-64, swift, cortex-a15
      -mfpu=<fpu-name>,如SSE3, NEON,控制FP单元可用
    • -mfloat-abi=<fabi>,如控制浮点寄存器的软、硬件
      默认值通常是公分母,因此Clang不会生成中断的代码。但这也意味着您无法为特定的硬件获得最佳代码,这可能意味着速度比您预期的要慢几个数量级。

    例如,如果您的目标是arm-none-eabi,那么默认的CPU将是使用软浮点数的arm7tdmi,这在现代内核上是非常慢的,而如果您的三元组是armv7a-none-eabi,那么它将是带NEON的Cortex-A8,但是仍然使用软浮点数,这要好得多,但是仍然不是很好。

    3.3 工具链选项

    控制对交叉编译器的访问有三个主要选项:-sysroot-I-L。最后两个是众所周知的,但是对于特定于目标的附加库和头文件来说,它们尤其重要。
    有两种主要的方式获得一个交叉编译器:

    1. 当您将交叉编译器从zip文件解压缩到目录中时,必须使用--sysroot=<path>path是您解压缩文件的根目录,Clang 将查找其中包含的目录bin、lib。
      在这种情况下,您的设置应该已经基本完成(如果不需要额外的头文件或库),因为Clang将在其中找到它需要的所有二进制文件(汇编器、链接器等)。
    2. 当您通过包管理器安装(现代Linux发行版有交叉编译器包可用)时,请确保您设置的目标triple也是交叉编译器工具链的前缀。
      在本例中,Clang 将找到其他二进制文件(汇编器、链接器),但并不总是在目标头文件和库所在的位置。人们经常在Clang 中添加特定于系统的线索,但是随着事情的变化,它很可能不会发现,而不是相反。
      因此,在这里,如果手动指定include/library目录(通过-I-L),将会安全得多。

    4. 特定目标的库(Target-Specific Libraries)

    作为构建的一部分编译的所有库都将被交叉编译到目标,构建系统可能会在正确的位置找到它们。但是,通常检查的所有依赖项(如libxmllibz等)都将与主机平台匹配,而不是与目标平台匹配。
    因此,如果构建系统没有意识到您想交叉编译代码,那么它将错误地获得每个依赖项,并且编译将在构建期间失败,而不是在配置期间。

    此外,查找目标的库并不像查找主机那么容易。大多数OS的包中没有多少跨库可用,所以您必须从源代码交叉编译它们,或者下载目标平台的包,提取库和头文件,将它们放在特定的目录中,并添加-I-L指向它们。

    此外,一些库对不同的目标具有不同的依赖关系,因此,在主机中查找依赖关系的配置工具可能会将目标平台的列表弄错。这意味着在设置自己的库路径时,您的构建的配置可能会出错,您必须通过附加标志(configure、Make、CMake等)来扩充它。

    5. Multilibs

    当您希望交叉编译到多个配置时,例如hard-float-ARMsoft-float-ARM,您必须拥有库的多个副本和(可能的)头文件。

    有些Linux发行版支持Multilib,用一种更简单的方式为你处理,但是如果你不小心,例如,忘记指定-ccc-gcc-name armv7l-linux-gnueabihf-gcc(使用hard-float),Clang将选择armv7l-linux-gnueabi-ld(使用soft-float),并且将会发生链接器错误。

    如果您正在为不同的ABIs(如gnueabiandroideabi)编译,甚至可能链接并运行,但会产生运行时错误,这将更加难以跟踪和修复,那么情况也是一样的。

    展开全文
  • 我正在尝试使用Clang将C语言应用程序从Linux(64位)交叉编译为Windows(64位).我读了page on cross-compilation,这不太有帮助.作为一个简单的测试,我在test.c中有以下代码:#include int main(){puts("hello world");...

    我正在尝试使用Clang将C语言应用程序从

    Linux(64位)交叉编译为Windows(64位).我读了

    page on cross-compilation,这不太有帮助.

    作为一个简单的测试,我在test.c中有以下代码:

    #include

    int main()

    {

    puts("hello world");

    return 0;

    }

    到目前为止,我最好的猜测是clang -o test -target x86_64-win64-?ABI? test.c.但是,我不知道ABI Windows 64位使用了什么.当我使用目标三重x86_64-win64-abcdefg运行clang时,它似乎编译正常 – 也就是说,它完成没有错误并导致某些有效的二进制文件.这没有任何意义,考虑到abcdefg绝对不是一个有效的ABI.由此产生的二进制文件对于这么小的程序来说太大了,Windows似乎认为它是一个16位程序(???).反汇编它显示了对“linux”和“gnu”的引用,所以看起来Clang甚至都没有尝试为Windows编译.

    定位win32(x86_64-win32 – ??? ABI ???)会导致以下错误消息:

    test.c:1:10: fatal error: 'stdio.h' file not found

    #include

    ^

    1 error generated.

    如果我没弄错的话,这个错误是因为它不知道在哪里查找系统文件.我假设Clang确实在某处存储了Windows头文件,因为它声称能够交叉编译;但是哪里?如果没有,有什么地方我可以下载它们吗?

    是否列出了所有架构,系统和ABI的Clang支持?交叉编译页面上的列表并不全面.

    该页面还建议使用-mcpu = …,但警告表明它已过时.相反,正如警告所建议的那样,我尝试了-mtune = x86_64.这似乎没有效果.考虑到目标三元组中指定的体系结构,这是否是必要的?

    我已经看到一些文献表明我需要lld,LLVM的实验连接器.是这样的吗?我有一些问题编译lld,并希望尽可能避免它.

    展开全文
  • 一、编译原因 公司项目需要,故编译安卓系统的boost库1.66.0。最开始考虑到原有boost版本,采用NDK16b中gcc编译器先后编译了armv7、armv8a架构下的boost。但在随后的Android Studio界面开发中,编译的boost库在...
  • 1、使用交叉编译,在PC上编译ARM程序 2、开发使用VSCode + clangd插件,同时PC机器上安装了llvm,有clangd和clang-tidy等套件 3、CMakeLists.txt里设置了set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 4、clangd插件...
  • CMAKE-DEMO 这里应该不会在维护了,后续更新请移步: cmake 学习 生成工程 cmake -D[宏名称]=[宏值] -S [源码目录] -B [生成目录] -G [目标工程(Unix Makefiles...)] -A [附加选项(Win32/x64)] -T [工具集...编译
  • wclang:在LinuxUnix上使用clang轻松交叉编译Windows源代码
  • 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数。 clang: clang 是一个C、C++、Object-C的轻量级编译器。基于LLVM(LLVM是以C++编写而成的构架编译器的框架...
  • 由于ffmpeg和NDK都是在不断进行迭代的,比如说NDK在r18之后之后彻底移除了gcc(包含r18版本),ffmpeg在4.o版本开始也针对Android平台的交叉编译默认使用clang编译,但是网上的很多资料都是使用gcc编译的。...
  • URL_LLVM="https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz" URL_GCC_LINARO="http://releases.linaro.org/components/to
  • LLVM-Clang编译器安装和使用

    万次阅读 2019-08-22 17:31:09
    常规的一个编译器分为前端、优化器和后端,LLVM编译器也不例外,Clang就是属于一个编译器的前端部分,LLVM属于优化器和后端,当然LLVM也可以支持其他类型的前端,比如GCC前端编译器。 Clang的安装 apt安装 本文...
  • 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数。 clang clang 是一个C、C++、Object-C的轻量级编译器。基于LLVM (LLVM是以C++编写而成的构架编译器的框架系统...
  • 转自: 因为原作者写的非常精简,故仅能做一个参考而已。...第一步:用gcc编译clang 1. 下载llvm+clang最新版本。具体见http://clang.llvm.org/get_started.html 2. mkdir build_with_gcc cd build_with_gc
  • Building on: linux-g++ (x86_64, CPU features: mmx sse sse2) Building for: linux-aarch64-gnu-g++ (arm64, CPU features: neon) Target compiler: gcc 6.3.1 Configuration: cross_compile use_gold_linker ...
  • 了解c/c++编译器的基本使用,能够在后续移植第三方框架进行交叉编译时,清楚的了解应该传递什么参数。 clang clang 是一个C、C++、Object-C的轻量级编译器。基于LLVM (LLVM是以C++编写而成的构架编译器的框架系统,...
  • 这个python脚本旨在最小程度地编译和链接Cargo二进制文件,以便在无法进行交叉编译的新平台上自举。 我专门写这篇文章是为了在上引导Cargo。 Bitrig是OpenBSD的一个分支,它使用clang / clang ++和其他BSD许可的工具...
  • Windows交叉编译工具链的Windows SDK文件 从17763.132.181022-1834.rs5_release_svc_prod1_WindowsSDK.iso提取。 笔记: 删除了对静态链接调试的支持,并发布了通用CRT库,因为它使SDK二进制文件的大小减少了50%...
  • 很多时候,对于C++软件工程师来说,可能需要编译能够在Android版本上直接运行的可执行程序、或者是编译so库文件,这个时候就需要完成交叉编译。在命令行下执行交叉编译有两种方式: 一是用NDK自带的工具链 二是使用...
  • 2019armv8交叉编译工具,个人用于rk3399的交叉编译,是64位的linux系统。是我从官网上下载的。国内的网络下载很慢,这里分享给大家,亲测可用。
  • 本篇我们的目标是在iPhone上运行...交叉编译 指在一个平台上生成另一个平台上的可执行代码。现在我们就在Mac上写代码,在iPhone上运行,想想都刺激! 设备环境 使用的是Mac和越狱iOS13.2.2的iPhoneX Arm64 新建一个he
  • 二、NDK交叉编译openssl

    2020-04-01 16:04:13
    then ARCH_NAME=android-x86_64 fi echo $TOOL_CHAIN func_cmp done 脚本需要根据自己的路径修改MY_OPENSSL_PATH变量 脚本其中使用的是clang编译,如果想了解详细过程,请参考博客 使用clang编译openssl1.1.1d...
  • i++)) do sh $shmake --arch=${archs[i]} --platform=$platform --install-dir=$HOME/android-toolchain/${archs[i]} --toolchain=${toolchains[i]} done 运行 sh make_toolchain.sh 交叉编译的工具链配置完成,方便...
  • 1,什么是交叉编译 交叉编译是在一个平台上生成另一个平台上的可执行代码。所以我们在Linux上编译出可以在arm平台上使用的so库就是属于交叉编译。 2,系统环境 ubuntu18.04 ndk -> r21 3,在ndk 19以前 都是需要...
  • dhcpcd-6.0.1_arm_install.tar

    2019-04-09 10:07:13
    dhcpcd-6.0.1_arm_install.tar。源码以及编译生成的文件。
  • windows 安装msys2 交叉编译环境 介绍 MSYS2 (Minimal SYStem 2) 是一个MSYS的独立改写版本,主要用于 shell 命令行开发环境。同时它也是一个在Cygwin (POSIX 兼容性层) 和 MinGW-w64(从"MinGW-生成")基础...
  • LLVM初步上手,使用Release版进行安装直接命令行调用。确保环境正常,新打开一个cmd,如下: ...目标window下交叉编译arm-linux的hello程序window下交叉编译x86-linux的hello程序简单的三个源文件:hello.c#include "...
  • 我试图为Android arm交叉编译llvm / clang .我将CC / CXX变量导出到arm-linux-androideabi交叉编译器,然后从我的构建文件夹中执行:cmake -G "Unix Makefiles" --target arm-linux-androideabi --sysroot=$NDK/...
  • cmake 交叉编译

    2018-04-03 14:34:27
    前言Android交叉编译工具链google官方出的android.toolchain.cmake第三方android-cmake,可以被android.toolchain.cmake兼容http://gitlab.vdian.net/WD-INPUT/toolchain/iOS交叉编译...cmake,建议使用这个交叉编译...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,770
精华内容 1,108
热门标签
关键字:

交叉编译clang