diff --git a/README.md b/README.md index bdb7046..11b3f10 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,7 @@ Download and install the latest [setup file](https://github.com/b-com-software-b - yum (redhat, fedora, centos) - zypper (openSUSE) - pkg (freebsd) -- pkgutil ( -- ris) +- pkgutil (solaris) - [chocolatey](https://chocolatey.org/) (Windows) - [scoop](https://scoop-docs.vercel.app/) (Windows) - [others to come] @@ -184,9 +183,9 @@ To get a sample how to declare an additional remote/bucket/ppa ... see the repos ### Installing/Configure dependencies -```remaken install [--conan_profile conan_profile_name] [-r path_to_remaken_root] -i [-o linux] -t github [-l nexus -u http://url_to_root_nexus_repo] [--cpp-std 17] [-c debug|release] [--project_mode,-p] [path_to_remaken_dependencies_description_file.txt] ``` +```remaken install [--conan_profile conan_profile_name] [-r path_to_remaken_root] -i [-o linux] -t github [-l nexus -u http://url_to_root_nexus_repo] [--cpp-std 17] [-c debug|release] [--project_mode,-p] [path_to_remaken_dependencies_description_file.txt] [--condition name=value]* [--conan-build dependency]* ``` -```remaken configure [--conan_profile conan_profile_name] [-r path_to_remaken_root] -i [-o linux] -t github [-l nexus -u http://url_to_root_nexus_repo] [--cpp-std 17] [-c debug|release] [--project_mode,-p] [path_to_remaken_dependencies_description_file.txt] ``` +```remaken configure [--conan_profile conan_profile_name] [-r path_to_remaken_root] -i [-o linux] -t github [-l nexus -u http://url_to_root_nexus_repo] [--cpp-std 17] [-c debug|release] [--project_mode,-p] [path_to_remaken_dependencies_description_file.txt] [--condition name=value]* ``` **Notes:** @@ -201,9 +200,12 @@ To get a sample how to declare an additional remote/bucket/ppa ... see the repos - for native compilation: the ```default``` conan profile is used - for cross compilation: remaken expects a ```[os]-[build-toolchain]-[architecture]``` profile to be available - for instance for android build, expects a ```android-clang-armv8``` profile +- ```[--conan_build dependency] ``` is a repeatable option, allows to specify to force rebuild of a conan dependency. Ex : ```--conan-build boost```. +- ```[--condition name=value] ``` is a repeatable option, allows to force a condition without application prompt (useful in CI). Ex : ```--condition USE_GRPC=true```. + #### Configure Conditions -By default, remaken (install or configure) prompt users for enabled or disabled configure conditions +By default, ```remaken install``` and ```remaken configure``` prompt users for enabled or disabled configure conditions. **Note:** A condition is defined just after library name. @@ -213,6 +215,8 @@ a ```configure_conditions.pri``` file can be added into the project root folder DEFINES+=CONDITION1 DEFINES-=CONDITION2 +of + After `remaken install` or `configure`, a `configure_conditions.pri` file is generated in ```.build-rules/[os]-[build-toolchain]-[architecture]``` folder with specified (by file or by user_prompt) enabled conditions. The generated file is used when run remaken configure of qmake (on current project) for enable/disable dependencies automatically. diff --git a/resources/install_remaken_3rdparties.nsh b/resources/install_remaken_3rdparties.nsh index 8574da8..33d3e91 100644 --- a/resources/install_remaken_3rdparties.nsh +++ b/resources/install_remaken_3rdparties.nsh @@ -152,7 +152,8 @@ SectionGroup /e "Chocolatey" CHOCO_TOOLS ;always install/update conan ;IfFileExists $1\Python3\Scripts\conan.exe conan_exists - ExecWait '$python_install_dir\Scripts\pip install --upgrade conan' + # 2023/03/08 set conan 1.x version + ExecWait '$python_install_dir\Scripts\pip install --upgrade conan==1.59.0' # remove old conan-commnunity remote ExecWait '$python_install_dir\Scripts\conan remote remove conan-community' # remove binCrafters and conan-center remote url diff --git a/scripts/unixes/build_remaken.sh b/scripts/unixes/build_remaken.sh new file mode 100755 index 0000000..cbd7c0f --- /dev/null +++ b/scripts/unixes/build_remaken.sh @@ -0,0 +1,35 @@ +#!/bin/bash +QTVERSION=5.15.2 +PROJECTROOT=../.. + +# default linux values +QMAKEPATH=$HOME/Qt/${QTVERSION}/gcc_64/bin +if [[ "$OSTYPE" == "darwin"* ]]; then + # overload for mac values + QMAKE_PATH=/Application/Qt/${QTVERSION}/clang_64/bin +fi + +display_usage() { + echo "This script builds Remaken in shared mode." + echo "It can receive three optional arguments." + echo -e "\nUsage: \$0 [path to xpcf project root | default='${PROJECTROOT}'] [Qt kit version to use | default='${QTVERSION}'] [path to qmake | default='${QMAKEPATH}'] \n" +} + +# check whether user had supplied -h or --help . If yes display usage +if [[ ( $1 == "--help") || $1 == "-h" ]] +then + display_usage + exit 0 +fi + +if [ $# -ge 1 ]; then + PROJECTROOT=$1 +fi +if [ $# -ge 2 ]; then + QTVERSION=$2 +fi +if [ $# -eq 3 ]; then + QMAKEPATH=$3 +fi + +${PROJECTROOT}/scripts/unixes/build_remaken_project.sh remaken shared ${PROJECTROOT} ${QTVERSION} ${QMAKEPATH} diff --git a/scripts/unixes/build_remaken_project.sh b/scripts/unixes/build_remaken_project.sh new file mode 100755 index 0000000..caf498d --- /dev/null +++ b/scripts/unixes/build_remaken_project.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +QTVERSION=5.15.2 +PROJECTROOT=../.. +MODE=shared +QMAKE_MODE="" + +# default linux values +QMAKE_PATH=$HOME/Qt/${QTVERSION}/gcc_64/bin +QMAKE_SPEC=linux-g++ +if [[ "$OSTYPE" == "darwin"* ]]; then + # overload for mac values + QMAKE_PATH=/Application/Qt/${QTVERSION}/clang_64/bin + QMAKE_SPEC=macx-clang +fi + +display_usage() { + echo "This script builds a remaken project." + echo "It takes the project name as first argument and can receive four optional arguments." + echo -e "\nUsage: \$0 [project name] [ build mode {shared|static} | default='${MODE}' ] [path to project root | default='${PROJECTROOT}'] [Qt kit version to use | default='${QTVERSION}'] [path to qmake | default='${QMAKEPATH}'] \n" +} + +# check whether user had supplied -h or --help . If yes display usage +if [[ ( $1 == "--help") || $1 == "-h" || $# -eq 0 ]] +then + display_usage + exit 0 +fi + +if [ $# -ge 1 ]; then + PROJECTNAME=$1 +fi +if [ $# -ge 2 ]; then + MODE=$2 +fi +if [ $# -ge 3 ]; then + PROJECTROOT=$3 +fi +if [ $# -ge 4 ]; then + QTVERSION=$4 +fi +if [ $# -eq 5 ]; then + QMAKE_PATH=$5 +fi + +if [[ ${MODE} != "shared" && ${MODE} != "static" ]]; then + echo "mode must be either shared or static - ${MODE} is an unsupported value" + exit 2 +fi + +if [[ ${MODE} == "static" ]]; then + QMAKE_MODE=CONFIG+=staticlib + echo "${MODE} build enabled: building with ${QMAKE_MODE} option" +fi + +if [ ! -d ${QMAKE_PATH} ]; then + echo "Qt path '${QMAKE_PATH}' doesn't exist : check your Qt installation and kits" + exit 2 +fi + +if [ ! -d ${PROJECTROOT} ]; then + echo "Project root path '${PROJECTROOT}' doesn't exist" + exit 2 +fi +if [ ! -e ${PROJECTROOT}/${PROJECTNAME}.pro ]; then + echo "Project path '${PROJECTROOT}/${PROJECTNAME}.pro' doesn't exist" + echo "Trying ${PROJECTROOT}/${PROJECTNAME}/${PROJECTNAME}.pro" + if [ -e ${PROJECTROOT}/${PROJECTNAME}/${PROJECTNAME}.pro ]; then + PROJECTROOT=${PROJECTROOT}/${PROJECTNAME} + else + echo "Project path '${PROJECTROOT}/${PROJECTNAME}/${PROJECTNAME}.pro' doesn't exist" + exit 2 + fi +fi +if [[ ! ${PROJECTROOT:0:1} = / ]]; then + PROJECTROOT=../../../${PROJECTROOT} +fi +echo "Project path used is : ${PROJECTROOT}/${PROJECTNAME}.pro" +source set_brew_env.sh + + +BUILDROOTFOLDER=build-${PROJECTNAME} + +if [ -d ${BUILDROOTFOLDER}/${MODE} ]; then + rm -rf ${BUILDROOTFOLDER}/${MODE} +fi +mkdir -p ${BUILDROOTFOLDER}/${MODE}/debug +mkdir -p ${BUILDROOTFOLDER}/${MODE}/release +echo "===========> building ${PROJECTNAME} project <===========" +pushd ${BUILDROOTFOLDER}/${MODE}/debug +`${QMAKE_PATH}/qmake ${PROJECTROOT}/${PROJECTNAME}.pro -spec ${QMAKE_SPEC} ${QMAKE_MODE} CONFIG+=debug CONFIG+=x86_64 CONFIG+=qml_debug && /usr/bin/make qmake_all` +make +make install +popd +pushd ${BUILDROOTFOLDER}/${MODE}/release +`${QMAKE_PATH}/qmake ${PROJECTROOT}/${PROJECTNAME}.pro -spec ${QMAKE_SPEC} ${QMAKE_MODE} CONFIG+=x86_64 CONFIG+=qml_debug && /usr/bin/make qmake_all` +make +make install +popd + diff --git a/scripts/unixes/clean_remaken_builds.sh b/scripts/unixes/clean_remaken_builds.sh new file mode 100755 index 0000000..2805ab9 --- /dev/null +++ b/scripts/unixes/clean_remaken_builds.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for i in $(find . -type d -name build-\*) +do + echo "Removing $i folder" + rm -rf $i +done diff --git a/scripts/win/build_remaken.bat b/scripts/win/build_remaken.bat new file mode 100644 index 0000000..67fb43e --- /dev/null +++ b/scripts/win/build_remaken.bat @@ -0,0 +1,39 @@ +@echo off +setlocal + +REM default parameter value +set QTVERSION=6.2.2 +set PROJECTROOT=../.. +set QMAKEPATH=C:\Qt\%QTVERSION%\msvc2019_64\bin + +REM check whether user had supplied -h or --help . If yes display usage +for %%A in ("--help" "-h") do if "%1"==%%A (call:display_usage %1 & exit /b 0) + +REM default win walues +if NOT [%1]==[] set PROJECTROOT=%1 +if NOT [%2]==[] set QTVERSION=%2 +if NOT [%3]==[] set QMAKEPATH=%3 + +if not exist %PROJECTROOT% (echo "Remaken project root path '%PROJECTROOT%' doesn't exist" & exit /b 2) +echo "Remaken project root path used is : %PROJECTROOT%" +if not exist %QMAKEPATH% (echo "qmake.exe path 'QMAKEPATH' doesn't exist" & exit /b 2) +echo "qmake path used is : %QMAKEPATH%" + +call %PROJECTROOT%/scripts/win/build_remaken_project.bat remaken shared %PROJECTROOT% %QTVERSION% %QMAKEPATH% + +endlocal +goto:eof + +::-------------------------------------------------------- +::-- Function display_usage starts below here +::-------------------------------------------------------- + +:display_usage + +echo This script builds Remaken in shared mode. +echo It can receive three optional argument. +echo. +echo Usage: param [path to remaken project root - default='%PROJECTROOT%'] [Qt kit version to use - default='%QTVERSION%'] [path to qmake.exe - default='%QMAKEPATH%'] +exit /b 0 + +:end diff --git a/scripts/win/build_remaken_project.bat b/scripts/win/build_remaken_project.bat new file mode 100644 index 0000000..105926e --- /dev/null +++ b/scripts/win/build_remaken_project.bat @@ -0,0 +1,93 @@ +@echo off +setlocal + +REM default parameter value +set QTVERSION=6.2.2 +set PROJECTROOT=../.. +set MODE=shared +set QMAKEMODE= + +REM check whether user had supplied -h or --help . If yes display usage +for %%A in ("--help" "-h") do if "%1"==%%A (call:display_usage %1 & exit /b 0) + +REM default win walues +if not "%1" == "" goto args_count_ok +:args_count_ko +call:display_usage +exit /b 1 +:args_count_ok + +set PROJECTNAME=%1 +if NOT [%2]==[] set MODE=%2 +if NOT [%3]==[] set PROJECTROOT=%3 +if NOT [%4]==[] set QTVERSION=%4 + +set JOM_PATH=c:\Qt\Tools\QtCreator\bin\jom +set QMAKE_PATH=C:\Qt\%QTVERSION%\msvc2019_64\bin + +if not %MODE%==shared (if not %MODE%==static (echo "mode must be either shared or static - %MODE% is an unsupported value" & exit /b 2) ) +if %MODE%==static ( + set QMAKEMODE="CONFIG+=staticlib" + if %MODE%==static (echo "%MODE% build enabled: building with "CONFIG+=staticlib" option") +) + +if not exist %QMAKE_PATH% (echo "Qt path '%QMAKE_PATH%' doesn't exist : check your Qt installation and kits" & exit /b 2) + +if not exist %PROJECTROOT% (echo "Project root path '%PROJECTROOT%' doesn't exist" & exit /b 2) + +if not exist %PROJECTROOT%/%PROJECTNAME%.pro ( + echo "Project path '%PROJECTROOT%/%PROJECTNAME%.pro' doesn't exist" + echo "Trying %PROJECTROOT%/%PROJECTNAME%/%PROJECTNAME%.pro" + if exist %PROJECTROOT%/%PROJECTNAME%/%PROJECTNAME%.pro (set PROJECTROOT=%PROJECTROOT%/%PROJECTNAME%) else echo ("Project path '%PROJECTROOT%/%PROJECTNAME%/%PROJECTNAME%.pro' doesn't exist" & exit /b /2) +) + +REM check path is relative or absolute +if not %PROJECTROOT:~1,1%==: (set PROJECTROOT=../../../%PROJECTROOT%) +echo "Project root path used is : %PROJECTROOT%" +echo "Project path used is : %PROJECTROOT%/%PROJECTNAME%.pro" + +REM call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvars64.bat" +REM call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" +@REM setup Visual Studio environment +set output=setup_script.txt +call init_compiler_env_script.bat --year 2019 --output %output% +set /p setup_script=<"%output%" +call "%setup_script%" +del %output% + +set BUILDROOTFOLDER=build-%PROJECTNAME% + +if exist %BUILDROOTFOLDER%\%MODE% rmdir /S /Q %BUILDROOTFOLDER%\%MODE% +if not exist %BUILDROOTFOLDER%\%MODE%\debug mkdir %BUILDROOTFOLDER%\%MODE%\debug +if not exist %BUILDROOTFOLDER%\%MODE%\release mkdir %BUILDROOTFOLDER%\%MODE%\release + +echo "===========> building %PROJECTNAME% static <===========" +pushd %BUILDROOTFOLDER%\%MODE%\debug +%QMAKE_PATH%\qmake.exe %PROJECTROOT%/%PROJECTNAME%.pro -spec win32-msvc CONFIG+=debug %QMAKEMODE% +%JOM_PATH%\jom.exe +%JOM_PATH%\jom.exe install +%JOM_PATH%\jom.exe create_setup + +popd +pushd %BUILDROOTFOLDER%\\%MODE%\release +%QMAKE_PATH%\qmake.exe %PROJECTROOT%/%PROJECTNAME%.pro -spec win32-msvc %QMAKEMODE% +%JOM_PATH%\jom.exe +%JOM_PATH%\jom.exe create_setup +popd + +endlocal +goto:eof + +::-------------------------------------------------------- +::-- Function display_usage starts below here +::-------------------------------------------------------- + +:display_usage + +echo This script builds a remaken project. +echo It takes the project name as first argument and can receive threes optional arguments. +echo. +echo "Usage: [project name] [ build mode {shared|static} | default='%MODE%' ] [path to project root - default='%PROJECTROOT%'] [Qt kit version to use - default='%QTVERSION%']" +exit /b 0 + +:end diff --git a/scripts/win/clean_builds.bat b/scripts/win/clean_builds.bat new file mode 100644 index 0000000..99eeb28 --- /dev/null +++ b/scripts/win/clean_builds.bat @@ -0,0 +1,22 @@ +@echo off +cls +setlocal + +for /f "delims=" %%D in ('dir /a:d /b build-*') do ( + echo "Removing %%~fD folder" + rmdir /S /Q %%~FD +) + +for /f "delims=" %%D in ('dir /a:d /b test-*') do ( + echo "Removing %%~fD folder" + rmdir /S /Q %%~FD +) + +rm out.txt + +endlocal +goto:eof + +:end + + diff --git a/scripts/win/init_compiler_env_script.bat b/scripts/win/init_compiler_env_script.bat new file mode 100644 index 0000000..262d63e --- /dev/null +++ b/scripts/win/init_compiler_env_script.bat @@ -0,0 +1,82 @@ +@setlocal enableextensions enabledelayedexpansion +@echo off + +REM ##################### +REM Parameters processing +REM ##################### +for %%A in (%*) do ( + if /I "%%A"=="--help" (call:display_usage %1 & exit /b 0) + if /I "%%A"=="-h" (call:display_usage %1 & exit /b 0) +) + +set year="" +set output="" + +for %%A in (%*) do ( + if "!yearFound!"=="true" ( + set year=%%A + goto yearParamProcessed + ) + if "%%A"=="--year" set yearFound=true + if "%%A"=="-y" set yearFound=true +) +:yearParamProcessed + +for %%A in (%*) do ( + if "!outputFound!"=="true" ( + set output=%%A + goto outputParamProcessed + ) + if "%%A"=="--output" set outputFound=true + if "%%A"=="-o" set outputFound=true +) +:outputParamProcessed + +REM ##################################################### +REM Search of the batch initializing compiler environment +REM ##################################################### +if not exist "c:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" ( + echo "vswhere.exe not installed, unable to find compiler path" + goto end +) + +set path="" +for /F "delims=" %%i in ('"c:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -requires Microsoft.Component.MSBuild -property installationPath') do ( + if %year%=="" ( + set path=%%i + goto displayPath + ) + set temp=%%i + set temp=!temp:%year%=! + if not !temp!==%%i ( + set path=%%i + goto displayPath + ) +) + +:displayPath +if !path!=="" ( + echo "Error: no path found for %year%" + goto end +) +if not %output%=="" ( + echo set Visual Studio environment: !path!\VC\Auxiliary\Build\vcvars64.bat + echo !path!\VC\Auxiliary\Build\vcvars64.bat > %output% +) else ( + echo !path!\VC\Auxiliary\Build\vcvars64.bat +) + +goto end + +:display_usage +echo This script searches for the path of the batch to execute to set up environment for Visual Studio compiler and writes it in a file +echo It takes the year of Visual Studio (2017, 2019, ...) and a file path to write the result. +echo +echo init_compiler_env_script [option ] +echo option: +echo - --help or -h display usage +echo - --year or -y define year of Visual Studio to search +echo - --output or -o define file path to write path of the batch to execute to set up the environment of Visual Studio compiler +exit /b 0 + +:end \ No newline at end of file diff --git a/src/CmdOptions.cpp b/src/CmdOptions.cpp index ac4d6a4..a5bb680 100755 --- a/src/CmdOptions.cpp +++ b/src/CmdOptions.cpp @@ -196,6 +196,7 @@ CmdOptions::CmdOptions() // CONFIGURE COMMAND CLI::App * configureCommand = m_cliApp.add_subcommand("configure", "configure project dependencies"); configureCommand->add_option("file", m_dependenciesFile, "Remaken dependencies files - must be located in project root"); // ,true); + configureCommand->add_option("--condition", m_configureConditions, "set condition to value"); // INFO COMMAND CLI::App * infoCommand = m_cliApp.add_subcommand("info", "Read package dependencies informations"); @@ -250,6 +251,7 @@ CmdOptions::CmdOptions() installCommand->add_option("--ziptool,-z", m_zipTool, "unzipper tool name : unzip, compact ..."); // ,true); installCommand->add_flag("--remote-only", m_remoteOnly, "Only add remote/source/tap from package dependencies, dependencies are not installed"); // same as remote add command installCommand->add_option("--conan-build", m_conanForceBuildRefs, "conan force build reference"); + installCommand->add_option("--condition", m_configureConditions, "set condition to value"); // LIST COMMAND CLI::App * listCommand = m_cliApp.add_subcommand("list", "list remaken installed dependencies. If package is provided, list the package available version. If package and version are provided, list the package files"); diff --git a/src/CmdOptions.h b/src/CmdOptions.h index c58aadc..8d287c0 100755 --- a/src/CmdOptions.h +++ b/src/CmdOptions.h @@ -70,6 +70,10 @@ class CmdOptions return m_conanForceBuildRefs; } + const std::vector & getConfigureConditions() const { + return m_configureConditions; + } + const std::string & getXpcfXmlFile() const { return m_xpcfConfigurationFile; } @@ -331,6 +335,7 @@ class CmdOptions bool m_debugEnabled = false; bool m_remoteOnly = false; std::vector m_conanForceBuildRefs; + std::vector m_configureConditions; CLI::App m_cliApp{"remaken"}; }; diff --git a/src/commands/ConfigureCommand.cpp b/src/commands/ConfigureCommand.cpp index f6bc81e..d9d5e63 100755 --- a/src/commands/ConfigureCommand.cpp +++ b/src/commands/ConfigureCommand.cpp @@ -48,6 +48,26 @@ int ConfigureCommand::execute() // try to parse generated conditions file in build platform folder generator->parseConditionsFile(depFolder/DepUtils::getBuildPlatformFolder(m_options), conditionsMap); } + + // Manage force configure conditions by command line + for (auto & arg : m_options.getConfigureConditions()) { + std::vector condition; + boost::split(condition, arg, [](char c){return c == '=';}); + string conditionName = condition[0]; + string conditionValue; + if (condition.size() >= 2) { + conditionValue = condition[1]; + } + if (!conditionName.empty() && !conditionValue.empty()) { + if (boost::iequals(conditionValue, "true")) { + conditionsMap.insert_or_assign(conditionName, true); + } + else if (boost::iequals(conditionValue, "false")) { + conditionsMap.insert_or_assign(conditionName, false); + } + } + } + if (m_options.projectModeEnabled()) { m_options.setProjectRootPath(depFolder); } diff --git a/src/managers/DependencyManager.cpp b/src/managers/DependencyManager.cpp index 9bf20b0..de05b93 100755 --- a/src/managers/DependencyManager.cpp +++ b/src/managers/DependencyManager.cpp @@ -313,6 +313,26 @@ void DependencyManager::retrieveDependencies(const fs::path & dependenciesFile, std::map conditionsMap; std::shared_ptr generator = BackendGeneratorFactory::getGenerator(m_options); generator->parseConditionsFile(dependenciesFile.parent_path(), conditionsMap); + + // Manage force configure conditions by command line + for (auto & arg : m_options.getConfigureConditions()) { + std::vector condition; + boost::split(condition, arg, [](char c){return c == '=';}); + string conditionName = condition[0]; + string conditionValue; + if (condition.size() >= 2) { + conditionValue = condition[1]; + } + if (!conditionName.empty() && !conditionValue.empty()) { + if (boost::iequals(conditionValue, "true")) { + conditionsMap.insert_or_assign(conditionName, true); + } + else if (boost::iequals(conditionValue, "false")) { + conditionsMap.insert_or_assign(conditionName, false); + } + } + } + std::vector conditionsDependencies; for (fs::path depsFile : dependenciesFileList) { if (fs::exists(depsFile)) {