Releasing software can often feel like navigating a labyrinth of tools, configurations, and best practices. As a C++ developer, ensuring that your project is easily accessible and installable for users across different platforms is paramount. In this blog post, I'll walk you through the process I undertook to release my C++ project, EnglishFormatter, using CMake and Vcpkg. I'll share the tools I chose, the step-by-step release process, the lessons learned, the adjustments made to my project, insights from user testing, and comprehensive instructions for users to install and utilize the tool.
Table of Contents
- Choosing the Right Tools
- Process for Creating a Release
- Lessons Learned
- Adjustments Made to the Project
- User Testing with macOS
- Installing and Using EnglishFormatter
- Conclusion
- Resources and Links
Choosing the Right Tools
Selecting the appropriate tools is crucial for a smooth release process. For EnglishFormatter, I opted for:
- CMake: A versatile build system generator that simplifies the build process across different platforms.
- Vcpkg: A C++ library manager that handles dependencies efficiently, ensuring reproducible builds.
- GitHub Releases: Leveraging GitHub's built-in release management to distribute binaries and source code.
Links:
Process for Creating a Release
1. Setting Up the Project with CMake
CMake was chosen as the build system due to its cross-platform capabilities and seamless integration with various package managers. Here's how I configured CMake for EnglishFormatter:
- CMakeLists.txt: Defined the project, set the C++ standard to C++20, and specified the toolchain file for Vcpkg.
cmake_minimum_required(VERSION 3.20)
# Enable Vcpkg manifest mode before the project command
set(VCPKG_MANIFEST_MODE ON CACHE BOOL "Enable Vcpkg manifest mode")
project(EnglishFormatter VERSION 1.0.0 LANGUAGES CXX)
# Set C++ standard to C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# ------------------------
# Core Library Configuration
# ------------------------
# Collect all source files for the core library, excluding cli.cpp
file(GLOB CORE_SOURCES CONFIGURE_DEPENDS cli_app/src/*.cpp)
# Exclude cli.cpp from CORE_SOURCES to prevent multiple main definitions
list(FILTER CORE_SOURCES EXCLUDE REGEX ".*/cli\\.cpp$")
# Define the core library
add_library(core_lib STATIC ${CORE_SOURCES})
# Include directories for the core library
target_include_directories(core_lib PUBLIC cli_app/include)
# Find and link CURL and fmt libraries
find_package(CURL REQUIRED)
find_package(fmt REQUIRED)
target_link_libraries(core_lib PUBLIC CURL::libcurl fmt::fmt)
# ------------------------
# GoogleTest and GoogleMock Configuration
# ------------------------
include(FetchContent)
# Fetch GoogleTest (which includes GoogleMock)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
# Prevent overriding the parent project's compiler/linker settings
if(MSVC)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
endif()
# Enable building GMock and GTest
set(BUILD_GMOCK ON CACHE BOOL "" FORCE)
set(BUILD_GTEST ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
# Enable testing before defining tests
enable_testing()
# ------------------------
# Main Executable Configuration
# ------------------------
# Define the main executable and link it against the core library
add_executable(EnglishFormatter cli_app/src/cli.cpp)
target_link_libraries(EnglishFormatter PRIVATE core_lib)
# ------------------------
# Test Executable Configuration
# ------------------------
# Collect all test source files
file(GLOB TEST_SOURCES CONFIGURE_DEPENDS cli_app/tests/*.cpp)
# Define the test executable
add_executable(EnglishFormatterTests ${TEST_SOURCES})
# Include directories for tests
target_include_directories(EnglishFormatterTests PRIVATE cli_app/include)
# Link test executable against GMock, GTest, GTest main, and the core library
target_link_libraries(EnglishFormatterTests
PRIVATE
gmock
gtest
gtest_main
core_lib
)
# Register the tests
add_test(NAME EnglishFormatterTests COMMAND EnglishFormatterTests)
2. Managing Dependencies with Vcpkg
Vcpkg was instrumental in managing the project's dependencies, ensuring that all required libraries were correctly installed and linked. Here's how I integrated Vcpkg:
- Installing Vcpkg:
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
- Installing Dependencies:
./vcpkg install curl fmt
- Using Vcpkg with CMake:
When configuring the project with CMake, I specified the toolchain file provided by Vcpkg:
cmake .. -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
Note: Replace path/to/vcpkg
with the actual path to your Vcpkg installation.
3. Configuring Git for Releases
Git tags are pivotal in marking specific points in the project's history, such as releases. Here's how I managed Git tags:
- Committing Changes:
git add .
git commit -m "Prepare for release 1.0.0"
- Creating an Annotated Tag:
git tag -a v1.0.0 -m "Release version 1.0.0"
- Pushing Tags to GitHub:
git push origin main
git push --follow-tags
This approach ensures that the release is clearly marked in the project's history and is easily accessible for future reference.
4. Building and Testing
With the project configured, the next step was to build and test it to ensure everything functioned as expected.
- Building the Project:
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build . --config Release
- Running Tests:
ctest --output-on-failure
This process verified that the core library and executables were correctly built and that the tests passed, ensuring the reliability of the release.
5. Publishing the Release on GitHub
Publishing the release on GitHub made it accessible to users and integrated with the project's version control.
- Creating a Release on GitHub:
- Navigate to the GitHub repository.
- Click on the "Releases" tab.
- Click "Draft a new release".
- Select the tag
v1.0.0
. - Provide a release title and description.
- Attach any build artifacts if necessary (e.g., binaries for different platforms).
- Click "Publish release".
This step officially marks the version 1.0.0
of EnglishFormatter as available for users to download and install.
Lessons Learned
Embarking on this release journey was both enlightening and challenging. Here are some key takeaways:
Importance of Proper Configuration Order: Setting variables like
CMAKE_TOOLCHAIN_FILE
andVCPKG_MANIFEST_MODE
before theproject()
command inCMakeLists.txt
was crucial. Misplacing these led to initial configuration issues.Managing Dependencies: Vcpkg simplified dependency management, but ensuring all dependencies were correctly listed in
vcpkg.json
prevented potential build issues.Git Tagging Best Practices: Using annotated tags with clear messages aids in maintaining a clean project history and facilitates easier rollbacks if needed.
Documentation is Key: Clear and comprehensive documentation in
README.md
ensures users can install and use the tool without hiccups.User Testing Insights: Real-world testing highlighted areas where documentation could be improved, emphasizing the need for user-centric documentation.
Adjustments Made to the Project
To accommodate the release process using CMake and Vcpkg, several modifications were necessary:
Integration of Vcpkg: Added
vcpkg.json
to manage dependencies and adjustedCMakeLists.txt
to enable Vcpkg manifest mode.Build Configuration: Configured output directories in CMake to organize binaries systematically.
Testing Setup: Incorporated GoogleTest and GoogleMock for unit testing, ensuring the core functionalities were reliable.
Documentation Enhancements: Expanded
README.md
with detailed installation, configuration, and usage instructions to guide users effectively.
These changes streamlined the build process, ensured dependency consistency, and enhanced the overall usability of EnglishFormatter.
User Testing with macOS
To validate the installation and usage instructions, I enlisted the help of a friend who uses macOS. Here's how the session unfolded:
Setup
-
Preparation: Shared the updated
README.md
with my friend, highlighting the installation steps. - Environment: My friend ensured they had CMake, Vcpkg, and a C++20-compatible compiler installed on their macOS system.
Testing Process
- Cloning the Repository:
git clone https://github.com/yourusername/EnglishFormatter.git
cd EnglishFormatter
- Setting Up Vcpkg:
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg install curl fmt
cd ..
- Configuring and Building the Project:
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build . --config Release
- Running the Application:
./EnglishFormatter
Observations and Feedback
- Smooth Installation: The installation steps were clear, and my friend was able to set up the environment without issues.
- Execution Clarity: Running the executable and navigating the interactive menu was straightforward.
- Minor Confusion: Initially, my friend was unsure about specifying the path to the Vcpkg toolchain file. Clarifying this step helped resolve the confusion.
- Documentation Improvements: Based on the feedback, I added more explicit instructions regarding the toolchain file path and included troubleshooting tips for common issues.
Corrections Made
- Toolchain File Path: Provided a clearer explanation of how to locate and specify the Vcpkg toolchain file during the CMake configuration.
- Environment Setup: Included additional details on ensuring that Vcpkg is correctly set up before building the project.
This user testing session was invaluable in refining the documentation, ensuring that users across different platforms can effortlessly install and utilize EnglishFormatter.
Installing and Using EnglishFormatter
With the release now live, users can easily install and use EnglishFormatter on their systems. Here's a comprehensive guide to get you started.
Installation Steps
- Install Vcpkg
Vcpkg is essential for managing dependencies. Follow these steps to install it:
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
For detailed instructions, refer to the Vcpkg Quick Start Guide.
- Clone the EnglishFormatter Repository
git clone https://github.com/yourusername/EnglishFormatter.git
cd EnglishFormatter
- Set Up the
.env
File
Create a .env
file in the project's root directory to store your API key:
API_KEY=your_api_key_here
Replace your_api_key_here
with your actual API key from your language model provider (e.g., OpenAI).
- Build the Project
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build . --config Release
Note: Ensure that the path to vcpkg
in the CMAKE_TOOLCHAIN_FILE
flag is correct based on your system setup.
Usage Instructions
Once built, you can use EnglishFormatter to format, summarize, or paraphrase your text documents.
Running via Command-Line Options
./EnglishFormatter [options]
Available Options:
-
-h, --help
: Show help message and exit. -
-v, --version
: Show the tool's version and exit. -
-m, --model MODEL
: Specify the language model to use (default: gpt-3.5-turbo). -
-o, --output SUFFIX
: Specify the output file suffix (default: _modified). -
-t, --token-usage
: Show token usage and exit.
Example:
Formatting documents with a specific model and output suffix:
./EnglishFormatter --model gpt-4 --output _formatted
Using the Interactive Menu
Simply run the executable without any arguments to access the interactive menu:
./EnglishFormatter
Menu Options:
- Format document: Improve the readability and structure of your text files.
- Summarize document: Generate concise summaries of your documents.
- Paraphrase document: Rephrase your text while retaining the original meaning.
- Exit: Close the application.
Navigation:
- Use the Up and Down arrow keys to navigate through the menu.
- Press Enter to select an option.
Processing Files:
- Select the desired action from the menu.
- When prompted, enter the names of the files you wish to process, separated by spaces.
- The tool will process each file and save the output with the specified suffix.
Conclusion
Releasing EnglishFormatter was a rewarding experience that underscored the importance of structured build systems, efficient dependency management, and comprehensive documentation. By leveraging CMake and Vcpkg, I ensured that the project is easily buildable across different platforms, making it accessible to a broader user base. The user testing session highlighted the significance of clear instructions, prompting necessary refinements to the documentation. As a result, users can now seamlessly install and utilize EnglishFormatter, enhancing their text processing tasks with advanced language models.
Resources and Links
- CMake Official Documentation
- Vcpkg Package Manager
- GitHub Releases
- GoogleTest Documentation
- nlohmann/json GitHub Repository
- dotenv-cpp GitHub Repository
- OpenAI API Documentation
- Github Repo
Feel free to reach out via the GitHub Issues page or contact me directly for any questions, suggestions, or support regarding EnglishFormatter.
Happy Formatting!
Top comments (0)