0

TLDR;

How is this question a duplicate of a python related question?

My question is: How do I create and then build to specific folders using Bash Script on Mac OS?

Detailed question with examples...

I am learning Bash and can't get my compiles/builds to write to specific directories on Mac OS.

I don't want to use Homebrew or MacPorts or anything like that. I want to compile/build from source and into very specific directories as to not mess up local box, as in I can delete whatever I install (build) without effecting the OS on the host box.

Here is my bash script:

#! /bin/bash

# Error checking
set -Eeuo pipefail

#define variables
PREFIX=$HOME/Desktop/OpenTimeLineIO 
PKG_CONFIG_PATH="${PREFIX}"/share/pkgconfig:"${PREFIX}"/lib/pkgconfig:"${PREFIX}"/lib64/pkgconfig
LD_LIBRARY_PATH="${PREFIX}"/lib:"${PREFIX}"/lib64
CFLAGS="${PREFIX}"/include
download="${PREFIX}"/download

mkdir -pv "${download}"

#Dependencies needed for OpenTimeline IO
#Cmake https://gitlab.kitware.com/cmake/cmake
cd "${download}"
curl -LO https://gitlab.kitware.com/cmake/cmake/-/archive/master/cmake-master.tar.gz
tar -xvzf cmake-master.tar.gz
cd "${download}"/cmake-master
./bootstrap --prefix="${PREFIX}" \
            --bindir="${PREFIX}"/bin \
            --datadir="${PREFIX}"/share/cmake \
            --docdir="${PREFIX}"/doc \
            --mandir="${PREFIX}"/man \
            --xdgdatadir="${PREFIX}"/share \
            --no-qt-gui
make
make install


#Python 3.x https://www.python.org/downloads/release/python-31011/
cd "${download}"
curl -LO https://www.python.org/ftp/python/3.10.11/Python-3.10.11.tar.xz
tar -xvzf Python-3.10.11.tar.xz
cd "${download}"/Python-3.10.11
./configure --exec-prefix="${PREFIX}" \
            --bindir="${PREFIX}"/bin \
            --includedir="${PREFIX}"/include \
            --libdir="${PREFIX}"/lib
make        
make install

I read the compile files (bootstrap and configure) for both and I thought I got it write (hahah see what I did there!) but nope!

Since I am explicitly setting the "mkdir" for downloads, that writes and since I am curl'ing there and extracting there, all good so far.

Compiles fine, but on build, it creates the CMAKE bin file in the extracted TAR directory and NOT where I want it: $HOME/Desktop/OpenTimeLineIO/bin

Python is worse!

Here is a picture of what I am getting: What I DON'T WANT

I get this:

Creating directory /usr/local/lib/python3.10
install: mkdir /usr/local/lib/python3.10: Permission denied

The above error I am NOT worried about since I DON'T want to write anything to /usr/local/*

Don't want that and I thought with the below I remedied that(this specific example):

./configure --exec-prefix="${PREFIX}" \
            --bindir="${PREFIX}"bin \
            --includedir="${PREFIX}"/include \
            --libdir="${PREFIX}"/lib

BUT, Python creates correctly: $HOME/Desktop/OpenTimeLineIO/bin /lib /

What I am trying to ultimately accomplish is...

Download tars into (after I create this myself): $HOME/Desktop/OpenTimeLineIO

Extract (which creates NEW directory) in: $HOME/Desktop/OpenTimeLineIO/downloadedfile.tar.gz

change directory into new directory from downloadedfile.tar.gz, compile while using my OS's /bin

Build binaries and any all other directories (share/libs/doc etc) in NEW directory (that I create) in: $HOME/Desktop/OpenTimeLineIO/bin /share /docs etc...

Here is an example:

mi-mac ~ % ls -al Desktop/OpenTimeLineIO/*
Desktop/OpenTimeLineIO/bin:
total 7536
xxxxxxxxxx  3 xxxxxxx  1815495230       96 May 10 15:33 .
xxxxxxxxxx  7 xxxxxxx  1815495230      224 May 10 15:33 ..
xxxxxxxxxx  1 xxxxxxx  1815495230  3856408 May 10 15:33 python3.10
xxxxxxxxxx  1 xxxxxxx  1815495230  3856408 May 10 15:33 cmake
xxxxxxxxxx  1 xxxxxxx  1815495230  3856408 May 10 15:33 whatever
xxxxxxxxxx  1 xxxxxxx  1815495230  3856408 May 10 15:33 whatever

Desktop/OpenTimeLineIO/download:
total 62656
xxx   7 xxxx  1815495230       224 May 10 15:29 .
xxx   7 xxxx  1815495230       224 May 10 15:33 ..
xxx  42 xxxx  1815495230      1344 May 10 15:33 Python-3.10.11
xxx   1 xxxx  1815495230  19640792 May 10 15:29 Python-3.10.11.tar.xz
xxx  48 xxxx  1815495230      1536 May 10 15:29 cmake-master
xxx   1 xxxx  1815495230  10815648 May 10 15:07 cmake-master.tar.gz

Desktop/OpenTimeLineIO/lib:
total 34056
xxxx  3 xxxx  1815495230        96 May 10 15:33 .
xxxx  7 xxxx  1815495230       224 May 10 15:33 ..
xxxx  1 xxxx  1815495230  17433192 May 10 15:33 libpython3.10.a

Desktop/OpenTimeLineIO/share:
total 34056
xxxx  3 xxxx  1815495230        96 May 10 15:33 .
xxxx  7 xxxx  1815495230       224 May 10 15:33 ..
xxxx  1 xxxx  1815495230  17433192 May 10 15:33 libpython3.10.a

Desktop/OpenTimeLineIO/include:
total 34056
xxxx  3 xxxx  1815495230        96 May 10 15:33 .
xxxx  7 xxxx  1815495230       224 May 10 15:33 ..
xxxx  1 xxxx  1815495230  17433192 May 10 15:33 libpython3.10.a
mi-mac ~ % 

Visually this is what I want: What I DO WANT!

Also, that any source that I want to compile AFTER I install the above uses only the directories I created.

Basically, I want to isolate the OS /bin from whatever I download.

Hope this makes sense!

Your time and help is appreciated.

Added part of my Makefile located in:

mi-mac ~ % ls -l Desktop/OpenTimeLineIO/download/cmake-master/MakeFile
# Generated by "Unix Makefiles" Generator, CMake Version 3.26

# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target

# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:

#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:

# Disable VCS-based implicit rules.
% : %,v

# Disable VCS-based implicit rules.
% : RCS/%

# Disable VCS-based implicit rules.
% : RCS/%,v

# Disable VCS-based implicit rules.
% : SCCS/s.%

# Disable VCS-based implicit rules.
% : s.%

.SUFFIXES: .hpux_make_needs_suffix_list

# Command-line flag to silence nested $(MAKE).
$(VERBOSE)MAKESILENT = -s

#Suppress display of executed commands.
$(VERBOSE).SILENT:

# A target that is always out of date.
cmake_force:
.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/Bootstrap.cmk/cmake

# The command to remove a file.
RM = /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/Bootstrap.cmk/cmake -E rm -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master

#=============================================================================
# Targets provided globally by CMake.

# Special rule for the target package
package: preinstall
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool..."
    /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/bin/cpack --config ./CPackConfig.cmake
.PHONY : package

# Special rule for the target package
package/fast: package
.PHONY : package/fast

# Special rule for the target package_source
package_source:
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Run CPack packaging tool for source..."
    /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/bin/cpack --config ./CPackSourceConfig.cmake /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/CPackSourceConfig.cmake
.PHONY : package_source

# Special rule for the target package_source
package_source/fast: package_source
.PHONY : package_source/fast

# Special rule for the target test
test:
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running tests..."
    bin/ctest --force-new-ctest-process $(ARGS)
.PHONY : test

# Special rule for the target test
test/fast: test
.PHONY : test/fast

# Special rule for the target edit_cache
edit_cache:
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
    Bootstrap.cmk/cmake -E echo No\ interactive\ CMake\ dialog\ available.
.PHONY : edit_cache

# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast

# Special rule for the target rebuild_cache
rebuild_cache:
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
    Bootstrap.cmk/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache

# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast

# Special rule for the target list_install_components
list_install_components:
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Available install components are: \"Unspecified\""
.PHONY : list_install_components

# Special rule for the target list_install_components
list_install_components/fast: list_install_components
.PHONY : list_install_components/fast

# Special rule for the target install
install: preinstall
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
    bin/cmake -P cmake_install.cmake
.PHONY : install

# Special rule for the target install
install/fast: preinstall/fast
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Install the project..."
    bin/cmake -P cmake_install.cmake
.PHONY : install/fast

# Special rule for the target install/local
install/local: preinstall
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
    bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
.PHONY : install/local

# Special rule for the target install/local
install/local/fast: preinstall/fast
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing only the local directory..."
    bin/cmake -DCMAKE_INSTALL_LOCAL_ONLY=1 -P cmake_install.cmake
.PHONY : install/local/fast

# Special rule for the target install/strip
install/strip: preinstall
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
    bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
.PHONY : install/strip

# Special rule for the target install/strip
install/strip/fast: preinstall/fast
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Installing the project stripped..."
    bin/cmake -DCMAKE_INSTALL_DO_STRIP=1 -P cmake_install.cmake
.PHONY : install/strip/fast

# The main all target
all: cmake_check_build_system
    $(CMAKE_COMMAND) -E cmake_progress_start /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/CMakeFiles /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master//CMakeFiles/progress.marks
    $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
    $(CMAKE_COMMAND) -E cmake_progress_start /Users/$HOME/Desktop/OpenTimeLineIO/download/cmake-master/CMakeFiles 0
.PHONY : all

# The main clean target
clean:
    $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
.PHONY : clean

====UPDATE!======

I THINK I got it. Seems to be doing what I want now but it ain't pretty!

Maybe someone can chime in to make it right?

#! /bin/bash

# Error checking
set -Eeuo pipefail

#define variables
PREFIX=$HOME/Desktop/OpenTimeLineIO
download=$HOME/Desktop/OpenTimeLineIO/download

echo "Creating download directory on your desktop first."
echo
mkdir -pv "$download"
echo
echo "Completed!"
echo
echo
echo "Next, downloading all dependencies for OpenTimeLineIO..."
echo
echo
echo "Cmake standalone download and install..."
echo
#Dependencies needed for OpenTimeline IO
#Cmake https://gitlab.kitware.com/cmake/cmake
cd "$download"
curl -LO https://gitlab.kitware.com/cmake/cmake/-/archive/master/cmake-master.tar.gz
tar -xvzf cmake-master.tar.gz
cd "$download/cmake-master"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" ./bootstrap --prefix="$PREFIX" \
                                                    --no-qt-gui
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make install
echo
echo "Completed!"
echo
echo "PERL5x standalone download and install..."
echo
#PERL 5.3.X https://github.com/Perl/perl5/tags
cd "$download"
curl -LO https://github.com/Perl/perl5/archive/refs/tags/v5.36.1.tar.gz
tar -xvzf v5.36.1.tar.gz
cd "$download/perl5-5.36.1"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" ./Configure -de -Dprefix="$PREFIX"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make      
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make install
echo
echo "Completed!"
echo
echo "OpenSSL standalone download and install..."
echo
#OpenSSL https://github.com/openssl/openssl/tags
cd "$download"
curl -LO https://github.com/openssl/openssl/archive/refs/tags/openssl-3.1.0.tar.gz
tar -xvzf openssl-3.1.0.tar.gz
cd "$download/openssl-openssl-3.1.0"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" ./Configure --prefix="$PREFIX" \
                                                    --openssldir="$PREFIX/ssl"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make      
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make install
echo
echo "Completed!"
echo
echo "Python 3.x standalone download and install..."
echo
#Python 3.x https://www.python.org/downloads/release/python-31011/
cd "$download"
curl -LO https://www.python.org/ftp/python/3.10.11/Python-3.10.11.tar.xz
tar -xvzf Python-3.10.11.tar.xz
cd "$download/Python-3.10.11"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" ./configure --prefix="$PREFIX" \
                                                    --disable-test-modules \
                                                    --enable-optimizations \
                                                    --enable-shared \
                                                    --with-openssl="$HOME/Desktop/OpenTimeLineIO/bin" 
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make      
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make install
echo
echo "Completed!"
echo
echo "Pyside 6 standalone download and install..."
echo
#Pyside6 via pip3 (Already installed with Python 3.x)
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" "$HOME/Desktop/OpenTimeLineIO/bin/pip3" -vvv install pyside6
echo
echo "Completed!"
echo
echo "Finally installing OpenTimelineIO!"
echo
echo "OpenTimelineIO standalone download and install..."
echo
#OpenTimelineIO https://github.com/AcademySoftwareFoundation/OpenTimelineIO
cd "$download"
curl -LO https://github.com/AcademySoftwareFoundation/OpenTimelineIO/archive/refs/tags/v0.15.tar.gz
tar -xvzf v0.15.tar.gzz
cd "$download/OpenTimelineIO-0.15"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" ./configure --prefix="$PREFIX"
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make      
PATH="$HOME/Desktop/OpenTimeLineIO:$PATH" make install
echo
echo "Completed!"

I took another look at Make as suggested by shellter (thanks a lot!) and thought to explicitly set make and make install.

Also a big help was Nic3500 that verified that what I wanted to do, could be done!

I would say that the question is SOLVED since the folders are now being created where I want!

fifer55
  • 9
  • 2
  • 1
    To get some useful hints paste your script at http://www.shellcheck.net/. – Cyrus May 10 '23 at 21:31
  • Thanks! I had some syntax errors and now I have NO errors but my issues persists! Thanks for the link though! – fifer55 May 10 '23 at 22:06
  • This seems to be a problem with the `cmake` build's`Makefile`. It's not really a `bash` problem/error based on the evidence you have provided. How big is that `Makefile` created, I think the problem is in there, but if it is a gigantic file, it will probably just confuse things. But statements like *"Python is worse! Creates the following ... $HOME/Desktop/OpenTimeLineIO/$HOME/Desktop/OpenTimeLineIO/bin /doc /share"* are very hard to understand. Please use correct formatting and better still show exact output of `/bin/ls -l $HOME/Desktop/OpenTimeLineIO/*`. Good luck! – shellter May 10 '23 at 22:24
  • 1
    Added some clarity and pictures! Thanks! – fifer55 May 10 '23 at 22:49
  • 1
    Can you clarify your concerns regarding "...as to not mess up local box."? – j_b May 10 '23 at 23:32
  • 1
    I want to be able to delete any file or directory in this folder without any impact on OS of my host box. Example: I compile/build cmake independent of where it would install if I download a prebuilt install (/usr/local/bin/). cannot use Homebrew because host will NOT have internet access. I want to make sure I can download, compile and build on my laptop, then would remove or omit CURL and TAR as I would have those already. – fifer55 May 10 '23 at 23:36
  • I"ve added a `cmake` tag to your Q as I think that is the base of your problem. (I'm only familiar with (old) `make`). Does your `Makefile` have a "rule" labeled `build:` ? If so, copy/paste just that section into your question. Other readers may ask for more details. Good luck. – shellter May 10 '23 at 23:50
  • Done I have added it at the end of the original post. Thanks again! – fifer55 May 11 '23 at 00:45
  • hum you have to be very careful with your PATH variable. In your makefile, it calls "bin/cmake", which will it use? The OS? Or the one located under "CURRENT DIRECTORY"/bin ? I do not know for these specific packages, but I compile Apache, OpenSSL and PHP like this all the time, so the idea is not completely crazy. – Nic3500 May 11 '23 at 01:26
  • I think what I need here is: use the "/usr/bin" OR "/usr/local/bin" to compile anything I need. Then to build where I want it to. Since I am installing dependencies that read from the "/usr/bin" or "/usr/local/bin" and build to "$HOME/Desktop/MyDirectory". – fifer55 May 11 '23 at 01:53
  • also, I am currently building OpenSSL since Python3 needs it. One of the dependencies I have is pyside6, which needs pip3 (pip3 install pyside6) – fifer55 May 11 '23 at 01:56
  • pluse-uno for updating your question with relevant details. Sorry, but as I feared, the build process that `cmake` supporst seems to be a different beast than what (old, unixy) `make` was used for, I don't have a clue )-;. .... Good comment from Nic3500 and hopefully that helps you. That was my one thought that some envVar isn't set roght, but which one, and at what layer? .... Following your Q to see if you get a good solution. Good luck – shellter May 11 '23 at 02:52
  • thanks for hanging in there! Much appreciated – fifer55 May 11 '23 at 03:47
  • Incidentallly, I did a search here for `[cmake] build` and there are 24K Q/A. Finding the right one may be tricky. Hopefully someone will give you a clue. Good luck. – shellter May 11 '23 at 04:07
  • Did you read the duplicate? The _question_ is superficially about Python but the answers explain how this concept works. – tripleee May 11 '23 at 06:07
  • 1
    Instead of repeatedly adding the same directory to the front of the `PATH`, just add it once at the beginning of your script. `PATH` changes within a script only affect the script itself, so there is no reason to try to avoid making the change "globally". – tripleee May 11 '23 at 06:14
  • Agree with above. does `export PATH="$HOME/Desktop/OpenTimeLineIO:$PATH"` near the top of your script, before calling any of your scripts/makes/programs solve your problem? Good luck. – shellter May 12 '23 at 16:50

0 Answers0