# 基于Qt进行跨平台开发的一些小问题 ## UTF-8 BOM 的问题 含有中文的源码,如果在Linux下开发,基本上无脑UTF-8就可以了。但是,如果你接着把代码拿到Windows下开发,又用的是msvc编译器,编译时就会出现“常量中有换行符”这种很恶心的错误,原因是:Linux下的UTF-8都是不带BOM的,而msvc编译器在默认设定下读到BOM才会把文件当做是UTF-8,否则统统按ANSI解码,于是读到中文那里就认为半个中文是一个换行符了(据说如果是四个汉字就不会报错?)。 最简单的方法自然是加上BOM,这可以通过QT Creator的编辑器设置实现。但是,考虑到我们还要在Linux下进行开发,如果在Windows这头给的文件加上BOM,当代码回到Linux环境时,这BOM会不会引起麻烦很难说。 解决这一矛盾的办法是,调用msvc编译器时,传递一个命令行选项,告诉他这个文件就是UTF-8,你他娘的不要给劳资乱解释。在`.pro`文件中加入: ``` win32 { QMAKE_CXXFLAGS += /utf-8 } ``` 即可实现在Windows环境下自动向编译器传递这个选项,同时不影响Linux下的开发。 ## 拷贝文件到编译目录 有些运行时配置文件,一般希望同步保存到代码树中,在编译时自动部署到编译位置。对此,Qt提供了有限而**迷人**的跨平台支持: ``` copydata.commands = $(COPY_DIR) $$shell_quote($$shell_path($$PWD/config)) $$shell_quote($$shell_path($$OUT_PWD)) first.depends = $(first) copydata export(first.depends) export(copydata.commands) QMAKE_EXTRA_TARGETS += first copydata ``` `copydata`就是个名字,随便取。`$(COPY_DIR)`在Windows下会被解释为`xcopy`,在Linux下则解释为`cp`,`$$shell_quote`/`$$shell_path`啥的都是自动替换路径斜杠、加引号啥的,`first`绑定的是编译之前要做的工作,给`first.depends`赋值表示“做完`copydata`,编译前准备工作才能开始开展”。 如果某些情况下需要更精细的控制,比如Windows下msvc版Qt编译出来的exe也是很讨厌地会被放到`Debug`/`Release`子目录下,就需要继续施展黑科技了: ``` copydata.commands = $(COPY_DIR) $$shell_quote($$shell_path($$PWD/config)) $$shell_quote($$shell_path($$OUT_PWD)) win32 { DESTDIR += CONFIG(release, debug|release) { message( "Release build" ) DESTDIR = release } CONFIG(debug, debug|release) { message( "Debug build" ) DESTDIR = debug } copydata.commands = $(COPY_DIR) $$shell_quote($$shell_path($$PWD/config)) $$shell_quote($$shell_path($$DESTDIR/config)) } first.depends = $(first) copydata export(first.depends) export(copydata.commands) QMAKE_EXTRA_TARGETS += first copydata ``` 两个`CONFIG(debug, debug|release)`语句实现的是根据编译配置的不同,为`DESTDIR`赋不同的值。具体为啥要写的这么难看,看了看[解释](https://stackoverflow.com/questions/18164490/qmake-config-function-and-active-configuration)也不是很懂……