文章出處

CoreCLR登陸GitHub之后,體驗CoreCLR首當其沖的方式就是在自己的電腦上編譯它,昨天分別在Windows與Linux上成功編譯了CoreCLR,詳見:

1)Windows上成功編譯CoreCLR源代碼 ;

2)Linux上成功編譯CoreCLR源代碼

Windows與Linux上編譯成功之后,有一個擋不住的沖動——在Mac上編譯CoreCLR。雖然微軟目前優先考慮的是Windows與Linux兩個平臺,CoreCLR的編譯暫時不支持Mac OS X,但我最期待的卻是在Mac OS X上編譯CoreCLR,而且編譯CoreCLR所需要的CMake與LLVM在Mac OS X上都有,嘗試一下是必須的。

于是,心動不如行動,開始了Mac OS X編譯CoreCLR之旅。

Build操作步驟如下:

1)簽出github上的CoreCLR代碼庫: git clone https://github.com/dotnet/coreclr.git 

2)安裝cmake: brew install cmake 

3)運行build命令: sh build.sh 

3)build結果-失敗,錯誤信息如下:

Unable to locate llvm-ar
Failed to generate native component build project!

錯誤信息顯示找不到llvm-ar命令。

運行命令 clang --version ,確認LLVM 3.5已安裝:

Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)

運行命令 ls /usr/bin/llvm* ,的確沒有llvm-ar:

/usr/bin/llvm-g++	/usr/bin/llvm-gcc

后來發現原來藏在 /usr/local/opt/llvm/bin/ 文件夾中:

ls /usr/local/opt/llvm/bin/llvm-ar
/usr/local/opt/llvm/bin/llvm-ar

但環境變量$PATH中沒有這個路徑,于是加上這個路徑:

export PATH=/usr/local/opt/llvm/bin:$PATH

(補充:持久添加到$PATH,sudo vi /etc/paths.d/llvm,添加內容/usr/local/opt/llvm/bin,保存并重新打開Terminal)

添加之后,繼續build,“Unable to locate llvm-ar”錯誤消失。

但出現了新的錯誤:

-- The C compiler identification is AppleClang 6.0.0.6000056
-- The CXX compiler identification is AppleClang 6.0.0.6000056
-- Check for working C compiler: /usr/bin/clang
-- Check for working C compiler: /usr/bin/clang -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/clang++
-- Check for working CXX compiler: /usr/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Error at CMakeLists.txt:317 (message):
  Not Implemented!

查看CMakeLists.txt中的代碼:

if (IS_64BIT_BUILD EQUAL 1)
  if (CLR_CMAKE_PLATFORM_UNIX_TARGET_AMD64)
    add_definitions(-DDBG_TARGET_AMD64_UNIX)
  endif (CLR_CMAKE_PLATFORM_UNIX_TARGET_AMD64)
  add_definitions(-D_TARGET_AMD64_=1)
  add_definitions(-DDBG_TARGET_AMD64)
else (IS_64BIT_BUILD EQUAL 1)
  # TODO: Support this
  message(FATAL_ERROR "Not Implemented!") #line 317
endif (IS_64BIT_BUILD EQUAL 1)

第317代碼是 message(FATAL_ERROR "Not Implemented!") 。分析這段if代碼塊,可以知道當操作系統是Mac OS X時,IS_64BIT_BUILD的值不為1,如果將之設置為1就可以避開這個錯誤。

于是順藤摸瓜,在CMakeLists.txt的第128行找到了設置IS_64BIT_BUILD的代碼:

elseif (CLR_CMAKE_PLATFORM_UNIX)  
  # Set flag to indicate if this will be a 64bit Linux build
  if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
    set(IS_64BIT_BUILD 1)  
  endif (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)

當CLR_CMAKE_PLATFORM_UNIX為true的時候,會將IS_64BIT_BUILD的值設置為1。

繼續順藤摸瓜,在CMakeLists.txt的第7行找到了設置CLR_CMAKE_PLATFORM_UNIX的代碼:

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
    set(CLR_CMAKE_PLATFORM_UNIX 1)
    set(CLR_CMAKE_PLATFORM_UNIX_TARGET_AMD64 1)
endif(CMAKE_SYSTEM_NAME STREQUAL Linux)

然后依葫蘆畫瓢,添加了針對Mac OS X的代碼:

# Mac OS X
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
    set(CLR_CMAKE_PLATFORM_UNIX 1)
    set(CLR_CMAKE_PLATFORM_UNIX_TARGET_AMD64 1)
endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)

然后運行./build.sh編譯CoreCLR,終于將build.sh跑起來了。雖然也有一些報錯,但是build的執行沒有中斷:

Commencing CoreCLR Repo build
Checking pre-requisites...
Commencing build of native components for amd64/debug
Invoking cmake with arguments: /git/dotnet/coreclr DEBUG
Detected Linux x86_64
-- Configuring done
CMake Warning (dev):
  Policy CMP0042 is not set: MACOSX_RPATH is enabled by default.  Run "cmake
  --help-policy CMP0042" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  MACOSX_RPATH is not specified for the following targets:

   coreclr
   mscordaccore

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
-- Build files have been written to: /git/dotnet/coreclr/binaries/CMake
Executing make
./build.sh: line 84: nproc: command not found
[  0%] Building C object src/pal/tools/cppmunge/CMakeFiles/cppmunge.dir/cppmunge.c.o
[  1%] [  1%] Built target palrt
[  1%] Built target mdhotdata_full
Built target gcinfo
/git/dotnet/coreclr/src/pal/tools/cppmunge/cppmunge.c:38:10: fatal error: 'linux/limits.h' file not found
#include <linux/limits.h>
         ^
[  1%] [  1%] Built target ildbsymlib
Built target dbgutil
[  2%] Built target corguids
[  3%] Built target ceefgen

滿懷期望地等待著build的結果。。。

但是在build過程中,MacBook的CPU風扇突然呼呼作響,接著OS X系統停止響應,只能強制關機。

開機后再嘗試,在build過程中依然會讓Mac掛掉。接著進行多次嘗試,只要build,Mac必掛。

Mac OS X上編譯CoreCLR之旅因為這個暫時無法解決的問題而中斷。

雖然這次嘗試失敗了,但是在Mac OS X上編譯CoreCLR的癡心不改,在Mac OS X上開發.NET程序的期待不變!

【更新】

“CPU風扇突然呼呼作響,OS X停止響應”可能與“nproc: command not found”這個錯誤有關,很可能是只用了一個CPU核在編譯。

果然是這個原因,將build.sh中的 make install -j `nproc` $__UnprocessedBuildArgs 改為下面的代碼,“CPU風扇突然呼呼作響,OS X停止響應”的問題解決: 

if [[ "$OSTYPE" == "linux-gnu" ]]; then
    # Linux
    make install -j `nproc` $__UnprocessedBuildArgs
elif [[ "$OSTYPE" == "darwin"* ]]; then
    # Mac OSX
    make install -j `sysctl -n hw.ncpu` $__UnprocessedBuildArgs
fi

后來,微軟的@Xy Ziemba提供了更好的解決方法:getconf _NPROCESSORS_ONLN(既支持Linux,又支持Mac OS X), 并且已經將修改提交至coreclr的代碼庫:

 

后來,在Issue#102的回復中得知@Geoff Norton已經修改出了一個可在Mac OS X上編譯的版(詳見#105),于是git簽出這個試了一下:

git clone -b osx --single-branch https://github.com/kangaroo/coreclr.git
./build.sh

結果成功了!

[100%] Built target corerun
Install the project...
-- Install configuration: "DEBUG"
-- Installing: /git/dotnet/coreclr-osx/coreclr/binaries/Product/amd64/debug/./corerun
-- Installing: /git/dotnet/coreclr-osx/coreclr/binaries/Product/amd64/debug/./libmscordaccore.dylib
-- Installing: /git/dotnet/coreclr-osx/coreclr/binaries/Product/amd64/debug/./libcoreclr.dylib
Repo successfully built.
Product binaries are available at /git/dotnet/coreclr-osx/coreclr/binaries/Product/amd64/debug

耶!

2月7日下午發現,驚喜地發現可在Mac OS X上編譯的版本已經合并到主分支,詳見 Merge pull request #117 from kangaroo/osx

編譯這個版本時出現"ld: symbol(s) not found for architecture x86_64"錯誤,刪除binaries文件夾之后重新編譯,問題解決。

【相關鏈接】

mac os x build error: CMake Error at CMakeLists.txt: Not Implemented #102

Use # of processors + 1 available to OS scheduler on Linux when building #100

MacOSX Support #105

Initial Mac OSX Support #117


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()