If you really want to “write exactly bash scripts into Makefiles” then you'll need to do it a bit indirectly. If you just paste the script after the target line, then you'll run into two problems that just cannot be bypassed: the command lines need to be indented with a tab, and dollar signs need to be escaped.
If you use GNU make (as opposed to BSD make, Solaris make, etc.), then you can define your script as a variable using the multi-line definition syntax, and then use the value
function to use the raw value of the variable, bypassing expansion.
In addition, as explained by skwllsp, you need to tell make to execute the command list for each target as a single shell script rather than line by line, which you can do in GNU make by defining a .ONESHELL
target.
define my_important_task =
# script goes here
endef
my-important-task: ; $(value my_important_task)
.ONESHELL:
On a 64-bit Centos7 virt with no particularly special modifications (lib
versus lib64
directories have been problematical when building on Linux in the past, hence my mentioning the arch):
# yum -y install git make cmake '@Development Tools' boost-devel
# git clone --branch=stable https://github.com/bigartm/bigartm.git
# cd bigartm
# mkdir build && cd build
# cmake ..
# make
... jeopardy music ...
Okay, it takes until 99% through the build to fail. With a verbose build we can discover the precise command (with some linefeeds manually added to avoid horizontal scrolling insanity):
# make VERBOSE=1
...
/usr/bin/c++ -Wall -pthread -fPIC -std=c++11 -O3 -DNDEBUG
-static CMakeFiles/bigartm.dir/srcmain.cc.o
CMakeFiles/bigartm.dir/__/artm/cpp_interface.cc.o -o ../../bin/bigartm
-rdynamic ../../lib/libmessages_proto.a ../../lib/libartm-static.a
../../lib/libprotobuf.a ../../lib/libgoogle-glog.a -lboost_thread-mt
-lboost_program_options-mt -lboost_date_time-mt -lboost_filesystem-mt
-lboost_iostreams-mt -lboost_system-mt -lboost_chrono-mt -lboost_timer-mt
../../lib/libmessages_proto.a ../../lib/libinternals_proto.a ../../lib/libgflags.a
-lpthread
/usr/bin/ld: cannot find -lboost_thread-mt
/usr/bin/ld: cannot find -lboost_program_options-mt
/usr/bin/ld: cannot find -lboost_date_time-mt
/usr/bin/ld: cannot find -lboost_filesystem-mt
/usr/bin/ld: cannot find -lboost_iostreams-mt
/usr/bin/ld: cannot find -lboost_system-mt
/usr/bin/ld: cannot find -lboost_chrono-mt
/usr/bin/ld: cannot find -lboost_timer-mt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make[2]: *** [bin/bigartm] Error 1
Not finding the C library, well now that's problematical. A relevant next question is what precise files was ld
looking for that it could not find, easily solved with sysdig
:
# sysdig -p '%fd.name' proc.name contains ld
And elsewhere re-run make
and lo! static *.a
files are being looked for according to sysdig
(which, as ld
already told us, do not exist). So there are at least two possible solutions here, on the one hand to not compile static, or the other to get all those various static libraries installed. Let's go with the not-static option, given handy the BUILD_STATIC_LIBS
flag in the CMakeLists.txt
file.
# cd .. && rm -rf build
# mkdir build && cd build
# cmake -D BUILD_STATIC_LIBS=OFF ..
Well that didn't help. Okay, let's manually edit the CMakeLists.txt
file and turn off STATIC
builds...
# cd .. && rm -rf build
# vi CMakeLists.txt
...
... make stuff again ...
[ 91%] Built target artm-static
Linking CXX shared library ../../lib/libartm.so
/usr/bin/ld: cannot find -lgflags-static
collect2: error: ld returned 1 exit status
Whoops, looks like this project really really really wants its static libraries. Some
yum whatprovides '*libboost_thread-mt.a'
yum whatprovides '*libc.a'
...
yum -y install glibc-static boost-static
churn later and then
cd ..
git checkout CMakeLists.txt
... build again ...
...
SystemError: Cannot compile 'Python.h'. Perhaps you need to install python-dev|python-devel.
Good to know, after all that other work...
# yum -y install git make cmake '@Development Tools' boost-devel glibc-static \
boost-static python-devel
# git clone --branch=stable https://github.com/bigartm/bigartm.git
# cd bigartm
# mkdir build && cd build
# cmake ..
# make
This sort of stuff should be moved into an RPM file, so those dependencies can all be listed instead of requiring folks to flail around with git clones and so-so docs...
Best Answer
Only the last command should be necessary.
install -d
will create the missing intermediate directories:From the GNU
install
manual:For what it's worth, BSD
install
also works like this: