public:it:cmake

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
public:it:cmake [2020/11/09 13:50] – 创建 oakfirepublic:it:cmake [2024/09/03 14:06] (当前版本) – [CMake] oakfire
行 2: 行 2:
   * Official Site:[[https://cmake.org/|cmake.org]]      * Official Site:[[https://cmake.org/|cmake.org]]   
   * c++跨平台构建工具,开源[BSD]免费。   * c++跨平台构建工具,开源[BSD]免费。
 +  * CMake [[https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html|变量列表]]: 
 +  * CMake 变量的作用域:[[https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#cmake-language-variables|cmake-language-variables]] 
 +    * 父目录里的绑定变量默认会传到子目录的CMakefile作为初始值 
 +  * find_package 默认支持的列表:''cmake --help-module-list | grep -E ^Find''
 ===== Tips ===== ===== Tips =====
   * MSVC中, cmake 默认生成的 release 工程不生成 pdb 文件,可如下添加<code cmake>   * MSVC中, cmake 默认生成的 release 工程不生成 pdb 文件,可如下添加<code cmake>
行 13: 行 16:
     # if build static .lib      # if build static .lib 
     set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF" CACHE STRING "" FORCE)     set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF" CACHE STRING "" FORCE)
-else (MSVC) 
 endif (MSVC) endif (MSVC)
-</code> 参考 https://cmake.org/cmake/help/latest/variable/CMAKE_SHARED_LINKER_FLAGS_CONFIG.html+</code> 参考 [[https://stackoverflow.com/questions/28178978/how-to-generate-pdb-files-for-release-build-with-cmake-flags/31264946|how to generate pdb files...]], 或者使用 [[https://cmake.org/cmake/help/v3.18/manual/cmake-generator-expressions.7.html|cmake generator expressions]]来设置:<code cmake> 
 +target_compile_options(${YourProjName}  
 +    PRIVATE "<<AND:<CXXCOMPILERID:MSVC>,<CONFIG:Release>>:/Zi>" 
 +
 +target_link_options(${YourProjName} 
 +    PRIVATE "<<AND:<CXXCOMPILERID:MSVC>,<CONFIG:Release>>:/DEBUG>" 
 +    PRIVATE "<<AND:<CXXCOMPILERID:MSVC>,<CONFIG:Release>>:/OPT:REF>" 
 +    PRIVATE "<<AND:<CXXCOMPILERID:MSVC>,<CONFIG:Release>>:/OPT:ICF>" 
 +
 +</code> 
 +  * 给dll右键属性的详细信息里添加git version, 参考[[https://zhuanlan.zhihu.com/p/97512450|zhihu 97512450]]<code cmake> 
 +add_definitions(-DMAIN_PROJECT_NAME=\"${YourProjName}\"
 +find_package(Git QUIET) 
 +if(GIT_FOUND) 
 +    set(COMMIT_HASH ""
 +    set(BRANCH_NAME ""
 +    execute_process( 
 +        COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%H 
 +        OUTPUT_VARIABLE COMMIT_HASH 
 +        OUTPUT_STRIP_TRAILING_WHITESPACE 
 +        ERROR_QUIET 
 +        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
 +    ) 
 +    execute_process( 
 +        COMMAND ${GIT_EXECUTABLE} symbolic-ref --short -q HEAD 
 +        OUTPUT_VARIABLE BRANCH_NAME 
 +        OUTPUT_STRIP_TRAILING_WHITESPACE 
 +        ERROR_QUIET 
 +        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
 +    ) 
 +    message(STATUS "Git version is BRANCHNAME:{COMMIT_HASH}"
 +    add_definitions(-DGIT_COMMIT_HASH=\"${COMMIT_HASH}\"
 +    add_definitions(-DGIT_BRANCH_NAME=\"${BRANCH_NAME}\"
 +endif() 
 +</code>然后添加VersionInfo.rc<code> 
 + 
 +#if (defined GIT_COMMIT_HASH && defined GIT_BRANCH_NAME) 
 +#define PRODUCT_VERSION GIT_BRANCH_NAME ":" GIT_COMMIT_HASH 
 +#else 
 +#define PRODUCT_VERSION "1.0.2" 
 +#endif //  GIT_COMMIT_HASH && GIT_BRANCH_NAME 
 + 
 +#ifndef MAIN_PROJECT_NAME 
 +#define MAIN_PROJECT_NAME "MyLib" 
 +#endif 
 + 
 +1 VERSIONINFO 
 + FILEVERSION 1,0,0,1 
 + PRODUCTVERSION 1,0,0,1 
 + FILEFLAGSMASK 0x17L 
 +#ifdef _DEBUG 
 + FILEFLAGS 0x1L 
 +#else 
 + FILEFLAGS 0x0L 
 +#endif 
 + FILEOS 0x4L 
 + FILETYPE 0x0L 
 + FILESUBTYPE 0x0L 
 +BEGIN 
 + BLOCK "StringFileInfo" 
 + BEGIN 
 + BLOCK "040904b0" 
 + BEGIN 
 + VALUE "FileDescription", MAIN_PROJECT_NAME " Binary" 
 + VALUE "FileVersion", "1.0.0.1" 
 + VALUE "InternalName", MAIN_PROJECT_NAME 
 + VALUE "LegalCopyright", "Copyright (C) 2020 " 
 + VALUE "OriginalFilename", MAIN_PROJECT_NAME ".dll" 
 + VALUE "ProductName", MAIN_PROJECT_NAME 
 + VALUE "ProductVersion", PRODUCT_VERSION 
 + END 
 + END 
 + BLOCK "VarFileInfo" 
 + BEGIN 
 + VALUE "Translation", 0x409, 1200 
 + END 
 +END 
 +</code> 
 +  * 循环子文件夹来包含子工程,参考 [[https://stackoverflow.com/questions/7787823/cmake-how-to-get-the-name-of-all-subdirectories-of-a-directory|stackoverflow 7787823]]:<code cmake> 
 +MACRO(SUBDIRLIST result curdir) 
 +  FILE(GLOB children RELATIVE curdir{curdir}/*) 
 +  SET(dirlist ""
 +  FOREACH(child ${children}) 
 +    IF(IS_DIRECTORY curdir/{child} AND EXISTS curdir/{child}/CMakeLists.txt) 
 +        LIST(APPEND dirlist ${child}) 
 +    ENDIF() 
 +  ENDFOREACH() 
 +  SET(result{dirlist}) 
 +ENDMACRO() 
 + 
 +SUBDIRLIST(SUBDIRS ${CMAKE_CURRENT_SOURCE_DIR}) 
 + 
 +message(STATUS "valid subdirs: ${SUBDIRS}"
 + 
 +FOREACH(subdir ${SUBDIRS}) 
 +  ADD_SUBDIRECTORY(${subdir}) 
 +ENDFOREACH() 
 +</code> 
 +  * 在 bat 批处理里面,如果cmake命令行报错,参考[[https://stackoverflow.com/questions/46709956/how-do-i-handle-cmake-exe-errors|这里]],可加以下一行来进行退出处理<code Winbatch > 
 +cmake . 
 +if errorlevel 1 exit /B 
 +</code> 
 +  * 屏蔽VC编译 release 时的具体某个 warning,比如c4566, 可用如下,<code cmake> 
 +add_compile_options("<<AND:<CXXCOMPILERID:MSVC>,<CONFIG:Release>>:/wd4566>"
 +</code> 注意 ''add_compile_options'' 可影响之后所有target与子项目target, 所以适合在ci(持续集成)时使用。如果只是想具体设置某target, 使用 ''target_compile_options''。另外,不建议开发时屏蔽warning。 
 +  * cmake 不支持静态库的 dependence, 本质上,静态库只有二进制的合并,没有 link, 只有MSVC可以加 静态库的dependence然后生成合并后的lib, 但这个其它编译器不一定支持,所以cmake也没有这个选项,如果生成的 a.lib 依赖b.lib, 而 c.exe 依赖 a.lib, 一种不用在 c 的配置中显式增加 b.lib 依赖的写法是利用 ''add_library(<name> INTERFACE)'': <code cmake> 
 +add_library(a STATIC  ${STRMBASE_FILES}) 
 +# target_link_libraries(a b) # 这是不起作用的,因为 a 是静态库,没有link 
 +add_library(ab INTERFACE) # 增加一个 ab, INTERFACE  
 +target_link_libraries(ab INTERFACE a b) 
 +add_executable(c ...) 
 +target_link_libraries(c ab) # 此时 c 工程就包含了a.lib, b.lib 
 +</code> 
 +  * [[https://stackoverflow.com/questions/26037954/cmake-target-link-libraries-interface-dependencies|target_link_libraries PUBLIC/PRIVATE/INTERFACE 的区别]]:当创建**动态库**时, 
 +    * 如果源文件包含该第三方头文件,但头文件中不包含该第三方头文件,采用 PRIVATE; 
 +    * 如果源文件和头文件中都包含该第三方头文件,采用 PUBLIC; 
 +    * 如果头文件中包含该第三方头文件,但源文件中不包含,采用 INTERFACE。 
  • public/it/cmake.1604901006.txt.gz
  • 最后更改: 2020/11/09 13:50
  • oakfire