[Project logo]
[Cool PNGs to attract people]
[Project short info]
[Project usage example GIFs]
Prerequisites
-
- Conan –
pip install conan
- Conan –
-
C++ compiler that can compile Qt6 – needs to support the C++17 standard. Lists of viable compilers:
Run conanLibrariesInstall.sh
or conanLibrariesInstall.bat
, or simply execute these commands in the cloned repository's directory:
conan install conan/ --build=missing --settings=build_type=Debug
conan install conan/ --build=missing --settings=build_type=Release
Bash
cmake . -G [generator] -T [toolset] --build [PathToBuiltProject]
Example:
cmake . -G "Visual Studio 16 2019" -T v143 -Bbuild
GUI
The procedure is the standard one, but there are three things to be way of.
In-source builds are not allowed so these directories must differ:
You need to provide architecture and toolkit. If you leave them blank, project generation will likely fail. Also select option to specify the toolchain file:
If you did not tinker with Conan, the toolchain file should be found at conan/conan_toolchain.cmake
.
You can use your local IDE or CMake again:
cmake --build [pathToBuiltProject] --config [configuration] -j4 -DCMAKE_TOOLCHAIN_FILE=[pathToConanToolchainFile]
Example:
cmake --build build --config release -j4 -DCMAKE_TOOLCHAIN_FILE=conan/conan_toolchain.cmake
[List of features]
Add a new library
Simply modify cmake/Modules.cmake
:
set(QT_COMPONENTS Core {Other Qt6 libraries you want})
Example:
set(QT_COMPONENTS Core Gui Widgets)
Modify conan/conanfile.txt
:
[requires]
{Other libraries}
{New library's name from https://conan.io/center/}
Example:
[requires]
zlib/1.2.11
libcurl
Remember to run Conan after the changes:
conan install conan/ --build=missing --settings=build_type=Debug
conan install conan/ --build=missing --settings=build_type=Release
If the library cannot be found on ConanCenter, you could try going for Artifactory, but this requires some effort. You can always use plain CMake and modify CMakeLists.txt
, ChatGPT might help with such quick fixes.
Now the library should be available but might not be linked to the CMake project.
Check if the library has components. Libraries with components are libraries like Qt6 or Boost, in which you can choose to use a few of their all features.
Header-only library
Nothing needs to be done. Header-only libraries are already added in Conan toolchain file.
Library w/o components
Modify
cmake/Modules.cmake
:set(MODULES {Libraries})
Example:
set(MODULES ZLIB libcurl)
That's it!
Library with components
This is quite some work :<Add to
cmake/Modules.cmake
:set({NEW_VARIABLE_WITH_COMPONENTS} {COMPONENTS})
Example:
set(BOOST_COMPONENTS filesystem)
Modify
CMakeLists.txt
and after line7
:include(cmake/Modules.cmake)
add following code:foreach(library IN LISTS {NEW_VARIABLE_WITH_COMPONENTS}) find_package({LIBRARY_NAME} COMPONENTS ${library} REQUIRED) endforeach()
Example:
foreach(library IN LISTS BOOST_COMPONENTS) find_package(Boost COMPONENTS ${library} REQUIRED) endforeach()
In the same file, after line
135
:# Link libraries
add following code:foreach(library IN LISTS {NEW_VARIABLE_WITH_COMPONENTS}) target_link_libraries(${PROJECT_NAME} PRIVATE {LIBRARY_NAME}::${library}) if(${PROJECT_NAME}_BUILD_EXECUTABLE) target_link_libraries(${PROJECT_NAME}_LIB PRIVATE {LIBRARY_NAME}::${library}) endif() endforeach()
Example:
foreach(library IN LISTS BOOST_COMPONENTS) target_link_libraries(${PROJECT_NAME} PRIVATE Boost::${library}) if(${PROJECT_NAME}_BUILD_EXECUTABLE) target_link_libraries(${PROJECT_NAME}_LIB PRIVATE Boost::${library}) endif() endforeach()
You should also link the library to the test projects. To do that, modify
test/CMakeLists.txt
and after line53
:# Link libraries
add following code:foreach(library IN LISTS {NEW_VARIABLE_WITH_COMPONENTS}) target_link_libraries(${test_name}_Tests PRIVATE {LIBRARY_NAME}::${library}) endforeach()
Example:
foreach(library IN LISTS BOOST_COMPONENTS) target_link_libraries(${test_name}_Tests PRIVATE Boost::${library}) endforeach()
Change the project's name
To change the project's name, you must correct a few entries:
By default, the file starts with:CMakeLists.txt
cmake_minimum_required(VERSION 3.21) project("qt-template" LANGUAGES CXX)
Change
"qt-template"
to the name of your project.Example:
cmake_minimum_required(VERSION 3.21) project("myproject" LANGUAGES CXX)
If you host your project on a GitHub repository and wish to use GitHub Actions for automatic deployment, you must provide a name that matches the repository name. It has to be lowercase. Otherwise, you need to change
${{ steps.repoName.outputs.name }}
to your project's executable/library name (it is the CMake project name, unless you tinkered withCMakeLists.txt
) in these files:.github/workflows/macos.yml
.github/workflows/ubuntu.yml
.github/workflows/windows.yml
If the name contains whitespace characters, you will need to enclose the entire entry in either
"
or'
.
Example:files: build/install/${{ steps.repoName.outputs.name }}_macOS_${{ steps.versionTag.outputs.tag }}.tar.gz
Becomes:
files: "build/install/Parrots and Cats_macOS_${{ steps.versionTag.outputs.tag }}.tar.gz"
config.desktop
The
Exec
option should contain the project's executable/library name (it is CMake project name, unless you tinkered withCMakeLists.txt
), while theName
is up to your choice.Change these entries:
Name=Qt Template Exec=qt-template
Example:
Name=Parrots That Sing Exec=birds-and-stuff
Setup a Qt Quick project
Adding the "Quick" module to cmake/Modules.cmake
will activate additional CMake steps for QML processing:
set(QT_COMPONENTS Core [...] Quick)
The .qml
files should be placed in src/qml
(creating subdirectories is possible) and they can be accessed from qrc:/qt/qml/{project_name}/{relativePathToFile}
.
Example for a file src/qml/birds/Bird1.qml
and project name parrot_songs
:
qrc:/qt/qml/parrot_songs/birds/Bird1.qml
.
There is a commented snippet in src/main.cpp
with int main(int argc, char* argv[])
definition for Qt Quick, which contains example of accessing a QML file.
Qt6 is not found, despite being installed
Ensure that these environment variables are set properly:
-
Qt6_DIR -
[path_to_Qt]/[version]/[compiler]/lib/cmake/Qt6
Example:C:/Qt/6.5.1/msvc2019_64/lib/cmake/Qt6
-
Qt6GuiTools_DIR -
[path_to_Qt]/[version]/[compiler]/lib/cmake/Qt6GuiTools
Example:/usr/lib/x86_64-linux-gnu/6.5.1/clang_64/lib/cmake/Qt6GuiTools
-
Qt6CoreTools_DIR -
[path_to_Qt]/[version]/[compiler]/lib/cmake/Qt6CoreTools
Example:D:/Qt/6.3/msvc2019_64/lib/cmake/Qt6CoreTools
Missing or wrong architecture libraries | Conan profile errors
Ensure conan/conanfile.txt
has listed all the needed libraries under [requires]
section.
Run:
conan install conan/ --build=missing --settings=build_type=Debug
conan install conan/ --build=missing --settings=build_type=Release
In case of a wrong architecture of the libraries and other possible profile errors, read: https://docs.conan.io/2.0/reference/config_files/profiles.html
If you don't have a profile, create one:
conan profile detect
or:
conan profile new default --detect
Change the icon of the project
Put your icon image in PNG format into a folder icon/
and rename it, so it matches this convention:
icon_[width]x[height].png
Example:
icon_256x256.png
The resolution should be one of these:
- 16x16
- 32x32
- 48x48
- 64x64
- 128x128
- 256x256
Further below, I will mention some scripts that use ImageMagick, so you need to install it, if you want to use them. On Ubuntu, it can be done by:
sudo apt install imagemagick
Beware that depending on your OS version, you can get either ImageMagick 6 or ImageMagick 7. Unix scripts contain [script]_ImageMagick7.sh
versions, in case you did not obtain ImageMagick 6, but ImageMagick 7.
You can provide an icon with any resolution, and it will be rescaled to the other valid resolutions, if you use the script:
Windows
/icon/WinScripts/rescale.bat
Unix
/icon/UnixScripts/rescale.sh
or/icon/UnixScripts/rescale_ImageMagick7.sh
If there are multiple icons with different resolutions, the highest resolution will be used to create other valid icons. They will overwrite any already existing ones! If you want to use different icons for different resolutions, provide them manually and do not use the script.
This is sufficient for Linux, but there are two other scripts, so the Windows and macOS applications will have icons too.
To generate an icon for Windows, use:
Windows
/icon/WinScripts/createIco.bat
Unix
/icon/UnixScripts/createIco.sh
or/icon/UnixScripts/createIco_ImageMagick7.sh
macOS icon is slightly tricky to create on Windows, as we do not have a ready script. I recommend using WSL or another form of virtualization (i.e.: VirtualBox or Docker) and running the Unix script /icon/UnixScripts/createIcns.sh
.
If you are on macOS, you can do this the native way, using iconutil. Otherwise, run /icon/UnixScripts/createIcns.sh
, which requires png2icns
library. On Ubuntu you can install it by:
sudo apt install icnsutils
Docs shouldn't contain private members and source code
If your project is a library, you might not want to add the private and protected members to your documentation. Editing one line in .github/workflows/doxygen.yml
can change this behaviour. Find this step:
- name: Generate documents and deploy
uses: DenverCoder1/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: docs
config_file: doxygen/Doxyfile_dev
And change it to:
- name: Generate documents and deploy
uses: DenverCoder1/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: docs
config_file: doxygen/Doxyfile
If you want to further customize output and its display, all files related to documentation are stored in /doxygen
folder.
"conan is not recognized as an internal or external command"
Problem that usually occurs on Windows.
Conan needs to be added to the PATH enviromental variable. It is usually found alongside other Python scripts:
C:/Users/[user_name]/AppData/Roaming/Python/Python[python_version]/Scripts
Example:
C:/Users/Owl/AppData/Roaming/Python/Python313/Scripts
"/bin/bash^M: bad interpreter: No such file or directory"
If you downloaded the project on Windows and try to run these scripts in Unix, you might encounter:
-bash: ./createIcns.sh: /bin/bash^M: bad interpreter: No such file or directory
Run icon/WinScripts/fixUnixScripts.ps1
Or some tool like dos2unix.
On Ubuntu you can install it by:
sudo apt install dos2unix
And then simply run (assuming you are at qt-template/
):
dos2unix ./icon/UnixScripts/*.sh
Add/change/remove custom filter
At line 174
of CMakeLists.txt
you can modify following code for filters to change or remove them:
The code
# For resource files
source_group("Resources" FILES
"${CMAKE_BINARY_DIR}/.rcc/resources.qrc"
"${CMAKE_BINARY_DIR}/.rcc/qrc_resources.cpp")
file(GLOB_RECURSE SOURCES "*.rc" "*.qrc")
foreach(SOURCE ${SOURCES})
source_group("Resources" FILES ${SOURCE})
endforeach()
# Resources defined in cmake/Resources.cmake
foreach(SOURCE ${RESOURCES})
source_group("Resources" FILES ${SOURCE})
endforeach()
# For source code
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h" "src/*.ui")
foreach(SOURCE ${SOURCES})
get_filename_component(SOURCE_DIR "${SOURCE}" DIRECTORY)
file(RELATIVE_PATH SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${SOURCE_DIR})
string(REPLACE "src" "Source Files" SOURCE_PATH "${SOURCE_PATH}")
source_group("${SOURCE_PATH}" FILES ${SOURCE})
endforeach()
# For autogenerated by Qt ui_[name].h files for every src/*.ui file
file(GLOB_RECURSE SOURCES "src/*.ui")
foreach(SOURCE ${SOURCES})
get_filename_component(FILE_NAME ${SOURCE} NAME_WE) # Extract file name without extension
file(RELATIVE_PATH SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${SOURCE})
string(REPLACE "${FILE_NAME}.ui" "" FILE_PATH "${SOURCE_PATH}" )
source_group("Autogen/ui/${FILE_NAME}" FILES
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/include_Debug/${FILE_PATH}ui_${FILE_NAME}.h"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/include_MinSizeRel/${FILE_PATH}ui_${FILE_NAME}.h"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/include_Release/${FILE_PATH}ui_${FILE_NAME}.h"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/include_RelWithDebInfo/${FILE_PATH}ui_${FILE_NAME}.h")
endforeach()
# For autogenerated by Qt stamp files
source_group("Autogen/autouic" FILES
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_LIB_autogen/autouic_Debug.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_LIB_autogen/autouic_MinSizeRel.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_LIB_autogen/autouic_Release.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_LIB_autogen/autouic_RelWithDebInfo.stamp" )
# For autogenerated by Qt stamp files
source_group("Autogen/autouic" FILES
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/autouic_Debug.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/autouic_MinSizeRel.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/autouic_Release.stamp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/autouic_RelWithDebInfo.stamp" )
# For autogenerated by Qt MOC files
source_group("Autogen/moc" FILES
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/mocs_compilation_Debug.cpp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/mocs_compilation_MinSizeRel.cpp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/mocs_compilation_Release.cpp"
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}_autogen/mocs_compilation_RelWithDebInfo.cpp")
source_group("CMake Rules" FILES "CMakeLists.txt")
You can add your own filters after line 232
in CMakeLists.txt
, by adding:
source_group("[FILTER_NAME]" FILES "[FILE_PATHS]")
Example:
source_group("birds" FILES "src/flamingo.ui" "src/Birds/crow.h")
This project follows these C++ Core Guidelines, and it would be fun if you followed them too. If you don't, someone will correct your code. An ugly contribution is better than no contribution. Thanks!
This project is licensed under the CC0 1.0 Universal; see the LICENSE file for details. It also uses the Qt library and possibly some of its additional modules that are licensed under the LGPL, but none of its code is present in this repository. Also note that Qt itself uses other third-party libraries under different license terms.