七、CMake练习
准备工作:在E盘新建一个文件夹cmakeproj,作为工程目录,
在cmakeproj文件夹中,建立src文件夹,用来存放源代码;建立build文件夹,用来构建我的应用程序;
在cmakeproj文件夹中,新建CMakeList.txt文件,我用工程根目录中的CMakeList.txt文件做以下几件事情:
1、指定CMake的最低版本
CMAKE_MINIMUM_required(VERSION 2.8)
2、设定项目名称
PROJECT(CMakeProj)
3、指定子目录
ADD_subdirectory(src)
这里还应当了解两个重要的变量${PROJECT_SOURCE_DIR}和${PROJECT_BINARY_DIR},他们分别是项目源代码目录和项目输出目录,可以用MESSAGE指令输出。
MESSAGE(STATUS "源码目录:" ${PROJECT_SOURCE_DIR})
MESSAGE(STATUS "编译目录:" ${PROJECT_BINARY_DIR})
4、在src文件夹中,建立mylibs和myapps文件夹
在mylibs中,建立mylib.cpp和mylib.h文件,代码如下:
// ----------------------------------------------------------------------------------------------------
#ifndef_MYliB_H
#define _MYliB_H
class Mylib{
public :
voID DoSomething();
};
#endif mylib.cpp
#include " mylib.h "
#include < iostream > Mylib::DoSomething(){
std::cout << hi~!我是一条来自Mylib中DoSomething的消息 std::endl;
}
----------------------------------------------------------------------------------------------------
在mylibs文件夹中的CMakeLists.txt文件中写CMake指令:
ADD_liBRARY(mylibs mylib)
ADD_liBRARY指令的第一个参数为库文件的名称,这里指定为mylibs,将来make之后,会生成一个名称为libmylibs.a的库文件,第二个参数为源码,可以只写文件名mylib,也可以写mylib.h空格mylib.cpp,如果头文件和源文件的名称一致简写为mylib就可以了。
5、在myapps文件夹中,建立myapp.cpp文件
#include
#include int main( argc, const char * argv[])
{
Mylib.DoSomething();
return 0 ;
}
在myapps文件夹中的CMakeLists.txt文件中写CMake指令:
告诉编译器共享库的位置:
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/mylibs)
根据myapp.cpp源文件生称名称为exename的可执行文件:exename.exe
ADD_EXECUtable(exename myapp.cpp)
链接可执行文件需要的动态库文件libmylibs.a
TARGET_link_liBRARIES(exename mylibs)
6、构建
在build文件夹中:cmd:cmake –G”MinGW Makefiles” .. 在build文件夹中已经生成了我需要的MakefIE,
接下来cmd:mingw32-make
在build文件夹的src文件夹中的myapps文件夹中,成功的生成了名称为exename.exe的可执行文件,在build文件夹的src文件夹中的mylibs文件夹中生成了libmylib.a文件。
八、CMake练习的深入
在上一步生成了exe文件后,还是有很多不如意的地方,例如exe文件生成的目录并不是我想要的等等等等。还需要对我的构建进行改进。
1、改变目标二进制的输出目录
在工程根目录中的CMakeList.txt文件中增加指令:
SET(EXECUtable_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(liBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
2、增加版本号
SET(${PROJECT_name}_MAJOR_VERSION 0)
SET(${PROJECT_name}_MInor_VERSION 1)
SET(${PROJECT_name}_PATCH_LEVEL 0)
但我设置后,在windows中并没有看到效果。去公司在linux下看看。
3、生成共享库
修改src/mylibs/中的CMakeLists.txt文件
ADD_liBRARY(mylibs SHARED mylib)
ADD_liBRARY的参数形式为:ADD_liBRARY (库名称 库类型 源文件)
只需要增加参数SHARED就可以了,在make之后,build/lib/中可生成mylibs.dll文件。
如果想同时生成静态库和共享库,如何实现?
九、使用其他库文件
建立一个目录,用来存放一些常用的库(e:/cpplibs)。
(一)sqlite
从最简单的sqlite开始。在E盘建目录cpplibs,在cpplibs文件夹中建立sqlite目录,在sqlite中建立include和lib文件夹,分别存放sqlite3.h文件和libsqlite3.a文件。
在myapps文件夹中的CMakeLists.txt文件中增加:
INCLUDE_DIRECTORIES(d:/cpplibs/sqlite/include)
link_DIRECTORIES(d:/cpplibs/sqlite/lib)
TARGET_link_liBRARIES(exename sqlite3 mylibs)
告诉编译器到哪里去找sqlite的头文件和库,连接sqlite3的库文件。
运行cmake和mingw32-make,sqlite3的应用程序可以正常运行了。但是在上面到处写类似d:/cpplibs/sqlite/include这样的路径,如果cpplibs名称改变了,那就太致命了。在项目根目录的CMakeLists.txt文件中定义一个变量:
SET(sqlite3_BASE d:/cpplibs/sqlite)
将上面两行CMake指令修改为:
INCLUDE_DIRECTORIES(${sqlite3_BASE}/include)
link_DIRECTORIES(${sqlite3_BASE}/lib)
这样看起来好多了。再次编译时,只要修改一下变量sqlite3_BASE的值就可以了。
(二)MysqL++
1、定义两个变量MysqL_BASE和MysqLPP_BASE,分别存放MysqL和MysqL++的位置,在myapps文件夹中的CMakeLists.txt文件中增加:
SET(MysqL_BASE "C:/Program files/MysqL/MysqL Server 5.1")
SET(MysqLPP_BASE "E:/MysqL++")
因为CMakeLists.txt的语法是以空格区分参数是否结束的,所以路径加了引号,在CMake的语法中,加不加引号其实都没有关系,但如果值中有空格或分号“;”,还是需要加引号。
2、源码目录(这里是myapps)的CMakeLists.txt文件修改为:
#INCLUDE_DIRECTORIES
#告诉编译器共享库的位置:
#sqlite MysqL MysqL++
INCLUDE_DIRECTORIES("${sqlite3_BASE}/include" "${MysqL_BASE}/include" "${MysqLPP_BASE}/include")
#link_DIRECTORIES
#告诉外部依赖库的搜索路径
#sqlite MysqL MysqL++
link_DIRECTORIES("${sqlite3_BASE}/lib" "${MysqLPP_BASE}/lib" "${MysqL_BASE}/lib")
最后别忘了告诉编译器MysqLpp的依赖项
TARGET_link_liBRARIES(${PROJECT_name} "${MysqLPP_BASE}/lib/libMysqLpp.a")
开始写一些代码试试看,已经可以很顺利的make了。
#include cstdlib cstdio sqlite3.h#include MysqL ++ .h
#include using namespace std;
sqlitecallback static callback( NotUsed,0)">** argv,0)">azColname){
i;
for (i = ;i argc;i ){
printf( %s=%s\n ,azColname[i],argv[i] ? argv[i]: NulL );
}
printf( \n );
;
}
endsqlitecallback argv[])
{
mylib Mylib().DoSomething();
sqlite sqlite3 db;
zErrMsg = ;
rc;
sql[ 1024 ] "" ;
sprintf(sql, SELECT*FROMtable1; );
rc sqlite3_open( test.db & db);
if (rc)
{
fprintf(stderr,0)">Can'topendatabase:%s\n PAUSE );
exit( 1 );
}
rc sqlite3_exec(db,sql,callback,0)">zErrMsg);
(rc != sqlITE_OK)
{
fprintf(stderr,0)">sqlerror:%s\n endsqlite
MysqLpp::Connectioncon( false );
con.set_option( new MysqLpp::SetCharsetnameOption( gbk ));
cout 请输入数据库(root用户)连接密码: string pwd;
getline(cin,pwd);
( ! con.connect( mytable localhost root 无法连接,请检查密码是否正确! endl;
- else
{
cout shit.终于连上了。 endl;
MysqLpp::queryquery con.query( selectmycolfromfirsttable (MysqLpp::StorequeryResultres query.store()){
cout Wehave: endl;
MysqLpp::StorequeryResult::const_iteratorit;
(it res.begin();it res.end(); it){
MysqLpp::Rowrow it;
cout ' \t ' row[ mycol 或者使用列索引
cout<<'\t'<<row[0]<<endl; }
}
{
cerr FailedtogetmycolList: query.error() ;
}
}
endMysqL
system( EXIT_SUCCESS;
}
(三)wxWidgets
在myapps的CMakeLists.txt文件中:
#wxWidgets
#MinGW 对库的顺序是有要求的,这一点很重要
FIND_PACKAGE(wxWidgets required)
INCLUDE(${wxWidgets_USE_file})
之后:
TARGET_link_liBRARIES(${PROJECT_name} ${wxWidgets_liBRARIES})
下面修改myapp.cpp的代码,写一个wxWidgets的hello world,wxFrame窗口已经呈现在眼前。
myapp.cpp的代码就是wxWidgets官方网站的helloword:
/**hworld.cpp
*/ wx/wx.h MyApp: wxApp
{
virtual bool OnInit();
};
MyFrame: wxFrame
{
:
MyFrame( wxString Title,0)">wxPoint pos,0)">wxSize size);
OnQuit(wxCommandEvent event OnAbout(wxCommandEvent );
DECLARE_EVENT_table()
};
enum
{
ID_Quit MyApp::OnInit()
{
MyFrame frame MyFrame(_( HelloWorld ),wxPoint( 50 450 340 ));
frame -> Show( true );
SettopWindow(frame);
;
}
MyFrame::MyFrame( size)
:wxFrame(NulL,Title,pos,size)
{
wxMenu menufile wxMenu;
menufile Append(ID_About,_( &About... ));
menufile AppendSeparator();
menufile Append(ID_Quit,0)">E&xit ));
wxMenubar menubar wxMenubar;
menubar Append(menufile,0)">&file ));
SetMenubar(menubar);
CreateStatusbar();
SetStatusText(_( WelcometowxWidgets! ));
}
MyFrame::OnQuit(wxCommandEvent WXUNUSED( ))
{
Close(TRUE);
}
MyFrame::OnAbout(wxCommandEvent ))
{
wxMessageBox(_( ThisisawxWidgetsHelloworldsample AboutHelloWorld | wxICON_informatION,255)">this );
}
编译,运行。
总结:
以前喜欢用vc,vs,但vs越来越庞大,每一次的安装都有如梦魇,相信很多朋友和我一样都有同样的感受。为了有一个轻便的环境,我逐渐转移到Devc++,再到CodeBlocks,但总是会遇到这样或那样的问题没有办法解决。我知道这并不是IDE的问题,而是我不知如何解决。
当然我并不是反对使用IDE,我本人也很依赖IDE。人类之所以发明工具,是因为工具可以提高生产效率。上面提到的这些IDE都是极品,尤其Visual studio,是我认为最强大的开发工具,确切的说是C#最强大的开发工具,我甚至一度认为没有其他的开发工具可以超越它,即便如此,我还是想知道在vs强大的背后到底是什么?现在我似乎知道了一些:-)。
学习和使用CMake,开始入手时比较困难,但我才经过总共不超过20个小时的学习,已经基本可以开始用CMake来完成大多数的日常工作了。但是还有一些迷惑,总不能不停的在命令行中敲命令吧,刚开始熟悉命令时多敲几次还过得去,命令已经非常熟悉了,而且使用频率也很高,不停的敲那也太麻烦了,在第三篇学习记录中解决这个问题,地址在这里:
来源:http://www.cnblogs.com/ode/archive/2011/08/04/2152251.html
总结以上是内存溢出为你收集整理的CMake使用方法全部内容,希望文章能够帮你解决CMake使用方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)