同一个 Makefile 在不同的计算机上执行不同的命令
Same Makefile executing different commands in different computers
在安装pintos的过程中,我不得不运行 make
。
以下是 Makefile。
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
它在一台计算机上正确执行。 (命令的输出如下所示)
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
gcc -Wall -W -c -o squish-pty.o squish-pty.c
gcc -lm squish-pty.o -o squish-pty
gcc -Wall -W -c -o squish-unix.o squish-unix.c
gcc -lm squish-unix.o -o squish-unix
但在其他电脑上出现以下错误
gcc -lm setitimer-helper.o -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xc9): undefined reference to `floor'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'setitimer-helper' failed
make: *** [setitimer-helper] Error 1
如果查看两个 make
命令的第一行输出
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
和
gcc -lm setitimer-helper.o -o setitimer-helper
它们是不同的。
为什么 make
对同一个 Makefile 执行不同的命令?以及我应该怎么做才能消除错误?
在第一台电脑上,setitimer-helper.o
文件不存在或者setitimer-helper.c
文件较新,所以make需要重建它。因此它运行编译器,然后执行 link 操作:
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
在第二台电脑上,setitimer-helper.o
文件已经存在,并且比setitimer-helper.c
文件新,所以不需要编译命令,第二台电脑直接进入link行:
gcc -lm setitimer-helper.o -o setitimer-helper
真正的问题是为什么您在第二台计算机上遇到 linker 错误。
答案是 -lm
标志需要出现在 linker 行 之后 目标文件。发生这种情况是因为您将 -lm
添加到 LDFLAGS
变量,但该变量不正确:它应该包含告诉 linker 在哪里查找文件等的选项(例如, -L
选项)。
库应该添加到 LDLIBS
变量,而不是 LDFLAGS
。将您的 makefile 更改为:
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDLIBS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
您的 link 行将如下所示:
gcc setitimer-helper.o -o setitimer-helper -lm
并且应该可以正常工作。
在安装pintos的过程中,我不得不运行 make
。
以下是 Makefile。
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
它在一台计算机上正确执行。 (命令的输出如下所示)
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
gcc -Wall -W -c -o squish-pty.o squish-pty.c
gcc -lm squish-pty.o -o squish-pty
gcc -Wall -W -c -o squish-unix.o squish-unix.c
gcc -lm squish-unix.o -o squish-unix
但在其他电脑上出现以下错误
gcc -lm setitimer-helper.o -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xc9): undefined reference to `floor'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'setitimer-helper' failed
make: *** [setitimer-helper] Error 1
如果查看两个 make
命令的第一行输出
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
和
gcc -lm setitimer-helper.o -o setitimer-helper
它们是不同的。
为什么 make
对同一个 Makefile 执行不同的命令?以及我应该怎么做才能消除错误?
在第一台电脑上,setitimer-helper.o
文件不存在或者setitimer-helper.c
文件较新,所以make需要重建它。因此它运行编译器,然后执行 link 操作:
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
在第二台电脑上,setitimer-helper.o
文件已经存在,并且比setitimer-helper.c
文件新,所以不需要编译命令,第二台电脑直接进入link行:
gcc -lm setitimer-helper.o -o setitimer-helper
真正的问题是为什么您在第二台计算机上遇到 linker 错误。
答案是 -lm
标志需要出现在 linker 行 之后 目标文件。发生这种情况是因为您将 -lm
添加到 LDFLAGS
变量,但该变量不正确:它应该包含告诉 linker 在哪里查找文件等的选项(例如, -L
选项)。
库应该添加到 LDLIBS
变量,而不是 LDFLAGS
。将您的 makefile 更改为:
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDLIBS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
您的 link 行将如下所示:
gcc setitimer-helper.o -o setitimer-helper -lm
并且应该可以正常工作。