windowsでのpython3のセットアップ
相変わらず仕事でpythonが絡むと「python2向けで」とか、下手すると「2.6で動作すること」とか言われますが、そろそろ自作のソフトくらいはpython3へ移行しようと思い立って、まずは環境を用意することにしました。
まずは、chocolateyからpython2/3をまとめてインストールします。
>choco install python python2 -y Chocolatey v0.9.9.7 Installing the following packages: python;python2 By installing you accept licenses for the packages. python v3.4.3.20150501 Get-BinRoot is going to be deprecated by v1. Many packages no longer require it since the folders no longer have versions on them. Downloading python 32 bit from 'https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi' Installing python... python has been installed. The install of python was successful. python2 v2.7.10 Get-BinRoot is going to be deprecated by v1. Many packages no longer require it since the folders no longer have versions on them. Warning: Old installation path “C:\Python27” detected. This package will continue to install python2 there unless you uninstall python2 from there and remove the “C:\Python27” folder. If you decide to do that, reinstall this package with the -force parameter and it will install to the Chocolatey bin root. Installing python2... python2 has been installed. The install of python2 was successful. Chocolatey installed 2/2 package(s). 0 package(s) failed. See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
途中で別のwindowが開いたりしますが、インストール完了後に一旦コマンドプロンプトを開き直すと
> python --version Python 3.4.3 > C:\Python27\python.exe --version Python 2.7.10
といった形でpython2と3が無事に動くようになりました。
続いてvirtualenvのインストール
>C:\tools\python3\Scripts\pip install virtualenv You are using pip version 6.0.8, however version 7.1.2 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Collecting virtualenv Downloading virtualenv-13.1.2-py2.py3-none-any.whl (1.7MB) 100% |################################| 1.7MB 63kB/s Installing collected packages: virtualenv Successfully installed virtualenv-13.1.2
では、さっそくvirtual envを使って、python2.7用の環境を作ってみましょう。
>python -m virtualenv --python=C:\Python27\python.exe Py27 Running virtualenv with interpreter C:\Python27\python.exe New python executable in Py27\Scripts\python.exe Installing setuptools, pip, wheel...done.
Py27フォルダに移動して、activateすると
>cd Py27 >Scripts\activate >python --version Python 2.7.10
となって、無事にpython2.7の環境ができました。
この状態からdeactivateすると素の環境に戻ります。
>deactivate >python --version Python 3.4.3
とりあえず、2.7と3.4用の開発環境を一式作っておこう。
chefをやめてchocolateyへ
単にパッケージをインストールするだけのこんな感じのレシピをいくつか書いた後でふと気づきました。
if platform_family?('windows') windows_package node['hoge']['display_name'] do source node['hoge']['url'] installer_type :custom action :install options "/quiet" end end
わざわざchefを使うまでの話でもないな・・・
というわけで、単純なインストール作業はchocolateyに
お任せすることにしました。
そうすると、今までchefでやってた作業で残るものは
- C:\WORKの作成
- 環境変数HOMEの設定
- gitで管理しているドットファイルの取得
- ssh鍵の作成
- フォントのインストール
- 環境変数PATHの設定(viとかのインストール先を追加したい)
- 自動起動の設定(主にautohotkey)
といったところです。
このうち、1, 2, 3, 6, 7についてはpowershellのスクリプトに移行しました。
4,5は大した手間でもないので、手作業でやってます。*1
私が考えていたchefの利点というのは以下の3つでした。
- 冪等性
- platform independent
- DSL
ところが、1のケースで考えると、そもそも既存のディレクトリが存在したら、ディレクトリは生成できるわけがないので、どんな手段を使うにしても冪等性を考える必要はないわけです。*2
同じように、3のケースであればgitコマンド自体が冪等性を保証してくれますし、ソフトのインストールについてもインストール済みであればwindowsのインストーラが大抵は勝手に判定してくれます。
環境変数の設定はbashのexportでもsetxコマンドでも考慮してくれないので、PATHに同じディレクトリが複数回設定されるような状況が容易に起こるわけですが、この程度のことのためにchefを導入するのは、役不足でしょう。
platform依存性という観点では、そもそも設定している内容がwindows環境だから設定しないといけないという性質のものばかりなので、実際のところ、これまでの運用ではあまり活かせてませんでした。
vagrantやvirtualboxみたいな、どんなOSでも入れたいソフトもあるので、こういったもののインストールはお任せしたいところなんですが、現状のchefではaptやyumやdmgやwindowsのような、各プラットフォームに対応するためのcookbookも準備する必要があって、少々煩わしいです。*3
あと、pythonとかnode.jsのような、重要なソフトのコミュニティcookbookがwindowsに対応していなくて、結局自分でwindows専用のcookbookを
書く羽目になるのも悲しいところです。
最後のDSLというのは、スクリプトで書き直していると重要性を痛感できるんですが、これまた環境変数の件と同じく、これだけのためにchefを導入するもんでもないなぁと感じてます。
というわけで、ほぼすべての自作cookbookは闇に葬られて、いくつかのpowershellスクリプトに生まれ変わりました。
windowsの"PROGRAMFILES"環境変数
32bit windowsでは、プログラムのインストール先はたいてい"C:Program Files"ですが、64bit windowsでは、64bitプログラムは"C:Program Files"に、32bitプログラムは"C:Program Files(x86)"に分けてインストールするのがお約束になっています。
この"Program Files"ディレクトリを参照する環境変数として%PROGRAMFILES%というのがあるんですが、この環境変数は呼び出し元プログラムが32bitか64bitかによって変わるようです。
C:\WORK>\Windows\SysWOW64\cmd.exe Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\WORK>echo %PROGRAMFILES% C:\Program Files (x86) C:\WORK>exit C:\WORK>\Windows\System32\cmd.exe Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\WORK>echo %PROGRAMFILES% C:\Program Files
一瞬逆に思えるけど、System32の下にあるのが64bit版で、SysWOW64の下にあるのが、32bit版のcmd.exeです。
インストーラ無しで配布されているプログラムをインストールする(chefの)recipeで、インストール先として
"#{ENV['PROGRAMFILES']}\\hoge"
みたいなのを指定してたら、git-bashから入れるとProgram Files(x86)に入るし、コマンドプロンプトから入れるとProgram Filesに入るし大混乱になりました・・・orz
一応、こんな感じで回避してますが、そもそもインストール先を選択する時に%PROGRAMFILES%を使うのは不適切だってことですね。
if kernel['machine'] =~ /x86_64/ default['install_to'] = "#{ENV['PROGRAMW6432']}" else default['install_to'] = "#{ENV['PROGRAMFILES']}" end
cmakeでC++ルーチンを呼び出すFortranプログラムをビルドする
自作のライブラリ(C++で作成、C、Fortranのインタフェースあり)をFortranのプログラムから呼び出すサンプルコードを書いてたんですが、CmakeList.txtの作成ではまったので、メモ
cmake fortran c++ mixedlink あたりでぐぐると、
SET_TARGET_PROPERTIESで、LINKER_LANGUAGE をCXXに設定するべし
という解決方法が定番のようです。実際にg++/gfortranの環境であればこれで問題無いんですが、intel コンパイラの場合は、この方法ではリンク時にエラーになります。
Compiling and Linking Intel® Fortran/C Programs
によると、リンク時に"-cxxlib"を渡せと書いてますが、これもうまく動作しなかったので、当面の回避策として、こんな形にしてみました。
project(hoge CXX C Fortran)
.
.
.
add_executable(huga huga.f90)
target_link_libraries(huga my_cxx_lib ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES})
要は、CXXコンパイラが暗黙的にリンクするライブラリを強制的にtarget_link_librariesで追加してるだけです。
これでPGIコンパイラとかでも動いてくれたらいいなぁ
chef -zeroでwindows用開発環境を構築(その4)
運用を始めてから気付いたことをバラバラとメモっときます。
gitでエラーになる
gitのレシピを実行すると、こんなエラーが発生する時があります。
FATAL: Errno::EIO: git[C:\WORK\unix_home] (update_home_dir::default line 10) had an error: Errno::EIO: Input/output error - CreateProcessW
ここにissueとして出てますが、gitじゃなくてgit.exeを呼ばないと発生するエラーだそうです。
git resource Errno::EIO on windows · Issue #1622 · chef/chef · GitHub
そのうち解決されると思いますが、とりあえずのワークアラウンドとしてこんな感じに修正しておきました。
if platform_family?('windows') git_command="git.exe" else git_command="git" end #clone remote repo to $HOME if not exist if ! ::File.directory?("#{ENV['HOME']}/.git") execute "git init" do command "#{git_command} init" cwd "#{ENV['HOME']}" end execute "git remote add" do command "#{git_command} remote add origin #{node['update_home_directory']['repo']}" cwd "#{ENV['HOME']}" end end execute "git pull" do command "#{git_command} pull origin master" cwd "#{ENV['HOME']}" end execute "git submodule" do command "#{git_command} submodule update --init --recursive" cwd "#{ENV['HOME']}" end
cloneせずに、わざわざinitしてからpullしてますが、これはこのエラーとは無関係で、gitが実行される前に%HOME%\.chefディレクトリが作られてしまってgit cloneに失敗することへの対策です。
windows_packageの羃等性
githubのページに書かれているように、windows_packageに渡す名前は[コントロールパネル]->[プログラムと機能]のリストに表示されている名前と正確に一致させていないと、インストール済かどうかの判定に失敗します。
opscode-cookbooks/windows · GitHub
でもって、この名前はプログラムによってバージョン名を含むものや含まないものが混在しているので、もしバージョン番号が入っていないソフトだったら、アップデートするのが難しくなるので違う名前にしておきましょう。(うちの環境だとAmazon KindleとかcourvusSKKとかがバージョン番号が無いです)
ログオン時に実行させる
スタートアップに追加するのは、専用のリソースが用意されていて、次のようなコードで登録できます。
windows_auto_run "autohotkey" do program node['autohotkey']['program_name'] not_if {Registry.value_exists?(AUTO_RUN_KEY, "autohotkey")} action :create end
ショートカットの追加
ショートカットも専用のリソースがあって、こんな感じで追加できます。
windows_shortcut "#{ENV['USERPROFILE']}\\Desktop\\gvim.lnk" do target exe_path description "gvim" action :create end
本当はスタートメニューとかタスクバーに登録したいんですが、こっちのやり方は分からず・・・
ファイルの関連付け変更
ファイルの関連付けは、コマンドラインからassocやftypeコマンドを使うのが正しいやり方だと思いますが、面倒なのでレジストリを直接いじります。しかし、ぐぐってみると昔のkeyも有効なようで
"HKEY_CURRENT_USER\\Software\\Classes\\.#{ext}\\shell\\open\\command"
に登録するパターンと
"HKEY_CURRENT_USER\\Software\\Classes\\#{ext}_auto_file\\shell\\open\\command"
に登録するパターンのどちらでも良いようです。(#{ext}は拡張子)
うちの環境でテストした限りでは、
という問題があるので、後者のkeyを使っています。
具体的にはgvimのレシピの中でこんな感じにしてます。
%w{rb py js txt log c C cpp h f F f90 F90}.each do |ext| registry_key "set file type assocication by auto_file #{ext}" do key "HKCU\\Software\\Classes\\#{ext}_auto_file\\shell\\open\\command" values [{ :name => "", :type => :string, :data => "#{exe_path} %1" }] recursive true end end
chef-zeroでwindows用開発環境を構築(その3)
再び続けてChef-zero on windowsの話です。
前回までで、まだ足りないソフトがあるものの、windows8.1用のchef-repoを作成してOneDriveに放り込み、chefによる環境設定の運用を開始することができました。
今回は、OndeDrive経由で別のwindowsマシンにも同じ環境を作ってみましょう。
ちなみに、新しいマシンはwindows7 pro(64bit)です。
下準備
msysgitとchef-clientをインストールします。内容は前々回と同じなので、詳細は省略
http://hpcmemo.hatenablog.com/entry/2015/03/19/125319
ノードの作成
chef-repoへ移動して以下のコマンドを実行します。
>chef-client -z [2015-03-23T12:44:21+09:00] WARN: No config file found or specified on command line, using command line options. Starting Chef Client, version 12.0.3 [2015-03-23T12:45:04+09:00] WARN: chef-client doesn't have administrator privileges on node new_pc. This might cause unexpected resource failures. resolving cookbooks for run list: [] Synchronizing Cookbooks: Compiling Cookbooks... [2015-03-23T12:45:04+09:00] WARN: Node new_pc has an empty run list. Converging 0 resources Running handlers: Running handlers complete Chef Client finished, 0/0 resources updated in 43.526 seconds
本当は、新規ノードを作成するには
> knife node create new_pc -z
で良いはずなんですが、何回やっても環境変数EDITORが設定されていないと言われて実行できなかったので・・・
run_listの追加とレシピの適用
1台目のマシンと同じですが、Admin権限をもったコマンドプロンプトで以下のコマンドを実行します。
> knife node run_list add new_pc firefox windows_initial_settings windows -z WARNING: No knife configuration file found new_pc: run_list: recipe[firefox] recipe[windows_initial_settings] recipe[windows] > chef-client -z [2015-03-25T13:51:33+09:00] WARN: No config file found or specified on command line, using command line options. Starting Chef Client, version 12.0.3 resolving cookbooks for run list: ["firefox", "windows_initial_settings", "windows"] Synchronizing Cookbooks: - firefox - windows_initial_settings - windows - chef_handler Compiling Cookbooks... Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Converging 13 resources Recipe: firefox::default * windows_package[Mozilla Firefox 36.0.4 en-US] action install Recipe: <Dynamically Defined Resource> * remote_file[C:\WORK\unix_home\.chef\local-mode-cache\cache/Firefox Setup 36.0.4.exe] action create - update content in file C:\WORK\unix_home\.chef\local-mode-cache\cache/Firefox Setup 36.0.4.exe from e3b0c4 to 15f75d (file sizes exceed 10000000 bytes, diff output suppressed) Recipe: windows_initial_settings::default * directory[C:WORK] action create (up to date) * git[C:\WORK\unix_home] action syncPassword for 'https://n_so5@bitbucket.org': (up to date) * env[HOME] action create (up to date) * directory[C:\WORK\unix_home\.ssh] action create (up to date) * execute[ssh-keygen] action run (skipped due to not_if) Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Running handlers: Running handlers complete Chef Client finished, 2/20 resources updated in 155.402539 seconds
既に環境変数が設定済だったり、鍵が生成済だったりするので、イロイロ飛ばされてますが、あっさりと適用できました。
あとは、インストールする各アプリのレシピを育てていけば、いつでもお手軽に新しいwindowsマシンのセットアップができますね。
chef-zeroでwindows用開発環境を構築(その2)
さて、前回の続きです。
普段、windowsマシンを使う時には、次のような運用方針にしているんですが、このための設定をchefのレシピでなんとかしてみましょう。
- C:\WORK を作成して、必要なファイル類はそこへ置く
- bitbucketに置いてあるドットファイルをC:\WORK\unix_homeにcloneしてくる。
- 環境変数 HOME にC:\WORK\unix_homeを設定
- sshの鍵を作成
cookbookの作成
まずは、knifeを使って新しいcookbookを作ります。*1
> knife cookbook create windows_initial_settings -z WARNING: No knife configuration file found ** Creating cookbook windows_initial_settings in C:/Users/n_so5/SkyDrive/chef-repo/cookbooks ** Creating README for cookbook: windows_initial_settings ** Creating CHANGELOG for cookbook: windows_initial_settings ** Creating metadata for cookbook: windows_initial_settings
無事にできたら、次のような感じのディレクトリが生成されているはずです。
>ls -R cookbooks\windows_initial_settings cookbooks\windows_initial_settings: CHANGELOG.md README.md attributes definitions files libraries metadata.rb providers recipes resources templates cookbooks\windows_initial_settings/attributes: cookbooks\windows_initial_settings/definitions: cookbooks\windows_initial_settings/files: default cookbooks\windows_initial_settings/files/default: cookbooks\windows_initial_settings/libraries: cookbooks\windows_initial_settings/providers: cookbooks\windows_initial_settings/recipes: default.rb cookbooks\windows_initial_settings/resources: cookbooks\windows_initial_settings/templates: default cookbooks\windows_initial_settings/templates/default:
このうちの、recipes/default.rbにつらつらとレシピを書いていきます。
ディレクトリの作成
まず、最初のC:\WORKの作成ですが、これはその名もずばりの"directory"というリソースがあるので、これを使います。
https://docs.chef.io/resource_directory.html
directory "C:\WORK" do action :create end
gitでドットファイルを持ってくる
こちらも"git"というリソースがあるので、これを使います。
https://docs.chef.io/resource_git.html
home_dir="C:\\WORK\\unix_home" git "#{home_dir}" do repository "https://n_so5@bitbucket.org/XXXX.git" enable_submodules true action :sync end
.vimの下にいくつかsubmoduleとしてvimプラグインのリポジトリを入れているので、"enable_submodule true"を指定しています。あと、sshの鍵を未だ登録していない環境からのアクセスを想定しているので、http経由でのアクセスにしています。
環境変数のHOMEを設定
これまた"env"というリソースがあるので、これを使います。
https://docs.chef.io/resource_env.html
env "HOME" do value "#{home_dir}" action :create end
sshの鍵作成
これまた、chefのリソースでと思いきや、あんまりこういう用途は想定していないのかうまく使えそうな手がありません。とりあえず、executeを使って、ssh-keygenを呼び出すことにします。
key_filename="C:\WORK\unix_home\.ssh\id_rsa" execute "ssh-keygen" do command "ssh-keygen -f #{key_filename} -t rsa " not_if {::File.exists?(key_filename)} end
既に鍵を作成した環境で実行した時に、上書きを避けるため、not_ifで条件を指定しています。
実際に適用してみる
ここまでをまとめてdefault.rbに書いた上で、windows以外の環境では実行されないように
if platform_family?('windows') ... end
で囲っておきます。
レシピの適用前はこんな状況ですが
> ls C:\WORK ls: C:\WORK: No such file or directory > echo %HOME% C:\Users\n_so5
実際に適用すると
> chef-client -z [2015-03-19T19:15:33+09:00] WARN: No config file found or specified on command line, using command line options. Starting Chef Client, version 12.0.3 resolving cookbooks for run list: ["firefox", "windows", "windows_initial_settings"] Synchronizing Cookbooks: - firefox - windows - windows_initial_settings - chef_handler Compiling Cookbooks... Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Converging 13 resources Recipe: firefox::default * windows_package[Mozilla Firefox 36.0.1 en-US] action install Recipe: <Dynamically Defined Resource> * remote_file[C:\Users\n_so5\.chef\local-mode-cache\cache/Firefox Setup 36.0.1.exe] action create (up to date) Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Recipe: windows_initial_settings::default * directory[C:WORK] action create - create new directory C:WORK * git[C:\WORK\unix_home] action syncPassword for 'https://n_so5@bitbucket.org': Password for 'https://n_so5@bitbucket.org': - clone from https://n_so5@bitbucket.org/XXXXX into C:\WORK\unix_home - checkout ref 26ea7cf8d79fb68b4273bc133c6165c636248b08 branch HEAD * directory[C:\WORK\unix_home\.ssh] action create - create new directory * execute[ssh-keygen] action runEnter passphrase (empty for no passphrase): Enter same passphrase again: - execute ssh-keygen -f C:\WORK\unix_home\.ssh\id_rsa -t rsa Running handlers: Running handlers complete
といった具合に適用されます。gitでアクセスしている時にはbitbucketのパスワードを聞かれるので、入力してください。あと、ssh-keygenのレシピを適用している時も普通にssh-keygenした時と同じようにパスフレーズの入力を求められます。
でもって、どういう状態になったかと言うと
>ls C:\WORK unix_home > ls C:\WORK\unix_home\.ssh\ id_rsa id_rsa.pub > echo %HOME% C:\Users\n_so5
あら?環境変数の変更が反映されていない・・・と思ったけどこれは単にコマンドプロンプトを再起動すれば反映されます。コマンドプロンプトを立ち上げ直すと、無事に反映されています。あと、.vim/bundleの下に色々と入っているのも確認。
> echo %HOME% C:\WORK\unix_home >ls %HOME%/.vim/bundle/* C:\WORK\unix_home/.vim\bundle/indentLine: README.md after doc C:\WORK\unix_home/.vim\bundle/pydiction: README README.md after complete-dict pydiction.py C:\WORK\unix_home/.vim\bundle/syntastic: CONTRIBUTING.md LICENCE README.markdown _assets autoload doc plugin syntax_checkers
ついでに、この状態から再実行するとどうなるか試してみました。
> cdhef-client -z [2015-03-19T19:29:26+09:00] WARN: No config file found or specified on command line, using command line options. Starting Chef Client, version 12.0.3 resolving cookbooks for run list: ["firefox", "windows", "windows_initial_settings"] Synchronizing Cookbooks: - firefox - windows - windows_initial_settings - chef_handler Compiling Cookbooks... Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Converging 13 resources Recipe: firefox::default * windows_package[Mozilla Firefox 36.0.1 en-US] action install Recipe: <Dynamically Defined Resource> * remote_file[C:\WORK\unix_home\.chef\local-mode-cache\cache/Firefox Setup 36.0.1.exe] action create - create new file C:\WORK\unix_home\.chef\local-mode-cache\cache/Firefox Setup 36.0.1.exe - update content in file C:\WORK\unix_home\.chef\local-mode-cache\cache/Firefox Setup 36.0.1.exe from none to ad32ad (file sizes exceed 10000000 bytes, diff output suppressed) Recipe: windows::default * chef_gem[win32-api] action install (up to date) * chef_gem[win32-service] action install (up to date) * chef_gem[windows-api] action install (up to date) * chef_gem[windows-pr] action install (up to date) * chef_gem[win32-dir] action install (up to date) * chef_gem[win32-event] action install (up to date) * chef_gem[win32-mutex] action install (up to date) Recipe: windows_initial_settings::default * directory[C:WORK] action create (up to date) * git[C:\WORK\unix_home] action syncPassword for 'https://n_so5@bitbucket.org': (up to date) * env[HOME] action create (up to date) * directory[C:\WORK\unix_home\.ssh] action create (up to date) * execute[ssh-keygen] action run (skipped due to not_if) Running handlers: Running handlers complete Chef Client finished, 2/20 resources updated in 417.811231 seconds
%HOME%を設定した影響で、firefoxのアーカイブをキャッシュしてる場所が変わるので、アーカイブを再ダウンロードしていますが、他は(up to date)と表示されて、するすると終わっていきます。
とりあえず今日のとこはこれで終わり。
*1:このメタファー破綻してないか・・・?