編譯環境介紹.

Slides:



Advertisements
Similar presentations
C/C++ 程序设计 吉林财经大学 管理科学与信息工程学院 李艳东 : Tel :
Advertisements

Linux 环境及 Shell 程序 操作系统实验 1. 二、 Shell 编程与进程通信 常用 shell 命令 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、
© 2001 孟静制作 版权所有 第二章 CPU 管理和进程、线程管理 2.1 CPU 管理概述 2.2 进程管理 2.3 进程模型实例分析 :UNIX 早期版本的 CPU 管理 子系统 ( 进程模型 ) 2.4 处理机管理实例分析 (2):linux CPU 管理(进程 模型) 2.5 线程模型.
主讲:王幸民 理学院计算机基础教学部.
Unix 指令4.
基础模块 模块一 程序设计基础 (一)开发环境部分.
C语言程序设计 主讲教师 :张群燕 电话:
培养目标 1.建立基本的程序设计概念体系,掌握基础程序设计方法。
命令行操作 shell介绍 常见三种Shell ---Bourne shell(sh) ---C shell(csh)
第 2 章 初探 C++.
操作系统结构.
第1讲 实验环境.
LINUX 环境下程序开发基础 曙光用户培训课程系列 课程时间:1.5小时 更新日期:2008年3月.
編譯環境介紹.
資訊安全與系統管理 2013/3/13 Chien wei lin.
補充: Input from a text file
基于操作系统的编程复习 张玉宏
UNIX系統與資料庫安裝 Why UNIX 常用的工具程式介紹 資料庫的安裝.
Linux Further.
Linux 的進階檔案處理.
Linux.
南京天石软件技术有限公司 陈锺 (QQ: Solaris 10 C编程 南京天石软件技术有限公司 陈锺 (QQ:
Linux环境下程序编译 曙光信息产业(北京)有限公司.
選擇排序法 通訊一甲 B 楊穎穆.
C的發展史 C程式初體驗 C程式設計基本注意事項 上機實習課程
第四章 函数和递归.
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
张吉豫 GNU编译工具链使用简介 张吉豫
第三章 文本编辑器vi.
Linux环境高级编程实验.
助教:胡光能,解定宝 编译原理讲师:戴新宇
编译与多文件.
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
講師:戴志華 國立台灣大學電機工程研究所 Visual Basic 程式設計 講師:戴志華 國立台灣大學電機工程研究所.
單晶片MCS-51 C語言入門實習 第2章 KEIL-51工具軟體 作者:董勝源.
黃印良 本教材引用自 作者:Edward Lee
Process management(程序管理)
作業系統實習課(四) -檔案管理- 實驗室:720A 助教:鄧執中.
第9章 DSP集成开发环境CCS 内容提要 CCS是TI公司推出的用于开发DSP芯片的集成开发环境,它采用Windows风格界面,集编辑、编译、链接、软件仿真、硬件调试以及实时跟踪等功能于一体,极大地方便了DSP芯片的开发与设计,是目前使用最为广泛的DSP开发软件之一。 本章对CCS开发软件的使用作了详细地介绍。首先,对CCS开发软件作了简要地说明,并介绍了该软件的安装及配置;其次,介绍了CCS的基本操作,包括:CCS的窗口和工具条、文件的编辑、反汇编窗口、存储器窗口、寄存器窗口、观察窗口
THE C PROGRAMMING LANGUAGE
MS Windows XP 作業系統使用操作簡介.
Instructor:Po-Yu Kuo 教師:郭柏佑
Linux核心編譯與模組管理 2013/01/19.
第3章 認識處理元.
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab3.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
序及第0章.
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
Confidential Property
2018 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A Lab3.
QQ群 主要用于线下讨论答疑 用于发布一些通知公告 修该备注,如 经济学院_2019_张三. 刘东华 信息技术中心 敬宾楼1406
C语言环境配置.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
实验一:编译运行Linux内核并使用gdb进行调试
项目1 C程序设计起步 学习目标: 通过该项目你可以知道: C语言的用途。 C语言的基本符号和关键字。 C语言程序的结构及特点。
第一章 C语言概述 目录 什么是语言、程序 C语言的历史与发展 C语言的书写形式与程序结构 运行C语言的步骤与方法
第二章 类型、对象、运算符和表达式.
Lab01 工作站&Linux操作 日期:2011/03/07.
程式設計--linear search 通訊一甲 B 楊穎穆.
实验二:添加Linux系统调用及熟悉常见系统调用
第1章程序设计和C语言.
作業一: 安裝Linux於btrfs上 中正大學 作業系統實驗室 指導教授:羅習五
杨振伟 清华大学 第一讲:Linux环境下编程(1)
嵌入式Linux编程环境.
劉庠宏、林合治編著 國立高雄大學應用數學系 2005年3月1日
Introduction to the C Programming Language
函式庫補充資料 1.
隨機函數.
Presentation transcript:

編譯環境介紹

最常用的文書編輯器vi及vim

安裝vim vi和vim的最大不同在於vim支 援「多顏色」的編輯環境,因 此我們選用vim vi幾乎是所有Linux都提供的編 輯器,請同學自學 第一次執行vim系統會說沒有 這個軟體,請依照螢幕只是輸 入 sudo apt-get install vim

使用圖形化介面安裝vim Ubuntu內建Ubuntu software center,可以使用圖形化介面 安裝程式 標準的vim是純文字介面, Ubuntu software center允許我 們安裝圖形化介面的vim 你們喜歡圖形化介面或純文字 介面呢?

先使用容易上手的「圖形化」vim 輸入「a」這個字母代表我們 要開始編譯 輸入程式碼 將檔案存成~/sp/hello.c 儲存的方式是按下「ESC」然後 打w hello.c 這時候你可以看到你的程式碼的 關鍵字變色了

一些設定 選擇下列選項,讓vim協助我 們程式碼的排版,並列出行號 Toggle Line Numbering Toggle auto-indent Toggle C-indenting

使用vim的「快捷鍵」

為何要學習「快捷鍵」 學會快捷鍵以後,編輯程式碼的速度可以變得更快 如果你使用的vim沒有圖形化介面,那麼你只能使用「快捷鍵」

Vim的編輯模式 編輯模式 按下i,o,a進入編輯模式,ESC退回一般模式 一般模式 指令模式 按下「:」進入命令列模式,ESC退回一般模式

vim一般模式常用功能 瀏覽 搜尋 上下左右鍵,移動游標 ctr-f, ctr-b,向下或向上移動一頁 0或「home」移到該列的第一個字元,$或「end」移到該列最後一個字 元 G移到最後一列,gg移到第一列 搜尋 「/word」向下尋找word這個字 「?word」向上尋找word這個字 n繼續尋找

vim一般模式常用功能 刪除、複製、貼上 x, X:小x向後刪除一個字元,大X向前刪除一個字元 dd:刪除整個列 ndd:n是一個數字,例如20,20dd代表向下刪除20列 yy:複製游標所在的那一行 nyy:複製游標所在的底下n行 p:將複製的資料,於游標的下一行開始貼上 u:復原前一個動作 [ctr]+r:重做上一個動作

一般指令模式 i:從目前游標所在位置開始插入(輸入) 「ESC」:退出一般模式

指令模式 :w,寫入檔案 :w!,強制寫入檔案 :q,離開vim :q!,強制離開vim :wq,寫入檔案並離開

寫程式碼常用指令 Ctr-n:自動補上該字

使用圖形化編輯器

選擇哪一個圖形化編輯器呢 - Geany

安裝

Geany的對程式碼編輯的支援 自動完成功能 參數提示功能

Geany的編譯環境

gcc 與 gdb

gcc常用的編譯參數 gcc xxx.c gcc xxx.c -o exec gcc xxx.c -O3 gcc xxx.c –ansi xxx.c必需內含main function,編譯以後產生的執行檔檔名為a.out gcc xxx.c -o exec xxx.c必需內含main function,編譯以後產生的執行檔檔名為exec gcc xxx.c -O3 xxx.c必需內含main function,啟動最佳化,O後面可以為1, 2, 3 gcc xxx.c –ansi xxx.c必須使用標準的ANSI C撰寫,所有gcc的擴充語法都不可以使用 gcc xxx.c –g 產生的執行檔案可以用gdb除錯 gcc xxx.c -pg 產生的執行檔案可以用gprofile量測效能

一個簡單但錯誤的例子 #include <stdio.h> #include <stdlib.h> int main () { int *p; /*指標未給初始值*/ int ret; ret = scanf("%d", p); printf("ret = %d, %d", ret, *p); }

編譯並除錯 $gcc pointer.c –g –o pointer $gdb ./pointer shiwulo@ubuntu:~/sp$ gdb ./pointer /*一堆版權宣告訊息*/ (gdb)b main /*在main函數設定break point*/ Breakpoint 1 at 0x4005a5: file pointer.c, line 6. (gdb)r /*開始執行*/ Starting program: /home/shiwulo/sp/pointer Breakpoint 1, main () at pointer.c:6 6 scanf(“%d”, p); /*程式碼停在main函數的第一行*/ 請注意,紅色字體為提醒文字,並非Linux所輸出的文字

編譯並除錯 (gdb)n 1 /*你的執行檔pointer等著你輸入一個字*/ Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7a6c742 in _IO_vfscanf_internal (s=<optimized out>, format=<optimized out>, argptr=argptr@entry=0x7fffffffde08, errp=errp@entry=0x0) at vfscanf.c:1857 1857 vfscanf.c: No such file or directory. /*gdb告訴你發生segmentation fault*/

編譯並除錯 (gdb)bt #0 0x00007ffff7a6c742 in…at vfscanf.c:1857 #1 0x00007ffff7a72ed9 in … at isoc99_scanf.c:37 #2 0x00000000004005bb in main () at pointer.c:6 /*bt可以看到目前的呼叫堆疊*/ /*從上述的訊息可以知道pointer.c的第6行呼叫isoc99_scanf.c,isoc99_scanf.c呼叫vfscanf.c,並且在vfsacnf.c的1857行發生錯誤,由於我們相信libC應該不會有bug,所以bug很有可能發生在pointer.c的第6行*/ 請注意…代表我刪除了一些沒用的訊息

編譯並除錯 vfscanf 目前在此函數 Isoc99_scanf (gdb) up #1 0x00007ffff7a72ed9 … at isoc99_scanf.c:37 37 isoc99_scanf.c: No such file or directory. #2 0x00000000004005bb in main () at pointer.c:6 6 scanf(“%d", p); (gdb) /*注意,還未執行up前,gdb在「呼叫堆疊」裡面是位於vfscanf,因此必須執行二次的up才會到pointer.c*/ (gdb) print p /*print可以印出某個變數的值*/ $1 = (int *) 0x0 /*到這裡我們可以確定這個程式碼是因為指標未給初始值造成錯誤*/ pointer 二次up後到此函數

編譯並除錯 常用的gdb功能 help 印出gdb的功能與解釋 commends定義簡短指令 b 設定breakpoint watch觀察某一個變數是否被修改 bt 看目前的呼叫堆疊 l 看目前的程式碼 s 單步執行(遇到函數會跳進去 追蹤) n 單步執行(遇到函數不會跳進 去追蹤) p 印出某個變數的值 r 開始執行 info 會印出許多有用的東西

gdb -tui ./pointer ┌──pointer.c────────────────────────────────────────────────────────────────┐ │4 int main () { │ │5 int *p; /*M-f~L~GM-fM-(~YM-f~\M-*M-gM-5M-&M-e~H~]M-│ │6 int ret; │ │7 ret = scanf("%d", p); │ │8 printf("ret = %d, %d", ret, *p); │ │9 } │ │10 │ │11 │ │12 │ │13 │ │14 │ │15 │ │16 │ └───────────────────────────────────────────────────────────────────────────┘ exec No process In: L?? PC: ?? For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./pointer...done. (gdb)

Code::Blocks(自己試試看,感覺不穩定)

Visual Studio Code https://code.visualstudio.com/download https://marketplace.visualstudio.com/items?itemName=ms- vscode.cpptools

File->Open Folder

Debug(在此步驟之前,記得先編譯)

Debug

設定(文字檔案,設定完記得儲存)

設定中斷點

開始執行

也是一個不錯的編輯器 (有自動填入功能)

Visual Studio Code未提供的功能

小結 必須熟悉gcc及gdb,因為Linux上的工具並無法完全替代掉這二 者 一定要熟悉vi及vim UNIX上一定會有vi UNIX與Windows不同,所有的設定檔都是「純文字」檔案,當系統崩潰 時你可以使用「single user mode」啟動,然後編輯設定檔案進行修復 可以選擇一個你最喜歡的GUI的環境,當平常寫程式用的工具

make:簡化常用的編譯指令

語法 target: source1.o source2.o… /*如果source1.o, source2.o其中有*/ gcc source1.o source2.o –o target /*一個比target還要新*/ /*就會執行gcc*/ clean: /*無預設條件*/ rm *.o

實例 pointer: pointer.c /*只有當pointer.c的時間比pointer還新時*/ gcc pointer.c -O3 -o pointer /*才會執行gcc指令*/ hello: hello.c gcc hello.c -O3 -o hello table: table.c gcc table.c -O3 -o table clean: /*只要執行clean就一定會執行remove*/ rm pointer rm hello rm table

更複雜一點點的例子 all: pointer hello table /*打make all時,只要xxx.c有任何變動,其*/ touch all /*對應的gcc會重新編譯該檔案*/ pointer: pointer.c gcc pointer.c -O3 -o pointer hello: hello.c gcc hello.c -O3 -o hello table: table.c gcc table.c -O3 -o table clean: rm pointer rm hello rm table

更複雜一點點的例子 all: pointer hello table /*打make all時,只要xxx.c有任何變動,其*/ touch all /*對應的gcc會重新編譯該檔案*/ pointer: pointer.c touch pointer /*www.cs.ccu.edu.tw/~shiwulo/course*/ hello: hello.c touch hello table: table.c touch table clean: rm pointer rm hello rm table

GNU C內建的效能衡量工具 gprofile

範例程式 如右圖,一個表格(table), 分別計算欄(col)的總和及列 (row)的總和 程式碼的程式碼如下頁所示

程式碼 將table初始化 列印結果 以row major方式計算 主函數,呼叫各個子函數 以col major方式計算 #define size 10000 long table[size][size]; long col[size]; long row[size]; void initTable() { int i, j; for (i=0; i< size; i++) for (j=0; j<size; j++) table[i][j]=random(); } void sumCol() { for (i=0; i<size; i++) col[j] = table[i][j]; void sumRow() { row[i] = table[i][j]; void printResult() { int i; printf(" RAW\tCol\n"); printf("%8ld\t%8ld\n", row[i], col[i]); int main() { printf("hello\n"); initTable(); sumRow(); sumCol(); printResult(); return 0; 將table初始化 列印結果 以row major方式計算 主函數,呼叫各個子函數 以col major方式計算

編譯的命令,及gprof命令 gcc table.c -pg -o table /*編譯,注意,要加入-pg*/ ./table /*執行,會自動產生gmon.out*/ gprof -b table gmon.out /*產生報表,如下頁所示*/

gprof產生的報表 主要產生 各個函數的執行時間 call graph(呼叫圖)

執行時間 sumCol的執行時間是42.71% sumRow的執行時間是28.48% 雖然前述二者做的加法次數一 樣。由這裡可以看出row major 會比較快! 較快的原因可以用perf觀察 initTable花了29.66%的時間

呼叫圖 由左圖可以看到main分別呼叫 了四個函數。 也可以觀察到呼叫這四個函數 佔了總體多少時間

可是人家覺得不漂亮, 人家看不懂啦

valgrind shiwulo@vm:~/sp/ch02$ gcc -g table.c shiwulo@vm:~/sp/ch02$ valgrind --tool=callgrind ./a.out shiwulo@vm:~/sp/ch02$ kcachegrind callgrind.out.#####

產生的結果 (請注意每個function消耗的時間並不是很精準)

initTable居然佔了最多時間 (gprof的結果是sumCol)

小結 gprof的結果比較正確 使用valgrind可以獲得比較多的東西,但結果(特別是時間)是 不正確的 Valgrind是虛擬機器,類似java,產生一種容易profiling的中間碼,之後 再做統計 因此Valgrind並不是真的執行x86程式碼,時間上就不是那樣準確了

作業 使用Linux環境撰寫一個程式,這個程式必須算出「費伯納西數列」, 到第1,000,000個「費伯納西數」 費伯納西數列 繳交程式 所有.c、.h、makefile,執行檔名稱「fib」,助教執行make後必須產生fib 選出程式碼寫最好、註解最完整的三名同學,額外加5分,並公佈這三位同下 的程式碼