【问题标题】:makefile pathing issues on OSXOSX 上的 makefile 路径问题
【发布时间】:2012-03-16 04:13:15
【问题描述】:

好的,我想我会尝试最后一次更新,看看它是否能让我到任何地方。我创建了一个非常小的测试用例。这不应该构建任何东西,它只是测试路径设置。另外我已经设置了路径,所以没有空格。这是我能想到的最小、最简单的测试用例。

此 makefile 将设置路径,回显路径,使用指定的完整路径运行 avr-gcc -v,然后尝试在未指定完整路径的情况下运行它。它应该在第二次尝试的路径中找到avr-gcc,但没有

制作文件

TOOLCHAIN := /Users/justinzaun/Desktop/AVRBuilder.app/Contents/Resources/avrchain


PATH := ${TOOLCHAIN}/bin:${PATH}
export PATH


all:
    @echo ${PATH}
    @echo --------
    "${TOOLCHAIN}/bin/avr-gcc" -v
    @echo --------
    avr-gcc -v

输出

JUSTINs-MacBook-Air:Untitled justinzaun$ make
/Users/justinzaun/Desktop/AVRBuilder.app/Contents/Resources/avrchain/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
--------
"/Users/justinzaun/Desktop/AVRBuilder.app/Contents/Resources/avrchain/bin/avr-gcc" -v
Using built-in specs.
COLLECT_GCC=/Users/justinzaun/Desktop/AVRBuilder.app/Contents/Resources/avrchain/bin/avr-gcc
COLLECT_LTO_WRAPPER=/Users/justinzaun/Desktop/AVRBuilder.app/Contents/Resources/avrchain/bin/../libexec/gcc/avr/4.6.3/lto-wrapper
Target: avr
Configured with: /Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../gcc/configure --prefix=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --exec-prefix=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --datadir=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --target=avr --enable-languages=c,objc,c++ --disable-libssp --disable-lto --disable-nls --disable-libgomp --disable-gdbtk --disable-threads --enable-poison-system-directories
Thread model: single
gcc version 4.6.3 (GCC) 
--------
avr-gcc -v
make: avr-gcc: No such file or directory
make: *** [all] Error 1
JUSTINs-MacBook-Air:Untitled justinzaun$ 


原始问题

我正在尝试从 makefile 中设置路径。我似乎无法在 OSX 上执行此操作。使用PATH := /new/bin/:$(PATH) 设置路径不起作用。请参阅下面的 makefile。

制作文件

PROJECTNAME = Untitled

# Name of target controller
# (e.g. 'at90s8515', see the available avr-gcc mmcu
# options for possible values)
MCU = atmega640

# id to use with programmer
# default: PROGRAMMER_MCU=$(MCU)
# In case the programer used, e.g avrdude, doesn't
# accept the same MCU name as avr-gcc (for example
# for ATmega8s, avr-gcc expects 'atmega8' and 
# avrdude requires 'm8')
PROGRAMMER_MCU = $(MCU)

# Source files
# List C/C++/Assembly source files:
# (list all files to compile, e.g. 'a.c b.cpp as.S'):
# Use .cc, .cpp or .C suffix for C++ files, use .S
# (NOT .s !!!) for assembly source code files.
PRJSRC = main.c   \
         utils.c

# additional includes (e.g. -I/path/to/mydir)
INC = 

# libraries to link in (e.g. -lmylib)
LIBS = 

# Optimization level,
# use s (size opt), 1, 2, 3 or 0 (off)
OPTLEVEL = s



### You should not have to touch anything below this line ###



PATH := /Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin:/usr/bin:/bin:$(PATH)
CPATH := /Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/include


# HEXFORMAT -- format for .hex file output
HEXFORMAT = ihex

# compiler
CFLAGS = -I. $(INC) -g -mmcu=$(MCU) -O$(OPTLEVEL)  \
         -fpack-struct -fshort-enums               \
         -funsigned-bitfields -funsigned-char      \
         -Wall -Wstrict-prototypes                 \
         -Wa,-ahlms=$(firstword                    \
                    $(filter %.lst, $(<:.c=.lst)))

# c++ specific flags
CPPFLAGS = -fno-exceptions                 \
           -Wa,-ahlms=$(firstword          \
           $(filter %.lst, $(<:.cpp=.lst)) \
           $(filter %.lst, $(<:.cc=.lst))  \
           $(filter %.lst, $(<:.C=.lst)))

# assembler
ASMFLAGS = -I. $(INC) -mmcu=$(MCU)          \
           -x assembler-with-cpp            \
           -Wa,-gstabs,-ahlms=$(firstword   \
           $(<:.S=.lst) $(<.s=.lst))

# linker
LDFLAGS = -Wl,-Map,$(TRG).map -mmcu=$(MCU)  \
          -lm $(LIBS)

##### executables ####
CC=avr-gcc
OBJCOPY=avr-objcopy
OBJDUMP=avr-objdump
SIZE=avr-size
AVRDUDE=avrdude
REMOVE=rm -f

##### automatic target names ####
TRG=$(PROJECTNAME).out
DUMPTRG=$(PROJECTNAME).s

HEXROMTRG=$(PROJECTNAME).hex
HEXTRG=$(HEXROMTRG) $(PROJECTNAME).ee.hex

# Start by splitting source files by type
#  C++
CPPFILES=$(filter %.cpp, $(PRJSRC))
CCFILES=$(filter %.cc, $(PRJSRC))
BIGCFILES=$(filter %.C, $(PRJSRC))
#  C
CFILES=$(filter %.c, $(PRJSRC))
#  Assembly
ASMFILES=$(filter %.S, $(PRJSRC))

# List all object files we need to create
OBJDEPS=$(CFILES:.c=.o)     \
        $(CPPFILES:.cpp=.o) \
        $(BIGCFILES:.C=.o)  \
        $(CCFILES:.cc=.o)   \
        $(ASMFILES:.S=.o)

# Define all lst files.
LST=$(filter %.lst, $(OBJDEPS:.o=.lst))

# All the possible generated assembly
# files (.s files)
GENASMFILES=$(filter %.s, $(OBJDEPS:.o=.s))

.SUFFIXES : .c .cc .cpp .C .o .out .s .S \
            .hex .ee.hex .h .hh .hpp

# Make targets:
# all, disasm, stats, hex, writeflash/install, clean
all: $(TRG)

$(TRG): $(OBJDEPS)
    $(CC) $(LDFLAGS) -o $(TRG) $(OBJDEPS)

#### Generating assembly ####
# asm from C
%.s: %.c
    $(CC) -S $(CFLAGS) $< -o $@

# asm from (hand coded) asm
%.s: %.S
    $(CC) -S $(ASMFLAGS) $< > $@

# asm from C++
.cpp.s .cc.s .C.s :
    $(CC) -S $(CFLAGS) $(CPPFLAGS) $< -o $@

#### Generating object files ####
# object from C
.c.o:
    $(CC) $(CFLAGS) -c $< -o $@

# object from C++ (.cc, .cpp, .C files)
.cc.o .cpp.o .C.o :
    $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

# object from asm
.S.o :
    $(CC) $(ASMFLAGS) -c $< -o $@

#### Generating hex files ####
# hex files from elf
.out.hex:
    $(OBJCOPY) -j .text                    \
               -j .data                    \
               -O $(HEXFORMAT) $< $@

.out.ee.hex:
    $(OBJCOPY) -j .eeprom                     \
               --change-section-lma .eeprom=0 \
               -O $(HEXFORMAT) $< $@

#### Information ####
info:
    @echo PATH:
    @echo "$(PATH)"
    $(CC) -v
    which $(CC)

#### Cleanup ####
clean:
    $(REMOVE) $(TRG) $(TRG).map $(DUMPTRG)
    $(REMOVE) $(OBJDEPS)
    $(REMOVE) $(LST)
    $(REMOVE) $(GENASMFILES)
    $(REMOVE) $(HEXTRG)

错误

JUSTINs-MacBook-Air:Untitled justinzaun$ make
avr-gcc -I.  -g -mmcu=atmega640 -Os -fpack-struct -fshort-enums -funsigned-bitfields -funsigned-char -Wall -Wstrict-prototypes -Wa,-ahlms=main.lst -c main.c -o main.o
make: avr-gcc: No such file or directory
make: *** [main.o] Error 1
JUSTINs-MacBook-Air:Untitled justinzaun$

如果我将CC= 更改为包含完整路径:

CC=/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin/avr-gcc

然后它会找到它,但这似乎不是正确的做事方式。例如,它试图使用as 系统而不是正确路径中的系统。

更新 - 可以肯定的是,我也添加了ls 命令的输出,以便每个人都知道该文件存在。此外,我还在 makefile 中添加了一个 make info 目标并显示该输出。

JUSTINs-MacBook-Air:Untitled justinzaun$ ls /Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin
ar      avr-elfedit avr-man     avr-strip   objcopy
as      avr-g++     avr-nm      avrdude     objdump
avr-addr2line   avr-gcc     avr-objcopy c++     ranlib
avr-ar      avr-gcc-4.6.3   avr-objdump g++     strip
avr-as      avr-gcov    avr-ranlib  gcc
avr-c++     avr-gprof   avr-readelf ld
avr-c++filt avr-ld      avr-size    ld.bfd
avr-cpp     avr-ld.bfd  avr-strings nm
JUSTINs-MacBook-Air:Untitled justinzaun$ 

make info 的输出与我的路径中的\

JUSTINs-MacBook-Air:Untitled justinzaun$ make info
PATH:
/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
avr-gcc -v
make: avr-gcc: No such file or directory
make: *** [info] Error 1
JUSTINs-MacBook-Air:Untitled justinzaun$ 

make info 的输出,\ 不在我的路径中

JUSTINs-MacBook-Air:Untitled justinzaun$ make info
PATH:
/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
avr-gcc -v
make: avr-gcc: No such file or directory
make: *** [info] Error 1
JUSTINs-MacBook-Air:Untitled justinzaun$ 

更新 - 当我将CC 设置为包含上述完整路径时,这是make info 的结果。

JUSTINs-MacBook-Air:Untitled justinzaun$ make info
PATH:
/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin/avr-gcc -v
Using built-in specs.
COLLECT_GCC=/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin/avr-gcc
COLLECT_LTO_WRAPPER=/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin/../libexec/gcc/avr/4.6.3/lto-wrapper
Target: avr
Configured with: /Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../gcc/configure --prefix=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --exec-prefix=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --datadir=/Users/justinzaun/Development/AVRBuilder/Packages/gccobj/../build/ --target=avr --enable-languages=c,objc,c++ --disable-libssp --disable-lto --disable-nls --disable-libgomp --disable-gdbtk --disable-threads --enable-poison-system-directories
Thread model: single
gcc version 4.6.3 (GCC) 
which /Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR\ Builder.app/Contents/Resources/avrchain/bin/avr-gcc
/Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin/avr-gcc
JUSTINs-MacBook-Air:Untitled justinzaun$ 

【问题讨论】:

  • 将工具安装到名称中没有空格的目录不是最简单的解决方案吗?

标签: makefile


【解决方案1】:

我在 OSX 和 Linux 上尝试了您的示例,并得到了与您相同的结果。我不太明白为什么这不起作用(我很想知道),但我确实有两种解决方法可能会有所帮助。

导出外壳

不要在 Makefile 中设置 PATH,而是像这样覆盖 SHELL:

export SHELL=/Users/whatever/avr-dir/wrapper

这是该包装器的一个可能版本:

#!/bin/bash
PATH="/Users/whatever/avr-dir:${PATH}"
/bin/bash "$@"

Make 将调用此包装器来运行 yoru 食谱的每一行。这有点难看,但它在 OSX 上确实对我有用。

外面

在 make 之外修复 PATH。也许创建一个脚本,每次登录时运行一次以修复 shell 中的 PATH,或者创建一个小脚本(我通常称之为mk)来修复 PATH,然后调用 make 传递任何参数。这是一个例子:

#!/bin/bash
PATH="/Users/whatever/avr-dir:${PATH}" exec make "$@"

我知道您要求使用 Makefile 解决方案,但我想我还是会提到这个选项。这只是我的看法,但诸如 PATH 之类的东西往往是特定于机器的(而不是特定于项目的),我更喜欢将它们与源代码分开。

【讨论】:

  • 您先生是救生员。我不知道 为什么 无法从 makefile 中设置路径,但您的 SHELL= 解决方法有效。我会将其标记为正确,因为它允许我使用我的工具链进行编译,尽管使用了一种解决方法来设置路径。 Xcode 可以调用这个 makefile 并找到 avr-gcc 的事实解决了我的主要问题。
  • 我无法在 GNU/Linux 上使用从 3.81 到 4.1 的任何版本的 GNU make 重现这个(对于没有空格的路径)(你没有说你正在使用什么版本)。我从其他人那里听说,OSX 发布了一个修改过的 GNU make 版本,其中有一些在标准版本的 GNU make 中没有出现的错误。也许如果你从源代码构建你自己的 GNU make 会更好。
  • @MadScientist 好建议!
【解决方案2】:

您的问题不是make 找不到avr-gcc。您的问题出在这一行:

$(CC) $(CFLAGS) -mmcu=$(MCU) -c $(input) -o $(output)

由于尚未定义 $(input)$(output),因此您的 avr-gcc 命令行不完整。尝试将该行改为:

$(CC) $(CFLAGS) -mmcu=$(MCU) -c $< -o $@

$&lt;$@自动 变量,分别定义为“第一个先决条件”和“输出目标”。

【讨论】:

  • makefile 可能是错误的,但这不是错误的原因。我已经发布了更新的 makefile 和错误消息。它仍然归结为在路径中找不到 avr-gcc,我可以看到它在那里。
  • 如果问题是在路径中找不到 avr-gcc,错误将是“找不到命令”,而不是“没有这样的文件或目录”,并且 make 的退出代码将为 127 ,而不是 1。
  • -我会看看他们的其他事情,只是看起来很奇怪。 main.c 也在那里。
  • 我真的认为这仍然是一个路径问题,请参阅我更新的问题。如果我只是遗漏了其他东西并且这不是路径问题,那么我真的不知道它是什么。
【解决方案3】:

问题 make 无法找到 avr-gcc,这是由于 PATH= 行中的 \ 造成的。

$ mkdir /tmp/foo\ bar
$ cd /tmp/foo\ bar
$ (echo "#! /bin/sh"; echo "echo this got run") > execable
$ chmod +x execable
$ mkdir /tmp/tstmake; cd /tmp/tstmake

(现在制作一个内容如图所示的 Makefile)

$ cat Makefile
PATH := /tmp/foo\ bar:$(PATH)

all:
        @echo path is "$(PATH)"
        execable
$ make
path is /tmp/foo\ bar:/Users/torek/bin.i386:/Users/torek/scripts:[snipped lots]
execable
make: execable: Command not found
make: *** [all] Error 127
$ ed Makefile
71
1s/\\//p
PATH := /tmp/foo bar:$(PATH)
w
70
q
$ make
path is /tmp/foo bar:/Users/torek/bin.i386:/Users/torek/scripts:[snipped lots]
execable
this got run


更新:这不是唯一的问题,至少当我使用我的 MBP 来模拟问题时。剩下的两个是:
  • CPATH 还需要删除反斜杠(这是关于这些 := 设置的一般规则)
  • CPATH 需要明确exported,通过添加行

    导出 CPATH

Makefile

(有时需要反斜杠但其他时候不需要反斜杠的原因与字符串被显式传递给 shell 的次数有关:一次是在 $(CC) 中,但零次是环境变量或$(PATH)的一部分。)

【讨论】:

  • 我已将路径线设置为PATH := /Users/justinzaun/Library/Developer/Xcode/DerivedData/AVR_Builder-gxiykwiwjywvoagykxvmotvncbyd/Build/Products/Debug/AVR Builder.app/Contents/Resources/avrchain/bin:$(PATH),但我仍然得到make: avr-gcc: No such file or directory。我添加 ls 命令的输出只是为了让我知道我没有疯。
  • 嗯。当您设置好手动调用avr-gcc 时,which(或type -p)会说什么?例如在我的 MBP which gcc 上打印 /usr/bin/gcc。另外,有趣的是我得到的是Command not found而不是No such file or directory,那里肯定有线索。
  • 我添加了make info 的结果和硬编码的CC。这是您要查找的信息吗?
  • 不,我只是想知道一些似乎无关紧要的事情。我想我明白了,让我编辑答案,还缺少两个步骤!
【解决方案4】:

鉴于此页面没有正确答案,我将链接到此页面:

How I could add dir to $PATH in Makefile?

无论出于何种原因,除非您也设置了 SHELL 变量,否则 OS X 不会导出 PATH。

所以:

SHELL=/bin/bash
export PATH:=/foo/bar:$(PATH)

..会工作的。

【讨论】:

  • 这正是我所需要的!有用!!谢谢你:)
【解决方案5】:

我最近遇到了这个问题。正如其他 cmets 所建议的,MacOS 附带的make 版本存在一些问题。构建(正如上面@MadScientist 所建议的)或install GNU make from Homebrew。我的系统上安装的make 版本是3.81,并且出现了同样的问题。 Homebrew 提供的版本(4.3 版)按预期工作。

【讨论】:

    【解决方案6】:

    我认为您使用的是 OSX。找出一个优雅的解决方案可能需要几次迭代。

    同时试试这个组合,告诉我们结果:

    CC=`avr-gcc`
    

    【讨论】:

      【解决方案7】:

      如果您想要更新 PATH 变量,请执行以下操作:

      export PATH=$(shell echo $${PATH}):<paths to add>
      

      我做的例子:

      文件:./c/luckme.sh

      echo "Hello Lucky Me ! "
      

      生成文件:

      export PATH=$(shell echo $${PATH}):c:.
      all:
          @luckyme.sh
      

      make 的输出:

      ~$ make
      Hello Lucky Me ! 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-16
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多