是否可以通过 makefile 设置环境变量?

Is it possible to set environment variable through a makefile?

我想利用 MALLOC_PERTURB_ 可以更改内存分配参数的环境变量 (man 3 mallopt)。但是,我想在应用程序级别而不是整个系统级别控制分配参数。理想情况下,如果我可以通过项目的 makefile 来控制它们。我试图通过 makefile 更改提到的变量,但没有成功。

为了测试,我创建了这个 test.c 文件:

#include<stdlib.h>
#include<stdio.h>

#define N 50

int main()
{
    char *chars;
    int i;

    if (NULL == (chars = malloc(N * sizeof(*chars))))
        return EXIT_FAILURE;

    free(chars);

    for (i = 0; i < N; ++i)
        printf("%c", chars[i]);
    printf("\n");

    return EXIT_SUCCESS;
}

是的,我知道我正在从释放的内存中读取,但这就是使用 MALLOC_PERTURB_.

的全部意义所在

预期结果:50 个字符的 ASCII 字符值为 MALLOC_PERTURB_。

足够接近:

$ export MALLOC_PERTURB_=97
$ gcc test.c -o test
$ ./test
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa��


$ export MALLOC_PERTURB_=105
$ gcc test.c -o test
$ ./test
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii��

然后我尝试将编译包含在 makefile 中,但没有成功。

正在导出变量 (as proposed here)

生成文件

all:
    export MALLOC_PERTURB_=110
    gcc test.c -o test

结果(我期待 110 的 'n' 个字母)

$ export MALLOC_PERTURB_=105
$ make
export MALLOC_PERTURB_=110
gcc test.c -o test 
$ ./test
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii��

递归调用make(as proposed here)

生成文件

all:
    MALLOC_PERTURB_=110
    $(MAKE) rec

rec:
    gcc test.c -o test

结果(我期待 110 的 'n' 个字母)

$ export MALLOC_PERTURB_=105
$ make
MALLOC_PERTURB_=110
make rec
make[1]: Entering directory '~/test'
gcc test.c -o test
make[1]: Leaving directory '~/test'
$ ./test
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii��

我试图从包含 MALLOC_PERTURB_ 的 github 的 makefile 中找到任何灵感,但它们太复杂了,我无法理解。 一些示例:(1), (2), (3)

一些技术信息:

Linux 4.0.1-1-ARCH x86_64
gcc version 4.9.2 20150304 (prerelease) (GCC)
GNU Make 4.1

在Bash中,可以在命令前指定环境变量,如

MALLOC_PERTURB_=105 gcc test.c -o test

MALLOC_PERTURB_=105 ./test

(我相信只有 运行 必须设置这个变量,而不是编译。)

因为你在 Linux 上,所以 Make 很有可能将 Bash 用作 shell,你可以将上面的行放在你的 makefile 中。

Browning,在makefile 中设置环境变量很容易,您已经这样做了,但这不是您想要的。这使得它在编译期间采用该值。但是你希望它在你 运行 程序时改变 malloc 的行为。

阅读您引用的手册页确认您需要在您的程序 运行ning 所在的环境中设置环境变量。另外阅读评论,已经提到设置环境变量的 makefile 只对测试程序这样做,它们实际上 运行 作为构建的一部分。

您不希望它出现在 makefile 中。您希望在实际 运行 程序时设置它,这是其他评论和答案告诉您如何做的。很抱歉接受一个答案,但我需要更多空间来解决这个问题,而且这就是你的答案。你已经知道怎么做了。你只是不知道它到底是什么。

您也可以在编译时通过将 M_PERTURB 选项传递给 mallopt() 函数(glibc 2.4 或更高版本)来设置 "MALLOC_PERTURB_" 值。有关详细信息,请参阅 http://man7.org/linux/man-pages/man3/mallopt.3.html

因此,如果您希望您的程序在编译时合并环境变量 "MALLOC_PERTURB_" 的设置,那么这样的事情应该可行:

#include<stdlib.h>
#include<stdio.h>

#include <malloc.h> // for mallopt() and M_PERTURB

#define N 50

int main()
{
    char *chars;
    int i;

#if MALLOC_PERTURB_
    mallopt( M_PERTURB, MALLOC_PERTURB_);
#endif

    if (NULL == (chars = malloc(N * sizeof(*chars))))
        return EXIT_FAILURE;

    free(chars);

    for (i = 0; i < N; ++i)
        printf("%c", chars[i]);
    printf("\n");

    return EXIT_SUCCESS;
}

然后让您的 makefile 将 MALLOC_PERTURB_ 值作为宏定义传递给编译器命令行(或您要使用的任何机制):

gcc -DMALLOC_PERTURB_=97 test.c -o test