命令行指定 CFLAGS 不生效
dpdk 的 Makefile 中有對 CFLAGS 的設定,在很多 Makefile 單獨設定了 CFLAGS 增加 -O3 參數。
下面是 dpdk-17.05 中一些 Makefile 在 CFLAGS 標誌中增加 -O3 選項的語句。
.......
./lib/librte_reorder/Makefile:37:CFLAGS += -O3
./drivers/net/fm10k/Makefile:39:CFLAGS += -O3
./drivers/net/tap/Makefile:42:CFLAGS += -O3
./drivers/net/pcap/Makefile:40:CFLAGS += -O3
./drivers/net/sfc/Makefile:38:CFLAGS += -O3
./drivers/net/vhost/Makefile:41:CFLAGS += -O3
./drivers/net/null/Makefile:39:CFLAGS += -O3
./drivers/net/mlx4/Makefile:47:CFLAGS += -O3
./drivers/net/af_packet/Makefile:45:CFLAGS += -O3
........
全局設定 export CFLAGS=" -O0 0g"
後重新編譯發現還是使用了 -O3 編譯,這表明 dpdk 的編譯腳本中對 CFLAGS 的值重新進行了設定,不能通過命令行指定 CFLAGS 來編譯出 debug 版本。
在 doc 目錄下找到了如下相關內容:
331 Variables that Can be Set/Overridden in a Makefile Only
332 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
333
334 * VPATH: The path list that the build system will search for sources. By default, RTE_SRCDIR will be included in VPATH.
335
336 * CFLAGS: Flags to use for C compilation. The user should use += to append data in this variable.
337
從上面的內容中可以看出,用戶不能通過命令行設定 CFLAGS,只能通過 Makefile 文件來設定。
命令行設置 EXTRA_CFLAGS 標誌生成 debug 版
繼續閱讀 doc 目錄中的幫助文檔,我發現 EXTRA_CFLAGS 標誌可以使用。文檔中相關的內容摘取如下:
Variables that Can be Set/Overridden by the User in a Makefile or Command Line
389 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390
391 * CFLAGS_my_file.o: Specific flags to add for C compilation of my_file.c.
392
393 * LDFLAGS_my_app: Specific flags to add when linking my_app.
394
395 * EXTRA_CFLAGS: The content of this variable is appended after CFLAGS when compiling.
396
397 * EXTRA_LDFLAGS: The content of this variable is appended after LDFLAGS when linking.
398
399 * EXTRA_LDLIBS: The content of this variable is appended after LDLIBS when linking.
400
401 * EXTRA_ASFLAGS: The content of this variable is appended after ASFLAGS when assembling.
402
403 * EXTRA_CPPFLAGS: The content of this variable is appended after CPPFLAGS when using a C preprocessor on assembly files.
上面的介紹表明 EXTRA_CFLAGS 變量可以通過命令行進行設定,同時它會在編譯時追加到 CFLAGS 內容之後。
執行 export EXTRA_CFLAGS="-O0 -g" 後重新編譯 dpdk 的庫,使用 gdb 調試 app 目錄下生成的可執行文件發現 gdb 能夠讀取到調試信息。
雖然有了調試信息,但是 Makefile 中對 CFLAGS 變量增加的 -O3 選項可能意味着編譯出來的是 O3 版本的程序,這樣就不能算作是 debug 版本。
我查看編譯編譯目錄中 *.o.cmd 中保存的編譯命令,發現庫函數的編譯命令中同時設定了 -O3 與 -O0 -g 參數。
示例如下:
[longyu@debian-10:22:02:09] x86_64-native-linuxapp-gcc $ cat ./build/lib/librte_eal/linuxapp/eal/.eal_alarm.o.cmd
cmd_eal_alarm.o = gcc -Wp,-MD,./.eal_alarm.o.d.tmp -m64 -pthread -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3 -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2 -DRTE_MACHINE_CPUFLAG_AES -DRTE_MACHINE_CPUFLAG_PCLMULQDQ -DRTE_MACHINE_CPUFLAG_AVX -DRTE_MACHINE_CPUFLAG_RDRAND -DRTE_MACHINE_CPUFLAG_FSGSBASE -DRTE_MACHINE_CPUFLAG_F16C -DRTE_MACHINE_CPUFLAG_AVX2 -I/home/longyu/Downloads/dpdk-stable-17.02.1/x86_64-native-linuxapp-gcc/include -include /home/longyu/Downloads/dpdk-stable-17.02.1/x86_64-native-linuxapp-gcc/include/rte_config.h -I/home/longyu/Downloads/dpdk-stable-17.02.1/lib/librte_eal/linuxapp/eal/include -I/home/longyu/Downloads/dpdk-stable-17.02.1/lib/librte_eal/common -I/home/longyu/Downloads/dpdk-stable-17.02.1/lib/librte_eal/common/include -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -O3 -O0 -g -o eal_alarm.o -c /home/longyu/Downloads/dpdk-stable-17.02.1/lib/librte_eal/linuxapp/eal/eal_alarm.c
查看到編譯命令,我想到了一個問題——指定了多個優化選項時 gcc 編譯時會使用哪個呢?
gcc 同時指定多個優化選項的問題
經過搜索,我發現 gcc 的官方網頁中對這個問題進行了描述。當 gcc 編譯命令中指定了多個優化選項時,只有最後一個優化選項生效。
-O3 是在 CFLAGS 變量中指定的,EXTRA_CFLAGS 是我們在命令行中指定的,根據 dpdk 的幫助文檔中的說明,EXTRA_CFLAGS 的值會在編譯時追加到 CFLAGS 的值後,這樣我們就看到了有 -O3 … -O0 -g 這樣的編譯命令。
-O0 是最後一個指定的優化選項,實際生效的是 -O0,而非 -O3,這樣我們通過設定 EXTRA_CFLAGS 爲 -O0 -g 就能夠編譯出 debug 版本的 dpdk。
備註: EXTRA_CFLAGS 是在 mk/internal/rte.compile-pre.mk 中使用的。
最終確定的編譯 dpdk debug 版本的方法
命令行中執行如下命令設定 EXTRA_CFLAGS 後重新編譯即可。
export EXTRA_CFLAGS="-O0 -g"