运行 cmake 命令时如何加载环境文件(.env)?

问题描述 投票:0回答:2

是否有任何选项可以允许我从 dotenv 文件加载键=值对?我知道我可以做到

-E env key=value
但我有很多值,我想从 dotenv 文件加载它们,因为其他工具可以从中加载环境变量。我不想做 bash 技巧,因为我希望它尽可能简单并且跨平台。

cmake
2个回答
5
投票

没有对 dotenv 文件的内置支持,但这里有纯 CMake 的完整实现。对于您的 CMakeLists.txt,这是一个示例:

cmake_minimum_required(VERSION 3.21)
project(env-test NONE)

add_custom_target(
  example
  COMMAND 
    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/env.cmake 
    ${CMAKE_CURRENT_SOURCE_DIR}/.env  # dotenv
    env  # command
)

这是

.env
文件的内容:

foo=bar
bears=beets
battlestar=galactica

这是此工作的演示:

$ cmake -G Ninja -S . -B build
$ cmake --build build --target example
...
foo=bar
bears=beets
battlestar=galactica

这是实现此功能的(复杂的)

env.cmake
脚本:

cmake_minimum_required(VERSION 3.21)

if (CMAKE_ARGC LESS 5)
  message(FATAL_ERROR "Usage: cmake -P env.cmake <dotenv> [command...]")
endif ()

set(dotenv "${CMAKE_ARGV3}")

if (NOT EXISTS "${dotenv}")
  message(FATAL_ERROR "Dot-env file not found: ${dotenv}")
endif ()

set(command "")
math(EXPR argc "${CMAKE_ARGC} - 1")
foreach (i RANGE 4 ${argc})
  list(APPEND command "${CMAKE_ARGV${i}}")
endforeach ()

file(STRINGS "${dotenv}" entries)
foreach (entry IN LISTS entries)
  if (entry MATCHES "^([^=]+)=(.*)$")
    set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")
  else ()
    message(FATAL_ERROR "Malformed dotenv entry:\n${entry}")
  endif ()
endforeach ()

execute_process(COMMAND ${command} COMMAND_ERROR_IS_FATAL ANY)

0
投票

您可以将

.env
文件作为字符串加载,并使用 foreach 将其分配给您的环境变量。

CMakeLists.txt

file(STRINGS ${CMAKE_HOME_DIRECTORY}/.env ENV_FILE)
foreach(VAR ${ENV_FILE})
    string(REGEX MATCH "^[^=]*" KEY ${VAR})
    string(REGEX REPLACE "^[^=]*=" "" VALUE ${VAR})
    set(ENV{${KEY}} ${VALUE})
endforeach()

message(STATUS $ENV{EXAMPLE_ENV_VAR})

.env 文件

EXAMPLE_ENV_VAR="hello world"
© www.soinside.com 2019 - 2024. All rights reserved.