What's The Best Way to Move a Directory into Place in a Makefile Install

What's the best way to move a directory into place in a Makefile install?

Yeah, it's hard to think of a more unix-ish way that cp -r, although the -r is a relatively late addition to cp. I can tell you the way we used to do it, and that works neatly across filesystems and such:

Let src be the source directory you want to move, and /path/to/target be an absolute path to the target. Then you can use:

$ tar cf - src | (cd /path/to/target; tar xf -)

Directory for files generated by Make during installation from configure, make and make install

  1. You are absolutely right: make just creates files in current directory and make install copies it to the destination directories, based on $prefix and other variables maintained by configure script.

  2. You can wipe out the whole directory you've ran the build at. It will not be used, because, well, that's what "install" means: you build in one directory and the the files are placed in the proper places of your system.

  3. Usually install destination and the directory you build in differ. The hierarchy of the files being installed usually do not relate to directory hierarchy of the build system. Just install to the other dir: it's cheap to create just yet another directory.

Makefile to move programs to specific directory

A makefile rule consists of two parts, a declaration of the rule's dependencies and the commands to invoke.

The dependencies are listed on the first line of the rule after the colon and the commands to execute are listed on subsequent lines, all indented with tabs.

Your install rule needs to depend on the programs which you are moving and possibly the destination directory (you may want a rule that creates the destination), but not the mv utility itself as you don't need to build that.

install: $(PROGS)
mv $(PROGS) $(PROG_PATH)

Note that although I've used four spaces, the indentation needs to be a tab. As you don't (yet?) have a rule to make PROG_PATH, I've left it out of the dependency list.

Also note that with this rule, make will have to rebuild your programs if you invoke make twice as they will have moved. You way want to consider using cp or install instead of mv.

Make install, but not to default directories?

It depends on the package. If the Makefile is generated by GNU autotools (./configure) you can usually set the target location like so:

./configure --prefix=/somewhere/else/than/usr/local

If the Makefile is not generated by autotools, but distributed along with the software, simply open it up in an editor and change it. The install target directory is probably defined in a variable somewhere.

How to copy directories into a directory using install in bash?

You want to use cp -r instead:

cp -r foo dest

How do I change directory in macports Portfile and run a Makefile

Ok I had a lot of help with this in the PR.

The answers boil down to this:

How to change directory:

build.dir           ${worksrcpath}/rust

How to run a Makefile (within a sub-folder):

pre-build {
system -W ${worksrcpath}/rust "make"
}

How to link it all in the end:

destroot {
xinstall -m 0755 ${worksrcpath}/rust/target/[cargo.rust_platform]/release/${name} \
${destroot}${prefix}/bin/
}

And how to create the dependencies and their hashes: There is a port called cargo2port that uses the Cargo.lock file and generates the output for you.

So with all that the final Portfile is:

# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem 1.0
PortGroup github 1.0
PortGroup cargo 1.0

github.setup DominikWilkowski cfonts 1.0.2 v rust
revision 0

categories textproc
license GPL-3+
maintainers {DominikWilkowski @DominikWilkowski} \
openmaintainer

description Sexy ANSI fonts for the console
long_description This is a silly little command line tool for sexy fonts in the console. \
Give your cli some love.

checksums ${distfiles} \
rmd160 6f5bedcb0e1cb54faf9efb2b4e34dbe6105152ea \
sha256 33c14dda907c4f3c046a40644c8856f6debb87b58ee6fbaab2b8d7af14ce8b6e \
size 3312272

build.dir ${worksrcpath}/rust

pre-build {
system -W ${worksrcpath}/rust "make"
}

destroot {
xinstall -m 0755 ${worksrcpath}/rust/target/[cargo.rust_platform]/release/${name} \
${destroot}${prefix}/bin/
}

cargo.crates \
atty 0.2.14 d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8 \
cfg-if 1.0.0 baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd \
enable-ansi-support 0.1.2 28d29d3ca9ba14c336417f8d7bc7f373e8c16d10c30cc0794b09d3cecab631ab \
exitcode 1.1.2 de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193 \
getrandom 0.2.6 9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad \
heck 0.4.0 2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9 \
hermit-abi 0.1.19 62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33 \
is_ci 1.1.1 616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb \
itoa 1.0.1 1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35 \
libc 0.2.125 5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b \
once_cell 1.10.0 87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9 \
ppv-lite86 0.2.16 eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872 \
proc-macro2 1.0.37 ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1 \
quote 1.0.18 a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1 \
rand 0.8.5 34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404 \
rand_chacha 0.3.1 e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88 \
rand_core 0.6.3 d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7 \
rustversion 1.0.6 f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f \
ryu 1.0.9 73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f \
serde 1.0.136 ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789 \
serde_derive 1.0.136 08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9 \
serde_json 1.0.79 8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95 \
strum 0.24.0 e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8 \
strum_macros 0.24.0 6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef \
supports-color 1.3.0 4872ced36b91d47bae8a214a683fe54e7078875b399dfa251df346c9b547d1f9 \
syn 1.0.91 b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d \
temp-env 0.2.0 45107136c2ddf8c4b87453c02294fd0adf41751796e81e8ba3f7fd951977ab57 \
terminal_size 0.1.17 633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df \
unicode-xid 0.2.2 8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3 \
wasi 0.10.2+wasi-snapshot-preview1 fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6 \
winapi 0.3.9 5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419 \
winapi-i686-pc-windows-gnu 0.4.0 ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6 \
winapi-x86_64-pc-windows-gnu 0.4.0 712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f

I hope it helps someone else later

How can Makefile use separate directories for source code and binaries?

You were almost there ...

#Current make system
BIN=./bin/
SOURCE=./source/

LIST=$(BIN)/program1 $(BIN)/program2...

all: $(LIST)

$(BIN)/%: $(SOURCE)%.cpp
$(CC) $(INC) $< $(CFLAGS) -o $@ $(LIBS)

You can also make the LIST easier by using the following

PROG=program1 program2
LIST=$(addprefix $(BIN)/, $(PROG))

How does install in the Makefile keep the directory structure unchanged?

This doesn't have anything to do with C or with Makefiles. You are using the install utility to copy the files, and that's how the install utility works: it takes the files on the command line and copies them to the directory you specified. It doesn't recreate the directory structure.

If you want to preserve the directory structure then your install_header recipe will need to be modified to do that, perhaps by writing multiple install commands with different directories or by invoking cp directly.

Create directories using make file

This would do it - assuming a Unix-like environment.

MKDIR_P = mkdir -p

.PHONY: directories

all: directories program

directories: ${OUT_DIR}

${OUT_DIR}:
${MKDIR_P} ${OUT_DIR}

This would have to be run in the top-level directory - or the definition of ${OUT_DIR} would have to be correct relative to where it is run. Of course, if you follow the edicts of Peter Miller's "Recursive Make Considered Harmful" paper, then you'll be running make in the top-level directory anyway.

I'm playing with this (RMCH) at the moment. It needed a bit of adaptation to the suite of software that I am using as a test ground. The suite has a dozen separate programs built with source spread across 15 directories, some of it shared. But with a bit of care, it can be done. OTOH, it might not be appropriate for a newbie.


As noted in the comments, listing the 'mkdir' command as the action for 'directories' is wrong. As also noted in the comments, there are other ways to fix the 'do not know how to make output/debug' error that results. One is to remove the dependency on the the 'directories' line. This works because 'mkdir -p' does not generate errors if all the directories it is asked to create already exist. The other is the mechanism shown, which will only attempt to create the directory if it does not exist. The 'as amended' version is what I had in mind last night - but both techniques work (and both have problems if output/debug exists but is a file rather than a directory).



Related Topics



Leave a reply



Submit