---
title: 编写CMake实现构建多版本工程
date: 2022-08-09 13:55:15
tags: Maya CMake
rating: ⭐️⭐️ 
---
# 编写CMake实现构建多版本工程
1. 点击Configure与Generate根据当前年份与起始年份生成对应的子项目CMakeList.txt。
2. 填入所要生成版本的Devkit路径。
3. 再次点击Configure与Generate,即可生成项目。

## 知识点
### 变量共享
在set中增加**CACHE**关键字就可以到主模块与子模块变量共享的目的。比如:
> set("Maya${CURRENT_YEAR}_DEVKIT_LOCATION" "" CACHE PATH "")

### 子模块
调用**add_subdirectory**添加含有CMakeList.txt的文件夹即可。

### CMake生成文件
使用**file(GENERATE  OUTPUT  Path CONTENT Code)** 就可以生成文本文件了。这样就做到让CMake生成子CMakeList.txt的功能。代码如下(xxx为文本内容):
```cmake
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Maya${CURRENT_YEAR}/CMakeLists.txt" CONTENT XXXX)
```

需要注意代码中的${},需要将他们拆开放置它转义。

### winsock库报错问题
>在cmake里加上一行:**link_libraries(ws2_32)**

或者在VisualStudio的Linker->Input->AdditionalDependencies中添加 Ws2_32.lib即可。 

## 具体代码
具体代码如下:
```cmake
cmake_minimum_required(VERSION 3.24)
project(DrivenByUE4)

# 取得现在是XX年,之后计算Maya最新版本
string(TIMESTAMP COMPILE_TIME %Y)
math(EXPR THIS_YEAR "${COMPILE_TIME} + 1")
set(START_YEAR 2018)
set(CURRENT_YEAR "${START_YEAR}")

# 生成设置变量
while(CURRENT_YEAR LESS_EQUAL THIS_YEAR)
    set("Maya${CURRENT_YEAR}_DEVKIT_LOCATION" "" CACHE PATH "")
    set("Maya${CURRENT_YEAR}_LOCATION" "" CACHE PATH "")
    math(EXPR CURRENT_YEAR "${CURRENT_YEAR} + 1")
    # message(STATUS "result:${CURRENT_YEAR}")
endwhile()

# 不存在子项目则生成
if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/Maya${CURRENT_YEAR}/CMakeLists.txt")
    set(CURRENT_YEAR "${START_YEAR}")
    while(CURRENT_YEAR LESS_EQUAL THIS_YEAR)
        # 防止生成文件把${}进行转义
        set(ENV_String "$")
        string(APPEND ENV_String "ENV{PATH}")
        string(APPEND ENV_String "\$ENV")
        string(APPEND ENV_String "{MAYA_LOCATION}/bin;")
        set(ENV_String2 "$")
        string(APPEND ENV_String2 "ENV{DEVKIT_LOCATION}")
        set(ENV_String3 "$")
        string(APPEND ENV_String3 "{PROJECT_NAME}")

        # 因为生成文件会在Generate按钮按下后执行,所以需要执行2遍Configure与Generate
        file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Maya${CURRENT_YEAR}/CMakeLists.txt" CONTENT 
"project(\"DrivenByUE4_Maya${CURRENT_YEAR}\")

set(ENV{DEVKIT_LOCATION} \"${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}\")
set(ENV{MAYA_LOCATION} \"${Maya${CURRENT_YEAR}_LOCATION}\")
set(ENV{PATH} \"${ENV_String}\")

include(${ENV_String2}/cmake/pluginEntry.cmake)
set(SOURCE_FILES 
../DBU_AddMesh.cpp 
../DBU_AddMesh.h 
../DBU_ScenePrimitiveCollector.cpp 
../DBU_ScenePrimitiveCollector.h 
../DBU_ControlCmd.cpp 
../DBU_ControlCmd.h 
../DBU_TCPSocket.cpp 
../DBU_TCPSocket.h 
../PluginRegister.cpp)
set(LIBRARIES OpenMaya Foundation)

set(PDB_OUTPUT_DIRECTORY ${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/plug-ins/plug-ins/DrivenByUE4.pdb)
link_libraries(ws2_32)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/plug-ins/plug-ins)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/plug-ins/plug-ins)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/plug-ins/plug-ins)

set(VS_DEBUGGER_COMMAND ${Maya${CURRENT_YEAR}_LOCATION}/bin/mayabatch.exe)

set(INCLUDE_DIRS \"\")
set(DEVKIT_BASE_DIR \"${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}\")
set(LIBRARY_DIRS \"${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/lib\")
set(Foundation_PATH \"${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/lib/Foundation.lib\")
set(OpenMaya_PATH \"${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}/lib/OpenMaya.lib\")

build_plugin()
set_target_properties(${ENV_String3} PROPERTIES OUTPUT_NAME \"DrivenByUE4\")")

        math(EXPR CURRENT_YEAR "${CURRENT_YEAR} + 1")
    endwhile()
endif()

set(CURRENT_YEAR "${START_YEAR}")

while(CURRENT_YEAR LESS_EQUAL THIS_YEAR)
    if(NOT "${Maya${CURRENT_YEAR}_DEVKIT_LOCATION}" STREQUAL "" AND EXISTS "${CMAKE_CURRENT_BINARY_DIR}/Maya${CURRENT_YEAR}/CMakeLists.txt")
        add_subdirectory("Maya${CURRENT_YEAR}" "Maya${CURRENT_YEAR}")
    endif()

    math(EXPR CURRENT_YEAR "${CURRENT_YEAR} + 1")
endwhile()
```