Không chạy được ệnh gcc trong linux
Hướng dẫn cách cài đặt trình biên dịch GCC trên Linux và cách viết 1 chương trình C cơ bản trên Linux. GCC (GNU Compiler Collection) là một tập hợp các trình biên dịch cho các ngôn ngữ lập trình khác nhau như C, C++, ... GCC hiện tại có thể cài trực tiếp trên hệ điều hành Linux hoặc thông qua môi trường Linux trên Windows 10. Cài đặt GCC trên LinuxMở Terminal trên Linux hoặc Bash on Unbutu on Windows một giao diện tương tự xuất hiện - 1 số máy sử dụng hệ điều hành không có giao diện đồ họa thì bản đã như màn hình bên dưới: Tiến hành kiểm tra liệu GCC đã được cài đặt trên thiết bị chưa với câu lệnh sau gcc -vgcc -v Giao diện trên cho thấy hiện tại máy đã được cài đặt GCC phiên bản 5.4.0 20160609. Nếu máy đã cài đặt GCC thì không cần cài đặt nữa, giả sử chưa cài đặt và tiến hành cài đặt, trước tiên xóa màn hình cho gọn gàng clear Để tải và cài đặt gói GCC sử dụng quyền root - sudo apt-get install gcc Một yêu cầu nhập mật khẩu của tài khoản root hiện ra, tiến hành nhập mật khẩu cho tài khoản root, chờ tải và cài đặt. Hello World với chương trình C đầu tiên bằng trình biên dịch GCC
Khởi động Bash on Unbutu on Windows và chạy lệnh sau để mở chương trình Nano (trình soạn thảo văn bản trên Linux). nano Giao diện chương trình Nano hiện lên, tiến hành soạn thảo đoạn mã cho chương trình: #include Giao diện của chương trình được viết bằng Nano sẽ như sau Sau khi soạn thảo xong chương trình, dùng tổ hợp Ctrl + O (phần Write Out) để lưu lại chương trình. Hoặc nếu Ctrl + X (Phần Exit) thì Nano sẽ hỏi có muốn lưu hay không? Đặt tên cho file chương trình là Text.c (phải đặt cả phần mở rộng cho file là .c hoặc .cpp) và lưu lại. Sau khi lưu lại chương trình có giao diện như sau Để thực thi chương trình Test.c ta sẽ tiến hành biên dịch Test.c thành một tập tin có định dạng .obj. Ta thoát khỏi chương trình Nano bằng tổ hợp Ctrl + X và quay lại giao diện console Linux, tại đây tôi dùng lệnh sau để tiến hành biên dịch Test.c thành Test.o (.o nghĩa là .obj) gcc -c Test.c -o Test.o Sau khi biên dịch xong, dùng lệnh ls Kết quả sẽ có một tập tin Test.o đã được tạo ra như hình trên. Tiếp theo link Test.o thành file thực thi (file này tương tự file .exe của môi trường Windows) bằng câu lệnh sau gcc -o program Test.o Với Sau khi link xong, dùng lệnh ls để kiểm tra danh sách tập tin hiện có trong thư mục hiện hành. Cuối cùng, để thực thi chương trình ./program The traditional way. Mã: Trước hết chúng ta sẽ cần một text editor. Sẵn có trên Ubuntu thì có Gedit, nano. Bạn nào dùng KDE thì có Kate cũng rất tốt. Trendy hiện nay thì có Sublime Text 3. Hard core hơn thì có
Emacs và Vim, ban đầu khó dùng
nhưng rất đáng bỏ công học. Bạn dùng editor nào cũng được, tất cả đều là editor tốt. PHP:
Compile thủ công Bây giờ thì ta có thể bắt đầu với một ứng dụng đầu tiên. Bạn gõ chương trình sau vào file hello.c bằng editor đã chọn ở trên. Mã:
PHP:
PHP:
Ở đây ta có thể thấy lệnh gcc được gọi với tham số hello.c là tập tin đầu vào và flag -o hello thể hiện tên của tập tin đầu ra (-o là viết tắt của out). Sau đó ta chạy file hello vừa tạo ra bằng lệnh ./hello. Dấu chấm và gạch chéo nghĩa là chạy file hello ở thư mục hiện tại (biết đâu trong $PATH của bạn lại chứa một chương trình cũng tên là hello?). Nếu bạn không đặt tên cho file đầu ra thì theo truyền thống, gcc sẽ tạo file có tên là a.out. Mã:
Bây giờ giả sử bạn muốn thay đổi chương trình và mở rộng thêm một file nữa. Coi như là main.c đi. Bạn sẽ tách lệnh hiển thị ra màn hình thành hàm hello() chứa trong hello.c còn hàm main() thì
chứa trong main.c. PHP: hello.cPHP: main.cPHP: Bạn vẫn compile như trên nhưng mở rộng thêm file main.c vào câu lệnh.PHP:
MakeRất tuyệt. Nhưng bạn có để ý nãy giờ là việc compile bằng cách chạy gcc trực tiếp thế này rất thủ công không? Stuart Feldman cũng nghĩ vậy vào năm 1976 và đã viết chương trình Make để tự động hóa những thao tác lặp đi lặp lại như thế này. Make đã được cài tự động cùng với gói build-essentialở trên. Để sử dụng Make, trước hết chúng ta sẽ viết một Makefile đơn giản, đặt tên tập tin là Makefile và nằm cùng thư mục với chương trình C của chúng ta. Mã:
Makefile PHP:
PHP: Có thể thấy là chỉ
với một lệnh make, các thao tác thủ công của chúng ta đều đã được thực hiện. Cùng phân tích Makefile một chút.Một Makefile bao gồm các target, là những thứ bạn muốn thực hiện. Ở đây có 3 target là all, hello và run. Sau dấu hai chấm của all có liệt kê 2 target còn lại, nghĩa là target allphụ thuộc vào hello và run. Như vậy, khi chúng ta make allthì Make sẽ thực thi hello và run trước, sau đó mới thực thi all. Nếu chỉ chạy make không thì target đầu tiên trong file sẽ được thực thi. Các target trong Makefile thực chất là các tên tập tin. Như vậy có thể "dịch" nội dung target hello ở trên là "tôi cần file hello, và các lệnh dưới đây là hướng dẫn tạo file hello". Bây giờ nếu bạn chạy make all một lần nữa thì sẽ thấy là không còn dòng gcc hiện ra nữa. Target hello không được thực thi vì Make biết rõ là đã tồn tại file hello trong hệ thống. Nhưng nếu bạn make clean (để xóa file hello) thì nó sẽ lại được thực thi. Nó cũng sẽ được chạy nếu một trong các dependency của nó (hello.c và main.c) bị thay đổi. Ý tưởng của Make là tạo một mạng lưới các tập tin và target phụ thuộc lẫn nhau và chỉ thực thi một target nếu kết quả của nó chưa tồn tại hoặc một trong các tập tin phụ thuộc của nó có thay đổi. Lấy thêm một ví dụ, chúng ta có thể tạo file run trong cùng thư mục và target run cũng sẽ không được thực thi. PHP: Để tránh hiện tượng này thì ta có thể thêm dòng .PHONY vào cuối Makefile để ép Make luôn thực thi
target run:Nhìn lại Makefile, bạn có thể thấy là chúng ta lặp lại chữ hello quá nhiều. Hoàn toàn không tuân thủ theo nguyên tắc DRY(Don't Repeat Yourself). Để giải quyết vấn đề này, chúng ta sẽ dùng biến. PHP:
Makefile giờ trông đã "generic" hơn. Thậm chí gcc cũng đã được thay bằng biến $(CC), là biến sẵn có của Make, có nội dung là compile chuẩn của hệ thống. Nếu sau này bạn muốn compile bằng compiler khác như clang thì chỉ cần chạyCC=clang make all là được. Không cần phải thay đổi Makefile. Với chương trình nhỏ vài file như thế này thì Makefile như vậy là hoàn toàn OK. Nhưng bạn có thể nghiên cứu thêm trên Google và tài liệu tra cứu của GNU Make. Ngoài ra tôi cũng thấy Makefile của trình phiên dịch ngôn ngữ Lua được viết cũng rất đơn giản mà vẫn cross-platform, mang sang Windows hay Mac OS X vẫn compile được. Rất hợp để nghiên cứu. Sau này bạn có thể tìm hiểu thêm về Autotools và CMake để thay thế việc viết Makefile thủ công và tạo hệ thống build tương thích nhiều nền tảng mà không cần phải lo nghĩ nhiều. conio.hTạm coi như bạn đã hiểu cách build đi. Nhưng khả năng cao là bạn sẽ vấp tiếp một vấn đề nữa. Phần lớn các giáo trình lập trình C/C++ ở Việt Nam được xây dựng dựa trên môi trường DOS/Windows. Bạn có thể nhận biết ngay điều này nếu thấy trong giáo trình có đề cập đến thư viện conio.h và hàmgetch(). Thư viện này chỉ có cũng như chỉ hoạt động trên môi trường DOS/Windows. Mục đích của nó là cho phép bạn thực hiện các thao tác vào/ra trực tiếp với console. Console (hay terminal) thông thường hoạt động trong chế độ có buffer (cooked mode). Tức là các phím nhấn của bạn không được gửi trực tiếp đến chương trình mà sẽ được giữ lại ở phần mềm console để cho phép bạn chỉnh sửa tự do trước khi nhấn ENTER và gửi đến chương trình. Tương tự, các thao tác printf() cũng không ghi trực tiếp vào console mà ghi vào một file đặc biệt, gọi là file stdout. Hệ thống sẽ chuyển tiếp nội dung file này vào console. File này có buffer nên đôi khi lệnh printf() của bạn sẽ không hiện gì ra màn hình hết và bạn phải fflush(stdout) thủ công. Conio.h cho bạn công cụ để đọc/ghi trực tiếp với console mà không qua buffer. VD: getch() sẽ return bất cứ ký tự nào vừa được nhấn xong mà không cần nhấn ENTER. Chúng ta sẽ implement lại một số tính năng của conio.h trên Linux. clrscr()Trước hết là hàm clrscr() dùng để xóa trắng terminal. Với Linux thì có thể dụng lệnh clear: getch()Trên Windows, vì khi chạy từ IDE, cửa sổ console sẽ tắt ngay lập tức sau khi chương trình chạy xong nên người ta thường thêm lệnh getch() ngay cuối chương trình làm "đứng hình" console để nhìn rõ kết quả. Với Linux thì lúc nào chúng ta cũng ở trong terminal nên không cần lệnh này. Nhưng nếu bạn cần tính năng kiểu Press any key to continuethì có thể dùng getchar() và đổi lời nhắn thành Press ENTER to continue. Hoặc hardcore hơn là chuyển terminal về cbreak mode, getchar(), rồi chuyển lại trở về cooked mode. PHP:
textcolor() và textbackground()Terminal thông thường trên Linux tuân theo chuẩn VT100, chuẩn này có định nghĩa một số tính năng cho bạn điều khiển trực tiếp terminal sử dụng một loại mã đặc biệt gọi là escape code. Bạn gửi mã này tới terminal chỉ đơn giản bằng cách printf nó ra với ký tự đầu tiên là ESCAPE (mã ASCII 0x1B). Ví dụ, để đổi màu text thành đỏ và background thành vàng chúng ta làm như sau: PHP: Trong đó, 31 là mã màu đỏ foreground còn 43 là màu vàng background còn 0 là mã reset. Bạn có thể xem một số mã màu và các hiệu ứng khác ở đây.gotoxy()Tương tự như trên, chúng ta có thể printf mã [{ROW};{COLUMN}H để đưa con trỏ tới vị trí bất kỳ trong terminal. PHP: Pheww, vậy là xong một bài hướng dẫn khá dài. Hy vọng tôi đã giúp bạn hiểu hơn về lập trình C trên Linux nói riêng và Unix nói chung.Nguồn : http://ngochin.com/2014/08/15/lap-trinh-c-tren-linux-the-hard-way/ |