不用BJAM编译心得(1)

sevencat 2003-06-17 10:25:05
上次把BOOST包下载下来了,1.3.0的,总共大概是5M多大小吧(压缩后大小)。
看了文档,才知道要用个什么BJAM来编译,而且那东西我编译后一看还是DOS命令行参数的,
像我这种被WIN宠坏的人不是很习惯的(虽然我在DOS时代DIR,FDISK的隐含参数都记得,UNIX的SHELL也记得好多呀)
也许高手都喜欢用命令行吧,或者说都用的是UNIX吧,第一反应就是将JAM原代码打开,想把这玩意儿改成
窗口模式的,后来慢慢发现要花去很多时间(那个JAM原代码基本是纯C写成的,所以用LCC就可以编译了)
而且有这个时间的话,我还不如去睡觉养精神呢。


反正都是原代码,我怕什么,下午正好有空,来拿这些东西开刀吧。
想要哪个库就直接编译哪个库好了。
BOOST这套库适应性很强(或者说能在很多操作系统和很多编译器下使用吧,因此肯定会有一些开关之类的文件
来对每个系统来进行配置,这就是boost\boost\config.hpp.

============================================================================
附:
我的目录结构
c:\boost
---boost 放头文件的(所有内容从boost\boost拷入)
---lib  放生成后的库文件的
---src  放原文件 
---DLL 放生成的DLL文件
---DLIB 放生成的debug lib
其他文件呢?被我删掉了或者移到其他地方了,因为我不会用到的
(VC++7.1已经比其他大部分编译器要好了,不知道是不是最好)。
你要是高兴的话,可以将boost目录直接放到你的系统的include目录下面去,就省得改头文件目录了。
不过我不太习惯。
===========================================================================
下面是我的以c:\boost\boost\config.hpp的内容
#pragma once
#include <boost/config/visualc.hpp>(编译器选项,这个文件其实很不错,
还有那个complier目录下的其他文件,就是说每个编译器
都有一个这样的文件,
能很明显的看出哪个编译器不支持哪个特性,
哪个编译器有什么已知的BUG)
gcc.hpp
borland.hpp
上面这两个就不用说了吧。
#include <boost/config/dinkumware.hpp>(标准库选项,NET2003的std版本就是这个Dinkumware standard lib
也就是有名的P.J.Plauger所搞的那一套了,
我现在用的版本号是_CPPLIB_VER=313(定义在文件yvals.h中)
当然假如你想要用STLPORT和BOOST合用的话,你有可能就要选用
stlport.hpp这个头文件了。
roguewave.hpp这个好像就是bcb里面的吧
libstdcpp3.hpp这个应该是对应g++3的吧
#include <boost/config/win32.hpp>  (平台选项)
大概支持LINUX,UNIX,BSD,MACOS,WIN32等等,我等懒人
就用WIN32吧。LINUX就让他去做服务器好了。

#include <boost/config/suffix.hpp>
我把上面三个文件都移到了boost/config下面了,并且删除该目录下面的所有子目录。
因为我基本上不会使用其他的操作系统或者编译器了,即使想用的话,到时候再从压缩包里面解出来就可以了。

注:
*事实上我感觉到VC7.1里面的minmax可能已经不存在BUG了,不过好像BOOST还是认为不行,还是自己重实现了。

*我的配置:
2000 professional sp3 810mainboard, 900C,128SDR
vc++13.10.3077(NET2003)
在头文件目录上加上c:\boost\boost
在库文件目录加上c:\boost\lib

就这样可以开始了吗?

建一个大的解决方案,肯定叫boost啦
一、测试thread库(好像用的人很多吧)

建一项目,就叫thread吧(lib输出的),
在c:\boost\src下面建thread目录,我准备所有的库都这样做,在SRC下面建对应的目录。
将所有的压缩包中boost\libs\thread\src里面的CPP文件拷至c:\boost\src\thread中
再将这些文件加到VC++项目中的原文件里面。
再将所有的boost\boost\thread\里面所有的*.hpp至头文件中,
项目属性中改链接库为_MT(多线程)
将boost\thread\detail\config.hpp中的BOOST_THREAD_DECL设为无了。

*这套类库里面很多都有各种选项,比如说输出DLL还是直接引用或者是LIB输出了
上面一个选项就是用在这个地方的,其实我认为就相当于一个DLL开关,这种技巧也是DLL的一种常用技巧了。

输出路径为c:\boost\lib和c:\boost\dlib
然后开始编译了,
测试成功后,又找了BOOST自带的EXAMPLE(注意加上刚才编译成功的链接库,不然直接用加一行什么lib之类的也可以)
,完全成功(测试时要注意DEBUG和RELEASE中的多线程链接库也不一样,要分开设置两个多线程库才行,
不然会说又什么东西找不到链接符号啦,或者有时还会说什么东西重复定义,基本上都是因为这个问题的)

...全文
195 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
sevencat 2003-06-17
  • 打赏
  • 举报
回复

*有的regex例子能解决一些大问题
像regex_merge_example.cpp: regex_merge example: converts a C++ file to syntax highlighted HTML.
这个例子就是能将C++文件改成语法高亮显示的HTML文件,简直是好多人梦想的东西啊,酷毙了。
我把这个改到了MFC下面就成了
==================
convert.cpp
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iterator>
#define BOOST_REGEX_STATIC_LINK //这行稍微注意点,我不知道有没有什么更好的办法来处理。
#include "convert.h"

const char* pre_expression = "(<)|(>)|\\r";
const char* pre_format = "(?1<)(?2>)";


const char* expression_text = // preprocessor directives: index 1
"(^[[:blank:]]*#(?:[^\\\\\\n]|\\\\[^\\n[:punct:][:word:]]*[\\n[:punct:][:word:]])*)|"
// comment: index 2
"(//[^\\n]*|/\\*.*?\\*/)|"
// literals: index 3
"\\<([+-]?(?:(?:0x[[:xdigit:]]+)|(?:(?:[[:digit:]]*\\.)?[[:digit:]]+(?:[eE][+-]?[[:digit:]]+)?))u?(?:(?:int(?:8|16|32|64))|L)?)\\>|"
// string literals: index 4
"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|"
// keywords: index 5
"\\<(__asm|__cdecl|__declspec|__export|__far16|__fastcall|__fortran|__import"
"|__pascal|__rtti|__stdcall|_asm|_cdecl|__except|_export|_far16|_fastcall"
"|__finally|_fortran|_import|_pascal|_stdcall|__thread|__try|asm|auto|bool"
"|break|case|catch|cdecl|char|class|const|const_cast|continue|default|delete"
"|do|double|dynamic_cast|else|enum|explicit|extern|false|float|for|friend|goto"
"|if|inline|int|long|mutable|namespace|new|operator|pascal|private|protected"
"|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_cast"
"|struct|switch|template|this|throw|true|try|typedef|typeid|typename|union|unsigned"
"|using|virtual|void|volatile|wchar_t|while)\\>"
;

const char* format_string = "(?1<font color=\"#008040\">$&</font>)"
"(?2<I><font color=\"#000080\">$&</font></I>)"
"(?3<font color=\"#0000A0\">$&</font>)"
"(?4<font color=\"#0000FF\">$&</font>)"
"(?5<B>$&</B>)";

const char* header_text = "<HTML>\n<HEAD>\n"
"<TITLE>Auto-generated html formated source</TITLE>\n"
"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=windows-1252\">\n"
"</HEAD>\n"
"<BODY LINK=\"#0000ff\" VLINK=\"#800080\" BGCOLOR=\"#ffffff\">\n"
"<P> </P>\n<PRE>";

const char* footer_text = "</PRE>\n</BODY>\n\n";



Cconvert::Cconvert(void)
{
e1.assign(expression_text);
e2.assign(pre_expression);
}

Cconvert::~Cconvert(void)
{
}

void Cconvert::LoadFile(std::string readfrom)
{
std::ifstream is(readfrom.c_str());
m_str.erase();
m_str.reserve(is.rdbuf()->in_avail());
char c;
while(is.get(c))
{
if(m_str.capacity() == m_str.size())
m_str.reserve(m_str.capacity() * 3);
m_str.append(1, c);
}
}

void Cconvert::Conver(std::string to)
{
std::ofstream os(to.c_str());
os<<header_text;
std::ostringstream t(std::ios::out | std::ios::binary);
std::ostream_iterator<char> oi(t);
boost::regex_merge(oi, m_str.begin(), m_str.end(), e2, pre_format);
// then output to final output stream
// adding syntax highlighting:
std::string s(t.str());
std::ostream_iterator<char> out(os);
boost::regex_merge(out, s.begin(), s.end(), e1, format_string);
os << footer_text;
}
============
convert.h
#pragma once
#include <boost\regex.hpp>
class Cconvert
{
boost::regex e1, e2;
std::string m_str;
public:
Cconvert(void);
~Cconvert(void);
void LoadFile(std::string readfrom);
void Conver(std::string to);
};
实际上这个类只要一个函数就够了"bool convert(const std::string& from,const std::string& to)",
不过为了扩展,我还是设计成了类的形式。
用起来很简单
直接在对应的消息处理里面填上(为htmlview)
void CtestregxView::On32771()
{
std::string strr;
CFileDialog cf(TRUE,"cpp","*.cpp");
if(cf.DoModal()!=IDOK)
return;
strr=cf.GetFileName();
Cconvert m_cv;
m_cv.LoadFile(strr);
CFileDialog of(FALSE,"htm","*.htm");
if(of.DoModal()!=IDOK)
return;
strr=of.GetPathName();
m_cv.Conver(strr);
Navigate(strr.c_str());
}


虽然说这个正则表达式速度可能不如PERL或者那个GRETA(?)记不得了,不过对普通人来说,对那些用户来说
(那些用户看新华日报也要查字典,ESC键上也要贴个纸条,不然不知道干什么用的,关机按纽上要写明“关机”,不然他们直接拔电源,
他们高中基础一般都很杂实,高三一般都读了好几年,他们应该不会关心这些东西的,他们有些候买的软件可执行文件
居然有二三十M那么大,他们打字只用二个指头...)


六、spirit
这个库是语法分析器的,不需要编译,只要直接包含头文件就可以了。
不过时间很长,因为好像用了很多模板。
测试还比较顺利



七、date_time
这个库只能说是一般化,其实应该大多数人都实现过其中的大多数功能了
老方法,顺利通过编译,
测试,也好像没问题,只不过因为是模板,所以实例化的时间也稍微长了点。
下面是我搞的一个小测试,只不过太简单了,根本没有挑战性嘛
=============================================================
#include <string>
#include <iostream>
#include <windows.h>
#include "boost/date_time/gregorian/gregorian.hpp"
void main()
{
std::string ds("20021225");
boost::gregorian::date dab(boost::gregorian::from_undelimited_string(ds));
ds=boost::gregorian::to_simple_string(dab);
std::cout<<dab<<std::endl;
boost::gregorian::date::ymd_type ymd = dab.year_month_day();
char bbbb[50];
sprintf(bbbb,"%u-%u-%u",(int)ymd.year,(int)ymd.month,(int)ymd.day);
std::cout<<bbbb<<std::endl;
std::cout<<(int)(dab.year())<<"-month"<<(int)(dab.month())<<"-day"<<(int)(dab.day())<<std::endl;
}
*注意的是上面的(int)ymd.year,(int)ymd.month,(int)ymd.day这前面的(int)好像是必须要的,因为原代码中此处有个隐含转换。
不然笨笨编译器就不知道你到底想要做什么了,就会出现奇怪的东东了。
而且实际上date.month()并没有什么效率,因为内部也是调用了一个临时对象boost::gregorian::date::ymd_type ymd;
感觉就好像afxbeginthread其实在内部还是生成了一个cthread的实例一样不爽。
==========================================================


==========================================================================================
其实这套类库好像也是有的复杂有的简单,所以上次有人说自己看看也可以写出来了,嘿嘿,不过要写一个regex,spirit好像就很牛B了。

还有,这套类库告诉我们,宏是极其有用的,我们少不了他,你能想像得出没有宏的支持,这套类库怎么样适应不同的编译器呢。
不知道CSDN有没有将这套类库放到下载区,反正我觉得应该放上去,而且应该用RAR再进行一下打包,不然太大了。


要点:某个库到底需要哪些源文件和头文件,这个一般来说都没问题,有时候需要看原代码和作者的帮助文件才行。这是最需要水平的了。

这样做的好处大概就是说一切在你的控制之下,假如想改什么东西的话,或者你想增加什么功能的话,应该很容易了,
省得那个BJAM不知道背着你做了些什么事情。

有什么问题直接在www.csdn.net直接交流或者发邮件给我:beio@sina.com(现在已经成了垃圾邮箱了,一天能收到40封信左右,
哪位朋友有好的邮件服务器的向我推荐一个,要求:WEB收发信,pop3支持,smtp支持(最好要认证吧),还有最重要的是不收费,谢了先)




sevencat 2003-06-17
  • 打赏
  • 举报
回复

二、tokenizer测试
这个东东不用编译,只要包含原文件就可以了
用自带的普通例子进行测试,
能通过,
除了第五个例子,那个需要其他的文件支持(事实上第五个例子就是其他几个例子的合集),
======================================
说:\vc\boost\tokentest\test.cpp(43) : error C3861: “BOOST_CRITICAL_TEST”:
即使使用参数相关的查找,也未找到标识符
======================================
很显然,是有个文件没有编译,
一找,是test目录下面的东西,不过我是不会再加入这个文件的,因为只要我自己能用就行了。
这个东东蛮不错的,以前学JAVA的时候里面就有这个库的。

三、timer
这个跟第二个一样,这个体积更小,也是只要包含头文件就可以了
很轻松就搞定了。经常在网上看到有人问有关这些什么时间啊日期啊之类的东西,建议他用data_time和
这个timer类库。

四、FILESYSTEM
这个跟第一个差不多,先把生成的链接库放到c:\boost\lib下面
然后运行自带的测试程序,
很成功。不过看作者写的介绍还是蛮有意思的。

五、regex很有名的正则表达式了,
也是的,跟第一个差不多,只不过要小心一点,就是说包含的头文件既有c:\boost\boost\regex下面的
也有c:\boost\boost\下面的,我第一次就是因为少包含了几个文件总是不成功,后来就没问题了,

还有这里好像有个小问题,那就是C:\boost\boost\regex\src.cpp应该是src.hpp,一开始我也是不知道,
后来总该有问题,最后发现这个问题好像最好改成头文件,上面再加个#pragma once保护。
而且在编译DLL和LIB的时候,只要修改这个文件就可以了。

只不过这个库比较大,而且对不同的使用还包含不同的文件,也就是说头文件自动帮你包含所需的文件,
用不同的编译器也会生成不同的LIB文件,用不同的线程模式也会生成不同的LIB,
特别是假如要用什么MFC的话,就要注意多线程,单线程,还有DLL模式和调试模式都要用对应的REGEX编译库才行。
于是我将<boost/regex/v3/regex_library_include.hpp>这里面改掉了。(*这个文件很重要,有好多问题可能
都出在这个文件里面)

实际上有些文件就不要编译了,哪些文件?请自己看原代码。
测试自带例子,反正测了前面几个,都很成功,后面就没继续了,毕竟我时间有限,

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧