鉴于自己一直都是在做客户端开发方面的工作,服务端很多知识都随着时间淡忘了,最近有一个计划,用一些时间补一下基础.所以早上很早就起床,花了一点时间大致浏览了一下BSD socket的相关API,然后用GNU C写了一个简单的多线程,阻塞EchoServer.工程的代码倒是不多,就是基于原生API开发,总是有很多的errcode需要处理,比较的烦.所以我干脆就直接写了个宏去处理,简单的输出strerrno(errno)和errno就好.虽然这个宏实现起来比较的简单,但是还是感觉比较的值,节省了不少的代码.而且整体的流程更简单明了.
本来是在写代码的,我是用CMake写的项目组织,当然,就几个文件,用CMake简直就是大材小用.但是也正是在这种情况下,更能体验CMake的强大.我用emacs收邮件的时候就想到了emacs的cedet插件中有个ede工程管理模块,所以就上手折腾了一下.期间浪费了一点时间,浪费在我国伟大的天朝上面,没办法,就是不给下载,后来干脆去github clone了1.1版本的插件包.
可能有一些新手在编译cedet包的时候会遇到一些问题,在编译文档的时候,如果确实需要的话,那么可以 sudo apt-get install texinfo.如果不需要,那么就直接make makeinfo=echo就好了.主要是你有没有在编译之前先查看一下文档,这个就不多说了,是常识.下面是我的cedet配置,很简单,只是配置了一些快捷键,其他的都还没弄,有时间再算吧.
1 ;;------------------------------------------------------------------ 2 ;;%% 打开显示行,列模式(行号显示为4位数) 3 ;;------------------------------------------------------------------ 4 (global-linum-mode t) 5 (column-number-mode t) 6 (setq linum-format "%4d\u2502") 7 8 ;;------------------------------------------------------------------ 9 ;;%% 关闭图标工具栏,打开ido模式 10 ;;------------------------------------------------------------------ 11 (tool-bar-mode -1) 12 (ido-mode t) 13 14 ;;------------------------------------------------------------------ 15 ;;%% 关闭自动备份设置,关闭自动保存 16 ;;------------------------------------------------------------------ 17 (setq-default make-backup-files nil) 18 (setq auto-save-default nil) 19 20 ;;------------------------------------------------------------------ 21 ;;%% 使用简单的y/n应答模式 22 ;;------------------------------------------------------------------ 23 (fset 'yes-or-no-p 'y-or-n-p) 24 25 ;;------------------------------------------------------------------ 26 ;;%% 高亮显示拷贝,括号配对 27 ;;------------------------------------------------------------------ 28 (global-font-lock-mode 1) 29 (transient-mark-mode 1) 30 (show-paren-mode 1) 31 (mouse-wheel-mode t) 32 33 ;;------------------------------------------------------------------ 34 ;;%% 设置默认字体,字体大小 35 ;;------------------------------------------------------------------ 36 (set-default-font "Ubuntu Mono-11") 37 38 ;;------------------------------------------------------------------ 39 ;;%% 设置tab缩进格式 40 ;;----------------------------------------------------------------- 41 (setq indent-tabs-mode nil) 42 (setq tab-width 4) 43 ;;------------------------------------------------------------------ 44 ;;%% 加载配置color-theme插件 45 ;;------------------------------------------------------------------ 46 (add-to-list 'load-path "~/.emacs.d/color-theme-6.6.0") 47 (require 'color-theme) 48 (color-theme-initialize) 49 50 ;;------------------------------------------------------------------ 51 ;;%% 加载配置auto-complete插件 52 ;;------------------------------------------------------------------ 53 (add-to-list 'load-path "~/.emacs.d/auto-complete-1.3.1") 54 (require 'auto-complete-config) 55 (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict") 56 (ac-config-default) 57 58 ;;------------------------------------------------------------------ 59 ;;%% 加载配置yasnippet插件 60 ;;------------------------------------------------------------------ 61 (add-to-list 'load-path "~/.emacs.d/yasnippet") 62 (require 'yasnippet) 63 (yas-global-mode 1) 64 65 ;;------------------------------------------------------------------ 66 ;;%% 默认启动多窗口调试 67 ;;------------------------------------------------------------------ 68 (setq gdb-many-windows t) 69 ;;------------------------------------------------------------------ 70 ;;%% 加载配置tabbar插件,定义快捷键 71 ;;------------------------------------------------------------------ 72 (add-to-list 'load-path "~/.emacs.d/tabbar/") 73 (require 'tabbar) 74 (tabbar-mode) 75 76 (global-set-key (kbd "<M-up>") 'tabbar-backward-group) 77 (global-set-key (kbd "<M-down>") 'tabbar-forward-group) 78 (global-set-key (kbd "<M-left>") 'tabbar-backward) 79 (global-set-key (kbd "<M-right>") 'tabbar-forward) 80 81 (set-face-attribute 'tabbar-default nil 82 :family "Ubuntu Mono" 83 ) 84 (set-face-attribute 'tabbar-button nil 85 :inherit 'tabbar-default 86 :box '(:line-width 1 :color "yellow") 87 ) 88 (set-face-attribute 'tabbar-selected nil 89 :inherit 'tabbar-default 90 :foreground "blue" 91 :background "gray" 92 :box '(:line-width 1 :color "yellow") 93 ) 94 (set-face-attribute 'tabbar-unselected nil 95 :inherit 'tabbar-default 96 :box '(:line-width 1 :color "yellow") 97 ) 98 99 ;;------------------------------------------------------------------ 100 ;;%% 加载配置cedet插件 101 ;;------------------------------------------------------------------ 102 (add-to-list 'load-path "~/.emacs.d/cedet-1.1/common") 103 (require 'cedet) 104 (global-ede-mode 1) 105 ;;(semantic-load-enable-code-helpers) 106 (global-srecode-minor-mode 1) 107 108 ;;(semantic-load-enable-minimum-features) 109 (semantic-load-enable-code-helpers) 110 ;;(semantic-load-enable-gaudy-code-helpers) 111 ;;(semantic-load-enable-excessive-code-helpers) 112 (semantic-load-enable-semantic-debugging-helpers) 113 114 (require 'semantic-gcc) 115 (require 'semantic-ia) 116 117 (defun my-cedet-hook() 118 119 (local-set-key [(control tab)] 'semantic-ia-complete-symbol-menu) 120 121 (local-set-key "\C-c?" 'semantic-ia-complete-symbol-menu) 122 (local-set-key (kbd "M-/") 'semantic-ia-complete-symbol) 123 124 (local-set-key "\C-c>" 'semantic-complete-analyze-inline) 125 (local-set-key (kbd "M-n") 'semantic-complete-analyze-inline) 126 127 (local-set-key "\C-cp" 'semantic-analyze-proto-impl-toggle) 128 (local-set-key "\C-cd" 'semantic-ia-fast-jump) 129 (local-set-key "\C-cr" 'semantic-symref-symbol) 130 (local-set-key "\C-cR" 'semantic-symref)) 131 (add-hook 'c-mode-common-hook 'my-cedet-hook) 132 133 ;;%% 配置项目解析tag路径 134 ;; (setq semanticdb-project-roots (list (expand-file-name "/"))) 135 (defconst cedet-user-include-dirs 136 (list ".." "../include" "../inc" "../common" "../public" 137 "../.." "../../include" "../../inc" "../../common" "../../public")) 138 (defconst cedet-win32-include-dirs 139 (list "C:/MinGW/include" 140 "C:/MinGW/include/c++/3.4.5" 141 "C:/MinGW/include/c++/3.4.5/mingw32" 142 "C:/MinGW/include/c++/3.4.5/backward" 143 "C:/MinGW/lib/gcc/mingw32/3.4.5/include" 144 "C:/Program Files/Microsoft Visual Studio/VC98/MFC/Include")) 145 (require 'semantic-c nil 'noerror) 146 (let ((include-dirs cedet-user-include-dirs)) 147 (when (eq system-type 'windows-nt) 148 (setq include-dirs (append include-dirs cedet-win32-include-dirs))) 149 (mapc (lambda (dir) 150 (semantic-add-system-include dir 'c++-mode) 151 (semantic-add-system-include dir 'c-mode)) 152 include-dirs)) 153 ;;------------------------------------------------------------------ 154 ;; 加载配置ecb插件 155 ;;------------------------------------------------------------------ 156 (add-to-list 'load-path "~/.emacs.d/ecb") 157 (require 'ecb) 158 (setq stack-trace-on-error nil) 159 (setq ecb-tip-of-the-day nil) 160 161 ;;-------------------------------------------------------------------
下面就来说说ede插件该如何用,首先就是M-x ede- TAB TAB 会弹出buffer 查看ede-*命令,这些命令还是比较容易懂的.先创建一个ede工程项目 : M-x ede-new RET, 按照要求输入,在选择项目类型的时候可以看到提供了好多种的选择,其中需要关注的就是两种:Make,Automake,其他的不属于本文范畴,可以自己去了解.
作为一个例子,我选择的是Automake,并在AutomakePrj下面创建了一个源文件main.c,里面就是一个简单的main入口方法.,输入项目名称也为:AutomakePrj.做完这些之后,还没有生成automake相关的配置,用过automake的都知道,一般都是在Makefile.am和configure.ac中书写配置,用来生成configure,然后生成Makefile.
执行M-x ede-proj-regenerate或者是在emacs menu-bar上面的project中选择->project options->regenerate makefiles.之后由于automake的规范要求还会提示你创建AUTHOR MISSING等一系列的文件,其中有些配置是根据系统变量或者是emacs配置变量自动填充的,需要修改的话自己去改吧.执行的过程是这样子的:
这里也就是automake执行的过程,通常我们也会将前面一些繁琐的步骤写成一个auto_gen.sh的脚本,在一些开发包中也是可以见得到的,这个就顺便提一下.现在是创建了模板,但是还没有添加我们需要编译的target, 相应的也是可以执行M-x ede-add-target, 可供选择的类型也是很多:
这里我就直接选择了生成program.接下来就可以直接执行M-x ede-compile-project了.另外,ede也提供了debug/release模式的选择,很容易切换 M-x ede-project-configuration-set debug|release.如果是启用了debug模式,那么ede还可以直接debug我们的target,我将emacs的debug模式默认设置成为启动gdb-many-windows,所以debug就很容易了.
使用emacs ede工程组织插件的这种管理方式,不推荐直接使用在实际的项目中,更好的选择是自己去使用automake/cmake去组织,二者之间,我倾向的选择是cmake.随便下载一个开源库,搜索其中的CMakeLists.txt就能知道使用cmake是多么的简单了.我这样选择,是因为经常会用C去写一些小项目(或者是算不上项目的散碎程序),自己不喜欢写Makefile,cmake倒是使用的还不错,只是喜欢使用emacs编码慢悠悠的节奏感,这是我的出发点,可能有点荒唐,我也不期望被大多数同行理解.