【问题标题】:How do write a makefile for C#?如何为 C# 编写 makefile?
【发布时间】:2013-12-22 00:44:18
【问题描述】:

我有一个简单的 C# 程序,需要从 Linux 的命令行通过 mono 运行。到目前为止,这是我的 makefile 的内容。它基于我为另一个程序找到的 C++ makefile。我尝试修改它以使用我的 C# 程序,但它说找不到某些源文件。

.PHONY : build view clean

build : test
@# do nothing

test : test.o
gmcs test test.o

test.o : test.cs
gmcs test.cs

view :
@\less test.cs

clean :
-\rm *.exe
-\rm test

我以前从未使用过 makefile,所以我真的不知道我做错了什么。我的整个项目中只有一个文件,就是 test.cs。这样做的最终目标是能够通过在命令行中键入来运行程序:

./test

它还应该清理生成的 .exe 文件。

【问题讨论】:

  • 您得到的确切错误是什么? make test 的输出是什么?
  • 输出为:gmcs test.cs gmcs test test.o error CS2001: Source file 'test' could not be found 错误 CS2001: Source file 'test.o' could not be found 编译失败: 2 个错误,0 个警告:*** [测试] 错误 1
  • 我不认为问题出在 makefile 上。你确定你使用 gmcs 对吗?根据mono-project.com/Mono_Basics,您从运行的第一个命令中得到一个 exe,而不是 .o 文件。
  • 我尝试将所有 .o 文件更改为 .exe,但我收到错误消息“test.exe”是二进制文件,而不是除之前的所有错误之外的文本文件。
  • 你能用MonoDevelop吗?无论如何,显然问题不在于makefile,而在于您使用gmcs的方式。尝试在没有 make 文件的情况下编译代码,直到获得正确的命令。

标签: c# mono makefile


【解决方案1】:

我整理了一个非常简单的适用于我的 Mono Makefile:

.PHONY: test.cs

all: run

test.exe: test.cs
    @gmcs test.cs 

clean:
    @rm -f test.exe

run: test.exe
    @mono test.exe

这有一个很好的属性,如果你只输入'make',它会重新编译并执行 test.cs。

【讨论】:

【解决方案2】:

我在我的项目中使用了一个非常简单的 Makefile 模型。 (PS:我在 GNU/Linux 上使用 mono 进行编译,但是更改配置非常容易(阅读我的 cmets))

#change this to the name of the Main class file, without file extension
MAIN_FILE = App/Program

#change this to the depth of the project folders
#if needed, add a prefix for a common project folder
CSHARP_SOURCE_FILES = $(wildcard */*/*.cs */*.cs *.cs)

#add needed flags to the compilerCSHARP_FLAGS = -out:$(EXECUTABLE)
CSHARP_FLAGS = -out:$(EXECUTABLE)

#change to the environment compiler
CSHARP_COMPILER = mcs

#if needed, change the executable file
EXECUTABLE = $(MAIN_FILE).exe

#if needed, change the remove command according to your system
RM_CMD = -rm -f $(EXECUTABLE)



all: $(EXECUTABLE)

$(EXECUTABLE): $(CSHARP_SOURCE_FILES)
    @ $(CSHARP_COMPILER) $(CSHARP_SOURCE_FILES) $(CSHARP_FLAGS)
    @ echo compiling...

run: all
    ./$(EXECUTABLE)

clean:
    @ $(RM_CMD)

remake:
    @ $(MAKE) clean
    @ $(MAKE)

【讨论】:

    【解决方案3】:

    为了回答这个问题,我将解释更多关于makefile的内容:
    当你有这样的陈述时:

    test: test.o
        gmcs test test.o
    

    这意味着:为了构建目标测试,您需要目标 test.o 并运行命令gmcs test test.o

    当您在命令行中输入make target 时,它将尝试按照您在makefile 中编写的规则来构建目标。所以,在我们的例子中,当你执行make test时,程序会尝试构建test,看到之前需要构建test.o,找到这条规则:

    test.o: test.cs
        gmcs test.cs
    

    找到文件test.cs,运行gmcs test.cs,然后回到上一个目标,现在运行gmcs test test.o,你的目录下没有test和test.o,所以命令报错.

    让你感到困惑(我只能猜到这一点)是 c++ make 文件。在 c++ 中,您首先创建目标文件(linux 中的 .o,windows 中的 .obj),然后将它们链接在一起。我不确定,但是您为 .o 目标所拥有的 c++ makefile 中的命令带有 -c 标志 - 一个告诉 gcc 仅编译的标志。在您的情况下,程序在第一个命令之后完全编译。

    所以 - 您正在寻找的 makefile 如下:

    PHONY : build view clean
    
    build : test
    @# do nothing
    
    test: test.cs
        gmcs test.cs -out:test
    
    view :
    @\less test.cs
    
    clean :
    -\rm *.exe
    -\rm test
    

    这将创建一个名为 test 的文件,您可以使用 mono test 运行它。如果你想省略mono,你可以创建一个脚本文件:

    #! /bin/bash
    
    mono test 
    

    不要忘记更改权限以允许您执行它!

    【讨论】:

    • gmcs test.cs -out:test 在 Scientific Linux 下似乎不适用于 Mono 2.4.3,它出现以下错误:未处理的异常:System.ArgumentException:模块文件名' test' 必须有文件扩展名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 2011-02-15
    相关资源
    最近更新 更多