判断 make 是在 windows 还是 linux 上运行

Gia*_*tta 7 makefile gnu-make os-agnostic os-detection

有没有办法在 makefile 中知道 GNU make 是在 linux 操作系统还是 windows 操作系统上运行?

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

Roo*_*ook 5

uname命令应该为您提供有关操作系统的基本信息。您可以使用它,然后根据返回值创建一个 IF 吗?

为了不重写所有内容,这里 - 您可能会对这两个问题感兴趣
1. 检测 makefile 的操作系统
2. 区分 Windows 和类 Unix 系统的 Makefile


oli*_*bre 5

更新
请阅读这个类似但更好的答案:https :
//stackoverflow.com/a/14777895/938111


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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

源代码

app/main.c

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

int main()
{
    const char* str = hello();
    puts(str);
}
Run Code Online (Sandbox Code Playgroud)

lib/hello.h

#ifndef __HELLO_H__
#define __HELLO_H__

const char* hello();

#endif
Run Code Online (Sandbox Code Playgroud)

lib/hello.c

#include "hello.h"

const char* hello()
{
    return "hello";
}
Run Code Online (Sandbox Code Playgroud)

构建

修复Makefiles副本(用制表替换前导空格)。

> sed  -i  's/^  */\t/'  */Makefile
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

运行

应用程序需要知道共享库在哪里。

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

> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'
Run Code Online (Sandbox Code Playgroud)

在 Linux 上,使用LD_LIBRARY_PATH环境变量:

> export LD_LIBRARY_PATH=lib
Run Code Online (Sandbox Code Playgroud)

两个平台上的运行命令行和输出是相同的:

> app/app.exe
hello
Run Code Online (Sandbox Code Playgroud)