We’re Earthly. We make building software simpler and therefore faster. This article is about make
and Makefile
s but if you’re interested in a different approach to building software then check us out.
As the field of DevOps and build release engineering continues to grow, many new tools are being developed to help make building and releasing applications easier. One of the tools that has been in use for many years is Make, which is still heavily used by engineers today.
A Makefile is a simple text file consisting of targets, which can invoke different actions depending on what has been configured. For example, with a Makefile, you can invoke a build of your application, deploy it, or run automated tests and it can dramatically increase the efficiency of your workflow.
Initially, it was Stuart Feldman who began working on the Make utility back in 1976 at Bell Labs. However, the version of Make most commonly used today is GNU Make, which was introduced in the late 1980s.
While the tool was originally meant to run on Linux, Make’s popularity has interested those working on other operating systems as well. There are several ways to run Makefiles on Windows, and in this article you’ll be introduced to each option and learn about their strengths and weaknesses.
Using Make on Windows
Before looking at the different options available, you should know why you want to run Makefiles on Windows in the first place. Or rather, if you’re working on Windows, why are you even interested in Makefiles?
Historically, the biggest reason for wanting Makefiles to run on Windows is that the developers in your organization are working on Windows. Seeing as how the de facto standard for languages like C and C++ is to use Make, it’s no wonder that Windows users want the ability to use Make as well.
As applications and infrastructure become more modern, the cloud is another reason for wanting Makefiles on Windows. Many infrastructure engineers want their applications to be run on Linux, likely led by the adoption of tools like Docker and containerization in general. Additionally, on Linux, a Makefile is the primary tool to use in many cases, especially when it comes to building native Linux applications. However, many engineers are still using Windows on their workstations, leading to the question of how to run Makefiles on Windows. Let’s dive into the possible answers.
Chocolatey
Linux users have been using package managers for decades, yet they’ve never gained much traction on Windows. Up until the release of winget, the concept of a package manager was never something that was natively included on Windows. Instead, Rob Reynolds started working on an independent package manager back in 2011 that would come to be known as Chocolatey. Chocolatey is now widely used on Windows to install packages, and you can use it to install make
as well.
To do so, run the following command in an Administrative PowerShell window:
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
You can find the newest installation instructions at any time on the Chocolatey website.
Once Chocolatey is installed, you may have to close down the PowerShell window and open it back up. After that, run the following command:
Once the script is done running, make
will be installed. You may need to restart the PowerShell window again, but at this point you are ready to use Makefiles on Windows.
Chocolatey will likely be the most popular option for those who want to stick to a pure Windows installation. It’s easy to install, easy to use, and you don’t need to jump through any hoops or workarounds to get it working.
At this point, you can use make
just like you otherwise would, and you can test it by running make -v
.
Cygwin
Historically, one of the most popular ways of running any type of Linux functionality on Windows has been to use Cygwin. Cygwin aims to give a Linux feeling to Windows by holding a large collection of GNU and open source tools. It’s important to note that this does not mean it will give you native Linux functionality. However, it does allow you to use Linux tools on Windows. There’s a big difference between the two; for instance, Cygwin does not have access to Unix functionality like signals, PTYs, and so on. It’s a great tool for when you want to use familiar Linux commands but still want them to be run on Windows.
To use Cygwin for Makefiles, start by downloading and installing Cygwin. During the installation, you’ll see a window popping up asking you what packages you want to install. In the top left corner, make sure to select Full and then search for make
.
Your search will give you a list of several different packages. You want to choose the one that’s labeled just as make
. Change the dropdown menu where it says Skip to the latest version.
Now you can finish the installation by clicking Next in the bottom right corner. Once the installation is done, you can open up Cygwin and verify that make
has been installed by executing make --version
.
NMAKE
One of the alternatives that you’ll often hear about regarding running Makefiles on Windows is NMAKE. While it is an alternative to make
, note that you cannot simply take your existing Makefiles from Linux and run them using NMAKE; they have to be ported.
First of all, the compilers are different on Windows and Linux, so if you are specifying your compiler in your Makefile, you’ll have to change that to whatever is relevant on Windows. At the same time, you’ll have to change the flags that you send to the compiler, because Windows typically denotes the flags using /
instead of -
.
On top of that, it doesn’t recognize all the syntax that you’re used to from GNU Make, like .PHONY
. Lastly, Windows obviously doesn’t recognize the commands that work on Linux, so if you have specified any Linux-specific commands in your Makefiles, you’ll also have to port them.
All in all, if your entire organization uses Windows and you simply want the typical functionality of GNU Make, then NMAKE is a viable solution. However, if you just want to quickly run your traditional Makefiles on Windows, NMAKE is not the answer.
CMake
As with NMAKE, CMake is not a direct way to run your Makefiles on Windows. Instead, CMake is a tool to generate Makefiles, at least on Linux. It works by defining a CMakeLists.txt
file in the root directory of your application. Once you execute cmake
, it generates the files you need to build your application, no matter what operating system you’re on.
On Linux, this means that it creates Makefiles for you to run, but on Windows it may mean that it creates a Visual Studio solution.
CMake is a great solution if you don’t care too much about running Makefiles specifically, but you want the functionality, namely the ease of use in a build process, that you can get from Makefiles.
Windows Subsystem for Linux
The Windows Subsystem for Linux (WSL) is an honorable mention. It’s cheating a bit to say that it’s a way to run Makefiles “on Windows,” as your Makefiles won’t actually be running on Windows.
If you haven’t heard of WSL before, here’s an extremely oversimplified explanation: It uses Hyper-V to create a hyper-optimized virtual machine on your computer, in which it runs Linux. Basically, you get a native Linux kernel running on your Windows computer, with a terminal that feels as if it’s part of Windows.
You should look into WSL if what you care about most is having Windows as your regular desktop environment, but you’re fine with all of your programming and development going on inside of Linux.
Conclusion
As you can see, there are a few different ways you can be successful in running Makefiles on Windows. However, you do need to be wary of the fact that it will never be a perfect solution. Every solution is in some way a workaround, and the closest you’ll get to feeling like you’re using native Makefiles while using Windows is to install something like WSL.
If you are looking for a solution to avoid the complexities of Makefile, check out Earthly. Earthly takes the best ideas from Makefile and Dockerfile, and provides understandable and repeatable build scripts, minus the head-scratching parts of the Makefile.
Makefile – это специальный файл, который используется разработчиками для автоматизации процесса сборки программного обеспечения. В операционной системе Windows, создание makefile может показаться сложной задачей, особенно для новичков. Однако, с правильной инструкцией и некоторыми базовыми знаниями о makefile, это можно сделать без особых проблем.
В этой статье мы рассмотрим подробную инструкцию о том, как создать makefile в Windows. Мы познакомим вас с основными правилами, переменными и командами, которые необходимо использовать при создании makefile. Также мы рассмотрим некоторые примеры makefile, чтобы вы могли лучше понять, как применить их в своем проекте.
Важно уточнить, что для создания makefile в Windows вам понадобится установить специальный инструмент. Мы рассмотрим использование MinGW (Minimalist GNU for Windows), который включает в себя все необходимые компиляторы и утилиты для разработки в среде Microsoft Windows.
Примечание: Прежде чем приступить к созданию makefile, убедитесь, что вы имеете представление о структуре вашего проекта и какие файлы должны быть включены в процесс сборки. Это поможет вам более эффективно организовать ваш makefile.
Содержание
- Как создать makefile в Windows
- Подробная инструкция для разработчиков
- Установка компилятора
- MinGW
- Cygwin
Как создать makefile в Windows
Первым шагом для создания makefile в Windows является установка компилятора, например, MinGW или Microsoft Visual Studio. После установки компилятора необходимо добавить его путь в переменную среды PATH, чтобы команды компилятора были доступны из командной строки.
Далее необходимо создать текстовый файл с именем «makefile» или «Makefile» в корневой директории проекта. Этот файл будет содержать инструкции для компиляции программы.
Синтаксис makefile в Windows может отличаться от UNIX-подобных систем. Для компиляции программы на языке C++ в Windows можно использовать следующий пример:
CC = g++ CFLAGS = -Wall -O2 LDFLAGS = -lglfw3 -lopengl32 SRCS = main.cpp foo.cpp bar.cpp OBJS = $(SRCS:.cpp=.o) EXEC = myprogram.exe all: $(EXEC) $(EXEC): $(OBJS) $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ .cpp.o: $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJS) $(EXEC)
После создания makefile в корневой директории проекта можно запустить команду «make» для компиляции программы. При успешной компиляции будет создан исполняемый файл «myprogram.exe».
Кроме того, в makefile можно добавить цели clean для удаления временных файлов компиляции и собранного программного кода.
Теперь вы знаете, как создать makefile в Windows. Используйте этот мощный инструмент для автоматизации сборки и компиляции ваших программных проектов.
Подробная инструкция для разработчиков
Создание makefile в Windows может показаться сложной задачей, но с правильным подходом и инструкцией все становится проще. В этой статье мы рассмотрим пошаговую инструкцию, которая поможет вам создать makefile на вашем компьютере.
Шаг 1: Установка GNU Make
Первым шагом в создании makefile в Windows является установка GNU Make. Вы можете загрузить установщик GNU Make с официального сайта и следовать инструкциям по установке.
Шаг 2: Создание makefile
После установки GNU Make вам необходимо создать файл makefile. Просто откройте любой текстовый редактор, создайте новый файл и сохраните его с именем «makefile» (без расширения). Этот файл будет содержать все инструкции для GNU Make.
Шаг 3: Задание целей и зависимостей
В makefile вы должны указать цели (targets), которые нужно собрать, и их зависимости. Например, если у вас есть файлы source1.c, source2.c и main.c, и вы хотите скомпилировать их в исполняемый файл program.exe, вы должны определить следующее:
program.exe: source1.c source2.c main.c gcc -o program.exe source1.c source2.c main.c
Шаг 4: Добавление дополнительных инструкций
В makefile вы также можете добавить дополнительные инструкции, такие как настройка компилятора или определение переменных. Например, вы можете добавить следующую инструкцию для определения переменной CC (компилятор C):
CC=gcc
Вы можете использовать эту переменную в дальнейшем для задания компилятора, как в примере выше.
Шаг 5: Сборка проекта
После того, как вы создали makefile, вы можете перейти в командную строку и выполнить команду «make» в папке, где находится ваш makefile. GNU Make будет автоматически читать ваш makefile и выполнять указанные в нем инструкции. В результате будут скомпилированы все необходимые файлы и создан исполняемый файл.
Это была подробная инструкция для разработчиков о том, как создать makefile в Windows. Следуя этим шагам, вы сможете настроить сборку проекта и упростить процесс разработки.
Установка компилятора
Для создания и использования makefile в Windows вам потребуется компилятор, который будет компилировать ваш код. Ниже приведены инструкции по установке двух популярных и бесплатных компиляторов: MinGW и Cygwin.
MinGW
MinGW (Minimalist GNU for Windows) — это набор инструментов для разработки, включающий компилятор GCC. Чтобы установить MinGW, следуйте инструкциям ниже:
- Скачайте установщик MinGW с официального сайта: http://www.mingw.org/.
- Запустите установщик и следуйте его инструкциям. Рекомендуется выбрать опцию «Download latest repository catalogues» во время установки.
- Выберите компоненты, которые вы хотите установить. Наименования компонентов могут отличаться в зависимости от версии MinGW, но вам понадобится как минимум «mingw32-base» и «mingw32-gcc-g++».
- Укажите путь установки MinGW и завершите установку.
- Добавьте путь к установленному MinGW в переменную среды PATH. Для этого откройте системные переменные окружения, найдите переменную PATH и добавьте в ее значение путь к папке bin в установленном каталоге MinGW (например, C:\MinGW\bin).
Cygwin
Cygwin — это пакетное приложение, которое предоставляет большинство функций и утилит Unix на платформе Windows. Для установки Cygwin выполните следующие действия:
- Скачайте установщик Cygwin с официального сайта: https://www.cygwin.com/.
- Запустите установщик и следуйте его инструкциям.
- Выберите параметр «Install from Internet», чтобы загрузить список пакетов с серверов Cygwin.
- Выберите каталог установки и типы пакетов, которые вы хотите установить. Наименования пакетов могут отличаться в зависимости от версии Cygwin, но вам понадобятся как минимум «gcc-core» и «gcc-g++».
- Завершите установку, следуя инструкциям установщика.
После установки выбранного компилятора у вас появится возможность создавать и компилировать программы с использованием makefile в Windows.
Makefile — это текстовый файл, который содержит инструкции для сборки и компиляции программного кода. Он является важной частью процесса разработки программ, особенно в среде UNIX и UNIX-подобных операционных системах.
Однако, несмотря на то, что Windows не является UNIX-подобной операционной системой, использование makefile может значительно упростить процесс сборки проектов на Windows. В этой статье мы рассмотрим пошаговую инструкцию по созданию makefile в Windows.
Шаг 1: Установка Make и настройка переменных среды
Первым шагом необходимо установить программу Make на ваш компьютер. Вы можете скачать установочный файл с официального сайта. После установки необходимо добавить директорию, в которой находится исполняемый файл make.exe, в переменную среды PATH.
Примечание: Если вы уже установили MinGW или Cygwin, то make уже должен быть установлен на вашем компьютере. В этом случае, пропустите этот шаг.
Содержание
- Что такое makefile и зачем он нужен?
- Преимущества использования makefile
- Основные компоненты makefile
Что такое makefile и зачем он нужен?
Основная задача makefile — обновление только тех файлов, которые были изменены, что существенно сокращает время процесса сборки при изменении кода. Это особенно полезно при работе с большими проектами, в которых компиляция может занимать значительное количество времени.
Makefile содержит в себе правила, которые описывают зависимости между файлами и команды, которые нужно выполнить для сборки программы. Для каждого файла проекта makefile определяет список зависимостей (например, исходные файлы) и на основе них определяет, какие команды нужно выполнить для обновления конечного файла (например, исполняемого файла).
Вместо того чтобы выполнять все команды вручную, makefile автоматически определяет, какие файлы нужно обновить и какие команды нужно выполнить, исходя из времени последнего изменения файлов и их зависимостей.
Makefile используется во многих компилируемых языках программирования, таких как C, C++, Java и других. Он является стандартным инструментом для сборки и управления проектами в этих языках.
Использование makefile позволяет разработчику сосредоточиться на кодировании, вместо того чтобы тратить время на ручную компиляцию и сборку программы. Он также улучшает переносимость кода между различными системами и облегчает совместную работу в команде, так как все члены команды используют один и тот же makefile для сборки проекта.
Преимущества использования makefile
- Автоматизация сборки: Makefile позволяет автоматизировать процесс сборки проекта. Разработчик может определить все необходимые шаги и зависимости, а затем запустить сборку одной командой. Это позволяет сэкономить время и упростить процесс разработки.
- Удобство отслеживания изменений: Makefile позволяет определить зависимости между файлами проекта и автоматически пересобрать только те файлы, которые были изменены. Это может существенно ускорить процесс разработки и уменьшить затраты на ресурсы компьютера.
- Повторяемость сборки: Makefile позволяет легко повторить процесс сборки проекта на другом компьютере или в другой среде разработки. Это особенно полезно в командной работе, когда разработчики используют разные операционные системы или различные инструменты разработки.
- Грамотная организация проекта: Makefile позволяет организовать проект в модули и определить зависимости между ними. Это упрощает разработку, тестирование и поддержку проекта.
- Поддержка множества языков программирования: Makefile может быть использован для сборки проектов на различных языках программирования, что делает его универсальным инструментом для разработки.
В целом, использование makefile в Windows позволяет упростить и ускорить процесс разработки, а также обеспечить повторяемость и гибкость сборки проекта. Он является мощным и удобным инструментом для разработчиков, особенно при работе с проектами большого объема или в командной среде.
Основные компоненты makefile
Основные компоненты makefile:
- Цели (targets): Цель — это объект, который должен быть создан или обновлен с помощью команд make. Цель задается именем файла или именем команды. Пример: «all», «clean», «myprogram».
- Зависимости (dependencies): Зависимости — это файлы или цели, которые должны быть созданы или обновлены перед выполнением цели. Зависимости задаются после двоеточия. Пример: «main.o: main.c functions.h».
- Команды (commands): Команды — это набор инструкций, которые необходимо выполнить для создания или обновления цели. Команды должны начинаться с символа табуляции. Пример: «gcc -c main.c».
- Переменные (variables): Переменные используются для хранения значений, которые затем можно использовать в других частях makefile. Переменные определяются с помощью символа «=», а значение переменной указывается справа от символа «=». Пример: «CC = gcc».
- Директивы (directives): Директивы представляют собой специальные команды, которые указывают make на определенные действия. Некоторые распространенные директивы: «.PHONY», «.SUFFIXES», «.INCLUDE».
Makefile представляет собой текстовый файл, состоящий из этих компонентов, которые вместе определяют логику и правила сборки проекта. Когда запускается команда make, программа make читает содержимое makefile и выполняет указанные в нем команды в заданном порядке для достижения целей.
Makefile — это текстовый файл, который содержит инструкции для компиляции и сборки программного проекта. Он используется для автоматизации процесса сборки, что повышает эффективность и упрощает разработку программного обеспечения.
Оригинально makefile был разработан для Unix-like систем, но благодаря программе GNU make, он стал доступен и для Windows. Makefile состоит из набора правил, каждое из которых указывает, какой файл нужно собрать и как это сделать.
Создание makefile начинается с идентификации всех зависимостей в проекте. Затем определяются правила для каждого файла, где указывается, какой файл нужно собрать и как это сделать. Также в makefile можно указывать переменные, которые упрощают настройку процесса сборки. Когда makefile готов, достаточно ввести команду make в командной строке, чтобы начать процесс сборки по заданным правилам.
Содержание
- Как создать makefile в Windows
- Определение makefile
- Преимущества использования makefile
- Шаги по созданию makefile в Windows
Как создать makefile в Windows
Для создания makefile в Windows, следуйте инструкциям ниже:
- Установите GNU Make с официального сайта проекта.
- Создайте новый текстовый файл с расширением .mak или .make.
- Откройте файл в редакторе кода и добавьте в него нужные инструкции.
Пример простого makefile:
Цель (Target) | Зависимости (Dependencies) | Команда (Command) |
---|---|---|
main | main.o | gcc -o main main.o |
main.o | main.c | gcc -c main.c |
В приведенном примере makefile определяет две цели: main и main.o. Цель main зависит от main.o и использует команду gcc для компиляции исходника main.c и создания исполняемого файла main. Цель main.o зависит от исходника main.c и использует команду gcc для создания объектного файла main.o.
Сохраните файл и перейдите в командную строку. Перейдите к папке с вашим makefile и выполните команду make. GNU Make автоматически определит необходимые действия и выполнит их.
Теперь вы знаете, как создать makefile в Windows и автоматизировать сборку проектов. Makefile является мощным инструментом для автоматизации процесса разработки и может быть использован для упрощения сборки, тестирования и управления проектом.
Определение makefile
Makefile определяет, какие файлы и в каком порядке должны быть скомпилированы, какие опции компилятора использовать, каким образом выполнять различные задачи в процессе сборки и многое другое.
Основной концепцией makefile является правило, которое состоит из цели (target) и команд (commands). Цель представляет собой файл или задачу, которую make должен выполнить, а команды определяют действия, которые должны быть выполнены для достижения цели.
Makefile содержит также переменные, которые позволяют настроить параметры сборки, такие как пути к файлам и компилятору, параметры компилятора и линковщика и т. д.
Термин | Описание |
---|---|
Цель (target) | Файл или задача, которую make должен выполнить |
Команда (command) | Действие, которое должно быть выполнено для достижения цели |
Переменная (variable) | Параметр сборки, настраиваемый в makefile |
Makefile является основным инструментом для автоматизации сборки проектов и упрощает работу разработчика, особенно когда проект состоит из большого количества файлов и имеет много зависимостей.
Makefile позволяет выполнить сборку проекта одной командой, обрабатывает только те файлы, которые изменились с момента предыдущей сборки, и позволяет легко изменять параметры сборки без необходимости вручную изменять скрипты сборки.
Преимущества использования makefile
1. Автоматизация сборки: Makefile позволяет автоматизировать процесс сборки проекта, что позволяет существенно сэкономить время разработчиков. С помощью makefile вы можете указать зависимости между файлами и команды, которые должны быть выполнены для сборки проекта.
2. Переносимость: Makefile позволяет переносить проекты между различными операционными системами. Он работает как в UNIX-подобных системах, таких как Linux или macOS, так и в Windows. Это делает makefile универсальным инструментом для управления процессом сборки проектов.
3. Упрощение сопровождения: Makefile позволяет разделить проект на небольшие модули и задать зависимости между ними. Это делает код более понятным и упрощает сопровождение проекта в будущем. Если внесены изменения в одну из зависимостей, makefile автоматически соберет только необходимые части проекта, что снова экономит время разработчиков.
4. Переиспользование кода: Makefile позволяет разработчикам переиспользовать код и сборочные инструкции. Это особенно полезно при создании нескольких проектов, которые используют один и тот же код и зависят от одних и тех же библиотек. Makefile позволяет определить общие правила, которые могут быть использованы в различных проектах.
5. Отказоустойчивость: Makefile обеспечивает надежность и отказоустойчивость при сборке проекта. В случае возникновения ошибок, makefile может проверить состояние файлов и пересобрать только те модули, которые были изменены. Это помогает предотвратить ненужное повторение сборки и повысить эффективность процесса разработки.
В целом, использование makefile позволяет значительно упростить и ускорить процесс сборки проектов, улучшить переносимость и обеспечить надежность. Он является мощным инструментом для автоматизации разработки программного обеспечения.
Шаги по созданию makefile в Windows
- Установите GNU Make: На Windows можно использовать GNU Make для работы с makefile. Скачайте и установите GNU Make с официального сайта или с помощью пакетного менеджера, такого как Chocolatey.
- Создайте makefile: Создайте новый текстовый файл с именем «makefile» или «Makefile» в папке с вашим проектом.
- Определите цели (targets): Цель — это конечный результат сборки, например, исполняемый файл или библиотека. В makefile вы можете определить несколько целей, указав их имена и зависимости.
- Определите зависимости и команды для каждой цели: Для каждой цели определите, от каких файлов она зависит, и какие команды необходимо выполнить для ее создания. Например, для сборки исполняемого файла вы можете указать зависимости от исходных файлов и команду для компиляции и линковки.
- Определите дополнительные правила и переменные: Вы можете добавить дополнительные правила и переменные в ваш makefile, чтобы управлять процессом сборки. Например, вы можете определить переменные для выбора компилятора или опций компиляции.
- Запустите сборку с помощью make: Перейдите в командную строку, перейдите в папку с вашим проектом (где находится makefile) и выполните команду «make» или «make <имя цели>«. Make автоматически выполнит необходимые команды для сборки вашего проекта в соответствии с makefile.
Создание makefile позволит вам автоматизировать сборку проектов в Windows и повысить эффективность разработки. Используйте готовые примеры makefile и документацию GNU Make для более подробной настройки процесса сборки.
Learn Makefiles by comparison with Visual Studio
Preface
Introduction
Under the hood of Visual Studio
GNU/Linux Equivalent
Visual Studio to Make Utility mapping
Example
Source Structure
Build
Run
Makefile
Details
Targets
Dependencies
Contents
NMake
Conclusion
External Links
Preface
If you develop software only on Windows using Visual studio, it’s a luxury. Enjoy it while it lasts. Sooner than later, you will come across Makefiles, maybe exploring some software on Linux or the misfortune of having a build system that uses make
with Cygwin on Windows.
Now you figure out that Makefiles are text files and open it in an editor hoping to get some insight into its workings. But, what do you see? Lots of cryptic hard to understand syntax and expressions. So, where do you start? Internet searches for make
and Makefiles
provide a lot of information but under the assumption that you come from a non-IDE Unix/Linux development environment. Pampered Visual Studio developers are never the target audience.
Here I will try to relate to the Visual Studio build system which will hopefully give an easier understanding of Makefiles. The goal is not to provide yet another tutorial on makefiles (because there are plenty available on the internet) but to instill the concept by comparison.
Introduction
Visual Studio provides features that are taken for granted until you have to read/create a classic Makefile
. For example, Visual Studio auto-magically does the following.
- Compiles all the sources in the project file
- Create an output directory and puts all the intermediate object files in it
- Manages dependencies between the source and object files
- Manages dependencies between the object files and binaries
- Links the object files and external dependent libraries to create binaries
All of the above have to be explicitly specified in a Makefile
. The make
utility in some ways is the equivalent of Visual Studio devenv.exe
(without the fancy GUI).
Under the hood of Visual Studio
Visual Studio is essentially a GUI over the compilation and link process. It utilizes an underlying command line compiler cl.exe
and linker link.exe
. Additionally, it provides a source code editor, debugger and other development tools.
c:\tmp> cl.exe
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
c:\tmp> link.exe
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
usage: LINK [options] [files] [@commandfile]
A simple win32 console application project in Visual Studio is shown below. You have a solution
file which contains a project
file.
Invoking a build on the solution in Visual Studio calls something like the following under the hood. Yes, it looks ugly! But that is the the project properties translated to compiler/linker flags and options.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\CL.exe /c /ZI /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc100.pdb" /Gd /TP /analyze- /errorReport:prompt Test.cpp C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"c:\tmp\Test\Debug\Test.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /ManifestFile:"Debug\Test.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"c:\tmp\Test\Debug\Test.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:\tmp\Test\Debug\Test.lib" /MACHINE:X86 Debug\Test.exe.embed.manifest.res Debug\Test.obj
GNU/Linux Equivalent
It is very similar in GNU/Linux. The equivalent of a compiler and linker is gcc
, the GNU project C and C++ compiler. It does the preprocessing, compilation, assembly and linking.
$ gcc --help Usage: gcc [options] file...
Shown below is a very simple Makefile
which can be accessed from GitHub https://github.com/cognitivewaves/Simple-Makefile.
# Specify compiler CC=gcc # Specify linker LINK=gcc .PHONY : all all : app # Link the object files into a binary app : main.o $(LINK) -o app main.o -lstdc++ # Compile the source files into object files main.o : main.cpp $(CC) -c main.cpp -o main.o # Clean target .PHONY : clean clean : rm main.o app
Invoking the make
command to build will output the following.
~/src/Simple-Makefile $ make gcc -c main.cpp -o main.o gcc -o app main.o -lstdc++
Visual Studio to Make Utility mapping
Below is a table relating Visual Studio aspects to Make utility. At a high level, the Project
file is equivalent to a Makefile
.
Visual Studio | make Utility | |
---|---|---|
Command | devenv.exe |
make |
Source structure | Solution (.sln ) has project files (typically in sub-directories) |
Starting at the root, each Makefile can indicate where other Makefile s (typically in sub-directories) exist |
Library build dependency | Solution (.sln ) has projects and build order |
Makefile |
Source files list | Project (.vcproj ) |
Makefile |
Source to Object dependency | Project (.vcproj ) |
Makefile |
Compile and Link options | Project (.vcproj ) |
Makefile |
Compiler | cl.exe |
gcc, g++, c++ (or any other compiler, even cl.exe ) |
Linker | link.exe |
gcc, ld (or any other linker, even link.exe ) |
Example
Download the example sources from GitHub at https://github.com/cognitivewaves/Makefile-Example.
Note that very basic Makefile
constructs are used because the focus is on the concept and not the capabilities of make itself.
Source Structure
Makefile-Example |-- app | |-- Makefile | |-- main.cxx |-- math | |-- advanced | | |-- AdvancedFunctions.cxx | | |-- AdvancedFunctions.h | |-- simple | | |-- SimpleFunctions.cxx | | |-- SimpleFunctions.h | |-- Makefile |-- Makefile
Build
Visual Studio | make Utility |
---|---|
Building in Visual Studio is via a menu item in the IDE or invoking devenv.exe on the .sln file at the command prompt. This will automatically create the necessary directories and build only the files modified after the last build. |
Initiating a build with makefiles is to invoke the make command at the shell prompt. Creating output directories has to be explicitly done either in the Makefile or externally. |
In this example, to keep the makefiles simple, the directories are created at the shell prompt.
~/src/Makefile-Example $ mkdir -p app/bin app/obj math/bin math/obj
The make
utility syntax is shown below. See make
manual pages for details.
make [ -f makefile ] [ options ] ... [ targets ]
Execute the command make
and specify the “root” Makefile
. However, it is more common to change to directory where the “root” Makefile
exists and call make
. This will read the file named Makefile
in the current directory and call the target all
by default.
Notice how make
enters sub-directories to build. This is because of nested Makefiles
which is explained later in the Makefiles Details section.
~/src/Makefile-Example $ makemake -C math make[1]: Entering directory `/home/user/src/Makefile-Example/math' g++ -fPIC -I. -c -o obj/AdvancedFunctions.o advanced/AdvancedFunctions.cxx g++ -fPIC -I. -c -o obj/SimpleFunctions.o simple/SimpleFunctions.cxx g++ -fPIC -shared -o bin/libmath.so obj/AdvancedFunctions.o obj/SimpleFunctions.o make[1]: Leaving directory `/home/user/src/Makefile-Example/math' make -C app make[1]: Entering directory `/home/user/src/Makefile-Example/app' g++ -I../math -c -o obj/main.o main.cxx g++ obj/main.o -L../math/bin -o bin/app.exe -lmath make[1]: Leaving directory `/home/user/src/Makefile-Example/app'
Run
Once the code is built, run the executable. This is nothing specific to makefiles but has been elaborated in case you are not familiar with Linux as you will notice that by default is will fail to run with an error message.
~/src/Makefile-Example $ app/bin/app.exe 4app/bin/app.exe: error while loading shared libraries: libmath.so: cannot open shared object file: No such file or directory
This is because the executable app.exe
requires the shared object libmath.so
which is in a different directory and is not in the system path. Set LD_LIBRARY_PATH
to specify the path to it.
~/src/Makefile-Example $ export LD_LIBRARY_PATH=~/src/Makefile-Example/math/bin/ ~/src/Makefile-Example $ app/bin/app.exe 4The sum of 4 and 4 is 8 The square root of 4 is 2
Makefile Details
The basis of a Makefile
has a very simple structure.
target: dependencies [tab] system commands
The [tab]
separator is very important! Spaces instead of a [tab]
is not the same. You will see rather obscure error messages as shown below.
Makefile:12: *** missing separator. Stop.
Targets
Here target
is a physical file on disk. When the target
is more of a label, then it has to be tagged as .PHONY
to indicate that the target is not an actual file.
Visual Studio | make Utility |
---|---|
Visual Studio by default provides options to clean and rebuild a project or solution. | Clean and rebuild have to be explicitly written in a makefile as targets which can then be invoked. |
A typical case would be to clean
before rebuilding.
~/src/Makefile-Example $ make cleanmake -C math clean make[1]: Entering directory `/home/api/src/Makefile-Example/math' rm -fv bin/* obj/* removed `bin/libmath.so' removed `obj/AdvancedFunctions.o' removed `obj/SimpleFunctions.o' make[1]: Leaving directory `/home/api/src/Makefile-Example/math' make -C app clean make[1]: Entering directory `/home/api/src/Makefile-Example/app' rm -fv bin/* obj/* removed `bin/app.exe' removed `obj/main.o' make[1]: Leaving directory `/home/api/src/Makefile-Example/app'
Dependencies
Dependencies
can be files on disk or other targets (including phony targets).
Visual Studio | make Utility |
---|---|
Visual Studio by default supports implicit dependencies (source to object files) within a project. Library(project) dependencies have to specified in the solution file | Every dependency has to be explicitly defined in makefiles |
For example, the target all
, depends on app.exe
which in turn depends on libmath.so
. If you remove app.exe
, make is capable of recognizing that libmath.so
need not be built again.
~/src/Makefile-Example $ rm -v app/bin/*removed `app/bin/app.exe'
~/src/Makefile-Example $ makemake -C app make[1]: Entering directory `/home/api/src/Makefile-Example/app' g++ obj/main.o -L../math/bin -o bin/app.exe -lmath make[1]: Leaving directory `/home/api/src/Makefile-Example/app'
Contents
File: Makefile
# all is the default target .PHONY : all all : app/bin/app.exe # Invoke the Makefile in the sub-directory "app" app/bin/app.exe : math/bin/libmath.so $(MAKE) -C app # Invoke the Makefile in the sub-directory "math" math/bin/libmath.so : $(MAKE) -C math # Invoke the clean target in the "math" and "app" sub-directory Makefile .PHONY : clean clean : $(MAKE) -C math clean $(MAKE) -C app clean
File: math/Makefile
# The shared object libmath.so depends on the object files # The command is to link and create the .so if the dependencies are up to date # Note the .so is put in a sub-directory 'bin' by specifying 'g++ -o' option bin/libmath.so : obj/AdvancedFunctions.o obj/SimpleFunctions.o g++ -fPIC -shared -o bin/libmath.so obj/AdvancedFunctions.o obj/SimpleFunctions.o # The object file depends on the source # The command is to compile the .cxx to .o obj/AdvancedFunctions.o : advanced/AdvancedFunctions.cxx g++ -fPIC -I. -c -o obj/AdvancedFunctions.o advanced/AdvancedFunctions.cxx # The object file depends on the source # The command is to compile the .cxx to .o obj/SimpleFunctions.o : simple/SimpleFunctions.cxx g++ -fPIC -I. -c -o obj/SimpleFunctions.o simple/SimpleFunctions.cxx # clean target for this sub-directory Makefile .PHONY : clean clean : rm -fv bin/* obj/
File: app/Makefile
# The executable depends on the main.o object file # Generate the exe if the object file dependencies are up to date # The exe is put in a sub-directory 'bin' by specifying 'g++ -o' option bin/app.exe : obj/main.o g++ obj/main.o -L../math/bin -o bin/app.exe -lmath # The object file depends on the source # The command is to compile the .cxx to .o # The object file is put in sub-directory 'obj' by specifying 'g++ -o' option obj/main.o : main.cxx g++ -I../math -c -o obj/main.o main.cxx # clean target for this sub-directory Makefile .PHONY : clean clean : rm -fv bin/* obj/
NMake
NMake is the native Windows alternative to the *nix make utility. The syntax is very similar to *nix makefiles. However, this does not mean that *nix makefiles can be executed seamlessly on Windows. See Makefiles in Windows for a discussion.
Conclusion
Makefiles are very powerful and gives a lot of control and flexibility compared to Visual Studio, but the content is not easily understandable. As an alternative, CMake has adopted similar concepts but the script is much easier and more readable. See CMake and Visual Studio.
External Links
Makefile in detail for beginners