最近想写一个库,需要支持windows+linux,但是自己是活在windows下的人,所以就用mingw来代替linux,代码写完了,可是编译环境问题一堆,所以这里总结下。
一.准备工作
安装好cmake,mingw 64位,yasm,msys,这些下载安装网上一堆,就不赘述了。环境变量什么的也需要都配好。
二.yasm编译器编译汇汇编代码运行,下面先贴代码hello.asm
global WinMain
extern ExitProcess ; external functions in system libraries
extern MessageBoxA
section .data
title: db 'Win64', 0
msg: db 'Hello world!', 0
section .text
WinMain:
sub rsp, 28h
mov rcx, 0 ; hWnd = HWND_DESKTOP
lea rdx,[msg] ; LPCSTR lpText
lea r8,[title] ; LPCSTR lpCaption
mov r9d, 0 ; uType = MB_OK
call MessageBoxA
add rsp, 28h
mov ecx,eax
call ExitProcess
hlt ; never here
a.编译asm文件
command:yasm hello.asm -fwin64会生成hello.obj
b.链接
命令:gcc hello.obj -o test.exe
c.运行test.exe,系统是win7 64,mingw是64,yasm是64位,运行是会缺少一些库,缺啥就去找。kernel32.lib libcmt.lib link.exe mspdb120.dll User32.lib
三,yasm+gcc互调
有时,我们写完代码之后,性能不佳,就想用汇编来优化代码,第二点纯属asm代码,没有c代码,新加一个例子,先贴代码,代码网上找的。
addone.asm
global addone ;
addone: MOV RAX, [RSP + 20] ; stack top + 20 bytes
ADD RAX, 1
RET
calladdone.c
#include <stdio.h>
int main(){
int a = 3;
printf("before call, a is %d.\n", a);
a = addone(a);
printf("after call, a is %d.\n", a);
return 0;
}
a.进入mingw,编译汇编代码
命令:yasm -felf64 addone.asm
会生成addone.o
b.编译c代码,链接
命令:gcc calladdone.c addone.o
c.执行文件
四,使用cmake
关于cmake的用法,网上也有入门的一些教程,本文主要针对yasm的一些用法,就拿第三点的例子,用camke来编译。
CMakeList.txt
project(test2)
cmake_minimum_required (VERSION 2.8.8)
find_package(Yasm)
if(YASM_FOUND)
if (YASM_VERSION_STRING VERSION_LESS "1.2.0")
message(STATUS "Yasm version ${YASM_VERSION_STRING} is too old. 1.2.0 or later required")
else()
message(STATUS "Found Yasm ${YASM_VERSION_STRING} to build assembly primitives")
endif()
else()
message(STATUS "NOT Found Yasm========")
endif()
enable_language(ASM_YASM)
set(ASM_SRC addone.asm)
set(APP_SRC calladdone.c)
#add_library(libaddone ${ASM_SRC})
add_executable(addone ${APP_SRC} ${ASM_SRC})本身可以考虑将addone.asm生成一个库文件,然后c文件去调;另一个就是直接连在一起生成可执行文件。
假如addone.asm calladdone.c CMakeLists.txt这三个文件一个目录,在该目录下创建一个build文件夹,进入到build目录中,
执行:cmake .. -G"MSYS Makefilse" //注意 有两个点 是makelist的目录,执行完之后,再执行make就搞定
五,vs使用asm
网上也有很多资源,注意汇编代码32,64的区别,很容易就编译出错
六,cmake 生成vs 2013(本文装的是2013)工程,并且集成yasm
cmake 生成vs 2013的命令是:cmake .. -G"Visual Studio 12 Win64" // 两个点是cmakelist的路径
这个没有难度,要集成yasm也跟第四点一样,也没有难度,将带有汇编的代码编译成库,然后主程序去链接。
但是照常理生成之后,单独的library会有一个工程文件,主程序也有一个工程,单独在vs中编译library没有问题;
可是主程序链接到库文件进行编译时,就会链接不到;另外一点,如果是cmake .. -G"MSYS Makefiles"的话,直接执行命令是没有问题的,
只有在vs中,主程序链接库编译时出问题。
这里介绍一种方法,我也是初学者,也就知道这一种方法:
将asm相关的库文件生成为object 库 在cmakelist 中加:
if(MSVC_IDE OR XCODE)
# MSVC requires custom build rules in the main cmake script for yasm
set(MSVC_ASMS "${A_SRCS}" CACHE INTERNAL "yasm sources")
set(A_SRCS)
endif()
add_library(libcom OBJECT ${LIB_SRC} ${ASM_PRIMITIVES}) # ASM_PRIMITIVES是你的asm相关文件在主程序的cmakelist文件中加:
foreach(ASM ${MSVC_ASMS})
set(YASM_SRC ${ASM})
message(${ASM})
list(APPEND YASM_SRCS ${YASM_SRC})
list(APPEND YASM_OBJS ${ASM}.${SUFFIX})
add_custom_command(
OUTPUT ${ASM}.${SUFFIX}
COMMAND ${YASM_EXECUTABLE} ARGS ${YASM_FLAGS} ${YASM_SRC} -o ${ASM}.${SUFFIX}
DEPENDS ${YASM_SRC})
endforeach()
add_library(common-static STATIC $<TARGET_OBJECTS:libcom> ${YASM_OBJS} ${YASM_SRCS}) #这是新加入的
add_executable(test ${APP_SRC} ) #这个是原先的
其他操作在网上查查,这样再cmake一下,进入到vs工程中去,编译执行。
楼主也是初学者,欢迎大家指教
Windows环境下CMake+MinGW+yasm+VS汇编编译实践
本文总结了在Windows下使用CMake、MinGW、yasm和Visual Studio进行汇编代码编译的步骤和常见问题。包括环境配置、yasm编译汇编代码、yasm与GCC的交互、CMake的使用以及如何在VS中处理库文件链接问题。适合初学者参考。
2967

被折叠的 条评论
为什么被折叠?



