0

I want to build an RPM package supported by x86_64 and i386. To achive this, I have to call different commands/scripts for different architecture types in the %pre and %post sections of RPM spec.

%pre
if [ $(arch) = "x86_64" ]; then
    #do sth for 64 bit
elif [ $(arch) = "i686" ]; then
    #do sth for 32 bit
else
    echo "Unsupported architecture"
    exit 1
fi

But when I check the scriptlets of the RPM file with

rpm -qp --scripts foo.rpm

$(arch) command has already been called and my if/else conditions had become:

if [ i686 = "x86_64" ]; then
    #do sth for 64 bit
elif [ i686 = "i686" ]; then
    #do sth for 32 bit
else
    echo "Unsupported architecture"
    exit 1
fi

Because I make rpmbuild in i686 machine. I want these scriplets to stay as they are. How can I do that? Thanks.

I am sorry guys. I have found the guilty. It is not rpmbuild. I didn't share enough information.

The thing is I do not have actual spec file. I have only one bash scripts to generate other stuf. the file looks like:

#!/bin/bash

# 1.Prepare rpmbuild folder
mkdir -p ~/rpmbuild/{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp}
cat <<EOF >~/.rpmmacros
%_topdir   %(echo $HOME)/rpmbuild
%_tmppath  %{_topdir}/tmp
%_unpackaged_files_terminate_build      0
%_binaries_in_noarch_packages_terminate_build   0
EOF

# 2.Prepare rpm SPEC file
cat <<EOF >~/rpmbuild/SPECS/foo.spec
%define        __spec_install_post %{nil}
%define          debug_package %{nil}
%define        __os_install_post %{_dbpath}/brp-compress

#all scriptlets here
%pre
if [ $(arch) = "x86_64" ]; then
    #do sth for 64 bit
elif [ $(arch) = "i686" ]; then
    #do sth for 32 bit
else
    echo "Unsupported architecture"
    exit 1
fi

EOF

# 3.Renew folders
cd ~/rpmbuild
mkdir -p FOO-$FOO_VER/some/path
install -m 644 $WORKSPACE_PATH/file FOO-$FOO_VER/target/path/file

# 4.Prepare tar.gz
tar -cvzf FOO-$FOO_VER.tar.gz FOO-$FOO_VER/
cp FOO-$FOO_VER.tar.gz ./SOURCES/
rm -rf FOO-$FOO_VER

# 5.Build rpm
rpmbuild -ba SPECS/foo.spec
cd ~/
rm -rf ~/rpmbuild

I have commented out rm's and call run the script again. And check the spec file. I see i686 here too. It appears that $(arch) is being called while cat'ing. So my question is, How can I prevent command substitution to create spec file with "here document" syntax?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
rido
  • 51
  • 6
  • The behavior you describe is very surprising, and my tests do not reproduce it. – John Bollinger Mar 09 '23 at 14:39
  • However, what you are trying to do makes sense only in an arch-specific RPM. For such an RPM, it would be more appropriate to use RPM conditionals and the `%_arch` macro at build time to prepare an appropriate scriptlet for the target RPM architecture, as opposed to making decisions at installation time based on system-architecture detection. – John Bollinger Mar 09 '23 at 14:44
  • 1
    Using an unquoted heredoc -- `< – Charles Duffy Mar 09 '23 at 16:12
  • 1
    @JohnBollinger, ...what's surprising here, exactly? (Yes, it would be surprising if `%_arch` were being replaced, but for `$(arch)` it's normal). – Charles Duffy Mar 09 '23 at 16:14
  • 1
    @CharlesDuffy, my comments were directed at the original version of this question, which stopped after the "Thanks". My surprise was directed at the OP's claim that `rpmbuild` would behave as described, and it appears that indeed, that claim was false. Given scriptlet text as specified by the OP *in an RPM spec file*, the command substitution of `$(arch)` happens when the scriptlet runs, not when `rpmbuild` records it in an RPM. – John Bollinger Mar 09 '23 at 16:19
  • 1
    @JohnBollinger Ahh -- makes sense, thank you for clarifying. I was wondering if there was something more complex going on I wasn't seeing. – Charles Duffy Mar 09 '23 at 16:23
  • Thanks guys. In order not to prevent $(HOME) and other variables interpretted, I have found the solution with backslash. `\$(arch)`. sorry for causing misunderstanding. – rido Mar 09 '23 at 16:35

0 Answers0