14.2.7 命令行定义
许多C编译器提供了一种能力,允许你在命令行中定义符号,用于启动编译过程。
当我们根据同一个源文件编译一个程序的不同版本时,这个特性特别有用。
例如:定义不同长度的数组。
int buf[MAX_NUM];
在编译程序时,MAX_NUM的值可以在命令行中指定。
在UNIX编译器中,-D选项可以完成这项任务。我们可以用两种方式使用这个选项。
①: -Dname
②: -Dname=stuff
第一种形式,定义了符号name(我们这里是MAX_NUM),它的值为1。
第二章形式,把该符号的值定义为等号后面的stuff。
测试源码
#include <stdio.h>
#include <string.h>
int main()
{
int buf[MAX_NUM] = {0};
memset(buf, 0, sizeof(buf));
int i;
for(i=0; i<MAX_NUM; i++)
{
buf[i] = i;
}
printf("\n ---------------------- \n");
for(i=0; i< MAX_NUM; i++)
{
printf(" %02X",buf[i]);
}
printf("\n ---------------------- \n\n");
return 0;
}
编译选项:
gcc -DMAX_NUM=5 test.c -o test
运行效果:
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# gcc -DMAX_NUM=5 test.c -o test
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# ./test
----------------------
00 01 02 03 04
----------------------
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test#
可以看见,在编译时,把MAX_NUM值传递给了函数。
多测试几次:
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# gcc -DMAX_NUM=10 test.c -o test
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# ./test
----------------------
00 01 02 03 04 05 06 07 08 09
----------------------
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# gcc -DMAX_NUM=16 test.c -o test
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# ./test
----------------------
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
----------------------
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# gcc -DMAX_NUM=25 test.c -o test
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# ./test
----------------------
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18
----------------------
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# gcc -DMAX_NUM=255 test.c -o test
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test# ./test
----------------------
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE
----------------------
root@ubuntu:/mnt/hgfs/Ubuntu12-share/01_C/02_test#
提供符号命令行定义的编译器通常也提供在命令行中去除符号的定义。
在UNIX中编译上,-U选项用于执行这项任务。指定-Uname将导致程序中符号name的初始化被忽略。当它与条件编译结合使用时,这个特性是很有用的。
ps:
个人感悟:当需要同一个源码编译出在X86和arm机器上运行的代码时,可以不用再每次都修改源码中的宏定义以及Makefile中的选项了。
可以只修改Makefile的编译参数,即可实现编译出不同架构的二进制文件。
pss:还是要多读书。