關於windows下使用 cmake 的 nmake 方式構建項目

NMake環境變量配置

正常情況下,安裝vs集成開發包時默認用戶使用msbuild作爲構建工具,雖然也順帶安裝了nmake,但是實際上用戶不進行一些配置的話,是不能直接使用nmake編譯項目的,原因是沒有配置環境變量,編譯時找不到各種路徑,win SDK庫\Rtc庫路徑、頭文件路徑、甚至編譯工具、構建工具路徑也找不到。微軟想讓用戶更傻瓜,最好啥原理也不懂,直接用就好。

於是乎,爲了可以直接使用nmake構建項目,我們需要對環境變量做一些配置,以下以一個簡單的示例介紹做法:

現有有代碼,main.cpp

爲了能在命令行下使用nmake,要將nmake.exe的目錄加入到環境變量Path中

編譯過程中會用到rc.exe、cl.exe、link.exe等工具,其所在目錄也要加入Path

 

然後將編譯期間可能需要包含的頭文件目錄以及庫目錄分別加入到INCLUDE和LIB環境變量,如:

然後就可以編寫Makefile,然後通過nmake構建項目了

 

使用cmake產生nmake腳本構建項目

CMakeLists.txt

#CMake最低版本號要求

cmake_minimum_required(VERSION 2.8)

#指定項目名稱

project(CMakeDemo)

#添加子目錄,這樣進入源碼文件src目錄可以繼續構建  

add_executable(hello main.cpp)

#PreLoad.cmake

#通過PreLoad.cmake可以強行指定編譯器

set(CMAKE_GENERATOR "NMake Makefiles" CACHE INTERNAL "" FORCE)

set(CMAKE_CXX_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe"  CACHE INTERNAL "" FORCE)

set(CMAKE_C_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/cl.exe"  CACHE INTERNAL "" FORCE)

注:如果CMAKE_GENERATOR使用了" Visual Studio xx 20xx"則CMAKE_CXX_COMPILERCMAKE_C_COMPILER是被鎖定的,PreLoad.cmake失效

問題:

1.NMAKE:fatal error U1077.“cl.exe” return code 0xc0000135

產生原因:在安裝visual studio的時候沒有勾選註冊環境變量導致的。

解決辦法:在系統環境變量中加入visual studio的安裝路徑:vs安裝路徑\VC\Bin,以及vs安裝路徑\Common7\IDE

2.NMAKE:fatal error U1077. return code 0x2

產生原因:找不到代碼文件中包含的頭文件

解決辦法:cmd下進入到vs安裝路徑\VC\Bin下,執行vcvars32,此時會執行vcvas32.bat自動爲vs設置環境變量

3.NMAKE:fatal error U1077. return code 0x460

產生原因:你的工程中連接了一個lib文件,鏈接的時候卻出現不能解析的外部符號。可能問題是你包含的lib是錯的,或者有不兼容問題。我的問題就是後者,我的系統的32位的,但是鏈接了一個64位的lib.

使用nmake構建項目時,使用vcvarsall.bat切換編譯器架構

(這個優先級應該低於同手動寫入環境)

一直以來我只知道vc設置命令行編譯環境的批處理命令是%VS140COMNTOOLS%/Common7/Tools下的vsvars32.bat,(%VS140COMNTOOLS%爲定義vs2015公共工具程序位置的環境變量,命令行窗口輸入set就能找到,vs2010的對應定義爲%VS100COMNTOOLS%) 微軟的官網上有這個命令的說明: https://technet.microsoft.com/zh-cn/library/1700bbwd.aspx

但在執行這個命令生成的命令行環境下用nmake只能編譯32位版本的代碼,我一直都不知道如何用nmake編譯64位的代碼。 今天才搞明白vsvars32.bat已經過時了,正確的打開方式是vcvarsall.bat 。 至少從vs2010開始, %VS140COMNTOOLS%/VC下就有vcvarsall.bat,用於生成命令行編譯環境。 如果要在命令行生成 32位代碼,就執行vcvarsall x86 如果要在32位系統下生成64位代碼,就執行vcvarsall x86_amd64 如果要在64位系統下生成32位代碼,就執行vcvarsall x86vcvarsall amd64_x86 到了VS2015,已經支持arm平臺了,所以如果要生成arm平臺的代碼,就執行vcvarsall x86_arm 如果你的操作系統是64位的也可以 vcvarsall amd64_arm

前面一個名字代表你的當前電腦的體系結構,後面的這個名字代表你要生成的代碼的體系結構。如果兩個名字一樣,就簡化爲一個名字。 搞清楚了這個,今天終於順利在命令行下實現nmake編譯32位和64位版本代碼:

生成用於編譯32位代碼的命令行編譯環境

C:\Program Files (x86)\Microsoft Visual Studio 14.0>cd VC
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC>vcvarsall x86

執行cmake生成NMake格式的Makefile,指定處理器爲x86,然後執行nmake編譯所有代碼,並安裝

>cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RELEASE -DTARGET_PROCESSOR=x86 ..\facecl
>nmake install

安裝成功的輸出

Install the project...
-- Install configuration: "RELEASE"
-- Installing: C:/Program Files (x86)/facecl/lib/static/detect_cl.lib
-- Installing: C:/Program Files (x86)/facecl/bin/detect_cl.dll
-- Installing: C:/Program Files (x86)/facecl/lib/static/img_tool.lib
-- Installing: C:/Program Files (x86)/facecl/bin/img_tool.dll
-- Installing: C:/Program Files (x86)/facecl/bin/test_detect.exe
-- Up-to-date: C:/Program Files (x86)/facecl/./README_utf8.txt
-- Up-to-date: C:/Program Files (x86)/facecl/include/detect_cl_types.h
-- Up-to-date: C:/Program Files (x86)/facecl/include/detect_cl.h
-- Up-to-date: C:/Program Files (x86)/facecl/include/img_tool.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/test_detect.cpp
-- Up-to-date: C:/Program Files (x86)/facecl/sample/utility.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/raii.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/assert_macros.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/cmdline.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/dirent.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/file_utilits.h
-- Up-to-date: C:/Program Files (x86)/facecl/sample/time_utilits.h

如果要在32位系統下生成64位代碼,也如法炮製

關於vcvarsall.bat更詳細的說明,參見微軟的官方文檔: https://msdn.microsoft.com/zh-cn/library/f2ccy3wt.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章