Страницы

Поиск по вопросам

Показаны сообщения с ярлыком make. Показать все сообщения
Показаны сообщения с ярлыком make. Показать все сообщения

понедельник, 9 марта 2020 г.

Ввод данных в С. Не определяется GetString() из cs50

#c #gcc #make #cs50


Почему у меня не определяется string s = GetString();?

hell.c

#include 
#include 

int main(void)
{
    printf("State our name: ");
    string s = GetString();
    printf("hello, %s\n", s);
}



  cc hell.c -o hell

/tmp/ccHZXs2m.o: In function `main'
hell.c:(.text+0x16): undefined reference to `GetString'
collect2: error: ld returned 1 exit status
make: *** [hell] Error 1


    


Ответы

Ответ 1



Почему бы тебе не воспользоваться методом scanf() для чтения с консоли? int main(void) { string name; printf("Введите ваше имя"); scanf("%s", name); printf("Привет, %s\n!", name); return 0; }

Ответ 2



Нужно скомпилировать и слинковать с файлом cs50.c cc -c help.c -o help.o cc -c cs50.c -o cs50.c cc -o help help.o cs50.o

Ответ 3



Потому что у тебя нету такой функции GetString(). Добавь например выше.. string GetString(void) { return "test"; }

Ответ 4



Могу предположить, что у вас слетели или не были настроены переменные среды CFLAGS и LDLIBS. Попробуйте создать в этой же папке файл с названием makefile и поместить в него данные строки: CC=clang CFLAGS=-ggdb3 -O0 -std=c99 -Wall -Werror LDLIBS=-lcs50 -lm После чего просто вызовите make: make hell for ABC ;)

Ответ 5



Потому что cs50 это библиотека курса гарварда cs50. А у Вас она не установлена. Запустите в их удаленной линуксовой среде и там подцепится.

Ответ 6



Используйте консоль в редакторе (отдельная иконка рядом с gedit). Тогда независимо от того, подключите ли вы библиотеку string.h или нет, функция GetString сработает.

Ответ 7



.h файл только декларирует список функций, для их использования в программу должен быть вкомпилирован их код находящийся скорее всего в .cшных файлах (но может оказаться в .asm .haskell ... .lib .dll .so .a) в самом простейшем случае у вас где-то должен лежать файл cs50.c, который тоже нужно скомпилировать: gcc -o ./hello[.exe] hello.c cs50/lib/src/cs50.c PS: описание принципа использования модулей, раздельной компиляции и использования ключевого слова static неплохо объяснено в курсе Евгения Линского

Ответ 8



В окружении CS50 на c9.io начиная с 2016 эту функцию переименовали в: get_string() Используйте её или найдите более свежие видео-лекции.

Ответ 9



Потому, что ты не читал нормально начало к заданиям - ТАМ ТАК ЖИРНО написано ЦТ Дополнительные материалы reference.cs50.net/ — разъяснение функций библиотек, используемых во время обучения. На английском. http://computer.howstuffworks.com/c.htm стр. 11 – 14 и 39 И вот если пройти в разъяснение функций библиотек - и поискать поиском string - то будет чудо, выяснится что надо подключать библиотеку string.h - а она не прописана в cs50 - ребята не на все делали костыль! Зачем костыль на библиотеку готовую?

пятница, 14 февраля 2020 г.

Как заголовочный файл указывает на библиотеку?

#linux #c #make


Начал знакомится с make и задался этим вопросом..
К примеру есть подключённый заголовок: #include
В нём ,как я понимаю лежат прототипы функций, а сами функции откомпилированы в объектные
файлы и собраны в библиотеку к примеру ".a". 
Линковщик увидев строку заголовка, идёт в /usr/lib . 
Но как он видит нужную библиотеку ? Перебирает все ?
    


Ответы

Ответ 1



В традиционной реализации линкер никак не видит нужную библиотеку. Это ваша задача вручную "скормить" линкеру соответствующую библиотеку во время линковки. Однако стандартная библиотека языка С обычно подается на вход линкеру автоматически, без вашего участия, т.е. именно для #include вам обычно ничего дополнительно делать не надо. В некоторых реализациях есть возможность таки указать внутри заголовочного файла, какую именно библиотеку необходимо подключить. Например, в MS Visual Studio это делается путем указания #pragma comment(lib, "something.lib") внутри заголовочного файла. В таком варианте после включения заголовочного файла соответствующая библиотека на этапе линковки подключится "сама". Линковщик увидев строку заголовка, идёт в /usr/lib... Линковщик обычно уже не может видеть никакой "строки заголовка". Эти "строки заголовка" исчезают бесследно еще на этапе препроцессинга, даже еще до начала собственно компиляции. До линковщика уже доходят откомпилированные объектные файлы, в которых никаких "строк заголовка" уже нет. Реализация таких вещей как #pragma comment(lib, держится на специальных полях в формате объектных файлов.

Ответ 2



Когда компилируешь на языке C, то автоматически линкуется одна библиотека. Она подключается вживую при запуске программы. У меня эта библиотека такая : /lib64/libc-2.22.so. Все остальные библиотеки ты должен подключать вручную. Например gcc -lrt ... подключает /lib64/librt-2.22.so для параллельных нитей. Она тоже будет подключатся вживую. То-же самое только через ссылки : /usr/lib64/libc.so и /usr/lib64/librt.so.

Ответ 3



Линковщик увидев строку заголовка, идёт в /usr/lib Разумеется - нет. Как уже отвечали, на этапе линковки никаких операторов #include да и самих файлов заголовков уже нет Но как он видит нужную библиотеку ? Поскольку речь идёт о linux и make, то можно ответить так - из командной строки gcc: Ключ -l (это буква "эль малая") задаёт имя ФАЙЛА используемой Вами библиотеки. Префикс lib и суффикс so можно опустить. Таким образом, если Вы используете математическую библиотеку libm.so, то ключ надо записать так: -lm Ключ -L задаёт ДИРЕКТОРИЮ, в которой лежат Ваши библиотеки. Если они расположены в стандартных каталогах (/lib, /usr/lib, ...) то использовать этот ключ не нужно. Если же Ваши библиотеки лежат в "левых" каталогах, то их надо указать обязательно. Типичная ситуация, когда автор программы желает расположить библиотеки в том же месте, где лежит исполняемый модуль. Тогда надо написать так: -L.

четверг, 13 февраля 2020 г.

Как выполнить make, находясь в другой дирректории?

#linux #vim #make


Возможно ли это? Не хочу тратить время на выход из vim, команду cd. Также не хочу
держать открытыми несколько окон.
    


Ответы

Ответ 1



Ключи: -C КАТАЛОГ, --directory=КАТАЛОГ Перейти в КАТАЛОГ перед выполнением действий. make -C /путь/к/каталогу

Makefile для отдельных каталогов src и bin

#g++ #make


Существует дерево файлов:

folder
|-src
  |-myfile.cpp
  |-myfile.h
|-bin
|-Makefile


Хочу написать Makefile так, чтобы компилировались файлы, находящиеся в каталоге src,
но объектные файлы создавались в текущем (в folder). А потом, чтобы они линковались
в один файл в каталог bin.

На данный момент имею нерабочий Makefile. Ругается на отсутствие правила для myfile.o.

TARGET=myfile
OBJECTS=myfile.o
XX=g++
CXXFLAGS=-std=c++11

all: ${TARGET}
${TARGET}: ${OBJECTS}
    ${XX} -o ${TARGET} ${OBJECTS}
.c.o:
    ${XX} ${CXXFLAGS} -c "${INCLUDE}$<" -o "$@"


Как правильно реализовать поставленную задачу?
    


Ответы

Ответ 1



чтобы они линковались в один файл в каталог bin значит, собирать вам надо не myfile, а bin/myfile. это я про переменную TARGET. объектные файлы создавались в текущем так и укажите цель и пререквизиты соответствующим образом: %.o: src/%.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION) $< здесь вторая строка, рецепт, взята из implicit rules, которые можно посмотреть в выводе команды make -p остаётся только объяснить компилятору, где искать заголовочный файл myfile.h (если, конечно, компилятор сам не «догадается»). тут я, как не-программист, вряд ли чем помогу. разве что предположу, что надо добавить к значению перменной CPPFLAGS или CXXFLAGS опцию -I src.

Ответ 2



Gnu make имеет интересную директиву vpath, которая позволяет указать где искать те или иные исходники. В вашем случае достаточно добавить в начало Makefile: vpath %.cpp src vpath %.h src CXXFLAGS+=-Isrc И implicit rules тогда можно не переписывать.

вторник, 28 января 2020 г.

Как скомпилить C++ проект

#qt #visual_cpp #g++ #make #makefile


Очень нужна dll'ка получаемая при сборке одного из проектов (любого) в данном репозитории: 
http://sourceforge.net/p/zint/code/ci/master/tree/

В указанном репозитории, как я понял, несколько вариантов: для qt, VC++ и, я так
полагаю, для C++ в GCC. Есть варианты создающие dll и варианты создающие десктопную
программу использующую данную dll. Меня интересует именно dll...

Вот только проблема в том, что я ни с чем вышеперечисленным ране не работал на уровне
достаточном для того, чтобы уметь собрать проект из файлов представленных в репозитории. 
Проект для VC++ у меня в 15-ой студии "с наскока" не собрался, ругается на отсутствие:
Не удается открыть файл включение: png.h. Которого в директории проекта не наблюдается.
В идеале хотелось бы конечно получить рабочую dll'ку именно в VS. Но если не выйдет,
то любой другой вариант так же приемлем.
Qtшный проект так же ругается (не могу сказать на что именно, в поле вывода абракадабра
какая-то...)

Вопрос: Какую последовательность действий мне нужно совершить чтобы скомпилировать
один из представленных в репозитории проектов создающий dll библиотеку.

PS: Если кто-то сам скомпилит и кинет ссылку на zint.dll я конечно тоже буду признателен,
но всё же хотелось бы знать как это делается.
    


Ответы

Ответ 1



Сборка zint с поддержкой PNG Сборку будем производить в некотором каталоге %BUILD_ROOT%. Везде в дальнейшем разделителем каталогов должна быть прямая дробная черта (/). При использовании обратной (\) возможны ошибки сборки. Для сборки в данном случае использовались CMake версии 3.3.2 и MinGW-builds версии 5.2.0rev0. Сборка библиотеки zlib (использовалась версия 1.2.8). Скачиваем архив исходников zlib и распаковываем его в каталог %BUILD_ROOT%/zlib. Далее собираем: cd /d %BUILD_ROOT% mkdir zlib-build cd zlib-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/zlib-out ../zlib cmake --build . mingw32-make install После этого в каталоге %BUILD_ROOT%/zlib-out будет скомпилированная библиотека zlib. Сборка библиотеки libpng (использовалась версия 1.6.19). Скачиваем архив исходников libpng и распаковываем его в каталог %BUILD_ROOT%/libpng. Собираем: cd /d %BUILD_ROOT% mkdir libpng-build cd libpng-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/libpng-out -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlib.dll.a -DZLIB_INCLUDE_DIR=%BUILD_ROOT%/zlib-out/include ../libpng cmake --build . mingw32-make install Предупреждения CMake игнорируем. После этого в каталоге %BUILD_ROOT%/libpng-out будет скомпилированная библиотека libpng. Сборка библиотеки zint (использовалась версия 2.4.3). Скачиваем архив исходников zint и распаковываем его в каталог %BUILD_ROOT%/zint. Файл CMakeLists.txt то ли не подходит для новых версий CMake, то ли в нём изначально ошибка, но в любом случае при сборке возникает ошибка, связанная с невозможностью найти файл png.h. Для исправления ошибки нужно этот файл немного подредактировать, а именно, в 14-й строке заменить ${PNG_INCLUDES} на ${PNG_INCLUDE_DIRS}. Теперь можно собирать: cd /d %BUILD_ROOT% mkdir zint-build cd zint-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/zint-out -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlib.dll.a -DZLIB_INCLUDE_DIR=%BUILD_ROOT%/zlib-out/include -DPNG_LIBRARY=%BUILD_ROOT%/libpng-out/lib/libpng.dll.a -DPNG_PNG_INCLUDE_DIR=%BUILD_ROOT%/libpng-out/include ../zint cmake --build . mingw32-make install Предупреждения при сборке игнорируем. После выполнения всех шагов в каталоге %BUILD_ROOT%/zint-out будет требуемая библиотека libzint.dll. Сборка без зависимостей. Полученная libzint.dll имеет в зависимостях libpng16.dll, а та, в свою очередь, libzlib.dll. Кроме того, все эти библиотеки зависят от libgcc*.dll. Чтобы убрать все эти зависимости и сделать сборку (почти) полностью независимой, можно сделать следующее. Определяем две переменных: set CFLAGS=-static set CXXFLAGS=%CFLAGS% Эти переменные уберут зависимость библиотек от libgcc*.dll. Чтобы убрать зависимость libpng.dll от zlib.dll, исправим один параметр при запуске cmake: -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlibstatic.a А чтобы убрать зависимость libzint.dll от libpng16.dll и libzlib.dll, нужно у cmake исправить два параметра: -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlibstatic.a -DPNG_LIBRARY=%BUILD_ROOT%/libpng-out/lib/libpng.a Готово! Полученная библиотека зависит только от kernel32.dll и msvcrt.dll.

понедельник, 6 января 2020 г.

Перевод makefile в команды

#linux #ubuntu #make #makefile


Подскажите, пожалуйста, как будут выглядеть вот эти строки в виде отдельных команд
(как если бы это было записано не в makefile, а в compile.sh, скажем)?

obj-m += OutIntTbl.o
OutIntTbl-objs := module.o main.o
$(KBUILD_EXTMOD)/main.o: main.asm
    nasm -f elf -o $@ $^


Запуск такой:

make -C /usr/src/linux-headers-`uname -r` SUBDIRS=$PWD modules

    


Ответы

Ответ 1



добавьте к опциям/параметрам, с которыми запускаете программу make, опцию -n: $ make -n остальные-опции-и-параметры “No-op”. Causes make to print the recipes that are needed to make the targets up to date, but not actually execute them. Note that some recipes are still executed, even with this flag (see How the MAKE Variable Works). Also any recipes needed to update included makefiles are still executed (see How Makefiles Are Remade). мой вольный перевод: «не выполнять». эта опция заставит программу напечатать все рецепты (читай — shell-команды), необходимые для обновления целей, не выполняя эти рецепты. но даже с этой опцией некоторые рецепты всё равно будут выполнены (см. How the MAKE Variable Works). также будут выполнены те рецепты, которые необходимы для обновления подключенных makefile-ов (см. How Makefiles Are Remade).

Ответ 2



Вы собираетесь собрать модуль для ядра Linux. Это очень сложный процесс, с точки зрения компиллятора и линковщика. Вот почему: Неизвестно, какие струтуры ядра Вы используете - нужны ВСЕ хидеры ядра. Неизвестно, какие функции ядра Вы вызываете, значит нужны объектные файлы ВСЕХ модулей ядра Если объектников ядра нет - их нужно скопилировать. Все... Для компилляции ядра нужно обработать конфигурационный файл ядра. Когда Александр Македонский, в юности, изучал геометрию, ему эта наука показалась слишком сложной и запутанной. Он спросил своего учителя - а нельзя-ли как-то покороче изучить это дело? :-) На что препод ответил, что в геометрии нет царских путей. Так вот я Вам скажу, что в разработке модулей ядра нет царских путей - это очень большая и сложная работа. Которую разработчики Linux пытаются хоть как-то облегчить с помощью obj-m и так далее. Короче - не получится!

вторник, 31 декабря 2019 г.

Как скрыть флаги при компиляции?

#c #linux #make


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

Как сделать, чтобы эти флаги во время компиляции не выводились на экран?

К примеру, хочу оставить только путь к компилируемому файлу и результат его компиляции. 
В make-файле команда для цели, как  понимаю, вся выводится на экран. Проект написан на C.
    


Ответы

Ответ 1



Какой бы не был makefile, но там в конечном счете должен быть вызов компилятора. Если перед этой сторокой добавить @, то эта строка не будет выводиться. Теперь перед этой строкой достаточно вставить @echo gcc $@ или что то подобное и будет "красивый вывод". Аналогично и с линковкой.

среда, 18 декабря 2019 г.

В Linux Debian нет стандартно программы make. Как устанавливать?

#make #debian #linux


Установил Linux Debian. Все стандартные программы есть, а хочу установить pindgin
и ещё парочку. А там надо из исходников собирать. А там нужен make. Ввел в терминале
make
Вывел
bash: make: команда не найдена.
Скачал этот make с офф. сайта. Глянул файл INSTALL и README. Ничего не понял. 
Как установить этот make? Напишите пожалуйста.    


Ответы

Ответ 1



Если есть необходимость компилировать софт, то одного make может быть мало. Поэтому обычно более оптимальным является установка пакета build-essential, который содержит make в том числе. В убунте он поставит к примеру dpkg-dev (package building tools for Debian g++ (The GNU C++ compiler), gcc (The GNU C compiler), libc6-dev (GNU C Library: Development Libraries and Header Files) or libc-dev (virtual package provided by libc6-dev) и make. В Debian приблизительно тоже. Поэтому рекомендую такую последовательность sudo -s apt-get update #это желательно, если хочется все новенькое apt-get install build-essential

Ответ 2



(под root -ом) sudo su apt-get install make apt-get install pidgin

Ответ 3



Попробуй ввести в командной строке sudo apt-get install make

Ответ 4



Сильно думаю, что можно поставить пакет от убунты.. не силен в debianских дистрибутивах, но думаю должно прокатить http://pidgin.im/download/ubuntu/

вторник, 9 июля 2019 г.

Невозможно запустить это приложение на вашем ПК (Windows 10) [закрыт]

Недавно перешел с MinGW на MinGW-w64. Все установил, поставил все пути в ide Code::block. Делаю тестовую программу Hello World, компилирую - на экране пустота. Захожу в папку, где лежит бинарник проекта. Запускаю, и вин 10 выдает - Невозможно запустить это приложение на вашем ПК. Как быть? Уже голову сломал.


Ответ

Если бинарник появился, значит компиляция прошла успешно и проблема в запуске вашего приложения.
Проблема запуска приложения может быть связана с отсутствием зависимых библиотек в папке с бинарником или в PATH или ещё из-за кучи причин.
Чтобы просмотреть, от каких библиотек зависит ваш exe, можно воспользоваться специальной утилитой Dependency Walker или Lister плагином для TotalCommander:

Как видно из скриншота, программа скомпилирована с зависимостью от runtime библиотеки MinGW libgcc_s_dw2-1.dll и месторасположение этой библиотеки неизвестно (на самом деле, она лежит в папке \mingw-w64\mingw32\bin\).
Чтобы решить эту проблему, надо либо добавить в PATH путь к зависимой библиотеке, либо положить её рядом с exe (и все библиотеки, от которых она зависит), либо при компиляции проекта указать, чтобы она линковалась статически (конкретно, для статической линковки libgcc_s_dw2-1.dll нужно в настройках проекта добавить флаг линковщику: -static-libgcc).

Upd: Как выяснилось из комментариев, была попытка запустить 64-х битный бинарник на 32-х битной системе. Отсюда следует вывод, что нужно внимательно смотреть, под какую платформу вы собираете своё приложение. У готового бинарника, так же можно выяснить, какой он разрядности (32/64 бит). Информация об этом находится в PE заголовках и есть программы, для просмотра этих заголовков (например, PE Explorer или тот же Lister плагин для TC):

вторник, 11 июня 2019 г.

Makefile: правильная пересборка .c файлов в случае изменения .h файлов:

Имеются файлы:
src1.c src1.h src2.c src3.c src4.c src4.h
Стоит обратить внимание, что НЕ для всех .c файлов есть свои .h файлы.
Текущий Мakefile работает, но с оговоркой: при изменении любого .h файла пересобираются ВСЕ .c файлы:
SRCS = $(wildcard *.c) HDRS = $(wildcard *.h)
%.o: %.c $(HDRS) @$(CC) -c -o $@ $<
Если раскрыть содержимое переменной $(HDRS), то автоматическая сборка будет выглядеть так:
%.o: %.c src1.h src4.h @$(CC) -c -o $@ $<
Именно поэтому, если изменился только один файл src4.h, то будут пересобраны все *.c файлы.
В другом случае, попытка сделать так, как указано в примере ниже, приведёт к ошибке, потому, что файлы src2.h src3.h не существуют:
%.o: %.c %.h @$(CC) -c -o $@ $<
Будьте любезны, подскажите, пожалуйста, как сделать правильный Makefile, чтобы при изменении src4.h пересобирался только src4.с, но не остальные.
Все мои самостоятельные попытки найти ответ на этот вопрос успехом не увенчались.
Заранее благодарю за совет.


Ответ

Можно указать зависимости в ручную в Makefile
src1.o: src1.c src1.h
и так далие для всех обектников
Или создать файлы зависимостей *.d для всех *.c файлов и включить в Makefile
SRCS = $(wildcard *.c) HDRS = $(wildcard *.h) OBJ_CATALOG=.obj/ OBJS=$(patsubst %.c,$(OBJ_CATALOG)%.o,$(SRCS)) DEPEND_CATALOG=.depend/ DEPEND=$(patsubst %.c,$(DEPEND_CATALOG)%.d,$(SRCS))
$(OBJ_CATALOG)%.o:%.c $(CXX) $(CFLAGS) -c $< -o $@
$(DEPEND_CATALOG)%.d:%.c $(CXX) -MM -I. $< | sed -e '1s/^/.obj\//' > $@
include $(DEPEND)

четверг, 30 мая 2019 г.

Ввод данных в С. Не определяется GetString() из cs50

Почему у меня не определяется string s = GetString();?
hell.c
#include #include
int main(void) { printf("State our name: "); string s = GetString(); printf("hello, %s
", s); }
cc hell.c -o hell
/tmp/ccHZXs2m.o: In function `main' hell.c:(.text+0x16): undefined reference to `GetString' collect2: error: ld returned 1 exit status make: *** [hell] Error 1


Ответ

Почему бы тебе не воспользоваться методом scanf() для чтения с консоли?
int main(void) { string name; printf("Введите ваше имя"); scanf("%s", name); printf("Привет, %s
!", name); return 0; }

вторник, 23 апреля 2019 г.

Как выполнить make, находясь в другой дирректории?

Возможно ли это? Не хочу тратить время на выход из vim, команду cd. Также не хочу держать открытыми несколько окон.


Ответ

Ключи: -C КАТАЛОГ, --directory=КАТАЛОГ Перейти в КАТАЛОГ перед выполнением действий.
make -C /путь/к/каталогу

Makefile для отдельных каталогов src и bin

Существует дерево файлов:
folder |-src |-myfile.cpp |-myfile.h |-bin |-Makefile
Хочу написать Makefile так, чтобы компилировались файлы, находящиеся в каталоге src, но объектные файлы создавались в текущем (в folder). А потом, чтобы они линковались в один файл в каталог bin.
На данный момент имею нерабочий Makefile. Ругается на отсутствие правила для myfile.o.
TARGET=myfile OBJECTS=myfile.o XX=g++ CXXFLAGS=-std=c++11
all: ${TARGET} ${TARGET}: ${OBJECTS} ${XX} -o ${TARGET} ${OBJECTS} .c.o: ${XX} ${CXXFLAGS} -c "${INCLUDE}$<" -o "$@"
Как правильно реализовать поставленную задачу?


Ответ

чтобы они линковались в один файл в каталог bin
значит, собирать вам надо не myfile, а bin/myfile. это я про переменную TARGET
объектные файлы создавались в текущем
так и укажите цель и пререквизиты соответствующим образом:
%.o: src/%.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
здесь вторая строка, рецепт, взята из implicit rules, которые можно посмотреть в выводе команды make -p

остаётся только объяснить компилятору, где искать заголовочный файл myfile.h (если, конечно, компилятор сам не «догадается»). тут я, как не-программист, вряд ли чем помогу. разве что предположу, что надо добавить к значению перменной CPPFLAGS или CXXFLAGS опцию -I src

среда, 27 марта 2019 г.

Как скомпилить C++ проект

Очень нужна dll'ка получаемая при сборке одного из проектов (любого) в данном репозитории: http://sourceforge.net/p/zint/code/ci/master/tree/
В указанном репозитории, как я понял, несколько вариантов: для qt, VC++ и, я так полагаю, для C++ в GCC. Есть варианты создающие dll и варианты создающие десктопную программу использующую данную dll. Меня интересует именно dll...
Вот только проблема в том, что я ни с чем вышеперечисленным ране не работал на уровне достаточном для того, чтобы уметь собрать проект из файлов представленных в репозитории. Проект для VC++ у меня в 15-ой студии "с наскока" не собрался, ругается на отсутствие: Не удается открыть файл включение: png.h. Которого в директории проекта не наблюдается. В идеале хотелось бы конечно получить рабочую dll'ку именно в VS. Но если не выйдет, то любой другой вариант так же приемлем. Qtшный проект так же ругается (не могу сказать на что именно, в поле вывода абракадабра какая-то...)
Вопрос: Какую последовательность действий мне нужно совершить чтобы скомпилировать один из представленных в репозитории проектов создающий dll библиотеку.
PS: Если кто-то сам скомпилит и кинет ссылку на zint.dll я конечно тоже буду признателен, но всё же хотелось бы знать как это делается.


Ответ

Сборка zint с поддержкой PNG
Сборку будем производить в некотором каталоге %BUILD_ROOT%. Везде в дальнейшем разделителем каталогов должна быть прямая дробная черта (/). При использовании обратной (\) возможны ошибки сборки.
Для сборки в данном случае использовались CMake версии 3.3.2 и MinGW-builds версии 5.2.0rev0.
Сборка библиотеки zlib (использовалась версия 1.2.8).
Скачиваем архив исходников zlib и распаковываем его в каталог %BUILD_ROOT%/zlib. Далее собираем:
cd /d %BUILD_ROOT% mkdir zlib-build cd zlib-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/zlib-out ../zlib cmake --build . mingw32-make install
После этого в каталоге %BUILD_ROOT%/zlib-out будет скомпилированная библиотека zlib
Сборка библиотеки libpng (использовалась версия 1.6.19).
Скачиваем архив исходников libpng и распаковываем его в каталог %BUILD_ROOT%/libpng. Собираем:
cd /d %BUILD_ROOT% mkdir libpng-build cd libpng-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/libpng-out -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlib.dll.a -DZLIB_INCLUDE_DIR=%BUILD_ROOT%/zlib-out/include ../libpng cmake --build . mingw32-make install
Предупреждения CMake игнорируем. После этого в каталоге %BUILD_ROOT%/libpng-out будет скомпилированная библиотека libpng
Сборка библиотеки zint (использовалась версия 2.4.3).
Скачиваем архив исходников zint и распаковываем его в каталог %BUILD_ROOT%/zint. Файл CMakeLists.txt то ли не подходит для новых версий CMake, то ли в нём изначально ошибка, но в любом случае при сборке возникает ошибка, связанная с невозможностью найти файл png.h. Для исправления ошибки нужно этот файл немного подредактировать, а именно, в 14-й строке заменить ${PNG_INCLUDES} на ${PNG_INCLUDE_DIRS}. Теперь можно собирать:
cd /d %BUILD_ROOT% mkdir zint-build cd zint-build cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%BUILD_ROOT%/zint-out -DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlib.dll.a -DZLIB_INCLUDE_DIR=%BUILD_ROOT%/zlib-out/include -DPNG_LIBRARY=%BUILD_ROOT%/libpng-out/lib/libpng.dll.a -DPNG_PNG_INCLUDE_DIR=%BUILD_ROOT%/libpng-out/include ../zint cmake --build . mingw32-make install
Предупреждения при сборке игнорируем. После выполнения всех шагов в каталоге %BUILD_ROOT%/zint-out будет требуемая библиотека libzint.dll
Сборка без зависимостей.
Полученная libzint.dll имеет в зависимостях libpng16.dll, а та, в свою очередь, libzlib.dll. Кроме того, все эти библиотеки зависят от libgcc*.dll. Чтобы убрать все эти зависимости и сделать сборку (почти) полностью независимой, можно сделать следующее.
Определяем две переменных:
set CFLAGS=-static set CXXFLAGS=%CFLAGS%
Эти переменные уберут зависимость библиотек от libgcc*.dll
Чтобы убрать зависимость libpng.dll от zlib.dll, исправим один параметр при запуске cmake
-DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlibstatic.a
А чтобы убрать зависимость libzint.dll от libpng16.dll и libzlib.dll, нужно у cmake исправить два параметра:
-DZLIB_LIBRARY=%BUILD_ROOT%/zlib-out/lib/libzlibstatic.a -DPNG_LIBRARY=%BUILD_ROOT%/libpng-out/lib/libpng.a
Готово! Полученная библиотека зависит только от kernel32.dll и msvcrt.dll

суббота, 29 декабря 2018 г.

Как скрыть флаги при компиляции?

При компиляции проекта для каждого файла используется безумное количество флагов.
Как сделать, чтобы эти флаги во время компиляции не выводились на экран?
К примеру, хочу оставить только путь к компилируемому файлу и результат его компиляции. В make-файле команда для цели, как понимаю, вся выводится на экран. Проект написан на C.


Ответ

Какой бы не был makefile, но там в конечном счете должен быть вызов компилятора. Если перед этой сторокой добавить @, то эта строка не будет выводиться. Теперь перед этой строкой достаточно вставить @echo gcc $@ или что то подобное и будет "красивый вывод". Аналогично и с линковкой.

четверг, 6 декабря 2018 г.

В Linux Debian нет стандартно программы make. Как устанавливать?

Установил Linux Debian. Все стандартные программы есть, а хочу установить pindgin и ещё парочку. А там надо из исходников собирать. А там нужен make. Ввел в терминале make Вывел bash: make: команда не найдена. Скачал этот make с офф. сайта. Глянул файл INSTALL и README. Ничего не понял. Как установить этот make? Напишите пожалуйста.


Ответ

Если есть необходимость компилировать софт, то одного make может быть мало. Поэтому обычно более оптимальным является установка пакета build-essential, который содержит make в том числе. В убунте он поставит к примеру dpkg-dev (package building tools for Debian g++ (The GNU C++ compiler), gcc (The GNU C compiler), libc6-dev (GNU C Library: Development Libraries and Header Files) or libc-dev (virtual package provided by libc6-dev) и make. В Debian приблизительно тоже. Поэтому рекомендую такую последовательность sudo -s apt-get update #это желательно, если хочется все новенькое apt-get install build-essential