# Project Structure
Complete guide to CCGO project organization and directory structure.
## Overview
CCGO projects follow a standardized structure:
- **Source code**: `src/` for implementation, `include/` for headers
- **Tests**: `tests/` for unit tests
- **Benchmarks**: `benches/` for performance tests
- **Documentation**: `docs/` for Doxygen/Sphinx docs
- **Configuration**: `CCGO.toml` for project settings
- **Build outputs**: `target/` for compiled binaries
## Standard Project Layout
```
myproject/
├── CCGO.toml # Project configuration
├── CMakeLists.txt # CMake configuration (generated)
├── build_config.py # Build-specific settings (generated)
├── .ccgoignore # Files to exclude from CCGO operations
├── README.md # Project documentation
├── LICENSE # License file
├── .gitignore # Git ignore rules
│
├── include/ # Public headers
│ └── myproject/
│ ├── myproject.h # Main header
│ ├── version.h # Version info (generated)
│ └── feature.h # Feature-specific headers
│
├── src/ # Implementation files
│ ├── myproject.cpp # Main implementation
│ ├── feature.cpp # Feature implementations
│ └── internal/ # Private implementation
│ └── utils.cpp
│
├── tests/ # Unit tests
│ ├── test_main.cpp # Test runner
│ ├── test_myproject.cpp # Tests for main module
│ └── test_feature.cpp # Tests for features
│
├── benches/ # Benchmarks
│ ├── bench_main.cpp # Benchmark runner
│ └── bench_performance.cpp # Performance benchmarks
│
├── docs/ # Documentation
│ ├── Doxyfile # Doxygen configuration
│ ├── api/ # API documentation
│ └── guides/ # User guides
│
├── examples/ # Example applications (optional)
│ ├── basic/
│ │ └── main.cpp
│ └── advanced/
│ └── main.cpp
│
├── cmake_build/ # CMake build directory (generated)
│ ├── android/
│ ├── ios/
│ ├── linux/
│ └── windows/
│
└── target/ # Build outputs (generated)
├── android/
├── ios/
├── linux/
└── windows/
```
## Directory Details
### Root Files
#### CCGO.toml
**Purpose:** Main project configuration file.
**Content:**
```toml
[package]
name = "myproject"
version = "1.0.0"
description = "My C++ project"
[library]
type = "both"
[build]
cpp_standard = "17"
[dependencies]
spdlog = { git = "https://github.com/gabime/spdlog.git", tag = "v1.12.0" }
```
**See:** [Configuration Guide](configuration.md)
#### CMakeLists.txt
**Purpose:** CMake configuration (auto-generated by CCGO).
**Content:**
```cmake
cmake_minimum_required(VERSION 3.20)
project(myproject VERSION 1.0.0)
# CCGO cmake utilities
include(${CCGO_CMAKE_DIR}/CMakeUtils.cmake)
# Add subdirectories
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(benches)
```
**Note:** Do not edit manually - regenerated on each build.
#### build_config.py
**Purpose:** Build-specific settings (auto-generated).
**Content:**
```python
PROJECT_NAME = "myproject"
PROJECT_VERSION = "1.0.0"
BUILD_TYPE = "release"
CPP_STANDARD = "17"
```
**Usage:** Used by build scripts internally.
#### .ccgoignore
**Purpose:** Exclude files from CCGO operations.
**Content:**
```
# Build directories
cmake_build/
target/
bin/
# IDE files
.vscode/
.idea/
# Generated files
*.pyc
```
**See:** [Configuration Guide - .ccgoignore](configuration.md#ccgoignore)
### include/
**Purpose:** Public header files that users of your library will include.
**Structure:**
```
include/
└── myproject/ # Namespace directory (required)
├── myproject.h # Main header
├── version.h # Version info (generated)
├── config.h # Configuration (generated)
├── feature_a.h # Feature headers
├── feature_b.h
└── internal/ # Internal headers (not for public use)
└── impl.h
```
**Guidelines:**
1. **Namespace directory:** Always use a subdirectory matching your project name
```cpp
#include <myproject/myproject.h>
#include <myproject.h>
```
2. **Header guards:** Use `#pragma once` or traditional guards
```cpp
#pragma once
namespace myproject {
}
```
3. **Version header:** Auto-generated with version info
```cpp
#pragma once
#define MYPROJECT_VERSION_MAJOR 1
#define MYPROJECT_VERSION_MINOR 0
#define MYPROJECT_VERSION_PATCH 0
#define MYPROJECT_VERSION "1.0.0"
```
4. **Minimize includes:** Only include what's necessary
```cpp
class FeatureA;
#include "feature_a.h"
```
### src/
**Purpose:** Implementation files (.cpp, .cc, .cxx).
**Structure:**
```
src/
├── myproject.cpp # Main implementation
├── feature_a.cpp # Feature implementations
├── feature_b.cpp
├── internal/ # Private implementation
│ ├── utils.cpp
│ └── platform/ # Platform-specific code
│ ├── android.cpp
│ ├── ios.cpp
│ └── linux.cpp
└── CMakeLists.txt # Generated by CCGO
```
**Guidelines:**
1. **One class per file:** Keep files focused
```
src/
├── feature_a.cpp # FeatureA implementation
└── feature_b.cpp # FeatureB implementation
```
2. **Private headers:** Use internal/ for private headers
```cpp
#pragma once
```
3. **Platform-specific code:** Use subdirectories or conditional compilation
```cpp
#ifdef __ANDROID__
#include "platform/android.cpp"
#elif defined(__APPLE__)
#include "platform/ios.cpp"
#endif
void platform_init() {
#ifdef __ANDROID__
#elif defined(__APPLE__)
#endif
}
```
### tests/
**Purpose:** Unit tests using Catch2 or Google Test.
**Structure:**
```
tests/
├── test_main.cpp # Test runner
├── test_myproject.cpp # Tests for main module
├── test_feature_a.cpp # Feature-specific tests
├── test_feature_b.cpp
└── CMakeLists.txt # Generated by CCGO
```
**Example test file:**
```cpp
// test_myproject.cpp
#include <catch2/catch_test_macros.hpp>
#include <myproject/myproject.h>
TEST_CASE("Basic functionality", "[myproject]") {
myproject::MyClass obj;
REQUIRE(obj.get_value() == 42);
}
TEST_CASE("Feature A", "[feature_a]") {
myproject::FeatureA feature;
REQUIRE(feature.is_enabled());
}
```
**Test runner:**
```cpp
// test_main.cpp
#define CATCH_CONFIG_MAIN
#include <catch2/catch_test_macros.hpp>
```
**Running tests:**
```bash
ccgo test # Run all tests
ccgo test --filter "Basic" # Run specific test
```
### benches/
**Purpose:** Performance benchmarks using Google Benchmark.
**Structure:**
```
benches/
├── bench_main.cpp # Benchmark runner
├── bench_performance.cpp # Performance benchmarks
├── bench_feature_a.cpp # Feature-specific benchmarks
└── CMakeLists.txt # Generated by CCGO
```
**Example benchmark:**
```cpp
// bench_performance.cpp
#include <benchmark/benchmark.h>
#include <myproject/myproject.h>
static void BM_MyFunction(benchmark::State& state) {
myproject::MyClass obj;
for (auto _ : state) {
obj.do_work();
}
}
BENCHMARK(BM_MyFunction);
BENCHMARK_MAIN();
```
**Running benchmarks:**
```bash
ccgo bench # Run all benchmarks
ccgo bench --filter "MyFunc" # Run specific benchmark
```
### docs/
**Purpose:** Documentation source files.
**Structure:**
```
docs/
├── Doxyfile # Doxygen configuration
├── README.md # Documentation overview
├── api/ # API documentation
│ └── reference.md
├── guides/ # User guides
│ ├── getting-started.md
│ └── advanced.md
└── images/ # Documentation images
└── architecture.png
```
**Generating docs:**
```bash
ccgo doc # Generate documentation
ccgo doc --open # Generate and open in browser
```
### examples/
**Purpose:** Example applications showing how to use your library.
**Structure:**
```
examples/
├── basic/ # Simple example
│ ├── main.cpp
│ └── CMakeLists.txt
├── advanced/ # Advanced usage
│ ├── main.cpp
│ └── CMakeLists.txt
└── README.md # Examples documentation
```
**Example application:**
```cpp
// examples/basic/main.cpp
#include <myproject/myproject.h>
#include <iostream>
int main() {
myproject::MyClass obj;
std::cout << "Value: " << obj.get_value() << std::endl;
return 0;
}
```
**Building examples:**
```cmake
# examples/basic/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(basic_example)
find_package(myproject REQUIRED)
add_executable(basic main.cpp)
target_link_libraries(basic myproject::myproject)
```
### cmake_build/
**Purpose:** CMake build artifacts (generated, not committed to git).
**Structure:**
```
cmake_build/
├── android/ # Android build files
│ ├── armeabi-v7a/
│ ├── arm64-v8a/
│ └── x86_64/
├── ios/ # iOS build files
│ ├── arm64/
│ └── x86_64/
├── linux/ # Linux build files
├── windows/ # Windows build files
└── macos/ # macOS build files
```
**Note:** Add to `.gitignore`:
```
cmake_build/
```
### target/
**Purpose:** Final build outputs (generated).
**Structure:**
```
target/
├── android/ # Android outputs
│ └── MyProject_Android_SDK-1.0.0.zip
├── ios/ # iOS outputs
│ └── MyProject_iOS_SDK-1.0.0.zip
├── linux/ # Linux outputs
│ └── MyProject_Linux_SDK-1.0.0.zip
├── windows/ # Windows outputs
│ └── MyProject_Windows_SDK-1.0.0.zip
└── doc/ # Documentation
└── html/
```
**Note:** Add to `.gitignore`:
```
target/
```
## File Naming Conventions
### Header Files
```
include/myproject/
├── myproject.h # Main header (lowercase, matches project)
├── feature_a.h # Feature headers (lowercase, underscores)
├── my_class.h # Class headers (lowercase, underscores)
└── constants.h # Utility headers
```
### Source Files
```
src/
├── myproject.cpp # Matches header name
├── feature_a.cpp
├── my_class.cpp
└── internal/
└── utils.cpp # Private utilities
```
### Test Files
```
tests/
├── test_myproject.cpp # Prefix with "test_"
├── test_feature_a.cpp
└── test_my_class.cpp
```
### Benchmark Files
```
benches/
├── bench_performance.cpp # Prefix with "bench_"
├── bench_feature_a.cpp
└── bench_algorithms.cpp
```
## Multi-Module Projects
For projects with multiple libraries:
```
workspace/
├── CCGO.toml # Workspace configuration (optional)
├── lib_core/ # Core library
│ ├── CCGO.toml
│ ├── include/
│ └── src/
├── lib_utils/ # Utilities library
│ ├── CCGO.toml
│ ├── include/
│ └── src/
└── app/ # Application
├── CCGO.toml
├── src/
└── main.cpp
```
**Workspace CCGO.toml:**
```toml
[workspace]
members = [
"lib_core",
"lib_utils",
"app"
]
```
**Module dependencies:**
```toml
# app/CCGO.toml
[dependencies]
lib_core = { path = "../lib_core" }
lib_utils = { path = "../lib_utils" }
```
## Platform-Specific Files
### Android
```
project/
├── android/ # Android-specific files (optional)
│ ├── gradle.properties
│ └── proguard-rules.pro
└── CCGO.toml
[android]
min_sdk_version = 21
```
### iOS
```
project/
├── ios/ # iOS-specific files (optional)
│ ├── Info.plist
│ └── Entitlements.plist
└── CCGO.toml
[ios]
deployment_target = "12.0"
```
### Windows
```
project/
├── windows/ # Windows-specific files (optional)
│ ├── resource.rc
│ └── app.manifest
└── CCGO.toml
[windows]
subsystem = "console"
```
## Best Practices
### 1. Consistent Naming
Use consistent naming conventions:
```
# Good - consistent lowercase with underscores
include/mylib/my_feature.h
src/my_feature.cpp
tests/test_my_feature.cpp
# Bad - inconsistent casing
include/mylib/MyFeature.h
src/my_feature.cpp
tests/TestMyFeature.cpp
```
### 2. Organize by Feature
Group related files:
```
src/
├── networking/ # Networking feature
│ ├── client.cpp
│ ├── server.cpp
│ └── protocol.cpp
└── database/ # Database feature
├── connection.cpp
└── query.cpp
```
### 3. Separate Public and Private
Keep API surface clean:
```
include/
└── mylib/
├── public_api.h # Public API only
└── internal/ # Internal details
└── impl.h
```
### 4. Documentation Near Code
Keep documentation close to source:
```
src/
├── feature_a/
│ ├── feature_a.cpp
│ ├── feature_a.h
│ └── README.md # Feature documentation
```
### 5. Examples Are Tests
Examples should compile and run:
```
examples/
└── basic/
├── main.cpp # Working example
├── CMakeLists.txt # Build configuration
└── README.md # How to run
```
## .gitignore Template
Recommended `.gitignore` for CCGO projects:
```gitignore
# Build directories
cmake_build/
target/
bin/
build/
# IDE files
.vscode/
.idea/
*.swp
*.swo
*~
# OS files
.DS_Store
Thumbs.db
desktop.ini
# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/
# Generated files
*.autosave
*.user
*.log
# Dependencies
vendor/
```
## Migration from Existing Projects
### From CMake Project
1. **Create CCGO.toml:**
```bash
ccgo init
```
2. **Copy source files:**
```bash
mkdir -p include/mylib src
cp src/*.h include/mylib/
cp src/*.cpp src/
```
3. **Configure CCGO.toml:**
```toml
[package]
name = "mylib"
version = "1.0.0"
[build]
cpp_standard = "17"
```
4. **Build:**
```bash
ccgo build linux
```
### From Header-Only Library
1. **Keep headers in include/:**
```
include/
└── mylib/
├── mylib.h
└── impl.h
```
2. **Configure as header-only:**
```toml
[library]
type = "header-only"
```
### From Multiple CMakeLists.txt
1. **Merge into CCGO structure:**
```
Old:
project/
├── CMakeLists.txt
├── module1/
│ └── CMakeLists.txt
└── module2/
└── CMakeLists.txt
New:
project/
├── CCGO.toml
├── module1/
│ ├── CCGO.toml
│ └── src/
└── module2/
├── CCGO.toml
└── src/
```
2. **Use workspace:**
```toml
# Root CCGO.toml
[workspace]
members = ["module1", "module2"]
```
## Common Patterns
### Library with Examples
```
mylib/
├── CCGO.toml
├── include/
├── src/
├── tests/
└── examples/
├── basic/
├── advanced/
└── integration/
```
### Library with Tools
```
mylib/
├── CCGO.toml
├── include/
├── src/
├── tests/
└── tools/
├── converter/
└── analyzer/
```
### Library with Plugins
```
mylib/
├── CCGO.toml
├── include/
├── src/
├── plugins/
│ ├── plugin_a/
│ └── plugin_b/
└── tests/
```
## See Also
- [Installation Guide](installation.md)
- [Configuration Guide](configuration.md)
- [Build System](../features/build-system.md)
- [CCGO.toml Reference](../reference/ccgo-toml.md)