Portable makefile creation of directories

前端 未结 3 1173
予麋鹿
予麋鹿 2021-01-06 04:17

I\'m looking to save myself some effort further down the line by making a fairly generic makefile that will put together relatively simple C++ projects for me with minimal m

3条回答
  •  孤城傲影
    2021-01-06 05:01

    I don't know autoconf. Every experience I've had with it has been tedious. The problem with zwol's solution is that on Windows mkdir returns an error, unlike mkdir -p on Linux. This could break your make rule. The workaround is to ignore the error with - flag before the command, like this:

    -mkdir dir
    

    The problem with this is that make still throws an ugly warning for the user. The workaround for this is to run an "always true" command after the mkdir fails as described here, like this:

    mkdir dir || true
    

    The problem with this is that Windows and Linux have different syntax for true.

    Anyway, I spent too much time on this. I wanted a make file that worked in both POSIX-like and Windows environments. In the end I came up with the following:

    ifeq ($(shell echo "check_quotes"),"check_quotes")
       WINDOWS := yes
    else
       WINDOWS := no
    endif
    
    ifeq ($(WINDOWS),yes)
       mkdir = mkdir $(subst /,\,$(1)) > nul 2>&1 || (exit 0)
       rm = $(wordlist 2,65535,$(foreach FILE,$(subst /,\,$(1)),& del $(FILE) > nul 2>&1)) || (exit 0)
       rmdir = rmdir $(subst /,\,$(1)) > nul 2>&1 || (exit 0)
       echo = echo $(1)
    else
       mkdir = mkdir -p $(1)
       rm = rm $(1) > /dev/null 2>&1 || true
       rmdir = rmdir $(1) > /dev/null 2>&1 || true
       echo = echo "$(1)"
    endif
    

    The functions/variables are used like so:

    rule:
        $(call mkdir,dir)
        $(call echo,  CC      $@)
        $(call rm,file1 file2)
        $(call rmdir,dir1 dir2)
    

    Rationale for the definitions:

    • mkdir: Fix up the path and ignore any errors.
    • del: In Windows del doesn't delete any files if one of the files is specified to be in a directory that doesn't exist. For example, if you try to delete a set of files and dir/file.c is in the list, but dir doesn't exist, no files will be deleted. This implementation works around that issue by invoking del once for each file.
    • rmdir: Fix up the path and ignore any errors.
    • echo: The output's appearance is preserved and doesn't show the extraneous "" in Windows.

    I spent a lot of time on this. Perhaps I would have been better off spending my time learning autoconf.

    See also:

    1. OS detecting makefile

提交回复
热议问题