Проекты cmake на основе make-файлов автоматически запускают make rebuild_cache при изменении переменной среды - PullRequest
3 голосов
/ 24 мая 2011

В моей конфигурации cmake несколько переменных зависят от переменной окружения для правильной установки. Эта переменная окружения может измениться, и это означает, что кэш для cmake должен быть перестроен.

Моя конфигурация может обнаружить необходимость этой перенастройки и обновить соответствующие записи в кэше, когда вызывается другой вызов «cmake» или вызывается «make rebuild_cache».

Тем не менее, я хотел бы, чтобы каждый раз, когда я запускаю, заставлял его автоматически проверяться на наличие изменений и запускать цель rebuild_cache при необходимости.

Возможно ли это?

Ответы [ 2 ]

1 голос
/ 29 июня 2011

Make не имеет памяти. У make нет способа «запомнить», какая переменная среды была установлена ​​при последнем запуске make.

Если не записать переменную среды в файл.

Я никогда не использовал CMake, поэтому я не знаю, как лучше всего его реализовать. Но на уровне «сырого» производства общая идея будет такова:

1) написать правило (скажем, envir_cache), которое записывает переменную среды в файл (именованный, не случайно, envir_cache), , если этот файл еще не существует, или файл существует, но его содержимое отличается от значения переменной среды. (Что-то вроде if [ -f envir_cache ] и read cached_var < envir_cache и if [ "${myvar}" != "${cached_var}" ].)

2) сделать цель rebuild_cache зависимой от envir_cache.

Таким образом, правило rebuild_cache будет выполняться при первом запуске и всякий раз, когда переменная изменялась между запусками.

0 голосов
/ 18 ноября 2015

Это нелегко сделать с помощью CMake, но пример того, как сделать это в качестве включаемых модулей CMake, показан ниже. Решение зависит от использования пользовательской цели, которая выводит соответствующие переменные в файл и вызывает параметр cmake compare_files для сравнения предыдущего файла с файлом проверки и вызывает cmake для восстановления кеша в случае, если они не совпадают.

Решение включает тщательно разработанный модуль CMake include, который будет рекурсивно вызывать себя для проверки того, что кэшированные значения не были изменены переменной Environment. Если это так, он выполнит шаг восстановления кеша, вызвав cmake с соответствующими аргументами, как показано ниже. Ожидается, что вы будете вызывать макрос add_option для каждой переменной, которую вы хотите переопределить с помощью переменной Environment (см. Примеры ниже):

# Capture the full path to this CMake module file
if(NOT _option_cmake_file)
  set(_option_cmake_file ${CMAKE_CURRENT_LIST_FILE})
endif()

# When this CMake module is called as a script include the option file
if(_option_verify)
  include(${_option_file})
endif()

# add_option macro for adding cached values you want to be able to
# override with an environment variable of the same name
# _name - variable name to use for the cached value
# _type - type of cached variable
# _description - description of cached variable for CMake GUI
# _default - default value if no variable with same name is defined
macro(add_option _name _type _description _default)
  # Define _option_file to be created if not in verify mode
  if(NOT _option_verify)
    set(_option_file ${CMAKE_BINARY_DIR}/${_name}.cmake)
  endif()

  # Determine the source for the alue of the cached variable
  set(_option_output "set(_name ${_name})")
  list(APPEND _option_output "\nset(_type ${_type})")
  list(APPEND _option_output "\nset(_description \"${_description}\")")
  if(DEFINED ENV{${_name}})
    set(${_name} $ENV{${_name}} CACHE ${_type} "${_description}" FORCE)
    list(APPEND _option_output "\nset(${_name} $ENV{${_name}})")
  elseif(${_name})
    set(${_name} ${${_name}} CACHE ${_type} "${_description}" FORCE)
    set(ENV{${_name}} ${${_name}}) # needed to pass from verify back to rebuild_cache
    list(APPEND _option_output "\nset(${_name} ${${_name}})")
  else()
    set(${_name} ${_default} CACHE ${_type} "${_description}" FORCE)
    list(APPEND _option_output "\nset(${_name} ${_default})")
  endif()

  # Create the _option_file (or verify file) containing the values
  # defined above
  execute_process(
    COMMAND ${CMAKE_COMMAND} -E echo ${_option_output}
    OUTPUT_FILE ${_option_output}${_option_verify})

  # If not in verify mode create check target to verify value
  if(NOT _option_verify)
    # Only create parent check-variables target once
    if(NOT TARGET check-variables)
      add_custom_target(check-variables ALL)
    endif()
    # Use this file as custom CMake target to verify variable value
    add_custom_target(check-${_name}
      COMMAND ${CMAKE_COMMAND}
      -D_option_verify:String=-verify
      -D_option_file:Filepath=${_option_file}
      -D_option_sdir:Path=${CMAKE_SOURCE_DIR}
      -D_option_bdir:Path=${CMAKE_BINARY_DIR}
      -P ${_option_cmake_file}
      COMMENT "Checking variable '${_name}' for changes"
      VERBATIM)
    # Add custom target as dependency for parent check-variables target
    add_dependencies(check-variables check-${_name})
  else()
    # Use cmake to compare options file and verify file created above
    execute_process(
      COMMAND ${CMAKE_COMMAND} -E compare_files
        ${_option_file} ${_option_file}${_option_verify}
      OUTPUT_VARIABLE COMPARE_OUTPUT
      ERROR_VARIABLE COMPARE_ERROR
      RESULT_VARIABLE COMPARE_RESULT)
    # Remove verify file
    file(REMOVE ${_option_file}${_option_verify})
    # If compare failed, then call CMAKE to rebuild_cache
    if(NOT COMPARE_RESULT EQUAL 0)
      # Perform the rebuild_cache step
      execute_process(
        COMMAND ${CMAKE_COMMAND} -H${_option_sdir} -B${_option_bdir})
    endif()
  endif()
endmacro()

# In verify mode? then call add_option macro to initiate the process
if(_option_verify)
  # The values below come from the include(_option_file) above
  add_option(${_name} ${_type} "${_description}" ${${_name}})
endif()

Если вышеуказанный модуль CMake был назван add_option.cmake, вы можете использовать его следующим образом:

cmake_minimum_required(VERSION 2.8)
project(Example)
include(${PROJECT_SOURCE_DIR}/add_option.cmake)
add_option(MYVAR
  BOOL
  "A boolean cached value that can be overridden by Environment variable"
  ON)
add_option(MYSTR
  STRING
  "A string cached value that can be overridden by Environment variable"
  "some string")
message(STATUS "MYVAR=${MYVAR}")
message(STATUS "MYSTR=${MYSTR}")

С помощью вышеуказанного файла CMakeLists.txt выполните следующие действия (с использованием файлов Makefile Unix):

mkdir build
cd build

Следующий пример демонстрирует первоначальное создание Make-файлов Unix. Обратите внимание, что в этом случае переменные используют свои значения по умолчанию.

cmake .. -G "Unix Makefiles"
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- MYVAR=ON
-- MYSTR=some string
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build

В следующем примере показано, как make может вызывать цель check-variable и ее зависимые цели, созданные модулем add_option.cmake выше. Обратите внимание, что кэш перестроения не происходит.

make
Scanning dependencies of target check-MYVAR
[ 50%] Checking variable 'MYVAR' for changes
[ 50%] Built target check-MYVAR
Scanning dependencies of target check-MYSTR
[100%] Checking variable 'MYSTR' for changes
[100%] Built target check-MYSTR
Scanning dependencies of target check-variables
[100%] Built target check-variables

В следующем примере показано, как переменная окружения вызывает сбой одного из шагов check-variable и вызывает событие восстановления кеша. Обратите внимание на изменение значения MYVAR в процессе перестройки кэша.

make MYVAR=off
[ 50%] Checking variable 'MYVAR' for changes
-- MYVAR=off
-- MYSTR=some string
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYVAR
[100%] Checking variable 'MYSTR' for changes
[100%] Built target check-MYSTR
[100%] Built target check-variables

В следующем примере показано, как временно измененная выше переменная возвращается к значениям по умолчанию, а другая переменная запускается для изменения ее значения. Обратите внимание, что переменная MYVAR возвращается к своему значению по умолчанию, в то время как переменная MYSTR получает новое предоставленное значение.

make MYSTR="hi mom"
[ 50%] Checking variable 'MYSTR' for changes
-- MYVAR=ON
-- MYSTR=hi mom
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYSTR
[100%] Checking variable 'MYVAR' for changes
[100%] Built target check-MYVAR
[100%] Built target check-variables
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...