Order of arguments to g++ shuffled when parsing makefile - makefile

Following makefile:
#Regular c++ rules
CXX=g++
CXXFLAGS=-Wall -march=native -ffast-math -O3
CXX_OBJECTS=AbsNode.o rle16.o rle8.o
# Link command:
test : $(CXX_OBJECTS)
$(CXX) $(CXX_OBJECTS) -o test
# Compilation commands:
$.o : %.cpp
$(CXX) -c $< $(CXXFLAGS) -o $#
Outputs
g++ -Wall -march=native -ffast-math -O3 -c -o AbsNode.o AbsNode.cpp
g++ -Wall -march=native -ffast-math -O3 -c -o rle16.o rle16.cpp
g++ -Wall -march=native -ffast-math -O3 -c -o rle8.o rle8.cpp
while I expect
g++ -c AbsNode.cpp -Wall -march=native -ffast-math -O3 -o AbsNode.o
g++ -c rle16.cpp -Wall -march=native -ffast-math -O3 -o rle16.o
g++ -c rle8.cpp -Wall -march=native -ffast-math -O3 -o rle8.o
Why is the order of arguments to g++ switched compared to the rule stated in makefile???

$.o : %.cpp
You typed $ instead of %, which turned is into a non-template rule. However make has a default rule for C++ file, which was taken instead of yours. The order of arguments match this internal rule.

Related

Why does ```CFLAGS:=$(CFLAGS) -O3``` not work as expected?

Makefile like this:
CFLAGS := $(CFLAGS) -O3
test: main.o
gcc $(CFLAGS) -o $# $^
clean:
rm test *.o -f
compile 1: command: make, output: gcc -O3 -o test main.c
compile 2: command: make CFLAGS="-Wall -Werror", output: gcc -Wall -Werror -o test main.c
question: why not output: gcc -Wall -Werror -O3 -o test main.c ?
use override directive:
override CFLAGS := $(CFLAGS) -O3
or
override CFLAGS += -O3

Building a Window exe using MinGW, Windows-7 in virtual machine

I'm working in Windows 7, 64 bit, running in a Virtual Box machine on a (recent-ish) Mac with Intel processor.
I have MinGW installed:
gcc -dumpmachine
>>> x86_64-w64-mingw32
I am trying to compile a Windows exe for this code (Landsat-8 routines for solar and satellite angle calculations):
gcc -I ias_lib -o l8_angle.exe -c l8_angle.c
which gives me no errors or warnings when run, and creates l8_angle.exe as expected. When opened, the exe gives:
The version of this file is not compatible with the version of Windows
you're running. Check your computer's system information to see
whether you need an x86 (32-bit) for x64 (64-bit) version of the
program, and then contact the software publisher.
Is it possible to compile this program on my setup?
If you're wondering I can run make on the Mac OS side to get a Linux executable, but I need a Windows executable for my production machine.
I was able to compile successully by echoing the gcc statements in both makefiles:
#echo $(value INCS)
which for some reasom prints the completely assembled gcc command. I then confirmed what the selected flags did and saw that they were all equally appropriate for a Windows build.
The build commands were then:
cd ias_lib
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_calculate_angles_rpc.c -o ias_angle_gen_calculate_angles_rpc.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_read_ang.c -o ias_angle_gen_read_ang.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_utilities.c -o ias_angle_gen_utilities.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_initialize.c -o ias_angle_gen_initialize.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_write_image.c -o ias_angle_gen_write_image.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_angle_gen_find_scas.c -o ias_angle_gen_find_scas.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_geo_convert_dms2deg.c -o ias_geo_convert_dms2deg.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_math_compute_unit_vector.c -o ias_math_compute_unit_vector.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_math_compute_vector_length.c -o ias_math_compute_vector_length.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_math_find_line_segment_intersection.c -o ias_math_find_line_segment_intersection.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_logging.c -o ias_logging.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_misc_create_output_image_trim_lut.c -o ias_misc_create_output_image_trim_lut.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_misc_convert_to_uppercase.c -o ias_misc_convert_to_uppercase.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_misc_write_envi_header.c -o ias_misc_write_envi_header.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_odl_free_tree.c -o ias_odl_free_tree.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_odl_get_field.c -o ias_odl_get_field.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_odl_read_tree.c -o ias_odl_read_tree.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_parm_provide_help.c -o ias_parm_provide_help.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_parm_read.c -o ias_parm_read.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_parm_map_odl_type.c -o ias_parm_map_odl_type.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_parm_check_ranges.c -o ias_parm_check_ranges.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c ias_satellite_attributes.c -o ias_satellite_attributes.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c landsat8.c -o landsat8.o
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -c lablib3.c -o lablib3.o
ar -r libl8ang.a ias_angle_gen_calculate_angles_rpc.o ias_angle_gen_read_ang.o ias_angle_gen_utilities.o ias_angle_gen_initialize.o ias_angle_gen_write_image.o ias_angle_gen_find_scas.o ias_geo_convert_dms2deg.o ias_math_compute_unit_vector.o ias_math_compute_vector_length.o ias_math_find_line_segment_intersection.o ias_logging.o ias_misc_create_output_image_trim_lut.o ias_misc_convert_to_uppercase.o ias_misc_write_envi_header.o ias_odl_free_tree.o ias_odl_get_field.o ias_odl_read_tree.o ias_parm_provide_help.o ias_parm_read.o ias_parm_map_odl_type.o ias_parm_check_ranges.o ias_satellite_attributes.o landsat8.o lablib3.o
cd ..
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -I./ias_lib/ -I./ -c -o l8_angles.o l8_angles.c
gcc -g -Wall -O2 -march=nocona -mfpmath=sse -msse2 -I./ias_lib/ -I./ -c -o angles_api.o angles_api.c
gcc -g -Wall -O2 -I./ias_lib/ -I./ -o l8_angles.exe ias_lib/libl8ang.a l8_angles.o angles_api.o -L./ias_lib/ -ll8ang -lm
where the only change was in the final line, l8_angles.exe rather than l8_angles. If anyone has a more straightforward way, I would love to see it.

generic makefile to create multiple executable using different flags

I would like to create a generic Makefile that builds several executables using different compiler flags for each executable without using shell commands. The executable file name should be composed from the source file and a unique post fixed name. It should also produce an assembly or preprocessor file per source file if needed.
For the target BIN_BDG_FILES, the "$<" (exercise-1.1.0.c ) is always the first item from the list (exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c) as expected. I tried without success to modify the SRC_FILES using the filter-out function. My intent was to remove the first item from the list for each Target, so that the first item corresponds to the correct target. I am not sure this is the correct approach. Your comments are welcome.
i.e.
This is my attempt at using built in make constructs.
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
echo SRC_FILES := $(filter-out $<, $(SRC_FILES))
Makefile
SHELL = bash
SRC_FILES = $(wildcard *.c)
BIN_FILES = $(patsubst %.c,%,$(SRC_FILES))
BIN_DBG_FILES = $(patsubst %.c,%-dbg,$(SRC_FILES))
SRC_PRE = $(patsubst %.c,%-pre,$(SRC_FILES))
CC = gcc
WARNINGS := -Wall
CFLAGS = -O2 -std=c99 $(WARNINGS)
DBG_CFLAGS = -g -O -std=c99 $(WARNINGS)
PRE_FLAG = -E
IFLAGS = -I.
all: $(BIN_FILES) $(BIN_DBG_FILES) MK-BASH
$(BIN_DBG_FILES): $(SRC_FILES)
$(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#
MK-BASH::
for src in $(SRC_FILES); do \
echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(DBG_CFLAGS) $(IFLAGS) $$src -o $${src%.c}-dbg; \
$(CC) $(PRE_FLAG) $$src > $${src%.c}-pre; \
done
clean:
rm -f $(BIN_FILES) *-dbg *-pre
This is the output from executing make command.
This is the output from the target BIN_FILES.
gcc -O2 -std=c99 -Wall exercise-1.1.0.c -o exercise-1.1.0
gcc -O2 -std=c99 -Wall exercise-1.1.1.c -o exercise-1.1.1
gcc -O2 -std=c99 -Wall exercise-1.2.0.c -o exercise-1.2.0
gcc -O2 -std=c99 -Wall exercise-1.2.1.c -o exercise-1.2.1
This is the output from target BIN_DBG_FILES which uses the first source file on the list to build all targets. It should use the appropriate file (exercise-1.1.1.c) to build each target file (exercise-1.1.1-dbg).
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. **exercise-1.1.0.c** -o exercise-1.2.1-dbg
This is the output from the target MK-BASH using shell commands.
for src in exercise-1.1.0.c exercise-1.1.1.c exercise-1.2.0.c exercise-1.2.1.c; do \
echo gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -g -O -std=c99 -Wall -I. $src -o ${src%.c}-dbg; \
gcc -E $src > ${src%.c}-pre; \
done
output:
gcc -g -O -std=c99 -Wall -I. exercise-1.1.0.c -o exercise-1.1.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.1.1.c -o exercise-1.1.1-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.0.c -o exercise-1.2.0-dbg
gcc -g -O -std=c99 -Wall -I. exercise-1.2.1.c -o exercise-1.2.1-dbg
Use a pattern rule:
DBG: $(BIN_DBG_FILES)
%-dbg: %.c
#echo $(CC) $(DBG_CFLAGS) $(IFLAGS) $< -o $#

make is ignoring some depedencies

Here is my Makefile:
CC=gcc
CFLAGS=-Wall -std=gnu99
OBJ1=mknlrescs.o collisionsys.o csheader.o utils.o labels.o csdata.o
OBJ2=mknrescs.o utils.o
all: mknlrescs mknrescs
mknlrescs: $(OBJ1)
$(CC) $(CFLAGS) -o $# $<
mknrescs: $(OBJ2)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $<
When I type make mknlrescs I get the following:
$ make mknlrescs
gcc -Wall -std=gnu99 -c -o mknlrescs.o mknlrescs.c
gcc -Wall -std=gnu99 -c collisionsys.c
gcc -Wall -std=gnu99 -c csheader.c
gcc -Wall -std=gnu99 -c utils.c
gcc -Wall -std=gnu99 -c labels.c
gcc -Wall -std=gnu99 -c csdata.c
gcc -Wall -std=gnu99 -o mknlrescs mknlrescs.o -lm
mknlrescs.o: In function `main':
mknlrescs.c:(.text+0x4b): undefined reference to...
And a bunch of other "undefined reference to..." errors.
The rest of the objects are not being linked. Notice it only linked the first object file. How can I correct this?
The automatic variable $< stands for the first prerequisite of the rule that defined the recipe.
If you want to use ALL the prerequisites, use $^ instead.
See Automatic Variables for a full list.

Creating a simple Makefile to build a shared library

I am trying to create a very basic hand crafted Makefile to create a shared library to illustrate a point.
This is what I have so far:
SHELL = /bin/sh
CC = gcc
FLAGS = -std=gnu99 -Iinclude
CFLAGS = -fPIC -pedantic -Wall -Wextra -march=native -ggdb3
DEBUGFLAGS = -O0 -D _DEBUG
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
TARGET = example.so
SOURCES = $(shell echo src/*.c)
HEADERS = $(shell echo include/*.h)
OBJECTS = $(SOURCES:.c=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(CFLAGS) $(DEBUGFLAGS) -o $(TARGET) $(OBJECTS)
When I run make, it attempts to build an application - and ld fails because it can't resolve main().
Problem seems to be with CFLAGS - I have specified -fPIC but that is not working - what am I doing wrong?
Edit
I added the -shared flag as suggested, when I run make, I got this error:
gcc -std=gnu99 -Iinclude -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3 -O0 -D _DEBUG -o example.so src/example.o
/usr/bin/ld: src/example.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/example.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [example.so] Error 1
Which seems to be suggesting to revert back to -fPIC only.
BTW, my new CFLAGS setting is:
CFLAGS = -fPIC -shared -pedantic -Wall -Wextra -march=native -ggdb3
I am running gcc v4.4.3 on Ubuntu 10.0.4.
The solution was to modify the XXFLAGS as follows:
FLAGS = # -std=gnu99 -Iinclude
CFLAGS = -fPIC -g #-pedantic -Wall -Wextra -ggdb3
LDFLAGS = -shared
Compile with -shared:
gcc -o libfoo.so module1.o module2.o -shared
(This also works on MingW under Windows to produce DLLs.)
Example for C++ files. I've also included a clean target.
.PHONY : clean
CPPFLAGS= -fPIC -g
LDFLAGS= -shared
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS=$(SOURCES:.cpp=.o)
FIKSENGINE_LIBDIR=../../../../lib
FIKSENGINE_INCDIR=../../../../include
TARGET=$(FIKSENGINE_LIBDIR)/tinyxml.so
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(TARGET)
$(TARGET) : $(OBJECTS)
$(CC) $(CPPFLAGS) $(OBJECTS) -o $# $(LDFLAGS)
Since you try to build so file, you probably need -shared.
this is my goto makefile rule for so files:
%.so: %.o ; $(LINK.c) $(LDFLAGS) -shared $^ -o $#
can be used like so
CFLAGS+=-fPIC
libmyfoo.so: # create from libmyfoo.o
# or
libmyfoo.so: myfoo.o # create from myfoo.o

Resources