simple - descargar cmake 3.2 2
Cómo capturar los argumentos de la línea de comandos de CMake? (2)
Quiero registrar los argumentos pasados a cmake en mis scripts generados. Por ejemplo, "my-config.in" será procesado por cmake, tiene una definición como esta:
config = "@ CMAKE_ARGS @"
Después de cmake
, my-config
contendrá una línea como esta:
config = "- DLINUX -DUSE_FOO = y -DCMAKE_INSTALL_PREFIX = / usr"
Intenté CMAKE_ARGS
, CMAKE_OPTIONS
, pero fallé. Ningún documento menciona esto. :-(
No conozco ninguna variable que proporcione esta información, pero puede generarla usted mismo (con algunas condiciones).
Cualquier argumento -D
pasado a CMake se agrega al archivo de caché CMakeCache.txt
en el directorio de compilación y se vuelve a aplicar durante las invocaciones posteriores sin tener que especificarlo nuevamente en la línea de comando.
Entonces en su ejemplo, si primero ejecuta CMake como
cmake ../.. -DCMAKE_INSTALL_PREFIX:PATH=/usr
entonces encontrará que posteriormente funciona simplemente
cmake .
todavía tendrá CMAKE_INSTALL_PREFIX
establecido en /usr
Si lo que estás buscando de CMAKE_ARGS
es la lista completa de variables definidas en la línea de comando desde cada invocación de CMake, lo siguiente debería ser el truco:
get_cmake_property(CACHE_VARS CACHE_VARIABLES)
foreach(CACHE_VAR ${CACHE_VARS})
get_property(CACHE_VAR_HELPSTRING CACHE ${CACHE_VAR} PROPERTY HELPSTRING)
if(CACHE_VAR_HELPSTRING STREQUAL "No help, variable specified on the command line.")
get_property(CACHE_VAR_TYPE CACHE ${CACHE_VAR} PROPERTY TYPE)
if(CACHE_VAR_TYPE STREQUAL "UNINITIALIZED")
set(CACHE_VAR_TYPE)
else()
set(CACHE_VAR_TYPE :${CACHE_VAR_TYPE})
endif()
set(CMAKE_ARGS "${CMAKE_ARGS} -D${CACHE_VAR}${CACHE_VAR_TYPE}=/"${${CACHE_VAR}}/"")
endif()
endforeach()
message("CMAKE_ARGS: ${CMAKE_ARGS}")
Esto es un poco frágil ya que depende del hecho de que cada variable que se ha configurado a través de la línea de comando tiene la frase "Sin ayuda, variable especificada en la línea de comando". especificado como su propiedad HELPSTRING
. Si CMake cambia este HELPSTRING
predeterminado, deberá actualizar la sentencia if
consecuencia.
Si esto no es lo que quiere que CMAKE_ARGS
muestre, sino solo los argumentos de la ejecución actual, ¡entonces no creo que haya una forma de hacerlo que no sea piratear el código fuente de CMake! Sin embargo, espero que esto no sea lo que desea, ya que todos los argumentos anteriores de la línea de comando se vuelven a aplicar de manera efectiva cada vez.
Una forma de almacenar los argumentos de la línea de comandos de CMake es tener un script envoltorio llamado ~/bin/cmake
(*** 1), que hace 2 cosas:
- crea
./cmake_call.sh
que almacena los argumentos de línea de comando - llamar al ejecutable real
cmake
con los argumentos de línea de comando
~/bin/cmake
código ~/bin/cmake
# se muestra a continuación
#!/usr/bin/env bash
#
# Place this file into this location: ~/bin/cmake
# (with executable rights)
#
# This is a wrapper for cmake!
# * It calls cmake -- see last line of the script
# It also:
# * Creates a file cmake_call.sh in the current directory (build-directory)
# which stores the cmake-call with all it''s cmake-flags etc.
# (It also stores successive calls to cmake, so that you have a trace of all your cmake calls)
#
# You can simply reinvoke the last cmake commandline with: ./cmake_call.sh !!!!!!!!!!
#
# cmake_call.sh is not created
# when cmake is called without any flags,
# or when it is called with flags such as --help, -E, -P, etc. (refer to NON_STORE_ARGUMENTS -- you might need to modify it to suit your needs)
SCRIPT_PATH=$(readlink -f "$BASH_SOURCE")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
#http://.com/a/13864829
if [ -z ${SUDO_USER+x} ]; then
# var SUDO_USER is unset
user=$USER
else
user=$SUDO_USER
fi
#http://.com/a/34621068
path_append () { path_remove $1 $2; export $1="${!1}:$2"; }
path_prepend() { path_remove $1 $2; export $1="$2:${!1}"; }
path_remove () { export $1="`echo -n ${!1} | awk -v RS=: -v ORS=: ''$1 != "''$2''"'' | sed ''s/:$//''`"; }
path_remove PATH ~/bin # when calling cmake (at the bottom of this script), do not invoke this script again!
# when called with no arguments, don''t create cmake_call.sh
if [[ -z "$@" ]]; then
cmake "$@"
exit
fi
# variable NON_STORE_ARGUMENTS stores flags which, if any are present, cause cmake_call.sh to NOT be created
read -r -d '''' NON_STORE_ARGUMENTS <<''EOF''
-E
--build
#-N
-P
--graphviz
--system-information
--debug-trycompile
#--debug-output
--help
-help
-usage
-h
-H
--version
-version
/V
--help-full
--help-manual
--help-manual-list
--help-command
--help-command-list
--help-commands
--help-module
--help-module-list
--help-modules
--help-policy
--help-policy-list
--help-policies
--help-property
--help-property-list
--help-properties
--help-variable
--help-variable-list
--help-variables
EOF
NON_STORE_ARGUMENTS=$(echo "$NON_STORE_ARGUMENTS" | head -c -1 `# remove last newline` | sed "s/^/^/g" `#begin every line with ^` | tr ''/n'' ''|'')
#echo "$NON_STORE_ARGUMENTS" ## for debug purposes
## store all the args
ARGS_STR=
for arg in "$@"; do
if cat <<< "$arg" | grep -E -- "$NON_STORE_ARGUMENTS" &> /dev/null; then # don''t use echo "$arg" ....
# since echo "-E" does not do what you want here,
# but cat <<< "-E" does what you want (print minus E)
# do not create cmake_call.sh
cmake "$@"
exit
fi
# concatenate to ARGS_STR
ARGS_STR="${ARGS_STR}$(echo -n " /"$arg/"" | sed "s,/($(pwd)/)/(/([/ /t,:;''/"].*/)/?/)$,/$(pwd)/2,g")"
# replace $(pwd) followed by
# / or
# whitespace or
# , or
# : or
# ; or
# '' or
# "
# or nothing
# with /$(pwd)
done
if [[ ! -e $(pwd)/cmake_call.sh ]]; then
echo "#!/usr/bin/env bash" > $(pwd)/cmake_call.sh
# escaping:
# note in the HEREDOC below, // means / in the output!!
# /$ means $ in the output!!
# /` means ` in the output!!
cat <<EOF >> $(pwd)/cmake_call.sh
#http://.com/a/34621068
path_remove () { export /$1="/`echo -n /${!1} | awk -v RS=: -v ORS=: ''/$1 != "''/$2''"'' | sed ''s/:/$//''/`"; }
path_remove PATH ~/bin # when calling cmake (at the bottom of this script), do not invoke ~/bin/cmake but real cmake!
EOF
else
# remove bottom 2 lines from cmake_call.sh
sed -i ''$ d'' $(pwd)/cmake_call.sh
sed -i ''$ d'' $(pwd)/cmake_call.sh
fi
echo "ARGS=''${ARGS_STR}''" >> $(pwd)/cmake_call.sh
echo "echo cmake /"/$ARGS/"" >> $(pwd)/cmake_call.sh
echo "eval cmake /"/$ARGS/"" >> $(pwd)/cmake_call.sh
#echo "eval which cmake" >> $(pwd)/cmake_call.sh
chmod +x $(pwd)/cmake_call.sh
chown $user: $(pwd)/cmake_call.sh
cmake "$@"
Uso:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$(pwd)/install ..
Esto creará cmake_call.sh
con el siguiente contenido:
#!/usr/bin/env bash
#http://.com/a/34621068
path_remove () { export $1="`echo -n ${!1} | awk -v RS=: -v ORS=: ''$1 != "''$2''"'' | sed ''s/:$//''`"; }
path_remove PATH ~/bin # when calling cmake (at the bottom of this script), do not invoke ~/bin/cmake but real cmake!
ARGS='' "-DCMAKE_BUILD_TYPE=Debug" "-DCMAKE_INSTALL_PREFIX=$(pwd)/install" ".."''
echo cmake "$ARGS"
eval cmake "$ARGS"
La 3ra última línea almacena los argumentos de cmake. Ahora puede reinvocar la línea de comando exacta que utilizó simplemente llamando:
./cmake_call.sh
Notas al pie:
(*** 1) ~/bin/cmake
usualmente está en la RUTA debido a ~/.profile
. Al crear ~/bin/cmake
la primera vez, puede ser necesario cerrar la sesión y volver a iniciarla, para que .profile vea ~/bin
.