Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

分享一种可以在 CMake+MSVC 中使用 yy-thinks 的方法 | Share an approach to link yy-thunks in CMake+MSVC #102

Open
BH2WFR opened this issue Jun 25, 2024 · 5 comments
Labels

Comments

@BH2WFR
Copy link
Contributor

BH2WFR commented Jun 25, 2024

以下代码可以让项目正常链接到 yy-thunks 的 .obj 库:
the code below can let the CMake project correctly link yy-thunks .obj libraries.

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "" FORCE) 	   # /MTd in Debug, /MT in Release
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:DebugDLL>" CACHE STRING "" FORCE) # /MDd in Debug, /MT in Release
# set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" CACHE STRING "" FORCE) # /MDd in Debug, /MD in Release (默认)



#* yy-thunks (MSVC only)
set(YY_THUNKS_DIR "D:/3rdlibs/YY-Thunks")	#* yy-thunks 根目录
set(YY_THUNKS_WIN_VERSION "WinXP")	#* 用于匹配文件名, 可用值: `WinXP` `Vista` `Win7` `Win8` `Win10.0.10240` `Win10.0.19041`, 用于匹配文件名
set(YY_THUNKS_WIN_VER_STR "5.1")	#* Windows 子系统版本, 5.1:XP, 5.2:2003, 6.0:Vista, 6.1:Win7, 6.2:Win8, 6.3:Win8.1, 10.0:Win10/11, 留空则默认
set(YY_THUNKS_ARCH	"x64")
if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 位
	set(YY_THUNKS_ARCH "x86")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") #* MSVC, 抢在系统库 lib 前挂入 yy-thunks 的 obj 文件
	set(YY_THUNKS_OBJ_NAME "${YY_THUNKS_DIR}/objs/${YY_THUNKS_ARCH}/YY_Thunks_for_${YY_THUNKS_WIN_VERSION}.obj") # 查找 obj 文件
	set(CMAKE_CXX_STANDARD_LIBRARIES "\"${YY_THUNKS_OBJ_NAME}\" ${CMAKE_CXX_STANDARD_LIBRARIES}")
	set(CMAKE_C_STANDARD_LIBRARIES   "\"${YY_THUNKS_OBJ_NAME}\" ${CMAKE_C_STANDARD_LIBRARIES}")
	if(YY_THUNKS_WIN_VER_STR)
		add_link_options("-SUBSYSTEM:$<IF:$<BOOL:${CMAKE_WIN32_EXECUTABLE}>,WINDOWS,CONSOLE>,${YY_THUNKS_WIN_VER_STR}")
	endif()
else()
	message(WARNING "yy-thunks obj files only support MSVC linker, this operation will be ignored...")
endif()

.
.

使用方法:
在上述代码中分别设置 YY_THUNKS_DIR YY_THUNKS_WIN_VERSION YY_THUNKS_WIN_VER_STR 三个变量, 指定路径和目标系统版本
.
Usage:
set variables YY_THUNKS_DIR YY_THUNKS_WIN_VERSION YY_THUNKS_WIN_VER_STR to your path and target system version

.
.
如需运行在 Windows XP 中, 需要在所有 DLL 项目中额外调用:
If you need to run in Windows XP, the code below is needed in each DLL target.

target_link_options(${PROJECT_NAME} PRIVATE "/ENTRY:DllMainCRTStartupForYY_Thunks")

@BH2WFR BH2WFR changed the title 分享一种可以在 CMake+MSVC 中使用 yy-thinks 的方法 | Share a way to import yy-thunks in CMake+MSVC 分享一种可以在 CMake+MSVC 中使用 yy-thinks 的方法 | Share an approach to import yy-thunks in CMake+MSVC Jun 25, 2024
@BH2WFR BH2WFR changed the title 分享一种可以在 CMake+MSVC 中使用 yy-thinks 的方法 | Share an approach to import yy-thunks in CMake+MSVC 分享一种可以在 CMake+MSVC 中使用 yy-thinks 的方法 | Share an approach to link yy-thunks in CMake+MSVC Jun 25, 2024
@mingkuang-Chuyu
Copy link
Collaborator

请问是否可以考虑提交PR,给yY-Thunks提供官方cmake支持。

@BH2WFR
Copy link
Contributor Author

BH2WFR commented Jun 26, 2024

请问是否可以考虑提交PR,给yY-Thunks提供官方cmake支持。

我交了一个PR,把这个写到 Readme.md 里面了

@yuejiyueren
Copy link

vc-ltl 需要设置下 set(WindowsTargetPlatformMinVersion "5.1.2600.0")

@BH2WFR
Copy link
Contributor Author

BH2WFR commented Dec 31, 2024

更新一下:
目前这个版本仍然有很多漏洞, 也不支持 clang, 看看有没有大佬愿意补充:
最好给它做成一个 import target,

#* 查找 YY-Thunks 并链接, 暂仅支持 MSVC
# _yy_thunks_dir 为 yy-thunks 根路径
# _winver 为 Windows 版本, 如 "10.0.19041.0"
#		(MSVC) `WinXP` `Vista` `Win7` `Win8` `Win10.0.10240`(Windows 10) `Win10.0.19041`(Windows 11)
#		(Clang) `5.1.2195.0` `5.1.2600.0` `5.2.3790.1180` `6.0.6000.0` `6.1.7600.0` `6.2.9200.0` `10.0.10240.0` `10.0.19041.0`
# _subsystem_ver 为子系统版本, 如 "5.01", 用于生成 链接时的最低子系统要求, 可以置空, 则不改变子系统版本
#		需要先定义 `CMAKE_WIN32_EXECUTABLE` 变量, 用于判断是否为 GUI 程序
# 		可用值: 5.0:2000; 5.1:XP_32bit; 5.2:XP_64bit/2003; 6.0:Vista/2008; 6.1:Win7/2008R2; 6.2:Win8/2012; 6.3:Win8.1/2012R2;
#		10.0:Win10/11/2016..2025
function(PROJ_FIND_YY_THUNKS   _yy_thunks_dir _winver _subsystem_ver)
	if(NOT WIN32) # 仅支持 Windows
		message(WARNING "YY-Thunks is only supported on Windows.")
		return()
	endif()
	if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # 仅支持 MSVC
		message(WARNING "YY-Thunks is only supported in MSVC compiler, but now is ${CMAKE_CXX_COMPILER_ID} compiler.")
		return()
	endif()
	if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "(x86(_64)?)|(AMD64)|(i[3-6]86)") # 仅支持 x86 和 x86_64 架构
		message(WARNING "YY-Thunks is only supported on x86 and x86_64 architectures.")
		return()
	endif()
	#if(NOT CMAKE_BUILD_TYPE MATCHES "Release") # 仅支持 Release 模式
	#	message(WARNING "YY-Thunks is only supported in Release mode.")
	#	return()
	#endif()

	
	set(YY_THUNKS_ARCH	"x64")
	if(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32 位
		set(YY_THUNKS_ARCH "x86")
	endif()
	get_filename_component(_yy_thunks_dir "${_yy_thunks_dir}" ABSOLUTE)
	
	set(PROJ_YY_THUNKS_FOUND FALSE PARENT_SCOPE) # 是否找到
	message("\n-> YY_THUNKS: ===============")
	#* MSVC, 抢在系统库 lib 前挂入 yy-thunks 的 obj 文件
	get_filename_component(YY_THUNKS_OBJ_PATH "${YY_THUNKS_Root}/objs/${YY_THUNKS_ARCH}/YY_Thunks_for_${_winver}.obj" ABSOLUTE)
	if(EXISTS ${YY_THUNKS_OBJ_PATH})
		set(PROJ_YY_THUNKS_FOUND TRUE PARENT_SCOPE)
		# link_libraries("${YY_THUNKS_OBJ_PATH}")
		set(CMAKE_CXX_STANDARD_LIBRARIES "\"${YY_THUNKS_OBJ_PATH}\" ${CMAKE_CXX_STANDARD_LIBRARIES}")
		set(CMAKE_C_STANDARD_LIBRARIES   "\"${YY_THUNKS_OBJ_PATH}\" ${CMAKE_C_STANDARD_LIBRARIES}")
		if(_subsystem_ver)
			add_link_options("-SUBSYSTEM:$<IF:$<BOOL:${CMAKE_WIN32_EXECUTABLE}>,WINDOWS,CONSOLE>,${_subsystem_ver}")
			# set(CMAKE_CREATE_WIN32_EXE   "${CMAKE_CREATE_WIN32_EXE} -subsystem:windows,${_subsystem_ver}" PARENT_SCOPE) # 这个是 VC_LTL 用到的方式, 但是我不知道是否能工作
			# set(CMAKE_CREATE_CONSOLE_EXE "${CMAKE_CREATE_CONSOLE_EXE} -subsystem:console,${_subsystem_ver}" PARENT_SCOPE)
		endif()
	else() # cannot find obj file
		message(WARNING "YY-Thunks cannot find the file `${YY_THUNKS_OBJ_PATH}`!")
	endif()
	message("    YY-Thunks found: ${PROJ_YY_THUNKS_FOUND}")
	message("    lib path: `${YY_THUNKS_OBJ_PATH}`")
	message("    subsystem version: `${_subsystem_ver}`")
	message("    CMAKE_WIN32_EXECUTABLE: `${CMAKE_WIN32_EXECUTABLE}`")
	message("")
endfunction()




#* Windows xp 中, 需要更改 DLL 入口点以可以在 WinXP 中使用 thread_local, 仅限动态链接库!!
function(PROJ_YY_THUNKS_WINXP_DLL _targetName)
	if(NOT WIN32) # 仅支持 Windows
		message(WARNING "YY-Thunks is only supported on Windows.")
		return()
	endif()
	if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # 仅支持 MSVC
		message(WARNING "YY-Thunks is only supported in MSVC compiler, but now is ${CMAKE_CXX_COMPILER_ID} compiler.")
		return()
	endif()
	if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "(x86(_64)?)|(AMD64)|(i[3-6]86)") # 仅支持 x86 和 x86_64 架构
		message(WARNING "YY-Thunks is only supported on x86 and x86_64 architectures.")
		return()
	endif()
	#if(NOT CMAKE_BUILD_TYPE MATCHES "Release") # 仅支持 Release 模式
	#	message(WARNING "YY-Thunks is only supported in Release mode.")
	#	return()
	#endif()
	if(NOT PROJ_YY_THUNKS_FOUND)
		message(WARNING "YY-Thunks not found, please call `PROJ_FIND_YY_THUNKS` first.")
		return()
	endif()
	target_link_options(${_targetName} PRIVATE "/ENTRY:DllMainCRTStartupForYY_Thunks")
endfunction()

@mingkuang-Chuyu
Copy link
Collaborator

其实可以吧,可以使用nuget,cmake是支持的,唯一要求就是生成器需要使用VS(msbuild)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants