Giới thiệu
Là một developer, chắc hẳn bạn đã từng đau đầu trong việc chọn công cụ làm việc với source code cho mình. Ở đây mình không chỉ đề cập đến editor mà còn bao gồm cả việc phân tích source code như nhảy đến định nghĩa, khai báo của 1 hàm hay 1 biến; hay tra toàn bộ các hàm gọi đến hàm hoặc biến hiện tại, hoặc đơn giản như tìm kiếm text trong toàn bộ source code của dự án…
Có rất nhiều công cụ code editor đang được dùng hiện nay, và mỗi công cụ đều có điểm mạnh và điểm yếu riêng. Do vậy, khó có thể nói tool nào tốt nhất, mà lựa chọn tool nào nên phụ thuộc vào môi trường làm việc cũng như tính chất của dự án. Trong bài viết này, mình muốn giới thiệu về text editor vi (hoặc vim) sử dụng kết hợp với tool phân tích source code cscopes.
Đầu tiên phải nói về công cụ text editor vi, là một công cụ rất tiện nhưng lại không được mọi người yêu thích lắm, chủ yếu là do không thân thiện với người dùng ban đầu. Sử dụng vi tiện ở chỗ tạo, mở và sửa được file ngay trong môi trường CLI (Command-Line Interface) của server chứa và complie source code. Bên cạnh đó, công cụ vi/vim cũng rất nhẹ và nhanh. Tuy nhiên, công cụ vi được thiết kế khá chuyên biệt cho developer trong môi trường Linux nên hướng tới việc sử dụng phím tắt nhiều thay vì dùng chuột. Vì vậy có thể gây khó khăn với những người mới sử dụng. Còn vim (vi improved) là công cụ cải tiến của vi nên đã bao gồm toàn bộ các tính năng của vi và thêm nhiều tính năng mới. Do đó trong Ubuntu, khi bạn dùng vi để mở file, thực chất hệ điều hành sẽ chạy vim luôn.
Nếu chỉ sử dụng vi/vim thì chưa đủ để làm việc với source code. Vì với vi/vim, bạn chỉ search được theo dạng text nội bộ trong file bạn mở chứ không thể xem đến thông tin khác (definition, reference…) của hàm/biến đó như chức năng của các công cụ source insight hay sublime text cung cấp. Và cscope chính là công cụ đi kèm hoàn hảo để giải quyết bài toán này. Cscopes hoạt động dựa trên việc đánh chỉ mục cùng với vị trí của tất cả các hàm/biến/macro…của toàn bộ source code của dự án (các chỉ mục này được gọi là tag hoặc index). Công cụ vi/vim có thể hiểu được các tag này và cho phép chúng ta dễ dàng nhảy đến hoặc quay lại giữa các tag ngay trong cửa sổ vi/vim hiện tại, từ đó cho phép bạn thuận tiện tra cứu source code của dự án.
Công cụ vi/vim dùng kết hợp với cscope tuy có thể gây khó khăn cho người dùng ở thời điểm ban đầu chưa quen thuộc nhưng rất hữu ích đặc biệt là những người làm việc với các dự án Unix/Linux embedded. Cá nhân mình đã sử dụng nhiều IDE như source insight, sublime text, visual studio, notepadd++… nhưng sau khi dùng quen vi/vim + cscope thì không muốn quay lại những IDE cũ nữa. Đó cũng là lý do ngày xưa khi mình sang training ở Hàn Quốc thấy các bác toàn dùng cscope tra code rất nhanh, lúc đó còn kém quá nên hoa hết cả mắt.
Cài đặt cscope
Trước hết bạn kiểm tra xem máy của mình đã có cscope chưa bằng câu lệnh “which cscope”. Nếu máy của bạn đã có cscope, câu lệnh này sẽ chỉ ra địa chỉ cscope được cài đặt.
Trong trường hợp chưa có, bạn có thể cài cscope bằng câu lệnh đơn giản “apt-get install cscope”. Để kiểm tra xem cscope được cài đặt thành công, bạn gõ câu lệnh “cscope –version” để xuất ra thông tin version của cscope được cài đặt. Việc cài đặt cscope rõ ràng là quá dễ dàng phải không? Việc tiếp theo chúng ta sẽ tạo ra file tag cho dự án mà chúng ta làm việc.
Thiết lập cscope trong vim
Để thiết lập cscope sử dụng được trong vi/vim, bạn chỉ cần làm theo các bước hướng dẫn trên trang tutorial của cscope http://cscope.sourceforge.net/cscope_vim_tutorial.html.
Trong terminal của máy chủ, mở file /etc/vim/vimrc, đây là file chứa cấu hình và các thiết lập của vim mà bạn sử dụng. Dán toàn bộ nội dung của file cscope_maps.vim vào cuối file này.
Tạo tag cho source code
Di chuyển đến đường dẫn dự án của bạn, gõ lệnh “cscope –R –b cscope.out”. Mục đích của lệnh này là để cscope scan toàn bộ source code của dự án để tạo ra các tag (-R nghĩa là recursive, -b để lưu các tag được tạo ra lưu vào file cscope.out). Thời gian scan và tạo file tag cho dự án tùy thuộc vào độ lớn của code cũng như cấu hình của server. Sau lệnh này, bạn kiểm tra xem có file cscope.out trong đường dẫn này không:
Hình 1: Tạo file cscope.out
Sử dụng cscope
Sau khi tạo ra file tag của dự án, chúng ta có thể bắt đầu thử tìm kiếm để xem sức mạnh của cscope nhé. Ở đây mình sẽ demo trên source code của linux kernel phiên bản 4.14.1 (14 GB).
Có thể tìm kiếm ở trong giao diện GUI của cscope hoặc ngay trong cửa sổ mở file của vi/vim.
Giao diện GUI của cscope
Để mở giao diện GUI của cscope, trong đường dẫn của dự án (chứa file cscope.out), gõ lệnh “cscope -d”, trên màn hình sẽ xuất hiện giao diện tìm kiếm sau:
Hình 2: Giao diện GUI của cscope
Mình sẽ giải thích tính năng tìm của một số dòng lệnh tìm kiếm hay dùng dưới đây:
- Find this C symbol: tìm kiếm theo symbol, hiểu đơn giản là tìm kiếm toàn bộ nơi nào chứa khai báo, định nghĩa, sử dụng của hàm/biến
- Find this global definition: Tìm kiếm nơi định nghĩa của hàm/biến
- Find functions called by this function: Liệt kê các hàm được hàm này gọi
- Find functions calling this function: Liệt kê các hàm gọi hàm này
- Find this text string: Tìm kiếm theo text, tương tự với câu lệnh grep
- Find this file: Tìm kiếm theo tên file
Ví dụ, nếu gõ vào dòng “Find this global definition” hàm register_chrdev_region, cscope sẽ mở và trỏ đến dòng chứa hàm này.
Hình 3. Tìm kiếm trong cscope GUI
Hoặc nếu gõ hàm register_chrdev_region vào dòng “Find functions calling this function”, cscope sẽ liệt kê các hàm gọi hàm này:
Hình 4: Tìm kiếm trong cscope GUI
Để thoát khỏi giao diện GUI của cscope, chúng ta nhấn tổ hợp CTRL+D.
Dùng cscope trong cửa sổ vi/vim
Điều làm cscope hữu ích hơn nữa là chúng ta có thể tìm kiếm ngay trong khi đang mở file bằng vi/vim mà không cần phải thoát ra để mở giao diện GUI của cscope. Chúng ta còn có thể nhảy đến nơi muốn tìm kiếm, sau đó quay lại nơi bắt đầu tìm kiếm 1 cách dễ dàng, qua đó không làm gián đoạn quá trình trace code. Để làm được điều này, cscope cung cấp 1 số phím tắt để thực hiện các tính năng tìm kiếm tương tự như giao diện GUI sau:
- CTRL + ]: Nhảy đến định nghĩa của biến/hàm
- CTRL + T: Quay trở về điểm trước
- CTRL + \ + s: Tìm kiếm symbol của biến/hàm
- CTRL + \ + c: Tìm kiếm nơi gọi biến/hàm
- CTRL + \ + t: Tìm kiếm theo text
- CTRL + \ + d: Tìm những hàm mà hàm này gọi
Ví dụ, bạn dùng câu lệnh “vi fs/char_dev.c” để mở file char_dev.c rồi trỏ đến hàm register_chrdev_region():
Hình 5. Tìm kiếm trong cửa sổ vi/vim
Chúng ta thấy hàm register_chrdev_region() sẽ gọi đến hàm __register_chrdev_region() và sử dụng biến struct char_device_struct *cd, bạn chỉ cần nhấn tổ hợp phí “CTRL + ]”, cscope sẽ nhảy đến định nghĩa của biến hoặc hàm này, sau khi xem xong bạn nhấn tổ hợp phím “CTRL T” để quay trở lại hàm register_chrdev_region() như lúc đầu.
Ngoài ra, chúng ta còn có thể tìm kiếm từ khóa bất kỳ trong cửa sổ vi/vim bằng các câu lệnh sau (giả sử từ bạn muốn tìm kiếm là "var_func"):
- cs find g var_func: tìm kiếm định nghĩa (global definition) của var_func
- cs find s var_func: tìm kiếm symbol của var_func
- cs find c var_func: tìm kiếm nơi gọi var_func
- cs find t var_func: tìm kiếm theo text cho var_func
Ví dụ, khi đang ở trong 1 file bất kỳ, bạn muốn tìm kiếm định nghĩa hàm register_chrdev_region(), bạn gõ câu lệnh sau trong vi/vim “cs find g register_chrdev_region()”, cscope sẽ nhảy đến định nghĩa của hàm này:
Hình 6: Tìm kiếm trong cửa sổ vi/vim
Sau đó, bạn có thể tìm kiếm tiếp bằng phím tăt, hoặc gõ “CTRL + T” để quay trở lại file trước.
Như vậy là chúng ta đã làm quen với các thao tác và tính năng cơ bản của cscope trong môi trường vi/vim. Việc sử dụng cscope cũng không khó khăn gì phải không? Theo cá nhân mình thấy nhiều người có thể ngại dùng là do vi/vim có quá nhiều phím tắt khó nhớ, mà lúc làm việc gấp gáp nên không đủ kiên nhẫn để sử dụng vi/vim. Vậy nên mình tổng hợp lại 1 số phím tắt quan trọng dùng trong môi trường vi/vim dưới đây. Thuộc những phím tắt này đủ để các bạn sử dụng vi/vim trong tìm kiếm và chỉnh sửa source code, tất nhiên là nếu nhớ được càng nhiều phím tắt khác thì càng tốt.
- SHIFT + *: tìm kiếm từ trong cửa sổ vi/vim
- N: nhảy đến từ tìm kiếm tiếp theo,
- CTRL +N: Nhảy đến từ tìm kiếm trước đó
- : + f: Hiển thị tên file đang mở
- [ + [ : Nhảy đến đầu hàm con trỏ đang đứng
- Quét chuột bôi đen + d: Cut đoạn code bôi đen
- Quét chuột bôi đen + y: Copy đoạn code bôi đen
- d+d: cut dòng code con trỏ đang đứng
- y+y: copy dòng code con trỏ đang đứng
- p: Dán đoạn code vừa cut/copy vào vị trí của con trỏ
Thêm 1 tip nữa cho nhiều bạn quen làm việc bằng cách lăn chuột mà than phiền trong vi/vim ở máy mình không dùng được. Các bạn có thể cài đặt dùng chuột trong vi/vim bằng cách thêm dòng "set mouse=a" vào file /etc/vim/vimrc hoặc file tương đương của vi/vim.
Kết luận
Sử dụng vi/vim kết hợp với cscope là công cụ rất hữu ích cho các kỹ sư phần mềm. Điểm mạnh của nó là tiện vì không cần cài các phần mềm IDE như source insight (có thể phải mua bản quyền) hoặc sublime text. Bạn thử tưởng tượng có thể trace, view và compile source code luôn trong môi trường của server có tiện lợi hơn rất nhiều so với việc phải cài samba, map code về máy local rồi tạo project làm việc trên máy local của mình. Điểm mạnh thứ hai là nhanh vì server làm việc thường có cấu hình cao nên tìm kiếm nhanh chóng hơn máy local làm việc. Việc sử dụng cscope trong vi/vim có thể hơi khó khăn ban đầu nhưng chỉ cần thực hành khoảng vài lần thì bạn sẽ quen và thấy được sự tiện lợi của nó.