Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,33 @@ jobs:
- name: Build main target
shell: bash
run: |
cmake --build cmake-build-release --target QtCMake
cmake --build cmake-build-release --target QtBoostCMake

- name: Run program
shell: bash
working-directory: ./cmake-build-release/bin
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
./QtCMake.exe --help
./QtBoostCMake.exe --help
else
./QtCMake --help
./QtBoostCMake --help
fi
- name: Build tests
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
cmake --build ./cmake-build-release --target QtCMake_tests || echo "Built with errors"
cmake --build ./cmake-build-release --target QtBoostCMake_tests || echo "Built with errors"
else
cmake --build ./cmake-build-release --target QtCMake_tests
cmake --build ./cmake-build-release --target QtBoostCMake_tests
fi
- name: Run tests
shell: bash
working-directory: ./cmake-build-release/tests
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
./QtCMake_tests.exe || echo "Tests failed" # Due to a specific MinGW-related Github Actions issue
./QtBoostCMake_tests.exe || echo "Tests failed" # Due to a specific MinGW-related Github Actions issue
else
./QtCMake_tests
./QtBoostCMake_tests
fi

style-check:
Expand Down Expand Up @@ -158,11 +158,12 @@ jobs:
sudo apt-get update
# Install a C++23-capable toolchain and clang-tidy-19 for better C++23 support
sudo apt-get -y install clang-19 clang-tidy-19
- name: Install Qt dependencies for Linux
- name: Install Qt and Boost
run: |
sudo apt update
sudo apt install libgl1-mesa-dev libglu1-mesa-dev
sudo apt install qt6-base-dev
sudo apt install libboost-all-dev

- name: Create CMake cache
run: |
Expand Down
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.25)

project(
QtCMake
VERSION 1.1.0
DESCRIPTION "CMake project for easy Qt connection to other CMake projects"
QtBoostCMake
VERSION 1.0.0
DESCRIPTION "CMake project for easy Qt and Boost connection to other CMake projects"
LANGUAGES CXX
)

Expand All @@ -29,7 +29,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS_DEBUG "/MDd")
set(CMAKE_CXX_FLAGS_RELEASE "/O2")
else ()
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
if (WIN32)
set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -lwsock32 -lws2_32 ${CMAKE_CXX_STANDARD_LIBRARIES}")
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# QtCMake
A C++ project template with Qt6 and CMake that downloads and compiles Qt.
The resulting app is an executable that can be run on a system without Qt.
# QtBoostCMake

A C++ project template with Qt6, Boost, Google Tests and CMake that downloads and compiles Qt and Boost.
The resulting app is an executable that can be run on a system without Qt and Boost.

The main Qt6 configuration is found in the [correspondent](lib/qt/CMakeLists.txt) CMakeLists.txt file.
The main Boost configuration is found in the [correspondent](lib/boost/CMakeLists.txt) CMakeLists.txt file.
The main Google Tests configuration is found in the [correspondent](tests/CMakeLists.txt) CMakeLists.txt file.

> Note that statically compiled Qt6 weights more than 5 GB.
> The good thing is that user does not need whole compiled Qt6 with this configuration.
Expand Down
16 changes: 12 additions & 4 deletions bin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
set(Boost_NO_SYSTEM_PATHS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(BOOST_ALL_DYN_LINK OFF)

if (NOT Boost_ROOT AND EXISTS $ENV{BOOSTROOT})
set(Boost_ROOT $ENV{BOOSTROOT})
endif()

message(STATUS "Qt6 directory: $ENV{QTDIR}")
set(QT_BIN_DIR "$ENV{QTDIR}/bin")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
find_package(Boost REQUIRED)

if (WIN32)
add_executable(${PROJECT_NAME} WIN32
Expand All @@ -13,4 +21,4 @@ else ()
)
endif ()

target_link_libraries(${PROJECT_NAME} PRIVATE qt)
target_link_libraries(${PROJECT_NAME} PRIVATE qt boost)
5 changes: 5 additions & 0 deletions bin/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <iostream>

#include <boost/filesystem.hpp>

#include <QApplication>
#include <QDateTime>
#include <QLCDNumber>
Expand All @@ -14,6 +16,9 @@ static constexpr const char* kFormat = "hh:mm:ss";
} // namespace

int main(int argc, char** argv) {
// Boost.Filesystem (requires linking)
std::cout << "CWD: " << boost::filesystem::current_path().string() << "\n";

if (argc > 1) {
std::cout << "No CLI arguments allowed.\n";
return 0;
Expand Down
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ cmake_minimum_required(VERSION 3.25)

if(NOT TESTS_ONLY)
add_subdirectory(qt)
add_subdirectory(boost)
endif()
100 changes: 100 additions & 0 deletions lib/boost/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Error if building out of a build directory
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
if(EXISTS "${LOC_PATH}")
message(FATAL_ERROR "You cannot build in a source directory (or any directory with "
"CMakeLists.txt file). Please make a build subdirectory. Feel free to "
"remove CMakeCache.txt and CMakeFiles.")
endif()

set(BOOST_VERSION "1.83.0")
set(BOOST_VERSION_UNDERSCORE "1_83_0")
set(BOOST_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/boost_${BOOST_VERSION_UNDERSCORE}")
# b2 stage (default) puts libs in <source>/stage/lib or stage/lib/<variant>/, headers stay in <source>
set(BOOST_STAGE_DIR "${BOOST_SOURCE_DIR}/stage")
set(BOOST_STAGE_LIB_DIR "${BOOST_SOURCE_DIR}/stage/lib")
set(ENV{BOOSTROOT} ${BOOST_SOURCE_DIR})

# If we already built Boost here (stage), use it directly and skip find_package/build
if(EXISTS "${BOOST_SOURCE_DIR}/boost/version.hpp")
if(EXISTS "${BOOST_STAGE_DIR}")
set(Boost_ROOT ${BOOST_SOURCE_DIR})
endif()
endif()

find_package(Boost 1.83 QUIET)

if(NOT Boost_FOUND)
message(STATUS "Boost not found. Downloading and building Boost...")

set(BOOST_ARCHIVE_URL "https://archives.boost.io/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_UNDERSCORE}.tar.gz")
set(BOOST_ARCHIVE_FILE "${CMAKE_CURRENT_BINARY_DIR}/boost_${BOOST_VERSION_UNDERSCORE}.tar.gz")

message(STATUS "Downloading Boost from archives.boost.io...")
file(DOWNLOAD ${BOOST_ARCHIVE_URL} ${BOOST_ARCHIVE_FILE}
SHOW_PROGRESS)

message(STATUS "Unpacking the archive...")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ${BOOST_ARCHIVE_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
OUTPUT_QUIET
)

message(STATUS "Running bootstrap...")
if(WIN32)
execute_process(COMMAND "${BOOST_SOURCE_DIR}/bootstrap.bat" gcc
WORKING_DIRECTORY ${BOOST_SOURCE_DIR})
set(B2_EXECUTABLE "${BOOST_SOURCE_DIR}/b2.exe")
else()
execute_process(COMMAND "${BOOST_SOURCE_DIR}/bootstrap.sh" --with-toolset=gcc
WORKING_DIRECTORY ${BOOST_SOURCE_DIR})
set(B2_EXECUTABLE "${BOOST_SOURCE_DIR}/b2")
endif()

message(STATUS "Building Boost with b2 stage (this may take a long time)...")
execute_process(
COMMAND ${B2_EXECUTABLE} stage
toolset=gcc
address-model=64
link=static
runtime-link=static
threading=multi
--layout=versioned
--build-type=complete
WORKING_DIRECTORY ${BOOST_SOURCE_DIR}
)

set(Boost_ROOT "${BOOST_SOURCE_DIR}")
find_package(Boost 1.83 QUIET)
else()
message(STATUS "Boost found in the system.")
endif()

# When using our staged Boost, FindBoost does not set Boost_LIBRARIES; collect built libs from stage.
# b2 --build-type=complete produces both release (-mt-s-) and debug (-mt-sd-) variants; link only one
# to avoid multiple definition errors.
if(Boost_FOUND AND EXISTS "${BOOST_STAGE_LIB_DIR}")
file(GLOB_RECURSE _stage_libs "${BOOST_STAGE_LIB_DIR}/*.a" "${BOOST_STAGE_LIB_DIR}/*.lib")
if(_stage_libs)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(FILTER _stage_libs INCLUDE REGEX "[-]mt[-]sd[-]|[-]sgd[-]")
else()
list(FILTER _stage_libs EXCLUDE REGEX "[-]mt[-]sd[-]|[-]sgd[-]")
endif()
set(Boost_LIBRARIES ${_stage_libs})
endif()
elseif(Boost_FOUND)
set(Boost_LIBRARIES boost_filesystem boost_system boost_chrono boost_date_time boost_regex boost_program_options boost_serialization boost_thread boost_wave boost_iostreams boost_locale boost_unit_test_framework boost_wave boost_iostreams boost_locale boost_unit_test_framework)
if(LINUX)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
endif()
endif()
# Do not pass NOTFOUND to the linker
if(Boost_LIBRARIES)
list(FILTER Boost_LIBRARIES EXCLUDE REGEX "NOTFOUND$")
endif()

add_library(boost INTERFACE)
target_include_directories(boost INTERFACE ${Boost_INCLUDE_DIRS})
if(Boost_LIBRARIES)
target_link_libraries(boost INTERFACE ${Boost_LIBRARIES})
endif()