C++ 比较尴尬的一点就是缺少比较“傻瓜”的工具库,不得不依靠第三方来补充。想快速开始写个小的 Demo 的时候光找库就花去不少时间。于是糊了一个脚本去自动生成这些基础的东西。放在这里方便自己以后参考。
用到的库列表:
{fmt}: 字符串格式化库
spdlog: 日志
backward-cpp: 崩溃时的堆栈输出
benchmark: 快速性能测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 #!/bin/bash print_help () { echo "Usage:" echo " cproject <type> <name>" echo "Types:" echo " bin, bench" } die () { echo "Unexpected error" exit 2 } new_bin () { local name="$1 " mkdir "$name " || die cd "$name " || die git clone 'https://github.com/fmtlib/fmt.git' third_party/fmt || die git clone 'https://github.com/bombela/backward-cpp.git' third_party/backward-cpp || die git clone 'https://github.com/gabime/spdlog.git' third_party/spdlog || die cat << EOF > CMakeLists.txt cmake_minimum_required(VERSION 3.11) project(${name} ) if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Debug) endif() set (CMAKE_EXPORT_COMPILE_COMMANDS ON)set (CMAKE_C_STANDARD 11)set (CMAKE_CXX_STANDARD 17)set (CMAKE_POSITION_INDEPENDENT_CODE ON)set (CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -Wall -Wextra" )set (CMAKE_CXX_FLAGS_DEBUG "\${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0" )set (CMAKE_EXE_LINKER_FLAGS "\${CMAKE_EXE_LINKER_FLAGS} -rdynamic" )add_subdirectory(third_party/fmt) add_subdirectory(third_party/spdlog) add_subdirectory(third_party/backward-cpp) add_executable(main) target_sources(main PRIVATE main.cpp \${BACKWARD_ENABLE} ) target_link_libraries(main PRIVATE fmt spdlog -ldw) EOF cat << 'EOF' > main.cpp { ::spdlog::critical(__VA_ARGS__); \ int _ [[maybe_unused]] = \ *reinterpret_cast<int*>(0); } inline int get_return_code () { CRASH("unimplemented function: {}" , __func__); return 0; } int main(int argc, char* argv[]) { fmt::print ("{}, {}\n\n" , "hello" , "world" ); spdlog::set_level(spdlog::level::debug); spdlog::debug("debug message" ); spdlog::info("info message" ); spdlog::warn("warning message" ); spdlog::error("Some error message with arg: {}" , 1); return get_return_code(); } EOF echo echo "Skeleton generated. Run the command and you shall see " \ "the stacktrace demo." echo " cd ${name} && cmake -B build && " \ "make -C build -j main && build/main" } new_bench () { local name="$1 " mkdir "$name " || die cd "$name " || die git clone 'https://github.com/fmtlib/fmt.git' third_party/fmt || die git clone 'https://github.com/bombela/backward-cpp.git' third_party/backward-cpp || die git clone 'https://github.com/gabime/spdlog.git' third_party/spdlog || die git clone 'https://github.com/google/benchmark.git' third_party/benchmark || die git clone 'https://github.com/google/googletest.git' third_party/benchmark/googletest || die cat << EOF > CMakeLists.txt cmake_minimum_required(VERSION 3.11) project(${name} ) if (NOT CMAKE_BUILD_TYPE) set (CMAKE_BUILD_TYPE Release) endif() set (CMAKE_EXPORT_COMPILE_COMMANDS ON)set (CMAKE_C_STANDARD 11)set (CMAKE_CXX_STANDARD 17)set (CMAKE_POSITION_INDEPENDENT_CODE ON)set (CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -Wall -Wextra -g" )set (CMAKE_EXE_LINKER_FLAGS "\${CMAKE_EXE_LINKER_FLAGS} -rdynamic" )set (BENCHMARK_ENABLE_LTO true )add_subdirectory(third_party/fmt) add_subdirectory(third_party/spdlog) add_subdirectory(third_party/backward-cpp) add_subdirectory(third_party/benchmark) add_executable(bench) target_sources(bench PRIVATE bench.cpp \${BACKWARD_ENABLE} ) target_link_libraries(bench PRIVATE fmt spdlog benchmark::benchmark_main -ldw) EOF cat << 'EOF' > bench.cpp constexpr size_t ARRAY_LEN = 1024*64; static void BM_SeqArrayAccess(benchmark::State& state) { int stride = state.range(0); uint64_t arr[ARRAY_LEN]; for (auto _ : state) { for (size_t idx = 0; idx < ARRAY_LEN; idx += stride) { arr[idx] = random(); } } } BENCHMARK(BM_SeqArrayAccess) ->Arg(1) ->Arg(2) ->Arg(3) ->Arg(4) ->Arg(5) ->Arg(6) ->Arg(7) ->Arg(8); EOF echo echo "Skeleton generated." echo " cd ${name} && cmake -B build && " \ "make -C build -j bench && build/bench" echo "You may also need to change your CPU scheduler:" echo " sudo cpupower frequency-set -g performance" } if [[ "$2 " == "" ]]; then echo "Missing project name" echo print_help exit 1 fi if [[ -e "$2 " ]]; then echo "File \"$2 \" already exists" exit 1 fi if [[ "$1 " == "bin" ]]; then new_bin "$2 " elif [[ "$1 " == "bench" ]]; then new_bench "$2 " else echo "Unknown type: $1 " echo print_help exit 1 fi