I'm trying to cross compile OpenSSL for PowerPC with the FIPS module. My build host's architecture is not PowerPC. I was able to cross compile the FIPS module just fine. However, when I run make on openssl, during the linking phase, it tries to execute certain binaries to run tests. The issue is that those binaries are produced for the target architecture and, as a result, I get the error "cannot execute binary file". Is there a way to produce executables of these tests on the host architecture rather than the target architecture? Should I be handling this process differently? Here are the following commands I used to build openssl. I replaced certain directories with DIR_HIDDEN.
export FIPS_DIRECTORY="$PWD/../../openssl-fips/tgt/linux-ppc603e/"
export cross="DIR_HIDDEN/powerpc-linux-gnu-"
make clean || exit 1
make dclean || exit 1
./Configure --prefix=$PWD/../tgt/linux-ppc603e linux-ppc fips --with-fipsdir=${FIPS_DIRECTORY}
make depend || exit 1
make CC="$FIPS_DIRECTORY/bin/fipsld" RANLIB="${cross}ranlib" AR="${cross}ar r" LD="$FIPS_DIRECTORY/bin/fipsld" FIPSLD_CC="${cross}gcc" HOSTCC="/usr/bin/gcc" || exit 1
make install || exit 1
I get the following error during the make command:
shlib_target=; if [ -n "" ]; then \
shlib_target="linux-shared"; \
elif [ -n "libcrypto" ]; then \
FIPSLD_CC="/DIR_HIDDEN/openssl/openssl-1.0.1i/../../openssl-fips/tgt/linux-ppc603e//bin/fipsld"; CC=/DIR_HIDDEN/openssl/openssl-1.0.1i/../../openssl-fips/tgt/linux-ppc603e//bin/fipsld; export CC FIPSLD_CC; \
fi; \
LIBRARIES="-L.. -lssl -L.. -lcrypto" ; \
make -f ../Makefile.shared -e \
APPNAME=openssl OBJECTS="openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o" \
LIBDEPS=" $LIBRARIES -ldl" \
link_app.${shlib_target}
make[2]: Entering directory `/DIR_HIDDEN/openssl/openssl-1.0.1i/apps'
( :; LIBDEPS="${LIBDEPS:--L.. -lssl -L.. -lcrypto -ldl}"; LDCMD="${LDCMD:-/DIR_HIDDEN/openssl/openssl-1.0.1i/../../openssl-fips/tgt/linux-ppc603e//bin/fipsld}"; LDFLAGS="${LDFLAGS:--DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DB_ENDIAN -DTERMIO -O3 -Wall -DOPENSSL_BN_ASM_MONT -I/DIR_HIDDEN/openssl/openssl-1.0.1i/../../openssl-fips/tgt/linux-ppc603e//include -DSHA1_ASM -DSHA256_ASM -DAES_ASM}"; LIBPATH=`for x in $LIBDEPS; do echo $x; done | sed -e 's/^ *-L//;t' -e d | uniq`; LIBPATH=`echo $LIBPATH | sed -e 's/ /:/g'`; LD_LIBRARY_PATH=$LIBPATH:$LD_LIBRARY_PATH ${LDCMD} ${LDFLAGS} -o ${APPNAME:=openssl} openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o ${LIBDEPS} )
/DIR_HIDDEN/openssl/openssl-1.0.1i/../../openssl-fips/tgt/linux-ppc603e//bin/fipsld: line 185: ./openssl: cannot execute binary file
make[2]: *** [link_app.] Error 126
When invoking the make command again and again, I get the same error but for all the applications located in the /test directory of the openssl tarball. Examples include bntest, ectest, and ecdhtest.
I received a similar error when I was cross compiling the FIPS module, but I was able to resolve that by including the host compiler in the HOSTCC variable. A similar trick did not work for the openssl compilation.
Any guidance would be appreciated. Thanks!
I was able to modify the make command to get the process to complete. I was missing the FIPS_SIG environment variable, which points to the incore script. The make command is now:
make FIPS_SIG=$PWD/`find ../../openssl-fips/ -iname incore` CC="$FIPS_DIRECTORY/bin/fipsld" RANLIB="${cross}ranlib" AR="${cross}ar r" LD="$FIPS_DIRECTORY/bin/fipsld" FIPSLD_CC="${cross}gcc"
I still see prints to console that indicate that openssl cannot be executed, but these are warnings and don't halt the makefile. Not really sure why or how this fixed the problem, but I'll take it.
Related
Basically, before linking is performed, I would like to convert a GCC linker script template file into a final linker script, as discussed in Can I use Preprocessor Directives in .ld file - and I'd like that step to be performed by Cmake.
I guess my problem is similar to the discussion in add_custom_command is not generating a target ; but I still cannot see how to solve it. Here is a minimal example, where I'm faking with an empty .ld linker script template file; first, let's create the files using bash:
mkdir /tmp/cmake_test && cd /tmp/cmake_test
touch my_linkerscript_template.ld
cat > main.c <<'EOF'
#include <stdio.h>
const char greeting[] = "hello world";
int main() {
printf("%s!\n", greeting);
return 0;
}
EOF
cat > CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.13)
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
project(foobar C)
message("PROJECT_NAME is '${PROJECT_NAME}'")
add_executable(${PROJECT_NAME}
main.c
)
add_compile_options(-Wall
)
target_link_options(${PROJECT_NAME} PRIVATE
"LINKER:--script=${CMAKE_SOURCE_DIR}/my_linkerscript.ld"
)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/my_linkerscript.ld
DEPENDS ${CMAKE_SOURCE_DIR}/my_linkerscript_template.ld
COMMAND bash ARGS -c "gcc -E -x c -CC -I/usr/include my_linkerscript_template.ld | grep -v '^#' > my_linkerscript.ld"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "build my_linkerscript_template.ld into my_linkerscript.ld (${CMAKE_CURRENT_SOURCE_DIR})"
VERBATIM
)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_DEPENDS "${CMAKE_SOURCE_DIR}/my_linkerscript.ld")
EOF
Note that my_linkerscript.ld is not created above; as I'd intend to put my_linkerscript_template.ld in git, and then have the final my_linkerscript.ld generated on demand.
If in this case, I do:
mkdir /tmp/cmake_test/build && cd /tmp/cmake_test/build
cmake ../ -DCMAKE_BUILD_TYPE=Debug
make
I get:
$ make
make[2]: *** No rule to make target 'D:/msys64/tmp/cmake_test/my_linkerscript.ld', needed by 'foobar.exe'. Stop.
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/foobar.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
$ grep -r linkerscript .
./CMakeFiles/foobar.dir/build.make:foobar.exe: D:/msys64/tmp/cmake_test/my_linkerscript.ld
./CMakeFiles/foobar.dir/build.make: /D/msys64/mingw64/bin/cc.exe -g -Wl,--script=D:/msys64/tmp/cmake_test/my_linkerscript.ld -Wl,--whole-archive CMakeFiles/foobar.dir/objects.a -Wl,--no-whole-archive -o foobar.exe -Wl,--out-implib,libfoobar.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
So, I did get a dependency on my_linkerscript.ld; and it did get added to linker options - but there is no build step generated by the add_custom_command.
How can I have generate the proper dependencies, so that when my_linkerscript.ld is needed for linking but it does not exist, then commands (that are given in add_custom_command above) are run, to generate this file from the template?
Output of add_custom_command needs to be "consumed" by some target, otherwise the custom command has no effect.
The property LINK_DEPENDS does NOT provide a consumer, so you need to create consumer target by yourself:
# ... in addition to your code
# Create a consumer target for the linker script.
# So previous `add_custom_command` will have an effect.
add_custom_target(my_linkerscript
DEPENDS ${CMAKE_SOURCE_DIR}/my_linkerscript.ld)
# Make executable to depend on that target.
# So, the check whether to relink the executable will be performed
# after possible rebuilding the linker script.
add_dependencies(${PROJECT_NAME} my_linkerscript)
We are trying to compile this by following instructions in the readme. I must say that we are not specialists with C at all, we are students of a web development bootcamp and trying to do our last project.
It's a command line tool to calculate ephemerides of multiple celestial bodies, and as you can read in the setup in the readme file, it need to download certain data from the internet, and then compile.
All is done through the setup.sh script.
So, we have tried:
In Windows 10 ubuntu WSL terminal
If we type $./setup or $./prettymake, after download the data, gives the error:
$mkfifo: cannot create fifo 'stderr': Operation not supported
$mkdir -p obj obj/argparse obj/coreUtils obj/ephemCalc obj/listTools obj/mathsTools obj/settings
cc -Wall -Wno-format-truncation -Wno-unknown-pragmas -g -c -I /mnt/d/reboot/ephemeris-compute-de430/src -O3 -D DEBUG=0 -D MEMDEBUG1=0 -D MEMDEBUG2=0 -fopenmp -D DCFVERSION=\"2.0\" -D DATE=\"09/06/2019\" -D PATHLINK=\"/\" -D SRCDIR=\"/mnt/d/reboot/ephemeris-compute-de430/src/\" src/ephemCalc/constellations.c -o obj/ephemCalc/constellations.o
If we do it with $sudo ./setup, the error printed is:
$mkfifo: cannot create fifo 'stderr': Operation not supported
$cat: stderr: No such file or directory
$mkdir -p obj obj/argparse obj/coreUtils obj/ephemCalc obj/listTools obj/mathsTools obj/settings
cc -Wall -Wno-format-truncation -Wno-unknown-pragmas -g -c -I /mnt/d/reboot/ephemeris-compute-de430/src -O3 -D DEBUG=0 -D MEMDEBUG1=0 -D MEMDEBUG2=0 -fopenmp -D DCFVERSION=\"2.0\" -D DATE=\"09/06/2019\" -D PATHLINK=\"/\" -D SRCDIR=\"/mnt/d/reboot/ephemeris-compute-de430/src/\" src/ephemCalc/constellations.c -o obj/ephemCalc/constellations.o
In macOS terminal
If we type $./prettymake, gives the error:
$mkdir -p obj obj/argparse obj/coreUtils obj/ephemCalc obj/listTools obj/mathsTools obj/settings
cc -Wall -Wno-format-truncation -Wno-unknown-pragmas -g -c -I /Users/rominaelorrietalopez/Documents/Descargas2/ephemeris-compute-de430-master/src -O3 -D DEBUG=0 -D MEMDEBUG1=0 -D MEMDEBUG2=0 -fopenmp -D DCFVERSION=\"2.0\" -D DATE=\"09/06/2019\" -D PATHLINK=\"/\" -D SRCDIR=\"/Users/rominaelorrietalopez/Documents/Descargas2/ephemeris-compute-de430-master/src/\" src/argparse/argparse.c -o obj/argparse/argparse.o
$clang: error: unsupported option '-fopenmp'
$make: *** [obj/argparse/argparse.o] Error 1
We have tried certain things to no avail, like granting permissions and what not, but have no idea what to do next.
It seems that it have something to do with the prettymake file:
mkfifo stderr
cat stderr | sed 's/\(.*\)/\1/' &
make $# 2>stderr | sed 's/\(.*\)/\1/'
rm stderr
It's like its trying to create a pipe to save the errors of the compilation but somehow it fails.
Also possibly worth of mention, it have a Makefile associated.
Since the github project does not have Issues, we've contacted the creator via email, but well, we thought maybe someone could help us here too.
Any kind of help would be honestly appreciated, thanks.
A comment from the OP invites me to answer; here it is.
The prettymake script creates a named fifo in order to receive the messages produced by make on its standard error.
A background process (cat) consumes the data from this fifo and sends them to a sed command (see right after) in order to transform these data before writing to standard output.
(note that cat is useless here since sed could have directly read from the named fifo thanks to <)
However, the two sed commands as shown in the question don't do anything since they just capture each line of text (\(.*\)) and repeat them unchanged (\1), thus they could have been omitted.
In this case, the script could just contain make $# 2>&1, it would have produced the same effect.
On a system where creating the named fifo is problematic (old version of WSL apparently), this change in the script should produce the same effect as expected.
Looking at the link provided in the question, we can see that the original prettymake script actually contains transformations in the sed commands in order to display standard output and standard error of the make command with different colours.
I'm trying to cross compile busy box V 1.27.2 for my embedded Linux device. I set share library build and cross compiler prefix and Sysroot to my compiler destinations. Compiler after trying to compile most library files is unable to link them.I received this:
Trying libraries: crypt m
Failed: -Wl,--start-group -lcrypt -lm -Wl,--end-group
Output of:
/home/bluebird/brcm-armtools-64bit/tools/le_arm11_external_20090306/bin/arm-brcm-linux-gnueabi-gcc -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wno-format-security -Wdeclaration-after-statement -Wold-style-definition -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-builtin-printf -Os -fpic -fvisibility=hidden --sysroot=/home/bluebird/brcm-armtools-64bit/tools/le_arm11_external_20090306/sysroot -o busybox_unstripped -Wl,--sort-common -Wl,--sort-section,alignment -Wl,--gc-sections -Wl,--start-group applets/built-in.o archival/lib.a archival/libarchive/lib.a console-tools/lib.a coreutils/lib.a coreutils/libcoreutils/lib.a debianutils/lib.a e2fsprogs/lib.a editors/lib.a findutils/lib.a init/lib.a libbb/lib.a libpwdgrp/lib.a loginutils/lib.a mailutils/lib.a miscutils/lib.a modutils/lib.a networking/lib.a networking/libiproute/lib.a networking/udhcp/lib.a printutils/lib.a procps/lib.a runit/lib.a selinux/lib.a shell/lib.a sysklogd/lib.a util-linux/lib.a util-linux/volume_id/lib.a archival/built-in.o archival/libarchive/built-in.o console-tools/built-in.o coreutils/built-in.o coreutils/libcoreutils/built-in.o debianutils/built-in.o e2fsprogs/built-in.o editors/built-in.o findutils/built-in.o init/built-in.o libbb/built-in.o libpwdgrp/built-in.o loginutils/built-in.o mailutils/built-in.o miscutils/built-in.o modutils/built-in.o networking/built-in.o networking/libiproute/built-in.o networking/udhcp/built-in.o printutils/built-in.o procps/built-in.o runit/built-in.o selinux/built-in.o shell/built-in.o sysklogd/built-in.o util-linux/built-in.o util-linux/volume_id/built-in.o -Wl,--end-group -Wl,--start-group -lcrypt -lm -Wl,--end-group
==========
coreutils/lib.a(mktemp.o): In function `mktemp_main':
mktemp.c:(.text.mktemp_main+0xbc): warning: the use of `mktemp' is dangerous, better use `mkstemp'
coreutils/lib.a(touch.o): In function `touch_main':
touch.c:(.text.touch_main+0x1f4): warning: warning: lutimes is not implemented and will always fail
util-linux/lib.a(nsenter.o): In function `nsenter_main':
nsenter.c:(.text.nsenter_main+0x1b4): undefined reference to `setns'
coreutils/lib.a(sync.o): In function `sync_main':
sync.c:(.text.sync_main+0x9c): undefined reference to `syncfs'
collect2: ld returned 1 exit status
Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.
Example: CONFIG_EXTRA_LDLIBS="pthread dl tirpc audit pam"
make: *** [busybox_unstripped] Error 1
Also I have libm.so in my sysroot dir.
EDIT:
I also try buildroot,but it needs some information about processor(e.g. endian, detailed version,etc.) which I am not aware,this is a black box device and I only develope app on it, total information I have is it run on the BCM5892 ,an ARM11 secure processor from broadcom.it runs on kenel V 2.6 and arm-brcm-linux-gnueabi V4.4.2 compiler, I also correctly set sysroot and cross compiler prefix,but how could I know which version of libc I'm using ?
Open busybox menuconfig and disable "Enable -d and -f flags"
[*] sync (3.8 kb)
[ ] Enable -d and -f flags (requires syncfs(2) in libc)
Uning a more recent verisons of uclibc (> 0.9.33) can allow to enable the option.
You can detect your glibc Version by inspecting the names of this link targets:
root#debianxc:/usr/src/busybox# file /opt/STM/STLinux-2.4/devkit/sh4/target/lib/libc.so.6
/opt/STM/STLinux-2.4/devkit/sh4/target/lib/libc.so.6: symbolic link to libc-2.10.2.so
root#debianxc:/usr/src/busybox# file /opt/STM/STLinux-2.4/devkit/sh4/target/lib/ld-linux.so.2
/opt/STM/STLinux-2.4/devkit/sh4/target/lib/ld-linux.so.2: symbolic link to ld-2.10.2.so
This indicates a glibc Version of 2.10.2.
But to get sure you can also do:
root#debianxc:/usr/src/busybox# strings /opt/STM/STLinux-2.4/devkit/sh4/target/lib/libc.so.6 | grep '^GLIBC_' | sort | uniq
GLIBC_2.10
GLIBC_2.2
GLIBC_2.2.1
GLIBC_2.2.2
GLIBC_2.2.3
GLIBC_2.2.4
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_PRIVATE
root#debianxc:/usr/src/busybox# strings /opt/STM/STLinux-2.4/devkit/sh4/target/lib/ld-linux.so.2 | grep '^GLIBC_' | sort | uniq
GLIBC_2.2
GLIBC_2.3
GLIBC_2.4
GLIBC_PRIVATE
As I experienced a similar issue when compiling busybox-1.30.1 for SH4 Kernel 2.6.32.59, I had had to prevent nsenter.c and sync.c from becoming compiled by the Makefile.
So in your case, you could try to change your .config file.
root#debianxc:/usr/src/busybox# diff -d .config_from_defconfig .config
4c4
< # Wed Apr 3 20:04:24 2019
---
> # Wed Apr 3 20:09:45 2019
273c273
< CONFIG_MKTEMP=y
---
> # CONFIG_MKTEMP is not set
304,305c304,305
< CONFIG_SYNC=y
< CONFIG_FEATURE_SYNC_FANCY=y
---
> # CONFIG_SYNC is not set
> # CONFIG_FEATURE_SYNC_FANCY is not set
316,318c316,318
< CONFIG_TOUCH=y
< CONFIG_FEATURE_TOUCH_NODEREF=y
< CONFIG_FEATURE_TOUCH_SUSV3=y
---
> # CONFIG_TOUCH is not set
> # CONFIG_FEATURE_TOUCH_NODEREF is not set
> # CONFIG_FEATURE_TOUCH_SUSV3 is not set
667c667
< CONFIG_NSENTER=y
---
> # CONFIG_NSENTER is not set
These are the steps you could follow:
#Backup your .config
cp .config .config.backup
#Create a new config with this sed command. You will see its effect by the follow-up diff command below...
sed -e '/^\(CONFIG_\)\(\(MKTEMP\)\|\(TOUCH\)\|\(NSENTER\)\|\(SYNC\)\)=.*$/s/^\([^=]*\)=.*$/# \1 is not set/' .config >.newconfig
#With this diff output you will see its effect
diff -d .config .newconfig
#Overwrite current .config with .newconfig
cp .newconfig .config
#Now run make oldconfig, because some disablings need auto-disablings of other depending configs, too...
make oldconfig
#See the effect ...
diff -d .config.old .config
#make clean before re-compiling
make clean
#make busybox with cross-compiler
make CROSS_COMPILE=sh4-linux-
#Your new busybox is located in your working direktory
#Optionally invoke make install to create dir tree with symlinks
make CROSS_COMPILE=sh4-linux- install
#Tree's name is _install
Hope this helps.
I am trying to compile a file using an ARM (RVCT 3.1) compiler.
The makefile looks something like this (pasting extract)
AS = armasm
LD = armlink
CC = armcc
TCC = armcc
#TCC = tcc
CPP = armcpp
TCPP = tcpp
AR = armar
NM = nm
ifeq ($(TERM),cygwin)
RM = rm
RM_OPT = -rf
else
RM = del
RM_OPT =
endif
# Standard CFLAGS
ENDIAN := --li
CFLAGS := -g -O2 -Otime --forceinline --cpu ARM7EJ-S $(ENDIAN) \
--apcs /interwork --fpu softvfp --fpmode ieee_fixed \
--bss_threshold=0 --split_sections \
--md --no_depend_system_headers --depend_format=unix
ASFLAGS := --keep -g --cpu ARM7EJ-S $(ENDIAN) \
--apcs /interwork \
--md
LINKFLAGS := --debug --remove --scatter $(BUILD).mem \
--map --symdefs $(BUILD).sym --keep SDK_Callback.o\(*\) \
--list linker.txt --info sizes,totals,veneers,unused \
--errors output.txt --entry SDK_Main \
--elf --output
ARFLAGS := -ru
when I run the make command I get an error like this
Assembling SDK_Callback.s......
armasm --keep -g --cpu ARM7EJ-S --li --apcs /interwork --md -o SDK_Callback.o SDK_Callback.s
make: *** No rule to make target `C:/Program', needed by `xxx_SDK.o'. Stop.
Generating scatter loading file.
make: del: Command not found
make: [makefile:140: clean] Error 127 (ignored)
my compiler is located at "C:\Program Files\ARM"
and I can even see that it is installed properly.
$ armcc --vsn
ARM/Thumb C/C++ Compiler, RVCT3.1 [Build 1055]
For support see http://www.arm.com/support/
Software supplied by: ARM Limited
based on ifeq ($(TERM),cygwin) condition, it should detect the shell to be cygwin (which I am using) and use rm- rf for delete operation and also follow the unix path and line endings. But looking at the errors looks like the makefile is still running under a windows shell (del is used instead of rm -rf)
Is there some configuration under cygwin that has changed or needs to be enabled for it to work as a unix shell?
I have already downloaded the whole 'devel' section of cygwin, just to be sure including 'make' and 'g++' options.
I have also included the cygwin path in the environment variables.
One more clue I have is, it used to work fine on my older system, I started seeing the problem after I switched to a new system and installed everything (cygwin, compiler) again.
Is this a cygwin problem? or the makefile?
Any help is appreciated thanks !
Update: I changed ifeq ($(TERM),cygwin) to ifeq ($(TERM),xterm) and it worked, looks like the terminal name was changed at some point of cygwin updates.
I have the following makefile (Makefile.certify) and when I execute:
make -f Makefile.certify
It gives me a:
/bin/sh: line 23: -o: command not found
PROG=certify
TMP=/var/tmp
ARCH=x86_64
_CC=/bin/cc
all: ${PROG}
${PROG}: ${ARCH}
#for mode in $? ; do \
case $${mode} in \
i386) \
CC="${_CC} -g -D__x86"; \
;; \
i386-f64) \
CC="${_CC} -D_FILE_OFFSET_BITS=64 -g -D__x86";\
;; \
amd64) \
CC="${_CC} -m64 -g -D__x86 -D__ia64 -D__GNUC";\
;; \
*) \
;; \
esac; \
$${CC} -o ${TMP}/$${mode}/$# ${TMP}/$#.c; \
done
I don't really use makefiles or c, but I have to deal with this one.
My questions are:
Why does for loop need a # prefix?
What is the $? in the for loop?
What would be a possible execution of this makefile? Obviously it tries to compile my certify.c file based on the architecture of the system executing or something like this, but I fail to see how it will choose either i386 or amd64 etc.
I am using an x86 system running RHEL.
# prefix is used for suppressing command print by make. If it is not present, make will print command before execution to output.
You can remove it and see the difference.
$? is the dependency list. In your particular case ARCH is defined as a single entry "x86_64". So $? will be expanded into that value. But you can try to modify ARCH value in the following way:
ARCH=x86_64 i386
It tries to build certify binary for a given architecture from cerfify.c source file. Each binary will be located in own sub-directory:
/var/tmp/{i386|x86_64|i386_f64}/certify
# is used to suppress the normal 'echo' of the command that is executed. Using it in the for loop is also new to me (does removing it change anything in the output?)
$? is one of the makefile automatic variables, this one means "The names of all the prerequisites that are newer than the target, with spaces between them"
It will iterate through $?, read above
Edit:
Example of $?
targetfile : firstfile secondfile thirdfile
cat $? > $#
if targetfile is older than all the other 3 files, the makefile will concatenate the contents of firstfile, secondfile and thirdfile together in targetfile.