内容纲要

可以简单的创建工程,并定义编译选项和链接选项,此特性利用 cmake 的可变参数。

cmake\create_projects.cmake

macro(SET_MT)
    foreach(flag
            CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
            CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
        if(${flag} MATCHES "/MD")
            string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
        endif()
    endforeach()

    foreach(flag
            CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
            CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
        if(${flag} MATCHES "/MD")
            string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
        endif()
    endforeach()
endmacro(SET_MT)

function(CREATE_CONSOLE_PROJECT)

    set(options MT)
    set(oneValueArgs TARGET)
    set(multiValueArgs SRC DEFINES CXX_FLAGS INCLUDE_DIRS LINK_DIRS LINK_LIBS LINK_FLAGS)
    cmake_parse_arguments(
        PREFIX
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN}
    )

    message("console target: " ${PREFIX_TARGET})

    add_executable(${PREFIX_TARGET} ${PREFIX_SRC})

    target_compile_definitions(${PREFIX_TARGET} PRIVATE ${PREFIX_DEFINES})
    target_compile_options(${PREFIX_TARGET} PRIVATE ${PREFIX_CXX_FLAGS})
    target_include_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_INCLUDE_DIRS})
    target_link_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_DIRS})
    target_link_libraries(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_LIBS})
    target_link_options(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_FLAGS})

#    STRING(LENGTH "${PREFIX_LINK_FLAGS}" length) 
#
#    if ( length GREATER 0 )
#        message("console flags: " ${PREFIX_LINK_FLAGS})
#        set_target_properties(${PREFIX_TARGET} PROPERTIES LINK_FLAGS ${PREFIX_LINK_FLAGS}) 
#    endif()

    if(${PREFIX_MT})
        set_property(TARGET ${PREFIX_TARGET} PROPERTY
            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    endif()

endfunction(CREATE_CONSOLE_PROJECT)

function(CREATE_DLL_PROJECT)
    set(options MT)
    set(oneValueArgs TARGET)
    set(multiValueArgs SRC DEFINES CXX_FLAGS INCLUDE_DIRS LINK_DIRS LINK_LIBS LINK_FLAGS)
    cmake_parse_arguments(
        PREFIX
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN}
    )

    message("    dll target: " ${PREFIX_TARGET})

    add_library(${PREFIX_TARGET} SHARED ${PREFIX_SRC})

    target_compile_definitions(${PREFIX_TARGET} PRIVATE ${PREFIX_DEFINES})
    target_compile_options(${PREFIX_TARGET} PRIVATE ${PREFIX_CXX_FLAGS})
    target_include_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_INCLUDE_DIRS})
    target_link_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_DIRS})
    target_link_libraries(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_LIBS})
    target_link_options(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_FLAGS})

    if(${PREFIX_MT})
        set_property(TARGET ${PREFIX_TARGET} PROPERTY
            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    endif()
endfunction(CREATE_DLL_PROJECT)

function(CREATE_STATIC_PROJECT)
    set(options MT)
    set(oneValueArgs TARGET)
    set(multiValueArgs SRC DEFINES CXX_FLAGS INCLUDE_DIRS LINK_DIRS LINK_LIBS LINK_FLAGS)
    cmake_parse_arguments(
        PREFIX
        "${options}"
        "${oneValueArgs}"
        "${multiValueArgs}"
        ${ARGN}
    )

    message(" static target: " ${PREFIX_TARGET})

    add_library(${PREFIX_TARGET} ${PREFIX_SRC})

    target_compile_definitions(${PREFIX_TARGET} PRIVATE ${PREFIX_DEFINES})
    target_compile_options(${PREFIX_TARGET} PRIVATE ${PREFIX_CXX_FLAGS})
    target_include_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_INCLUDE_DIRS})
    target_link_directories(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_DIRS})
    target_link_libraries(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_LIBS})
    target_link_options(${PREFIX_TARGET} PRIVATE ${PREFIX_LINK_FLAGS})

    if(${PREFIX_MT})
        set_property(TARGET ${PREFIX_TARGET} PROPERTY
            MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    endif()
endfunction(CREATE_STATIC_PROJECT)

function(defines project_name VALUES)
    target_compile_definitions(${project_name} PRIVATE ${VALUES})
endfunction(defines)

function(includedirs project_name include_dirs)
    target_include_directories(${project_name} PRIVATE ${include_dirs})  
endfunction(includedirs)

function(libdirs project_name link_dirs)
    target_link_directories(${project_name} PRIVATE ${link_dirs})
endfunction(libdirs)

function(links project_name link_libs)
    target_link_libraries(${project_name} PRIVATE ${link_libs})
endfunction(links)

function(linkoptions project_name VALUES)
    set_target_properties(${project_name} PROPERTIES LINK_FLAGS ${VALUES})  
endfunction(linkoptions)    

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
cmake_policy(SET CMP0091 NEW)

# cmake 工程名,不影响 vs 工程名
project(cpp-hook-examples VERSION 0.1.0)

include(cmake/create_projects.cmake)

#set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")

if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE})
endif()

# 编译库输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# cmake 附加模块
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

# 设置 cmake 搜索头文件路径
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${PROJECT_SOURCE_DIR}/include")

# 设置 cmake 搜索库路径
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${PROJECT_SOURCE_DIR}/lib")

# set(CMAKE_GENERATOR_TOOLSET "v110_xp" CACHE STRING "CMAKE_GENERATOR_TOOLSET" FORCE)
# set(CMAKE_VS_PLATFORM_TOOLSET "v110_xp" CACHE STRING "CMAKE_VS_PLATFORM_TOOLSET" FORCE)

# set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "CMAKE_BUILD_TYPE" FORCE)
option(DEBUG_CONSOLE "是否启用调试控制台" ON)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")

# 通用的 include 路径
#include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/123" "${CMAKE_CURRENT_SOURCE_DIR}/456" )

#add_subdirectory(src)

create_console_project(TARGET hello
    MT 
    SRC    
        "src/hello/main.cpp" 
)

create_dll_project(TARGET patch_dll 

    DEFINES
        -DWIN32
        -D_WINDOWS

    SRC    
        "src/patch_dll/MemoryMgr.h"   
        "src/patch_dll/dllmain.cpp"
        "src/hello/main.cpp"   

    INCLUDE_DIRS

        "src/hello1/"  
        "src/hello2/"  
        "src/hello3/"  

    LINK_DIRS

        "src/hello1/"  
        "src/hello2/"  
        "src/hello3/"  

#    LINK_LIBS
#
#        "a.lib"
#        "b.lib"
#
#    LINK_FLAGS
#
#        "/NODEFAULTLIB:\"LIBCMT\" /SAFESEH:NO"
)

create_static_project(TARGET hello_static
    DEFINES
        -DWIN32
        -D_WINDOWS

    SRC    
        "src/patch_dll/MemoryMgr.h"   
        "src/patch_dll/dllmain.cpp"
        "src/hello/main.cpp"   

    INCLUDE_DIRS

        "src/hello1/"  
        "src/hello2/"  
        "src/hello3/"  

    LINK_DIRS

        "src/hello1/"  
        "src/hello2/"  
        "src/hello3/"  

)

create_console_project(TARGET hex_console_test

    SRC    
        "src/hex_console_test/main.cpp" 

    CXX_FLAGS

        "/Zi"
        "/GS-"

    LINK_FLAGS

        "/DYNAMICBASE:NO"
        "/DEBUG"

)

create_dll_project(TARGET hook_example 

    DEFINES
        -DWIN32
        -D_WINDOWS

    SRC    
        "src/hook_example/dllmain.cpp"   

)

发表评论

电子邮件地址不会被公开。 必填项已用*标注