判断 make 是否在 Windows 或 Linux 上运行

9

有没有一种方法可以在makefile中知道GNU make是在Linux操作系统还是Windows操作系统上运行?

我已经编写了一个bash脚本来生成用于构建我的应用程序的makefile,在我的Debian机器上运行良好。我想尝试在MinGW/MSYS上构建它,但问题是我必须构建和运行一些测试程序来检查源代码中的错误,并且在Windows上运行它时,我必须添加.exe后缀。


是时候使用Maven了。它是跨平台的。 - MockerTim
1
为了避免这个特定的问题,你可以在所有平台上都包含 .exe 后缀;只要你在运行程序时记得包含它,Linux 就不会介意它是否存在。 - Ilmari Karonen
1
这是 https://dev59.com/PHRB5IYBdhLWcg3wH0SW 的副本。 - Michaelangel007
@Michaelangel007 不同意这是重复的。我搜索了关于在不同操作系统上使用 .exe 的特定问题,但谷歌首先显示了你引用的问题,该问题没有直接回答,只是收集了各种技术来识别操作系统,而不是专门为使用它的平台可选地添加“.exe”文件扩展名。其他技术可能允许更广泛的通用解决方案范围,以解决类似的问题,但这与重复回答或甚至提出此特定问题不同。 - user2895783
2个回答

5

更新
请阅读这篇类似但更好的回答:
https://dev59.com/PHRB5IYBdhLWcg3wH0SW#14777895


make(和gcc)可以通过使用 CygwinMinGW 轻松安装在 MS-Windows 上。

正如@ldigas所说,make 可以使用 UNAME:=$(shell uname) 来检测平台(命令 uname 也由 Cygwin 或 MinGW 安装程序安装)。

下面,我提供了一个完整的例子,基于make(和gcc),来解释如何构建一个共享库:根据平台生成 *.so*.dll

示例是基本/简单的,易于理解 :-)

让我们看看这五个文件:

 ├── app
 │   └── Makefile
 │   └── main.c
 └── lib
     └── Makefile
     └── hello.h
     └── hello.c

The Makefiles

app/Makefile

app.exe: main.o
        gcc -o $@ $^ -L../lib -lhello
        # '-o $@'    => output file => $@ = the target file (app.exe)
        # '   $^'    => no options => Link all depended files 
        #            => $^ = main.o and other if any
        # '-L../lib' => look for libraries in directory ../lib
        # '-lhello   => use shared library hello (libhello.so or hello.dll)

%.o: %.c
        gcc -o $@ -c $< -I ../lib
        # '-o $@'     => output file => $@ = the target file (main.o)
        # '-c $<'     => COMPILE the first depended file (main.c)
        # '-I ../lib' => look for headers (*.h) in directory ../lib

clean:
        rm -f *.o *.so *.dll *.exe

lib/Makefile

UNAME := $(shell uname)

ifeq ($(UNAME), Linux)
TARGET = libhello.so
else
TARGET = hello.dll
endif

$(TARGET): hello.o
        gcc  -o $@  $^  -shared
        # '-o $@'    => output file => $@ = libhello.so or hello.dll
        # '   $^'    => no options => Link all depended files => $^ = hello.o
        # '-shared'  => generate shared library

%.o: %.c
        gcc  -o $@  -c $<  -fPIC
        # '-o $@' => output file => $@ = the target file (hello.o)
        # '-c $<' => compile the first depended file (hello.c)
        # '-fPIC' => Position-Independent Code (required for shared lib)

clean:
        rm -f *.o *.so *.dll *.exe

源代码

app/main.c

#include "hello.h" //hello()
#include <stdio.h> //puts()

int main()
{
    const char* str = hello();
    puts(str);
}

lib/hello.h

#ifndef __HELLO_H__
#define __HELLO_H__

const char* hello();

#endif

lib/hello.c

#include "hello.h"

const char* hello()
{
    return "hello";
}

构建

修复Makefiles的复制问题(将前导空格替换为制表符)。

> sed  -i  's/^  */\t/'  */Makefile

make 命令在两个平台上是相同的。以下是在 MS-Windows 上的输出(已删除不必要的行)。

> cd lib
> make clean
> make
gcc  -o hello.o  -c hello.c  -fPIC
gcc  -o hello.dll  hello.o  -shared
> cd ../app
> make clean
> make
gcc -o main.o -c main.c -I ../lib
gcc -o app.exe main.o -L../lib -lhello

运行

该应用程序需要知道共享库的位置。

在 MS-Windows 上,最简单/基本/愚蠢的方法是将库复制到应用程序所在的位置:

> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'

在Linux上,使用LD_LIBRARY_PATH环境变量:
> export LD_LIBRARY_PATH=lib

在这两个平台上,运行命令行和输出结果是相同的:

> app/app.exe
hello

5

谢谢,我认为这应该可以工作。也许可以添加一些忽略版本的代码,以便它可以在不同的发布版本上工作。 - Gianni Pisetta
当我尝试这样做时,我从Powershell调用的Makefiles失败了,因为它们找不到uname。对于MinGW/MSYS,也许你可以让你的makefile检查$MSYSTEM环境变量?虽然这在Cygwin中没有帮助。 - AJM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接