linuxbashqtqt-creator

bash fails in providing environment variables from file to Qt sdktool


Qt provides sdktool for creating kits. I'm using it to automaticaly setup kit for cross-compilation.
Normally I should call source environment_file_from_sdk and then start Qt Creator in the same terminal.
I've adapted configure-qtcreator.sh for my needs. However at last step (addKit) I would like to provide all exports from environment_file_from_sdk as --env var.
So

ENV_VALUES=$(grep "export " $SDK_PATH/../environment-setup-cortexa53-crypto-veld-linux | tr -d '"' | sed -e 's/export //;s/^\(.*\)/--env "\1"/')

When I print this variable through echo - it look ok. Set of --env "<var>=<long_or_multiple_values>".
When I add it to sdktool addKit command

sdktool addKit
....
--cmake-config QT_QMAKE_EXECUTABLE:FILEPATH=$SDK_PATH/x86_64-pokysdk-linux/usr/bin/qmake \
$ENV_VALUES

It fails due to Argument parsing failed. Bash set -x command print shows that plenty of --env <var>=<value> has been surrounded by single quotation marks and look like --env '"ARCH=arm64"' --env '"CROSS_COMPILE=aarch64-veld-linux-"' --env '"OECORE_TUNE_CCARGS=-mcpu=cortex-a53' -march=armv8-a+crc+crypto '-mbranch-protection=standard"'.
How to solve it?


Solution

  • You have variables where the value contains spaces, so you have to do this a different way (see https://mywiki.wooledge.org/BashFAQ/050) -- you need to use an array:

    # initialize an empty array
    env_vars=()
    
    # read the sed output
    while IFS= read -r env_var; do
        # add this variable as an env option
        env_vars+=( --env "$env_var" )
    done < <(
        sed 's/^export //p' "$env_file"
    ) 
    
    sdktool addKit ... "${env_vars[@]}"
    

    All the quotes are absolutely required. The < <(...) part is not a typo -- that is redirecting the process substitution into the while-read loop.


    sed is not really required: bash can do it

    env_vars=()
    
    while IFS= read -r line; do
        if [[ "$line" =~ "export "(.*) ]]; then
            env_vars+=( --env "${BASH_REMATCH[1]//\"/}" )
        fi
    done < "$env_file"