diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..4eaf80f47 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,71 @@ +name: CMake CI + +on: + push: + branches: + - master + +jobs: + build-and-test: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + qt_version: [5, 6] + python_version: ["3.8", "3.9", "3.10"] + fail-fast: false + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python_version }} + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + if [ "${{ matrix.qt_version }}" = "5" ]; then + sudo apt-get install -y qtbase5-dev qtbase5-private-dev qtchooser qt5-qmake qtbase5-dev-tools \ + libqt5svg5-dev qttools5-dev libqt5xmlpatterns5-dev qtmultimedia5-dev qtdeclarative5-dev \ + qtwebengine5-dev libqt5webkit5-dev + echo "QTDIR=/usr/lib/x86_64-linux-gnu/qt5" | tee -a $GITHUB_ENV + else + sudo apt-get install -y qt6-base-dev qt6-base-private-dev qt6-5compat-dev qt6-base-dev-tools \ + libqt6svg6-dev qt6-multimedia-dev qt6-declarative-dev qt6-webengine-dev + echo "QTDIR=/usr/lib/x86_64-linux-gnu/qt6" | tee -a $GITHUB_ENV + fi + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + run: | + if ("${{ matrix.qt_version }}" -eq "5") { + pip install aqtinstall + aqt install-qt windows desktop 5.15.2 win64_msvc2019 -m all + $Qt5Dir = "$env:USERPROFILE\Qt\5.15.2\msvc2019_64" + echo "Qt5Dir=$Qt5Dir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + echo "$Qt5Dir\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "QTDIR=$Qt5Dir" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + } else { + choco install -y qt6-base-dev qt6-base-private-dev qt6-5compat-dev qt6-base-dev-tools ` + libqt6svg6-dev qt6-multimedia-dev qt6-declarative-dev qt6-webengine-dev ` + --params "/InstallationFolder C:/Qt/${{ matrix.qt_version }}" + echo "C:/Qt/${{ matrix.qt_version }}/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "QTDIR=C:/Qt/${{ matrix.qt_version }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + } + + - name: Configure CMake + run: | + cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./install + + - name: Build project + run: | + cmake --build build --parallel --target all install + + - name: Run tests + run: | + cd build + ctest --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..7b0748077 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.27) + +project(PythonQt LANGUAGES CXX VERSION 3.5.6) + +enable_testing() + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Python3 COMPONENTS Development) + +set(PYTHONQT_SUFFIX Qt${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}-Python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}) + +add_subdirectory(generator) +add_subdirectory(src) +add_subdirectory(extensions) +add_subdirectory(tests) +# add_subdirectory(examples) diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt new file mode 100644 index 000000000..03577a7a2 --- /dev/null +++ b/extensions/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(PythonQt_QtAll) \ No newline at end of file diff --git a/extensions/PythonQt_QtAll/CMakeLists.txt b/extensions/PythonQt_QtAll/CMakeLists.txt new file mode 100644 index 000000000..bd91d4b4a --- /dev/null +++ b/extensions/PythonQt_QtAll/CMakeLists.txt @@ -0,0 +1,92 @@ +project(QtAll LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +file(GLOB SOURCES *.h *.cpp) + +if(BUILD_SHARED_LIBS) + add_library(${PROJECT_NAME} SHARED) + target_compile_definitions(${PROJECT_NAME} PRIVATE PYTHONQT_QTALL_EXPORTS) +else() + add_library(${PROJECT_NAME} STATIC) + target_compile_definitions(${PROJECT_NAME} PUBLIC PYTHONQT_QTALL_STATIC) +endif() + +target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} PUBLIC Core) + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +list(APPEND QTMODULES Core Gui Svg Sql Network OpenGL Xml XmlPatterns Multimedia Qml Quick UiTools WebEngineWidgets WebKit) + +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS ${QTMODULES}) + +foreach(QtModule IN LISTS QTMODULES) + if(NOT TARGET "Qt${QT_VERSION_MAJOR}::${QtModule}") + continue() + endif() + + string(TOUPPER ${QtModule} QTMODULE) + target_sources(${PROJECT_NAME} PRIVATE ${PYTHONQT_WRAPPER_${QTMODULE}_SOURCES}) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::${QtModule}) + target_compile_definitions(${PROJECT_NAME} PRIVATE PYTHONQT_WITH_${QTMODULE}) +endforeach() + +if(TARGET "Qt${QT_VERSION_MAJOR}::Gui") + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets PrintSupport REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::PrintSupport + ) +endif() + +if(TARGET "Qt${QT_VERSION_MAJOR}::Svg" AND QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6) + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS SvgWidgets REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::SvgWidgets + ) +endif() + +if(TARGET "Qt${QT_VERSION_MAJOR}::Multimedia") + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS MultimediaWidgets REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::MultimediaWidgets + ) +endif() + +if(TARGET "Qt${QT_VERSION_MAJOR}::Quick") + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS QuickWidgets REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::QuickWidgets + ) +endif() + +if(TARGET "Qt${QT_VERSION_MAJOR}::WebKit") + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS WebKitWidgets REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::WebKitWidgets + ) +endif() + +file(GLOB PUBLIC_HEADER *.h) + +set_target_properties(${PROJECT_NAME} PROPERTIES + OUTPUT_NAME PythonQt-QtAll-${PYTHONQT_SUFFIX} + PUBLIC_HEADER "${PUBLIC_HEADER}" +) + +if(MSVC) + target_compile_options(${PROJECT_NAME} PRIVATE "/bigobj") +elseif(MINGW) + target_compile_options(${PROJECT_NAME} PRIVATE "-Wa,-mbig-obj") +endif() + +include(GNUInstallDirs) +install(TARGETS ${PROJECT_NAME} + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/extensions/PythonQt_QtAll/PythonQt_QtAll.h b/extensions/PythonQt_QtAll/PythonQt_QtAll.h index 689e2e83c..f4a5ff769 100644 --- a/extensions/PythonQt_QtAll/PythonQt_QtAll.h +++ b/extensions/PythonQt_QtAll/PythonQt_QtAll.h @@ -33,14 +33,16 @@ * */ -#ifdef WIN32 -#ifdef PYTHONQT_QTALL_EXPORTS -#define PYTHONQT_QTALL_EXPORT __declspec(dllexport) -#else -#define PYTHONQT_QTALL_EXPORT __declspec(dllimport) -#endif +#include + +#ifndef PYTHONQT_QTALL_STATIC +# if defined(PYTHONQT_QTALL_EXPORTS) +# define PYTHONQT_QTALL_EXPORT Q_DECL_EXPORT +# else +# define PYTHONQT_QTALL_EXPORT Q_DECL_IMPORT +# endif #else -#define PYTHONQT_QTALL_EXPORT +# define PYTHONQT_QTALL_EXPORT #endif namespace PythonQt_QtAll diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 1d659dd87..f9f095a6e 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -1,162 +1,83 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.27) +project(PythonQtGenerator LANGUAGES CXX) -#----------------------------------------------------------------------------- -project(PythonQtGenerator) -#----------------------------------------------------------------------------- +add_subdirectory(parser) -include(CTestUseLaunchers OPTIONAL) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) -#----------------------------------------------------------------------------- -# Setup Qt +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets Xml REQUIRED) -set(minimum_required_qt_version "4.6.2") +file(GLOB SOURCES *.h *.cpp *.qrc) +list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_LIST_DIR}/qtscript_masterinclude.h") -find_package(Qt4) +add_executable(${PROJECT_NAME}) + +target_sources(${PROJECT_NAME} PRIVATE + ${SOURCES} +) -if(QT4_FOUND) +target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Xml + rxx +) - set(found_qt_version ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}) +if (${QT_VERSION_MAJOR} VERSION_GREATER 5) + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core5Compat REQUIRED) + target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core5Compat) +endif() - if(${found_qt_version} VERSION_LESS ${minimum_required_qt_version}) - message(FATAL_ERROR "error: PythonQt requires Qt >= ${minimum_required_qt_version} -- you cannot use Qt ${found_qt_version}.") - endif() - - set(QT_USE_QTXML ON) - - include(${QT_USE_FILE}) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) + +get_filename_component(PYTHONQT_GENERATED_PATH "${CMAKE_CURRENT_BINARY_DIR}" PATH) +set(PYTHONQT_GENERATED_PATH "${PYTHONQT_GENERATED_PATH}/generated_cpp") + +file(GLOB resources_files *.txt *.xml qtscript_masterinclude.h) +foreach(resources_file IN LISTS resources_files) + configure_file(${resources_file} ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) +endforeach() + +if(WIN32) + set(LIBRARY_SEARCH_PATH PATH) else() - message(FATAL_ERROR "error: Qt4 was not found on your system. You probably need to set the QT_QMAKE_EXECUTABLE variable") + set(LIBRARY_SEARCH_PATH LD_LIBRARY_PATH) endif() -#----------------------------------------------------------------------------- -# Sources - -set(sources - parser/ast.cpp - parser/binder.cpp - parser/class_compiler.cpp - parser/codemodel.cpp - parser/codemodel_finder.cpp - parser/compiler_utils.cpp - parser/control.cpp - parser/declarator_compiler.cpp - parser/default_visitor.cpp - parser/dumptree.cpp - parser/lexer.cpp - parser/list.cpp - parser/name_compiler.cpp - parser/parser.cpp - parser/smallobject.cpp - parser/tokens.cpp - parser/type_compiler.cpp - parser/visitor.cpp - - abstractmetabuilder.cpp - abstractmetalang.cpp - asttoxml.cpp - customtypes.cpp - fileout.cpp - generator.cpp - generatorset.cpp - generatorsetqtscript.cpp - main.cpp - metajava.cpp - metaqtscriptbuilder.cpp - metaqtscript.cpp - prigenerator.cpp - reporthandler.cpp - setupgenerator.cpp - shellgenerator.cpp - shellheadergenerator.cpp - shellimplgenerator.cpp - typeparser.cpp - typesystem.cpp - ) - -#----------------------------------------------------------------------------- -# List headers. This list is used for the install command. - -set(headers - ) - -#----------------------------------------------------------------------------- -# Headers that should run through moc - -set(moc_sources - fileout.h - generator.h - generatorset.h - generatorsetqtscript.h - prigenerator.h - setupgenerator.h - shellgenerator.h - shellheadergenerator.h - shellimplgenerator.h - ) - -#----------------------------------------------------------------------------- -# UI files - -set(ui_sources ) - -#----------------------------------------------------------------------------- -# Resources - -set(qrc_sources - generator.qrc - ) - -#----------------------------------------------------------------------------- -# Do wrapping -qt4_wrap_cpp(gen_moc_sources ${moc_sources}) -qt4_wrap_ui(gen_ui_sources ${ui_sources}) -qt4_add_resources(gen_qrc_sources ${qrc_sources}) - -#----------------------------------------------------------------------------- -# Copy file expected by the generator and specify install rules - -file(GLOB files_to_copy RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "build_*.txt" "typesystem_*.xml") -list(APPEND files_to_copy qtscript_masterinclude.h parser/rpp/pp-qt-configuration) -foreach(file ${files_to_copy}) - configure_file( - ${file} - ${CMAKE_CURRENT_BINARY_DIR}/${file} - COPYONLY +list(APPEND wrapper_list core core_builtin gui gui_builtin multimedia network qml quick sql svg uitools xml) +foreach(wrapper IN LISTS wrapper_list) + string(TOUPPER ${wrapper} WRAPPER) + set(PYTHONQT_WRAPPER_${WRAPPER}_SOURCES + "${PYTHONQT_GENERATED_PATH}/com_trolltech_qt_${wrapper}/com_trolltech_qt_${wrapper}0.h" + "${PYTHONQT_GENERATED_PATH}/com_trolltech_qt_${wrapper}/com_trolltech_qt_${wrapper}0.cpp" + "${PYTHONQT_GENERATED_PATH}/com_trolltech_qt_${wrapper}/com_trolltech_qt_${wrapper}_init.cpp" ) - get_filename_component(destination_dir ${file} PATH) - install(FILES ${file} DESTINATION bin/${destination_dir}) + list(APPEND PYTHONQT_WRAPPER_SOURCES ${PYTHONQT_WRAPPER_${WRAPPER}_SOURCES}) + set(PYTHONQT_WRAPPER_${WRAPPER}_SOURCES ${PYTHONQT_WRAPPER_${WRAPPER}_SOURCES} PARENT_SCOPE) endforeach() -#----------------------------------------------------------------------------- -# Build the library - -SOURCE_GROUP("Resources" FILES - ${qrc_sources} - ${ui_sources} - ${files_to_copy} - ) +get_target_property(_qtcore_include_dirs Qt${QT_VERSION_MAJOR}::Core INTERFACE_INCLUDE_DIRECTORIES) +foreach(_qtcore_include_dir IN LISTS _qtcore_include_dirs) + if (IS_DIRECTORY "${_qtcore_include_dir}/QtCore") + set(_qt_include_prefix "${_qtcore_include_dir}") + break() + endif() +endforeach() -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/parser - ${CMAKE_CURRENT_SOURCE_DIR}/parser/rpp - ) - -add_definitions(-DRXX_ALLOCATOR_INIT_0) - -add_executable(${PROJECT_NAME} - ${sources} - ${gen_moc_sources} - ${gen_ui_sources} - ${gen_qrc_sources} +add_custom_command(OUTPUT ${PYTHONQT_WRAPPER_SOURCES} + COMMAND ${CMAKE_COMMAND} -E env --modify ${LIBRARY_SEARCH_PATH}=path_list_prepend:$ + $ --qt-include-prefix="${_qt_include_prefix}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${PROJECT_NAME} ) -target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES}) - -#----------------------------------------------------------------------------- -# Install library (on windows, put the dll in 'bin' and the archive in 'lib') +set_source_files_properties(${PYTHONQT_WRAPPER_SOURCES} PROPERTIES + SKIP_AUTOMOC TRUE + SKIP_AUTOUIC TRUE +) -install(TARGETS ${PROJECT_NAME} - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) +add_custom_target(PythonQtWrapper + DEPENDS ${PROJECT_NAME} ${PYTHONQT_WRAPPER_SOURCES} +) diff --git a/generator/generatorsetqtscript.h b/generator/generatorsetqtscript.h index 06d836906..237abbdbc 100644 --- a/generator/generatorsetqtscript.h +++ b/generator/generatorsetqtscript.h @@ -62,7 +62,7 @@ class GeneratorSetQtScript : public GeneratorSet private: MetaQtScriptBuilder builder; - int maxClassesPerFile{30}; + int maxClassesPerFile{std::numeric_limits::max() >> 1}; }; diff --git a/generator/main.cpp b/generator/main.cpp index a6494363b..38e06f70e 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -61,7 +61,7 @@ void displayHelp(GeneratorSet *generatorSet); namespace { - QStringList getIncludeDirectories(const QString &commandLineIncludes) + QStringList getIncludeDirectories(const QString &commandLineIncludes, const QString &qtIncludePrefix) { QStringList includes; includes << QString("."); @@ -121,11 +121,20 @@ namespace includes << (qtdir + "/QtOpenGL"); includes << qtdir; } + if (!qtIncludePrefix.isEmpty() && QFile::exists(qtIncludePrefix)) { + std::cout << "qt include prefix: " << qtIncludePrefix.toLocal8Bit().constData() << std::endl; + includes << (qtIncludePrefix + "/QtXml"); + includes << (qtIncludePrefix + "/QtNetwork"); + includes << (qtIncludePrefix + "/QtCore"); + includes << (qtIncludePrefix + "/QtGui"); + includes << (qtIncludePrefix + "/QtOpenGL"); + includes << qtIncludePrefix; + } return includes; } bool - preprocess(const QString &sourceFile, const QString &targetFile, const QString &commandLineIncludes = QString()) + preprocess(const QString &sourceFile, const QString &targetFile, const QString &commandLineIncludes = QString(), const QString &qtIncludPrefix = {}) { rpp::pp_environment env; rpp::pp preprocess(env); @@ -146,7 +155,7 @@ namespace preprocess.operator()(ba.constData(), ba.constData() + ba.size(), null_out); foreach(QString - include, getIncludeDirectories(commandLineIncludes)) { + include, getIncludeDirectories(commandLineIncludes, qtIncludPrefix)) { preprocess.push_include_path(QDir::toNativeSeparators(include).toStdString()); } @@ -177,10 +186,10 @@ namespace return true; } - unsigned int getQtVersion(const QString &commandLineIncludes) + unsigned int getQtVersion(const QString &commandLineIncludes, const QString &qtIncludPrefix = {}) { QRegularExpression re("#define\\s+QTCORE_VERSION\\s+0x([0-9a-f]+)", QRegularExpression::CaseInsensitiveOption); - for (const QString &includeDir: getIncludeDirectories(commandLineIncludes)) + for (const QString &includeDir: getIncludeDirectories(commandLineIncludes, qtIncludPrefix)) { QFileInfo fi(QDir(includeDir), "qtcoreversion.h"); if (fi.exists()) @@ -315,7 +324,7 @@ int main(int argc, char *argv[]) if (!qtVersion) { printf("Trying to determine Qt version...\n"); - qtVersion = getQtVersion(args.value("include-paths")); + qtVersion = getQtVersion(args.value("include-paths"), args.value("qt-include-prefix")); if (!qtVersion) { fprintf(stderr, "Aborting\n"); // the error message was printed by getQtVersion @@ -337,7 +346,7 @@ int main(int argc, char *argv[]) printf("PreProcessing - Generate [%s] using [%s] and include-paths [%s]\n", qPrintable(pp_file), qPrintable(fileName), qPrintable(args.value("include-paths"))); ReportHandler::setContext("Preprocess"); - if (!preprocess(fileName, pp_file, args.value("include-paths"))) { + if (!preprocess(fileName, pp_file, args.value("include-paths"), args.value("qt-include-prefix"))) { fprintf(stderr, "Preprocessor failed on file: '%s'\n", qPrintable(fileName)); return 1; } diff --git a/generator/parser/CMakeLists.txt b/generator/parser/CMakeLists.txt new file mode 100644 index 000000000..45bd7fe87 --- /dev/null +++ b/generator/parser/CMakeLists.txt @@ -0,0 +1,27 @@ +project(rxx LANGUAGES CXX) +add_subdirectory(rpp) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) + +file(GLOB SOURCES *.h *.cpp) + +add_library(${PROJECT_NAME} INTERFACE) + +target_sources(${PROJECT_NAME} INTERFACE + ${SOURCES} +) + +target_link_libraries(${PROJECT_NAME} INTERFACE + Qt${QT_VERSION_MAJOR}::Core + rpp +) + +target_include_directories(${PROJECT_NAME} INTERFACE + ${CMAKE_CURRENT_LIST_DIR} +) + +target_compile_definitions(${PROJECT_NAME} INTERFACE RXX_ALLOCATOR_INIT_0) diff --git a/generator/parser/rpp/CMakeLists.txt b/generator/parser/rpp/CMakeLists.txt new file mode 100644 index 000000000..08d9f1879 --- /dev/null +++ b/generator/parser/rpp/CMakeLists.txt @@ -0,0 +1,18 @@ +project(rpp LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) + +file(GLOB SOURCES *.h preprocessor.cpp) + +add_library(${PROJECT_NAME} INTERFACE) + +target_sources(${PROJECT_NAME} INTERFACE ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} INTERFACE Qt${QT_VERSION_MAJOR}::Core) + +target_include_directories(${PROJECT_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..4ad6f781b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,57 @@ +project(Core LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets REQUIRED) +find_package(Python3 COMPONENTS Development REQUIRED) + +file(GLOB SOURCES *.h *.cpp) + +if(BUILD_SHARED_LIBS) + add_library(${PROJECT_NAME} SHARED) + target_compile_definitions(${PROJECT_NAME} PRIVATE PYTHONQT_EXPORTS) +else() + add_library(${PROJECT_NAME} STATIC) + target_compile_definitions(${PROJECT_NAME} PUBLIC PYTHONQT_STATIC) +endif() + +target_sources(${PROJECT_NAME} PRIVATE + ${SOURCES} + ${PYTHONQT_WRAPPER_CORE_BUILTIN_SOURCES} + ${PYTHONQT_WRAPPER_GUI_BUILTIN_SOURCES} +) + +add_dependencies(${PROJECT_NAME} PythonQtWrapper) + +file(GLOB PUBLIC_HEADER *.h) + +set_target_properties(${PROJECT_NAME} PROPERTIES + OUTPUT_NAME PythonQt-${PYTHONQT_SUFFIX} + PUBLIC_HEADER "${PUBLIC_HEADER}" +) + +target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::CorePrivate + Qt${QT_VERSION_MAJOR}::Widgets + Python3::Python +) + +target_compile_definitions(${PROJECT_NAME} PRIVATE PYTHONQT_EXPORTS PYTHONQT_CATCH_ALL_EXCEPTIONS) + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +if(MSVC) + target_compile_options(${PROJECT_NAME} PRIVATE "/bigobj") +elseif(MINGW) + target_compile_options(${PROJECT_NAME} PRIVATE "-Wa,-mbig-obj") +endif() + +include(GNUInstallDirs) +install(TARGETS ${PROJECT_NAME} + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/PythonQtSystem.h b/src/PythonQtSystem.h index d49345eeb..dc0bfd0e6 100644 --- a/src/PythonQtSystem.h +++ b/src/PythonQtSystem.h @@ -42,21 +42,17 @@ */ //---------------------------------------------------------------------------------- +#include -#if defined(WIN32) - #ifdef PYTHONQT_EXPORTS - #define PYTHONQT_EXPORT __declspec(dllexport) - #else - #define PYTHONQT_EXPORT __declspec(dllimport) - #endif +#ifndef PYTHONQT_STATIC +# if defined(PYTHONQT_EXPORTS) +# define PYTHONQT_EXPORT Q_DECL_EXPORT +# else +# define PYTHONQT_EXPORT Q_DECL_IMPORT +# endif #else - #ifdef PYTHONQT_EXPORTS - #define PYTHONQT_EXPORT __attribute__((__visibility__("default"))) - #else - #define PYTHONQT_EXPORT - #endif +# define PYTHONQT_EXPORT #endif - #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..8926055be --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,35 @@ +project(PythonQtTest LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Test REQUIRED) + +file(GLOB SOURCES *.h *.cpp) + +add_executable(${PROJECT_NAME}) + +target_sources(${PROJECT_NAME} PRIVATE + ${SOURCES} +) + +target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Test + Core + QtAll +) + +add_test(NAME ${PROJECT_NAME} + COMMAND $ + WORKING_DIRECTORY $ +) + +if(WIN32) + set(LIBRARY_SEARCH_PATH PATH) +else() + set(LIBRARY_SEARCH_PATH LD_LIBRARY_PATH) +endif() + +set_tests_properties(${PROJECT_NAME} PROPERTIES + ENVIRONMENT_MODIFICATION "${LIBRARY_SEARCH_PATH}=path_list_prepend:$" +)