今天又重新整理并配置了一下YCM的configure file,对于头文件引用路径终于仔细查阅了一下文档,关于-sysroot -isysroot -isystem -iquote以及-I做了一个小的归类:

  • -sysroot – 指定当前的系统路径,就相当于是添加了一个路径作为根目录来搜索,比如,若指定-sysroot /usr/local,那么在紧接下来的参数中若有-isystem /include,那么/usr/local/include路径也会被加入到搜索路径中
  • -isysroot – 同-sysroot,唯一区别是-isysroot只添加头文件的搜索路径,而-sysroot会添加头文件及库文件的搜索路径
  • -isystem – 添加系统搜索路径,也就是使用#include <...>的文件的搜索路径
  • -iquote – 添加本地搜索路径,也就是使用#include "..."的文件的搜索路径
  • -I – 添加系统或者本地搜索路径,已经弃用,建议使用-isystem-iquote

详细的参数解释可以参考:GCC官方网站的关于Directory Options的英文文档

为什么使用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

长期以来写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

苹果的推送服务

每一台的苹果设备(iOS, Mac)都会和苹果服务器建立一个加密的长连接,当有需要的时候,苹果公司使用该长连接向指定的设备发送消息,往往用于通知用户设备中的某个App有新的数据需要接收等,并且该通知消息会显示在设备的通知消息栏中。而用户可以根据自己的喜好来打开或者关闭某个App的通知。

如下图所示,我们要做的工作就是蓝色方块(Provider)的事情,拿到了证书(Certificate)后向APNS Servers发送推送消息,再由APNS Servers向用户设备发送消息。

apns

如何做推送

事实上,除了本地推送外(客户端在本地设置好定时推送消息给用户的方式,该方式是不需要走苹果的远程推送服务的,也不需要任何的网络介入,所以不在本文的讨论范围)推送都需要经过苹果的服务器来将信息传递给指定的客户端,所以如何将信息提交给苹果服务器是关键的一步。

首先你需要和苹果服务器建立一个安全连接

    1. 要想建立安全连接,那么就需要证书,打开https://developer.apple.com进入到开发者的页面,按照苹果官方的文档添加你的App-id到开发者帐号中(在该过程中,你有可能需要制作开发证书用于真机调试,也有可能需要制作发布证书,若你需要提交你的App到苹果的AppStore。嗯,无尽的证书模式已开启)
    2. 添加好了App-id后,添加推送的证书,你可以选择添加开发证书和生产证书,添加好了之后类似下图所示:其中Development SSL Certificate是开发证书,用于开发调试的时候使用,而Production SSL Certificate是生产证书,当App提交并且通过审核后将会使用该证书来进行推送
      推送证书
    3. 添加好了开发证书后,此时在你的机器中的钥匙管理器里应该可以找得到对应的钥匙记录,将证书和key导出成为.p12文件,如下图所示:(开发证书或者生产证书都需要导出两个.p12文件,一个是证书的.p12,一个是私key的.p12,下图显示的是导出证书的.p12文件,需要导出私key的.p12文件请点开该证书记录前面的小三角符号展开获得私key记录后,再右击该私key记录点击导出选项进行导出操作)
      导出推送需要的证书
    4. 证书和私key准备好了之后,使用openssl将证书和私key的两个.p12文件转成.pem格式
      openssl pkcs12 -in [.p12文件] -out [.pem文件] -nodes

将libcapn开发包接入到你的程序

  1. 其实github上的开源项目都是挺好编译并且使用的,即使是想用在自己的工程中,最简单的就是直接将源代码克隆下来,然后把对应的代码拷贝到自己的工程中调整编译开关等参数编译即可。
  2. 值得注意的是,libcapn为了不自己写json,使用了一个json库,叫做jansson,但是该库已经在其源代码中包含了一份拷贝,在添加libcapn到自己的工程的时候注意添加jansson库的源代码以及头文件。
  3. 若你使用C++,可以考虑使用我的github上的基于libcapn的代码整合出来的C++类,具体的请参见:https://github.com/mattxlee/ios-push-service。其实都是很简单的封装,只是使用C++封装后让事情变得简单了起来。

国内推送SDK

我们在开发社交软件服务器时,往往需要根据某个事件(比如当某用户不在线而有另一个用户给他/她发送了消息)向指定的用户发送消息,于是这时需要我们的服务器来将该条通知消息发送给用户,于是必不可少的需要自己来写这些推送的代码,但是如果只是定时发送推送内容或者手动发送推送消息,则可以考虑使用国内的一些SDK来完成这些推送,这样做往往也会省掉不少的事情。

  1. 首先定义一个PCH文件,把所有的公共的include都加到这个文件中来
  2. 定义一个cpp文件,只include该PCH文件
  3. bjam的Jamfiles里增加cpp-pch pch : <pch头文件> ;以及在lib或者exe中将pch包括到编译列表中
  4. 所有的其它的cpp文件都需要在第一行include这个PCH文件
  5. 详细可以参见:http://www.boost.org/boost-build2/doc/html/bbv2/reference/precompiled_headers.html

如果你不巧要使用protobuf 2.4.1并且很不巧需要在macosx下编译,那么你需要修改google/protobuf/message.h,否则编译将会出错,具体的解决办法可以参考:https://code.google.com/p/protobuf/issues/detail?id=570

下面的代码是从帖子里拷贝过来的,替换掉原来的google/protobuf/message.h中的内容即可

I think the right way to fix it is to modify the message.h like below
#ifdef __DECCXX
// HP C++'s iosfwd doesn't work.
#include <iostream>
#else
#include <sstream>
//#include <iosfwd>
#endif

1. 在.pro文件中增加TRANSLATIONS = chinese.ts
2. 使用”工具”->”外部”->”qt语言家”->”更新翻译”,然后会在当前的工程目录下生成chinese.ts文件
3. 在工具Linguist中打开chinese.ts文件,逐个将翻译的语言输入,每翻译好一个使用CTRL+ENTER保存并自动跳到下一个
4. 都做好了,保存文件,然后选择”发布”,将该语言编译成qm文件
5. 回到Qt,在资源文件中添加该qm文件,然后到main.cpp,添加以下代码,注意要把对应的资源文件路径和名称替换成为你自己的

QTranslator translator;
translator.load(":/languages/chinese.qm");
app.installTranslator(&translator);