// -*- mode: org; -*-
下载boost_1_57_0.7z(从源里直接安装老版本的boost,在编译用户程序时,会遇到问题) ./bootstrap.sh –show-libraries 看有哪些库 ./bootstrap.sh –with-libraries=filesystem 说我只想要filesystem sudo ./b2 install 安装
文档在这里 http://www.boost.org/doc/libs/1_57_0/more/getting_started/unix-variants.html 5.1 Easy Build and Install
因为之前只选择了filesystem,此时想安装program options 再运行./bootstrap.sh –show-libraries 却只显示已经安装的filesystem
想了个办法,运行 ./bootstrap.sh –without-libraries=filesystem 然后再运行 ./bootstrap.sh –show-libraries
就能看到所有库的名字了 ./bootstrap.sh –with-libraries=filesystem,program_options
duyanning@du-ASUS ~/work/cpps/debug $ cpps hi.cpp cpps: error while loading shared libraries: libboost_filesystem.so.1.57.0: cannot open shared object file: No such file or directory
这个文件明明有,位于/usr/local/lib
sudo tee /etc/ld.so.conf.d/locallib.conf 输入 /usr/local/lib 回车 Ctrl-D
执行 sudo ldconfig
用last_write_time只能调整modify time,却调整不了change time 用//抹掉#!会导致两者都改变
“Modify” is the timestamp of the last time the file’s content has been mofified. This is often called “mtime”. “Change” is the timestamp of the last time the file’s inode has been changed, like by changing permissions, ownership, file name, number of hard links.
这会对cpps造成什么影响呢?我怎么忘了记录了。
这个文件也就开发时用用,发布后要从config.h.in生成config.h
执行gcc都是在cpps最初运行的当前目录。 提供给gcc的文件名都是绝对路径。 但是内嵌Makefile的动作,都是些shell命令。命令中引用的文件,是Makefile中写死的,是相对路径。
这样一来,但main.cpp引入src/foo.cpp时,foo.cpp中的内嵌Makefile动作的执行,可能就存在问题。
对于文件节点,什么时候执行关联的动作呢? 首先,当文件节点代表的文件还不存在时,自然应当执行动作。 然后,就是看依赖的节点(通过都代表文件)所代表的文件在更新之后有没有发生变化。 如何就是有变化了? 不是说比较以下当前节点文件跟下级节点文件,如果后者比前者年轻,才算有变化。 变老也算变化。 就算年龄没变,大小不了也是不了。 就算大小也没变,实际的内容也可能发生变化。 所以,我们所说的“变化”,实际上是指下级文件节点所代表的文件的内容发生“变化”。 内容才是真正关键的。考察时间,不过是我们认为时间变化暗含着内容的变化。 但实际并非如此。时间变了,内容可能并没有变化。比如执行touch。 但出于对touch的尊重,我们认为时间变了,也是一种变。但仅仅是对惯例的一种尊重。
真正要追踪内容是否变化,得用到文件摘要,但摘要是个很慢的过程。我们有折衷办法。
如果如果一个cache中的文件,依赖另一个cache中的文件,后者年龄的年轻化就代表了后者的内容发生改变。 而且cache中的文件不会变老。
会变老的文件,就是cache之外的文件,比如.cpp文件。比如用备份文件覆盖修改过的.cpp,就会导致.cpp文件变老。
================================= Entity 依赖图节点 FileEntity 文件节点 PhonyEntity 并不对应物理实体的节点
Entity定义了update方法,这个方法叫make也可以。
对于FileEntity,update方法并不一定重新生成文件。 update的返回值代表update是否成功。 但成功有两种情况: 1.重新生成了文件 2.不用重新生成文件
什么时候update要重新生成文件? 答:当下级节点的内容发生改变时。否则的话,就不用重新生成文件。
所在,就需要在update中检查下级节点的内容是否发生改变。 即,当前节点的update首先调用下级节点的update,然后判断下级节点在update前后内容是否发生改变。 如何判断内容是否发生改变?可以对比下级节点在update前后文件的md5哈希值。
下级节点的内容变了,当前节点肯定是要生成文件的。 除此之外,以下情况下,当前节点也要生成文件: 当前节点的文件压根不存在 某个非关键下级节点(比如.h节点)的update失败了(比如该下级节点不复存在):生成当前节点文件才能导致编译器报错
========================= 对于位于叶子上的文件节点,它没有下级节点。 它的update是怎么样? 因为下级节点列表为空,所以并不会真正去update什么下级节点。所以也不会比较下级节点在update前后md5的变化。
========================== PhonyEntity 并不对应物理实体的节点
它的update也是先让下级节点update。下级节点可能是文件节点。 至于自己身上的动作,是必须执行的,但只执行一次。哪怕有两个节点将该节点作为下级节点。 即在节点中记录一下updated=true,下次update时若发现updated==true就直接返回true。 =========================== 如果一个FileEntity把一个PhonyEntity当作下级节点,它该如何检查下级节点的md5? 也许会有这种情况。但一般不会有,在cpp项目中不会有,但epm中可能会有。判断一下下级节点是什么节点就能解决。 =================================================== 上面所说的,都没考虑到一个问题。 同一个obj文件,我想让它被两个exe使用。 两个exe来自两次无关的脚本执行。即两个exe不在同一张依赖图上。
用md5会有什么问题? a.exe与b.exe都包含了c.obj a.exe先生成,其中包含的是c.obj(old c.cpp)
然后修改c.cpp 然后生成b.exe,其中包含的是c.obj(new c.cpp)
然后重新生成a.exe,会发现c.obj在update前后,签名并没有变化。所以a.exe不会重新生成。
解决方案:a.exe中应该记录自己包含的c.obj的md5。如果md5没有变,就不用重新进入exe。
md5可以用来检测update前后是否发生变化,也可以用来检测现在跟上次包含obj时,obj是否变化。
====================================== 我说的是md5,其实就是签名。 ===================================== 不是obj的签名在update前后变了,exe就要重新产生。 而是obj现在的签名,跟exe上次使用的obj的签名不一样,就要重新产生exe。
那我对比obj文件update前后的签名是干什么用呢?是为了知道哪些下级节点改变了。 但这个“改变”,仅仅是update前后的改变,若不是当前跟exe上次生成时obj的改变。 ================================= 再回到导致这次fix的bug:
main.cpp包含了foo.h,执行main.cpp后,将foo.h改名为bar.h,但不修改main.cpp。 希望:main.cpp编译时报错。 可是:没等main.cpp报错,cpps就抱怨无法make foo.h。因为.d文件中说main.o依赖foo.h,但是现在却找不到foo.h。
解决办法:.h找不到就找不到,又不是关键文件。.cpp才是关键文件。在这种情况继续编译.cpp,让编译器报错说找不到foo.h。 不然cpps报找不到foo.h,你还不知道是哪里用到这个foo.h。让编译器在.cpp文件中发现问题要好得多。
出生证明文件还得用上,里面记录着生成该文件时所用的下级文件的签名。
检测update前后文件是否发生改变有什么用?无非就是给将要执行的动作提供一点信息。 当前节点的动作要不要执行,还是要比较生成当前节点时记录的下级的签名,跟下级节点现在的签名。
gcc的选项 https://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html
cpps必须在执行过vcvars32.bat的cmd窗口中才能调用cl.exe 我想把vcvars32.bat这步省了
system函数通过绝对路径调用调用cl.exe
std::cout << "Hello World!\n";
// 没有管道ok的
//string cmd = R"("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\Hostx86\x86\cl.exe")";
// 管道+minised 不行。
//string cmd = R"("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\Hostx86\x86\cl.exe" | sed "xxx")";
//string cmd = R"("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\Hostx86\x86\cl.exe" | sed --help )";
// 管道+dir ok的.
// 管道+工程目录下的hello.exe是好的
// 管道+通过path找到的hello.exe也是好的
// 只要管道后边出现双引号就不行
// 参考: https://stackoverflow.com/questions/9964865/c-system-not-working-when-there-are-spaces-in-two-different-parameters
// 最后改成下面这种形式。就是在前后再加上双引号就可以了。即传给system函数的东西,除了给带空格的路径加上双引号之外,还要最后再在所有东西前后加上双引号。
// 这最后加的双引号会被cmd去掉。
string cmd = R"***(""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\Hostx86\x86\cl.exe" "" ")***";
cout << "detail: " << cmd << endl;
system(cmd.c_str());
然而通过绝对路径调用cl搞定了,但是cl需要的一些设置,因为没有执行vcvars32.bat却缺乏了。导致无法正常编译。
vcvars32.bat应当就是设置了一些环境变量 我先在一个干净的cmd窗口中执行set,列出所有环境变量; 然后再在该cmd窗口中执行vcvars32.bat,然后再用set列出所有环境变量。 并将二者对比,发现果然设置了很多环境变量。 我觉得其中重要的是:INCLUDE, LIB, LIBPATH, PATH四个
set INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\include;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt
set LIB=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\lib\x86;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86;C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86;
set LIBPATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\lib\x86;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86\store\references;C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0;C:\Program Files (x86)\Windows Kits\10\References\10.0.17763.0;C:\Windows\Microsoft.NET\Framework\v4.0.30319;
set Path=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x86;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\VCPackages;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\;C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86;C:\Program Files (x86)\Windows Kits\10\bin\x86;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\MinGW\bin;F:\myprj\cpps\Debug;C:\Users\duyanning\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Java\jdk1.8.0_144\bin;F:\java-tools\apache-maven-3.6.1\bin;;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;F:\vcpkg\installed\x86-windows\tools\qt5
把这四个设置一下,就可以执行cl了。 我希望能够再精简一下 我把libpath整个干掉,好像没问题。cpps仍能正常工作。
set INCLUDE= C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\include; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\include; C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um; C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt; C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared; C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um; C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt; C:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt
set LIB= C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\ATLMFC\lib\x86; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\lib\x86; C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86; C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x86; C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86;
set Path=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.21.27702\bin\HostX86\x86; 其实path只需要上面这一个目录,就是cl.exe所在的目录 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\VCPackages; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TestWindow; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\bin\Roslyn; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Team Tools\Performance Tools; C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\; C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\; C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86; C:\Program Files (x86)\Windows Kits\10\bin\x86; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin; C:\Windows\Microsoft.NET\Framework\v4.0.30319; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\; C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\; 下面剩下的都是系统自己的路径 C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\MinGW\bin;F:\myprj\cpps\Debug;C:\Users\duyanning\AppData\Local\Microsoft\WindowsApps;C:\Program Files\Java\jdk1.8.0_144\bin;F:\java-tools\apache-maven-3.6.1\bin;;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;F:\vcpkg\installed\x86-windows\tools\qt5
例子: 比如fltk的fluid 可从.fl文件生成.cpp文件跟.h文件
例子: qt的moc从.h生成.cpp
例子: qt的uic从.ui(qt的界面文件)生成.h uic widget.ui -o ui_widget.h http://c.biancheng.net/view/1820.html
有生成.h的,有生成.cpp的
给.cpp文件附加动作(本来.cpp文件是没有关联动作的) 并让.cpp文件依赖于.fl文件(本来在依赖图中.cpp文件是叶子节点)
至于要生成.cpp文件需要执行什么动作,需要在其他先天存在的.cpp文件中指定
/* cpps-make a.cpp : a.fl
fluid -c filename.fl
*/
// cpps-make a.cpp a.h : a.fl // fluid -c filename.fl
动作部分可以有多行,直到*/ 每一行都会成为一个ShellAction对象,挂在.cpp文件对象身上。
参考: https://doc.qt.io/archives/qt-4.8/moc.html
/* cpps-make moc_myclass.cpp : myclass.h
moc myclass.h
*/
因为这类.cpp是生成的,所以在scan阶段,可能并不存在,所以usingcpp跟using指令还得处理文件不存在的情况,
#include xxx.h // using(gen) moc_myclass.cpp
或者可以把生成动作也写在这里
#include xxx.h // using(gen) moc_myclass.cpp : myclass.h // moc myclass.h
只产生.cpp好处理,要是也产生.h,那么编译.cpp的顺序就很重要。 要先产生.h,产生才能编译包含该.h的其他.cpp。 (可以参考处理gcc预编译头文件的做法,单独搞个阶段处理生成他们)
说这么多?因为python脚本使用fltk时,有没有自动执行fluid? http://pyfltk.sourceforge.net/
这个事情先放放
自从有了内嵌Makefile,就可以处理Qt等项目了 但是,手动编写内嵌的Makefile依然是很麻烦的。 可以提供一些特殊指令,方便Qt工程的处理
比如某个.h要用moc编译,产生的.h.cpp还要加进工程,可以用一条指令完成,比如
#include "a.h" // cpps-rule-qt-moc a.h
// or
#include "a.h" // cpps-rule-qt
这些指令对应的规则,不要内建在cpps的代码中,而应该以可编辑的模板文件形式提供
我mingw编译出来的cpps,用的老版本的boost
vc编译出来的cpps,用的新版本的boost
于是,前者在读取后者串行化的文件时,抛出异常了。