关于cmake+mingw+yasm+vs 生成工程 编译代码问题总结

Windows环境下CMake+MinGW+yasm+VS汇编编译实践
本文总结了在Windows下使用CMake、MinGW、yasm和Visual Studio进行汇编代码编译的步骤和常见问题。包括环境配置、yasm编译汇编代码、yasm与GCC的交互、CMake的使用以及如何在VS中处理库文件链接问题。适合初学者参考。

最近想写一个库,需要支持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工程中去,编译执行。

楼主也是初学者,欢迎大家指教




 


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值