虚拟机的内存昂贵,买一台内存少的机器然后配置 swap 文件可以省不少钱,当然前提是对虚拟机的性能要求不高。

参见这篇文章:
https://support.rackspace.com/how-to/create-a-linux-swap-file/

用下面的命令初始化 swap 文件,并且把该文件权限修改成为 600。

fallocate -l 4GB /tmp/4GB.swap
mkswap /tmp/4GB.swap
chmod 600 /tmp/4GB.swap

使用 swapon 这个命令可以直接把 swap 文件挂载,但是写到 fstab 文件里是最省事的,所以修改 /etc/fstab 文件,然后添加一行

/tmp/4GB.swap  none  swap  sw 0  0

重启服务器,使用 top 命令会看到系统多出了 4GB 的 swap 内存。

为什么使用cppman?

cppman可以让你在命令行窗口中方便的翻阅C++文档,文档的来源是http://www.cplusplus.com,你只需要输入cppman [关键字]则会打开vim将对应关键字的文档列出,然后使用ctrl+]键可以跳转到当前光标指向的链接,使用ctrl+T可以返回上一个页面。

cppman在vim里打开的效果图

必需安装Python3以及使用pip3来安装cppman

是的,你必须使用Python3,因为cppman使用到了urllib.request,而这个函数只有在Python3中才带有,而在Python2里,需要安装urllib2才能使用,但是在cppman的github上官方教程是要求安装Python3的,之前安装cppman的时候因为对Python不熟悉,所以卡在了这里,今天来研究的时候终于发现了问题。

所以,使用brew install python3来安装Python3,或者,你在安装vim的时候直接参照下面提到的命令在安装vim的时候一并安装python3。

另外,如果你已经使用过brew安装过Python2了,那么记得把它删除掉brew uninstall python

Python3带来的vim安装的问题

安装vim如果不带–without-python参数的话,那么一定会安装Python2,哪怕你带上了–with-python3的参数也一样会安装Python2,因为–with-python是管Python2,而–with-python3是管Python3,这两个参数互不干扰,所以正确的方法是使用诡异的命令brew install vim --without-python --with-python3

如果你使用brew uninstall python了之后,那么You complete me这个vim插件将无法使用,必须重新编译。

参考

cppman在github上的的地址 https://github.com/aitjcize/cppman

为什么这么做?

因为这样可以使用TypeScript代替JavaScript进行开发,开发过程中准确的代码提示以及强类型还有对于JavaScript的多种扩展将使得开发效率最大化,避免掉了JavaScript各种坑且获得完美的OO支持。

技术要点

TypeScript

TypeScript是JavaScript语言的一个超集,它提供了JavaScript没有的静态类型,以及很多有用的扩展,比如class,interface等。同时TypeScript Compiler将TypeScript源代码编译成为JavaScript源代码,使得TypeScript无缝替代JavaScript变成了可能。

Node.js

Node.js®是一个基于Chrome V8 引擎的 JavaScript 运行时。 Node.js 使用高效、轻量级的事件驱动、非阻塞 I/O 模型。Node.js 之生态系统是目前最大的开源包管理系统(From https://nodejs.org/zh-cn/)。

NPM

NPM是Node.js的包管理器,安装好了Node.js后都附带该包管理器。使用NPM可以方便的安装、更新以及删除Node.js的包。

Typings

Typings是TypeScript的Definition Manager,简单来说,它提供了Node.js的包的autocompletion支持以及lint检查支持。使用NPM安装typings,然后再使用typings来安装对应Node.js包的Typings库。

Express from Node.js

Express是Node.js的一个开发包,用于开发Web前后端应用。

环境配置

安装Node.js和NPM

  • 访问Node.js的官方网站下载LTS版本的Node.js。
  • 在国内使用npm访问包资源库会非常慢,这里推荐使用淘宝的npm库源镜像,输入命令添加淘宝的npm源镜像npm config set registry http://registry.npm.taobao.org
  • 使用npm安装TypeScript 2.2.2版本npm install -g typescript@2.2.2。之所以安装这个版本的Typescript是为了让Typescript的版本和Visual Studio Code的版本一至,这样在启动Visual Studio Code的时候不会出现警告提示。

安装Typings

  • 使用npm安装typingsnpm install -g typings

开始初始化Express工程

  • 建立工作路径mkdir express-ts && cd express-ts
  • 初始化TypeScript编译配置tsc --init。执行完该命令后会在当前的工作区中创建一个新的文件,名称为:tsconfig.json。
  • 修改tsconfig.json,添加"outDir": "build""compilerOptions"项目中。将编译出来的.js保存到build目录下。
  • 初始化typings配置,执行typings init将创建typings.json到当前的工作区目录下。
  • 使用typings安装Definitions TypeScript包typings install dt~node dt~es6-shim --save --global以及typings install dt~express dt~serve-static dt~express-serve-static-core dt~mime --save
  • 初始化NPM工程npm init -y && npm install express --save

TypeScript的编译

  • 编译是指把TypeScript的代码编译成为JavaScript,直接在当前的根目录下使用命令tsc则可以开始编译,输出的JavaScript文件将按照tsconfig.json中配置的"outDir"目录存放。
  • 在开发过程中,因为我们频繁的修改代码,于是有时候不得不频繁的输入编译命令,这时如果你使用tsc --watch这个命令,TypeScript的编译器将会自动监视工程中的所有TypeScript源文件,若有文件修改,则自动发起一次编译,这个自动化的操作将会省掉很多手动输入编译命令的操作。

Module模块

Module模块是Node.js引入的模块管理,一个Module可以方便的Export或者Import类型、变量及其它符号。

导出符号

使用TypeScript来导出符号只需要在该符号前添加export关键字即可。例如,以下的代码将会把Sample类型导出,其它的模块可以直接使用import来导入该符号。

export class Sample {
    public callMe() {
        // ...
    }
}

导入符号

使用import语法可以将模块中已经标记为导出的一个或多个符号导入为可见。例如:以下的代码将会把Sample类导入。注:’./sample’为不带扩展名的模块文件名称。

import { Sample } from './sample';

你也可以导入指定模块中所有的符号,例如:

import * as sample from './sample';
let obj = new sample.Sample();

索引文件导入、导出

我们也可以在某一目录下建立index.ts,然后在其中多次使用export * from './xxx';这样的形式,将该目录下的所有的模块都导出,然后在主模块中使用import * from './某一目录/'来导出。

模块安装

安装包内容

Node.js的包库里有各种各样的模块,要使用这些模块则需要安装到当前的工程中,而使用npm这个包管理工具则可以非常简单的将包安装到本地的项目中。例如,我们要想使用express这个模块,那么则可以使用以下命令。

npm install express --save

--save将会修改当前工程目录下的package.json文件,把对应安装的expresss信息写入该文件,则下次再初始化该工程的时候直接使用npm install则会安装package.json中所有已经登记的包。

安装TypeScript符号包

当安装完了模块后,我们需要安装对应该模块的TypeScript的符号库,这样可以直接在VSCode中获得代码提示、自动完成等功能,仍然拿express包来举例。

typings install dt~express --save

使用--save与npm的原因相同,只是命令改为typings。dt为安装包的位置,express为安装的包名,一般的安装位置都是指定dt。

为VSCode调试做准备

调试非常重要,使用VSCode来调试是非常简单的,在调试过程中可以看到断点,堆栈以及当前相关的变量值及类型,要初始化只需要遵守以下步骤。

  1. 打开VSCode,左边工具栏选择第四个按钮,或者使用快捷键ctrl+shift+d
  2. 在上方的工具栏中点击齿轮按钮,此时配置文件自动创建并且打开
  3. 修改配置文件中的”program”项,将其指向启动文件,比如:${workspaceRoot}/app/server.ts。其中${workspaceRoot}环境变量值为当前项目的根目录。
  4. 修改”sourceMaps”的值为true
  5. 看到”outFiles”这个数组,添加"$workspaceRoot}/build/*.js"。在未来代码若添加到了其它的目录,则同时需要在这里添加对应的目录值。

一切准备就绪后,在VSCode中按下F5键则可以启动当前的程序,使用F9可以对当前的TypeScript代码下断点。几个调试相关的快捷键和Visual Studio的C++调试快捷键一样。

编写一个最基本的web服务器

基本结构

使用express编写一个最基本的web服务器,需要涉及几个方面

  1. 导入符号
  2. 导入express中的所有的符号

    import * as express from 'express';
    

    导入express中的特定符号

    import { Router, Request, Response } from 'express';
    
  3. 编写服务器启动代码
  4. import * as express from 'express';
    
    let app: express.Application = express();
    app.listen(3000, () => {
        console.log('Server listen on port 3000');
    });
    
  5. 编写路由
  6. 需要编写路由对象来接收客户端的访问,一般会创建新的模块放到新的文件中。比如,我们创建一个叫做RootController的路由,并且导出。如下:

    // file: root_controller.ts
    import { Router, Request, Resource } from 'express';
    const router: Router = Router();
    
    router.get('/', (req: Request, res: Response) => {
        res.write('hello world.');
        res.end();
    });
    
    export const rootController: Router = router;
    

    然后,我们修改主程序文件,添加对该路由模块的导入,并且将主服务器与路由挂到一起。、

    import * as express from 'express';
    import { rootController } from './root_controller';
    
    let app: express.Application = express();
    app.use('/'. rootController);
    app.listen(3000, () => {
        console.log('Server listen on port 3000');
    });
    

    然后我们启动程序,打开浏览器访问http://localhost:3000/将应该看到hello world.字样。

  7. 支持静态文件
  8. 服务器需要支持静态文件,在主程序的适当位置添加以下代码。

    import * as path from 'path';
    
    app.use(express.static(path.join(__dirname, 'public')));
    

    然后在当前的项目根目录下创建’./public’目录,里面的文件将会被访问者直接读取。

处理get和post的参数

  1. 安装body-parser
  2. 我们需要安装body-parser模块来处理post上来的数据。

    npm install body-parser --save
    typings install dt~body-parser --save
    
  3. 在服务器主代码中的适当位置添加处理代码
  4. import * as bodyParser from 'body-parser';
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
  5. 获取参数内容
  6. 所有的请求处理代码都写在Router对象里,若是处理get事件,那么则使用router.get('/path/', (req: Request, res: Response) => {});,若是post则使用router.post('/path/', (req: Request, res: Response) => {});

    get和post的参数获取分别使用req.queryreq.body,比如,我有对服务器这样的get请求:http://localhost:3000/?hello=world,那么在如下的代码中将可以获得键为”hello”的值”world’。

    router.get('/', (req: Request, res: Response) => {
      let world: string = req.query.hello; // world = 'world';
    });
    

使用session

关于session其实也是保存一个数据到cookies里,但是却把对应的数据保存在了服务器上,而用户的浏览器中只保存一个键值,使用该键值与服务器上该用户的数据对应起来。

  1. 安装express-session
  2. 在服务器主程序中的适当位置添加代码
  3. import * as cookieParser from 'cookie-parser';
    import * as session from 'express-session';
    
    // 记得要打开cookie支持
    app.use(cookieParser());
    
    // 打开session支持
    app.use(session({
        secret: '(your secret code here)',
        resave: true,
        saveUninitialized: true
    
  4. 存取对应某用户的session值和get与post是一样的,只是对象名字为req.session,直接修改这个对象的键值则会将其保存至服务器的内存中。

使用ejs

ejs是express所支持的前端模板框架,非常简单轻量,脚本直接使用javascript。

  1. 安装ejs模块
  2. npm install ejs --save
    
  3. 在主服务器代码的适当位置添加以下内容。
  4. app.set('view engine', 'ejs');
    

跨域处理

默认是不允许跨域访问的,要打开这个限制需要加入以下的代码,放在所有的Router之前。

app.all('*', (req: express.Request, res: express.Response, next: express.NextFunction) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

使用gulp打包

gulp是一个打包发布工具,如果对应C++的开发,它应该算是makefile。gulp有各种插件,可以方便的把你的Node.js代码,网页,JS脚本打包成为线上版本。比如,有时候我们打开一些网站然后选择查看源代码,会发现里面的html代码非常紧凑,js脚本非常难读,这些网站线上跑的代码就是经过打包处理的。

gulp基本安装流程

安装gulp

  1. 使用npm安装gulp的命令行版本,执行了以下命令后,系统中就存在的gulp命令了。
    npm install -g gulp-cli
    
  2. 添加gulp支持到devDependencies里。
    npm install gulp --save-dev
    

gulp基本编写规范

gulpfile.js文件中包含了打包当前工程要做的事情,每一件事情都叫做一个task,每一个task都有一个名字,而名字叫做’default’的那个task是默认启动的task。每个task执行的流程基本上都是确定源文件,中间处理步骤(一或多),输出到目标目录(文件)。

  1. 创建gulpfile.js文件在工程的根目录
  2. 打开gulpfile.js文件,写入作为一个gulpfile.js的最基本的内容
    var gulp = require('gulp');
    
    gulp.task('default', function() {
    });
    
  3. 执行gulp命令,将会看到gulp工具在打包并且输出了打包日志(尽管什么都没有做)。

基本的文件拷贝Task

  1. 需要定义一个源,可以是一个文件或者多个文件,使用通配符描述,如下描述了一个单独的’mysql.json’文件。
    var files = {
      config: ['./mysql.json']
    };
    
  2. 直接使用管道将源复制到目标。
    gulp.task('config', function() {
      gulp.src(files.config)
        .pipe(gulp.dest('dist'));
    });
    

编译TypeScript的Task

  1. 执行以下的命令以安装gulp-typescript并且保存到devDependencies里。
    npm install gulp-typescript --save-dev
    
  2. 在gulpfile.js文件中添加编译TypeScript的Task
    var gulp = require('gulp');
    var ts = require('gulp-typescript');
    var tsproj = ts.createProject('tsconfig.json');
    
    gulp.task('ts', function() {
      tsproj.src()
        .pipe(tsproj())
        .js
        .pipe(gulp.dest('dist');
    });
    
    gulp.task('default', ['ts']);
    
  3. 首先引用了ts对象,然后使用该对象按照当前根目录下的tsconfig.json文件创建了一个tsproj对象。tsproj.src()则为所有的TypeScript文件,然后通过管道输出给tsproj()这个函数,这一步相当于编译了所有的TypeScript文件。然后js函数获取了所有的编译输出的js文件,再通过管道输出到目标目录’dist’里。

ejs, js的编译

  1. 分别需要使用gulp-minify-ejs以及gulp-uglify,所以需要先安装好。
    npm install gulp-minify-ejs gulp-uglify --save-dev
    
  2. 引用并且通过管道执行。
    var minifyejs = require('gulp-minify-ejs');
    var uglify = require('gulp-uglify');
    
    var files = {
      ejs: ['./views/*.ejs'],
      js: ['./public/js/*.js']
    }
    
    gulp.task('ejs', function() {
      gulp.src(files.ejs)
        .pipe(minifyejs())
        .pipe(gulp.dest('dist/views'));
    });
    
    gulp.task('js', function() {
      gulp.src(files.js)
        .pipe(uglify())
        .pipe(gulp.dest('dist/public/js'));
    });
    

执行任务以及其它

  1. 串起所有的任务,只需要在gulp的’default’ Task中添加每个任务的名称到数组里即可。
    gulp.task('default', ['ejs', 'js', 'ts']);
    
  2. 如果需要单独执行某个任务,只需要使用命令gulp "Task名称"即可。
  3. 使用gulp命令打包完成之后,在当前的工程目录下的dist目录将保存了所有的编译好的文件,在该目录下直接使用node来执行server.js则可以启动服务器,当然也可以使用forever等工具来执行服务器,看个人喜好。

使用Generator

在每次创建TypeScript的项目都得要添加很多重复的代码以保证各方面的需求,使用Generator可以省掉这些麻烦。可以产生express的TypeScript版本框架的代码的Generator有很多个,测试了几个后觉得不错的应该是generator-express-typescript-typings,但是这些个Generator都需要一个叫做Yo的程序来运行,同样也可以使用npm来安装。具体的安装及生成框架代码的步骤参见如下:

npm install -g yo generator-express-typescript-typings
mkdir sample && cd sample
yo express-typescript-typings

生成好的代码,可以直接使用code打开,很多功能都已经具备,并且是活生生的TypeScript源代码,且也可以使用tsc命令直接编译。

参考文章

Using Typescript with Node JS

Unity自己貌似并没有搭配一个事件系统,也是俗称的观察者系统,但事实上,用UnityEventUnityAction配合起来搭建一个事件系统是非常简单的,参照以下步骤:

  • 创建一个用于参数传递的类,比如MyEventArgs,这个类不需要继承其它的类,它只作为参数的基类。
  • 创建一个继承自UnityEvent的事件类,比如命名为MyEvent,用于存储特定消息的一系列事件句柄Listener
  • 创建一个Dictionary的字典类,并在事件系统的Awake函数中初始化它。
  • 在事件系统中添加RegisterMessage(string messageId, UnityAction listener)函数,并将按照messageId在事件字典中查找或者创建对应的事情,然后将listener添加到事件里。
  • 在事件系统中添加SendMessage(string messageId, MyEventArgs args)函数,在事件字典中找到对应于messageId的事件并且调用Invoke(args)

Gitlab实在是太大了,安装一次Gitlab像是安装了一套复杂的操作系统一样,以至于出了问题后处理起来及其麻烦。近期有了解到Gogs是一个新的开源项目,也是用于管理Git仓库,使用Go语言开发,安装极其简单,于是今天研究了一下安装方法并且成功安装到我的服务器上。

安装Gogs

通过编译好的包来安装Gogs

  • 创建git用户useradd git -m,然后切到该用户su - git
  • 访问https://gogs.io/然后点击Install按钮,在左边的菜单中选择From binary下载编译好的包,注意自己的操作系统,我选的包类型是Linux AMD64。然后将包解到/home/git/gogs目录下。
  • 运行/home/git/gogs/gogs web来启动gogs,这时候gogs将侦听0.0.0.0:3000
  • 打开浏览器,访问http://[服务器ip地址]:3000来继续gogs的安装。
  • 安装完毕后,gogs就已经可以访问了,但是不可能裸奔,所以要考虑使用nginx来做前端及添加SSL证书。

配置Nginx

配置Nginx前端及SSL

  • 按照下面的方法来配置Nginx站点信息,关于SSL证书申请请参考上一篇文章。把配置中的example改成你的站点的域名。

    server {
      listen 80;
      listen [::]:80;
      server_name git.example.com;
      return 301 https://$host$request_uri;
    }
    
    server {
      listen 0.0.0.0:443;
      listen [::]:443;
      server_name git.example.com;
    
      ssl on;
      ssl_certificate /etc/letsencrypt/live/git.example.com/cert.pem;
      ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem;
    
      location / {
        proxy_pass http://127.0.0.1:3000;
      }
    }
    
  • 打开配置文件/home/git/gogs/custom/conf/app.ini,将[server]段落中的DOMAIN改成站点域名,添加或修改HTTP_ADDR127.0.0.1,然后将ROOT_URL修改成为https打头。
  • 重启Nginx及Gogs,则可以访问配置好的服务器域名进行测试了。

配置Supervisor来将Gogs启动成为服务

如果只是运行gogs web命令来使用gogs,那么如果碰到崩溃或者服务器重启,则无法自动故障恢复,所以还需要多做一步

  • 首先需要安装Supervisor,执行命令apt install supervisor
  • /home/git/gogs/scripts/supervisor目录下,有一个叫做gogs的文件,将其拷贝到/etc/supervisor/conf.d/gogs.conf,注意,扩展名conf不能漏。
  • 修改这个conf文件成为下面这个样子:
    [program:gogs]
    directory=/home/git/gogs/
    command=/home/git/gogs/gogs web
    autostart=true
    autorestart=true
    startsecs=10
    stdout_logfile=/var/log/gogs/stdout.log
    stdout_logfile_maxbytes=1MB
    stdout_logfile_backups=10
    stdout_capture_maxbytes=1MB
    stderr_logfile=/var/log/gogs/stderr.log
    stderr_logfile_maxbytes=1MB
    stderr_logfile_backups=10
    stderr_capture_maxbytes=1MB
    user = git
    environment = HOME="/home/git", USER="git"
    
  • 最后执行命令supervisorctl start gogs,将Gogs变成可监控的服务。

如果网站仍然使用HTTP协议,会感觉网站处于全裸状态,这实在是不利于身心健康。而Let’s encrypt网站免费为大家签发证书让我们不用花钱则获得可信任的SSL私KEY用于网站的HTTPS服务,实在是太方便各网站站长了。然后使用Let’s encrypt的开源项目Certbot,可以很方便的申请网站证书以及下载证书。Certbot的网站为https://certbot.eff.org/,访问这个网站然后按照上面的说明来安装Certbot并且申请证书,然后修改你的Web服务器配置,将SSL证书配置好即可,第一次配置整个过程不会超过半小时。

首先我用的系统是Debian 8.7 (jessie),所以说明文档在https://certbot.eff.org/#debianjessie-nginx,按照文档上的步骤:

  • 需要先安装Certbot:sudo apt-get install certbot -t jessie-backports
  • 然后申请证书:certbot certonly --webroot -w /var/www/example -d example.com

    注:之所以需要网站根目录作为参数,是因为在申请证书的时候需要验证网站所有权,证书机构会往该域名的网站目录下写一些验证文件,然后通过http访问以确定你拥有该网站。

  • 然后修改nginx服务器侦听端口成为443(apache服务器请自行查阅相关文档):
    listen 443;
    listen [::]:443;
    
  • 添加ssl相关的选项:
    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/cert.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
  • 添加服务器配置将http的访问自动导向https:
    server {
      listen 80;
      listen [::]:80;
      server_name example.com www.example.com;
      return 301 https://$host$request_uri;
    }
    
  • 添加Renew的代码到contab服务中,每天定时Renew一下证书,虽然证书有效期是三个月,但是Renew的时候若证书没有超时则不会重新下载新的证书下来,所以每天定时Renew一下是非常有必要的,Renew的代码为:certbot renew --dry-run

以上步骤完成后,使用命令nginx -s reload把nginx服务器的配置重新载入一遍,打开Chrome浏览器访问配置好的网站则可以看到地址栏左边有绿色的Secure字样,若没有看到Secure字样,有可能是因为该页面中仍然包含了非加密和浏览链接。想要找出这些非加密的浏览链接,可以按快捷键CTRL+SHIFT+J打开命令控制台看Console页面中的日志,Chrome会告诉你哪些地方加载了未加密的内容。

首先确保已经安装了ncurses,然后使用以下其中一个命令(32或者64位自行挑选)

ln -s /lib64/libncurses.so.5 /usr/lib/libtinfo.so.5
ln -s /usr/lib/libtinfo.so.5 /usr/lib/libtinfo.so

长期以来写C++代码,其实自己的格式和规范在不同的项目中都不一样,有时候全小写下划线,有时候用驼峰,在写代码的过程中,碰到很多问题也经过了自己的一些思考。今天终于抽时间读了一下Google的C++规范文档,关于命名方式有些也和自己思考的结果一致。

以下为参考链接

Google C++代码命名规范
Google C++代码格式

其实Google的规范文档不止是格式或者命名,对于C++的使用还有其它的一些规定,比如:禁止使用宏来定义常量,禁止使用异常,禁止使用C++流。这几点在我平时的C++代码里是经常出现的。

使用CMake的最低版本为2.8.4

cmake_minimum_required(VERSION 2.8.4)

指定工程名称为”sample”

project(sample)

使用find_package来查找已经安装到系统中的库

# Boost
find_package(Boost 1.54 REQUIRED regex program_options date_time filesystem system thread)
 
# OpenSSL
find_package(OpenSSL REQUIRED)
 
# Google Protobuf
find_package(Protobuf REQUIRED)

添加C++的编译参数

add_definitions(-std=c++11)

设置编译参数(DEBUG)

set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")

./src/*.cpp文件添加到编译列表

file(GLOB SRC "./src/*.cpp")
add_executable(sample ${SRC})

链接额外的库文件(Boost_LIBRARIES是Boost.cmake中预定义的宏,也就是文件最头定义的那些boost文件)。同时,以下的makefile脚本也将链接OpenSSL的库,以及protobuf和mysqlcppconn两个库。

target_link_libraries(sample ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} protobuf mysqlcppconn)

安装目标文件到[prefix]/bin/目录下,默认的prefix目录是/usr/local/,所以,以下的makefile脚本将会把sample工程的可执行文件安装到/usr/local/bin/目录下。

install(TARGETS sample DESTINATION bin)

以下为安装可执行脚本到[prefix]/sbin/目录下。与TARGETS唯一不同的地方是,安装完成后将会把对应的文件加上可执行属性。

install(PROGRAMS ./hello.sh DESTINATION sbin)

以下为安装文件,并且会在安装文件前先判断该是否存在,若存在则不安装该文件。

file(GLOB config_file “${CMAKE_INSTALL_PREFIX}}/etc/ume/ume-sc.conf")
if(NOT EXISTS ${config_file})
  install(FILES "./ume-sc.conf" DESTINATION etc/ume)
endif()

变量的基本操作

# 定义一个变量
set(variable_name 100)
 
# 取消一个变量的定义
unset(variable_name)
 
# 判断一个变量是否定义
if (DEFINED variable_name)

在指定的目录中查找某个库并链接

find_library(JSONCPP_LIB jsoncpp /opt/local/lib)
target_link_libraries(sample ${JSONCPP_LIB})

在某TARGET完成编译后执行命令,通常可以用来执行测试用例

add_custom_command(TARGET [target_name] POST_BUILD COMMAND [command])

添加指定的生成命令,例如,在编译某工程时使用到了protobuf编译器生成的源文件,于是需要在这里添加该源文件的生成说明,然后当编译需要使用到该文件时将会自动调用该生成步骤将源文件生成出来。注:CMAKE_CURRENT_BINARY_DIR为当前CMake编译目录。

add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/file.cpp
  COMMAND protoc file.proto --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/
  COMMENT "Generating file.c..."
)

上海这几天雨不断,翻了以前的代码,把计算生辰八字的代码整理了一下,并且放到了github上。代码是用c++写的,其实中文年、月、日直接从本地数据库查的农历,获得了六个字后,将小时转换成为时辰算出第八个字。编译后可以直接获得命令行工具版本,具体请参见github上的说明。

希望以前做的每一件事情都能留下些好的东西并且能够帮到别人。

https://github.com/mattxlee/eightwords