随笔 - 10, 文章 - 1, 评论 - 9, 引用 - 0
数据加载中……

置顶随笔

[置顶]Cmake的介绍和使用 Cmake实践

Cmake优点:

1.       开发源代码,实用类BSD许可发布。

2.       跨平台,并可以生成native编译配置文件,在linux/unix平台,生成makefile,在mac平台可以生成xcode,在windows平台可以生成msvc工程的配置文件。

3.       能够管理大型项目

4.       简化编译构建过程和编译过程,只需要cmake+make就可以

5.       高效率

6.       可扩展,可以为cmake编写特定功能的模块,扩充cmake功能

如何安装cmake

1.       Cmake的安装可以使用autotools进行安装,点击cmake-2.8.6.tar.gz 链接,可以对软件进行下载。

2.       ./configure

3.       make

4.       sudo make install

 

Cmake的原理

 

Helloworld cmake

//main.cpp

#include<cstdio>

 

int main()

{

    printf("hello world from main\n");

    return 0;

}

 

创建CMakeLists.txt(注意大小写一个字母都不能错)

向该文件中加入以下几行(稍后会做解释)

PROJECT (HELLO)

SET(SRC_LIST main.cpp)

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST})

运行以下命令:

cmake . (别忘记加上这个点,表示当前目录)


注意执行完这句话之后会生成几个文件如下:


CMakeFiles, CMakeCache.txt, cmake_install.cmake等文件,并且生成了Makefile

然后执行make 就可以生成可执行文件hello


这是当前目录下就会生成可执行文件如下图:


对例子的解释:

CMakeLists.txt的内容如下:

PROJECT (HELLO)

SET(SRC_LIST main.cpp)

MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})

MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})

ADD_EXECUTABLE(hello ${SRC_LIST})

 

Project的指令的语法是:

PROJECT(projectname [CXX] [C] [JAVA])

这个执行是用来定义工程的名称的和定义工程支持的语言。这个指令也隐式的定义了两个cmake变量:<projectname>_BINARY_DIR以及<projectname>_BINARY_DIR,这里就是HELLO_BINARY_DIR和HELLO_SOURCE_DIR,两个变量指的都是当前工程的路径。

SET指令的语法:

SET(VAR[VALUE] [CACHE TYPE DOCSTRING [FORCE]])

Set指令是用来显式的定义变量的,我们之前用到的是SET(SRC_LIST main.cpp)如果有多个源文件,也可以定义成SET(SRC_LIST main.cpp t1.cpp t2.cpp)。

 

MESSAGE指令的语法是:

MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

这个指令用于向终端输出用户信息,包含三种类型:

SEND_ERROR,产生错误,生成过程被跳过。

SATUS,输出前缀为-的信息。

FATAL_ERROR,立即终止所有cmake过程。

我们在这里使用的是STATUS信息输出,显示了由PROJECT指令顶一顶两个饮食变量HELLO_BINARY_DIR和HELLO_SOURCE_DIR。

 

ADD_EXECUTABLE(hello ${SRC_LIST})

定义了这个工程会生成一个文件名为hello的可执行文件,相关的源文件是SRC_LIST中定义的源文件列表,本例中你可以直接写成ADD_EXECUTABLE(hello main.c)。

 

将本例改写成一个最简化的CMakeLists.txt:

PROJECT(HELLO)

ADD_EXECUTABLE(hello main.c)

 

下面我们介绍一个比较实用的例子,即包含生成静态库又包含引入外部头文件和链接库的cmake demo。

先按照工程规范建立工程目录,并编写代码,以下面的工程目录为例进行解释这个例子,工程的目录结构为:

 

编译工程要实现的目标:

1. 添加子目录doc,用以放置这个工程的文档hello.txt

2. 生成hello的静态库,并在main可执行程序链接hello静态库

3. 在这个工程中添加COPYRIGHT,README

4. 在工程目录中添加一个run.sh的脚本,用以调用生成的二进制可执行文件

5. 将生成的二进制文件生成到bin子目录中

6. 编写安装程序

 

1. 编写CMakeLists.txt

由于一个工程目录中包含多个项目,其中在此项目中包含util项目和main项目,其中util项目是用以生成main程序需要的静态库,main是用以生成可执行文件。

在工程项目中的父目录向有一个CMakeLists.txt是用以声明定义工程需要的Cmake设置还定义了子目录src,用以递归的调用src中的MakeLists.txt。其中工程目录的CMakeLists.txt内容定义如下:

PROJECT(HELLO)

ADD_SUBDIRECTORY(src)

在src里面的CMakeLists.txt是用以定义src目录包含的两个工程的依赖关系分别进行编译。

util目录里面的CMakeLists.txt是用以定义生成util静态库的规则,其中内容如下:

SET(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)

SET(CMAKE_C_COMPILER g++)

SET(SRC_LIST hello.c)

 

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)

ADD_LIBRARY(util STATIC ${SRC_LIST})

其中SET(LIBRARY_OUTPUT_PATH ${HELLO_SOURCE_DIR}/lib)定义了库生成的路径,LIBRARY_OUTPUT_PATH是一个内部变量,存放库生成路径。

SET(SRC_LIST hello.c)是用来定义库文件需要的源文件。

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)是用来定义非标准库头文件要搜索的路径。其中INCLUDE_DIRECTORIES命令的格式为:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

ADD_LIBRARY(util STATIC ${SRC_LIST})是用来定义生成的库的名字,以及生成库的类型和生成库需要的源文件,其中ADD_LIBRARY命令格式为:

     ADD_LIBRARY(libname    [SHARED|STATIC|MODULE]

          [EXCLUDE_FROM_ALL]

                source1 source2 ... sourceN)

SET(CMAKE_C_COMPILER g++)是用来定义c的编译器为g++,防止出现C和C++代码在不指定C编译器的情况下默认使用gcc,导致系统编译混乱。

在main目录中的CMakeLists.txt是用来定义可执行程序编译和链接时所需要的一些命令或环境。内容如下:

SET(EXECUTABLE_OUTPUT_PATH ${HELLO_SOURCE_DIR}/bin)

SET(SRC_LIST main.cpp)

 

INCLUDE_DIRECTORIES(${HELLO_SOURCE_DIR}/include)

LINK_DIRECTORIES(${HELLO_SOURCE_DIR}/lib)

 

ADD_EXECUTABLE(hello ${SRC_LIST})

TARGET_LINK_LIBRARIES(hello util)

INCLUDE_DIRECTORIES命令是定义工程的include文件夹,其中存放使用到的库的头文件,LINK_DIRECTORIES是定义工程的库文件,其中存放着库文件,ADD_EXECUTABLE是定义生成的可执行文件,TARGET_LINK_LIBRARIES用以定义链接时需要的库文件。

2.在工程目录下创建build目录,并采用out-of-source方式编译项目。执行命令make ..,执行结果如下:


执行make,这时在build目录下生成了中间编译文件:


执行make命令,结果如下:


可以看到工程创建和编译成功了。

2. 安装

在工程目录下添加COPYRIGHT、README、和run.sh,重新编辑工程目录下的CMakeLists.txt。在CMakeLists.txt中添加如下命令:

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake_demo)

INSTALL(PROGRAMS run.sh DESTINATION bin)

INSTALL(PROGRAMS bin/hello DESTINATION bin)

INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake_demo)

这些命令表示在执行make install命令时,安装程序会拷贝相应的文件、目录或程序到指定的前缀开始的目录中,cmake执行命令如下:

cmake -DCMAKE_INSTALL_PREFIX=~/data/cmake_demo ..这时将工程目录安装到~/data/cmake_demo目录下。执行结果如下:


其中cmake编译c、c++工程完毕。

posted @ 2011-11-17 20:18 Roger 阅读(71733) | 评论 (2)编辑 收藏

[置顶]Makefile 解析

一个工程中的源文件可能很多的情况下,按其类型、功能、模块分别放到若干个目录中,makefile定义了一系列的规则,用以指定那些需要先编译,那些需要后编译,那些需要重新编译,和一些更复杂的操作。,makefile的好处就是自动化编译,一点写好,只需要make命令,整个工程就会自动编译,提高了项目的管理能力和软件的开发效率。

Makefile 文件解读

 

edit : main.o kbd.o command.o display.o \ 

insert.o search.o files.o utils.o 

cc -o edit main.o kbd.o command.o display.o \ 

insert.o search.o files.o utils.o 

 

main.o : main.c defs.h 

cc -c main.c 

kbd.o : kbd.c defs.h command.h 

cc -c kbd.c 

command.o : command.c defs.h command.h 

cc -c command.c 

display.o : display.c defs.h buffer.h 

cc -c display.c 

insert.o : insert.c defs.h buffer.h 

cc -c insert.c 

search.o : search.c defs.h buffer.h 

cc -c search.c 

files.o : files.c defs.h buffer.h command.h 

cc -c files.c 

utils.o : utils.c defs.h 

cc -c utils.c 

clean : 

rm edit main.o kbd.o command.o display.o \ 

insert.o search.o files.o utils.o 

 

反斜杠(\)是换行的意思。上述makefile文件可以命名为makefileMakefile,如果在目录中输入make,就可以生成edit可执行文件。如果想要删除可执行文件或者是中间目标文件直接make clean就行了。

依赖关系:

有上述例子可以看出,目标文件包含两种:执行文件(edit)和中间目标文件(*.obj),依赖文件(prerequisites)就是冒号后面的那些.c.h文件。每一个.o 文件都有一组依赖文件,这些.o的文件又是执行文件edit的依赖文件。其实依赖关系就是说明了目标文件是有那些文件申城的,换言之就是目标文件是哪些文件更新的。

定义好依赖关系后,后面的一行就定义了如何生成目标文件的操作系统命令,一定要以tab键开头。记住make并不管命令式怎么工作的,它只关心定义的命令。Make会比较目标文件和依赖文件的修改日期,如果依赖文件的日期要比目标文件的日期更新,或者是目标文件不存在的话,make就会执行后续定义的命令。

 

Make是如何工作的

1.       查找Makefilemakefile文件

2.       查找第一个目标文件,并将这个文件作为最终的目标文件

3.       查找目标文件是否存在,或者是当前目标文件依赖的.o 文件的文件修改时间要比当前目标文件新,则执行后面定义的命令来生成edit这个文件

4.       如果edit依赖的.o文件也存在,那么make会在当前文件中查找目标文件为.o文件的依赖性,如果找到则根据哪一个规则生成.o文件。

5.       根据c文件和.h文件,make生成.o文件,然后生成最终目标文件。

 

Make会一层已成的查找文件的依赖关系,知道最终编译出第一个目标文件。在查找过程中,如果出现错误,比如被依赖的文件找不到,那么make就会直接退出,并报错,但是对于所定义的命令的错误,或者是编译不成功,make会置之不理。但是当查找到一个文件的依赖关系的时候,并且执行依赖关系之后命令,冒号后面的依赖文件如果还是不存在,那么make就会退出。

由上可知,想clean这种没有被第一个目标文件直接或间接关联,那么他后面定义的命令将不会自动执行。如果想显式执行要求make执行clean之后的命令,“输入make clean”就行了,用以清除所有的目标文件,便于重新编译。

1.       另外makefile中也可以添加一些宏定义(变量)

2.       gnu make可以实现自动推倒

posted @ 2011-11-17 20:04 Roger 阅读(7901) | 评论 (0)编辑 收藏

[置顶]C++编译器 GCC G++ 使用

     摘要: 什么是gcc、什么是g++?
gcc和g++都是GNU(组织)的一个编译器。
但两者有一些区别:后缀为.c的文件gcc把它当做c程序,g++当做c++程序。后缀为c++的两者都当做c++程序。对于cpp程序,无论gcc或者是g++编译阶段都是相同的,都是用的gcc进行编译,但是在链接阶段gcc不能自动和c++程序使用的库连接,如果使用的话,形如下: gcc helloworld.cpp -lstdc++ -o helloworld
所以我们通常用g++来进行连接(g++会自动连接c++常用库),所以为了使用方便对于cpp程序干脆编译链接统统都使用g++,这样就给人一种错觉,好像cpp只能用g++编译。

Gcc编译处理过程是什么呢?
下面以helloworld程序为例去进行解释过程:
其中hello.c的内容如下:
#include

int main()
{
printf("hello world\n");
}
第一步:预处理
预  阅读全文

posted @ 2011-11-13 15:01 Roger 阅读(11308) | 评论 (1)编辑 收藏

[置顶]详尽的Mysql安装过程 讲解

安装步骤:

inux平台mysql source安装的安装及配置步骤

1、 下载MySQLsourcecode

进入mysql download页面http://dev.mysql.com/downloads/

  点击进入http://dev.mysql.com/downloads/mysql/ 到如下页面:

    

   选择sourcecode下拉列表进入到如下页面:

    
  点击 Generic Linux (Architecture Independent), Compressed TAR Archive,进入
    
选择 » No thanks, just take me to the downloads!

进行下载

2、 安装MySQL

解压mysql5 的安装包:

[root@niutian365 local]# tar zxvf mysql-5.5.16.tar.gz

进入解压后的安装包

:[root@niutian365 local]# cd mysql-5.5.16

3、 选择root用户进入,建立mysql用户组和用户名:

建立mysql用户组:groupadd mysql

建立mysql用户并将mysql用户加到mysql用户组中: useradd -g mysql mysql

4、 创建/usr/mysql/mysql/usr/mysql/data/usr/mysql/log目录

mkdir /usr/mysql/mysql

mkdir /usr/mysql/data

cmake 编译sourcecode

cmake -DCMAKE_INSTALL_PREFIX=/mysql/mysql

-DMYSQL_DATADIR=/mysql/mysql/data

-DDEFAULT_CHARSET=utf8

-DDEFAULT_COLLATION=utf8_general_ci

-DWITH_INNOBASE_STORAGE_ENGINE=1

-DWITH_ARCHIVE_STORAGE_ENGINE=1

-DWITH_BLACKHOLE_STORAGE_ENGINE=1

-DWITH_FEDERATED_STORAGE_ENGINE=1

-DWITH_PARTITION_STORAGE_ENGINE=1

-DENABLED_LOCAL_INFILE=1

-DMYSQL_UNIX_ADDR=/mysql/mysql/data/mysql.sock

5、 复制配置文件到/etc

[root@niutian365 local]#vi /etc/my.cnf

修改

[mysqld]

basedir=/home/mysql/mysql

datadir=/home/mysql/data

socket=/var/lib/mysql/mysql.sock

[mysqld_safe]

log-error=/home/mysql/log/mysqld.log

pid-file=/home/mysql/log/mysqld.pid

6、 修改文件的文件主:

chown –R mysql:mysql /home/mysql/log/

chown –R mysql:mysql /var/lib/mysql

 

运行[root@niutian365 local]#./usr/local/mysql/bin/mysql_install_db

在这一步中可能会发生错误,查看错误原因,如果是由于权限的问题则需要将父目录拥有者改成mysql:mysql,使用chown –R mysql:mysql XXX

7、 运行mysql

进入mysqlbin目录,运行sh mysqld_safe

如果不能正常运行,可以查看log目录下的mysqld.log,查看错误信息,然后做出相应的修改。

8、 mysql注册为服务

mysql源代码目录的support-files/mysql.server拷贝至/etc/init.d/,重命名为mysqld

安装chkconfig: apt-get install chkconfig 

运行 chkconfig -add mysql注册服务

运行 mysql start开启服务

运行 mysql stop关闭服务

 

修改远程登录mysql权限,现在提供两种支持远程登录的方法:

1.       改表法。其中在user表中的host那一列保存的是user允许的用户登录的位置信息,通过修改这一列的数据来修改mysql的远程登录,使用如下命令进入mysqlmysql –u root –p 输入密码(默认为空)第一次进入到数据库系统。

选择数据库:mysql> use mysql;

如下图所示执行sql命令:

说明: C:\Users\roger\AppData\Roaming\Tencent\Users\455769859\QQ\WinTemp\RichOle\EOQH1V)J62%D[KFZM8N)MB5.jpg

由上图可以看到,mysql只允许127.0.0.1localhost,以及localhost.localdomain的机器以root身份登录到mysql数据库中,下面我们做如下更改:

说明: C:\Users\roger\AppData\Roaming\Tencent\Users\455769859\QQ\WinTemp\RichOle\4AY[GQ~VX4TDD$S4@)[E[ZS.jpg

上面的error是有host是唯一属性导致的错误,可以不用理会,现在我们已经改好了mysql远程登录的配置,一定要主要通过如下命令是上述做的改动生效。

mysql> FLUSH PRIVILEGES;

好了现在可以在其他机器上进行远程登录mysql了。

2.       授权法。

使用如下命令:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '111111' WITH GRANT OPTION;root用户在任意机器上以111111密码访问,上面的执行结果如下:

实际上,在user表中添加了一行,如上面标注部分。如果你想允许用户myuserip192.168.1.3的主机连接到mysql服务器,并使用mypassword作为密码,执行如下语句:

GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'192.168.1.3' IDENTIFIED BY 'mypassword' WITH GRANT OPTION;

Mysql修改密码:

UPDATE user SET password=password('111111') where user='root'; 

mysql> FLUSH privileges;

如下图:

         说明: C:\Users\roger\AppData\Roaming\Tencent\Users\455769859\QQ\WinTemp\RichOle\]T~OX)`1~3OC8XFW04KP9DI.jpg

请注意,此密码是经过hash后的密码,不能用原密码如mysql> update user set password = 111111 where user = 'root' ;这样是不正确的。

Mysql添加用户:

mysql> GRANT ALL PRIVILEGES ON *.* TO 'sphinx'@'%' IDENTIFIED BY '111111' WITH GRANT OPTION;                          

Query OK, 0 rows affected (0.00 sec)

 

mysql> FLUSH PRIVILEGES;                                                                   

Query OK, 0 rows affected (0.00 sec)

以上命令是创建sphinx用户远程登录mysql,密码是111111

 

posted @ 2011-10-09 13:30 Roger 阅读(2302) | 评论 (3)编辑 收藏