views:

331

answers:

2

Hi all- I've got a makefile (developed for gmake on Linux) that I'm attempting to port to OSX, but it seems like sed doesn't want to cooperate. What I do is use GCC to autogenerate dependency files, and then tweak them a bit using sed. The relevant portion of the makefile:

$(OBJ_DIR)/%.d: $(SRC_DIR)/%.cpp
  $(CPPC) -MM -MD $< -o $@
  sed -i 's|\(.*\)\.o:|$(OBJ_DIR)/\1.o $(OBJ_DIR)/\1.d $(TEST_OBJ_DIR)/\1_utest.o:|' $@

While this runs with no trouble under GNU/Linux, I get errors like the following when attempting to build on OSX:

sed: 1: "test/obj/equipmentConta ...": undefined label 'est/obj/equipmentContainer_utest.d'
sed: 1: "test/obj/dice_utest.d": undefined label 'est/obj/dice_utest.d'
sed: 1: "test/obj/color-string_u ...": undefined label 'est/obj/color-string_utest.d'

It would seem like sed is chopping off a character, but I can't see the solution.

Thanks in advance,
Cheers!

+6  A: 

OS X sed handles the -i argument differently to the Linux version.

You can probably generate a command that will work for both by adding -e:

#      vv
sed -i -e 's|\(.*\)\.o:|$(OBJ_DIR)/\1.o $(OBJ_DIR)/\1.d $(TEST_OBJ_DIR)/\1_utest.o:|' $@

It's because OS X sed -i interprets the next thing after the -i as a file extension for a backup copy of the in-place edit. (Probably the Linux version only does this if there is no space between the -i and the extension.)

The upshot of this is that sed consumes the s||| as the extension (!) then interprets the next argument as a command - in this case it begins with t, which sed recognises as a branch-to-label command expecting the target label as an argument - hence the error you see.

If you create a file testyou can reproduce the error on OS X:

$ sed -i 's|x|y|' test
sed: 1: "test": undefined label 'est'
martin clayton
Brilliant - thanks so much!
Chris
I think if POSIXLY_CORRECT or (older) POSIX_ME_HARDER is defined in the environment, the same behavior can be expected.
Tim Post
+1  A: 

Actally.. doing

sed -i -e "s/blah/blah/" files

doesn't do what you expect in OS X either.. instead it creates backup files with "-e" extension.

The proper for OS is

sed -i "" -e "s/blah/blah/" files
Urkle