我更喜欢把CMake中的“配置文件”称为“模板文件”。

Hello模板文件

如何写一个模板文件,并使用呢?

  1. 一般将模板文件命名为<文件名>.<后缀名>.in
  2. 在模板文件中,使用@<cmake-var-name>@方式即可引用一个CMake变量,如@Tutorial_VERSION_MAJOR@
  3. 在CMake文件中,使用configure_file命令,即可把CMake变量传入模板文件,生成结果文件
    1. configure_file(TutorialConfig.h.in #输入文件(即模板文件)
    2. TutorialConfig.h #输出文件
    3. @ONLY #替换配置文件中的@变量,这个可以省略不写
    4. )

配置文件的妙用

毋庸置疑,CMake之C++是非常成熟的。但在构建某些C#工程而言,会显得非常吃力。此时“模板文件”就能帮助我们构建一个非常复杂的工程。

使用步骤:

  1. 使用Visual Studio创建好你中意的C#工程
  2. 然后将<文件名>.csproj进行修改
    1. 将需要CMake传入的变量改成@<cmake-var-name>@
    2. 将文件名改成<文件名>.csproj.in
  3. 使用configure_file将模板文件编译成<文件名>.csproj
  4. 有多种方式
    1. 将项目加入工程中,可以使用命令include_external_msproject(目标名, <文件名>.csproj)引入外部的VS工程
    2. 可以使用dotnet.exe,直接编译、运行这个工程

详细的例子可参考《CMake SWIG C#》的应用文章。

配置文件会用到的相关写法

拼接字符串

参考文章:configure_file list of files -> #includes cmake

例一:获取源代码列表,并拼接成字符串

  1. CMakeLists.txt ``` cmake_minimum_required(VERSION 3.8) project(swigdotnettest)

获得源代码列表,并拼接成字符串,模板文件中要使用

set(source_files_string) file(GLOB_RECURSE SRC_FILES ${CMAKE_CURRENT_LIST_DIR}/*.cs) foreach(item ${SRC_FILES})

  1. # <Compile Include="exe_test.cs" />
  2. set(source_files_string
  3. "${source_files_string}<Compile Include=\"${item}\" />
  4. "
  5. )

endforeach()

获得依赖库

set(references_string “”) join_references_string(references_string ${Project_OUTPUT_DIR}/smartgis_core_csharp.dll ${Project_OUTPUT_DIR}/glal_core_wrapper_dotnet.dll ${Project_OUTPUT_DIR}/glal_util_wrapper_dotnet.dll )

生成测试工程

configure_file(dotnet_xunit_template.csproj.in ${PROJECT_NAME}.csproj @ONLY)

加入

include_external_msproject( ${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.csproj )

  1. 2. dotnet_xunit_template.csproj.in

@PROJECT_NAME@ netcoreapp2.0

  1. <IsPackable>false</IsPackable>
  2. <Configuration>Release</Configuration>
  3. <Platform>@platform_type@</Platform>
  4. <OutputPath>@Project_OUTPUT_DIR@</OutputPath>
  5. <!--输出目录去掉版本目录。没有这个标签,输出目录是OutputPath\net5 -->
  6. <AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>

@source_files_string@

@references_string@

  1. 3. join_references_string

拼接csproj中依赖库的字符串

references_string 返回值(csproj中依赖库的字符串)

其他参数 收集在dependlibs_path中

macro(join_references_string references_string) set(dependlibs_path “${ARGN}”) #依赖库的全路径

  1. # 处理一个依赖库
  2. foreach(dependlib_path ${dependlibs_path})
  3. #没有后缀名的文件名称
  4. get_filename_component(dependlib_name ${dependlib_path} NAME_WLE)
  5. # <Reference Include="simple_wrapper_dotnet">
  6. # <HintPath>$(OutputPath)\simple_wrapper_dotnet.dll</HintPath>
  7. # </Reference>
  8. set(item_string
  9. "
  10. <Reference Include=\"${dependlib_name}\">
  11. <HintPath>${dependlib_path}</HintPath>
  12. </Reference>
  13. "
  14. )
  15. set(${references_string}
  16. "${${references_string}}${item_string}"
  17. )
  18. endforeach()

endmacro() ```