From ba66c0a53a3284954996b301af67e23b04513d87 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Wed, 13 Nov 2013 16:06:00 +0100 Subject: [PATCH 1/1] Rewrite smpi build scripts to deal with file names containing spaces. Retain sh compatibility. More work is still needed to make it work completely: - cmake substitutions don't escape spaces (e.g. @INCLUDEARGS@) - smpif2c breaks with spaces in file names --- buildtools/Cmake/CompleteInFiles.cmake | 1 + buildtools/Cmake/DefinePackages.cmake | 1 + src/smpi/smpicc.in | 56 +++++++------ src/smpi/smpif90.in | 79 ++++++++---------- src/smpi/smpiff.in | 111 +++++++++++++------------ src/smpi/smpitools.sh | 57 +++++++++++++ 6 files changed, 179 insertions(+), 126 deletions(-) create mode 100644 src/smpi/smpitools.sh diff --git a/buildtools/Cmake/CompleteInFiles.cmake b/buildtools/Cmake/CompleteInFiles.cmake index 16aff5cbd4..54b63aecaf 100644 --- a/buildtools/Cmake/CompleteInFiles.cmake +++ b/buildtools/Cmake/CompleteInFiles.cmake @@ -809,6 +809,7 @@ if(HAVE_NS3_LIB) endif() set(CMAKE_SMPI_COMMAND "${CMAKE_SMPI_COMMAND}:\${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}\"") +file(READ ${CMAKE_HOME_DIRECTORY}/src/smpi/smpitools.sh SMPITOOLS_SH) configure_file(${CMAKE_HOME_DIRECTORY}/include/smpi/mpif.h.in ${CMAKE_BINARY_DIR}/include/smpi/mpif.h @ONLY) configure_file(${CMAKE_HOME_DIRECTORY}/include/smpi/smpif.h.in ${CMAKE_BINARY_DIR}/include/smpi/smpif.h @ONLY) configure_file(${CMAKE_HOME_DIRECTORY}/src/smpi/smpicc.in ${CMAKE_BINARY_DIR}/bin/smpicc @ONLY) diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 23b4b965ee..701ffe4ab0 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -821,6 +821,7 @@ set(bin_files src/smpi/smpiff.in src/smpi/smpif90.in src/smpi/smpirun.in + src/smpi/smpitools.sh ) set(txt_files diff --git a/src/smpi/smpicc.in b/src/smpi/smpicc.in index 843c526927..5e9eec4271 100755 --- a/src/smpi/smpicc.in +++ b/src/smpi/smpicc.in @@ -5,38 +5,42 @@ CC=@CMAKE_C_COMPILER@ INCLUDEARGS="@includeflag@" CMAKE_LINKARGS="-L@libdir@" +@SMPITOOLS_SH@ + +list_set CFLAGS +list_set LINKARGS if [ "@WIN32@" != "1" ]; then - CFLAGS="-Dmain=smpi_simulated_main_" - LINKARGS="-lsimgrid" + list_add CFLAGS "-Dmain=smpi_simulated_main_" + list_add LINKARGS "-lsimgrid" else - CFLAGS="-include @includedir@/smpi/smpi_main.h" - LINKARGS="@libdir@\libsimgrid.dll" + list_add CFLAGS "-include" "@includedir@/smpi/smpi_main.h" + list_add LINKARGS "@libdir@\libsimgrid.dll" fi -CMDLINE="" -while [ -n "$1" ]; do - ARG="$1" - shift - case "${ARG}" in - -c) - CMAKE_LINKARGS="" - LINKARGS="" - CMDLINE="${CMDLINE} -c " - ;; - *.c) - SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" - if [ -z $SRCFILE ] ; then - SRCFILE="$ARG" - fi - CMDLINE="${CMDLINE} ${SRCFILE} " - ;; - *) - CMDLINE="${CMDLINE} ${ARG} " +list_set CMDLINE +while [ $# -gt 0 ]; do + ARG="$1" + shift + case "${ARG}" in + -c) + CMAKE_LINKARGS="" + LINKARGS="" + list_add CMDLINE "-c" + ;; + *.c) + SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" + if [ -z "$SRCFILE" ] ; then + SRCFILE="$ARG" + fi + list_add CMDLINE "${SRCFILE}" + ;; + *) + list_add CMDLINE "${ARG}" ;; esac done -CMDLINE="${CC} ${CFLAGS} ${CMDLINE} ${INCLUDEARGS} ${CMAKE_LINKARGS} ${LINKARGS}" +list_set CMDLINE "${CFLAGS}" "${CMDLINE}" ${INCLUDEARGS} ${CMAKE_LINKARGS} "${LINKARGS}" +eval $(list_get CMDLINE) -#echo "${CMDLINE}" -${CMDLINE} +"${CC}" "$@" diff --git a/src/smpi/smpif90.in b/src/smpi/smpif90.in index 8295f3e136..60d8d59b9a 100644 --- a/src/smpi/smpif90.in +++ b/src/smpi/smpif90.in @@ -5,55 +5,44 @@ F90=@GFORTRAN_EXE@ INCLUDEARGS="@includeflag@" CMAKE_LINKARGS="-L@libdir@" -FFLAGS="-ff2c -fno-second-underscore" -LINKARGS="-lsimgrid -lm -lgfortran" +@SMPITOOLS_SH@ + +list_set FFLAGS "-ff2c" "-fno-second-underscore" +list_set LINKARGS "-lsimgrid" "-lm" "-lgfortran" +list_set TMPFILES main_name=main -TMPFILES="" -trap 'rm -f ${TMPFILES}' EXIT - -# $1: prefix, $2: suffix -mymktemp () { - tmp=$(mktemp --suffix="$2" "$1_XXXXXXXXXX" 2> /dev/null) - if [ -z "$tmp" ]; then - # mktemp failed (unsupported --suffix ?), try unsafe mode - tmp=$(mktemp -u "$1_XXXXXXXXXX" 2> /dev/null) - if [ -z "$tmp" ]; then - # mktemp failed again (doesn't exist ?), try very unsafe mode - tmp="$1_$$x$RANDOM" - fi - tmp="${tmp}$2" - # create temp file, and exit if it existed before - sh -C -c "true > \"${tmp}\"" || exit 1 - fi - echo "${tmp}" +cleanup () { + eval $(list_get TMPFILES) + rm -f "$@" } - -CMDLINE="" -while [ -n "$1" ]; do - ARG="$1" - shift - case "${ARG}" in - -c) - CMAKE_LINKARGS="" - LINKARGS="" - CMDLINE="${CMDLINE} -c " - ;; - *.f90|*.F90) - TMPFILE=$(mymktemp "${ARG}" ".f90") - TMPFILES="${TMPFILES} ${TMPFILE}" +trap 'cleanup' EXIT + +list_set CMDLINE +while [ $# -gt 0 ]; do + ARG="$1" + shift + case "${ARG}" in + -c) + CMAKE_LINKARGS="" + LINKARGS="" + list_add CMDLINE "-c" + ;; + *.f90|*.F90) + TMPFILE=$(mymktemp "${ARG}" ".f90") + list_add TMPFILES "${TMPFILE}" #replace "program main_name by subroutine user\_main (and the end clause as well)" - sed 's/[[:space:]]*program[[:space:]]*\([a-zA-Z0-9\-\_]*\)/subroutine user\_main /gI;s/[[:space:]]*use[[:space:]]*mpi/\include \"mpif\.h\" /gI' ${ARG} > ${TMPFILE} - SRCFILE="${TMPFILE}" - CMDLINE="${CMDLINE} ${SRCFILE} " - ;; - *) - CMDLINE="${CMDLINE} ${ARG} " - ;; - esac + sed 's/[[:space:]]*program[[:space:]]*\([a-zA-Z0-9\-\_]*\)/subroutine user\_main /gI;s/[[:space:]]*use[[:space:]]*mpi/\include \"mpif\.h\" /gI' "${ARG}" > "${TMPFILE}" + SRCFILE="${TMPFILE}" + list_add CMDLINE "${SRCFILE}" + ;; + *) + list_add CMDLINE "${ARG}" + ;; + esac done -CMDLINE="${F90} ${FFLAGS} ${CMDLINE} ${INCLUDEARGS} ${CMAKE_LINKARGS} ${LINKARGS}" +list_set CMDLINE "${FFLAGS}" "${CMDLINE}" ${INCLUDEARGS} ${CMAKE_LINKARGS} "${LINKARGS}" +eval $(list_get CMDLINE) -#echo "${CMDLINE}" -${CMDLINE} +"${F90}" "$@" diff --git a/src/smpi/smpiff.in b/src/smpi/smpiff.in index feb45630ed..bcb376fa78 100644 --- a/src/smpi/smpiff.in +++ b/src/smpi/smpiff.in @@ -1,63 +1,64 @@ #! /bin/sh + prefix="@exec_prefix@" +smpicc="$prefix/bin/smpicc" +smpif2c="$prefix/bin/smpif2c" + +@SMPITOOLS_SH@ + +list_set ARGS "-DMAIN__=user_main" "-Diargc_=smpi_process_argc" "-Dgetarg_=smpi_process_getarg" +list_set LINKARGS "-L@F2C_LIBRARY_PATH@" "-lf2c" "-lm" +list_set SRCFILES + +while [ $# -gt 0 ]; do + ARG="$1" + shift + case "${ARG}" in + *.f) + SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" + if [ -z "$SRCFILE" ] ; then + SRCFILE="$ARG" + fi + list_add SRCFILES "${SRCFILE}" + ;; + *) + if [ "${ARG}" = "-c" ]; then + LINKARGS="" + fi + list_add ARGS "${ARG}" + ;; + esac +done +list_add ARGS "${LINKARGS}" -ARGS="-DMAIN__=user_main -Diargc_=smpi_process_argc -Dgetarg_=smpi_process_getarg" -LINKARGS="-L@F2C_LIBRARY_PATH@ -lf2c -lm" -# $1: prefix, $2: suffix -mymktemp () { - tmp=$(mktemp --suffix="$2" "$1_XXXXXXXXXX" 2> /dev/null) - if [ -z "$tmp" ]; then - # mktemp failed (unsupported --suffix ?), try unsafe mode - tmp=$(mktemp -u "$1_XXXXXXXXXX" 2> /dev/null) - if [ -z "$tmp" ]; then - # mktemp failed again (doesn't exist ?), try very unsafe mode - tmp="$1_$$x$RANDOM" - fi - tmp="${tmp}$2" - # create temp file, and exit if it existed before - sh -C -c "true > \"${tmp}\"" || exit 1 +build () { + local SRCFILE + SCFILE="$1" + TMPFILE=$(mymktemp "${SRCFILE}" ".f") + CFILE="${TMPFILE%.f}.c" + + eval $(list_get ARGS) + + cp "${SRCFILE}" "${TMPFILE}" \ + && "$smpif2c" "${TMPFILE}" \ + && "$smpicc" "$@" "${CFILE}" \ + && rm -f "${CFILE}" \ + && rm -f "${TMPFILE}" \ + || exit $? + + # When the file is compiled with "-c" and no output file is specified with + # "-o", rename the output. FIXME: do it properly. + if [ -f "${CFILE%.c}.o" ]; then + mv "${CFILE%.c}.o" "${SRCFILE%.f}.o" fi - echo "${tmp}" } -SRCFILES="" -while [ -n "$1" ]; do - ARG="$1" - shift - case "${ARG}" in - *.f) - SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" - if [ -z "$SRCFILE" ] ; then - SRCFILE="$ARG" - fi - SRCFILES="${SRCFILES} ${SRCFILE}" - ;; - *) - if [ "${ARG}" = "-c" ]; then - LINKARGS="" - fi - ARGS="${ARGS} ${ARG}" - ;; - esac -done -ARGS="${ARGS} ${LINKARGS}" - -if [ -n "${SRCFILES}" ] -then - for SRCFILE in ${SRCFILES} - do - TMPFILE=$(mymktemp "${SRCFILE}" ".f") - cp ${SRCFILE} ${TMPFILE} - CFILE="${TMPFILE%.f}.c" - #echo "$prefix/bin/smpif2c ${TMPFILE} && $prefix/bin/smpicc ${ARGS} ${CFILE} && rm ${CFILE} && rm ${TMPFILE}" - $prefix/bin/smpif2c ${TMPFILE} && $prefix/bin/smpicc ${ARGS} ${CFILE} && rm ${CFILE} && rm ${TMPFILE} || exit $? - # When the file is compiled with "-c" and no output file is specified with - # "-o", rename the output. FIXME: do it properly. - if [ -f ${CFILE%.c}.o ]; then - mv ${CFILE%.c}.o ${SRCFILE%.f}.o - fi - done +if [ -n "${SRCFILES}" ]; then + eval $(list_get SRCFILES) + for SRCFILE in "$@"; do + build "$SRCFILE" + done else - #echo "$prefix/bin/smpicc ${ARGS}" - $prefix/bin/smpicc ${ARGS} + eval $(list_get ARGS) + "$smpicc" "$@" fi diff --git a/src/smpi/smpitools.sh b/src/smpi/smpitools.sh new file mode 100644 index 0000000000..835cd595d0 --- /dev/null +++ b/src/smpi/smpitools.sh @@ -0,0 +1,57 @@ +SAVEIFS="$IFS" +LISTSEP="$(printf '\b')" + +# Create a temporary file, with its name of the form $1_XXX$2, where XXX is +# replaced by an unique string. +# $1: prefix, $2: suffix +mymktemp () { + tmp=$(mktemp --suffix="$2" "$1_XXXXXXXXXX" 2> /dev/null) + if [ -z "$tmp" ]; then + # mktemp failed (unsupported --suffix ?), try unsafe mode + tmp=$(mktemp -u "$1_XXXXXXXXXX" 2> /dev/null) + if [ -z "$tmp" ]; then + # mktemp failed again (doesn't exist ?), try very unsafe mode + if [ -z "${mymktemp_seq}" ]; then + mymktemp_seq=$(date +%d%H%M%S) + fi + tmp="$1_$$x${mymktemp_seq}" + mymktemp_seq=$((mymktemp_seq + 1)) + fi + tmp="${tmp}$2" + # create temp file, and exit if it existed before + sh -C -c "true > \"${tmp}\"" || exit 1 + fi + echo "${tmp}" +} + +# Add a word to the end of a list (words separated by LISTSEP) +# $1: list, $2...: words to add +list_add () { + local list content + list="$1" + shift + eval content=\"\${$list}\" + IFS="$LISTSEP" + if [ -z "$content" ]; then + content="$*" + else + content="$content${LISTSEP}$*" + fi + IFS="$SAVEIFS" + eval $list=\"\${content}\" +} + +# Set contents of a list (words separated by LISTSEP) +# $1: list, $2...: words to set +list_set () { + eval $1="" + list_add "$@" +} + +# Get the content of a list: positional parameters ($1, $2, ...) are set to the +# content of the list +# $1: list +# usage: eval $(list_get list) +list_get () { + printf 'IFS="$LISTSEP"; eval set -- \\$%s; IFS="$SAVEIFS"' "$1" +} -- 2.20.1