diff --git a/CMakeLists.txt b/CMakeLists.txt index 67a70c23..b9f20d23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(ROSProjectManager VERSION 13.1) +project(ROSProjectManager VERSION 14.0) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Werror -Wall -Wextra -Wpedantic -Wsuggest-override) diff --git a/setup.py b/setup.py index 63b9dc9f..ab32e1c7 100755 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ os_arch_toolchain = { "linux": { - "x64": "gcc_64", + "x64": "linux_gcc_64", "arm64": "linux_gcc_arm64", }, "windows": { @@ -57,8 +57,7 @@ def download_check_fail(url, expected_type): if not response.ok: raise RuntimeError("error retrieving "+response.url) if response.headers.get('content-type') != expected_type: - print("Warning: invalid content type, expected '{}', got '{}'".format( - expected_type, response.headers.get('content-type')), flush=True) + print(f"Warning: invalid content type, expected '{expected_type}', got '{response.headers.get('content-type')}'", flush=True) return response def read_downloadable_archives(package): @@ -104,10 +103,10 @@ def qtc_download_check_extract(cfg, dir_install): qtc_ver_major = ver_split[0] qtc_ver_minor = ver_split[1] if len(ver_split)>1 else 0 qtc_ver_patch = ver_split[2] if len(ver_split)>2 else 0 - qtc_ver_maj = "{}.{}".format(qtc_ver_major, qtc_ver_minor) - qtc_ver_full = "{}.{}".format(qtc_ver_maj, qtc_ver_patch) + qtc_ver_maj = f"{qtc_ver_major}.{qtc_ver_minor}" + qtc_ver_full = f"{qtc_ver_maj}.{qtc_ver_patch}" if qtc_ver_type: - qtc_ver_full = "{ver}-{type}".format(ver = qtc_ver_full, type = qtc_ver_type) + qtc_ver_full = f"{qtc_ver_full}-{qtc_ver_type}" base_url = url_repo_qtc_fmt.format(release_type = release, qtcv_maj = qtc_ver_maj, @@ -152,7 +151,7 @@ def qt_download_check_extract(cfg, dir_install): qt_ver = cfg['versions']['qt_version'] ver_maj, ver_min = qt_ver.split('.') - ver_concat = "{}{}0".format(ver_maj, ver_min) + ver_concat = f"{ver_maj}{ver_min}0" base_url = url_repo_qt_fmt.format( os = sys_os, arch = url_arch, @@ -166,18 +165,11 @@ def qt_download_check_extract(cfg, dir_install): toolchain = os_arch_toolchain[sys_os][sys_arch] - base_package_name = "qt.qt{ver_maj}.{ver_concat}.{compiler}".format( - ver_maj = ver_maj, ver_concat = ver_concat, - compiler = toolchain) - - extra_package_name = "qt.qt{ver_maj}.{ver_concat}.{module}.{compiler}".format( - ver_maj = ver_maj, ver_concat = ver_concat, - module = "{module}", - compiler = toolchain) + base_package_name = f"qt.qt{ver_maj}.{ver_concat}.{toolchain}" extra_package_names = list() for module in cfg['versions']['qt_modules']: - extra_package_names.append(extra_package_name.format(module = module)) + extra_package_names.append(f"qt.qt{ver_maj}.{ver_concat}.{module}.{toolchain}") package_archives = dict() for package in metadata.iter("PackageUpdate"): @@ -209,12 +201,10 @@ def qt_download_check_extract(cfg, dir_install): extract_progress(content, archive_name, dir_install) - qt_path = os.path.join(dir_install, "{}.{}.0".format(ver_maj, ver_min)) + qt_path = os.path.join(dir_install, f"{ver_maj}.{ver_min}.0") qt_archs = os.listdir(qt_path) if len(qt_archs) > 1: - raise RuntimeWarning( - "more than one architecture found in {path}, will use first: {arch}" - .format(path = qt_path, arch = qt_archs[0])) + raise RuntimeWarning(f"more than one architecture found in {qt_path}, will use first: {qt_archs[0]}") return os.path.join(qt_path, qt_archs[0]) @@ -263,5 +253,5 @@ def qt_download_check_extract(cfg, dir_install): if args.export_variables: with open("env", 'w') as f: - f.write("QTC_PATH={}\n".format(dir_qtc)) - f.write("QT_PATH={}\n".format(dir_qt)) + f.write(f"QTC_PATH={dir_qtc}\n") + f.write(f"QT_PATH={dir_qt}\n") diff --git a/src/project_manager/ros_catkin_tools_step.cpp b/src/project_manager/ros_catkin_tools_step.cpp index 8778ad2c..3891ae06 100644 --- a/src/project_manager/ros_catkin_tools_step.cpp +++ b/src/project_manager/ros_catkin_tools_step.cpp @@ -363,7 +363,7 @@ void ROSCatkinToolsStepWidget::updateDetails() m_makeStep->m_catkinMakeArguments = m_ui->catkinMakeArgumentsLineEdit->text(); m_makeStep->m_cmakeArguments = m_ui->cmakeArgumentsLineEdit->text(); m_makeStep->m_makeArguments = m_ui->makeArgumentsLineEdit->text(); - m_makeStep->m_catkinToolsWorkingDir = m_ui->catkinToolsWorkingDirWidget->rawFilePath().toString(); + m_makeStep->m_catkinToolsWorkingDir = m_ui->catkinToolsWorkingDirWidget->unexpandedFilePath().toString(); ROSBuildConfiguration *bc = m_makeStep->rosBuildConfiguration(); ROSUtils::WorkspaceInfo workspaceInfo = ROSUtils::getWorkspaceInfo(bc->project()->projectDirectory(), bc->rosBuildSystem(), bc->project()->distribution()); diff --git a/src/project_manager/ros_package_wizard.cpp b/src/project_manager/ros_package_wizard.cpp index 7cf4156e..334e3a98 100644 --- a/src/project_manager/ros_package_wizard.cpp +++ b/src/project_manager/ros_package_wizard.cpp @@ -372,14 +372,16 @@ bool ROSPackageWizard::writeFiles(const Core::GeneratedFiles &files, QString *er QProcess create_pkg_proc; create_pkg_proc.setWorkingDirectory(packagePath.path()); - ROSUtils::sourceROS(&create_pkg_proc, project->distribution()); + QProcessEnvironment env; + ROSUtils::sourceROS(env, project->distribution()); + create_pkg_proc.setProcessEnvironment(env); create_pkg_proc.start("bash", {"-c", create_args.join(" ")}); if (!create_pkg_proc.waitForStarted(-1)) { - Core::MessageManager::writeFlashing(tr("[ROS Error] Faild to start catkin_create_pkg.")); + Core::MessageManager::writeFlashing(tr("[ROS Error] Failed to start catkin_create_pkg.")); return false; } if (!create_pkg_proc.waitForFinished(-1)) { - Core::MessageManager::writeFlashing(tr("[ROS Error] Faild to finish catkin_create_pkg.")); + Core::MessageManager::writeFlashing(tr("[ROS Error] Failed to finish catkin_create_pkg.")); return false; } const QByteArray message_stdio = create_pkg_proc.readAllStandardOutput(); @@ -392,7 +394,7 @@ bool ROSPackageWizard::writeFiles(const Core::GeneratedFiles &files, QString *er return false; } if (create_pkg_proc.exitStatus() != QProcess::NormalExit) { - Core::MessageManager::writeFlashing(tr("[ROS Error] Faild to create catkin package.")); + Core::MessageManager::writeFlashing(tr("[ROS Error] Failed to create catkin package.")); return false; } return true; diff --git a/src/project_manager/ros_project.cpp b/src/project_manager/ros_project.cpp index cab1bb45..f4afa567 100644 --- a/src/project_manager/ros_project.cpp +++ b/src/project_manager/ros_project.cpp @@ -127,7 +127,7 @@ const int UPDATE_INTERVAL = 300; ROSProject::ROSProject(const Utils::FilePath &fileName) : ProjectExplorer::Project(Constants::ROS_MIME_TYPE, fileName), - m_cppCodeModelUpdater(new CppEditor::CppProjectUpdater), + m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()), m_project_loaded(false), m_asyncUpdateFutureInterface(nullptr), m_asyncBuildCodeModelFutureInterface(nullptr) diff --git a/src/project_manager/ros_project.h b/src/project_manager/ros_project.h index 84bacd27..4540bef3 100644 --- a/src/project_manager/ros_project.h +++ b/src/project_manager/ros_project.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -39,10 +40,6 @@ #include #include -namespace CppEditor { - class CppProjectUpdater; -} - namespace ROSProjectManager { namespace Internal { @@ -88,7 +85,7 @@ private slots: ROSUtils::PackageInfoMap m_wsPackageInfo; ROSUtils::PackageBuildInfoMap m_wsPackageBuildInfo; - CppEditor::CppProjectUpdater *m_cppCodeModelUpdater; + ProjectExplorer::ProjectUpdater *m_cppCodeModelUpdater; // Watching Directories to keep Project Tree updated QTimer m_asyncUpdateTimer; diff --git a/src/project_manager/ros_utils.cpp b/src/project_manager/ros_utils.cpp index 5eedd453..bbfdca08 100644 --- a/src/project_manager/ros_utils.cpp +++ b/src/project_manager/ros_utils.cpp @@ -59,15 +59,15 @@ QString ROSUtils::buildTypeName(const ROSUtils::BuildType &buildType) } } -bool ROSUtils::sourceROS(QProcess *process, const Utils::FilePath &rosDistribution) +bool ROSUtils::sourceROS(QProcessEnvironment &env, const Utils::FilePath &rosDistribution) { - sourceWorkspaceHelper(process, Utils::FilePath(rosDistribution).pathAppended(QLatin1String("setup.bash")).toString()); + sourceWorkspaceHelper(env, Utils::FilePath(rosDistribution).pathAppended(QLatin1String("setup.bash")).toString()); return true; } -bool ROSUtils::sourceWorkspace(QProcess *process, const WorkspaceInfo &workspaceInfo) +bool ROSUtils::sourceWorkspace(QProcessEnvironment &env, const WorkspaceInfo &workspaceInfo) { - if (!initializeWorkspace(process, workspaceInfo)) + if (!initializeWorkspace(env, workspaceInfo)) return false; Utils::FilePath sourcePath(workspaceInfo.develPath); @@ -94,7 +94,7 @@ bool ROSUtils::sourceWorkspace(QProcess *process, const WorkspaceInfo &workspace source_path = QString{}; } - sourceWorkspaceHelper(process, source_path); + sourceWorkspaceHelper(env, source_path); return true; } @@ -169,23 +169,26 @@ bool ROSUtils::initializeWorkspaceFolders(const WorkspaceInfo &workspaceInfo) return true; } -bool ROSUtils::initializeWorkspace(QProcess *process, const WorkspaceInfo &workspaceInfo) +bool ROSUtils::initializeWorkspace(QProcessEnvironment &env, const WorkspaceInfo &workspaceInfo) { WorkspaceInfo workspace = workspaceInfo; - if (sourceROS(process, workspaceInfo.rosDistribution)) + if (sourceROS(env, workspaceInfo.rosDistribution)) { if (!isWorkspaceInitialized(workspaceInfo)) { + QProcess process; + process.setProcessEnvironment(env); + switch (workspaceInfo.buildSystem) { case CatkinMake: { if( !initializeWorkspaceFolders(workspaceInfo) ) return false; - process->setWorkingDirectory(workspaceInfo.sourcePath.toString()); - process->start(QLatin1String("bash"), QStringList() << QStringList() << QLatin1String("-c") << QLatin1String("catkin_init_workspace")); + process.setWorkingDirectory(workspaceInfo.sourcePath.toString()); + process.start(QLatin1String("bash"), QStringList() << QStringList() << QLatin1String("-c") << QLatin1String("catkin_init_workspace")); - if( !process->waitForFinished() ) + if( !process.waitForFinished() ) return false; break; @@ -201,10 +204,10 @@ bool ROSUtils::initializeWorkspace(QProcess *process, const WorkspaceInfo &works if( !initializeWorkspaceFolders(workspace) ) return false; - process->setWorkingDirectory(workspace.path.toString()); - process->start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin init")); + process.setWorkingDirectory(workspace.path.toString()); + process.start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin init")); - if( !process->waitForFinished() ) + if( !process.waitForFinished() ) return false; break; @@ -220,45 +223,46 @@ bool ROSUtils::initializeWorkspace(QProcess *process, const WorkspaceInfo &works break; } - } + } // switch - if (process->exitStatus() != QProcess::CrashExit) - return buildWorkspace(process, workspace); + if (process.exitStatus() != QProcess::CrashExit) + return buildWorkspace(process, workspace); - Core::MessageManager::writeSilently(QObject::tr("[ROS Warning] Failed to initialize workspace: %1.").arg(workspace.path.toString())); - return false; + Core::MessageManager::writeSilently(QObject::tr("[ROS Warning] Failed to initialize workspace: %1.").arg(workspace.path.toString())); + return false; + } // if } return true; } -bool ROSUtils::buildWorkspace(QProcess *process, const WorkspaceInfo &workspaceInfo) +bool ROSUtils::buildWorkspace(QProcess &process, const WorkspaceInfo &workspaceInfo) { switch(workspaceInfo.buildSystem) { case CatkinMake: { - process->setWorkingDirectory(workspaceInfo.path.toString()); - process->start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin_make --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); - process->waitForFinished(); + process.setWorkingDirectory(workspaceInfo.path.toString()); + process.start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin_make --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); + process.waitForFinished(); break; } case CatkinTools: { - process->setWorkingDirectory(workspaceInfo.path.toString()); - process->start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin build --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); - process->waitForFinished(); + process.setWorkingDirectory(workspaceInfo.path.toString()); + process.start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("catkin build --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); + process.waitForFinished(); break; } case Colcon: { - process->setWorkingDirectory(workspaceInfo.path.toString()); - process->start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("colcon build --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); - process->waitForFinished(); + process.setWorkingDirectory(workspaceInfo.path.toString()); + process.start(QLatin1String("bash"), QStringList() << QLatin1String("-c") << QLatin1String("colcon build --cmake-args -G \"CodeBlocks - Unix Makefiles\"")); + process.waitForFinished(); break; } } - if (process->exitStatus() != QProcess::CrashExit) + if (process.exitStatus() != QProcess::CrashExit) return true; Core::MessageManager::writeSilently(QObject::tr("[ROS Warning] Failed to build workspace: %1.").arg(workspaceInfo.path.toString())); @@ -315,29 +319,27 @@ QList ROSUtils::installedDistributions() return distributions; } -void ROSUtils::sourceWorkspaceHelper(QProcess *process, const QString &path) +void ROSUtils::sourceWorkspaceHelper(QProcessEnvironment &env, const QString &path) { - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + if (path.isEmpty()) + return; - if (!path.isEmpty()) - { - const QString cmd = QLatin1String("source ") + path + QLatin1String(" && env"); - process->start(QLatin1String("bash"), QStringList()); - process->waitForStarted(); - process->write(cmd.toLatin1()); - process->closeWriteChannel(); - process->waitForFinished(); - - if (process->exitStatus() != QProcess::CrashExit) - { - while (process->canReadLine()) { - const QStringList env_kv = QString::fromLocal8Bit(process->readLine().trimmed()).split('='); - env.insert(env_kv[0], env_kv[1]); - } - } - } + QProcess process; - process->setProcessEnvironment(env); + const QString cmd = QLatin1String("source ") + path + QLatin1String(" && env"); + process.start(QLatin1String("bash"), QStringList()); + process.waitForStarted(); + process.write(cmd.toLatin1()); + process.closeWriteChannel(); + process.waitForFinished(); + + if (process.exitStatus() == QProcess::CrashExit) + return; + + while (process.canReadLine()) { + const QStringList env_kv = QString::fromLocal8Bit(process.readLine().trimmed()).split('='); + env.insert(env_kv[0], env_kv[1]); + } } bool ROSUtils::generateQtCreatorWorkspaceFile(QXmlStreamWriter &xmlFile, const ROSProjectFileContent &content) @@ -1209,15 +1211,13 @@ ROSUtils::WorkspaceInfo ROSUtils::getWorkspaceInfo(const Utils::FilePath &worksp QProcessEnvironment ROSUtils::getWorkspaceEnvironment(const WorkspaceInfo &workspaceInfo, const Utils::Environment& current_environment) { - QProcess process; - - process.setProcessEnvironment(current_environment.toProcessEnvironment()); - - sourceWorkspace(&process, workspaceInfo); - - QProcessEnvironment env = process.processEnvironment(); + // initialise environment + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert(current_environment.toProcessEnvironment()); env.insert("PWD", workspaceInfo.path.toString()); - env.insert("TERM", "xterm"); + + // source workspaces + sourceWorkspace(env, workspaceInfo); return env; } diff --git a/src/project_manager/ros_utils.h b/src/project_manager/ros_utils.h index dee5ce9d..60f84fe2 100644 --- a/src/project_manager/ros_utils.h +++ b/src/project_manager/ros_utils.h @@ -171,19 +171,19 @@ class ROSUtils { /** * @brief Source ROS - * @param process QProcess to execute the ROS bash command + * @param env environment to create from sourcing workspaces * @param rosDistribution ROS distribution * @return True if successful, otherwise false */ - static bool sourceROS(QProcess *process, const Utils::FilePath &rosDistribution); + static bool sourceROS(QProcessEnvironment &env, const Utils::FilePath &rosDistribution); /** * @brief Source Workspace - * @param process QProcess to execute the ROS bash command + * @param env environment to create from sourcing workspaces * @param workspaceInfo Workspace information * @return True if successful */ - static bool sourceWorkspace(QProcess *process, + static bool sourceWorkspace(QProcessEnvironment &env, const WorkspaceInfo &workspaceInfo); /** @@ -195,11 +195,11 @@ class ROSUtils { /** * @brief Initialize workspace - * @param process QProcess to execute the ROS bash command + * @param env QProcess to execute the ROS bash command * @param workspaceInfo Workspace information * @return True if successfully executed, otherwise false */ - static bool initializeWorkspace(QProcess *process, + static bool initializeWorkspace(QProcessEnvironment &env, const WorkspaceInfo &workspaceInfo); /** @@ -211,11 +211,11 @@ class ROSUtils { /** * @brief Build workspace - * @param process QProcess to execute the catkin_make + * @param process QProcess to execute the build tool commands * @param workspaceInfo Workspace information * @return True if successfully executed, otherwise false */ - static bool buildWorkspace(QProcess *process, + static bool buildWorkspace(QProcess &process, const WorkspaceInfo &workspaceInfo); /** @@ -431,10 +431,10 @@ class ROSUtils { private: /** * @brief sourceWorkspaceHelper - Source workspace helper function - * @param process - QProcess to execute source bash command + * @param env - environment to create from sourcing workspaces * @param path - Path to workspace setup.bash */ - static void sourceWorkspaceHelper(QProcess *process, const QString &path); + static void sourceWorkspaceHelper(QProcessEnvironment &env, const QString &path); /** * @brief This will parse the CodeBlock file and get the build info (incudes, Cxx Flags, etc.) diff --git a/versions.yaml b/versions.yaml index 42e7dec3..42e0d815 100644 --- a/versions.yaml +++ b/versions.yaml @@ -3,8 +3,8 @@ # - https://download.qt.io/official_releases/qtcreator/ # for valid versions # the version schema is: {major}[.{minor}][.{patch}][-{devel}] -qtc_version: "13" +qtc_version: "14" qtc_modules: ["qtcreator", "qtcreator_dev"] -qt_version: "6.6" +qt_version: "6.7" qt_modules: ['qtbase', 'qtdeclarative', 'icu', 'qttools', 'qt5compat']