0%

头文件:template.hpp

#ifndef TEMPLATE_HPP
#define TEMPLATE_HPP

template <typename T>
void println(T t);

#endif

源文件:main.cpp

#include "template.hpp"

int main() {
  println(9);
  println(-7);
}

源文件:instantiation.cpp

在看 Modern CMake for C++ 的时候看到了这段代码:

void RunOutputsCorrectEquations() {
  string expected {"2 + 2 = 4\n3 * 3 = 9\n"};
  stringstream buffer;
  // redirect cout
  auto prevcoutbuf = cout.rdbuf(buffer.rdbuf());
  run();
  auto output = buffer.str();
  // restore original buffer
  cout.rdbuf(prevcoutbuf);
  if (expected != output)
    exit(1);
}

看起来 stdio 的 FILE 也能重定向(但是不能保存之前的关联,因而恢复到 stdout 不能跨平台):

https://stackoverflow.com/a/29154180/

// 重定向
freopen("output.txt", "a+", stdout);

// 恢复到终端输出
freopen("/dev/tty", "w", stdout); /*for gcc, ubuntu*/
// or
freopen("CON", "w", stdout); /*Mingw C++; Windows*/

cmake 的 CONFIG 生成器表达式有两种形式,一种是不接受参数、输出当前的 CONFIG 值,还有一种是判断当前的 CONFIG 是否属于几者之一。在判断 Debug 模式的时候一定要小心,因为使用 Makefile 作为生成器时,不传入 CMAKE_BUILD_TYPE 时使用的 CONFIG 为空。

target_compile_options(YourTarget PRIVATE 
    -Wall 
    $<$<CONFIG:,Debug>:-g3>
)

不过,也可以通过显式设置 CMAKE_BUILD_TYPE 来防范就是了:

if (NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE "Debug")
endif()

这样之后再用生成表达式创建自定义 target 打印 $<CONFIG> 的结果就是 Debug。

这篇用来记录学过但是不容易记住的写法。

CMake language

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])
                             ^^^^^^^^^
e.g.
add_subdirectory(src bin)

这个操作是可以给单个文件设置不同的编译选项,而不是对 target 设置。控制的粒度就更细了。

if(MSVC AND NOT CLANG_CL)
 set_source_files_properties(CompileCommands.cpp PROPERTIES COMPILE_FLAGS -wd4130) # disables C4130: logical operation on address of string constant
endif()

CMake 在 3.12 之后有 -j 选项了,无参数则表示不受限。

常用的两个 generators:

Unix Makefiles 默认使用 1 个线程,支持 -j 选项。

Ninja 也支持 -j 选项,如果不指定则使用默认线程数。可以用 ninja --help 来查看。

ninja --help 2>&1|grep -- -j

docker run 创建容器的时候用 --cpuset-cpus 0-3 可以限制 CPU 在 0-3 这四个核心上,实测 nproc 的结果已经改变了。

docker build 的时候也可以用同样的参数,比如 docker build . --cpuset-cpus 0-3,这能够被正常识别,但是 nproc 的结果没有改变,也不知道是否正常限制了。

\begin{document}
% Answer: [trim={left bottom right top},clip]
% Ex. 1: trim from left edge
\includegraphics[trim={5cm 0 0 0},clip]{example-image-a}
% Ex. 2: trim from right edge
\includegraphics[trim={0 0 5cm 0},clip]{example-image-a}
\end{document}

顺序是左下右上。和 css 中的 margin 的指定是相反的顺序。(css 中是上右下左。css 这个好记忆,就是初始位置在最上面,然后顺时针。)

对于整数,可以用 [[]](()) 来比较。

对于浮点数,可以用 bc,但是 bc 不是每个环境都有。

还有一种方法是 perl(如果装了 perl 但是没有装 bc):perl -e "exit(1) if not $a > $b",这样可以用返回值标志是否成功。

重新加载 PATH 中的可执行文件

hash -r:用于解决在 PATH 中加入可执行文件后找不到的情况。

** 匹配多级目录(find 不能匹配双星号)

shopt -s globstar
set +o pipefail
clang-tidy -p build/ ./{src,include}/**/*.{h,hpp,cc,cpp,cu}

第一句是打开 ** 选项,第二句是忽略 pipefail(-o+o 相反)不然第三句的 pipe 可能出错,第三句 2>/dev/null 是忽略错误信息。

*** 都不能直接匹配 *nix 上的隐藏文件,即用 . 开头的文件。

上述命令的功能:clang-tidy 会找到 .clang-tidybuild/ 下的 compile_commands.json 配置并对代码进行分析。