1

I have this configuration file in my CI where I'm specifying a header file and some CMAKE flags on one line.

The configuration file looks like this (filelist):

./settings6.h -DMY_COMPILE_FLAGS="-m32 -fstrict-aliasing"
./settings7.h -DMY_FEATURE_1=ON
./settings8.h -DMY_FLAG=ON -DMY_FEATURE_2=ON -DMY_INCLUDE_DIR=/usr/include/

Now, I'm using a bash script to process this configuration file:

#!/bin/bash
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
while read i; do
    HEADERFILE=$(echo $i | cut -d ' ' -f 1)
    CMAKEFLAGS=$(echo $i | cut -s -d ' ' -f 2-)
    if [[ "$HEADERFILE" == "" ]]; then
        continue
    fi
    CFLAGS="-Werror" cmake "my_build_dir" "$CMAKEFLAGS" -G "Ninja" -DMY_EXTRA_INCLUDE="$SCRIPTDIR/$HEADERFILE" -B"build_env_dir" > /dev/null
    ninja -C "build_env_dir"
done <<ENDOFINPUT
$(grep -v '^#' $SCRIPTDIR/filelist)
ENDOFINPUT

When I have the bash script as above, the line with settings6.h gets processed properly, i.e. the MY_COMPILE_FLAGS are set to -m32 -fstrict-aliasing.

However, settings8.h is failing because the value of MY_FLAG is seen by CMAKE as ON -DMY_FEATURE_2=ON -DMY_INCLUDE_DIR=/usr/include/, so MY_FEATURE_2 and MY_INCLUDE_DIR are not processed correctly.

After googling around a bit, I thought, well, surely a quoting issue, probably I have to remove the quotes around $CMAKEFLAGS like this:

    CFLAGS="-Werror" cmake "my_build_dir" $CMAKEFLAGS -G "Ninja" -DMY_EXTRA_INCLUDE="$SCRIPTDIR/$HEADERFILE" -B"build_env_dir" > /dev/null

In fact, this lets settings8.h work as expected (all three options are processed), but now, settings6.h is suddenly failing since CMAKE complains:

CMake Error: The source directory "/src/-fstrict-aliasing"" does not exist

Can someone guide me please how I read the settings correctly from my filelist so that settings6.h and settings8.h both succeed?

7
  • Possible duplicate of stackoverflow.com/questions/12136948/… Commented Nov 22, 2019 at 10:53
  • @tripleee I actually don't think this is a duplicate: passing $CMAKEFLAGS as array doesn't improve anything. Do you have another suggestion? Commented Nov 22, 2019 at 11:42
  • The best proposal I can come up with is to modify your input file format so that you can parse it without eval or other horrible workarounds. Wrapping this in a Makefile comes to mind as one potentially rather elegant workaround. Commented Nov 22, 2019 at 11:44
  • @tripleee do you have an example (maybe you post it as an answer) how such a file format would look like? Commented Nov 22, 2019 at 13:26
  • 1
    If you are using cmake anyway I would probably use that for the whole thing, but I'm not familiar enough with it to show you how. Commented Nov 22, 2019 at 14:28

1 Answer 1

1

Here's a Makefile which refactors this into a sequence of recipes.

Cases := $(patsubst %.h,%,$(wildcard ./settings*.h))
all_done := $(patsubst %,.%.done,$(Cases))

.PHONY: all
all: $(all_done)

cases.mk: filelist.txt
    sed 's%^\./%case_%;s% % := %' $< >$@
include cases.mk

.%_done: ./%.h
    CFLAGS="-Werror" cmake "my_build_dir" $(case_$*) -G "Ninja" \
        -DMY_EXTRA_INCLUDE="$<" -B"build_env_dir" > /dev/null
    ninja -C "build_env_dir"
Sign up to request clarification or add additional context in comments.

1 Comment

Not in a place where I can test this but hopefully this can at least inspire some lateral thinking...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.