開発環境の利用目的
- Windows 10 64bit環境で開発する
- 自分の現在の用途はPythonパッケージの作成が主である。
- 処理速度改善のためにC/C++を使ったPythonライブラリも書き、CrossコンパイルしパッケージングしPyPIに上げたりもたまにする。
ということをやるのに、VSCodeは軽量で素晴らしい。自分の中では久々のヒットだ。
ある程度小慣れてきて自分なりの構成が分かったので、PCがぶっ壊れたとき用に環境を再現する手順として備忘しておく。
この手順で完成する開発環境
- IDE : Visual Studio Code
- cpp extention
- python extention
- markdown extention
- Git Lense
- Histroy
- etc..
- C/C++ : Clang/LLVM
- C/C++ header & library : 最低限のWindows10 SDK & MSVC Build
- python : pyenvでバージョン切替え & poetry
- SCM : Git for Windows
- etc : nodejs, 7zip, sakura editor, wegt, ripgrep, fzf, などを少々
以降の手順は可能な限りコマンドラインで淡々と実施できるよう考えた。
全ての手順はWindows標準のコマンドプロンプトからの入力が前提。
1. 環境変数設定
(1) ユーザ環境変数等
@rem IDEROOTはインストール先ルートディレクトリのパスをどこにするかまずは指定する。パスは任意です
set IDEROOT=Y:
set PYTHONVERSION=3.9.13
- PYTHONVERSIONは グローバル使用するPythonバージョン(pyenvでインストール可能なpythonバージョン
pyenv install --list
であること) - DATAROOTはプロジェクトデータを保存するディレクトリ
- PYTHONVERSIONは グローバル使用するPythonバージョン(pyenvでインストール可能なpythonバージョン
pyenv install --list
であること)
powershell -Command "& cd (Get-ChildItem env:IDEROOT).value"
if %errorlevel% neq 0 echo %IDEROOT%が存在しないか、ディレクトリではありません。&& pause && exit
powershell
echo @"
set IDEROOT=$env:IDEROOT
set DATAROOT=%IDEROOT%\usr\local\data
set PYTHONVERSION=$env:PYTHONVERSION
set USRLOCAL=%IDEROOT%\usr\local
set VSCODE_HOME=%USRLOCAL%\vscode
set PYENV_ROOT=%USRLOCAL%\pyenv
set PYENV=%PYENV_ROOT%\pyenv-win
set PYTHONPATH=%PYENV%\versions\%PYTHONVERSION%
set POETRY_HOME=%USRLOCAL%\poetry
set NODEJS_HOME=%USRLOCAL%\nodejs
setx Path `"%PYENV%\bin;%PYENV%\shims;%PYTHONPATH%;%PYTHONPATH%\Scripts;%PYTHONPATH%\Tools\scripts;%POETRY_HOME%\bin;%IDEROOT%\bin;%IDEROOT%\cmd;%IDEROOT%\mingw64\bin;%IDEROOT%\usr\bin;%VSCODE_HOME%\bin;%NODEJS_HOME%;%APPDATA%\npm;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps`"
setx IDEROOT %IDEROOT%
setx DATAROOT %DATAROOT%
setx PYTHONVERSION %PYTHONVERSION%
setx VSCODE_HOME %VSCODE_HOME%
setx PYENV_ROOT %PYENV_ROOT%
setx PYENV %PYENV%
setx PYTHONPATH %PYTHONPATH%
setx POETRY_HOME %POETRY_HOME%
setx NODEJS_HOME %NODEJS_HOME%
"@ | Set-Content $env:IDEROOT\setenv.bat
echo @'
@echo on
%PYTHONPATH%\%~n0.exe %PYTHONPATH%\Scripts\*.exe
pause
'@ | Set-Content $env:IDEROOT\repair_scripts.bat
exit
環境変数をセットします。
%IDEROOT%\setenv.bat
exit
注意:IDEROOTに既存のディレクトリを指定したら
同名のファイル又はディレクトリがある場合には、上書き良否確認などは一切せず
強制的に上書きするので
新規ディレクトリの指定を強く推奨する。
2. まず入れるもの
(1) ダウンロード用の関数準備します
mkdir %DATAROOT%
mkdir %IDEROOT%\usr\bin
powershell -ExecutionPolicy RemoteSigned
# github等 release 最新版URLをゲットする関数とzipをダウンロードしたら任意のパスに解凍し、元のzipファイルは削除する関数を二つ生成する
echo @'
Param(
[String]$Arg1,
[String]$Arg2 = '.*(windows|win64|((x86|amd)_?)?64|win32)?.*\.(zip|exe)'
)
Function gitlatest($url, $pattern = $Arg2){
$url = $url.replace("https://github.com", "https://api.github.com/repos")
$res = $(curl.exe -sL $url) -replace "`s*`"body`":.*",""
$res = ($res -join "`n") -replace ",(\n\s*\})", "`$1"
$j = ConvertFrom-Json "$res"
$assets = foreach($rl in $j.assets) {
If($rl.name -match $pattern -and $rl.name -notmatch "darwin|arm"){
$rl.browser_download_url
}
}
If($assets.Length -gt 0) {
return $assets[0]
} else {
return ""
}
}
Function nodelatest($url){
$v = $(curl.exe -sL "https://nodejs.org/dist/index.json" | ConvertFrom-Json)[0].version
return "https://nodejs.org/dist/$v/node-$v-win-x64.zip"
}
Function getlatest($url, $pattern = $Arg2) {
If($url -match "https://.*github.com.*") {
return (gitlatest $url $pattern)
} elseIf($url -match "https://.*nodejs.org.*") {
return (nodelatest $url)
} else {
return $url
}
}
getlatest $Arg1 $Arg2
'@ | Set-Content $env:IDEROOT\usr\bin\getlatest.ps1
echo @'
Param(
[String]$Arg1,
[String]$Arg2,
[String]$Arg3 = "*"
)
Function dunzip($expdir, $url, $target = "*"){
$TMPNAME = "$env:TEMP\workdir_download_will_unzip"
Remove-Item -Force -Recurse "$TMPNAME*"
curl.exe -sL -o "$TMPNAME.zip" $url
if ( !(Test-Path "$TMPNAME.zip") ) {
echo ダウンロードに失敗しました
return
}
if ( !(Test-Path $expdir) ) {
mkdir $expdir
}
if ( $target -eq "*" ) {
7z.exe x -o"$expdir" "$TMPNAME.zip" -aoa
} else {
7z.exe x -o"$TMPNAME" "$TMPNAME.zip" -aoa
Copy-Item -Force -Recurse "$TMPNAME\$target" "$expdir\"
}
Remove-Item -Force -Recurse "$TMPNAME*"
}
dunzip "$Arg1" "$Arg2" "$Arg3"
'@ | Set-Content $env:IDEROOT\usr\bin\dunzip.ps1
echo "@echo off`npowershell -ExecutionPolicy RemoteSigned -File `"%IDEROOT%\usr\bin\getlatest.ps1`" %*" | Set-Content $env:IDEROOT\usr\bin\getlatest.cmd
echo "@echo off`npowershell -ExecutionPolicy RemoteSigned -File `"%IDEROOT%\usr\bin\dunzip.ps1`" %*" | Set-Content $env:IDEROOT\usr\bin\dunzip.cmd
以下最新版をインストールします
(1) 7zip
この後の作業で必須
curl.exe -sL -o.\7zip.exe https://sourceforge.net/projects/sevenzip/files/latest/download
Start-Process -Verb runas -Wait .\7zip.exe
if ($?) { del .\7zip.exe } else {Write-Error "Install Failed 7zip";return}
$sevenzippath = reg query HKEY_LOCAL_MACHINE\SOFTWARE\7-Zip |select-string Path64
$sevenzippath = [regex]::replace($sevenzippath, '.*[^\s]\s{2,}(.+[^\\])\\?', { $args.groups[1].value })
if (! (Test-Path -Path ${Env:IDEROOT}\usr\bin\7z.exe) ) {Copy-Item $sevenzippath\* -Recurse ${Env:IDEROOT}\usr\bin}
# Set-Item Env:Path "${sevenzippath};${Env:Path}"
(2) サクラエディタ
好み。なんでもよい
$sakuraurl = getlatest "https://github.com/sakura-editor/sakura/releases" ".*Win32-Release-Installer.zip"
curl.exe -sL -o.\sakura.zip $sakuraurl
7z x .\sakura.zip
Start-Process -Verb runas -Wait .\sakura_install*.exe /VERYSILENT
if ($?) { del .\sakura* } else { Write-Error "Install Failed Sakura Editor" }
$sakurapath = reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" /s | select-string -Pattern "InstallLocation.*sakura"
$sakurapath = [regex]::replace($sakurapath, '.*[^\s]\s{2,}(.+[^\\])\\?', { $args.groups[1].value })
Set-Item Env:Path "${Env:Path};${sakurapath}"
(4) Git for Windows
Git必須なのと、mingw環境もそこそこ活用するため
$giturl = getlatest "https://github.com/git-for-windows/git/releases" "Git.*64-bit.tar."
curl.exe -sL -o.\git-for-windows.tar.bz2 $giturl
echo ${env:IDEROOT}にインストールしてます
7z.exe x .\git-for-windows.tar.bz2 -bsp2
if ($?) { del .\git-for-windows.tar.bz2 }
7z.exe x -o"${Env:IDEROOT}" .\git-for-windows.tar -aoa -bsp2 -x"!dev/fd" -x"!dev/std*" -x"!etc/mtab"
if ($? -And (Test-Path -Path ${Env:IDEROOT}/git-bash.exe) ) { del .\git-for-windows.tar } else {Write-Error "Install Failed Git for windows";return}
# [environment]::SetEnvironmentVariable("Path", $Env:Path, "User")
(5) C/C++ Windows headers & libraries
Microsoft BuildTools
インストールウィザード手順
- 個別のコンポーネントタブを選択
- 検索窓で以下のワードで絞り込む
- 「MSVC x64 ビルド ツール 最新」
- 「Windows 10 SDK」
この2つだけあれば最低限OK。5GBもいるけど、、
curl.exe -sL -o ${env:TEMP}\vs_BuildTools.exe https://aka.ms/vs/17/release/vs_BuildTools.exe
Start-Process -Verb runas -Wait "${env:TEMP}\vs_BuildTools.exe"
Remove-Item -Force -Recurse "${env:TEMP}\vs_BuildTools.exe"
3. 開発環境構築
(1) セットアップ、セットアップコマンドの作成
-
後の手順で最新版ダウンロード用のワークシェル
-> バッチファイルやpowershellは冗長で貧弱で難解すぎて怒りのbash -
お気に入りのコマンドDL
a. fzfをインストール
b. RipGrepをインストール
c. RipGrep-allをインストール
## 2. Favorite commands
## fzf
dunzip "$env:IDEROOT\usr\bin" $(getlatest "https://github.com/junegunn/fzf/releases")
## ripgrep
dunzip "$env:IDEROOT\usr\bin" $(getlatest "https://github.com/BurntSushi/ripgrep/releases") ripgrep-*/rg.exe
## jq
curl.exe -sL -o "$env:IDEROOT\usr\bin\jq.exe" $(getlatest "https://github.com/stedolan/jq/releases" "jq-win64.exe")
exit
(2) Python(pyenv-win)インストール
git clone https://github.com/pyenv-win/pyenv-win.git "%PYENV_ROOT%"
cd /d "%PYENV_ROOT%"
mv .version pyenv-win
rm -rf [._a-oq-zR]*
mv pyenv-win/.version ./
pyenv --version
pyenv rehash
pyenv install %PYTHONVERSION%
pyenv global %PYTHONVERSION%
pyenv update
pyenv install -l | grep -v "win"
echo python %PYTHONVERSION% の他に必要なバージョンがあれば、ここで入れてください。上に出ているバージョン一覧参照
echo 例: pyenv install 2.7.18
(3) Python(pyenv-win) 初期設定
やってること
- python関連 SJIS固有の不具合の強引な対策
- ライブラリインストール
- pip最新化
- 開発用ライブラリのインストール
- CAPI開発用にpythonXX_d.libのインストール
echo pyenv Issue51関連の不具合修正してます
grep -rl "chcp 1250" * | xargs sed -i.bak "s/chcp 1250/chcp 932/g"
pyenv rehash
powershell -Command "& cd (Get-ChildItem env:IDEROOT).value"
cd /d %PYENV%\versions
for /d %d in (*) do (
pyenv local %d
echo zipファイル名日本語の文字化け対策をしてます
sed -i.bak "s/cp437/cp932/g" %PYENV%\versions\%d\Lib\zipfile.py
echo repair_pathアプリのダウンロード
curl.exe -sL -o %PYTHONPATH%\repair_scripts.exe https://github.com/kirin123kirin/dotfile/raw/master/python/repair_scripts.exe
echo pipを最新化します
python -m pip install --upgrade pip
echo 開発用ツールをインストールしてます
pip install autopep8 scikit-build
pip install -r https://github.com/scikit-build/scikit-build/raw/master/requirements-dev.txt
echo debug用ライブラリをダウンロードしてます
curl.exe -sL -o %TEMP%\dev_d_%d.msi https://www.python.org/ftp/python/%d/amd64/dev_d.msi
sleep 1
msiexec /a %TEMP%\dev_d_%d.msi targetdir="%PYENV%\versions\%d" /qn
del /s /q %TEMP%\dev_d_%d.msi
)
pyenv local %PYTHONVERSION%
python -V
pyenv versions
(4) poetryインストール
curl.exe -L https://install.python-poetry.org | python -
poetry --version
poetry self update
poetry config --list
poetry config virtualenvs.in-project true
poetry config cache-dir "%POETRY_HOME%\pypoetry\Cache"
poetry config --list
(5) C/C++ Build Tool
LLVM & CMake & Ninjaインストール
echo LLVM インストール...
for /f "tokens=*" %u in ('getlatest https://github.com/llvm/llvm-project/releases win64.exe') do dunzip %IDEROOT% "%u"
rm -rf "%IDEROOT%\$PLUGINSDIR"
echo CMake インストール...
for /f "tokens=*" %u in ('getlatest https://github.com/Kitware/CMake/releases windows-x86_64.zip') do dunzip %IDEROOT% "%u" cmake*/*
echo Ninja インストール...
for /f "tokens=*" %u in ('getlatest https://github.com/ninja-build/ninja/releases win') do dunzip %IDEROOT%\bin "%u"
(6) 必要ならNode.jsインストール
for /f "tokens=*" %u in ('getlatest https://nodejs.org/dist') do dunzip %NODEJS_HOME% "%u" node-v*\*
(7) VSCodeインストール
echo VSCodeインストールしてます
dunzip "%VSCODE_HOME%" "https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-archive"
echo VSCodeのショートカットを作成してます
set TARGET='%VSCODE_HOME%\Code.exe'
set SHORTCUT='%APPDATA%\Microsoft\Windows\Start Menu\Code.lnk'
powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -Command "$ws = New-Object -ComObject WScript.Shell; $s = $ws.CreateShortcut(%SHORTCUT%); $S.TargetPath = %TARGET%; $S.Save()"
cp %SHORTCUT% %USERPROFILE%\Desktop
4. 個人的な初期設定
(1) VSCodeユーザ設定
echo 拡張機能をインストールします
mkdir %VSCODE_HOME%\data\extensions %VSCODE_HOME%\data\user-data\User
for /f "tokens=*" %x in ('curl.exe -sSL https://raw.githubusercontent.com/kirin123kirin/.vscode/main/vscode_extensions.txt') do code --extensions-dir %VSCODE_HOME%\data\extensions --install-extension %x
echo ステータスバーのダウンロードが完了するまで待ってVSCodeを再起動してください
@code %DATAROOT% && pause
echo 全般設定の設定中
curl.exe -sL -o %VSCODE_HOME%\data\user-data\User\settings.json https://raw.githubusercontent.com/kirin123kirin/.vscode/main/settings.json
echo キーバインドの設定中
curl.exe -sL -o %VSCODE_HOME%\data\user-data\User\keybindings.json https://raw.githubusercontent.com/kirin123kirin/.vscode/main/_keybindings.json
(2) Git config global & PyPI configユーザ設定
ユーザ名とEmailを入力してください。
echo git configとpypircの設定を行います。
%IDEROOT%\bin\bash.exe
cat<<'EOF' > ~/.gitconfig
[user]
email =
name =
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[gui]
encoding = utf-8
[core]
autocrlf = input
EOF
notepad ~/.gitconfig
cat<<'EOF' > ~/.pypirc
[distutils]
index-servers=
pypi
pypitest
[pypi]
username:
password:
#[pypitest]
#repository: https://test.pypi.org/legacy/
#username :
#password :
EOF
notepad ~/.pypirc
exit
以下は別にやらなくても良い。
(N) INCLUDE, LIBPATHのユーザ環境変数設定
Windows SDK? Visual Studioのパスが死ぬほどめんどくさいので
無理やり環境変数INCLUDE、LIBPATHをぶち込む
%IDEROOT%\bin\bash.exe
ARCH=x64
IDEROOT_S=$(echo $IDEROOT | sed "s;\\\;/;g")
WKIT=$(reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" | grep "KitsRoot" | sed "s;\\\;/;g" | sed -E "s;.*KitsRoot.+\s\s([^\s].+)/$;\1;g")
MSVC_ROOT=$(reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\Setup" | grep "SharedInstallationPath" | sed "s;\\\;/;g" | sed -E "s;.*SharedInstallationPath.+\s\s([^\s].+)/Shared/?$;\1;g")
MSBUILD=`ls -d "$MSVC_ROOT"/[0-9]*/BuildTools | tail -1`
MSVC=`ls -d "$MSBUILD"/VC/Tools/MSVC/[0-9]* | tail -1`
CLANGVERSION=`ls -d "$IDEROOT_S"/lib/clang | tail -1`
INCLUDE=`ls -d "$(ls -d "$WKIT"/Include/[0-9]* | tail -1)"/* | tr '\n' ';'`
INCLUDE="${INCLUDE};${MSVC}/include;$INCLUDE;$MSVC/include;$IDEROOT_S/usr/local/poetry/venv/Include;$IDEROOT_S/lib/clang/${CLANGVERSION}/include;$IDEROOT_S/include"
LIBPATH=`ls -d "$(ls -d "$WKIT"/Lib/[0-9]* | tail -1)"/*/$ARCH | tr '\n' ';'`
LIBPATH="${LIBPATH};${MSVC}/lib/${ARCH};${LIBPATH};$IDEROOT_S/lib/clang/${CLANGVERSION}/lib"
LIBPATH="${LIBPATH};$IDEROOT_S/usr/local/pyenv/pyenv-win/libexec/libs;$IDEROOT_S/usr/lib;$IDEROOT_S/lib"
cat <<EOF > /tmp/setenv.bat
@setx INCLUDE "${INCLUDE}"
@setx LIBPATH "${LIBPATH}"
@setx MSVC "${MSVC//\//\\}"
@setx WKIT "${WKIT//\//\\}"
@setx Path "%Path%;${MSVC//\//\\}\\bin\\Host${ARCH}\\${ARCH}"
EOF
/tmp/setenv.bat && rm /tmp/setenv.bat
cat <<EOF > "$IDEROOT_S"/bin/vsdevcmd.cmd
@echo off
@call "$MSBUILD/Common7/Tools/VsDevCmd.bat" %*
EOF
cp "$IDEROOT_S"/bin/vsdevcmd.cmd "$IDEROOT_S"/bin/vcvarsall.cmd
exit
exit
VSCode Serverを起動できる環境も作りたい場合
mkdir %VSCODE_HOME%\resources\server-cli %VSCODE_HOME%\data
mklink /j %USERPROFILE%\.vscode-cli %VSCODE_HOME%\resources\server-cli
mklink /j %USERPROFILE%\.vscode-server %VSCODE_HOME%\data
curl.exe -sL -o %VSCODE_HOME%\bin\code-server.exe https://aka.ms/vscode-server-launcher/x86_64-pc-windows-msvc
echo @echo off > "%VSCODE_HOME%\bin\vscode-server.cmd"
copy %VSCODE_HOME%\data\extensions\extensions.json %VSCODE_HOME%\data\data\User\extensions.json
echo "%~dp0code-server.exe" serve-local --host 0.0.0.0 --port 8090 --without-connection-token %* >> "%VSCODE_HOME%\bin\vscode-server.cmd"
その他
ドライブマウントについて
コマンドラインからドライブレターをマウントする例(%IDEROOT%をYドライブとしてマウント)
subst Y: %IDEROOT%
しかし再起動したらYドライブへのマウントが消えてしまう。
$IDEROOTをYドライブとして永続的に割り当てたい場合は以下2つの方法がある。
方法1. ユーザ別割り当て
echo subst Y: "%IDEROOT%" > "%APPDATA%\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\subst.bat"
方法2. レジストリにマウント情報保存する例(管理者権限プロンプト)
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices" /v "E:" /t REG_SZ /d "\??\%IDEROOT%"
以上、