分类 技术志 下的文章

成功Build ACE

近期公司实行新的绩效考核机制,我的考核目标中就有一项叫做:"成功使用新技术、框架、思路等至少3个",呵呵,先不论绩效考核机制是否合理,既然已经这样了那就需要去适应。一直在做Network Application,早就知道ACE在业界中的名气,这回有理由找个时间好好挖掘一下ACE的思路,也为我的绩效目标增色啊^_^。

以上只是开个玩笑罢了。上周末去书店看到电子工业出版社再次出版的'C++网络编程卷一',这套书的卷1以及卷2的英文电子版我早已有了,但是还是喜欢抱着纸板书看书的那种感觉,所以就顺便买了下来。翻看了一下,发现里面的内容恰恰是现在我所需要的,如果是前两年看这本书,理解起来肯定不会很透彻,因为那时的心中缺少的是恰恰是问题和困惑,没有了那些东西看书的效果也就大打折扣;反之如果作者的思路恰恰是把你扶上的正确的思维轨道,以帮助你解决了心中的那个结,你的收获就会是大大的。

记得前年的时候曾经下载过ACE并且尝试从源代码Build,结果是失败了,原因现在已经记不清了;这次重新下载ACE-5.5版本在Solaris 9上用G++ 3.2编译,居然顺利通过,其功劳应该归功于ACE的开发者之一Stephen D. Huston的'The ACE Programmers Guide'一书,而且从ACE自带文档中得知,ACE最先就是在Solaris上开发的。

Build过程:
1. 下载ACE的源码包;解包解压,一般你会在当前目录下获得一个名为'ACE_wrappers'的目录;
2. 设置ACE_ROOT环境变量;如我用的是csh,我就会在用户的HOME路径下的.cshrc中增加一个环境变量ACE_ROOT,比如:setenv ACE_ROOT '/export/home1/baim/ACE_wrappers';
3. 切换路径到$ACE_ROOT/ace/下,创建config.h,在这个头文件中,我们需要做一件事,就是include一个你所在的编译平台的头文件,比如我是在Sun Solaris 9上编译的,我的config.h中的内容就是这样的:
//config.h
#include "config-sunos5.9.h"

不同的平台,包含的头文件不同,这些头文件也都在$ACE_ROOT/ace/下,你可以用'ls -l|grep config'来看看究竟有哪些config头文件,选择你所在平台对应的即可。

4. 切换到$ACE_ROOT/include/makeinclude下,创建一个叫'platform_macros.GNU'的文件,同样这里也有平台相关的一堆.GNU文件,我们只需在我们新建的platform_macros.GNU文件中包含对应文件即可。
如我用g++在Solaris 9上编译,我就该选择:platform_sunos5_g++.GNU
//platform_macros.GNU
include $(ACE_ROOT)/include/makeinclude/platform_sunos5_g++.GNU

这个文件里还可以放置make的编译选项,比如我要生成.a文件,我可以这么做:
//platform_macros.GNU
static_libs=1
include $(ACE_ROOT)/include/makeinclude/platform_sunos5_g++.GNU

5. 切换到$ACE_ROOT/ace/下,输入make命令执行即可。编译的过程是漫长的,大约1个小时,之后你就会发现在$ACE_ROOT/ace/下有libACE.so -> libACE.so.5.5.0*、libACE.so.5.5.0*和libACE.a出现了。

构建过程到此结束。

ACE的makefile没有.phony install,所以在你的ACE应用程序里可直接引用$(ACE_ROOT)/ace下面的头文件,直接链接$(ACE_ROOT)/ace下面的libACE.a库即可。

//HelloACE.cpp
#include "ace/Log_Msg.h"

void foo (void);

int ACE_TMAIN (int, ACE_TCHAR *[])
{
  ACE_TRACE(ACE_TEXT ("main"));

  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHi Mom\n")));
  foo();
  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IGoodnight\n")));

  return 0;
}

void foo (void)
{
  ACE_TRACE (ACE_TEXT ("foo"));

  ACE_DEBUG ((LM_INFO, ACE_TEXT ("%IHowdy Pardner\n")));
}

//编译
g++ -o HelloACE HelloACE.cpp -I$ACE_ROOT -I./ -L$ACE_ROOT/ace -lACE  -lsocket -ldl -lgen -lnsl -lposix4 -lthread

这里有几点注意事项:
1、如果libACE.so.5.5.0*和libACE.a都同时在$ACE_ROOT/ace下的话,上面的编译命令默认优先进行动态链接。也就是说编译出来的可执行程序HelloACE在运行的时候如果找不到libACE.so.5.5.0就会报错。
2、如果想进行静态链接的话,可以将$ACE_ROOT/ace下的libACE.so.5.5.0删除或者改名,这样在执行上面的编译命令后即是静态链接。
3、注意g++链接.a和.o时是有顺序的,g++从左到右读入目标文件或.a文件中的符号,如果靠右边的目标文件或者.a文件中没有靠左面的目标文件或者.a文件中的未定义的符号定义的话(或者白话一点说:右边没有左边想要的),程序就会报错。比如我们把上述的编译命令改一下,改为:
g++ -o HelloACE -I$ACE_ROOT -I./ -L$ACE_ROOT/ace -lACE  -lsocket -ldl -lgen -lnsl -lposix4 -lthread HelloACE.cpp
执行命令后,会出现下面错误提示:

未定义                  文件中的
 符号                       在文件中
ACE_Log_Msg::log(ACE_Log_Priority, char const*, …)/var/tmp//ccBl9Q0L.o
ACE_Log_Msg::last_error_adapter()      /var/tmp//ccBl9Q0L.o
ACE_Log_Msg::conditional_set(char const*, int, int, int)/var/tmp//ccBl9Q0L.o
ACE_Log_Msg::instance()             /var/tmp//ccBl9Q0L.o
ld: 致命的: 符号参照错误. 没有输出被写入HelloACE
collect2: ld returned 1 exit status

实际上上面的命令g++ -o HelloACE -I$ACE_ROOT -I./ -L$ACE_ROOT/ace -lACE  -lsocket -ldl -lgen -lnsl -lposix4 -lthread HelloACE.cpp等价于下面两个命令:

g++ -c -I$ACE_ROOT -I./ HelloACE.cpp
g++ -o HelloACE -L$ACE_ROOT/ace -lACE  -lsocket -ldl -lgen -lnsl -lposix4 -lthread HelloACE.o

其实上面错误提示中的"/var/tmp//ccBl9Q0L.o",其实就是一个匿名的HelloACE.o

另外在'The ACE Programmers Guide'一书中,作者给了个Makefile,如下:
BIN   = HelloACE
BUILD = $(VBIN)
SRC = $(addsuffix .cpp,$(BIN))
LIBS =
LDFLAGS = -L$(PROJ_ROOT)/lib
#—————————————————
#Include macros and targets
#—————————————————
include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU
include $(ACE_ROOT)/include/makeinclude/macros.GNU
include $(ACE_ROOT)/include/makeinclude/rules.common.GNU
include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU
include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU
include $(ACE_ROOT)/include/makeinclude/rules.local.GNU

直接用该Makefile会让你的build更简洁,另外还有支持多个.cpp文件的Makefile在那本书里,大家可以参考。

开发人员之维护他人项目有感

软件行业人员流动比较频繁,如果你是一个公司的老员工,你常常会有如此经历:一个同事即将离职,领导可能分配你去与之进行工作交接,有时他做过的项目很可能和你做过的有很大差距,没办法领导发话了,你还是要硬着头皮接下来,心中盘算着但愿这个项目的产品在现场运行不要出现什么问题或者用户最好一个新需求都不要提,这样就算是挂个名,也没什么大不了的。

可是事情往往是事与愿违,需求变化速度之快让你猝不及防,这时如果你接手的维护项目和你做的东西是一个套路的,那也许还并不是很头疼,顶多花上一段时间就可以搞定,但是如果你像我一样,接手了一个多年都不接触的,有复杂业务逻辑的项目维护,那简直就是一种折磨呀,如果还是在你自己手头上的活加班都做不完的情况下,则更是让你抓心挠肝了^_^。

这不五一前一个同事离职,按照领导的意志,其项目维护暂由我来接替。恰逢最近忙于系统的结构设计,进度吃紧之关头,这个维护的项目要进行现场软件升级,由于以前版本控制不是很好,导致居然找不到对应的Release版本,无奈之下只能基于其中一个版本修改,采用比较不精密的方式:文件比对,花了若干时间,才勉强拿出一个版本交给现场的实施人员进行升级。运行一段时间过后,现场维护发现出了问题,并反馈回来。无奈之下,开始博览成千上万行的代码,无果。打电话问离职人员,几番交流之后,发现原来改动时基于的版本不对,原因是他在修改一个版本后忘记做记录了,唉,还好,这个版本代码还在,文件比对后,发现改动的地方就两行代码。之前看了若干小时的代码的我本来也想这么改的,呵呵。

我一直在Unix下开发,而这个维护项目是Windows上的使用Visual C++开发的,昨天无奈下装上Visual C++。

把新的Release版本发给远方的维护后,我心里在想:在这种情况下一定要端正态度啊,无论如何这都是你的活,摆正心态解决问题才是正道,否则抱怨只能延缓你解决问题的时间。当然了,谁接到这样的活心里不是别别扭扭的,刚开始都不例外。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats