OSX上的makefile路径问题

时间:2012-03-16 04:13:15

标签: makefile

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

此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的{​​{1}}输出

\

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

7 个答案:

答案 0 :(得分:2)

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

导出SHELL

不要在Makefile中设置PATH,而是覆盖SHELL,如下所示:

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

以下是该包装器的可能版本:

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

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

<强>外

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

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

我知道你要求Makefile解决方案,但我想我还是会提到这个选项。这只是我的意见,但像PATH这样的东西往往是机器特定的(而不是特定于项目的),我更喜欢将它们与源代码分开。

答案 1 :(得分:1)

问题不在于make找不到avr-gcc。你的问题就在这一行:

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

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

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

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

答案 2 :(得分:1)

的问题是找不到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需要明确export,添加行

    导出CPATH

Makefile

(你有时需要反斜杠的原因,但有时候不需要反斜杠的原因,与字符串传递给shell的次数有多少关系:一次是在$(CC)时,但是当它是一个环境时为零次变量或部分$(PATH)。)

答案 3 :(得分:1)

我最近遇到了这个问题。正如其他评论所暗示的那样,MacOS附带的make版本存在一些问题。从Homebrew构建(如@MadScientist所建议)或install GNU make。我的系统上make的安装版本为3.81,并且出现相同的问题。 Homebrew提供的版本(版本4.3)可以正常工作。

答案 4 :(得分:0)

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

在此期间尝试这个kludge,告诉我们结果:

CC=`avr-gcc`

答案 5 :(得分:0)

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

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

示例我做了:

档案:./ c / luckme.sh

echo "Hello Lucky Me ! "

Makefile:

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

make的输出:

~$ make
Hello Lucky Me ! 

答案 6 :(得分:0)

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

How I could add dir to $PATH in Makefile?

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

所以:

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

..会起作用。