使用Makefile编译不同平台目标文件方法

使用Makefile编译不同平台目标文件方法

一、源码autoconf、automake生成软件包

1、基础概念

  1. configure.in 这是最重要的文件,整个安装过程都靠它来主导。
  2. Makefile.am automake会根据它来生成Makefile.in,再由./configure 把Makefile.in变成最终的Makefile,一般来说在顶级目录和各个子目录都应该有一个Makefile.am
  3. acconfig.h autoheader会根据它来生成config.h.in,再由./configure 把config.h.in变成最终的config.h
  4. test.c test1.c test.h … … 等等源程序。

二、automake步骤流程

①autoscan命令生成autoscan.log和configure.scan

autoscan是用来扫描源代码目录生成configure.scan文件的。autoscan可以用目录名做为参数,但如果你不使用参数的话,那么autoscan将认为使用的是当前目录。autoscan将扫描你所指定目录中的源文件,并创建configure.scan文件。  

②重命名configure.scan为configure.in,然后配置configure.in

configure.scan包含了系统配置的基本选项,里面都是一些宏定义。需要将它改名为configure.in 

configure.in文件的内容是一些宏,这些宏经过autoconf 处理后会变成检查系统特性、环境变量、软件必须的参数的shell脚本。configure.in文件中的宏的顺序并没有规定,但是必须在所有宏的最前面和最后面分别加上AC_INIT宏和AC_OUTPUT宏。 

③aclocal命令生成aclcal.m4

aclocal是一个perl 脚本程序。aclocal根据configure.in文件的内容,自动生成aclocal.m4文件。aclocal的定义是:“aclocal - create aclocal.m4 by scanning configure.ac”。 

④编写acconfig.h头文件

⑤autoheader命令生成config.h.in

⑥编写Makefile.am

Makefile.am是用来生成Makefile.in的,需要手工书写。Makefile.am中定义了一些内容:  AUTOMAKE_OPTIONS     这个是automake的选项。在执行automake时,它会检查目录下是否存在标准GNU软件包中应具备的各种文件,例如AUTHORS、ChangeLog、NEWS等文件。将其设置成foreign时,automake会改用一般软件包的标准来检查。  bin_PROGRAMS    这个是指定所要产生的可执行文件的文件名。如果要产生多个可执行文件,那么在各个名字间用空格隔开。   helloworld_SOURCES     这个是指定产生“helloworld”时所需要的源代码。如果它用到了多个源文件,使用空格符号将它们隔开。比如需要helloworld.h,helloworld.c那么请写成helloworld_SOURCES= helloworld.h helloworld.c。    如果在bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的filename_SOURCES。 

⑦在源文件子目录中也编写相应的Makefile.am

扫描二维码关注公众号,回复: 2480128 查看本文章

⑧执行automake -a 或者automake –add-missing命令产生Makefile.in

选项--add-missing的定义是“add missing standard files to package”,它会让automake加入一个标准的软件包所必须的一些文件。 用automake产生出来的Makefile.in文件是符合GNU Makefile惯例的,接下来只要执行configure这个shell 脚本就可以产生合适的 Makefile 文件了。 

⑨执行autoconf生成最终的configure

autoconf是用来产生configure文件的。configure是一个脚本,它能设置源程序来适应各种不同的操作系统平台,并且根据不同的系统来产生合适的Makefile,从而可以使源代码能在不同的操作系统平台上被编译出来。 

⑩运行./configure

执行make  ,根据Makefile编译源代码,连接,生成目标文件,可执行文件。 

make clean   

清除上次的make命令所产生的object文件(后缀为“.o”的文件)及可执行文件。 

make install   

将编译成功的可执行文件安装到系统目录中,一般为/usr/local/bin目录。 

make dist   

产生发布软件包文件(即distribution package)。这个命令将会将可执行文件及相关文件打包成一个tar.gz压缩的文件用来作为发布软件的软件包。  

make distcheck

生成发布软件包并对其进行测试检查,以确定发布包的正确性。这个操作将自动把压缩包文件解开,然后执行configure命令,并且执行make,来确认编译不出现错误,最后提示你软件包已经准备好,可以发布了。  

make distclean

类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile。 

三、修改Makefile(参数传递)

编译的可执行文件有时候需要在PC机(x86)的平台上运行,有时候则需要在A嵌入式平台(arm端)i.mx6的平台上运行,而还有时候则需要在B嵌入式平台(arm端)mini2440的平台上运行,需要能随时进行切换,编译出对应平台所需要的可执行文件。 

方法:

①最土的办法自然就是写三份makefile,需要编译某一个平台时,拷贝对应的makefile,然后再make。 效率很低。

②在makefile中,定义三套编译规则,通过输入make x86,以及make imx6,以及make mini2440这样的目标选择命令,来指示编译器选择某一套编译规则并运行 ,导致makefile的文件很冗余,存在多套几乎一模一样的编译规则。

③在makefile中预先使用一个未定义的变量, 这个变量可以在make执行时传递给它。向make命令传递参数,告诉它怎么去解释makefile这个文件。

同一个工程在不同平台上编译时需要修改的Makefile中选项为:

build_triplet = x86_64-unknown-linux-gnu

可通过命令uname -a 查看当前设备平台版本信息 ;--build=编译该软件所使用的平台。  //注:该参数在不指定的情况下将自动尝试猜测目前平台的名称 

host_triplet = arm-unknown-linux-gnu

--host=该软件将运行的平台    ;  --target=该软件所处理的目标平台 

ACLOCAL = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run aclocal-1.11

AMTAR = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run tar

AUTOCONF = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run autoconf

AUTOHEADER = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run autoheader

AUTOMAKE = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run automake-1.11

指定一些自动生成的文件路径

CC = arm-hisiv510-linux-gcc

特定交叉编译工具指定      H90板端:arm-hisiv510-linux-gcc

                            H100板端:aarch64-linux-gnu-gcc

CPP = arm-hisiv510-linux-gcc -E

E参数将对源程序example.c进行预处理,生成example.i文件, 就是将#include,#define等进行文件插入及宏扩展等操作。 

MAKEINFO = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/missing –run makeinfo

abs_builddir = /workteam/huangxiang6/data/work/strace-4.6

abs_srcdir = /workteam/huangxiang6/data/work/strace-4.6

abs_top_builddir = /workteam/huangxiang6/data/work/strace-4.6

abs_top_srcdir = /workteam/huangxiang6/data/work/strace-4.6

build = x86_64-unknown-linux-gnu

build_cpu = x86_64

build_os = linux-gnu

host = arm-unknown-linux-gnu

host_alias = arm-linux

host_cpu = arm

host_os = linux-gnu

includedir = /opt/toolchains-BE/hisi/arm-hisiv510-linux/bin/../target/usr/include

install_sh = ${SHELL} /workteam/huangxiang6/data/work/strace-4.6/install-sh

opsys = linux

OS = linux (说明:OS is one of linux , sunos4 , svr4 , or freebsd .)

ARCH = arm (ARCH is i386, m68k , sparc , etc.包含了此核心源代码所支持的硬件体系结构相关的核心代码。如对于X86平台就是i386。)

搞不明白的几个问题:

在编译服务器上./configure 后生成的Makefile中的配置 build是X86,host也是X86,将make后的可执行文件strace传到H90板上,出现的错误很好理解:

        -sh: ./strace: cannot execute binary file: Exec format error

但是将Makefile修改为arm-hisiv510-linux的环境后运行make报错:

        syscall.c:46:21: fatal error: sys/reg.h:没有那个文件或目录

        #include <sys/reg.h>

原因:项目中的makefile必须能够正确的定位源文件和依赖文件 ,特殊的预定义变量VPATH用于指示make如何查找文件 ,不同文件夹可作为VPATH的值同时出现,文件夹的名字之间需要使用分隔符进行区分 。

例如:VPATH:=inc src

    VPATH:=inc;src

    VPATH:=inc:src

VPATH使用场景:当前文件夹找不到需要的文件时 ;

            make会在VPATH指定的文件夹中依次搜索文件;

            当多个文件夹存在同名文件时,选择第一次搜索到的文件 ;

VPATH只能决定make的搜索路径,无法决定命令的搜索路径 ;

对于特定的编译命令(gcc),需要独立指定编译搜索路径

四、CMake

网上有一种方法CMake 可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。CMake 支持 in-place 建构(二进档和源代码在同一个目录树中)和 out-of-place 建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake 也支持静态与动态程式库的建构。

“CMake”这个名字是“cross platform make”的缩写。虽然名字中含有“make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高阶。

猜你喜欢

转载自blog.csdn.net/Huangxiang6/article/details/81291743