Jump to content

    

Помогите разобраться в работе make

Имеется проект из одного файла, для сборки которого используется makefile:

[code]CFLAGS ?= -O2

LIBNAME = libmarsh
VERSION_MAJOR = 2
VERSION_MINOR = 0
VERSION_RELEASE = 0

LINKER_NAME = ${LIBNAME}.so
SONAME = ${LINKER_NAME}.${VERSION_MAJOR}
REALNAME = ${SONAME}.${VERSION_MINOR}.${VERSION_RELEASE}

TARGET_DIR = ../lib
TARGET = ${TARGET_DIR}/${REALNAME}
TARGET_STATIC = ${TARGET_DIR}/${LIBNAME}.a

SRC = ${wildcard *.cpp}
OBJECTS = ${SRC:.cpp=.o}
HEADERS = ${wildcard ../include/*.h *.h}

CFLAGS += -Wall -fPIC -I../include -I../../
LDFLAGS = -L/usr/lib/
LIBSERIAL_STATIC = -static -L/usr/lib/ -I/usr/include/ ../../libserial-0.6.0rc1/src/.libs/libserial.a
LDFLAGS += -lrt

CXXFLAGS += -g -std=c++0x -fpermissive
CC = g++

all: ${TARGET} ${TARGET_STATIC} Makefile

${TARGET}: ${OBJECTS} Makefile
    mkdir -p ${TARGET_DIR}
${OBJECTS}
    ${CC} ${LDFLAGS} ${OBJECTS} ${LIBSERIAL_STATIC} -Wl,-soname,${SONAME} -o ${TARGET} ${LDFLAGS}
    ln -sf ${REALNAME} ${TARGET_DIR}/${SONAME}
    ln -sf ${REALNAME} ${TARGET_DIR}/${LINKER_NAME}

${TARGET_STATIC}: ${OBJECTS} Makefile
    ar cr $@ ${OBJECTS}

%.o: %.c ${HEADERS} Makefile
    ${CC} -c ${CFLAGS} $< -o $@

clean:
    rm -rf ${OBJECTS} ${TARGET} ${TARGET_STATIC} ${TARGET_DIR}/${SONAME} ${TARGET_DIR}/${LINKER_NAME}

.PHONY: all clean

[/code]

При сборке выполняются следующие команды:

g++ -g -std=c++0x -fpermissive   -c -o libmarsh.o libmarsh.cpp
mkdir -p ../lib
g++ -L/usr/lib/  -lrt libmarsh.o -static -L/usr/lib/ -I/usr/include/ ../../libserial-0.6.0rc1/src/.libs/libserial.a -Wl,-soname,libmarsh.so.2 -o ../lib/libmarsh.so.2.0.0 -L/usr/lib/  -lrt
ln -sf libmarsh.so.2.0.0 ../lib/libmarsh.so.2
ln -sf libmarsh.so.2.0.0 ../lib/libmarsh.so
ar cr ../lib/libmarsh.a libmarsh.o

У меня, собственно 2 вопроса:

1. Почему в 1-й команде используется CXXFLAGS, хотя он не указан в правиле, а CFLAGS не используется, хотя и указан. При этом в 3-й команде CXXFLAGS уже не используется, хотя точно также не указан в правиле

2. (Этот вопрос относится, скорее, к идеологии разработки ПО под Линукс)

Зачем нужно создавать символические ссылки, если результатом сборки должна быть библиотека ../lib/libmarsh.a?

Edited by Harvester

Share this post


Link to post
Share on other sites

не будучи экспертом - из общей эрудиции

1) в makefile правило для *.c файла, а компилится cpp - то есть вызывается дефолтное cpp правило, которое описывать не нужно

2) там уже линкер, не увидел CFLAG вообще

 

3) - чтобы избавится от зависимомти от версий so.2.0.0 - в директорию lib кладется линк, при смене версии меняется только линк, а программы, которые использовали эту библиотеку продолжают работать. то есть всегда lib/libmarsh.so а какая там версия - для них не важно (скрыто в линке установщиком/сборщиком)

 

Share this post


Link to post
Share on other sites

К первому вопросу - не уверен, но может быть из-за того что ссылка на компилятор указана как CC = g++, и автоматом подтягивается флаг для C++?

 

По крайне мере если судить по второму листингу, компилятор подцепил именно флаг, а не дефолтное значение

Share this post


Link to post
Share on other sites

Неправильный какой-то makefile: где цель install? Вручную что ли все это хозяйство копировать предлагается в /usr/lib? Тогда нет смысла делать симлинки, т.к. их и вручную можно сделать.

 

Share this post


Link to post
Share on other sites
Неправильный какой-то makefile: где цель install? Вручную что ли все это хозяйство копировать предлагается в /usr/lib?

Какой есть. :laughing:

Эта библиотека используется в локальном проекте, расположенном в соседней папке. Наверное поэтому разработчик и не стал заморачиваться.

Share this post


Link to post
Share on other sites

Тогда симлинки тоже не нужны, достаточно библиотеку туда копировать.

Share this post


Link to post
Share on other sites

1. CXXFLAGS это макрос. Как хотите так и называйте. Типа объявления макроса в С при помощи #define

Можно объявить и использовать когда-нибудь в будущем.

 

2. Допустим один написал библиотеку версии 2.0.0 libmarsh.so.2.0.0, кто-то другой ее использовал. Потом первый добавил функциональности и написал libmarsh.so.2.1.0.

Кто-то третий, компилируя прогрмму второго, всегда будет линковать ее с библиотекой libmarsh.so.2.0.0 и никогда libmarsh.so.2.1.0, пока не поменяет в мейк файле с чем линковать. Неудобно.

Чтобы избежать этого всегда линкуют с libmarsh.so, которая есть soft link на текущую версию библиотеки. В мейк файле всегда libmarsh.so.

Share this post


Link to post
Share on other sites
У меня, собственно 2 вопроса:

1. Почему в 1-й команде используется CXXFLAGS, хотя он не указан в правиле, а CFLAGS не используется, хотя и указан. При этом в 3-й команде CXXFLAGS уже не используется, хотя точно также не указан в правиле

2. (Этот вопрос относится, скорее, к идеологии разработки ПО под Линукс)

Зачем нужно создавать символические ссылки, если результатом сборки должна быть библиотека ../lib/libmarsh.a?

У make существует огромное число внутренних (дефаултных) правил, переменных, суффиксов и т.д.

Вы их можете все посмотреть так:

$ make -p > make.suffix
...

(я потому и советую переадресовать в файл, а потом изучить, что их число огромное)

 

Здесь вам перевод (не самый свежий, но достаточно ... для беглого чтения, там объём большой):

GNU Make. Программа управления компиляцией. GNU make Версия 3.79. Апрель 2000, авторы: Richard M. Stallman и Roland McGrath, перевод: Владимир Игнатов, 2000.

 

Подробнее про идеологию технику сборки под Linux можете почитать здесь: Разработка программных проектов в Linux.

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now