diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-linux-pack-containers.yml similarity index 72% rename from .github/workflows/build-containers.yml rename to .github/workflows/build-linux-pack-containers.yml index 68c2195aa..29a00fee0 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-linux-pack-containers.yml @@ -1,9 +1,11 @@ --- -name: Build development containers +name: Build Linux containers for packaging on: workflow_dispatch: + # DDD + push: jobs: - build-container: + build-packaging-container: runs-on: ubuntu-latest strategy: fail-fast: false @@ -24,13 +26,11 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build the image and push it to the registry + id: docker-build uses: docker/build-push-action@v2 with: - # relative path to the place where source code with Dockerfile is located - context: ./packaging/dockerfiles - file: ./packaging/dockerfiles/Dockerfile.${{ matrix.os }} - # Note: tags must be lower-case + file: ./packaging/dockerfiles/linux/Dockerfile.${{ matrix.os }} tags: ghcr.io/khiopsml/khiops/khiopsdev-${{ matrix.os }}:latest push: true - name: Display the image digest - run: echo ${{ steps.docker_build.outputs.digest }} + run: echo ${{ steps.docker-build.outputs.digest }} diff --git a/.github/workflows/build-nsis-reqs-container.yml b/.github/workflows/build-nsis-reqs-container.yml new file mode 100644 index 000000000..1297bc7a1 --- /dev/null +++ b/.github/workflows/build-nsis-reqs-container.yml @@ -0,0 +1,47 @@ +--- +name: Build NSIS requirements container +on: + workflow_dispatch: +jobs: + build-requirements-container: + name: "Build NSIS software requirements container" + runs-on: ubuntu-latest + permissions: + packages: write + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + - name: Login to Github Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build the image and push it to the registry + id: docker-build + uses: docker/build-push-action@v2 + with: + file: ./packaging/dockerfiles/windows/nsis-requirements/Dockerfile + tags: ghcr.io/khiopsml/khiops/khiops-nsis-requirements:latest + push: true + - name: Display the image digest + run: echo ${{ steps.docker-build.outputs.digest }} + test-requirements-container: + name: "Test NSIS software requirements container" + runs-on: ubuntu-latest + needs: build-requirements-container + container: ghcr.io/khiopsml/khiops/khiops-nsis-requirements:latest + permissions: + packages: read + steps: + - name: Test installer files existence + shell: bash + run: |- + cd /var/share/nsis-requirements + test -f $JRE_FILENAME + test -f $KHIOPS_VIZ_FILENAME + test -f $KHIOPS_COVIZ_FILENAME + test -f $MSMPI_FILENAME diff --git a/.github/workflows/pack-nsis.yml b/.github/workflows/pack-nsis.yml new file mode 100644 index 000000000..5f7020994 --- /dev/null +++ b/.github/workflows/pack-nsis.yml @@ -0,0 +1,94 @@ +--- +name: Build NSIS Windows installer +on: + workflow_dispatch: + # DDD + push: +jobs: + retrieve-nsis-requirements: + name: Retrieve NSIS installer software requirements + runs-on: ubuntu-latest + container: ghcr.io/khiopsml/khiops/khiops-nsis-requirements:latest + outputs: + jre-filename: ${{ steps.save-file-data.outputs.jre-filename }} + jre-version: ${{ steps.save-file-data.outputs.jre-version }} + khiops-viz-filename: ${{ steps.save-file-data.outputs.khiops-viz-filename }} + khiops-viz-version: ${{ steps.save-file-data.outputs.khiops-viz-version }} + khiops-coviz-filename: ${{ steps.save-file-data.outputs.khiops-coviz-filename }} + khiops-coviz-version: ${{ steps.save-file-data.outputs.khiops-coviz-version }} + msmpi-filename: ${{ steps.save-file-data.outputs.msmpi-filename }} + msmpi-version: ${{ steps.save-file-data.outputs.msmpi-version }} + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Upload NSIS package requirements + uses: actions/upload-artifact@v3.1.2 + with: + name: nsis-requirements + path: /var/share/nsis-requirements/* + retention-days: 7 + - name: Save package file data to the environment + id: save-file-data + run: | + echo "jre-filename=$JRE_FILENAME" >> "$GITHUB_OUTPUT" + echo "jre-version=$JRE_VERSION" >> "$GITHUB_OUTPUT" + echo "khiops-viz-filename=$KHIOPS_VIZ_FILENAME" >> "$GITHUB_OUTPUT" + echo "khiops-viz-version=$KHIOPS_VIZ_VERSION" >> "$GITHUB_OUTPUT" + echo "khiops-coviz-filename=$KHIOPS_COVIZ_FILENAME" >> "$GITHUB_OUTPUT" + echo "khiops-coviz-version=$KHIOPS_COVIZ_VERSION" >> "$GITHUB_OUTPUT" + echo "msmpi-filename=$MSMPI_FILENAME" >> "$GITHUB_OUTPUT" + echo "msmpi-version=$MSMPI_VERSION" >> "$GITHUB_OUTPUT" + build-nsis-installer: + name: Build NSIS Windows installer + needs: retrieve-nsis-requirements + runs-on: windows-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + - name: Download NSIS requirements + uses: actions/download-artifact@v3.0.2 + with: + name: nsis-requirements + path: ./packaging/windows/nsis/nsis-requirements + - name: Build Khiops binaries + uses: ./.github/actions/build-khiops + with: + preset-name: windows-msvc-release + targets: MODL MODL_Coclustering norm_jar khiops_jar + override-flags: -DTESTING=OFF + - name: Build NSIS package + shell: pwsh + run: |- + cd ./packaging/windows/nsis + makensis ` + /DKHIOPS_VERSION=10.1.5 ` + /DKHIOPS_WINDOWS_BUILD_DIR=..\..\..\build\windows-msvc-release ` + /DJRE_INSTALLER_PATH=.\nsis-requirements\${{ needs.retrieve-nsis-requirements.outputs.jre-filename }} ` + /DMSMPI_INSTALLER_PATH=.\nsis-requirements\${{ needs.retrieve-nsis-requirements.outputs.msmpi-filename }} ` + /DKHIOPS_VIZ_INSTALLER_PATH=.\nsis-requirements\${{ needs.retrieve-nsis-requirements.outputs.khiops-viz-filename }} ` + /DKHIOPS_COVIZ_INSTALLER_PATH=.\nsis-requirements\${{ needs.retrieve-nsis-requirements.outputs.khiops-coviz-filename }} ` + khiops.nsi + - name: Upload installer as artifact + uses: actions/upload-artifact@v3.1.2 + with: + name: khiops-installer + path: ./packaging/windows/nsis/khiops-10.1.5-setup.exe + test-nsis-installer: + name: Test NSIS Windows installer + needs: build-nsis-installer + runs-on: windows-2019 + steps: + - name: Download NSIS installer artifact + uses: actions/download-artifact@v3.0.2 + with: + name: khiops-installer + path: ./khiops-10.1.5-setup.exe + - name: Install Khiops + shell: pwsh + run: | + dir + Get-Host + powershell -Command $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; Start-Process -FilePath .\khiops-10.1.5-setup.exe -ArgumentList '/S' -Wait; + - name: Check the installation + run: |- + $Env:ProgramFiles\khiops\bin\khiops.cmd -v diff --git a/packaging/common/images/installer_khiops.ico b/packaging/common/images/installer_khiops.ico new file mode 100644 index 000000000..95d877710 Binary files /dev/null and b/packaging/common/images/installer_khiops.ico differ diff --git a/packaging/common/images/khiops.ico b/packaging/common/images/khiops.ico new file mode 100644 index 000000000..4be84ba01 Binary files /dev/null and b/packaging/common/images/khiops.ico differ diff --git a/packaging/common/images/khiops_coclustering.ico b/packaging/common/images/khiops_coclustering.ico new file mode 100644 index 000000000..4d479036e Binary files /dev/null and b/packaging/common/images/khiops_coclustering.ico differ diff --git a/packaging/dockerfiles/Dockerfile.rocky8 b/packaging/dockerfiles/linux/Dockerfile.rocky8 similarity index 100% rename from packaging/dockerfiles/Dockerfile.rocky8 rename to packaging/dockerfiles/linux/Dockerfile.rocky8 diff --git a/packaging/dockerfiles/Dockerfile.rocky9 b/packaging/dockerfiles/linux/Dockerfile.rocky9 similarity index 100% rename from packaging/dockerfiles/Dockerfile.rocky9 rename to packaging/dockerfiles/linux/Dockerfile.rocky9 diff --git a/packaging/dockerfiles/Dockerfile.ubuntu18.04 b/packaging/dockerfiles/linux/Dockerfile.ubuntu18.04 similarity index 100% rename from packaging/dockerfiles/Dockerfile.ubuntu18.04 rename to packaging/dockerfiles/linux/Dockerfile.ubuntu18.04 diff --git a/packaging/dockerfiles/Dockerfile.ubuntu20.04 b/packaging/dockerfiles/linux/Dockerfile.ubuntu20.04 similarity index 100% rename from packaging/dockerfiles/Dockerfile.ubuntu20.04 rename to packaging/dockerfiles/linux/Dockerfile.ubuntu20.04 diff --git a/packaging/dockerfiles/Dockerfile.ubuntu22.04 b/packaging/dockerfiles/linux/Dockerfile.ubuntu22.04 similarity index 100% rename from packaging/dockerfiles/Dockerfile.ubuntu22.04 rename to packaging/dockerfiles/linux/Dockerfile.ubuntu22.04 diff --git a/packaging/dockerfiles/windows/nsis-requirements/Dockerfile b/packaging/dockerfiles/windows/nsis-requirements/Dockerfile new file mode 100644 index 000000000..d6fe8fc33 --- /dev/null +++ b/packaging/dockerfiles/windows/nsis-requirements/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:22.04 + +ENV JRE_FILENAME="jre-8u371-windows-x64.exe" +ENV JRE_VERSION="8u371" +ENV KHIOPS_VIZ_FILENAME="khiops-visualization-Setup-10.2.8.exe" +ENV KHIOPS_VIZ_VERSION="10.2.8" +ENV KHIOPS_COVIZ_FILENAME="khiops-covisualization-Setup-10.2.4.exe" +ENV KHIOPS_COVIZ_VERSION="10.2.4" +ENV MSMPI_FILENAME="msmpisetup.exe" +ENV MSMPI_VERSION="10.1.3" + +RUN true \ + && apt-get update -y \ + && apt-get install -y --no-install-recommends wget ca-certificates \ + && mkdir -p /var/share/nsis-requirements \ + && cd /var/share/nsis-requirements \ + && wget -O ${JRE_FILENAME} \ + https://javadl.oracle.com/webapps/download/AutoDL?BundleId=248242_ce59cff5c23f4e2eaf4e778a117d4c5b \ + && wget -O ${KHIOPS_VIZ_FILENAME} \ + https://github.com/khiopsrelease/kv-release/releases/download/v10.2.8/khiops-visualization-Setup-10.2.8.exe \ + && wget -O ${KHIOPS_COVIZ_FILENAME} \ + https://github.com/khiopsrelease/kc-release/releases/download/v10.2.4/khiops-covisualization-Setup-10.2.4.exe \ + && wget -O ${MSMPI_FILENAME} \ + https://download.microsoft.com/download/7/2/7/72731ebb-b63c-4170-ade7-836966263a8f/msmpisetup.exe \ + && apt-get remove -y wget ca-certificates \ + && apt-get clean autoclean \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && true diff --git a/packaging/windows/nsis/CreateKhiopsCmdFileFunc.nsh b/packaging/windows/nsis/CreateKhiopsCmdFileFunc.nsh new file mode 100644 index 000000000..3fce501e9 --- /dev/null +++ b/packaging/windows/nsis/CreateKhiopsCmdFileFunc.nsh @@ -0,0 +1,119 @@ +!include "FileFunc.nsh" +!include "x64.nsh" + +# Macro to create the khiops.cmd script +# Example: +# ${CreateKhiopsCmdFile} "$INSTDIR\khiops.cmd" "MODL" "" "$INSTDIR" "scenario._kh" "log.txt" "1" +# +!define CreateKhiopsCmdFile "!insertmacro CreateKhiopsCmdFile" +!macro CreateKhiopsCmdFile FileName ToolName BinSuffix KhiopsHome ScenarioFileName LogFileName ParallelMode + Push "${ParallelMode}" + Push "${LogFileName}" + Push "${ScenarioFileName}" + Push "${KhiopsHome}" + Push "${BinSuffix}" + Push "${ToolName}" + Push "${FileName}" + Call CreateKhiopsCmdFile +!macroend + + +Function CreateKhiopsCmdFile + # Function parameters + Var /GLOBAL _FileName + Var /GLOBAL _ToolName + Var /GLOBAL _BinSuffix + Var /GLOBAL _KhiopsHome + Var /GLOBAL _ScenarioFileName + Var /GLOBAL _LogFileName + Var /GLOBAL _ParallelMode + + # Retrieve parameters from stack + Pop $_FileName + Pop $_ToolName + Pop $_BinSuffix + Pop $_KhiopsHome + Pop $_ScenarioFileName + Pop $_LogFileName + Pop $_ParallelMode + + # Open file to create + FileOpen $0 "$_FileName" w + + # Write file + FileWrite $0 `@echo off$\r$\n` + FileWrite $0 `setlocal$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM ========================================================$\r$\n` + FileWrite $0 `REM See the khiops_env script for full documentation on the$\r$\n` + FileWrite $0 `REM environment variables used by Khiops$\r$\n` + FileWrite $0 `REM ========================================================$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM ========================================================$\r$\n` + FileWrite $0 `REM Initialization of the installation directory of Khiops$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Test is Khiops environment already set up$\r$\n` + FileWrite $0 `if "%KHIOPS_HOME%".=="". set KHIOPS_HOME=$_KhiopsHome$\r$\n` + FileWrite $0 `if not exist "%KHIOPS_HOME%\bin$_BinSuffix\$_ToolName.exe" goto ERR_PATH$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Test if batch mode from parameters$\r$\n` + FileWrite $0 `set _KHIOPS_BATCH_MODE=$\r$\n` + FileWrite $0 `for %%i in (%*) do if %%i.==-b. set _KHIOPS_BATCH_MODE=true$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Initialize Khiops env variables$\r$\n` + FileWrite $0 `call "%KHIOPS_HOME%\bin\khiops_env" --env > NUL$\r$\n` + FileWrite $0 `if not %_KHIOPS_BATCH_MODE%.==true. if not exist "%KHIOPS_JAVA_PATH%\jvm.dll" goto ERR_JAVA$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Set path$\r$\n` + FileWrite $0 `set path=%KHIOPS_PATH%;%KHIOPS_JAVA_PATH%;%path%$\r$\n` + FileWrite $0 `set classpath=%KHIOPS_CLASSPATH%;%classpath%$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM ========================================================$\r$\n` + FileWrite $0 `REM Start Khiops (with or without parameteres)$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `if %1.==. goto NOPARAMS$\r$\n` + FileWrite $0 `if not %1.==. goto PARAMS$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Start without parameters$\r$\n` + FileWrite $0 `:NOPARAMS$\r$\n` + FileWrite $0 `if not exist "%KHIOPS_LAST_RUN_DIR%" md "%KHIOPS_LAST_RUN_DIR%"$\r$\n` + FileWrite $0 `if not exist "%KHIOPS_LAST_RUN_DIR%" goto PARAMS$\r$\n` + ${If} $_ParallelMode == "0" + FileWrite $0 `"%KHIOPS_PATH%$_BinSuffix\$_ToolName" -o "%KHIOPS_LAST_RUN_DIR%\$_ScenarioFileName" -e "%KHIOPS_LAST_RUN_DIR%\$_LogFileName"$\r$\n` + ${Else} + FileWrite $0 `%KHIOPS_MPI_COMMAND% "%KHIOPS_PATH%$_BinSuffix\$_ToolName" -o "%KHIOPS_LAST_RUN_DIR%\$_ScenarioFileName" -e "%KHIOPS_LAST_RUN_DIR%\$_LogFileName"$\r$\n` + ${EndIf} + FileWrite $0 `goto END$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Start with parameters$\r$\n` + FileWrite $0 `:PARAMS$\r$\n` + ${If} $_ParallelMode == "0" + FileWrite $0 `"%KHIOPS_PATH%$_BinSuffix\$_ToolName" %*$\r$\n` + ${Else} + FileWrite $0 `%KHIOPS_MPI_COMMAND% "%KHIOPS_PATH%$_BinSuffix\$_ToolName" %*$\r$\n` + ${EndIf} + FileWrite $0 `goto END$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM ========================================================$\r$\n` + FileWrite $0 `REM Error messages$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:ERR_PATH$\r$\n` + FileWrite $0 `start "KHIOPS CONFIG PROBLEM" echo ERROR Incorrect installation directory for Khiops (File $_ToolName.exe not found in directory %KHIOPS_PATH%$_BinSuffix)$\r$\n` + FileWrite $0 `exit /b 1$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:ERR_JAVA$\r$\n` + FileWrite $0 `start "KHIOPS CONFIG PROBLEM" echo ERROR Java not correctly installed, jvm.dll not found under java directory tree %_KHIOPS_JAVA_HOME% (%_KHIOPS_JAVA_HOME_ORIGIN%): see khiops_env.cmd file in %KHIOPS_HOME%\bin, after line 'Set user Java Home'$\r$\n` + FileWrite $0 `exit /b 1$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:END$\r$\n` + FileWrite $0 `endlocal$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Return 1 if fatal error, 2 if error(s), 0 otherwise$\r$\n` + FileWrite $0 `exit /b %errorlevel%$\r$\n` + + # Close file + FileClose $0 +FunctionEnd diff --git a/packaging/windows/nsis/CreateKhiopsEnvCmdFileFunc.nsh b/packaging/windows/nsis/CreateKhiopsEnvCmdFileFunc.nsh new file mode 100644 index 000000000..26d4e0877 --- /dev/null +++ b/packaging/windows/nsis/CreateKhiopsEnvCmdFileFunc.nsh @@ -0,0 +1,195 @@ +!include "FileFunc.nsh" +!include "x64.nsh" + +# Macro to create the khiops_env.cmd script +# Example: +# ${CreateKhiopsEnvCmdFile} "$INSTDIR\khiops_env.cmd" "$INSTDIR" "4" +# +!define CreateKhiopsEnvCmdFile "!insertmacro CreateKhiopsEnvCmdFile" +!macro CreateKhiopsEnvCmdFile FileName KhiopsHome PhysicalCoresNumber + Push "${PhysicalCoresNumber}" + Push "${KhiopsHome}" + Push "${FileName}" + Call CreateKhiopsEnvCmdFile +!macroend + +# Function to be used with the macro defined above +Function CreateKhiopsEnvCmdFile + # Define function parameters + Var /GLOBAL _EnvFileName + Var /GLOBAL _EnvKhiopsHome + Var /GLOBAL _EnvProcessNumber + + # Retrieve parameters from stack + Pop $_EnvFileName + Pop $_EnvKhiopsHome + Pop $_EnvProcessNumber + + # Open the file to create + FileOpen $0 "$_EnvFileName" w + + # Write file contents + FileWrite $0 `@echo off$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `if %1.==--env. goto SET_ENV$\r$\n` + FileWrite $0 `goto HELP$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:HELP$\r$\n` + FileWrite $0 `echo Usage: khiops-env [-h] [--env]$\r$\n` + FileWrite $0 `echo khiops-env is an internal script intended to be used by Khiops tool and Khiops'$\r$\n` + FileWrite $0 `echo wrappers only.$\r$\n` + FileWrite $0 `echo If the --env flag is used, the environment list is printed on the standard output$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo The following variables are used to set the path and classpath$\r$\n` + FileWrite $0 `echo for the prerequisite of Khiops.$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo KHIOPS_HOME: home directory of Khiops, on Windows only$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo KHIOPS_PATH: path of Khiops' executable, to add in path$\r$\n` + FileWrite $0 `echo KHIOPS_MPI_COMMAND: MPI command to call the Khiops tool$\r$\n` + FileWrite $0 `echo KHIOPS_MPI_LIB: MPI library path used by the Khiops tool$\r$\n` + FileWrite $0 `echo KHIOPS_JAVA_PATH: path of Java tool, to add in path$\r$\n` + FileWrite $0 `echo KHIOPS_CLASSPATH: Khiops java libraries, to add in classpath$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo If they are not already defined, the following variables used by$\r$\n` + FileWrite $0 `echo Khiops are set :$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo KHIOPS_LAST_RUN_DIR: directory where Khiops writes output command$\r$\n` + FileWrite $0 `echo file and log (when not defined with -e and -o)$\r$\n` + FileWrite $0 `echo KHIOPS_PROC_NUMBER: processes number launched by Khiops (it's$\r$\n` + FileWrite $0 `echo default value corresponds to the number of physical cores of$\r$\n` + FileWrite $0 `echo the computer plus one)$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo The following variables are not defined by default and can be used to$\r$\n` + FileWrite $0 `echo change some default properties of Khiops:$\r$\n` + FileWrite $0 `echo.$\r$\n` + FileWrite $0 `echo KHIOPS_TMP_DIR: Khiops' temporary directory location (default : the$\r$\n` + FileWrite $0 `echo system's default) This location can be modified from the tool as well$\r$\n` + FileWrite $0 `echo KHIOPS_MEMORY_LIMIT: Khiops' memory limit (default : the system's$\r$\n` + FileWrite $0 `echo memory limit). This setting is ignored if it is above the system's$\r$\n` + FileWrite $0 `echo memory limit. It can only be reduced from the tool$\r$\n` + FileWrite $0 `echo KHIOPS_API_MODE: standard or api mode for the management of output result files created by Khiops$\r$\n` + FileWrite $0 `echo In standard mode, the result files are stored in the train database directory,$\r$\n` + FileWrite $0 `echo unless an absolute path is specified, and the file extension is forced if necessary.$\r$\n` + FileWrite $0 `echo In api mode, the result files are stored in the current working directory, using the specified results as is.$\r$\n` + FileWrite $0 `echo . default behavior if not set: standard mode$\r$\n` + FileWrite $0 `echo . set to 'true' to force standard mode$\r$\n` + FileWrite $0 `echo . set to 'false' to force api mode$\r$\n` + FileWrite $0 `echo KHIOPS_RAW_GUI: graphical user interface for file name selection$\r$\n` + FileWrite $0 `echo . default behavior if not set: depending on the file drivers available for Khiops$\r$\n` + FileWrite $0 `echo . set to 'true' to allow file name selection with uri schemas$\r$\n` + FileWrite $0 `echo . set to 'false' to allow local file name selection only with a file selection dialog$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `if not %2.==. exit /b 1$\r$\n` + FileWrite $0 `if %1.==-h. exit /b 0$\r$\n` + FileWrite $0 `exit /b 1$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Set Khiops env variables$\r$\n` + FileWrite $0 `:SET_ENV$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Test if Khiops environment already set up$\r$\n` + FileWrite $0 `if "%KHIOPS_HOME%".=="". set KHIOPS_HOME=$_EnvKhiopsHome$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_PATH$\r$\n` + FileWrite $0 `set KHIOPS_PATH=%KHIOPS_HOME%\bin$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_CLASSPATH$\r$\n` + FileWrite $0 `set KHIOPS_CLASSPATH=%KHIOPS_HOME%\bin\norm.jar$\r$\n` + FileWrite $0 `set KHIOPS_CLASSPATH=%KHIOPS_HOME%\bin\khiops.jar;%KHIOPS_CLASSPATH%$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_LAST_RUN_DIR$\r$\n` + FileWrite $0 `if "%KHIOPS_LAST_RUN_DIR%".=="". set KHIOPS_LAST_RUN_DIR=%USERPROFILE%\khiops_data\lastrun$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_PROC_NUMBER$\r$\n` + FileWrite $0 `if "%KHIOPS_PROC_NUMBER%".=="". set KHIOPS_PROC_NUMBER=$_EnvProcessNumber$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_MPI_COMMAND$\r$\n` + FileWrite $0 `REM Priority$\r$\n` + FileWrite $0 `REM 0: Idle$\r$\n` + FileWrite $0 `REM 1: Below normal$\r$\n` + FileWrite $0 `REM 2: Normal$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `set KHIOPS_MPI_COMMAND="%MSMPI_BIN%mpiexec" -al spr:P -n %KHIOPS_PROC_NUMBER% /priority 1$\r$\n` + FileWrite $0 `if %KHIOPS_PROC_NUMBER%==1 set KHIOPS_MPI_COMMAND=$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM KHIOPS_JAVA_PATH$\r$\n` + FileWrite $0 `REM May not work in case of a recent new installation of Java on the PC$\r$\n` + FileWrite $0 `set KHIOPS_JAVA_PATH=$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Set user Java Home$\r$\n` + FileWrite $0 `REM Uncomment the following line your own Java version$\r$\n` + FileWrite $0 `REM set _KHIOPS_JAVA_HOME=C:\Program Files\Java\jre${JavaRequiredFullVersion}$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_0$\r$\n` + FileWrite $0 `set _KHIOPS_JAVA_HOME_ORIGIN=java home set by user$\r$\n` + FileWrite $0 `REM Search if set by user$\r$\n` + FileWrite $0 `if not "%_KHIOPS_JAVA_HOME%".=="". goto JAVA_HOME_LAST$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_1$\r$\n` + FileWrite $0 `set _KHIOPS_JAVA_HOME_ORIGIN=found java recent version in registry$\r$\n` + FileWrite $0 `REM Search for a recent version of Java (greater than 8)$\r$\n` + FileWrite $0 `REM Search Java Version from registry and set _KHIOPS_JAVA_VERSION env var$\r$\n` + FileWrite $0 `for /F "tokens=2*" %%f in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JRE" -v CurrentVersion 2^>nul') do set _KHIOPS_JAVA_VERSION=%%g$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Search Java Home from registry and set _KHIOPS_JAVA_HOME env var$\r$\n` + FileWrite $0 `for /F "tokens=2*" %%f in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JRE\%_KHIOPS_JAVA_VERSION%" -v JavaHome 2^>nul') do set _KHIOPS_JAVA_HOME=%%g$\r$\n` + FileWrite $0 `if not "%_KHIOPS_JAVA_HOME%".=="". goto JAVA_HOME_LAST$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_2$\r$\n` + FileWrite $0 `set _KHIOPS_JAVA_HOME_ORIGIN=found java version in registry$\r$\n` + FileWrite $0 `REM Search for a previous version of Java$\r$\n` + FileWrite $0 `REM Search Java Version from registry and set _KHIOPS_JAVA_VERSION env var$\r$\n` + FileWrite $0 `for /F "tokens=2*" %%f in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment" -v CurrentVersion 2^>nul') do set _KHIOPS_JAVA_VERSION=%%g$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Search Java Home from registry and set _KHIOPS_JAVA_HOME env var$\r$\n` + FileWrite $0 `for /F "tokens=2*" %%f in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%_KHIOPS_JAVA_VERSION%" -v JavaHome 2^>nul') do set _KHIOPS_JAVA_HOME=%%g$\r$\n` + FileWrite $0 `if not "%_KHIOPS_JAVA_HOME%".=="". goto JAVA_HOME_LAST$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_3$\r$\n` + FileWrite $0 `set _KHIOPS_JAVA_HOME_ORIGIN=found in java installation sub dirs$\r$\n` + FileWrite $0 `REM Heuristic search in sub-directories of java installation dir$\r$\n` + FileWrite $0 `if not exist "%programFiles%\java" goto JAVA_HOME_LAST$\r$\n` + # Following instruction surrounding by simple quotes ', to allow internal use of back-quotes ` + FileWrite $0 'FOR /F "usebackq delims=" %%i IN (`where /R "%programFiles%\java" jvm.dll`) DO (set KHIOPS_JAVA_PATH=%%~di%%~pi)$\r$\n' + FileWrite $0 `if exist "%KHIOPS_JAVA_PATH%\jvm.dll" goto JAVA_END$\r$\n` + FileWrite $0 `if not exist "%KHIOPS_JAVA_PATH%\jvm.dll" set KHIOPS_JAVA_PATH=$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_4$\r$\n` + FileWrite $0 `set _KHIOPS_JAVA_HOME_ORIGIN=default installation settings$\r$\n` + FileWrite $0 `REM Set default Java Home if not found in registry$\r$\n` + FileWrite $0 `if "%_KHIOPS_JAVA_HOME%".=="". set _KHIOPS_JAVA_HOME=C:\Program Files\Java\jre${JavaRequiredFullVersion}$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_HOME_LAST$\r$\n` + FileWrite $0 `REM Add java runtime dir to KHIOPS_JAVA_PATH$\r$\n` + FileWrite $0 `if exist "%_KHIOPS_JAVA_HOME%\bin\client\jvm.dll" set KHIOPS_JAVA_PATH=%_KHIOPS_JAVA_HOME%\bin\client$\r$\n` + FileWrite $0 `if exist "%_KHIOPS_JAVA_HOME%\bin\server\jvm.dll" set KHIOPS_JAVA_PATH=%_KHIOPS_JAVA_HOME%\bin\server$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `:JAVA_END$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `$\r$\n` + FileWrite $0 `REM Print the environment list on the standard output$\r$\n` + FileWrite $0 `echo KHIOPS_HOME %KHIOPS_HOME%$\r$\n` + FileWrite $0 `echo KHIOPS_PATH %KHIOPS_PATH%$\r$\n` + FileWrite $0 `echo KHIOPS_MPI_COMMAND %KHIOPS_MPI_COMMAND%$\r$\n` + FileWrite $0 `echo KHIOPS_MPI_LIB %KHIOPS_MPI_LIB%$\r$\n` + FileWrite $0 `echo KHIOPS_JAVA_PATH %KHIOPS_JAVA_PATH%$\r$\n` + FileWrite $0 `echo KHIOPS_CLASSPATH %KHIOPS_CLASSPATH%$\r$\n` + FileWrite $0 `echo KHIOPS_LAST_RUN_DIR %KHIOPS_LAST_RUN_DIR%$\r$\n` + FileWrite $0 `echo KHIOPS_PROC_NUMBER %KHIOPS_PROC_NUMBER%$\r$\n` + FileWrite $0 `echo KHIOPS_TMP_DIR %KHIOPS_TMP_DIR%$\r$\n` + FileWrite $0 `echo KHIOPS_MEMORY_LIMIT %KHIOPS_MEMORY_LIMIT%$\r$\n` + FileWrite $0 `echo KHIOPS_API_MODE %KHIOPS_API_MODE%$\r$\n` + FileWrite $0 `echo KHIOPS_RAW_GUI %KHIOPS_RAW_GUI%$\r$\n` + FileWrite $0 `exit /b 0$\r$\n` + + # Close file + FileClose $0 +FunctionEnd diff --git a/packaging/windows/nsis/GetCoresCount.nsh b/packaging/windows/nsis/GetCoresCount.nsh new file mode 100644 index 000000000..74822c04e --- /dev/null +++ b/packaging/windows/nsis/GetCoresCount.nsh @@ -0,0 +1,54 @@ +# Copied entirely from +# http://stackoverflow.com/questions/29911549/cpu-features-getcount-return-incorrect-number-for-cpu-cores +!include LogicLib.nsh +!ifndef ERROR_INSUFFICIENT_BUFFER +!define ERROR_INSUFFICIENT_BUFFER 122 +!endif +!define RelationProcessorCore 0 + +!if "${NSIS_PTR_SIZE}" <= 4 +Function GetProcessorPhysCoreCount +System::Store S +StrCpy $9 0 ; 0 if we fail +System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},i,*i0r2)i.r0?e' +Pop $3 +${If} $3 = ${ERROR_INSUFFICIENT_BUFFER} +${AndIf} $2 <> 0 + System::Alloc $2 + System::Call 'kernel32::GetLogicalProcessorInformationEx(i${RelationProcessorCore},isr1,*ir2r2)i.r0' + Push $1 + ${If} $0 <> 0 + loop_7: + IntOp $9 $9 + 1 + System::Call *$1(i,i.r3) + IntOp $1 $1 + $3 + IntOp $2 $2 - $3 + IntCmp $2 0 "" loop_7 loop_7 + ${EndIf} + Pop $1 + System::Free $1 +${Else} + System::Call 'kernel32::GetLogicalProcessorInformation(i,*i0r2)i.r0?e' + Pop $3 + ${If} $3 = ${ERROR_INSUFFICIENT_BUFFER} + System::Alloc $2 + System::Call 'kernel32::GetLogicalProcessorInformation(isr1,*ir2r2)i.r0' + Push $1 + ${If} $0 <> 0 + loop_v: + System::Call *$1(i,i.r3) + ${If} $3 == ${RelationProcessorCore} + IntOp $9 $9 + 1 + ${EndIf} + IntOp $1 $1 + 24 + IntOp $2 $2 - 24 + IntCmp $2 0 "" loop_v loop_v + ${EndIf} + Pop $1 + System::Free $1 + ${EndIf} +${EndIf} +Push $9 +System::Store L +FunctionEnd +!endif diff --git a/packaging/windows/nsis/KhiopsGlobals.nsh b/packaging/windows/nsis/KhiopsGlobals.nsh new file mode 100644 index 000000000..70a04129f --- /dev/null +++ b/packaging/windows/nsis/KhiopsGlobals.nsh @@ -0,0 +1,14 @@ +# Global Definitions +# ------------------ + +# Minimal required Java version +!define JavaRequiredVersion "1.8" + +# Minimal required Java update version of the package installer +!define JavaInstallerVersionUpdate "181" + +# Minimal required full Java version (stored in the registry) +!define JavaRequiredFullVersion "1.8.0_181" + +# Minimal required MPI version +!define MPIRequiredVersion "10.0" diff --git a/packaging/windows/nsis/KhiopsPrerequisiteFunc.nsh b/packaging/windows/nsis/KhiopsPrerequisiteFunc.nsh new file mode 100644 index 000000000..8f76e63d6 --- /dev/null +++ b/packaging/windows/nsis/KhiopsPrerequisiteFunc.nsh @@ -0,0 +1,134 @@ +!include "FileFunc.nsh" +!include "x64.nsh" +!include "WordFunc.nsh" + +# To deactivate the requirements installation define DO_NOT_INSTALL_REQUIREMENTS + +# Detects and loads Java installation path and the JRE version +# - Defines JavaInstalledVersion and JavaInstallationPath +# - If the detection fails JavaInstalledVersion is set to "" +Function DetectAndLoadJavaEnvironment + # Installed version + Var /GLOBAL JavaInstalledVersion + + # Installation path + Var /GLOBAL JavaInstallationPath + + # Set the 64 bit registry to detect the correct version of Java + SetRegView 64 + + # Detection of JRE for Java >= 10 + StrCpy $JavaInstalledVersion "" + StrCpy $JavaInstallationPath "" + StrCpy $1 "SOFTWARE\JavaSoft\JRE" + StrCpy $2 0 + ReadRegStr $2 HKLM "$1" "CurrentVersion" + ${If} $2 != "" + ReadRegStr $3 HKLM "$1\$2" "JavaHome" + ${If} $3 != "" + StrCpy $JavaInstalledVersion $2 + StrCpy $JavaInstallationPath $3 + ${EndIf} + ${EndIf} + + # Debug message + !ifdef DEBUG + Messagebox MB_OK "JRE (>=10.0): required=${JavaRequiredVersion}, installed=$JavaInstalledVersion, path=$JavaInstallationPath" + !endif + + # Detection of JRE for Java < 10.0 + ${If} $JavaInstalledVersion == "" + StrCpy $JavaInstallationPath "" + StrCpy $1 "SOFTWARE\JavaSoft\Java Runtime Environment" + StrCpy $2 0 + ReadRegStr $2 HKLM "$1" "CurrentVersion" + ${If} $2 != "" + ReadRegStr $3 HKLM "$1\$2" "JavaHome" + ${If} $3 != "" + StrCpy $JavaInstallationPath $3 + StrCpy $JavaInstalledVersion $2 + ${EndIf} + ${EndIf} + ${EndIf} + + # Debug message + !ifdef DEBUG + Messagebox MB_OK "JRE (< 10.0): required=${JavaRequiredVersion}, installed=$JavaInstalledVersion, path=$JavaInstallationPath" + !endif + + # Get back to 32 bit registry + SetRegView 32 +FunctionEnd + +# Installs Java +Function InstallJava +!ifndef DO_NOT_INSTALL_REQUIREMENTS + # Write the JRE installer + SetOutPath $TEMP + File ${JRE_INSTALLER_PATH} + + # Execute the JRE installer silently + Var /Global JRE_INSTALLER_FILENAME + ${GetFileName} ${JRE_INSTALLER_PATH} $JRE_INSTALLER_FILENAME + nsexec::Exec '"$TEMP\$JRE_INSTALLER_FILENAME" INSTALL_SILENT=1 REBOOT=0' + Pop $0 + DetailPrint "Installation of Java JRE: $0" + + # Delete JRE installer + Delete "$TEMP\$JRE_INSTALLER_FILENAME" + + # Load the Java Environment + Call DetectAndLoadJavaEnvironment + + # Fail if the required version is newer than installed version + ${VersionCompare} "${JavaRequiredVersion}" "$JavaInstalledVersion" $0 + ${If} $0 == 1 + Messagebox MB_OK "Could not install Java runtime (version ${JavaRequiredVersion}): Khiops will run only in batch mode. Try installing Java JRE directly before installing to Khiops." /SD IDOK + ${EndIf} +!endif +FunctionEnd + + +# Detects MPI and loads its version +# - Defines MPIInstalledVersion +# - If not installerd MPIInstalledVersion is equal to 0 +Function DetectAndLoadMPIEnvironment + # Installed version + Var /GLOBAL MPIInstalledVersion + StrCpy $MPIInstalledVersion 0 + + # Look in the registry for the MPI installation + StrCpy $1 "SOFTWARE\Microsoft\MPI" + StrCpy $2 0 + ReadRegStr $2 HKLM "$1" "Version" + StrCpy $MPIInstalledVersion $2 +FunctionEnd + + +# Installs MPI +Function InstallMPI +!ifndef DO_NOT_INSTALL_REQUIREMENTS + # Save MPI installer + SetOutPath $TEMP + File ${MSMPI_INSTALLER_PATH} + + # Execute MPI installer + Var /Global MSMPI_INSTALLER_FILENAME + ${GetFileName} ${MSMPI_INSTALLER_PATH} $MSMPI_INSTALLER_FILENAME + nsexec::Exec '"$TEMP\$MSMPI_INSTALLER_FILENAME" -unattend -force -minimal' + Pop $0 + DetailPrint "Installation of MPI: $0" + + # Delete MSMPI installer + Delete "$TEMP\$MSMPI_INSTALLER_FILENAME" + + # Load MPI environment (MPIInstalledVersion) + Call DetectAndLoadMPIEnvironment + + # Show an error if the required version is newer than installed version + ${VersionCompare} "${MPIRequiredVersion}" "$MPIInstalledVersion" $0 + ${If} $0 == 1 + Messagebox MB_OK "Could not install MPI runtime (version ${MPIRequiredVersion}): Khiops will not run. Try installing Microsoft MPI directly before installing Khiops." /SD IDOK + ${EndIf} +!endif +FunctionEnd diff --git a/packaging/windows/nsis/images/headerimage.bmp b/packaging/windows/nsis/images/headerimage.bmp new file mode 100644 index 000000000..16942a3ce Binary files /dev/null and b/packaging/windows/nsis/images/headerimage.bmp differ diff --git a/packaging/windows/nsis/images/installer.ico b/packaging/windows/nsis/images/installer.ico new file mode 100644 index 000000000..95d877710 Binary files /dev/null and b/packaging/windows/nsis/images/installer.ico differ diff --git a/packaging/windows/nsis/images/welcomefinish.bmp b/packaging/windows/nsis/images/welcomefinish.bmp new file mode 100644 index 000000000..def59f3a7 Binary files /dev/null and b/packaging/windows/nsis/images/welcomefinish.bmp differ diff --git a/packaging/windows/nsis/khiops.nsi b/packaging/windows/nsis/khiops.nsi new file mode 100644 index 000000000..a65f2c3b0 --- /dev/null +++ b/packaging/windows/nsis/khiops.nsi @@ -0,0 +1,608 @@ +# Khiops installer builder NSIS script + +# Set Unicode to avoid warning 7998: "ANSI targets are deprecated" +Unicode True + +# Set compresion to LZMA (faster) +SetCompressor /SOLID lzma + +# Include NSIS librairies +!include "LogicLib.nsh" +!include "MUI2.nsh" +!include "FileFunc.nsh" +!include "x64.nsh" +!include "winmessages.nsh" + +# Include Custom libraries +!include "KhiopsGlobals.nsh" +!include "GetCoresCount.nsh" +!include "CreateKhiopsEnvCmdFileFunc.nsh" +!include "CreateKhiopsCmdFileFunc.nsh" +!include "KhiopsPrerequisiteFunc.nsh" + +# Definitions for registry change notification +!define SHCNE_ASSOCCHANGED 0x8000000 +!define SHCNF_IDLIST 0 + +# Macro to check input parameter definitions +!macro CheckInputParameter ParameterName + !ifndef ${ParameterName} + !error "${ParameterName} is not defined. Use the flag '-D${ParameterName}=...' to define it." + !endif +!macroend + +# Check the mandatory input definitions +!insertmacro CheckInputParameter KHIOPS_VERSION +!insertmacro CheckInputParameter KHIOPS_WINDOWS_BUILD_DIR +!insertmacro CheckInputParameter KHIOPS_VIZ_INSTALLER_PATH +!insertmacro CheckInputParameter KHIOPS_COVIZ_INSTALLER_PATH +!insertmacro CheckInputParameter JRE_INSTALLER_PATH +!insertmacro CheckInputParameter MSMPI_INSTALLER_PATH + +# Application name and installer file name +Name "Khiops ${KHIOPS_VERSION}" +OutFile "khiops-${KHIOPS_VERSION}-setup.exe" + +# Get installation folder from registry if available +InstallDirRegKey HKLM Software\khiops "" + +# Request admin privileges +RequestExecutionLevel admin + +# Make it aware of HiDPI screens +ManifestDPIAware true + +######################## +# Variable definitions # +######################## + +# MPI installation flag +Var /GLOBAL IsMPIRequired + +# Requirements installation flags +Var /GLOBAL MPIInstallationNeeded +Var /GLOBAL JavaInstallationNeeded + +# Requirements installation messages +Var /GLOBAL MPIInstallationMessage +Var /GLOBAL JavaInstallationMessage + +# Number of physical cores +Var /GLOBAL PhysicalCoresNumber + +# Number of processes to use +Var /GLOBAL ProcessNumber + +# Root key for the uninstaller in the windows registry +!define UninstallerKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" + +##################################### +# Modern UI Interface Configuration # +##################################### + +# General configuration +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP ".\images\headerimage.bmp" +!define MUI_HEADERIMAGE_LEFT +!define MUI_WELCOMEFINISHPAGE_BITMAP ".\images\welcomefinish.bmp" +!define MUI_ABORTWARNING +!define MUI_ICON ".\images\installer.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\win-uninstall.ico" +BrandingText "Orange Innovation" + +# Welcome page +!define MUI_WELCOMEPAGE_TITLE "Welcome to the Khiops ${KHIOPS_VERSION} Setup Wizard" +!define MUI_WELCOMEPAGE_TEXT \ + "Khiops is a data mining tool includes data preparation and scoring, visualization, coclustering and covisualization.$\r$\n$\r$\n$\r$\n$\r$\n$(MUI_${MUI_PAGE_UNINSTALLER_PREFIX}TEXT_WELCOME_INFO_TEXT)" +!insertmacro MUI_PAGE_WELCOME + +# Licence page +!insertmacro MUI_PAGE_LICENSE "..\..\..\LICENSE" + +# Custom page for requirements software +Page custom RequirementsPageShow RequirementsPageLeave + +# Install directory choice page +!insertmacro MUI_PAGE_DIRECTORY + +# Install files choice page +!insertmacro MUI_PAGE_INSTFILES + +# Final page +!define MUI_FINISHPAGE_RUN +!define MUI_FINISHPAGE_RUN_TEXT "Create desktop shortcut" +!define MUI_FINISHPAGE_RUN_FUNCTION "CreateDesktopShortcuts" +!define MUI_FINISHPAGE_TEXT "$\r$\n$\r$\nThank you for installing Khiops." +!define MUI_FINISHPAGE_LINK "www.khiops.com" +!define MUI_FINISHPAGE_LINK_LOCATION "https://www.khiops.com" +!insertmacro MUI_PAGE_FINISH + +# Uninstaller pages +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES + +# Language (must be defined after uninstaller) +!insertmacro MUI_LANGUAGE "English" + +####################### +# Version Information # +####################### + +VIProductVersion "${KHIOPS_VERSION}.0.0" +VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "Khiops" +VIAddVersionKey /LANG=${LANG_ENGLISH} "CompanyName" "Orange" +VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "Copyright (c) 2023 Orange" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "Khiops Installer" +VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "${KHIOPS_VERSION}" + +###################### +# Installer Sections # +###################### + +Section "Install" SecInstall + # In order to have shortcuts and documents for all users + SetShellVarContext all + + # Detect Java + Call RequirementsDetection + + # Install java if needed + ${If} $JavaInstallationNeeded == "1" + Call InstallJava + ${EndIf} + + # MPI installation is always required, because Khiops is linked with MPI DLL + ${If} $MPIInstallationNeeded == "1" + Call InstallMPI + ${EndIf} + + # Install files + + # Activate file overwrite + SetOverwrite on + + # Files to install in the root directory + SetOutPath "$INSTDIR" + File "..\..\..\LICENSE" + + # Install executables and java libraries + SetOutPath "$INSTDIR\bin" + File "${KHIOPS_WINDOWS_BUILD_DIR}\bin\MODL.exe" + File "${KHIOPS_WINDOWS_BUILD_DIR}\bin\MODL_Coclustering.exe" + File "${KHIOPS_WINDOWS_BUILD_DIR}\jars\norm.jar" + File "${KHIOPS_WINDOWS_BUILD_DIR}\jars\khiops.jar" + + # Install icons + SetOutPath "$INSTDIR\bin\icons" + File "..\..\common\images\installer_khiops.ico" + File "..\..\common\images\khiops.ico" + File "..\..\common\images\khiops_coclustering.ico" + + # Install Khiops Visualization App + + # Add the installer file + SetOutPath $TEMP + File ${KHIOPS_VIZ_INSTALLER_PATH} + + # Execute Khiops visualization installer: + # - It is not executed with silent mode so the user can customize the install + # - It is executed with "cmd /C" so it opens the installer options window + Var /Global KHIOPS_VIZ_INSTALLER_FILENAME + ${GetFileName} ${KHIOPS_VIZ_INSTALLER_PATH} $KHIOPS_VIZ_INSTALLER_FILENAME + ${If} ${Silent} + nsexec::Exec 'cmd /C "$KHIOPS_VIZ_INSTALLER_FILENAME /S"' + ${Else} + nsexec::Exec 'cmd /C "$KHIOPS_VIZ_INSTALLER_FILENAME"' + ${EndIf} + Pop $0 + DetailPrint "Installation of Khiops visualization: $0" + + # Delete the installer + Delete "$TEMP\KHIOPS_VIZ_INSTALLER_FILENAME" + + + # Execute Khiops covisualization installer: + # Same rules as above with the visualization + + # Files to install in installer directory + File ${KHIOPS_COVIZ_INSTALLER_PATH} + + Var /Global KHIOPS_COVIZ_INSTALLER_FILENAME + ${GetFileName} ${KHIOPS_COVIZ_INSTALLER_PATH} $KHIOPS_COVIZ_INSTALLER_FILENAME + ${If} ${Silent} + nsexec::Exec 'cmd /C "$TEMP\$KHIOPS_COVIZ_INSTALLER_FILENAME /S"' + ${Else} + nsexec::Exec 'cmd /C "$TEMP\$KHIOPS_COVIZ_INSTALLER_FILENAME"' + ${EndIf} + Pop $0 + DetailPrint "Installation of Khiops covisualization: $0" + + # Delete the installer + Delete "$TEMP\$KHIOPS_COVIZ_INSTALLER_FILENAME" + + + ############################# + # Finalize the installation # + ############################# + + + # Creation of Khiops cmd files for Khiops et Khiops Coclustering + StrCpy $ProcessNumber $PhysicalCoresNumber + ${If} $PhysicalCoresNumber >= 2 + IntOp $ProcessNumber $PhysicalCoresNumber + 1 + ${EndIf} + ${CreateKhiopsEnvCmdFile} "$INSTDIR\bin\khiops_env.cmd" "$INSTDIR" $ProcessNumber + ${CreateKhiopsCmdFile} "$INSTDIR\bin\khiops.cmd" "MODL" "" "$INSTDIR" "scenario._kh" "log.txt" $IsMPIRequired + ${CreateKhiopsCmdFile} "$INSTDIR\bin\khiops_coclustering.cmd" "MODL_Coclustering" "" "$INSTDIR" "scenario._khc" "logc.txt" "0" + + # Create the Khiops shell + FileOpen $0 "$INSTDIR\bin\shell_khiops.cmd" w + FileWrite $0 '@echo off$\r$\n' + FileWrite $0 'REM Open a shell session with access to Khiops$\r$\n' + FileWrite $0 `if "%KHIOPS_HOME%".=="". set KHIOPS_HOME=$INSTDIR$\r$\n` + FileWrite $0 'set path=%KHIOPS_HOME%\bin;%path%$\r$\n' + FileWrite $0 'title Shell Khiops$\r$\n' + FileWrite $0 '%comspec% /K "echo Welcome to Khiops scripting mode & echo Type khiops -h or khiops_coclustering -h to get help' + FileClose $0 + + # Create the uninstaller + WriteUninstaller "$INSTDIR\uninstall-khiops.exe" + + + ##################################### + # Windows environment customization # + # ################################### + + + # Write registry keys to add Khiops in the Add/Remove Programs pane + WriteRegStr HKLM "Software\Khiops" "" $INSTDIR + WriteRegStr HKLM "${UninstallerKey}\Khiops" "UninstallString" '"$INSTDIR\uninstall-khiops.exe"' + WriteRegStr HKLM "${UninstallerKey}\Khiops" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "${UninstallerKey}\Khiops" "DisplayName" "Khiops" + WriteRegStr HKLM "${UninstallerKey}\Khiops" "Publisher" "Orange Labs" + WriteRegStr HKLM "${UninstallerKey}\Khiops" "DisplayIcon" "$INSTDIR\bin\icons\installer_khiops.ico" + WriteRegStr HKLM "${UninstallerKey}\Khiops" "DisplayVersion" "${KHIOPS_VERSION}" + WriteRegStr HKLM "${UninstallerKey}\Khiops" "URLInfoAbout" "http://www.khiops.com" + WriteRegDWORD HKLM "${UninstallerKey}\Khiops" "NoModify" "1" + WriteRegDWORD HKLM "${UninstallerKey}\Khiops" "NoRepair" "1" + + # Create application shortcuts in the installation directory + DetailPrint "Installing Start menu Shortcut..." + SetOutPath "$INSTDIR" # for the start directory + CreateShortCut "$INSTDIR\Khiops.lnk" "$INSTDIR\bin\khiops.cmd" "" "$INSTDIR\bin\icons\khiops.ico" 0 SW_SHOWMINIMIZED + CreateShortCut "$INSTDIR\Khiops Coclustering.lnk" "$INSTDIR\bin\khiops_coclustering.cmd" "" "$INSTDIR\bin\icons\khiops_coclustering.ico" 0 SW_SHOWMINIMIZED + ExpandEnvStrings $R0 "%COMSPEC%" + CreateShortCut "$INSTDIR\Shell Khiops.lnk" "$INSTDIR\bin\shell_khiops.cmd" "" "$R0" + + # Create start menu shortcuts for exe + DetailPrint "Installing Start menu Shortcut..." + SetOutPath "$INSTDIR" # for the start directory + CreateDirectory "$SMPROGRAMS\Khiops" + CreateShortCut "$SMPROGRAMS\Khiops\Khiops.lnk" "$INSTDIR\bin\khiops.cmd" "" "$INSTDIR\bin\icons\khiops.ico" 0 SW_SHOWMINIMIZED + CreateShortCut "$SMPROGRAMS\Khiops\Khiops Coclustering.lnk" "$INSTDIR\bin\khiops_coclustering.cmd" "" "$INSTDIR\bin\icons\khiops_coclustering.ico" 0 SW_SHOWMINIMIZED + ExpandEnvStrings $R0 "%COMSPEC%" + CreateShortCut "$SMPROGRAMS\Khiops\Shell Khiops.lnk" "$INSTDIR\bin\shell_khiops.cmd" "" "$R0" + CreateShortCut "$SMPROGRAMS\Khiops\Uninstall.lnk" "$INSTDIR\uninstall-khiops.exe" + + # Define aliases for the following registry keys (also used in the uninstaller section) + # - HKLM (all users) + # - HKCU (current user) + !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' + !define env_hkcu 'HKCU "Environment"' + + # Set KHIOPS_HOME for the local machine and current user + WriteRegExpandStr ${env_hklm} "KHIOPS_HOME" "$INSTDIR" + WriteRegExpandStr ${env_hkcu} "KHIOPS_HOME" "$INSTDIR" + + # Make sure windows knows about the change + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + # Register file association for Khiops visualisation tools # + # inspired from examples\makensis.nsi + + # Khiops dictionary file extension + ReadRegStr $R0 HKCR ".kdic" "" + ${if} $R0 == "Khiops.Dictionary.File" + DeleteRegKey HKCR "Khiops.Dictionary.File" + ${EndIf} + WriteRegStr HKCR ".kdic" "" "Khiops.Dictionary.File" + WriteRegStr HKCR "Khiops.Dictionary.File" "" "Khiops Dictionary File" + ReadRegStr $R0 HKCR "Khiops.Dictionary.File\shell\open\command" "" + ${If} $R0 == "" + WriteRegStr HKCR "Khiops.Dictionary.File\shell" "" "open" + WriteRegStr HKCR "Khiops.Dictionary.File\shell\open\command" "" 'notepad.exe "%1"' + ${EndIf} + + # Khiops scenario file + ReadRegStr $R0 HKCR "._kh" "" + ${if} $R0 == "Khiops.File" + DeleteRegKey HKCR "Khiops.File" + ${EndIf} + WriteRegStr HKCR "._kh" "" "Khiops.File" + WriteRegStr HKCR "Khiops.File" "" "Khiops File" + WriteRegStr HKCR "Khiops.File\DefaultIcon" "" "$INSTDIR\bin\icons\khiops.ico" + ReadRegStr $R0 HKCR "Khiops.File\shell\open\command" "" + ${If} $R0 == "" + WriteRegStr HKCR "Khiops.File\shell" "" "open" + WriteRegStr HKCR "Khiops.File\shell\open\command" "" 'notepad.exe "%1"' + ${EndIf} + WriteRegStr HKCR "Khiops.File\shell\compile" "" "Execute Khiops Script" + WriteRegStr HKCR "Khiops.File\shell\compile\command" "" '"$INSTDIR\bin\khiops.cmd" -i "%1"' + + # Khiops coclustering scenario file + ReadRegStr $R0 HKCR "._khc" "" + ${if} $R0 == "Khiops.Coclustering.File" + DeleteRegKey HKCR "Khiops.Coclustering.File" + ${EndIf} + WriteRegStr HKCR "._khc" "" "Khiops.Coclustering.File" + WriteRegStr HKCR "Khiops.Coclustering.File" "" "Khiops Coclustering File" + WriteRegStr HKCR "Khiops.Coclustering.File\DefaultIcon" "" "$INSTDIR\bin\icons\khiops_coclustering.ico" + ReadRegStr $R0 HKCR "Khiops.Coclustering.File\shell\open\command" "" + ${If} $R0 == "" + WriteRegStr HKCR "Khiops.Coclustering.File\shell" "" "open" + WriteRegStr HKCR "Khiops.Coclustering.File\shell\open\command" "" 'notepad.exe "%1"' + ${EndIf} + WriteRegStr HKCR "Khiops.Coclustering.File\shell\compile" "" "Execute Khiops Coclustering Script" + WriteRegStr HKCR "Khiops.Coclustering.File\shell\compile\command" "" '"$INSTDIR\bin\khiops_coclustering.cmd" -i "%1"' + + # Notify the file extension changes + System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)' + + # Debug message + !ifdef DEBUG + Messagebox MB_OK "Installation finished!" + !endif + +SectionEnd + + +############### +# Uninstaller # +############### + +Section "Uninstall" + # In order to have shortcuts and documents for all users + SetShellVarContext all + + # Restore Registry # + # Unregister file associations + DetailPrint "Uninstalling Khiops Shell Extensions..." + + # Unregister Khiops dictionary file extension + ${If} $R0 == "Khiops.Dictionary.File" + DeleteRegKey HKCR ".kdic" + ${EndIf} + DeleteRegKey HKCR "Khiops.Dictionary.File" + + # Unregister Khiops file extension + ${If} $R0 == "Khiops.File" + DeleteRegKey HKCR "._kh" + ${EndIf} + DeleteRegKey HKCR "Khiops.File" + + # Unregister Khiops coclustering file extension + ${If} $R0 == "Khiops.Coclustering.File" + DeleteRegKey HKCR "._khc" + ${EndIf} + DeleteRegKey HKCR "Khiops.Coclustering.File" + + # Notify file extension changes + System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)' + + # Delete installation folder key + DeleteRegKey HKLM "${UninstallerKey}\Khiops" + DeleteRegKey HKLM "Software\Khiops" + + # Delete environement variable KHIOPS_HOME + DeleteRegValue ${env_hklm} "KHIOPS_HOME" + DeleteRegValue ${env_hkcu} "KHIOPS_HOME" + + # Delete deprecated environment variable KhiopsHome + DeleteRegValue ${env_hklm} "KhiopsHome" + DeleteRegValue ${env_hkcu} "KhiopsHome" + + # Make sure windows knows about the changes in the environment + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + # Delete files # + DetailPrint "Deleting Files ..." + + # Files to delete in root directory + Delete "$INSTDIR\LICENSE" + + # Files to delete in bin directory + Delete "$INSTDIR\bin\khiops_env.cmd" + Delete "$INSTDIR\bin\khiops.cmd" + Delete "$INSTDIR\bin\khiops_coclustering.cmd" + Delete "$INSTDIR\bin\MODL.exe" + Delete "$INSTDIR\bin\MODL_Coclustering.exe" + Delete "$INSTDIR\bin\norm.jar" + Delete "$INSTDIR\bin\khiops.jar" + Delete "$INSTDIR\bin\shell_khiops.cmd" + + # Files to delete in bin\icons directory + Delete "$INSTDIR\bin\icons\installer_khiops.ico" + Delete "$INSTDIR\bin\icons\khiops.ico" + Delete "$INSTDIR\bin\icons\khiops_coclustering.ico" + + # Delete short cuts from install dir + Delete "$INSTDIR\Khiops.lnk" + Delete "$INSTDIR\Khiops Coclustering.lnk" + Delete "$INSTDIR\Shell Khiops.lnk" + + # Delete the installer + Delete "$INSTDIR\uninstall-khiops.exe" + + # Delete the installation directory tree + # Note: Directories are removed only if they are completely empty + RMDir "$INSTDIR\bin\icons" + RMDir "$INSTDIR\bin" + RMDir "$INSTDIR\key" + RMDir "$INSTDIR\doc" + RMDir "$INSTDIR" + + # Delete shortcuts + Delete "$DESKTOP\Khiops.lnk" + Delete "$DESKTOP\Khiops Coclustering.lnk" + Delete "$DESKTOP\Shell Khiops.lnk" + RMDir /r "$SMPROGRAMS\Khiops" +SectionEnd + + +####################### +# Installer Functions # +####################### + +Function "CreateDesktopShortcuts" + DetailPrint "Installing Desktop Shortcut..." + SetOutPath "$INSTDIR" + CreateShortCut "$DESKTOP\Khiops.lnk" "$INSTDIR\bin\khiops.cmd" "" "$INSTDIR\bin\icons\khiops.ico" 0 SW_SHOWMINIMIZED + CreateShortCut "$DESKTOP\Khiops Coclustering.lnk" "$INSTDIR\bin\khiops_coclustering.cmd" "" "$INSTDIR\bin\icons\khiops_coclustering.ico" 0 SW_SHOWMINIMIZED +FunctionEnd + +# Predefined initialization install function +Function .onInit + # Define variables + Var /GLOBAL PreviousUninstaller + Var /GLOBAL PreviousVersion + + # Read location of the uninstaller + ReadRegStr $PreviousUninstaller HKLM "${UninstallerKey}\Khiops" "UninstallString" + ReadRegStr $PreviousVersion HKLM "${UninstallerKey}\Khiops" "DisplayVersion" + + # Ask the user to proceed if there was already a previous Khiops version installed + # In silent mode: remove previous version + ${If} $PreviousUninstaller != "" + MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \ + "Khiops $PreviousVersion is already installed. $\n$\nClick OK to remove the \ + previous version $\n$\nor Cancel to cancel this upgrade." \ + /SD IDOK IDOK uninst + Abort + + # Run the uninstaller + uninst: + ClearErrors + ExecWait '$PreviousUninstaller /S _?=$INSTDIR' + + # Run again the uninstaller to delete the uninstaller itself and the root dir (without waiting) + # Must not be used in silent mode (may delete files from silent following installation) + ${IfNot} ${Silent} + ExecWait '$PreviousUninstaller /S' + ${EndIf} + ${EndIf} + + # Choice of default installation directory, for windows 32 or 64 + ${If} $INSTDIR == "" + ${If} ${RunningX64} + StrCpy $INSTDIR "$PROGRAMFILES64\khiops" + # No 32-bit install + ${EndIf} + ${EndIf} +FunctionEnd + + +# Function to show the page for requirements +Function RequirementsPageShow + # Detect requirements + Call RequirementsDetection + + # Creation of page, with title and subtitle + nsDialogs::Create 1018 + !insertmacro MUI_HEADER_TEXT "Check software requirements" "Check Microsoft MPI and Java Runtime Environment" + + # Message to show for the Microsoft MPI installation + ${NSD_CreateLabel} 0 20u 100% 10u $MPIInstallationMessage + + # Message to show for the JRE installation + ${NSD_CreateLabel} 0 50u 100% 10u $JavaInstallationMessage + + # Show page + nsDialogs::Show +FunctionEnd + + +# Requirements detection +# - Detects if the system architecture is 64-bit +# - Detects whether Java JRE and MPI are installed and their versions +Function RequirementsDetection + # Abort installation if the machine does not have 64-bit architecture + ${IfNot} ${RunningX64} + Messagebox MB_OK "Khiops works only on Windows 64 bits: installation will be terminated." /SD IDOK + Quit + ${EndIf} + + # Decide if MPI is required by detecting the number of cores + StrCpy $PhysicalCoresNumber "0" + Call GetProcessorPhysCoreCount + Pop $0 + StrCpy $PhysicalCoresNumber $0 + ${If} $PhysicalCoresNumber > 1 + StrCpy $IsMPIRequired "1" + ${Else} + StrCpy $IsMPIRequired "0" + ${EndIf} + ${If} $IsMPIRequired == "1" + # Note: This call defines MPIInstalledVersion + Call DetectAndLoadMPIEnvironment + ${EndIf} + + # Try to install MPI if it is required + StrCpy $MPIInstallationNeeded "0" + StrCpy $MPIInstallationMessage "" + ${If} $IsMPIRequired == "1" + # If it is not installed install it + ${If} $MPIInstalledVersion == "0" + StrCpy $MPIInstallationMessage "Microsoft MPI version ${MPIRequiredVersion} will be installed" + StrCpy $MPIInstallationNeeded "1" + # Otherwise install only if the required version is newer than the installed one + ${Else} + ${VersionCompare} "${MPIRequiredVersion}" "$MPIInstalledVersion" $0 + ${If} $0 == 1 + StrCpy $MPIInstallationMessage "Microsoft MPI will be upgraded to version ${MPIRequiredVersion}" + StrCpy $MPIInstallationNeeded "1" + ${Else} + StrCpy $MPIInstallationMessage "Microsoft MPI version $MPIInstalledVersion already installed" + ${EndIf} + ${EndIf} + # Otherwise just inform that MPI is not required + ${Else} + StrCpy $MPIInstallationMessage "Microsoft MPI installation not required" + ${EndIf} + + # Show debug information + !ifdef DEBUG + Messagebox MB_OK "MS-MPI: needed=$MPIInstallationNeeded required=${MPIRequiredVersion} installed=$MPIInstalledVersion" + !endif + + # Detect and load Java Environment + Call DetectAndLoadJavaEnvironment + + # Message to install Java + StrCpy $JavaInstallationNeeded "0" + StrCpy $JavaInstallationMessage "" + ${If} $JavaInstallationPath == "" + StrCpy $JavaInstallationMessage "Java runtime (version ${JavaRequiredVersion}, update ${JavaInstallerVersionUpdate}) will be installed" + StrCpy $JavaInstallationNeeded "1" + # If Java allready installed + ${Else} + # Suite a ce qui semble etre bug de l'installeur Java, on se base desormais sur JavaRequiredVersion, et non sur JavaRequiredFullVersion + ${VersionCompare} "${JavaRequiredVersion}" "$JavaInstalledVersion" $0 + # Required version is newer than installed version + ${If} $0 == 1 + StrCpy $JavaInstallationMessage "New Java runtime (version ${JavaRequiredVersion}, update ${JavaInstallerVersionUpdate}) will be installed" + StrCpy $JavaInstallationNeeded "1" + # Require version is equal or older than installed version + ${Else} + StrCpy $JavaInstallationMessage "Java runtime already installed" + ${EndIf} + ${EndIf} + + # Debug message + !ifdef DEBUG + Messagebox MB_OK "Java runtime: isNeeded=$JavaInstallationNeeded reqVersion=${JavaRequiredVersion} installedVersion=$JavaInstalledVersion" + !endif +FunctionEnd + +# No leave page for required softwares +Function RequirementsPageLeave +FunctionEnd diff --git a/src/Parallel/PLSamples/CMakeLists.txt b/src/Parallel/PLSamples/CMakeLists.txt index 2880beae1..2b048217e 100644 --- a/src/Parallel/PLSamples/CMakeLists.txt +++ b/src/Parallel/PLSamples/CMakeLists.txt @@ -1,7 +1,10 @@ file(GLOB cppfiles ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) add_library(PLSamples STATIC ${cppfiles}) +add_executable(parallel-samples ${cppfiles}) set_khiops_options(PLSamples) +set_khiops_options(parallel-samples) +target_link_libraries(parallel-samples PUBLIC base PLParallelTask) target_include_directories(PLSamples PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(PLSamples PUBLIC PLParallelTask)