diff --git a/.gitignore b/.gitignore index 32698b35..138bebe4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ Makefile .qmake.stash .uuid +build obj moc rcc diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ee66fd..b971c6aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,8 +62,18 @@ macro(qsk_setup_build) endmacro() macro(qsk_setup_install) - set(QSK_INSTALL_HEADERS include) - set(QSK_INSTALL_LIBS lib) + + # package vars + set(PACKAGE_NAME ${PROJECT_NAME}) + set(PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) + set(PACKAGE_NAMESPACE ${PROJECT_NAME}::) + set(PACKAGE_LOCATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) + + # install paths for headers and libraries + string(TOLOWER "${PROJECT_NAME}" PACKAGE_DIR) + set(QSK_INSTALL_HEADERS ${CMAKE_INSTALL_INCLUDEDIR}/${PACKAGE_DIR}) + set(QSK_INSTALL_LIBS ${CMAKE_INSTALL_LIBDIR}/${PACKAGE_DIR}) + endmacro() ############################################################################ @@ -76,6 +86,7 @@ project(QSkinny VERSION 0.8.0) set(QSK_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(QSK_CMAKE_DIR ${QSK_SOURCE_DIR}/cmake) qsk_setup_options() @@ -95,6 +106,32 @@ qsk_setup_install() add_subdirectory(src) add_subdirectory(skins) +include(CMakePackageConfigHelpers) + +# write QSkinnyConfigVersion.cmake file for cmake import +write_basic_package_version_file( + ${CMAKE_BINARY_DIR}/_QSkinny/${PACKAGE_NAME}ConfigVersion.cmake + VERSION ${PACKAGE_VERSION} + COMPATIBILITY AnyNewerVersion) + +# Copy QSkinnyConfig.cmake to build dir +configure_file(${QSK_CMAKE_DIR}/${PACKAGE_NAME}Config.cmake + ${CMAKE_BINARY_DIR}/_QSkinny/${PACKAGE_NAME}Config.cmake + COPYONLY) + +# install QSkinnyConfig.cmake and QSkinnyConfigVersion.cmake +# and QskTools.cmake file to lib/cmake/QSkinny directory +install( + FILES + ${CMAKE_BINARY_DIR}/_QSkinny/${PACKAGE_NAME}Config.cmake + ${CMAKE_BINARY_DIR}/_QSkinny/${PACKAGE_NAME}ConfigVersion.cmake + ${QSK_CMAKE_DIR}/QskTools.cmake + DESTINATION + ${PACKAGE_LOCATION} + COMPONENT + Devel) + +# Build other libraries if(BUILD_QML_EXPORT) add_subdirectory(qmlexport) endif() @@ -118,48 +155,3 @@ endif() if(BUILD_PLAYGROUND) add_subdirectory(playground) endif() - -# packaging -set(PACKAGE_NAME ${PROJECT_NAME}) -set(PACKAGE_VERSION ${CMAKE_PROJECT_VERSION}) -set(PACKAGE_NAMESPACE Qsk) -set(PACKAGE_LOCATION ${QSK_INSTALL_LIBS}/cmake/${PROJECT_NAME}) - -install(TARGETS qskinny EXPORT ${PACKAGE_NAME}Targets - LIBRARY DESTINATION ${QSK_INSTALL_LIBS} - ARCHIVE DESTINATION ${QSK_INSTALL_LIBS} - RUNTIME DESTINATION ${QSK_INSTALL_LIBS} - INCLUDES DESTINATION ${QSK_INSTALL_HEADERS} - PUBLIC_HEADER DESTINATION ${QSK_INSTALL_HEADERS}) - -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}/${PACKAGE_NAME}ConfigVersion.cmake - VERSION ${PACKAGE_VERSION} - COMPATIBILITY AnyNewerVersion) - -export(EXPORT ${PACKAGE_NAME}Targets - FILE ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}/${PACKAGE_NAME}Targets.cmake - NAMESPACE ${PACKAGE_NAMESPACE}::) - -configure_file(cmake/${PACKAGE_NAME}Config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}/${PACKAGE_NAME}Config.cmake - COPYONLY) - -install(EXPORT ${PACKAGE_NAME}Targets - FILE - ${PACKAGE_NAME}Targets.cmake - NAMESPACE - ${PACKAGE_NAMESPACE}:: - DESTINATION - ${PACKAGE_LOCATION}) - -install( - FILES - cmake/${PACKAGE_NAME}Config.cmake - cmake/QskTools.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}/${PACKAGE_NAME}ConfigVersion.cmake - DESTINATION - ${PACKAGE_LOCATION} - COMPONENT - Devel) \ No newline at end of file diff --git a/README.md b/README.md index 070079fe..a90e2688 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,9 @@ It might support all versions Qt >= 5.15, but you can rely on: - current long term supported ( LTS ) version of Qt ( at the moment Qt 6.5.x ) - current version of Qt -On debian bullseye these packages need to be installed for Qt5: `build-essential +On debian bullseye these packages need to be installed for Qt5: `build-essential cmake qtbase5-dev qtbase5-private-dev qtdeclarative5-dev qtdeclarative5-private-dev libqt5svg5-dev`. -For Qt6 you need the corresponding ones. +For Qt6 you need the corresponding packages. > Optional: When enabling the `hunspell` feature the following package needs to be installed: `libhunspell-dev` diff --git a/cmake/QSkinnyConfig.cmake b/cmake/QSkinnyConfig.cmake index e24cd20c..fbffae9e 100644 --- a/cmake/QSkinnyConfig.cmake +++ b/cmake/QSkinnyConfig.cmake @@ -1,2 +1 @@ include("${CMAKE_CURRENT_LIST_DIR}/QSkinnyTargets.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/QskTools.cmake") \ No newline at end of file diff --git a/cmake/QskBuildFunctions.cmake b/cmake/QskBuildFunctions.cmake index 38fee091..a35151bc 100644 --- a/cmake/QskBuildFunctions.cmake +++ b/cmake/QskBuildFunctions.cmake @@ -65,7 +65,7 @@ function(qsk_add_plugin target TYPE CLASS_NAME) set_target_properties( ${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/${TYPE}) - install(TARGETS ${target} DESTINATION "plugins/${TYPE}" ) + install(TARGETS ${target} DESTINATION "${QSK_INSTALL_LIBS}/plugins/${TYPE}" ) set_target_properties(${target} PROPERTIES INSTALL_RPATH "\${ORIGIN}/../../lib" ) @@ -99,3 +99,11 @@ function(qsk_add_example target) target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) endfunction() + +function(qsk_update_package_config_file target) + + file(APPEND + ${CMAKE_BINARY_DIR}/_QSkinny/QSkinnyConfig.cmake + "include(\"\${CMAKE_CURRENT_LIST_DIR}/${target}.cmake\")\n") + +endfunction() diff --git a/doc/tutorials/03-writing-your-first-application.asciidoc b/doc/tutorials/03-writing-your-first-application.asciidoc index b912e892..b0d86d5d 100644 --- a/doc/tutorials/03-writing-your-first-application.asciidoc +++ b/doc/tutorials/03-writing-your-first-application.asciidoc @@ -11,21 +11,26 @@ layout: docs === Building the QSkinny repository In this chapter we will write a simple QSkinny application on Linux from scratch. -As a prerequisite, a recent Qt version (>= 5.6) should be available and the directory of -its `qmake` binary in the current `$PATH`. On debian bullseye we need to install -these packages `build-essential qt-qmake qtbase5-dev qtbase5-private-dev -qtdeclarative5-dev qtdeclarative5-private-dev libqt5svg5-dev`. +As a prerequisite, a recent Qt version (>= 5.15) should be available. On debian bullseye we need to install +these packages `build-essential cmake qtbase5-dev qtbase5-private-dev qtdeclarative5-dev qtdeclarative5-private-dev libqt5svg5-dev`. +For Qt6 you need the corresponding packages. Then we can build and install QSkinny to `/opt/qskinny` with the following commands: -[source,xml] +[source,shell] .... -cd /home/user/dev/ -git clone https://github.com/uwerat/qskinny.git -cd qskinny -PREFIX=/opt/qskinny qmake -r -make -sudo make install +$ git clone https://github.com/uwerat/qskinny.git # clone +$ cd qskinny +$ mkdir build && cd build +$ cmake ../ && make # build +$ sudo make install # install +.... + +To target a specific Qt version simply pass the cmake build variable `QSK_QT_VERSION` during the build step: + +[source,shell] +.... +$ cmake -DQSK_QT_VERSION=Qt5 ../ && make .... === Compiling our first app @@ -52,40 +57,49 @@ int main( int argc, char* argv[] ) For now this will just create an empty window (the `QskWindow`) without any controls. Next, we need to create a `myapp.pro` file in our `myapp` directory. -.myapp.pro -[source,xml] +.CMakeLists.txt +[source,cmake] .... -TEMPLATE = app -TARGET = myapp +cmake_minimum_required(VERSION 3.27) -QT *= quick +project(myapp + VERSION 1.0.0 + LANGUAGES CXX) -QSK_ROOT=/opt/qskinny +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) -INCLUDEPATH += $${QSK_ROOT}/include -LIBS += -L$${QSK_ROOT}/lib -lqskinny +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) -QMAKE_RPATHDIR *= $${QSK_ROOT}/lib +find_package(Qt5 REQUIRED COMPONENTS Widgets Quick) +find_package(QSkinny REQUIRED) -SOURCES += \ - main.cpp +add_executable(myapp + src/main.cpp) + +target_link_libraries(myapp PRIVATE + Qt5::Widgets + Qt5::Quick + QSkinny::QSkinny) .... Now we can compile our app: -[source,xml] +[source,shell] .... -cd myapp -qmake -make +$ cd myapp +$ mkdir build && cd build +$ cmake ../ && make .... When running myapp it needs to find the skin plugins. Setting QT_PLUGIN_PATH is one option ( see https://doc.qt.io/qt-5/deployment-plugins.html ): -[source,xml] +[source,shell] .... -QT_PLUGIN_PATH=/opt/qskinny/plugins ./myapp +$ QT_PLUGIN_PATH=/opt/qskinny/plugins ./myapp .... This should show just an empty window. @@ -95,7 +109,7 @@ This should show just an empty window. Now that we have our app running, we can add some UI controls to it by extending the `main.cpp` file we created earlier. We will add some additional include directives, and then create a horizontal layout containing two push buttons. The layout with the two buttons will be shown in the window. Below is the complete updated source file: .main.cpp -[source] +[source, cpp] .... #include #include diff --git a/doc/tutorials/08-qskinny-and-qml.asciidoc b/doc/tutorials/08-qskinny-and-qml.asciidoc index ef521bc4..f1570e23 100644 --- a/doc/tutorials/08-qskinny-and-qml.asciidoc +++ b/doc/tutorials/08-qskinny-and-qml.asciidoc @@ -18,7 +18,16 @@ When using a QSkinny control, all the methods exposed as either properties, slots or invokables can be used in QML. For example, the QSkinny control `QskLinearBox` defines the following properties: -[source] +.CMakeLists.txt +[source,cmake] +.... +target_link_libraries(myapp PRIVATE + ... + QSkinny::QmlExport) +... +.... + +[source,cpp] .... class QSK_EXPORT QskLinearBox : public QskIndexedLayoutBox { diff --git a/examples/iotdashboard_smoketest/CMakeLists.txt b/examples/iotdashboard_smoketest/CMakeLists.txt index ea34d940..f9924b04 100644 --- a/examples/iotdashboard_smoketest/CMakeLists.txt +++ b/examples/iotdashboard_smoketest/CMakeLists.txt @@ -22,7 +22,7 @@ endfunction() function(qsk_add_example target) cmake_parse_arguments(PARSE_ARGV 1 arg "MANUAL_FINALIZATION" "" "") add_executable(${target} WIN32 MACOSX_BUNDLE ${arg_UNPARSED_ARGUMENTS} ) - target_link_libraries(${target} PRIVATE Qsk::qskinny ) + target_link_libraries(${target} PRIVATE QSkinny::QSkinny ) target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) endfunction() @@ -44,4 +44,4 @@ add_subdirectory(../iotdashboard ${CMAKE_CURRENT_BINARY_DIR}/../iotdashboard) # TODO we don't delivery the support library get_target_property(iotdashboard_COMPILE_DEFINITIONS iotdashboard COMPILE_DEFINITIONS) list(FILTER iotdashboard_COMPILE_DEFINITIONS EXCLUDE REGEX [[^USE_SHORTCUTS=1$]]) -set_property(TARGET iotdashboard PROPERTY COMPILE_DEFINITIONS ${iotdashboard_COMPILE_DEFINITIONS}) \ No newline at end of file +set_property(TARGET iotdashboard PROPERTY COMPILE_DEFINITIONS ${iotdashboard_COMPILE_DEFINITIONS}) diff --git a/qmlexport/CMakeLists.txt b/qmlexport/CMakeLists.txt index ef245952..e3ca96c0 100644 --- a/qmlexport/CMakeLists.txt +++ b/qmlexport/CMakeLists.txt @@ -10,7 +10,8 @@ set(target qskqmlexport) qsk_add_library(${target} SHARED ${SOURCES} ${HEADERS}) target_link_libraries(${target} PRIVATE qskinny) -target_include_directories(${target} PUBLIC ${CMAKE_CURRENT_LIST_DIR}) +target_include_directories(${target} PUBLIC + $) set_target_properties(${target} PROPERTIES PUBLIC_HEADER QskQml.h) if(BUILD_QSKDLL) @@ -20,6 +21,26 @@ if(BUILD_QSKDLL) VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) endif() -set_target_properties(${target} PROPERTIES FOLDER libs) +# packaging +set(PACKAGE_NAME QmlExport) +set(QSKQE_INSTALL_HEADERS "${CMAKE_INSTALL_INCLUDEDIR}/${target}") -install(TARGETS ${target} ) +set_target_properties(${target} PROPERTIES FOLDER libs) +set_target_properties(${target} PROPERTIES EXPORT_NAME ${PACKAGE_NAME}) + +install(TARGETS ${target} EXPORT ${PACKAGE_NAME}Targets + INCLUDES DESTINATION ${QSKQE_INSTALL_HEADERS} + PUBLIC_HEADER DESTINATION ${QSKQE_INSTALL_HEADERS}) + +export(EXPORT ${PACKAGE_NAME}Targets + NAMESPACE ${PACKAGE_NAMESPACE}) + +install(EXPORT ${PACKAGE_NAME}Targets + FILE + ${PACKAGE_NAME}Targets.cmake + NAMESPACE + ${PACKAGE_NAMESPACE} + DESTINATION + ${PACKAGE_LOCATION}) + +qsk_update_package_config_file(${PACKAGE_NAME}Targets) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c6b4970..36fad042 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -513,7 +513,30 @@ set_target_properties(${target} list(TRANSFORM HEADERS PREPEND "${CMAKE_CURRENT_LIST_DIR}/") set_target_properties(${target} PROPERTIES PUBLIC_HEADER "${HEADERS}") +set_target_properties(${target} PROPERTIES EXPORT_NAME ${PROJECT_NAME}) set_target_properties(${target} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} ) -install(TARGETS ${target} ) +# packaging +set(PACKAGE_NAME ${PROJECT_NAME}) + +# setup destination file paths for qskinny target +install(TARGETS ${target} EXPORT ${PACKAGE_NAME}Targets + LIBRARY DESTINATION ${QSK_INSTALL_LIBS} + ARCHIVE DESTINATION ${QSK_INSTALL_LIBS} + RUNTIME DESTINATION ${QSK_INSTALL_LIBS} + INCLUDES DESTINATION ${QSK_INSTALL_HEADERS} + PUBLIC_HEADER DESTINATION ${QSK_INSTALL_HEADERS}) + +# export QSkinnyTargets namespace +export(EXPORT ${PACKAGE_NAME}Targets + NAMESPACE ${PACKAGE_NAMESPACE}) + +# install QSkinnyTargets under QSkinny namespace +install(EXPORT ${PACKAGE_NAME}Targets + FILE + ${PACKAGE_NAME}Targets.cmake + NAMESPACE + ${PACKAGE_NAMESPACE} + DESTINATION + ${PACKAGE_LOCATION}) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 74da26cc..74d10d19 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,3 +1,4 @@ if(TARGET Qt::Svg) add_subdirectory(svg2qvg) -endif() \ No newline at end of file + qsk_update_package_config_file(QskTools) +endif()