执行脚本 ./configure
configure:它能根据不同的系统,产生不同的 Makefile,从而使我们的程序具有可移植性。它还有一些参数:
参数 | 描述 |
---|---|
–cache-file=FILE | 测试系统的特性,并将结果放到FILE中 |
–help | 输出帮助信息 |
–no-create | 阻止其生成输出文件 |
–quiet | 执行是不做输出 |
–silent | 同上,若设置则不会有任何输出到屏幕 |
–version | 输出automake的版本号 |
这篇帖子很棒!我从百度文库中下载了 此教程,因为未做深度的考证,所以也不知原作者是谁,但在此谢谢作者。以下是作者原文,略有删改,本人有修改部分都已做出备注。
使用过开源 C/C++ 项目的同学们都知道,标准的编译过程已经变成了简单的三部曲:configure/make/make install, 使用起来很方便,不像平时自己写代码,要手写一堆复杂的 Makefile,而且换个编译环境,Makefile 还需要修改(Eclipse 也是这样)。
这么好的东东当然要拿来用了,但 GNU 的 Autotool 系列博大精深,工具数量又多,涉及的语言也多,要是自己从头看到尾,黄花菜都凉了,项目估计早就结束了;上网搜样例倒是有一大堆,但都是“hello world”的样例,离真正完成大型项目的目标还差得远。
没有办法,对照网上的样例,再找几个开源的源码,然后参考各种 Autotools 的手册,花了 2 天时间,终于完成了一个基本可用的 Autotools。为了避免其他 XDJM 也浪费时间,因此将过程总结下来,就算是新年礼物,送给大家!!
通用唯一识别码(英语:Universally Unique Identifier,简称 UUID)的标准型式包含 32 个 16 进制数字,以连字号分为五段,形式为 8-4-4-4-12 的 32 个字符。示例:
550e8400-e29b-41d4-a716-446655440000
接下来重点描述在开发中的使用及应用。
C++ 原生(C++03、C++11/0x)并不支持 UUID。所以要想在 C++ 代码中生成 UUID,如果要求跨平台推荐使用第三方库 Boost UUID,要么结合各自的平台,使用系统 API。以下方法整理自互联网,除 Boost Uuid 和 libuuid 使用过之外,其他的未亲自试验。
在 StackOverflow 上的一个例子:跳转链接
1 | #include <iostream> |
如果以上例子满足不了你的需求,需要在更复杂的情景下使用,请移步 Boost Uuid 官方文档。
Qt 是一个跨平台的 C++ 编程框架,QUuid
类实现了 UUID 的生成、比较、转换等功能。
函数 QUuid createUuid()
,可用于生成 UUID。示例如下:
1 | #include <iostream> |
Unix/Linux 环境中大都有一个名为 uuidgen 的小工具,运行即可生成一个 UUID 到标准输出。读取文件 /proc/sys/kernel/random/uuid
即得UUID,例如:
cat /proc/sys/kernel/random/uuid
libuuid 是一个用于生成 UUID 的 C 库,具体用法参考 http://linux.die.net/man/3/libuuid,示例如下:
1 | #include <stdio.h> |
在 Linux 下编译时需要链接 uuid 库
gcc -o uuid uuid.c -luuid
问题: 在什么系统下自带?在什么系统中需要另行安装?
在 Ubuntu 中,可以用下面的命令安装 libuuid:
sudo apt-get install uuid-dev
Windows 下提供了函数 CoCreateGuid
用于生成 GUID。需要使用的头文件是 #include <objbase.h>
,需要链接的库是 ole32.lib
,函数原型为:HRESULT CoCreateGuid(GUID *pguid);
,GUID 的原型为
1 | typedef struct _GUID |
1 | #pragma comment(lib, "rpcrt4.lib") // UuidCreate - Minimum supported OS Win 2000 |
工作中偶尔会写一些 Java 的项目,所以也捎带整理一下。
MySQL 本身是带有生成 uuid 功能的。也就是我们惯用的整数递增作为主键,其实是可以用 uuid 替代的。可以在一条记录插入之前写触发器,调用 UUID()
函数生成 uuid。
C/C++ 的 socket 编程。开篇
socket 编程,入门学习非常推荐吴秦的 Linux Socket编程(不限Linux)。当做学习 socket 编程的第一篇完全足够,甩开网上其他的帖子一万八千里,强烈推荐。本意是整理 socket 的学习笔记,但有上述帖子完全足够,在此只记录一些“边边角角”的零碎知识。
手册推荐:Beej’s Guide to Network Programming
htonl()
函数、htons()
函数在吴秦的博客里重点强调了主机字节序(host byte order)与网络字节序(network byte order)的,上述两个函数就是用来实现两者之间的转换的。参考 Beej’s Guide to Network Programming 我们能够找到以下函数原型:
1 | #include <netinet/in.h> |
不需要死记硬背,函数的命名通俗易懂。强调一下,转换 ip 地址使用长整型转换函数,转换 port 使用短整型转换函数。我在码代码学习时,误用 htonl(6666);
转换端口编译通过,运行时也不报错,启动多个服务程序也不报错 ps 正常情况重复启动服务程序时会报错“端口已经占用”。
INADDR_ANY
宏详细解释参考 understanding INADDR_ANY for socket programming - c。在此只强调一点,INADDR_ANY
表示的是一个服务器上所有的网卡。
inet_pton()
函数IP地址转换函数,可以在将 IP 地址在“点分十进制”和“二进制整数”之间转换。在 Beej’s Guide to Network Programming 我们找到的描述以及函数原型:
Convert IP addresses to human-readable form and back.
1 | #include <arpa/inet.h> |
强调一点,inet_pton()
同样支持 “localhost”。
inet_addr()
函数Convert IP addresses from a dots-and-number string to a
struct in_addr
and back
1 | #include <sys/socket.h> |
我们可以看到其中的注释,这三个函数即将淘汰。
select()
函数第一个参数为什么要 maxfd+1
?不理解 官方手册 中讲述 select()
低效的这段话:
On the userspace side, …But on the kernel side,…
为什么在 Example: select()-based ROT13 server 中需要 make_nonblocking()
?为什么 Example: A low-level ROT13 server with Libevent 中需要 evutil_make_socket_nonblocking()
?
setvbuf(stdout, NULL, _IONBF, 0);
的意义?
最初步的认识,最简单的例子:使用libevent输出Hello
(niel)这里只提到了
strcut event_base
、struct event
。给出的简单示例代码里,有一处瑕疵:event_base_set()
函数属于过时的函数,在 2.0 之前的版本中配合event_set()
使用,在 2.0 及其之后的版本中这两者被event_new()
替代,所以作者混用event_new()
+event_base_set()
表明了作者并未多花时间学习。
接下来,我们可以学习一下:libevent入门教程:Echo Server based on libevent
(niel)这篇博客循序渐进,讲到了
strcut buffevent
及其相关操作。美中不足的是作者在介绍过程中穿插记录了自己的疑惑,新手读起来打破了学习的连贯性,本就在学习新知识,却也要困于作者的“泥潭”。只能说这真的只是作者的学习笔记,并未从读者的角度做考虑。总的来说,帖子很不错!初次学习时,这些问题的存在让人很难受,影响学习进度、学习动力;但熟悉作者讲的知识之后,这些问题反而才是“金子”,认真思考这些问题。
接下来推荐的学习资源就是官方手册了:Programming with Libevent
(niel)虽然是用英文写的,但阅读起来毫无障碍,很容易理解。marks C0、C1、R0 ~ R4、R8 认真阅读;R5、R6 重点关注了小部分函数,其余走马观花浏览了一下;R6a、R7、R9 三节没有看。开发过程中,查阅函数原型肯定是得翻这个手册的!
Libevent 官方文档学习笔记,这篇帖子可以看一看,和自己读英文手册理解的相互佐证。
Libevent学习笔记(一):基本使用,检验自己的学习成果。
总的来说,后面这两篇帖子并不适合用来学习。更多的定位于作者知识的整理,并不是面向新手的入门介绍。
2015年12月22日 14:48:52
这个标题《Makefile 自动生成》 8 号立的,拖到今天刚好两周。ps 2017/8/24 14:04:25 删改了 2/3 的内容,改为现在的标题。
一方面因为最近在忙别的工作,整理数据库表结构的;另一方面,是直到今天,对于自动生成 Makefile 操作依旧懵懵懂懂,在实际项目中无法使用,还是自己手动写 Makefile 文件。下面进入主题。
Makefile 自动生成,实际项目中接触到的工具有:easymake、cmake 和 autotools。 在这里只整理 autotools。
autotools 作为重点学习,所以发现了很多篇不错的帖子。
2015年11月6日 16:57:34
最全的学习材料当然是 GCC 的官方文档。如果有耐心但是英语不好的话,可以参看一下 这个网站。先说
gcc -E
仅作预处理,即只激活预处理,不进行编译、汇编和链接 {通常以什么为后缀?}
$gcc -E main.c -o main.i
gcc -s
编译到汇编语言,不进行汇编和链接,即只激活预处理和编译,生成汇编语言
$gcc -S main.i -o main.s #参数-S,大写
gcc -c
编译、汇编到目标代码,不进行链接,即只激活预处理、编译和汇编功能,生成目标文件(.o)
$gcc -c main.s -o main.o
生成,到执行文件 (根据依赖关系链接各目标文件,生成最终的执行程序)
$gcc main.o printf1.o printf2.o -o main
2015年12月8日 16:48:31
此中测试代码见笔记 《Makefile入门》
2016年1月4日 10:05:04
shell提供了参数置换能力以便用户可以根据不同的条件来给变量赋不同的值。参数置换的变量有四种,这些变量通常与某一个位置参数相联系,根据指定的位置参数是否已经设置类决定变量的取值,它们的语法和功能分别如下。
变量=${参数-word}
:如果设置了参数,则用参数的值置换变量的值,否则用 word 置换。即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于 word 的值。变量=${参数=word}
:如果设置了参数,则用参数的值置换变量的值,否则把变量设置成 word 然后再用 word 替换参数的值。注意,位置参数不能用于这种方式,因为在 shell 程序中不能为位置参数赋值。变量=${参数?word}
:如果设置了参数,则用参数的值置换变量的值,否则就显示 word 并从 shell 中退出,如果省略了 word,则显示标准信息。这种变量要求一定等于某一个参数的值,如果该参数没有设置,就显示一个信息,然后退出,因此这种方式常用于出错指示。变量=${参数+word}
:如果设置了参数,则用 word 置换变量,否则不进行置换。2016/3/16 12:17:18
汇总 3 篇。此处 shell 指工具,不涉及 shell 编程、脚本等知识。
Shell 是什么呢? 确切地说,Shell 就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给操作系统内核,它为用户提供了一个向 Linux 发送请求以便运行程序的接口,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。
Linux Shell的种类 很多,目前流行的 Shell 包括 ash、bash、ksh、csh、zsh 等,用户可以通过查看 /etc/shells 文件中的内容来查看自己主机中当前有哪些种类的 Shell。