Goのbuildディレクトリでバイナリと生成ファイルを効率管理する方法

Go言語のプロジェクト開発では、効率的なビルド管理がプロジェクトの成功に直結します。特に、buildディレクトリを活用することで、コンパイル済みのバイナリや生成された一時ファイルを明確に整理することが可能になります。本記事では、Go言語におけるbuildディレクトリの役割を理解し、効果的に運用する方法を詳しく解説します。これにより、プロジェクトの可読性やメンテナンス性を向上させ、チーム全体の作業効率を最大化するヒントを得ることができます。

目次

Go言語の`build`ディレクトリの役割


Go言語のプロジェクトにおいて、buildディレクトリはコンパイル済みのバイナリやその他の生成ファイルを格納するための専用フォルダとして広く利用されています。このディレクトリを活用することで、ソースコードと生成物を分離し、プロジェクト構造をクリーンに保つことができます。

`build`ディレクトリの主な用途

  • コンパイル済みバイナリの保存: プロジェクトで生成される実行可能ファイルを一元管理します。
  • 生成ファイルの格納: プロトコルバッファーやSwaggerドキュメントなど、自動生成された補助ファイルの保存に適しています。
  • マルチプラットフォームの出力管理: 異なるOSやアーキテクチャ向けにビルドしたバイナリを整理できます。

`build`ディレクトリを利用するメリット

  • コードの可読性向上: ソースコードが生成物に埋もれるのを防ぎます。
  • クリーンなリポジトリ管理: 生成物が明確に分離されるため、Gitリポジトリに不要なファイルが混在するのを防げます。
  • 簡単なクリーンアップ: 生成ファイルを削除する際、buildディレクトリごと操作するだけで完了します。

開発者視点での重要性


適切にbuildディレクトリを管理することで、ビルドエラーの特定や生成物の扱いが簡単になり、プロジェクトの開発効率を向上させることができます。buildディレクトリの役割を理解し、最大限に活用することが、効果的なGo開発の第一歩です。

Goプロジェクトにおけるディレクトリ構造のベストプラクティス

Go言語のプロジェクトを効率的に管理するためには、明確で一貫性のあるディレクトリ構造を設計することが重要です。ここでは、buildディレクトリを含むプロジェクト構造のベストプラクティスを紹介します。

標準的なディレクトリ構造


以下は、Goプロジェクトにおける推奨されるディレクトリ構造の一例です:

my-project/
├── cmd/             # 各コマンド用のサブディレクトリ
├── pkg/             # 再利用可能なパッケージ
├── internal/        # プロジェクト内でのみ使用されるパッケージ
├── build/           # コンパイル済みバイナリや生成物
├── configs/         # 設定ファイル(YAML, JSONなど)
├── docs/            # プロジェクトのドキュメント
├── scripts/         # ビルドやデプロイ用スクリプト
├── test/            # テストコード
└── main.go          # エントリーポイント

`build`ディレクトリの位置付けと役割

  • 一時的なファイルの保管場所: buildディレクトリには、生成されたバイナリやその他の一時的なファイルを格納します。
  • 生成物の分離: ソースコードと生成物を明確に分けることで、開発環境の整然性を保ちます。
  • 環境ごとの分離: サブディレクトリを使用して、異なる環境やプラットフォーム用の生成物を整理します。例えば:
build/
├── linux/           # Linux用バイナリ
├── windows/         # Windows用バイナリ
└── darwin/          # macOS用バイナリ

実際のプロジェクトでの活用例

  1. コンパイル済みバイナリの格納: buildディレクトリにOSやアーキテクチャごとに生成物を保存。
  2. 生成されたドキュメントやコード: SwaggerやProtoファイルの出力先としても活用。
  3. CI/CDパイプラインとの統合: JenkinsやGitHub Actionsでビルド結果をbuildディレクトリに格納し、後続の処理(デプロイやアーティファクトの保存)に利用します。

注意点

  • バージョン管理の対象外に設定: .gitignoreファイルでbuildディレクトリを除外して、リポジトリをクリーンに保ちましょう。
  • 明確な命名規則: 各生成物には一貫した命名規則を採用し、ファイル管理を容易にします。

適切なディレクトリ構造を構築することで、プロジェクトの可読性と管理のしやすさが大幅に向上します。特にbuildディレクトリの適切な運用が、プロジェクト全体の効率化に寄与します。

`go build`コマンドでバイナリを生成する方法

Go言語のgo buildコマンドは、プロジェクトのソースコードから実行可能なバイナリを生成するための基本的なツールです。このセクションでは、go buildコマンドの使用方法と、生成したバイナリをbuildディレクトリに整理する方法を解説します。

`go build`コマンドの基本


go buildコマンドは、指定したパッケージやモジュールのコードをコンパイルし、実行可能なバイナリを生成します。以下のように使用します:

go build

デフォルトでは、バイナリは現在のディレクトリに生成されます。

特定の出力ファイル名を指定する


生成されるバイナリの名前を指定するには、-oオプションを使用します:

go build -o my-app

これにより、my-appという名前のバイナリが生成されます。

`build`ディレクトリへのバイナリの配置


生成物をbuildディレクトリに配置することで、プロジェクトの構造を整理できます。例えば、次のようにコマンドを実行します:

go build -o build/my-app

また、OSやアーキテクチャごとにディレクトリを分ける場合:

go build -o build/linux/my-app

これにより、生成物を用途ごとに整理できます。

複数のプラットフォーム向けのビルド


Goでは、環境変数GOOSGOARCHを設定することで、クロスコンパイルが可能です。例として、Linux用のバイナリを生成する方法を示します:

GOOS=linux GOARCH=amd64 go build -o build/linux/my-app

他の例:

  • Windows向け:
  GOOS=windows GOARCH=amd64 go build -o build/windows/my-app.exe
  • macOS向け:
  GOOS=darwin GOARCH=amd64 go build -o build/darwin/my-app

複数のバイナリを生成する場合


cmdディレクトリを利用することで、複数のエントリーポイントを管理し、それぞれのバイナリを生成できます。

例:
ディレクトリ構造:

my-project/
├── cmd/
│   ├── app1/
│   │   └── main.go
│   └── app2/
│       └── main.go
├── build/
└── go.mod

コマンド:

go build -o build/app1 cmd/app1/main.go
go build -o build/app2 cmd/app2/main.go

トラブルシューティング

  • 未解決の依存関係: go mod tidyで依存関係を整理します。
  • 環境変数のエラー: GOOSGOARCHを正しく設定することを確認してください。

実践的な管理のポイント


buildディレクトリを活用することで、プロジェクトのビルド結果を明確に整理でき、ソースコードの管理を効率化できます。また、Gitリポジトリにはbuildディレクトリを含めず、生成物をリポジトリ外で管理するのが推奨されます。

バイナリ生成のカスタマイズと最適化の手法

Go言語では、go buildコマンドを使用して生成されるバイナリをカスタマイズし、プロジェクトの要件や実行環境に応じて最適化することが可能です。このセクションでは、ビルドフラグやオプションを活用した効率的なバイナリ生成の方法を解説します。

カスタマイズ可能なビルドフラグ


go buildコマンドには、さまざまなフラグを使用してビルドプロセスをカスタマイズするオプションがあります。

デバッグ情報を除外した最小限のバイナリ生成


デバッグ情報を含まない軽量なバイナリを生成するには、-ldflagsオプションを使用します:

go build -ldflags="-s -w" -o build/my-app
  • -s: シンボルテーブルを削除
  • -w: デバッグ情報を削除

これにより、バイナリのサイズを大幅に削減できます。

バージョン情報の埋め込み


バイナリにバージョン情報やビルド時のメタデータを埋め込むことで、管理性を向上させます:

go build -ldflags="-X 'main.version=1.0.0' -X 'main.buildDate=$(date)'"

コード内で以下のように埋め込まれた情報を利用できます:

package main

import "fmt"

var version string
var buildDate string

func main() {
    fmt.Printf("Version: %s, Build Date: %s\n", version, buildDate)
}

複数のアーキテクチャ向けビルドの自動化


Makefileやスクリプトを活用して、異なるプラットフォーム向けのバイナリを一括生成します:

Makefileの例:

build:
    GOOS=linux GOARCH=amd64 go build -o build/linux/my-app
    GOOS=windows GOARCH=amd64 go build -o build/windows/my-app.exe
    GOOS=darwin GOARCH=amd64 go build -o build/darwin/my-app

コマンド:

make build

パフォーマンス最適化

圧縮ツールを使用したバイナリサイズ削減


生成されたバイナリをさらに軽量化するために、upxなどの圧縮ツールを利用します:

upx --best --lzma build/my-app

CPUアーキテクチャの最適化


特定のCPUアーキテクチャ向けに最適化するために、GOARCHオプションを使用します。たとえば、ARMアーキテクチャ用:

GOOS=linux GOARCH=arm go build -o build/linux-arm/my-app

静的リンクによる依存解消


外部ライブラリへの依存を削減し、スタンドアロンバイナリを生成するには、CGO_ENABLED=0を設定して静的リンクを有効にします:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o build/my-static-app

これにより、外部ライブラリが不要なバイナリを生成できます。

トラブルシューティングと検証

ビルドエラーの解消

  • 依存関係の確認: go mod tidyを実行して、モジュールの整合性を保ちます。
  • 環境変数の誤設定: 必要に応じてGOOSGOARCHを正しく設定します。

生成物の検証


生成されたバイナリが正常に動作することを確認するには、以下のコマンドで実行します:

./build/my-app

バージョン情報や動作確認用のメッセージを含むバイナリを作成しておくと、デプロイ前の確認がスムーズになります。

まとめ


go buildコマンドを活用したカスタマイズと最適化は、プロジェクトの効率化に欠かせません。軽量化やプラットフォーム別ビルド、デバッグ情報の除去などの手法を組み合わせることで、運用に適したバイナリを生成できます。適切な最適化により、開発のパフォーマンスとプロダクション環境の信頼性が向上します。

生成ファイルの整理と削除の自動化

Goプロジェクトでは、バイナリやその他の生成ファイルを適切に管理することで、プロジェクトの可読性と効率性を高めることができます。このセクションでは、生成物の整理方法と削除の自動化手法を解説します。

生成物を整理する基本方針

ディレクトリ構造を統一する


buildディレクトリを作成し、生成物を一元管理することで、プロジェクトの構造が明確になります。以下のようにサブディレクトリを作成して用途別に分けるとさらに管理しやすくなります:

build/
├── linux/
├── windows/
├── darwin/
└── docs/

生成物の命名規則を決める


一貫した命名規則を採用することで、生成ファイルの識別が容易になります。たとえば、以下の形式を使用します:

[プロジェクト名]_[OS]_[アーキテクチャ]
例: my-app_linux_amd64

不要な生成ファイルの削除方法

手動で削除する方法


生成物を削除する最も基本的な方法は、rmコマンドを使用することです。以下のコマンドでbuildディレクトリ全体を削除できます:

rm -rf build/

自動化された削除スクリプトの作成


プロジェクト内にクリーンアップスクリプトを作成し、不要なファイルを効率的に削除します。以下は簡単なBashスクリプトの例です:

#!/bin/bash
echo "Cleaning up build directory..."
rm -rf build/
echo "Build directory cleaned."

スクリプトに実行権限を付与して使用します:

chmod +x clean.sh
./clean.sh

Makefileを使用した整理と削除の自動化

Makefileを使用すると、ビルドとクリーンアップを簡単に管理できます。以下の例では、make buildで生成物を作成し、make cleanで削除します:

build:
    GOOS=linux GOARCH=amd64 go build -o build/linux/my-app
    GOOS=windows GOARCH=amd64 go build -o build/windows/my-app.exe
    GOOS=darwin GOARCH=amd64 go build -o build/darwin/my-app

clean:
    rm -rf build/

Makefileの利用方法


ビルド:

make build

クリーンアップ:

make clean

CI/CDパイプラインでの自動クリーンアップ

ビルド後の自動削除


JenkinsやGitHub ActionsなどのCI/CDツールを使用して、ビルドプロセスの最後に生成物を削除するタスクを設定できます。

GitHub Actionsの例:

name: Go Build

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: '1.20'
      - name: Build binaries
        run: |
          mkdir -p build/linux
          GOOS=linux GOARCH=amd64 go build -o build/linux/my-app
      - name: Clean up
        run: rm -rf build/

生成物の無視設定

Gitリポジトリに含めない


生成物がGitリポジトリにコミットされないように、.gitignoreファイルを設定します。以下は一般的な設定例です:

# Ignore build directory
build/

Dockerや他のツールでの除外


Dockerコンテナを使用している場合、生成物をボリュームやイメージから除外します:

# Dockerfile
COPY . /app
RUN rm -rf /app/build/

まとめ


生成ファイルを整理し、不要な生成物を自動で削除する手法を活用することで、プロジェクトのメンテナンス性を向上させることができます。ディレクトリ構造の明確化、スクリプトやMakefileの利用、さらにCI/CDでの統合によって、効率的な開発環境を構築しましょう。

他のチームメンバーとのbuildディレクトリの共有戦略

Goプロジェクトでは、buildディレクトリを効率的に共有することで、チームの作業効率が向上します。共有に適切な方法を選択することは、ミスの防止や一貫性のあるビルド環境を維持するために重要です。このセクションでは、チーム開発でのbuildディレクトリ管理のベストプラクティスを解説します。

ローカル環境でのビルド管理

個別の`build`ディレクトリを使用


各開発者がローカル環境で独自のbuildディレクトリを利用するのが基本です。この方法は、以下の利点があります:

  • 開発者間の生成物の干渉を防ぐ
  • 各自の環境に依存したカスタマイズが可能

ローカルのbuildディレクトリをGitリポジトリから除外する設定を行います:

# .gitignore
build/

Makefileやスクリプトの統一


チーム全体で同じビルド手順を実行するため、Makefileやビルドスクリプトをリポジトリに共有します。例えば:

build:
    GOOS=linux GOARCH=amd64 go build -o build/linux/my-app

これにより、各開発者が同じディレクトリ構造で生成物を整理できます。

リモート環境での`build`ディレクトリ共有

アーティファクトリポジトリの活用


生成されたバイナリやその他の生成物は、リモートのアーティファクトリポジトリ(例: JFrog Artifactory、AWS S3)に保存し、チームメンバー間で共有します。

例: AWS CLIを使用してS3にアップロード:

aws s3 cp build/linux/my-app s3://my-bucket/build/linux/my-app

これにより、チームメンバーがローカルで生成する必要がなくなります。

CI/CDパイプラインの利用


GitHub ActionsやJenkinsを使用して、自動ビルドとアーティファクトの共有を実現します。以下はGitHub Actionsの例です:

name: Build and Share

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: '1.20'
      - name: Build binary
        run: GOOS=linux GOARCH=amd64 go build -o build/linux/my-app
      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          name: linux-binary
          path: build/linux/my-app

これにより、生成物が中央リポジトリに保存され、チームメンバーがダウンロード可能になります。

プラットフォーム間の互換性確保

クロスプラットフォームビルド


チームメンバーが異なるOSを使用している場合、複数のプラットフォーム向けのバイナリを生成して共有します。

例:

GOOS=linux GOARCH=amd64 go build -o build/linux/my-app
GOOS=windows GOARCH=amd64 go build -o build/windows/my-app.exe
GOOS=darwin GOARCH=amd64 go build -o build/darwin/my-app

これにより、どの開発者でも自分の環境で動作するバイナリを利用できます。

ベストプラクティス

Gitリポジトリに生成物を含めない


生成物をコミットしないことで、リポジトリをクリーンに保ちます。.gitignorebuildディレクトリを除外します。

ドキュメント化された手順の共有


チームが一貫してbuildディレクトリを管理できるよう、ビルドや共有の手順をREADMEなどに明記します。

まとめ


チーム開発では、ローカルとリモートの両方で効率的にbuildディレクトリを管理する戦略が重要です。アーティファクトリポジトリやCI/CDを活用し、生成物を共有することで、チーム全体の効率を最大化できます。明確な手順とツールの利用で、開発環境を統一し、一貫性のある成果物を維持しましょう。

実用例: 実際のGoプロジェクトでの`build`ディレクトリの活用

Goプロジェクトでbuildディレクトリを効果的に活用することで、ビルドプロセスの効率化やプロジェクトの整然性を高めることができます。このセクションでは、具体的なGoプロジェクトを例に、buildディレクトリを用いたバイナリ管理の実践例を紹介します。

プロジェクトの背景

あるGoプロジェクトでは、以下の要件がありました:

  1. 複数のプラットフォーム向けにバイナリを生成する必要がある。
  2. 自動生成されたコード(例: Protocol Buffers)の管理を明確にする必要がある。
  3. CI/CDで生成物を他の環境に共有しやすくしたい。

これらの要件を満たすために、buildディレクトリを活用する方法を採用しました。

プロジェクト構造

以下のようなプロジェクト構造を採用しました:

my-project/
├── cmd/
│   ├── app1/
│   │   └── main.go
│   └── app2/
│       └── main.go
├── internal/
├── pkg/
├── proto/            # Protocol Buffers定義ファイル
│   └── service.proto
├── build/
│   ├── linux/
│   ├── windows/
│   ├── darwin/
│   └── proto/
├── scripts/
│   └── clean.sh
├── go.mod
└── README.md
  • proto/: Protocol Buffersの定義を格納。
  • build/proto/: 自動生成されたProtocol Buffersコードを保存。
  • build/linux/build/windows/build/darwin/: 各OS向けバイナリを格納。

バイナリ生成と管理

Makefileでの管理

Makefileを使用して、以下のようなタスクを簡単に実行できるようにしました:

build-linux:
    GOOS=linux GOARCH=amd64 go build -o build/linux/app1 cmd/app1/main.go

build-windows:
    GOOS=windows GOARCH=amd64 go build -o build/windows/app1.exe cmd/app1/main.go

build-darwin:
    GOOS=darwin GOARCH=amd64 go build -o build/darwin/app1

proto-gen:
    protoc --go_out=build/proto --go-grpc_out=build/proto proto/service.proto

clean:
    rm -rf build/

Makefile実行例

  • Linux用バイナリの生成:
make build-linux
  • Protocol Buffersコードの生成:
make proto-gen
  • すべての生成物を削除:
make clean

CI/CDパイプラインでの運用

GitHub Actionsでの設定

GitHub Actionsを使用して、ビルドと生成物の共有を自動化しました。以下は、GitHub Actionsの設定例です:

name: Build and Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: '1.20'
      - name: Build binaries
        run: |
          mkdir -p build/linux build/windows build/darwin
          GOOS=linux GOARCH=amd64 go build -o build/linux/app1 cmd/app1/main.go
          GOOS=windows GOARCH=amd64 go build -o build/windows/app1.exe cmd/app1/main.go
          GOOS=darwin GOARCH=amd64 go build -o build/darwin/app1
      - name: Generate Proto Code
        run: protoc --go_out=build/proto --go-grpc_out=build/proto proto/service.proto
      - name: Upload Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: build/

成果物のダウンロードと利用


GitHub Actionsが生成した成果物をダウンロードすることで、他の環境で簡単に利用可能にしました。

成果と利点

  1. 効率的なバイナリ管理: プラットフォームごとに整理されたバイナリで、開発者全員が必要なバージョンを簡単に利用可能。
  2. 生成コードの分離: Protocol Buffersのコードをbuild/protoに分離し、プロジェクト構造をクリーンに保つ。
  3. 自動化によるミス防止: MakefileやCI/CDの利用で、手作業によるエラーを排除。

まとめ


実際のGoプロジェクトでbuildディレクトリを活用することで、生成物の管理が容易になり、開発効率が大幅に向上します。一貫性のある構造を採用し、自動化ツールを適切に活用することが、効果的なプロジェクト運用の鍵です。

開発環境における`build`ディレクトリのトラブルシューティング

buildディレクトリを使用したプロジェクト管理は非常に便利ですが、運用中にさまざまな問題が発生することがあります。このセクションでは、buildディレクトリに関する一般的なトラブルとその解決方法を紹介します。

よくある問題と解決方法

1. 生成物が期待通りに配置されない

原因: ビルドスクリプトやMakefileの設定ミス、または相対パスの誤りが原因で生成物が正しいディレクトリに配置されないことがあります。

解決策:

  • 出力パスを明示する: -oオプションを使用して生成物の出力先を明示します。

例:

go build -o build/linux/my-app
  • パスを確認する: Makefileやスクリプト内のディレクトリ指定が正しいか確認します。

防止策:

  • Makefileやスクリプトで統一したディレクトリ構造を採用する。
  • 生成物のパスを環境変数として管理し、スクリプト内で再利用する。

2. `build`ディレクトリに不要なファイルが蓄積する

原因: 古い生成物が残ったまま新しい生成物と混在することで、管理が煩雑になる。

解決策:

  • 定期的なクリーンアップ: 不要な生成物を削除するスクリプトを用意します。

例:

rm -rf build/*
  • Makefileでの自動化:
clean:
    rm -rf build/
  • CI/CDパイプラインでのクリーンアップ: ビルドの前にbuildディレクトリをクリアするタスクを追加します。

3. 複数のプラットフォーム向け生成物の混乱

原因: 異なるプラットフォーム向けのバイナリが混在し、正しいバージョンを選択するのが困難になる。

解決策:

  • サブディレクトリで整理: 各プラットフォームごとにサブディレクトリを作成します。

例:

build/
├── linux/
├── windows/
└── darwin/
  • 命名規則を統一: 生成物にプラットフォーム情報を付与します。

例:

my-app_linux_amd64
my-app_windows_amd64.exe

4. ファイルのバージョン管理で競合が発生する

原因: チーム開発中にbuildディレクトリの生成物がGitリポジトリに含まれていると、競合が発生することがあります。

解決策:

  • .gitignoreを設定する:
# Ignore build directory
build/
  • 生成物をバージョン管理しないポリシーを徹底する: バイナリや生成コードはリポジトリに含めず、リモートのアーティファクトリポジトリやCI/CDで管理します。

5. バイナリが実行時にエラーを出す

原因: ビルド時の環境設定ミス、または外部ライブラリの依存関係が正しく解決されていない可能性があります。

解決策:

  • 環境変数を確認: クロスコンパイル時のGOOSGOARCHの設定を確認します。
  • 静的リンクの有効化: 外部依存を削減するために静的リンクを使用します。

例:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o build/linux/my-static-app
  • ランタイムエラーをデバッグ: 実行時のエラーが発生した場合、詳細なログを確認して原因を特定します。

トラブルシューティングのプロセス

  1. 問題の再現手順を確認する: 発生した問題が再現可能か確認します。
  2. ログを調査する: ビルドや実行時のログを詳細に確認し、エラー内容を分析します。
  3. スクリプトやMakefileをレビューする: 設定ミスやタイポがないか見直します。
  4. ドキュメントを参照する: 使用しているツールやコマンドの公式ドキュメントを確認し、正しい設定方法を確認します。
  5. テストを実行する: 修正後、問題が解決しているかテストします。

まとめ

buildディレクトリの運用では、適切な整理とトラブルシューティングが重要です。ファイルの配置や命名規則、不要なファイルの削除を自動化することで、開発環境をスムーズに運用できます。問題が発生した際には、エラーログやスクリプトを確認し、原因を特定して迅速に対応することがプロジェクト成功の鍵となります。

まとめ

本記事では、Go言語のプロジェクトにおけるbuildディレクトリの活用方法を詳しく解説しました。buildディレクトリを利用することで、生成物を効率的に管理し、プロジェクトの整然性とチーム作業の効率性を大幅に向上させることができます。

特に、ディレクトリ構造の整理、go buildコマンドのカスタマイズ、生成物の削除の自動化、そしてチームでの共有戦略の実践が、プロジェクト運用の成功に直結します。さらに、具体的なトラブルシューティングの手法も取り上げ、buildディレクトリに関する問題への対応力を高めました。

これらの知識とベストプラクティスを活用して、Goプロジェクトの管理を一段と効率化し、スムーズな開発環境を構築してください。

コメント

コメントする

目次