'Makefile: sources inside path with spaces

I am writing a Makefile for a project where all the cpp files are in subdirectories and some of them contains spaces:

 └──     L0/ 
 │  └────     Commodities API/ 
 │  │  └────     commodities_api.h  
 │  └────     Communication API/ 
 │  │  └────     communication_api.h  
 │  └────     L0 Base/ 
 │  │  ├────     L0_base.cpp  
 │  │  └────     L0_base.h  
 │  └────     Provision API/ 
 │  │  └────     provision_api.h  
 │  ├────     L0_commodities.cpp  
 │  ├────     L0_communication.cpp  
 │  ├────     L0.cpp  
 │  ├────     L0_enumerations.h  
 │  ├────     L0_error_manager.h  
 │  ├────     L0.h  
 │  ├────     L0_provision.cpp  

This is my Makefile 'til now:

CPP = g++
LFLAGS += 
CFLAGS += -g -MMD
INCLUDES += 

CPP_SRCS := $(shell find sources -name '*.cpp' | sort | uniq | sed 's/ /\\\\ /g')
CPP_DIRS := $(shell find sources -name '*.cpp' -printf '%h\n' | sort | uniq | sed 's/ /\\\\ /g')
OBJS := $(CPP_SRCS:.cpp=.o)

OUT_DIR := out

all:
    @echo $(CPP_SRCS)
    @echo
    @echo $(OBJS)
    @echo
    @echo $(CPP_DIRS)

lib.so: $(OBJS)

%.o: %.cpp Makefile
    @echo "[C] $<"
    $(CPP) -c $(CFLAGS) $(INCLUDES) "$<"

This is the output from the "all" target, used to print the three variables:

sources/L0/L0\ Base/L0_base.cpp sources/L0/L0_commodities.cpp sources/L0/L0_communication.cpp sources/L0/L0.cpp sources/L0/L0_provision.cpp sources/L1/Crypto\ Libraries/aes256.cpp sources/L1/L1\ Base/L1_base.cpp sources/L1/L1.cpp sources/L1/L1_login_logout.cpp sources/L1/L1_security.cpp sources/L1/L1_sekey.cpp

sources/L0/L0\ Base/L0_base.o sources/L0/L0_commodities.o sources/L0/L0_communication.o sources/L0/L0.o sources/L0/L0_provision.o sources/L1/Crypto\ Libraries/aes256.o sources/L1/L1\ Base/L1_base.o sources/L1/L1.o sources/L1/L1_login_logout.o sources/L1/L1_security.o sources/L1/L1_sekey.o

sources/L0 sources/L0/L0\ Base sources/L1 sources/L1/Crypto\ Libraries sources/L1/L1\ Base

But when I try to launch make lib.so

make: *** No rule to make target 'sources/L0/L0\', needed by 'lib.so'.  Stop.

What can I do to solve this problem? Thanks!



Solution 1:[1]

Make use spaces as list delimiter, and there is no good way to escape it (pun intended). Your options include:

  • Replace the spaces with something else, like dash or underscore
  • Migrate from Make to e.g. CMake or SCons

For Windows you can reference any file or directory by its short path which is guaranteed not having spaces, see https://superuser.com/questions/348079/how-can-i-find-the-short-path-of-a-windows-directory-file.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andreas