初自作PCの構成および組み立て感想

今まで研究室等にあるPCを分解したりもらったPC(10年物)だったりの経験や電子工作をかじったりの経験はあるがデスクトップのPCを購入したことがなかったので購入することにした。

最終的な構成

商品へのリンクなどは記載なし

要件

  • 光らない(絶対条件)
  • 10 年ぐらい戦える(つもり)
    • 今現在のそこそこではなく次世代の標準程度
  • メモリはガン積み
  • グラボはいらない
    • ただしゲームはそれなりにするので将来的にハイエンドを買う可能性はある

選択

CPU: なし

なんとなく Ryzen 9 5950X で決定済み

Chipset: B550 vs X570

CPU は決まっているので物理的な要因による制約として Socket AM4 に対応した マザーボードを選択する必要があった。 Socket AM4 に対応した chipset は A520, B550, X570 あたりが対応しているとされており、大雑把に比較すると B550, X570 のどちらかがよい様子。 記載中に気付いたがスペック的には B < X であるらしいが B550 のほうが後に出ていたらしい。

まあとりあえず AMD のページを見ると X570 が上にあった。 2021 年頭あたりなどでは BIOS バージョンが低いと Zen3 が対応してない可能性があり、BIOS update が USB でできる MSI が安心そうだが X570 なら特に問題なさそうなどの話があり X570 を選択。ただ購入を始めたのが 春になってからなので B550 でも新規発売や新規出荷分は対応済みだろうからほぼ問題なかったかもしれない。

参考

マザーボード: MEG X570 UNIFY vs Pro WS X570-ACE

主題: 光らせない。

いわゆるゲーム向けではなくソフトウェア開発が主な目的なのであまり世間一般の記事を参考にしていない。 ワークステーション向けという目的に惹かれ Pro WS X570-ACE を選択。まあ本人がいいのであればいいのでしょう。

最初は Integrated Graphics の意味が分からなくて グラボも興味がないのでオンボードHDMIが使えるのかと思ったら そういうCPUじゃないとダメということに後で気付いた。

Pro WS X570-ACE のほうは LANポート が2つあるが両方 1Gbps で、最近は 2.5Gbps が多いということで見劣りはするが、まあ現段階では環境の問題でそもそも 1Gbps に到達できないのと将来を考えても 追加対応すればいいかという判断。Wi-Fi6 はまあどちらでもよい。ルータは対応してるが、速度は前述のLANポートと同様にそこまで到達しない。

CPU Cooler: Noctua NH-D15 vs Deepcool Assasin III

地味にこれが一番時間かけた気がする。

どのCPUの記事でも温度に関する記載が多く、 5950X の箱にも "Liquid Cooling Recoomended" という記載がある。しかし水冷は故障しやすいらしいし、自作初心者にとってはハードルが高いのではと思い空冷を選択。

空冷としては以下のものを比較。

  • Noctua NH-D15
  • Deepcool Assasin III

後者は割と辛辣な言葉が多そうで、前者は空冷最強との呼び声が高いため NH-D15 を選択。 ただしこれの問題としてはただただでかい。これが入るケースかどうか、メモリと被るという意味などいろいろ調べる必要があった。

日本で購入するには どうも パソコン工房 ぐらいしかないためパソコン工房から購入。

このとき本家のページか楽天市場経由で購入可能なようだったが、なぜか保証期間が前者で 10日(輸入品)で後者が1ヵ月なので後者で購入しようと検討。 chromax.black は最近発売された同型でまったくかわらないが数千円値段が異なる。最初は 無印を購入予定だったが、記載上 Socket AM4 用マウントキットがなく、別途購入でもいいのものこれがどう影響するか不安だったため記載上 Socket AM4 対応されていた chromax.black に決定。

ケースに入るかどうかのクーラー長 については後述。

参考

メインメモリ

開発用として利用するうえで IDE や Docker などを考慮した場合大量に積んでいるのが望ましい。 いずれ 128GBにするのはほぼ確定なので 1枚 32GB であるものを検討。

32GBとなるとだいぶ選択肢が狭まり、もともと Kingstom のものを購入しようと思っていたが宗教上の理由により Amazon でできるだけ購入しないようにするとほぼ選択肢がなくなり、 CORSAIR に到達。

どうでもいいが 32GB で検索したとき 16GBx2 のセットの合計値として出すのはわりとやめてほしい。

CL などはよくわからなかったので crucial のページを参考にした。

参考

SSD

あまり容量も使わないかなと思ってあまり深く考えずに Gen4 PCIe x4 M.2 NVMe SSD で出てきたもので購入。メインメモリのときに名前が出ていたので目に入ったというのもある。 Pro WS X570-ACE ではそれ用にヒートシンクがついているのでむき出してもよいと思って購入したところどうもヒートシンク付きだったためその役目を果たさない状態となった。

ちなみに Pro WS X570-ACE では M.2 スロットが二つあるが チップセット側につながるスロットは x4 ではなく x2、かつ近くにある PCIe スロットを使うとさらに x1 に落ちるためとりあえず利用を保留。(ほかのマザーボードもそうなってるかは調査してない)

電源

大体何でもいいが使用量の半分程度がよいこということ、使用量はグラボが支配的ということ、今後グラボもハイエンドにする可能性があるということ、を考えるとそれなりにあったほうがいいということで適当に 玄人志向の1000Wのものを購入しようとしたが、どうも品薄らしく、電源だけ手に入らない状況になったため適当に他のものとして SUPER FLOWER のものを購入。(この選択は日本から台湾向けのワクチンが届いたニュースを見て影響を受けたというのもある)

ケース

あまり興味がなかったのでお勧めされた Define 7 を検討。重すぎ(総重量 16kg)なのでもうちょい何とかならないか見てると Compact なるものがあるのでそちらで検討。今見ると Meshify 2 Compact とかもあったようだがまあいいでしょう。

懸念していたのは NH-D15 が入るかどうかという点。 高さが ファンなしで160 mm, ありで165mm であり、Define 7 Compact のCPUクーラー高は 169 mm となり 4mm 程度の余裕しかない。ずっとこのあたりを懸念していて調べていたが、twitter で調べると Define 7 Compact に入るという情報が見つかり多分大丈夫だろうと Define 7 Compact に決定。

組み立て感想

マザーボード関連については似たような構成の動画があり、事前に知ることができていたためそんなに苦労はしなかった。 動画のなかでもメモリについて引っかかっていたが自分のときも差し込みが甘いため起動しない問題が発生していた。

ケース関係としては SUPER FLOWER の電源のファン部分にロゴの出っ張りが存在し、ケースに入れるときに引っかかってしまう問題がある。電源側のロゴを押し込んでへこませたあと強引に押し込むと入った。

CPUクーラーについては参考動画でも取り扱っているが、ファンの取り付けが思ったよりも自由度が高く、場所を変え深さを変えという感じで特に気にせず組み立てることができた。

参考

ベンチマーク

そんなに興味がないのでとりあえず FF14 のものを実行して抜粋。グラボが古くて他が新しい状態の例。

ファイナルファンタジーXIV: 漆黒のヴィランズ ベンチマーク
計測日時: 2021/6/19 21:46:31
SCORE: 8097
平均フレームレート: 55.20157
最低フレームレート: 15
評価: 非常に快適
-非常に快適に動作すると思われます。お好みのグラフィック設定でお楽しみください。
ローディングタイム:
  シーン#1   1.356sec
  シーン#2   2.566sec
  シーン#3   3.572sec
  シーン#4   2.405sec
  シーン#5   0.998sec
  合  計  10.897sec

windows で開発するリポジトリから Github Actions で gradlew を実行できるようにする

Github Actions で gradle wrapper を実行するようにしようとした際以下のようなエラーが出る場合がある。

f:id:nise_nabe:20210312083438p:plain
gradlew の実行の失敗

windows で作って push した場合は実行権限がつかないので git 上で実行権限を付与する必要がある。 また windowsexplorer や WSL2 などで chmod しても効果がないように見えるため git 上で表現されている実行権限を変更するのが安定そう。 WSL2 などで以下のように

$ git update-index --chmod=+x gradlew

gradle で Intellij IDEA の copyright 設定を追加する

Versions

  • Intellij IDEA 2020.3
  • Gradle 6.8.1
  • gradle-idea-ext-plugin 0.10

Contents

Copyright を自動で設定したい

Intellij IDEA には バンドルプラグインとして Copyright プラグインというものがあり、各ファイルに copyright 表記を自動的に付与したりしてくれる。

www.jetbrains.com

各種設定や copyright template に埋め込み可能な変数などは以下のリンク先のようになっている。

Copyright Profiles—IntelliJ IDEA

この設定を自プロジェクトに反映し、他の人が参加した時にも設定してほしいが手作業による追加を極力減らしたい、ということを考える。

Intellij IDEA で設定を共有する

調べた限りだと以下のような方法がある。

  • Intellij IDEA で生成された Copyright 設定を共有する
  • gradle buildscript で Intellij IDEA に設定する

Intellij IDEA で生成された Copyright 設定を共有する

Intellij IDEA は .idea ディレクトリ以下を VCS に追加することによって設定を共有可能にしている。

intellij-support.jetbrains.com

Copyright プラグインの設定は .idea/copyright ディレクトリに設定されるためこのファイルを VCS にコミットして共有すると良さそう。

gradle buildscript で Intellij IDEA に設定する

Gradle には bundle の idea plugin があるが、それとは別に idea-ext という jetbrains が開発している gradle plugin がある。

github.com

この plugin は idea plugin よりも細かく設定が追加できるような機能を提供している様子。 そのうち copyright についても設定可能な様子。

https://github.com/JetBrains/gradle-idea-ext-plugin/wiki#copyright

copyright {
  useDefault = "MyDefaultCopyright" // copyright profile to use by default
  profiles {                        // container for named profiles
    MyDefaultCopyright {                      // name of a profile
      notice = "My License text Here"         // license text, usually multi line
      keyword = "keywords"                
    }
    UnusedLicense {
      notice = "Another license text"
    }
}

kotlin DSL の場合はなぜか以下のように しないと Extension of type 'ProjectSettings' does not exist. などで使えない場合があるので これを追加して対応する。これは gradle そのもののコードを見てみると gradle も idea-ext plugin を使っており、 このように対応してる様子。

gradle/gradlebuild.ide.gradle.kts at v6.8.1 · gradle/gradle · GitHub

fun IdeaProject.settings(configuration: ProjectSettings.() -> Unit) = (this as ExtensionAware).configure(configuration)

fun ProjectSettings.copyright(configuration: CopyrightConfiguration.() -> Unit) = (this as ExtensionAware).configure(configuration)
idea {
    module {
        excludeDirs = setOf(layout.projectDirectory.file("intTestHomeDir").asFile)
    }
    project {
        settings {
            configureCopyright()
            configureRunConfigurations()
            doNotDetectFrameworks("android", "web")
        }
    }
}

fun ProjectSettings.configureCopyright() {
    copyright {
        useDefault = GradleCopyright.profileName
        profiles {
            create(GradleCopyright.profileName) {
                notice = GradleCopyright.notice
                keyword = GradleCopyright.keyword
            }
        }
    }
}

Code Reading

Intellij IDEA 側は ConfigurationHandler というクラスのサブクラスで map 形式のデータを受け取っている。 gradle-idea-ext plugin の方も Map を作っているようなので Intellij IDEA 側は何らかの形で gradle から map object を受け取って処理している?

intellij-community/CopyrightConfigurationHandler.kt at idea/203.6682.115 · JetBrains/intellij-community · GitHub

gradle-idea-ext-plugin/Copyright.groovy at 145a351972fae3bf4ce4565ce67f5784a2603f0d · JetBrains/gradle-idea-ext-plugin · GitHub

gradle で共通の設定をまとめる

バージョン

  • Gradle 6.8

この記事の目的

gradle で共通の設定をまとめたい場合にとれる方法について列挙。 実際どれがいいかについては今の利用状況によるので何とも言えないのでそこまでは書かない。

内容

gradle の buildscript で記述を共通化したい

自分の gradle プロジェクトで multi-project を採用しており複数の project が存在するとき、 buildscript で何度もおなじようなことを書くことがよくあり、このあたりを共通化したい場合がある。

例えば java project で spring boot で開発してるので、 lombok gradle plugin と spring boot gradle plugin は毎回設定し、 annotationProcessor configuration に spring-boot-annotation-processor を適用し、 implememtation configuration に spring-boot-starter を追加している、などである。

この時取れる方法は以下の2つ。

  • allprojects や subprojects に書いて project tree に対してまとめて書く
  • plugin で書く

本家ドキュメントの記載を見ると下記の通り。

Sharing Build Logic between Subprojects

前者は cross project configuration と呼ばれており、 gradle のドキュメントでは良くない書き方とされている。 前述のリンク先には直接記述はないが kotlin DSL を使う場合でも問題があり、 type-safe accessor が動かなくなる。*1

後者は convention plugin と呼ばれており、gradle のドキュメントでは推奨された書き方となっている。

以下この convention plugin について考える。

Convention Plugin を書く

この convention plugin を開発するためにはどうすればいいかを考える。 gradle のドキュメントでは色々な場所に目的に合わせて色々書いてあってわかりにくいが、ここでの話ではそのプロジェクトにおける buildscript の共通化を目的としているので基本的には buildSrc 以下に置く 。*2 buildSrc 以下に置く場合でも開発方法としては以下の三種類がある。

  • 通常の java/kotlin プロジェクトとして開発する
  • script plugin として script を 直接 apply する形で利用されるもので開発する
  • Precompiled Script plugin を利用して buildscript と同じような記述で開発する

通常の java/kotlin プロジェクトとして開発する

ドキュメント: https://docs.gradle.org/6.8/userguide/custom_plugins.html

昔からある方法で、たいていのプラグインはこの形で実装されている。 ただ簡単に共通化したいといった場合、すでにある buildscript から Plugin クラスを継承したりしないといけないためオーバーテクノロジー感がある。

script plugin として script を 直接 apply する形で利用されるもので開発する

https://docs.gradle.org/6.8/userguide/plugins.html#sec:script_plugins

こちらも昔からある方法で、普通に書いたbuildscript を抽出して共通化する簡単な方法の一つ。

制約

  • 6.8 現在では script plugin で追加された configuration などは typesafe accessor として利用できない。*3
  • 6.8 現在では plugins DSL を使って plugin を適用することができない。*4

Precompiled Script plugin を利用して buildscript と同じような記述で開発する

https://docs.gradle.org/6.8/userguide/custom_plugins.html#sec:precompiled_plugins

結果としてできるライブラリは1番目とほぼ同じだが記述方法とが buildscript と同じ書き方をそのまま利用できる。 最近の gradle init でできる初期構成などはこの方法も含まれている。 *5 このプラグインの書き方ができたときは kotlin DSL しか対応してなかったが最近になって groovy DSL も対応したようなので groovy の場合でもそのままコピペして共通化できるようになった(らしい。確認したことはない)。

その他巨大なプロジェクトの場合の構成例についてのユーザガイドがある。

Structuring Large Projects

その他情報

歴史

release note
Gradle 4.10 Release Notes 4.10 から kotlin DSL を使えるようになる。Get ready for Kotlin DSL 1.0
Gradle 5.0 Release Notes 5.0 で stable Precompiled Script Plugin がサポート Release 1.0.4 · gradle/kotlin-dsl-samples · GitHub
Gradle 6.4 Release Notes 6.4 から groovy を使った precompiled script を利用できるようになった kts に書き換えなくても共通化できるようになった
Gradle 6.7 Release Notes 6.7 から composite build が buildSrc から見えるようになった

リンク

*1: Gradle Kotlin DSL Primer

*2: Organizing Gradle Projects

*3: Gradle Kotlin DSL Primer

*4: Using Gradle Plugins

*5:gradle 6.8 で gradle init すると下記のサンプルのような project が出力され、このリンクも表示される。https://docs.gradle.org/6.8/samples/sample_building_kotlin_applications_multi_project.html

2020 年まとめ

技術編

  • Kotlin コードをだいぶ書いた
  • Spring Boot にそれなりに詳しくなった
  • Gradle にそれなりに詳しくなった
  • apache kafka を触り始めた
  • Rust を少し触った

f:id:nise_nabe:20201231163919p:plain

ゲーム編

  • PS4
    • Spider-Man Miles Morales
    • サクナヒメ
  • Switch
  • PC
    • Apex Legends
    • Oxygen Not Included
    • Satisfactry
    • X4 Foundation
    • Shapez.io
    • ARK
    • Graveyard Keeper
    • Outer Wilds
    • Little Witch Nobeta
    • while True: Learn()
    • Transport Fever2
    • Space Haven
    • Cities: Skyline
    • Moon Hunters
    • Project Winter
    • Don't Starve Together
    • Risk of Rain 2

マンガ編

  • 1161 冊買った

家編

  • ウォーキングマシンを買った
  • 象印スチーム加湿器を買った(2台目)
  • プリンターを買った
  • Logicool Ergo E575 を買った
  • ふるさと納税を始めた
  • 税金を調べ始めた

コーヒー編

全部生豆 10kg 級を数回買った

  • ブエノスアイレス農園
  • プロヴィデンシア農園
  • トミオフクダブルボン
  • カフェインレス コロンビア
  • ブルーマウンテン No. 1
  • クリスタルマウンテン
  • エスメラルダ農園 ゲイシ

Java(Jar) で大量クラスを取り扱う時の zip64 について

あるプロジェクトのビルドをしようとしたところ下記のようなエラーがでてきた。 このプロジェクトは gradle のビルドパフォーマンスを調べるために 10 万クラスを適当に作ったプロジェクトである。

Execution failed for task ':jar'.
> archive contains more than 65535 entries.

jar タスクを実行しようとしたとき jar に含められるエントリー数が 65535 を超えているとビルドできないらしい。

軽く検索してみると以下のようなページが出てくる。

java - What is the maximum number of files per jar? - Stack Overflow

この制限は jar アーカイブの話であり、java7 以上であれば zip64 format を使うと一つの jar に 65535 以上のファイルをつかえるらしい。

以下気になったので調べたことをまとめる。

ZIP64 とは

wikipedia を見ると zip64 は zip であり、その拡張領域に zip64 であること、または zip64 の情報が含まれているように見える。 また最近の環境であれば大体サポート対象のため普通に動くようにみえる。

zip の仕様 の version としては 4.5 以上。

ZIP (ファイルフォーマット) - Wikipedia

https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT

多分 fat jar とは関係ないが zipinfo コマンドなどでファイルの中身を見ると fat と書かれている、File Allocation Table の略が出てくる。

File Allocation Table - Wikipedia

Java における zip64

Java SE 7 以上ならばサポートされている様子。

BTS は以下のものの様子。

Bug ID: JDK-4681995 Add support for large (> 4GB) zip/jar files

javadoc をみると zip64 サポートはオプションであり、実装によりそう。

例として adopt openjdk を見るとサポートされている様子。今はもうだいたい Java SE 8 以上だと思うんで 1.6 この辺りは深堀しない。

https://github.com/AdoptOpenJDK/openjdk-jdk/commit/21aa30606a26191e0418ab9fdfd04d9ecfe155a0

Fat Jar における zip64

with Gradle

gradle で build するときには zip64 であるかどうかのオプションを指定することで zip64 形式で jar を生成できる様子。このときの実装は apache ant の ZipOutputStream。 gradle plugin など gradle 側で利用する側の jar が zip64 形式のとき動くかどうかはドキュメントやコードを見ただけではよくわからなかった。 gradle 1.12 以上ならば サポートされている様子。

Jar - Gradle DSL Version 6.7.1

Support zip/jar with more than 64k files & total size >2G by MisterTea · Pull Request #245 · gradle/gradle · GitHub

ZipOutputStream (Apache Ant API)

適当に Web 検索すると gradle buildscript に zip64 オプションを突然入れている記事が見えるので世の中ではよくある要件っぽくみえる。

with Spring Boot

Spring Boot では fully executable jar として jar ファイルを同梱して利用している様子。 この jar ファイルは Spring Boot 側の機能で実現されているようであるため Spring Boot の Loader 自前で頑張って zip64 format を解釈してるように見える。

このサポートは Spring Boot 2.2 から。ただしサポートされているのは同梱するライブラリのほうであり、 Spring Boot Gradle Plugin などで作られる実行可能な jar ファイルについてはサポートされていない。

Spring Boot 2.2 Release Notes · spring-projects/spring-boot Wiki · GitHub

Zip64 files are now supported inside "Fat Jars".

Support zip64 jars by cvienot · Pull Request #16091 · spring-projects/spring-boot · GitHub

Deploying Spring Boot Applications

A zip64-format jar file cannot be made fully executable. Attempting to do so will result in a jar file that is reported as corrupt when executed directly or with java -jar. A standard-format jar file that contains one or more zip64-format nested jars can be fully executable.

このあたりの事情を鑑みるに、Spring Boot Application を実装するプロジェクト上では 65535 以上のファイルを含んだ実行可能ファイルを作ることができない。 そのため一部のコードなどを別のプロジェクトとしてビルドし、それを依存するような構成などにするようなワークアラウンドが必要そう。

with other fat/uber jar

gradle shadow plugin や maven shade plugin などで生成される jar は一回 unzip してその中のクラスファイル等を追加して zip しなおす。 このときの jar はおそらく gradle の jar task に依存するため zip64 option を設定することで zip64 形式の jar を吐き出すことができる様子。