CINXE.COM
GitHub - clementvidon/Makefile_tutor: This project aims to create a crystal clear tutorial on a cryptic looking topic.
<!DOCTYPE html> <html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark" data-a11y-animated-images="system" data-a11y-link-underlines="true" > <head> <meta charset="utf-8"> <link rel="dns-prefetch" href="https://github.githubassets.com"> <link rel="dns-prefetch" href="https://avatars.githubusercontent.com"> <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com"> <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/"> <link rel="preconnect" href="https://github.githubassets.com" crossorigin> <link rel="preconnect" href="https://avatars.githubusercontent.com"> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-74231a1f3bbb.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-8a995f0bacd4.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-f37fb7684b1f.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-9ac301c3ebe5.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-cd826e8636dc.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-f91b0f603451.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-83beb16e0ecf.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-6e122dab64fc.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-18119e682df0.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-225433424a87.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-aaa714e5674d.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-0a3c53b9d1c2.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-ea73c9cb5377.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-4fce88777fa8.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-0210be90f4d3.css" /> <script type="application/json" id="client-env">{"locale":"en","featureFlags":["a11y_quote_reply_fix","copilot_immersive_issue_preview","copilot_new_references_ui","copilot_chat_repo_custom_instructions_preview","copilot_no_floating_button","copilot_topics_as_references","copilot_read_shared_conversation","copilot_duplicate_thread","copilot_buffered_streaming","dotcom_chat_client_side_skills","experimentation_azure_variant_endpoint","failbot_handle_non_errors","geojson_azure_maps","ghost_pilot_confidence_truncation_25","ghost_pilot_confidence_truncation_40","github_models_gateway_parse_params","github_models_o3_mini_streaming","insert_before_patch","issues_react_remove_placeholders","issues_react_blur_item_picker_on_close","marketing_pages_search_explore_provider","primer_react_css_modules_ga","react_data_router_pull_requests","remove_child_patch","sample_network_conn_type","swp_enterprise_contact_form","site_proxima_australia_update","viewscreen_sandbox","issues_react_create_milestone","issues_react_cache_fix_workaround","lifecycle_label_name_updates","copilot_task_oriented_assistive_prompts","issue_types_prevent_private_type_creation","refresh_image_video_src","react_router_dispose_on_disconnect","codespaces_prebuild_region_target_update","turbo_app_id_restore","copilot_code_review_sign_up_closed"]}</script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/wp-runtime-900d20148682.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover_js-9da652f58479.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_arianotify-polyfill_ariaNotify-polyfill_js-node_modules_github_mi-3abb8f-46b9f4874d95.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_failbot_failbot_ts-75968cfb5298.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/environment-f04cb2a9fc8c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_primer_behaviors_dist_esm_index_mjs-0dbb79f97f8f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_selector-observer_dist_index_esm_js-f690fd9ae3d5.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_relative-time-element_dist_index_js-62d275b7ddd9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_text-expander-element_dist_index_js-78748950cb0c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_auto-complete-element_dist_index_js-node_modules_github_catalyst_-8e9f78-a90ac05d2469.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-b5f1d7-a1760ffda83d.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_markdown-toolbar-element_dist_index_js-ceef33f593fa.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_primer_view-co-c44a69-efa32db3a345.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/github-elements-394f8eb34f19.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/element-registry-25113a65b77f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_braintree_browser-detection_dist_browser-detection_js-node_modules_githu-2906d7-2a07a295af40.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_lit-html_lit-html_js-be8cb88f481b.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_morphdom_dist_morphdom-e-7c534c-a4a1922eb55f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_turbo_dist_turbo_es2017-esm_js-a03ee12d659a.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-893f9f-b6294cf703b7.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_color-convert_index_js-e3180fe3bcb3.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_quote-selection_dist_index_js-node_modules_github_session-resume_-947061-e7a6c4a19f98.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_updatable-content_updatable-content_ts-eb3147a21e96.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_task-list_ts-app_assets_modules_github_sso_ts-ui_packages-900dde-768abe60b1f8.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_sticky-scroll-into-view_ts-3e000c5d31a9.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_ajax-error_ts-app_assets_modules_github_behaviors_include-87a4ae-4c160a67a3f8.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_behaviors_commenting_edit_ts-app_assets_modules_github_behaviors_ht-83c235-e429cff6ceb1.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/behaviors-1f167e0c2aee.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_delegated-events_dist_index_js-node_modules_github_catalyst_lib_index_js-f6223d90c7ba.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-global-01e85cd1be94.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_virtualized-list_es_index_js-node_modules_github_template-parts_lib_index_js-94dc7a2157c1.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-70450e-4b93df70b903.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/app_assets_modules_github_ref-selector_ts-3e9d848bab5f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/codespaces-f76fb2dd7b91.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_filter-input-element_dist_index_js-node_modules_github_remote-inp-3eebbd-0763620ad7bf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_decorators_js-node_modules_delegated-events_di-e161aa-9d41fb1b6c9e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_file-attachment-element_dist_index_js-node_modules_github_remote--3c9c82-b71ef90fbdc7.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/repositories-e6e7c7ff47a3.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_github_catalyst_lib_inde-dbbea9-26cce2010167.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/code-menu-1c0aedc134b1.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/primer-react-602097a4b0db.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-core-0bc17999cb79.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/react-lib-f1bca44e0926.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/octicons-react-cf2f2ab8dab4.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_emotion_is-prop-valid_dist_emotion-is-prop-valid_esm_js-node_modules_emo-62da9f-2df2f32ec596.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_mini-throttle_dist_index_js-node_modules_stacktrace-parser_dist_s-e7dcdd-9a233856b02c.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_oddbird_popover-polyfill_dist_popover-fn_js-55fea94174bf.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-57956eade845.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.8157a56b30ae88a1b356.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.1bcff9205c241e99cff2.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.8157a56b30ae88a1b356.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.1bcff9205c241e99cff2.module.css" /> <title>GitHub - clementvidon/Makefile_tutor: This project aims to create a crystal clear tutorial on a cryptic looking topic.</title> <meta name="route-pattern" content="/:user_id/:repository" data-turbo-transient> <meta name="route-controller" content="files" data-turbo-transient> <meta name="route-action" content="disambiguate" data-turbo-transient> <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb"> <meta name="request-id" content="BD4C:110D53:25B29FB:2E718CA:67EA2C71" data-pjax-transient="true"/><meta name="html-safe-nonce" content="1fe91ad97751ff1a53dbd4bfe8d6c20965b0c20aaeb708d12101fe6c8d64e117" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCRDRDOjExMEQ1MzoyNUIyOUZCOjJFNzE4Q0E6NjdFQTJDNzEiLCJ2aXNpdG9yX2lkIjoiNDQxODgzOTIzMTIxMTM4MzkyMSIsInJlZ2lvbl9lZGdlIjoic291dGhlYXN0YXNpYSIsInJlZ2lvbl9yZW5kZXIiOiJzb3V0aGVhc3Rhc2lhIn0=" data-pjax-transient="true"/><meta name="visitor-hmac" content="1d107e02c73372cef6eae18871b392d44a8ce52d2c847728e80cbf94231516ec" data-pjax-transient="true"/> <meta name="hovercard-subject-tag" content="repository:531583150" data-turbo-transient> <meta name="github-keyboard-shortcuts" content="repository,copilot" data-turbo-transient="true" /> <meta name="selected-link" value="repo_source" data-turbo-transient> <link rel="assets" href="https://github.githubassets.com/"> <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I"> <meta name="octolytics-url" content="https://collector.github.com/github/collect" /> <meta name="analytics-location" content="/<user-name>/<repo-name>" data-turbo-transient="true" /> <meta name="user-login" content=""> <meta name="viewport" content="width=device-width"> <meta name="description" content="This project aims to create a crystal clear tutorial on a cryptic looking topic. - clementvidon/Makefile_tutor"> <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub"> <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub"> <meta property="fb:app_id" content="1401488693436528"> <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/clementvidon/Makefile_tutor" /> <meta name="twitter:image" content="https://opengraph.githubassets.com/dd70353aba4906021a24900328ee80bd7a9933514c60e86ba8c266ba6b94ac09/clementvidon/Makefile_tutor" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="GitHub - clementvidon/Makefile_tutor: This project aims to create a crystal clear tutorial on a cryptic looking topic." /><meta name="twitter:description" content="This project aims to create a crystal clear tutorial on a cryptic looking topic. - clementvidon/Makefile_tutor" /> <meta property="og:image" content="https://opengraph.githubassets.com/dd70353aba4906021a24900328ee80bd7a9933514c60e86ba8c266ba6b94ac09/clementvidon/Makefile_tutor" /><meta property="og:image:alt" content="This project aims to create a crystal clear tutorial on a cryptic looking topic. - clementvidon/Makefile_tutor" /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="GitHub - clementvidon/Makefile_tutor: This project aims to create a crystal clear tutorial on a cryptic looking topic." /><meta property="og:url" content="https://github.com/clementvidon/Makefile_tutor" /><meta property="og:description" content="This project aims to create a crystal clear tutorial on a cryptic looking topic. - clementvidon/Makefile_tutor" /> <meta name="hostname" content="github.com"> <meta name="expected-hostname" content="github.com"> <meta http-equiv="x-pjax-version" content="154e3ed6ec9e0d6fff5da6846be55e3cefb81f7aa557cdcfe2a45d929fc158d2" data-turbo-track="reload"> <meta http-equiv="x-pjax-csp-version" content="e26f9f0ba624ee85cc7ac057d8faa8618a4f25a85eab052c33d018ac0f6b1a46" data-turbo-track="reload"> <meta http-equiv="x-pjax-css-version" content="159e03504eed5183f9787c72780a7d8c1460af30746ab09d728b048c41719efa" data-turbo-track="reload"> <meta http-equiv="x-pjax-js-version" content="3ef84064f1c111becc704df35223db168ecae977ac2d9ec422601ed98490e586" data-turbo-track="reload"> <meta name="turbo-cache-control" content="no-preview" data-turbo-transient=""> <meta data-hydrostats="publish"> <meta name="go-import" content="github.com/clementvidon/Makefile_tutor git https://github.com/clementvidon/Makefile_tutor.git"> <meta name="octolytics-dimension-user_id" content="66557702" /><meta name="octolytics-dimension-user_login" content="clementvidon" /><meta name="octolytics-dimension-repository_id" content="531583150" /><meta name="octolytics-dimension-repository_nwo" content="clementvidon/Makefile_tutor" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="531583150" /><meta name="octolytics-dimension-repository_network_root_nwo" content="clementvidon/Makefile_tutor" /> <link rel="canonical" href="https://github.com/clementvidon/Makefile_tutor" data-turbo-transient> <meta name="turbo-body-classes" content="logged-out env-production page-responsive"> <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats"> <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors"> <meta name="release" content="2be5aafe0432389fb363c998cec778d086b04b14"> <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000"> <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png"> <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon"> <meta name="theme-color" content="#1e2327"> <meta name="color-scheme" content="light dark" /> <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials"> </head> <body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;"> <div class="position-relative header-wrapper js-header-wrapper "> <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a> <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full"> <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span> </span> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ui-commands_ui-commands_ts-2ea4e93613c0.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-79d6a754ebf9.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.8157a56b30ae88a1b356.module.css" /> <react-partial partial-name="keyboard-shortcuts-dialog" data-ssr="false" data-attempted-ssr="false" > <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script> <div data-target="react-partial.reactRoot"></div> </react-partial> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_github_remote-form_dist_index_js-node_modules_delegated-events_dist_inde-94fd67-4898d1bf4b51.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/sessions-730dca81d0a2.js"></script> <header class="HeaderMktg header-logged-out js-details-container js-header Details f4 py-3" role="banner" data-is-top="true" data-color-mode=light data-light-theme=light data-dark-theme=dark> <h2 class="sr-only">Navigation Menu</h2> <button type="button" class="HeaderMktg-backdrop d-lg-none border-0 position-fixed top-0 left-0 width-full height-full js-details-target" aria-label="Toggle navigation"> <span class="d-none">Toggle navigation</span> </button> <div class="d-flex flex-column flex-lg-row flex-items-center px-3 px-md-4 px-lg-5 height-full position-relative z-1"> <div class="d-flex flex-justify-between flex-items-center width-full width-lg-auto"> <div class="flex-1"> <button aria-label="Toggle navigation" aria-expanded="false" type="button" data-view-component="true" class="js-details-target js-nav-padding-recalculate js-header-menu-toggle Button--link Button--medium Button d-lg-none color-fg-inherit p-1"> <span class="Button-content"> <span class="Button-label"><div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div> <div class="HeaderMenu-toggle-bar rounded my-1"></div></span> </span> </button> </div> <a class="mr-lg-3 color-fg-inherit flex-order-2 js-prevent-focus-on-mobile-nav" href="/" aria-label="Homepage" data-analytics-event="{"category":"Marketing nav","action":"click to go to homepage","label":"ref_page:Marketing;ref_cta:Logomark;ref_loc:Header"}"> <svg height="32" aria-hidden="true" viewBox="0 0 24 24" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12 1C5.9225 1 1 5.9225 1 12C1 16.8675 4.14875 20.9787 8.52125 22.4362C9.07125 22.5325 9.2775 22.2025 9.2775 21.9137C9.2775 21.6525 9.26375 20.7862 9.26375 19.865C6.5 20.3737 5.785 19.1912 5.565 18.5725C5.44125 18.2562 4.905 17.28 4.4375 17.0187C4.0525 16.8125 3.5025 16.3037 4.42375 16.29C5.29 16.2762 5.90875 17.0875 6.115 17.4175C7.105 19.0812 8.68625 18.6137 9.31875 18.325C9.415 17.61 9.70375 17.1287 10.02 16.8537C7.5725 16.5787 5.015 15.63 5.015 11.4225C5.015 10.2262 5.44125 9.23625 6.1425 8.46625C6.0325 8.19125 5.6475 7.06375 6.2525 5.55125C6.2525 5.55125 7.17375 5.2625 9.2775 6.67875C10.1575 6.43125 11.0925 6.3075 12.0275 6.3075C12.9625 6.3075 13.8975 6.43125 14.7775 6.67875C16.8813 5.24875 17.8025 5.55125 17.8025 5.55125C18.4075 7.06375 18.0225 8.19125 17.9125 8.46625C18.6138 9.23625 19.04 10.2125 19.04 11.4225C19.04 15.6437 16.4688 16.5787 14.0213 16.8537C14.42 17.1975 14.7638 17.8575 14.7638 18.8887C14.7638 20.36 14.75 21.5425 14.75 21.9137C14.75 22.2025 14.9563 22.5462 15.5063 22.4362C19.8513 20.9787 23 16.8537 23 12C23 5.9225 18.0775 1 12 1Z"></path> </svg> </a> <div class="flex-1 flex-order-2 text-right"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor" class="HeaderMenu-link HeaderMenu-button d-inline-flex d-lg-none flex-order-1 f5 no-underline border color-border-default rounded-2 px-2 py-1 color-fg-inherit js-prevent-focus-on-mobile-nav" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"site header menu","repository_id":null,"auth_type":"SIGN_UP","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="0646d4e8dbe2bcf00581e1e6d80cf5c4428cf4f78ddb7599db173a7270f757f5" data-analytics-event="{"category":"Marketing nav","action":"click to Sign in","label":"ref_page:Marketing;ref_cta:Sign in;ref_loc:Header"}" > Sign in </a> </div> </div> <div class="HeaderMenu js-header-menu height-fit position-lg-relative d-lg-flex flex-column flex-auto top-0"> <div class="HeaderMenu-wrapper d-flex flex-column flex-self-start flex-lg-row flex-auto rounded rounded-lg-0"> <nav class="HeaderMenu-nav" aria-label="Global"> <ul class="d-lg-flex list-style-none"> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Product <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"github_copilot","context":"product","tag":"link","label":"github_copilot_link_product_navbar"}" href="https://github.com/features/copilot"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">GitHub Copilot</div> Write better code with AI </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"security","context":"product","tag":"link","label":"security_link_product_navbar"}" href="https://github.com/features/security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Security</div> Find and fix vulnerabilities </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"actions","context":"product","tag":"link","label":"actions_link_product_navbar"}" href="https://github.com/features/actions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-workflow color-fg-subtle mr-3"> <path d="M1 3a2 2 0 0 1 2-2h6.5a2 2 0 0 1 2 2v6.5a2 2 0 0 1-2 2H7v4.063C7 16.355 7.644 17 8.438 17H12.5v-2.5a2 2 0 0 1 2-2H21a2 2 0 0 1 2 2V21a2 2 0 0 1-2 2h-6.5a2 2 0 0 1-2-2v-2.5H8.437A2.939 2.939 0 0 1 5.5 15.562V11.5H3a2 2 0 0 1-2-2Zm2-.5a.5.5 0 0 0-.5.5v6.5a.5.5 0 0 0 .5.5h6.5a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5ZM14.5 14a.5.5 0 0 0-.5.5V21a.5.5 0 0 0 .5.5H21a.5.5 0 0 0 .5-.5v-6.5a.5.5 0 0 0-.5-.5Z"></path> </svg> <div> <div class="color-fg-default h4">Actions</div> Automate any workflow </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"codespaces","context":"product","tag":"link","label":"codespaces_link_product_navbar"}" href="https://github.com/features/codespaces"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-codespaces color-fg-subtle mr-3"> <path d="M3.5 3.75C3.5 2.784 4.284 2 5.25 2h13.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 18.75 13H5.25a1.75 1.75 0 0 1-1.75-1.75Zm-2 12c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v4a1.75 1.75 0 0 1-1.75 1.75H3.25a1.75 1.75 0 0 1-1.75-1.75ZM5.25 3.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h13.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Zm-2 12a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h17.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25Z"></path><path d="M10 17.75a.75.75 0 0 1 .75-.75h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> <div> <div class="color-fg-default h4">Codespaces</div> Instant dev environments </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"issues","context":"product","tag":"link","label":"issues_link_product_navbar"}" href="https://github.com/features/issues"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-issue-opened color-fg-subtle mr-3"> <path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Zm9.5 2a2 2 0 1 1-.001-3.999A2 2 0 0 1 12 14Z"></path> </svg> <div> <div class="color-fg-default h4">Issues</div> Plan and track work </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"code_review","context":"product","tag":"link","label":"code_review_link_product_navbar"}" href="https://github.com/features/code-review"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-review color-fg-subtle mr-3"> <path d="M10.3 6.74a.75.75 0 0 1-.04 1.06l-2.908 2.7 2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M1.5 4.25c0-.966.784-1.75 1.75-1.75h17.5c.966 0 1.75.784 1.75 1.75v12.5a1.75 1.75 0 0 1-1.75 1.75h-9.69l-3.573 3.573A1.458 1.458 0 0 1 5 21.043V18.5H3.25a1.75 1.75 0 0 1-1.75-1.75ZM3.25 4a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h2.5a.75.75 0 0 1 .75.75v3.19l3.72-3.72a.749.749 0 0 1 .53-.22h10a.25.25 0 0 0 .25-.25V4.25a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Review</div> Manage code changes </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"discussions","context":"product","tag":"link","label":"discussions_link_product_navbar"}" href="https://github.com/features/discussions"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Discussions</div> Collaborate outside of code </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{"location":"navbar","action":"code_search","context":"product","tag":"link","label":"code_search_link_product_navbar"}" href="https://github.com/features/code-search"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-code-square color-fg-subtle mr-3"> <path d="M10.3 8.24a.75.75 0 0 1-.04 1.06L7.352 12l2.908 2.7a.75.75 0 1 1-1.02 1.1l-3.5-3.25a.75.75 0 0 1 0-1.1l3.5-3.25a.75.75 0 0 1 1.06.04Zm3.44 1.06a.75.75 0 1 1 1.02-1.1l3.5 3.25a.75.75 0 0 1 0 1.1l-3.5 3.25a.75.75 0 1 1-1.02-1.1l2.908-2.7-2.908-2.7Z"></path><path d="M2 3.75C2 2.784 2.784 2 3.75 2h16.5c.966 0 1.75.784 1.75 1.75v16.5A1.75 1.75 0 0 1 20.25 22H3.75A1.75 1.75 0 0 1 2 20.25Zm1.75-.25a.25.25 0 0 0-.25.25v16.5c0 .138.112.25.25.25h16.5a.25.25 0 0 0 .25-.25V3.75a.25.25 0 0 0-.25-.25Z"></path> </svg> <div> <div class="color-fg-default h4">Code Search</div> Find more, search less </div> </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="product-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="product-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"all_features","context":"product","tag":"link","label":"all_features_link_product_navbar"}" href="https://github.com/features"> All features </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"documentation","context":"product","tag":"link","label":"documentation_link_product_navbar"}" href="https://docs.github.com"> Documentation <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"github_skills","context":"product","tag":"link","label":"github_skills_link_product_navbar"}" href="https://skills.github.com"> GitHub Skills <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"blog","context":"product","tag":"link","label":"blog_link_product_navbar"}" href="https://github.blog"> Blog <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Solutions <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 pb-lg-3 mb-3 mb-lg-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-company-size-heading">By company size</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-company-size-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"enterprises","context":"solutions","tag":"link","label":"enterprises_link_solutions_navbar"}" href="https://github.com/enterprise"> Enterprises </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"small_and_medium_teams","context":"solutions","tag":"link","label":"small_and_medium_teams_link_solutions_navbar"}" href="https://github.com/team"> Small and medium teams </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"startups","context":"solutions","tag":"link","label":"startups_link_solutions_navbar"}" href="https://github.com/enterprise/startups"> Startups </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"nonprofits","context":"solutions","tag":"link","label":"nonprofits_link_solutions_navbar"}" href="/solutions/industry/nonprofits"> Nonprofits </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-use-case-heading">By use case</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-use-case-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"devsecops","context":"solutions","tag":"link","label":"devsecops_link_solutions_navbar"}" href="/solutions/use-case/devsecops"> DevSecOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"devops","context":"solutions","tag":"link","label":"devops_link_solutions_navbar"}" href="/solutions/use-case/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"ci_cd","context":"solutions","tag":"link","label":"ci_cd_link_solutions_navbar"}" href="/solutions/use-case/ci-cd"> CI/CD </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"view_all_use_cases","context":"solutions","tag":"link","label":"view_all_use_cases_link_solutions_navbar"}" href="/solutions/use-case"> View all use cases </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="solutions-by-industry-heading">By industry</span> <ul class="list-style-none f5" aria-labelledby="solutions-by-industry-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"healthcare","context":"solutions","tag":"link","label":"healthcare_link_solutions_navbar"}" href="/solutions/industry/healthcare"> Healthcare </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"financial_services","context":"solutions","tag":"link","label":"financial_services_link_solutions_navbar"}" href="/solutions/industry/financial-services"> Financial services </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"manufacturing","context":"solutions","tag":"link","label":"manufacturing_link_solutions_navbar"}" href="/solutions/industry/manufacturing"> Manufacturing </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"government","context":"solutions","tag":"link","label":"government_link_solutions_navbar"}" href="/solutions/industry/government"> Government </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"view_all_industries","context":"solutions","tag":"link","label":"view_all_industries_link_solutions_navbar"}" href="/solutions/industry"> View all industries </a></li> </ul> </div> </div> <div class="HeaderMenu-trailing-link rounded-bottom-2 flex-shrink-0 mt-lg-4 px-lg-4 py-4 py-lg-3 f5 text-semibold"> <a href="/solutions"> View all solutions <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-right HeaderMenu-trailing-link-icon"> <path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"></path> </svg> </a> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Resources <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 d-lg-flex flex-wrap dropdown-menu-wide"> <div class="HeaderMenu-column px-lg-4 border-lg-right mb-4 mb-lg-0 pr-lg-7"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-topics-heading">Topics</span> <ul class="list-style-none f5" aria-labelledby="resources-topics-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"ai","context":"resources","tag":"link","label":"ai_link_resources_navbar"}" href="/resources/articles/ai"> AI </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"devops","context":"resources","tag":"link","label":"devops_link_resources_navbar"}" href="/resources/articles/devops"> DevOps </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"security","context":"resources","tag":"link","label":"security_link_resources_navbar"}" href="/resources/articles/security"> Security </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"software_development","context":"resources","tag":"link","label":"software_development_link_resources_navbar"}" href="/resources/articles/software-development"> Software Development </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"view_all","context":"resources","tag":"link","label":"view_all_link_resources_navbar"}" href="/resources/articles"> View all </a></li> </ul> </div> </div> <div class="HeaderMenu-column px-lg-4"> <div class="border-bottom pb-3 pb-lg-0 border-lg-bottom-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="resources-explore-heading">Explore</span> <ul class="list-style-none f5" aria-labelledby="resources-explore-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"learning_pathways","context":"resources","tag":"link","label":"learning_pathways_link_resources_navbar"}" href="https://resources.github.com/learn/pathways"> Learning Pathways <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"events_amp_webinars","context":"resources","tag":"link","label":"events_amp_webinars_link_resources_navbar"}" href="https://resources.github.com"> Events & Webinars <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"ebooks_amp_whitepapers","context":"resources","tag":"link","label":"ebooks_amp_whitepapers_link_resources_navbar"}" href="https://github.com/resources/whitepapers"> Ebooks & Whitepapers </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"customer_stories","context":"resources","tag":"link","label":"customer_stories_link_resources_navbar"}" href="https://github.com/customer-stories"> Customer Stories </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary Link--external" target="_blank" data-analytics-event="{"location":"navbar","action":"partners","context":"resources","tag":"link","label":"partners_link_resources_navbar"}" href="https://partner.github.com"> Partners <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link-external HeaderMenu-external-icon color-fg-subtle"> <path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path> </svg> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"executive_insights","context":"resources","tag":"link","label":"executive_insights_link_resources_navbar"}" href="https://github.com/solutions/executive-insights"> Executive Insights </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Open Source <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{"location":"navbar","action":"github_sponsors","context":"open_source","tag":"link","label":"github_sponsors_link_open_source_navbar"}" href="/sponsors"> <div> <div class="color-fg-default h4">GitHub Sponsors</div> Fund open source developers </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{"location":"navbar","action":"the_readme_project","context":"open_source","tag":"link","label":"the_readme_project_link_open_source_navbar"}" href="https://github.com/readme"> <div> <div class="color-fg-default h4">The ReadME Project</div> GitHub community articles </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="open-source-repositories-heading">Repositories</span> <ul class="list-style-none f5" aria-labelledby="open-source-repositories-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"topics","context":"open_source","tag":"link","label":"topics_link_open_source_navbar"}" href="https://github.com/topics"> Topics </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"trending","context":"open_source","tag":"link","label":"trending_link_open_source_navbar"}" href="https://github.com/trending"> Trending </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary" data-analytics-event="{"location":"navbar","action":"collections","context":"open_source","tag":"link","label":"collections_link_open_source_navbar"}" href="https://github.com/collections"> Collections </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <button type="button" class="HeaderMenu-link border-0 width-full width-lg-auto px-0 px-lg-2 py-lg-2 no-wrap d-flex flex-items-center flex-justify-between js-details-target" aria-expanded="false"> Enterprise <svg opacity="0.5" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-chevron-down HeaderMenu-icon ml-1"> <path d="M12.78 5.22a.749.749 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.06 0L3.22 6.28a.749.749 0 1 1 1.06-1.06L8 8.939l3.72-3.719a.749.749 0 0 1 1.06 0Z"></path> </svg> </button> <div class="HeaderMenu-dropdown dropdown-menu rounded m-0 p-0 pt-2 pt-lg-4 position-relative position-lg-absolute left-0 left-lg-n3 pb-2 pb-lg-4 px-lg-4"> <div class="HeaderMenu-column"> <div class="border-bottom pb-3 pb-lg-0 pb-lg-3 mb-3 mb-lg-0 mb-lg-3"> <ul class="list-style-none f5" > <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{"location":"navbar","action":"enterprise_platform","context":"enterprise","tag":"link","label":"enterprise_platform_link_enterprise_navbar"}" href="/enterprise"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-stack color-fg-subtle mr-3"> <path d="M11.063 1.456a1.749 1.749 0 0 1 1.874 0l8.383 5.316a1.751 1.751 0 0 1 0 2.956l-8.383 5.316a1.749 1.749 0 0 1-1.874 0L2.68 9.728a1.751 1.751 0 0 1 0-2.956Zm1.071 1.267a.25.25 0 0 0-.268 0L3.483 8.039a.25.25 0 0 0 0 .422l8.383 5.316a.25.25 0 0 0 .268 0l8.383-5.316a.25.25 0 0 0 0-.422Z"></path><path d="M1.867 12.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path><path d="M1.867 16.324a.75.75 0 0 1 1.035-.232l8.964 5.685a.25.25 0 0 0 .268 0l8.964-5.685a.75.75 0 0 1 .804 1.267l-8.965 5.685a1.749 1.749 0 0 1-1.874 0l-8.965-5.685a.75.75 0 0 1-.231-1.035Z"></path> </svg> <div> <div class="color-fg-default h4">Enterprise platform</div> AI-powered developer platform </div> </a></li> </ul> </div> <div class="border-bottom pb-3 pb-lg-0 border-bottom-0"> <span class="d-block h4 color-fg-default my-1" id="enterprise-available-add-ons-heading">Available add-ons</span> <ul class="list-style-none f5" aria-labelledby="enterprise-available-add-ons-heading"> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"advanced_security","context":"enterprise","tag":"link","label":"advanced_security_link_enterprise_navbar"}" href="https://github.com/enterprise/advanced-security"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-shield-check color-fg-subtle mr-3"> <path d="M16.53 9.78a.75.75 0 0 0-1.06-1.06L11 13.19l-1.97-1.97a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5-5Z"></path><path d="m12.54.637 8.25 2.675A1.75 1.75 0 0 1 22 4.976V10c0 6.19-3.771 10.704-9.401 12.83a1.704 1.704 0 0 1-1.198 0C5.77 20.705 2 16.19 2 10V4.976c0-.758.489-1.43 1.21-1.664L11.46.637a1.748 1.748 0 0 1 1.08 0Zm-.617 1.426-8.25 2.676a.249.249 0 0 0-.173.237V10c0 5.46 3.28 9.483 8.43 11.426a.199.199 0 0 0 .14 0C17.22 19.483 20.5 15.461 20.5 10V4.976a.25.25 0 0 0-.173-.237l-8.25-2.676a.253.253 0 0 0-.154 0Z"></path> </svg> <div> <div class="color-fg-default h4">Advanced Security</div> Enterprise-grade security features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description pb-lg-3" data-analytics-event="{"location":"navbar","action":"copilot_for_business","context":"enterprise","tag":"link","label":"copilot_for_business_link_enterprise_navbar"}" href="/features/copilot/copilot-business"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-copilot color-fg-subtle mr-3"> <path d="M23.922 16.992c-.861 1.495-5.859 5.023-11.922 5.023-6.063 0-11.061-3.528-11.922-5.023A.641.641 0 0 1 0 16.736v-2.869a.841.841 0 0 1 .053-.22c.372-.935 1.347-2.292 2.605-2.656.167-.429.414-1.055.644-1.517a10.195 10.195 0 0 1-.052-1.086c0-1.331.282-2.499 1.132-3.368.397-.406.89-.717 1.474-.952 1.399-1.136 3.392-2.093 6.122-2.093 2.731 0 4.767.957 6.166 2.093.584.235 1.077.546 1.474.952.85.869 1.132 2.037 1.132 3.368 0 .368-.014.733-.052 1.086.23.462.477 1.088.644 1.517 1.258.364 2.233 1.721 2.605 2.656a.832.832 0 0 1 .053.22v2.869a.641.641 0 0 1-.078.256ZM12.172 11h-.344a4.323 4.323 0 0 1-.355.508C10.703 12.455 9.555 13 7.965 13c-1.725 0-2.989-.359-3.782-1.259a2.005 2.005 0 0 1-.085-.104L4 11.741v6.585c1.435.779 4.514 2.179 8 2.179 3.486 0 6.565-1.4 8-2.179v-6.585l-.098-.104s-.033.045-.085.104c-.793.9-2.057 1.259-3.782 1.259-1.59 0-2.738-.545-3.508-1.492a4.323 4.323 0 0 1-.355-.508h-.016.016Zm.641-2.935c.136 1.057.403 1.913.878 2.497.442.544 1.134.938 2.344.938 1.573 0 2.292-.337 2.657-.751.384-.435.558-1.15.558-2.361 0-1.14-.243-1.847-.705-2.319-.477-.488-1.319-.862-2.824-1.025-1.487-.161-2.192.138-2.533.529-.269.307-.437.808-.438 1.578v.021c0 .265.021.562.063.893Zm-1.626 0c.042-.331.063-.628.063-.894v-.02c-.001-.77-.169-1.271-.438-1.578-.341-.391-1.046-.69-2.533-.529-1.505.163-2.347.537-2.824 1.025-.462.472-.705 1.179-.705 2.319 0 1.211.175 1.926.558 2.361.365.414 1.084.751 2.657.751 1.21 0 1.902-.394 2.344-.938.475-.584.742-1.44.878-2.497Z"></path><path d="M14.5 14.25a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Zm-5 0a1 1 0 0 1 1 1v2a1 1 0 0 1-2 0v-2a1 1 0 0 1 1-1Z"></path> </svg> <div> <div class="color-fg-default h4">Copilot for business</div> Enterprise-grade AI features </div> </a></li> <li> <a class="HeaderMenu-dropdown-link d-block no-underline position-relative py-2 Link--secondary d-flex flex-items-center Link--has-description" data-analytics-event="{"location":"navbar","action":"premium_support","context":"enterprise","tag":"link","label":"premium_support_link_enterprise_navbar"}" href="/premium-support"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-comment-discussion color-fg-subtle mr-3"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 14.25 14H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 15.543V14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 1.784.784 1 1.75 1ZM1.5 2.75v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Z"></path><path d="M22.5 8.75a.25.25 0 0 0-.25-.25h-3.5a.75.75 0 0 1 0-1.5h3.5c.966 0 1.75.784 1.75 1.75v9.5A1.75 1.75 0 0 1 22.25 20H21v1.543a1.457 1.457 0 0 1-2.487 1.03L15.939 20H10.75A1.75 1.75 0 0 1 9 18.25v-1.465a.75.75 0 0 1 1.5 0v1.465c0 .138.112.25.25.25h5.5a.75.75 0 0 1 .53.22l2.72 2.72v-2.19a.75.75 0 0 1 .75-.75h2a.25.25 0 0 0 .25-.25v-9.5Z"></path> </svg> <div> <div class="color-fg-default h4">Premium Support</div> Enterprise-grade 24/7 support </div> </a></li> </ul> </div> </div> </div> </li> <li class="HeaderMenu-item position-relative flex-wrap flex-justify-between flex-items-center d-block d-lg-flex flex-lg-nowrap flex-lg-items-center js-details-container js-header-menu-item"> <a class="HeaderMenu-link no-underline px-0 px-lg-2 py-3 py-lg-2 d-block d-lg-inline-block" data-analytics-event="{"location":"navbar","action":"pricing","context":"global","tag":"link","label":"pricing_link_global_navbar"}" href="https://github.com/pricing">Pricing</a> </li> </ul> </nav> <div class="d-flex flex-column flex-lg-row width-full flex-justify-end flex-lg-items-center text-center mt-3 mt-lg-0 text-lg-left ml-lg-3"> <qbsearch-input class="search-input" data-scope="repo:clementvidon/Makefile_tutor" data-custom-scopes-path="/search/custom_scopes" data-delete-custom-scopes-csrf="vCT48ZetnGoFAE_1Kaey-SjWLdaUSmO6yE8sS9Gi9XhORypY-iiCw3fQvusJ-cbYABjoa-XywQKpml2VwUIGUg" data-max-custom-scopes="10" data-header-redesign-enabled="false" data-initial-value="" data-blackbird-suggestions-path="/search/suggestions" data-jump-to-suggestions-path="/_graphql/GetSuggestedNavigationDestinations" data-current-repository="clementvidon/Makefile_tutor" data-current-org="" data-current-owner="clementvidon" data-logged-in="false" data-copilot-chat-enabled="false" data-nl-search-enabled="false" data-retain-scroll-position="true"> <div class="search-input-container search-with-dialog position-relative d-flex flex-row flex-items-center mr-4 rounded" data-action="click:qbsearch-input#searchInputContainerClicked" > <button type="button" class="header-search-button placeholder input-button form-control d-flex flex-1 flex-self-stretch flex-items-center no-wrap width-full py-0 pl-2 pr-0 text-left border-0 box-shadow-none" data-target="qbsearch-input.inputButton" aria-label="Search or jump to…" aria-haspopup="dialog" placeholder="Search or jump to..." data-hotkey=s,/ autocapitalize="off" data-analytics-event="{"location":"navbar","action":"searchbar","context":"global","tag":"input","label":"searchbar_input_global_navbar"}" data-action="click:qbsearch-input#handleExpand" > <div class="mr-2 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </div> <span class="flex-1" data-target="qbsearch-input.inputButtonText">Search or jump to...</span> <div class="d-flex" data-target="qbsearch-input.hotkeyIndicator"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="20" aria-hidden="true" class="mr-1"><path fill="none" stroke="#979A9C" opacity=".4" d="M3.5.5h12c1.7 0 3 1.3 3 3v13c0 1.7-1.3 3-3 3h-12c-1.7 0-3-1.3-3-3v-13c0-1.7 1.3-3 3-3z"></path><path fill="#979A9C" d="M11.8 6L8 15.1h-.9L10.8 6h1z"></path></svg> </div> </button> <input type="hidden" name="type" class="js-site-search-type-field"> <div class="Overlay--hidden " data-modal-dialog-overlay> <modal-dialog data-action="close:qbsearch-input#handleClose cancel:qbsearch-input#handleClose" data-target="qbsearch-input.searchSuggestionsDialog" role="dialog" id="search-suggestions-dialog" aria-modal="true" aria-labelledby="search-suggestions-dialog-header" data-view-component="true" class="Overlay Overlay--width-large Overlay--height-auto"> <h1 id="search-suggestions-dialog-header" class="sr-only">Search code, repositories, users, issues, pull requests...</h1> <div class="Overlay-body Overlay-body--paddingNone"> <div data-view-component="true"> <div class="search-suggestions position-fixed width-full color-shadow-large border color-fg-default color-bg-default overflow-hidden d-flex flex-column query-builder-container" style="border-radius: 12px;" data-target="qbsearch-input.queryBuilderContainer" hidden > <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="query-builder-test-form" action="" accept-charset="UTF-8" method="get"> <query-builder data-target="qbsearch-input.queryBuilder" id="query-builder-query-builder-test" data-filter-key=":" data-view-component="true" class="QueryBuilder search-query-builder"> <div class="FormControl FormControl--fullWidth"> <label id="query-builder-test-label" for="query-builder-test" class="FormControl-label sr-only"> Search </label> <div class="QueryBuilder-StyledInput width-fit " data-target="query-builder.styledInput" > <span id="query-builder-test-leadingvisual-wrap" class="FormControl-input-leadingVisualWrap QueryBuilder-leadingVisualWrap"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search FormControl-input-leadingVisual"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </span> <div data-target="query-builder.styledInputContainer" class="QueryBuilder-StyledInputContainer"> <div aria-hidden="true" class="QueryBuilder-StyledInputContent" data-target="query-builder.styledInputContent" ></div> <div class="QueryBuilder-InputWrapper"> <div aria-hidden="true" class="QueryBuilder-Sizer" data-target="query-builder.sizer"></div> <input id="query-builder-test" name="query-builder-test" value="" autocomplete="off" type="text" role="combobox" spellcheck="false" aria-expanded="false" aria-describedby="validation-a84c3f34-f237-4b5d-9180-4af5edb912b5" data-target="query-builder.input" data-action=" input:query-builder#inputChange blur:query-builder#inputBlur keydown:query-builder#inputKeydown focus:query-builder#inputFocus " data-view-component="true" class="FormControl-input QueryBuilder-Input FormControl-medium" /> </div> </div> <span class="sr-only" id="query-builder-test-clear">Clear</span> <button role="button" id="query-builder-test-clear-button" aria-labelledby="query-builder-test-clear query-builder-test-label" data-target="query-builder.clearButton" data-action=" click:query-builder#clear focus:query-builder#clearButtonFocus blur:query-builder#clearButtonBlur " variant="small" hidden="hidden" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium mr-1 px-2 py-0 d-flex flex-items-center rounded-1 color-fg-muted"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x-circle-fill Button-visual"> <path d="M2.343 13.657A8 8 0 1 1 13.658 2.343 8 8 0 0 1 2.343 13.657ZM6.03 4.97a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042L6.94 8 4.97 9.97a.749.749 0 0 0 .326 1.275.749.749 0 0 0 .734-.215L8 9.06l1.97 1.97a.749.749 0 0 0 1.275-.326.749.749 0 0 0-.215-.734L9.06 8l1.97-1.97a.749.749 0 0 0-.326-1.275.749.749 0 0 0-.734.215L8 6.94Z"></path> </svg> </button> </div> <template id="search-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-search"> <path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path> </svg> </template> <template id="code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="file-code-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-file-code"> <path d="M4 1.75C4 .784 4.784 0 5.75 0h5.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v8.586A1.75 1.75 0 0 1 14.25 15h-9a.75.75 0 0 1 0-1.5h9a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 10 4.25V1.5H5.75a.25.25 0 0 0-.25.25v2.5a.75.75 0 0 1-1.5 0Zm1.72 4.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734l1.47-1.47-1.47-1.47a.75.75 0 0 1 0-1.06ZM3.28 7.78 1.81 9.25l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Zm8.22-6.218V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path> </svg> </template> <template id="history-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-history"> <path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path> </svg> </template> <template id="repo-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> </template> <template id="bookmark-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bookmark"> <path d="M3 2.75C3 1.784 3.784 1 4.75 1h6.5c.966 0 1.75.784 1.75 1.75v11.5a.75.75 0 0 1-1.227.579L8 11.722l-3.773 3.107A.751.751 0 0 1 3 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.91l3.023-2.489a.75.75 0 0 1 .954 0l3.023 2.49V2.75a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="plus-circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-plus-circle"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm7.25-3.25v2.5h2.5a.75.75 0 0 1 0 1.5h-2.5v2.5a.75.75 0 0 1-1.5 0v-2.5h-2.5a.75.75 0 0 1 0-1.5h2.5v-2.5a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="circle-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill"> <path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path> </svg> </template> <template id="trash-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-trash"> <path d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75ZM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15ZM6.5 1.75V3h3V1.75a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25Z"></path> </svg> </template> <template id="team-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-people"> <path d="M2 5.5a3.5 3.5 0 1 1 5.898 2.549 5.508 5.508 0 0 1 3.034 4.084.75.75 0 1 1-1.482.235 4 4 0 0 0-7.9 0 .75.75 0 0 1-1.482-.236A5.507 5.507 0 0 1 3.102 8.05 3.493 3.493 0 0 1 2 5.5ZM11 4a3.001 3.001 0 0 1 2.22 5.018 5.01 5.01 0 0 1 2.56 3.012.749.749 0 0 1-.885.954.752.752 0 0 1-.549-.514 3.507 3.507 0 0 0-2.522-2.372.75.75 0 0 1-.574-.73v-.352a.75.75 0 0 1 .416-.672A1.5 1.5 0 0 0 11 5.5.75.75 0 0 1 11 4Zm-5.5-.5a2 2 0 1 0-.001 3.999A2 2 0 0 0 5.5 3.5Z"></path> </svg> </template> <template id="project-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-project"> <path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25ZM11.75 3a.75.75 0 0 1 .75.75v7.5a.75.75 0 0 1-1.5 0v-7.5a.75.75 0 0 1 .75-.75Zm-8.25.75a.75.75 0 0 1 1.5 0v5.5a.75.75 0 0 1-1.5 0ZM8 3a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 3Z"></path> </svg> </template> <template id="pencil-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pencil"> <path d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z"></path> </svg> </template> <template id="copilot-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot"> <path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path> </svg> </template> <template id="copilot-error-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copilot-error"> <path d="M16 11.24c0 .112-.072.274-.21.467L13 9.688V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-.198 0-.388-.009-.571-.029L6.833 5.226a4.01 4.01 0 0 0 .17-.782c.117-.935-.037-1.395-.241-1.614-.193-.206-.637-.413-1.682-.297-.683.076-1.115.231-1.395.415l-1.257-.91c.579-.564 1.413-.877 2.485-.996 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095Zm-5.083-8.707c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Zm2.511 11.074c-1.393.776-3.272 1.428-5.43 1.428-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.18-.455-.241-.963-.252-1.475L.31 4.107A.747.747 0 0 1 0 3.509V3.49a.748.748 0 0 1 .625-.73c.156-.026.306.047.435.139l14.667 10.578a.592.592 0 0 1 .227.264.752.752 0 0 1 .046.249v.022a.75.75 0 0 1-1.19.596Zm-1.367-.991L5.635 7.964a5.128 5.128 0 0 1-.889.073c-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433 1.539 0 3.089-.505 4.063-.934Z"></path> </svg> </template> <template id="workflow-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-workflow"> <path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="book-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book"> <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path> </svg> </template> <template id="code-review-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-review"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 13H8.061l-2.574 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25v-8.5C0 1.784.784 1 1.75 1ZM1.5 2.75v8.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-8.5a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm5.28 1.72a.75.75 0 0 1 0 1.06L5.31 7l1.47 1.47a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018l-2-2a.75.75 0 0 1 0-1.06l2-2a.75.75 0 0 1 1.06 0Zm2.44 0a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.69 7 9.22 5.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </template> <template id="codespaces-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-codespaces"> <path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path> </svg> </template> <template id="comment-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment"> <path d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> </template> <template id="comment-discussion-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-comment-discussion"> <path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path> </svg> </template> <template id="organization-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-organization"> <path d="M1.75 16A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 0 0 .25-.25V8.285a.25.25 0 0 0-.111-.208l-1.055-.703a.749.749 0 1 1 .832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0 1 14.25 16h-3.5a.766.766 0 0 1-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 0 1-.75-.75V14h-1v1.25a.75.75 0 0 1-.75.75Zm-.25-1.75c0 .138.112.25.25.25H4v-1.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 .75.75v1.25h2.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM3.75 6h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 3.75A.75.75 0 0 1 3.75 3h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 3.75Zm4 3A.75.75 0 0 1 7.75 6h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 7 6.75ZM7.75 3h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5ZM3 9.75A.75.75 0 0 1 3.75 9h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 9.75ZM7.75 9h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="rocket-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-rocket"> <path d="M14.064 0h.186C15.216 0 16 .784 16 1.75v.186a8.752 8.752 0 0 1-2.564 6.186l-.458.459c-.314.314-.641.616-.979.904v3.207c0 .608-.315 1.172-.833 1.49l-2.774 1.707a.749.749 0 0 1-1.11-.418l-.954-3.102a1.214 1.214 0 0 1-.145-.125L3.754 9.816a1.218 1.218 0 0 1-.124-.145L.528 8.717a.749.749 0 0 1-.418-1.11l1.71-2.774A1.748 1.748 0 0 1 3.31 4h3.204c.288-.338.59-.665.904-.979l.459-.458A8.749 8.749 0 0 1 14.064 0ZM8.938 3.623h-.002l-.458.458c-.76.76-1.437 1.598-2.02 2.5l-1.5 2.317 2.143 2.143 2.317-1.5c.902-.583 1.74-1.26 2.499-2.02l.459-.458a7.25 7.25 0 0 0 2.123-5.127V1.75a.25.25 0 0 0-.25-.25h-.186a7.249 7.249 0 0 0-5.125 2.123ZM3.56 14.56c-.732.732-2.334 1.045-3.005 1.148a.234.234 0 0 1-.201-.064.234.234 0 0 1-.064-.201c.103-.671.416-2.273 1.15-3.003a1.502 1.502 0 1 1 2.12 2.12Zm6.94-3.935c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 0 0 .119-.213ZM3.678 8.116 5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 0 0-.213.119l-1.2 1.95ZM12 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </template> <template id="shield-check-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield-check"> <path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="heart-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-heart"> <path d="m8 14.25.345.666a.75.75 0 0 1-.69 0l-.008-.004-.018-.01a7.152 7.152 0 0 1-.31-.17 22.055 22.055 0 0 1-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.066 22.066 0 0 1-3.744 2.584l-.018.01-.006.003h-.002ZM4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.58 20.58 0 0 0 8 13.393a20.58 20.58 0 0 0 3.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.749.749 0 0 1-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5Z"></path> </svg> </template> <template id="server-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-server"> <path d="M1.75 1h12.5c.966 0 1.75.784 1.75 1.75v4c0 .372-.116.717-.314 1 .198.283.314.628.314 1v4a1.75 1.75 0 0 1-1.75 1.75H1.75A1.75 1.75 0 0 1 0 12.75v-4c0-.358.109-.707.314-1a1.739 1.739 0 0 1-.314-1v-4C0 1.784.784 1 1.75 1ZM1.5 2.75v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25Zm.25 5.75a.25.25 0 0 0-.25.25v4c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-4a.25.25 0 0 0-.25-.25ZM7 4.75A.75.75 0 0 1 7.75 4h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 7 4.75ZM7.75 10h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM3 4.75A.75.75 0 0 1 3.75 4h.5a.75.75 0 0 1 0 1.5h-.5A.75.75 0 0 1 3 4.75ZM3.75 10h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1 0-1.5Z"></path> </svg> </template> <template id="globe-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-globe"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM5.78 8.75a9.64 9.64 0 0 0 1.363 4.177c.255.426.542.832.857 1.215.245-.296.551-.705.857-1.215A9.64 9.64 0 0 0 10.22 8.75Zm4.44-1.5a9.64 9.64 0 0 0-1.363-4.177c-.307-.51-.612-.919-.857-1.215a9.927 9.927 0 0 0-.857 1.215A9.64 9.64 0 0 0 5.78 7.25Zm-5.944 1.5H1.543a6.507 6.507 0 0 0 4.666 5.5c-.123-.181-.24-.365-.352-.552-.715-1.192-1.437-2.874-1.581-4.948Zm-2.733-1.5h2.733c.144-2.074.866-3.756 1.58-4.948.12-.197.237-.381.353-.552a6.507 6.507 0 0 0-4.666 5.5Zm10.181 1.5c-.144 2.074-.866 3.756-1.58 4.948-.12.197-.237.381-.353.552a6.507 6.507 0 0 0 4.666-5.5Zm2.733-1.5a6.507 6.507 0 0 0-4.666-5.5c.123.181.24.365.353.552.714 1.192 1.436 2.874 1.58 4.948Z"></path> </svg> </template> <template id="issue-opened-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </template> <template id="device-mobile-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-mobile"> <path d="M3.75 0h8.5C13.216 0 14 .784 14 1.75v12.5A1.75 1.75 0 0 1 12.25 16h-8.5A1.75 1.75 0 0 1 2 14.25V1.75C2 .784 2.784 0 3.75 0ZM3.5 1.75v12.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25ZM8 13a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path> </svg> </template> <template id="package-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-package"> <path d="m8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.201.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432Zm6.25 8.271 4.625-2.683a.25.25 0 0 0 .125-.216V5.677L8.75 8.432Z"></path> </svg> </template> <template id="credit-card-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-credit-card"> <path d="M10.75 9a.75.75 0 0 0 0 1.5h1.5a.75.75 0 0 0 0-1.5h-1.5Z"></path><path d="M0 3.75C0 2.784.784 2 1.75 2h12.5c.966 0 1.75.784 1.75 1.75v8.5A1.75 1.75 0 0 1 14.25 14H1.75A1.75 1.75 0 0 1 0 12.25ZM14.5 6.5h-13v5.75c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25Zm0-2.75a.25.25 0 0 0-.25-.25H1.75a.25.25 0 0 0-.25.25V5h13Z"></path> </svg> </template> <template id="play-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </template> <template id="gift-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-gift"> <path d="M2 2.75A2.75 2.75 0 0 1 4.75 0c.983 0 1.873.42 2.57 1.232.268.318.497.668.68 1.042.183-.375.411-.725.68-1.044C9.376.42 10.266 0 11.25 0a2.75 2.75 0 0 1 2.45 4h.55c.966 0 1.75.784 1.75 1.75v2c0 .698-.409 1.301-1 1.582v4.918A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25V9.332C.409 9.05 0 8.448 0 7.75v-2C0 4.784.784 4 1.75 4h.55c-.192-.375-.3-.8-.3-1.25ZM7.25 9.5H2.5v4.75c0 .138.112.25.25.25h4.5Zm1.5 0v5h4.5a.25.25 0 0 0 .25-.25V9.5Zm0-4V8h5.5a.25.25 0 0 0 .25-.25v-2a.25.25 0 0 0-.25-.25Zm-7 0a.25.25 0 0 0-.25.25v2c0 .138.112.25.25.25h5.5V5.5h-5.5Zm3-4a1.25 1.25 0 0 0 0 2.5h2.309c-.233-.818-.542-1.401-.878-1.793-.43-.502-.915-.707-1.431-.707ZM8.941 4h2.309a1.25 1.25 0 0 0 0-2.5c-.516 0-1 .205-1.43.707-.337.392-.646.975-.879 1.793Z"></path> </svg> </template> <template id="code-square-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code-square"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </template> <template id="device-desktop-icon"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-device-desktop"> <path d="M14.25 1c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 14.25 12h-3.727c.099 1.041.52 1.872 1.292 2.757A.752.752 0 0 1 11.25 16h-6.5a.75.75 0 0 1-.565-1.243c.772-.885 1.192-1.716 1.292-2.757H1.75A1.75 1.75 0 0 1 0 10.25v-7.5C0 1.784.784 1 1.75 1ZM1.75 2.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25ZM9.018 12H6.982a5.72 5.72 0 0 1-.765 2.5h3.566a5.72 5.72 0 0 1-.765-2.5Z"></path> </svg> </template> <div class="position-relative"> <ul role="listbox" class="ActionListWrap QueryBuilder-ListWrap" aria-label="Suggestions" data-action=" combobox-commit:query-builder#comboboxCommit mousedown:query-builder#resultsMousedown " data-target="query-builder.resultsList" data-persist-list=false id="query-builder-test-results" ></ul> </div> <div class="FormControl-inlineValidation" id="validation-a84c3f34-f237-4b5d-9180-4af5edb912b5" hidden="hidden"> <span class="FormControl-inlineValidation--visual"> <svg aria-hidden="true" height="12" viewBox="0 0 12 12" version="1.1" width="12" data-view-component="true" class="octicon octicon-alert-fill"> <path d="M4.855.708c.5-.896 1.79-.896 2.29 0l4.675 8.351a1.312 1.312 0 0 1-1.146 1.954H1.33A1.313 1.313 0 0 1 .183 9.058ZM7 7V3H5v4Zm-1 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"></path> </svg> </span> <span></span> </div> </div> <div data-target="query-builder.screenReaderFeedback" aria-live="polite" aria-atomic="true" class="sr-only"></div> </query-builder></form> <div class="d-flex flex-row color-fg-muted px-3 text-small color-bg-default search-feedback-prompt"> <a target="_blank" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax" data-view-component="true" class="Link color-fg-accent text-normal ml-2">Search syntax tips</a> <div class="d-flex flex-1"></div> </div> </div> </div> </div> </modal-dialog></div> </div> <div data-action="click:qbsearch-input#retract" class="dark-backdrop position-fixed" hidden data-target="qbsearch-input.darkBackdrop"></div> <div class="color-fg-default"> <dialog-helper> <dialog data-target="qbsearch-input.feedbackDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="feedback-dialog" aria-modal="true" aria-labelledby="feedback-dialog-title" aria-describedby="feedback-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="feedback-dialog-title"> Provide feedback </h1> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="feedback-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="feedback-dialog-title"> <div data-view-component="true" class="Overlay-body"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="code-search-feedback-form" data-turbo="false" action="/search/feedback" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="MCbsiuelCXZE7ahtid0uC//Tv8P42szBUTqFRjMo41rzKY0M/3Uy6r+3UiavPLuDWK62KZl8alj4L5P2zXYW9A==" /> <p>We read every piece of feedback, and take your input very seriously.</p> <textarea name="feedback" class="form-control width-full mb-2" style="height: 120px" id="feedback"></textarea> <input name="include_email" id="include_email" aria-label="Include my email address so I can be contacted" class="form-control mr-2" type="checkbox"> <label for="include_email" style="font-weight: normal">Include my email address so I can be contacted</label> </form></div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd"> <button data-close-dialog-id="feedback-dialog" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="code-search-feedback-form" data-action="click:qbsearch-input#submitFeedback" type="submit" data-view-component="true" class="btn-primary btn"> Submit feedback </button> </div> </dialog></dialog-helper> <custom-scopes data-target="qbsearch-input.customScopesManager"> <dialog-helper> <dialog data-target="custom-scopes.customScopesModalDialog" data-action="close:qbsearch-input#handleDialogClose cancel:qbsearch-input#handleDialogClose" id="custom-scopes-dialog" aria-modal="true" aria-labelledby="custom-scopes-dialog-title" aria-describedby="custom-scopes-dialog-description" data-view-component="true" class="Overlay Overlay-whenNarrow Overlay--size-medium Overlay--motion-scaleFade Overlay--disableScroll"> <div data-view-component="true" class="Overlay-header Overlay-header--divided"> <div class="Overlay-headerContentWrap"> <div class="Overlay-titleWrap"> <h1 class="Overlay-title " id="custom-scopes-dialog-title"> Saved searches </h1> <h2 id="custom-scopes-dialog-description" class="Overlay-description">Use saved searches to filter your results more quickly</h2> </div> <div class="Overlay-actionWrap"> <button data-close-dialog-id="custom-scopes-dialog" aria-label="Close" type="button" data-view-component="true" class="close-button Overlay-closeButton"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg></button> </div> </div> </div> <scrollable-region data-labelled-by="custom-scopes-dialog-title"> <div data-view-component="true" class="Overlay-body"> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <div hidden class="create-custom-scope-form" data-target="custom-scopes.createCustomScopeForm"> <!-- '"` --><!-- </textarea></xmp> --></option></form><form id="custom-scopes-dialog-form" data-turbo="false" action="/search/custom_scopes" accept-charset="UTF-8" method="post"><input type="hidden" data-csrf="true" name="authenticity_token" value="W/fQqJj9Ef3zZedCk5gPLN9/I0PmnK0LPl/K97poIxUdWb/94Vw7Mzlp2ZjF7QKxw+pT+lvACbXPcDzUxVDWmQ==" /> <div data-target="custom-scopes.customScopesModalDialogFlash"></div> <input type="hidden" id="custom_scope_id" name="custom_scope_id" data-target="custom-scopes.customScopesIdField"> <div class="form-group"> <label for="custom_scope_name">Name</label> <auto-check src="/search/custom_scopes/check_name" required only-validate-on-blur="false"> <input type="text" name="custom_scope_name" id="custom_scope_name" data-target="custom-scopes.customScopesNameField" class="form-control" autocomplete="off" placeholder="github-ruby" required maxlength="50"> <input type="hidden" data-csrf="true" value="mC0Ao/5zfr5wxZJshEOcaA1FLGvONb2LZm7e3u8E1V57jRx9MU9opAlvb1+GDGvXWiCK/5X67cqFQGpXIgn8sw==" /> </auto-check> </div> <div class="form-group"> <label for="custom_scope_query">Query</label> <input type="text" name="custom_scope_query" id="custom_scope_query" data-target="custom-scopes.customScopesQueryField" class="form-control" autocomplete="off" placeholder="(repo:mona/a OR repo:mona/b) AND lang:python" required maxlength="500"> </div> <p class="text-small color-fg-muted"> To see all available qualifiers, see our <a class="Link--inTextBlock" href="https://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax">documentation</a>. </p> </form> </div> <div data-target="custom-scopes.manageCustomScopesForm"> <div data-target="custom-scopes.list"></div> </div> </div> </scrollable-region> <div data-view-component="true" class="Overlay-footer Overlay-footer--alignEnd Overlay-footer--divided"> <button data-action="click:custom-scopes#customScopesCancel" type="button" data-view-component="true" class="btn"> Cancel </button> <button form="custom-scopes-dialog-form" data-action="click:custom-scopes#customScopesSubmit" data-target="custom-scopes.customScopesSubmitButton" type="submit" data-view-component="true" class="btn-primary btn"> Create saved search </button> </div> </dialog></dialog-helper> </custom-scopes> </div> </qbsearch-input> <div class="position-relative HeaderMenu-link-wrap d-lg-inline-block"> <a href="/login?return_to=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor" class="HeaderMenu-link HeaderMenu-link--sign-in HeaderMenu-button flex-shrink-0 no-underline d-none d-lg-inline-flex border border-lg-0 rounded rounded-lg-0 px-2 py-1" style="margin-left: 12px;" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"site header menu","repository_id":null,"auth_type":"SIGN_UP","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="0646d4e8dbe2bcf00581e1e6d80cf5c4428cf4f78ddb7599db173a7270f757f5" data-analytics-event="{"category":"Marketing nav","action":"click to go to homepage","label":"ref_page:Marketing;ref_cta:Sign in;ref_loc:Header"}" > Sign in </a> </div> <a href="/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E&source=header-repo&source_repo=clementvidon%2FMakefile_tutor" class="HeaderMenu-link HeaderMenu-link--sign-up HeaderMenu-button flex-shrink-0 d-flex d-lg-inline-flex no-underline border color-border-default rounded px-2 py-1" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"site header menu","repository_id":null,"auth_type":"SIGN_UP","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="0646d4e8dbe2bcf00581e1e6d80cf5c4428cf4f78ddb7599db173a7270f757f5" data-analytics-event="{"category":"Sign up","action":"click to sign up for account","label":"ref_page:/<user-name>/<repo-name>;ref_cta:Sign up;ref_loc:header logged out"}" > Sign up </a> <button type="button" class="sr-only js-header-menu-focus-trap d-block d-lg-none">Reseting focus</button> </div> </div> </div> </div> </header> <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span> <button id="icon-button-cd7ba0ec-2976-4148-9685-caa84fcb9cb6" aria-labelledby="tooltip-a5ef725b-65e9-49c0-83e1-c9cdca266270" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button><tool-tip id="tooltip-a5ef725b-65e9-49c0-83e1-c9cdca266270" for="icon-button-cd7ba0ec-2976-4148-9685-caa84fcb9cb6" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip> </div> </div> <div id="start-of-content" class="show-on-focus"></div> <div id="js-flash-container" class="flash-container" data-turbo-replace> <template class="js-flash-template"> <div class="flash flash-full {{ className }}"> <div > <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div aria-atomic="true" role="alert" class="js-flash-alert"> <div>{{ message }}</div> </div> </div> </div> </template> </div> <div class="application-main " data-commit-hovercards-enabled data-discussion-hovercards-enabled data-issue-and-pr-hovercards-enabled data-project-hovercards-enabled > <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class=""> <main id="js-repo-pjax-container" > <div id="repository-container-header" class="pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace> <div class="d-flex flex-nowrap flex-justify-end mb-3 px-3 px-lg-5" style="gap: 1rem;"> <div class="flex-auto min-width-0 width-fit"> <div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2"> <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path> </svg> <span class="author flex-self-stretch" itemprop="author"> <a class="url fn" rel="author" data-hovercard-type="user" data-hovercard-url="/users/clementvidon/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/clementvidon"> clementvidon </a> </span> <span class="mx-1 flex-self-stretch color-fg-muted">/</span> <strong itemprop="name" class="mr-2 flex-self-stretch"> <a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/clementvidon/Makefile_tutor">Makefile_tutor</a> </strong> <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span> </div> </div> <div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;"> <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;"> <li> <a href="/login?return_to=%2Fclementvidon%2FMakefile_tutor" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"notification subscription menu watch","repository_id":null,"auth_type":"LOG_IN","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="b19bb82b04cbea206e6ed8910e61e79075358f90ad2a227217418a2d166628d8" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2"> <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path> </svg>Notifications </a> <tool-tip id="tooltip-9b9577f7-a17e-4455-b50a-0a6e7a195662" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip> </li> <li> <a icon="repo-forked" id="fork-button" href="/login?return_to=%2Fclementvidon%2FMakefile_tutor" rel="nofollow" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"repo details fork button","repository_id":531583150,"auth_type":"LOG_IN","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="11c43623fc748c9b555026e0507f3c625006308d9773283ef39d01372f69a714" data-view-component="true" class="btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2"> <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path> </svg>Fork <span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="30" data-view-component="true" class="Counter">30</span> </a> </li> <li> <div data-view-component="true" class="BtnGroup d-flex"> <a href="/login?return_to=%2Fclementvidon%2FMakefile_tutor" rel="nofollow" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"star button","repository_id":531583150,"auth_type":"LOG_IN","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="fe5c9d4c160fa7c3ab7dc23879d93c220b8aa3a0baabfbccd2bcac465afae9dd" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg><span data-view-component="true" class="d-inline"> Star </span> <span id="repo-stars-counter-star" aria-label="626 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="626" data-view-component="true" class="Counter js-social-count">626</span> </a></div> </li> </ul> </div> </div> <div id="responsive-meta-container" data-turbo-replace> <div class="d-block d-md-none mb-2 px-3 px-md-4 px-lg-5"> <p class="f4 mb-3 "> This project aims to create a crystal clear tutorial on a cryptic looking topic. </p> <div class="mb-2 d-flex flex-items-center Link--secondary"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link flex-shrink-0 mr-2"> <path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path> </svg> <span class="flex-auto min-width-0 css-truncate css-truncate-target width-fit"> <a title="https://clemedon.github.io/Makefile_tutor/" role="link" target="_blank" class="text-bold" rel="noopener noreferrer" href="https://clemedon.github.io/Makefile_tutor/">clemedon.github.io/Makefile_tutor/</a> </span> </div> <h3 class="sr-only">License</h3> <div class="mb-2"> <a href="/clementvidon/Makefile_tutor/blob/main/LICENCE" class="Link--muted" data-analytics-event="{"category":"Repository Overview","action":"click","label":"location:sidebar;file:license"}" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-law mr-2"> <path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path> </svg> CC-BY-SA-4.0 license </a> </div> <div class="mb-3"> <a class="Link--secondary no-underline mr-3" href="/clementvidon/Makefile_tutor/stargazers"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star mr-1"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg> <span class="text-bold">626</span> stars </a> <a class="Link--secondary no-underline mr-3" href="/clementvidon/Makefile_tutor/forks"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-1"> <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path> </svg> <span class="text-bold">30</span> forks </a> <a class="Link--secondary no-underline mr-3 d-inline-block" href="/clementvidon/Makefile_tutor/branches"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-branch mr-1"> <path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path> </svg> <span>Branches</span> </a> <a class="Link--secondary no-underline d-inline-block" href="/clementvidon/Makefile_tutor/tags"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-tag mr-1"> <path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path> </svg> <span>Tags</span> </a> <a class="Link--secondary no-underline d-inline-block" href="/clementvidon/Makefile_tutor/activity"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pulse mr-1"> <path d="M6 2c.306 0 .582.187.696.471L10 10.731l1.304-3.26A.751.751 0 0 1 12 7h3.25a.75.75 0 0 1 0 1.5h-2.742l-1.812 4.528a.751.751 0 0 1-1.392 0L6 4.77 4.696 8.03A.75.75 0 0 1 4 8.5H.75a.75.75 0 0 1 0-1.5h2.742l1.812-4.529A.751.751 0 0 1 6 2Z"></path> </svg> <span>Activity</span> </a> </div> <div class="d-flex flex-wrap gap-2"> <div class="flex-1"> <div data-view-component="true" class="BtnGroup d-flex"> <a href="/login?return_to=%2Fclementvidon%2FMakefile_tutor" rel="nofollow" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"star button","repository_id":531583150,"auth_type":"LOG_IN","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="fe5c9d4c160fa7c3ab7dc23879d93c220b8aa3a0baabfbccd2bcac465afae9dd" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn btn-block"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg><span data-view-component="true" class="d-inline"> Star </span> </a></div> </div> <div class="flex-1"> <a href="/login?return_to=%2Fclementvidon%2FMakefile_tutor" rel="nofollow" id="files-overview-watch-button" data-hydro-click="{"event_type":"authentication.click","payload":{"location_in_page":"notification subscription menu watch","repository_id":null,"auth_type":"LOG_IN","originating_url":"https://github.com/clementvidon/Makefile_tutor","user_id":null}}" data-hydro-click-hmac="b19bb82b04cbea206e6ed8910e61e79075358f90ad2a227217418a2d166628d8" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn btn-block"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2"> <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path> </svg>Notifications </a> <tool-tip id="tooltip-36fd0b7b-99fe-4190-88d6-eaf9a235a57a" for="files-overview-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip> </div> <span> </span> </div> </div> </div> <nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 px-md-4 px-lg-5"> <ul data-view-component="true" class="UnderlineNav-body list-style-none"> <li data-view-component="true" class="d-inline-flex"> <a id="code-tab" href="/clementvidon/Makefile_tutor" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /clementvidon/Makefile_tutor" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Code","target":"UNDERLINE_NAV.TAB"}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> <span data-content="Code">Code</span> <span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="issues-tab" href="/clementvidon/Makefile_tutor/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /clementvidon/Makefile_tutor/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Issues","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> <span data-content="Issues">Issues</span> <span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="pull-requests-tab" href="/clementvidon/Makefile_tutor/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /clementvidon/Makefile_tutor/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Pull requests","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> <span data-content="Pull requests">Pull requests</span> <span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="actions-tab" href="/clementvidon/Makefile_tutor/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /clementvidon/Makefile_tutor/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Actions","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> <span data-content="Actions">Actions</span> <span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="projects-tab" href="/clementvidon/Makefile_tutor/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /clementvidon/Makefile_tutor/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Projects","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> <span data-content="Projects">Projects</span> <span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="security-tab" href="/clementvidon/Makefile_tutor/security" data-tab-item="i5security-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /clementvidon/Makefile_tutor/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Security","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <span data-content="Security">Security</span> <include-fragment src="/clementvidon/Makefile_tutor/security/overall-count" accept="text/fragment+html"></include-fragment> </a></li> <li data-view-component="true" class="d-inline-flex"> <a id="insights-tab" href="/clementvidon/Makefile_tutor/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /clementvidon/Makefile_tutor/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-analytics-event="{"category":"Underline navbar","action":"Click tab","label":"Insights","target":"UNDERLINE_NAV.TAB"}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> <span data-content="Insights">Insights</span> <span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span> </a></li> </ul> <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 pr-md-4 pr-lg-5 right-0"> <action-menu data-select-variant="none" data-view-component="true"> <focus-group direction="vertical" mnemonics retain> <button id="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-button" popovertarget="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-overlay" aria-controls="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-list" aria-haspopup="true" aria-labelledby="tooltip-968b6d4c-a23c-43fa-97a0-0dcee92b9fe3" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual"> <path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path> </svg> </button><tool-tip id="tooltip-968b6d4c-a23c-43fa-97a0-0dcee92b9fe3" for="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip> <anchored-position data-target="action-menu.overlay" id="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-overlay" anchor="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true"> <div data-view-component="true" class="Overlay Overlay--size-auto"> <div data-view-component="true" class="Overlay-body Overlay-body--paddingNone"> <action-list> <div data-view-component="true"> <ul aria-labelledby="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-button" id="action-menu-0ea28554-f8f0-4f38-9f64-79dda8ddf798-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap"> <li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-36def080-9e96-45ba-97ce-0a9c3ea4a240" href="/clementvidon/Makefile_tutor" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code"> <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Code </span> </a> </li> <li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-eeaff826-2d36-4315-adef-603d03d8b991" href="/clementvidon/Makefile_tutor/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened"> <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Issues </span> </a> </li> <li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-5e7f5122-5865-4377-b6f9-b169d5ecd7d6" href="/clementvidon/Makefile_tutor/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request"> <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Pull requests </span> </a> </li> <li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-c3adc1b9-0475-4787-b8ed-de57806fd7bc" href="/clementvidon/Makefile_tutor/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play"> <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Actions </span> </a> </li> <li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-e6890193-c2b7-4294-b120-b618fda14f67" href="/clementvidon/Makefile_tutor/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table"> <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Projects </span> </a> </li> <li hidden="hidden" data-menu-item="i5security-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-bb44971a-dbe2-4aca-9420-cd90505aaaef" href="/clementvidon/Makefile_tutor/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield"> <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Security </span> </a> </li> <li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem"> <a tabindex="-1" id="item-b1aa305b-6360-4187-b1b3-b1357a250239" href="/clementvidon/Makefile_tutor/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16"> <span class="ActionListItem-visual ActionListItem-visual--leading"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph"> <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path> </svg> </span> <span data-view-component="true" class="ActionListItem-label"> Insights </span> </a> </li> </ul> </div></action-list> </div> </div></anchored-position> </focus-group> </action-menu></div> </nav> </div> <turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class=""> <div id="repo-content-pjax-container" class="repository-content " > <h1 class='sr-only'>clementvidon/Makefile_tutor</h1> <div class="clearfix container-xl px-md-4 px-lg-5 px-3"> <div> <div style="max-width: 100%" data-view-component="true" class="Layout Layout--flowRow-until-md react-repos-overview-margin Layout--sidebarPosition-end Layout--sidebarPosition-flowRow-end"> <div data-view-component="true" class="Layout-main"> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_dompurify_dist_purify_es_mjs-dd1d3ea6a436.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/vendors-node_modules_tanstack_query-core_build_modern_queryObserver_js-node_modules_tanstack_-defd52-843b41414e0e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_aria-live_aria-live_ts-ui_packages_history_history_ts-ui_packages_promise-with-re-01dc80-134579ff449f.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_paths_index_ts-3adbcf6faa83.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_ref-selector_RefSelector_tsx-7496afc3784d.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_commit-attribution_index_ts-ui_packages_commit-checks-status_index_ts-ui_packages-7094d4-b869a469ca5e.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_hydro-analytics_hydro-analytics_ts-ui_packages_verified-fetch_verified-fetch_ts-u-4672d1-96a19eaeffb7.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/ui_packages_code-view-shared_hooks_use-canonical-object_ts-ui_packages_code-view-shared_hooks-d63960-3a5579c864b4.js"></script> <script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/repos-overview-fa360a7b1b46.js"></script> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react.8157a56b30ae88a1b356.module.css" /> <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repos-overview.0ee7cac3ab511a65d9f9.module.css" /> <react-partial partial-name="repos-overview" data-ssr="true" data-attempted-ssr="true" > <script type="application/json" data-target="react-partial.embeddedData">{"props":{"initialPayload":{"allShortcutsEnabled":false,"path":"/","repo":{"id":531583150,"defaultBranch":"main","name":"Makefile_tutor","ownerLogin":"clementvidon","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2022-09-01T15:41:14.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/66557702?v=4","public":true,"private":false,"isOrgOwned":false},"currentUser":null,"refInfo":{"name":"main","listCacheKey":"v0:1662046875.2492118","canEdit":false,"refType":"branch","currentOid":"52668fa87a1e3f4ff247e6af811bd7b4519c6753"},"tree":{"items":[{"name":"projects","path":"projects","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"LICENCE","path":"LICENCE","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"}],"templateDirectorySuggestionUrl":null,"readme":null,"totalCount":4,"showBranchInfobar":false},"fileTree":null,"fileTreeProcessingTime":null,"foldersToFetch":[],"treeExpanded":false,"symbolsExpanded":false,"isOverview":true,"overview":{"banners":{"shouldRecommendReadme":false,"isPersonalRepo":false,"showUseActionBanner":false,"actionSlug":null,"actionId":null,"showProtectBranchBanner":false,"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_repo","releasePath":"/clementvidon/Makefile_tutor/releases/new?marketplace=true","showPublishActionBanner":false},"interactionLimitBanner":null,"showInvitationBanner":false,"inviterName":null,"actionsMigrationBannerInfo":{"releaseTags":[],"showImmutableActionsMigrationBanner":false,"initialMigrationStatus":null}},"codeButton":{"contactPath":"/contact","isEnterprise":false,"local":{"protocolInfo":{"httpAvailable":true,"sshAvailable":null,"httpUrl":"https://github.com/clementvidon/Makefile_tutor.git","showCloneWarning":null,"sshUrl":null,"sshCertificatesRequired":null,"sshCertificatesAvailable":null,"ghCliUrl":"gh repo clone clementvidon/Makefile_tutor","defaultProtocol":"http","newSshKeyUrl":"/settings/ssh/new","setProtocolPath":"/users/set_protocol"},"platformInfo":{"cloneUrl":"https://desktop.github.com","showVisualStudioCloneButton":false,"visualStudioCloneUrl":"https://windows.github.com","showXcodeCloneButton":false,"xcodeCloneUrl":"xcode://clone?repo=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor","zipballUrl":"/clementvidon/Makefile_tutor/archive/refs/heads/main.zip"}},"newCodespacePath":"/codespaces/new?hide_repo_select=true\u0026repo=531583150"},"popovers":{"rename":null,"renamedParentRepo":null},"commitCount":"140","overviewFiles":[{"displayName":"README.md","repoName":"Makefile_tutor","refName":"main","path":"README.md","preferredFileType":"readme","tabName":"README","richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 align=\"center\" tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\n MAKEFILE TUTOR (GNU)\n\u003c/h1\u003e\u003ca id=\"user-content-----makefile-tutor-gnu\" class=\"anchor\" aria-label=\"Permalink: \n MAKEFILE TUTOR (GNU)\n\" href=\"#----makefile-tutor-gnu\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 align=\"center\" tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\n \u003ca href=\"#summary\"\u003eSummary\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#glossary\"\u003eGlossary\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#syntax\"\u003eSyntax\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#index\"\u003eIndex\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#sources\"\u003eSources\u003c/a\u003e\n \u003cspan\u003e · \u003c/span\u003e\n \u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\n\u003c/h3\u003e\u003ca id=\"user-content-----summary----------usage----------glossary----------syntax----------index----------sources----------contact\" class=\"anchor\" aria-label=\"Permalink: Summary · Usage · Glossary · Syntax · Index · Sources · Contact\" href=\"#----summary----------usage----------glossary----------syntax----------index----------sources----------contact\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSummary\u003c/h1\u003e\u003ca id=\"user-content-summary\" class=\"anchor\" aria-label=\"Permalink: Summary\" href=\"#summary\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAddressed to beginners and not to newcomers, the idea behind this tutorial is to\n\u003cstrong\u003efocus on the essential\u003c/strong\u003e. Anything that is not directly related to the\ntemplate we are going to explore will not be covered here. On the other hand\neverything that is covered in this tutorial will be carefully detailed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eInitially intended to help 42 students to step up their Makefile skills through\n\u003cstrong\u003ea C-focused documented template\u003c/strong\u003e that evolves gradually, \u003cstrong\u003eversion by\nversion\u003c/strong\u003e. With the aim of making them more digestible and even tasty 🍔\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAllow \u003cstrong\u003e1 hour\u003c/strong\u003e to complete this tutorial, plus some additional time to work with the \u003ca href=\"https://github.com/clemedon/Makefile_tutor/tree/main/projects\"\u003e\u003cstrong\u003eexamples\u003c/strong\u003e\u003c/a\u003e. For those of you who are wondering, as I write this line, I have invested a total of 102 hours and 50 minutes in creating this tutorial.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eTL;DR\u003c/strong\u003e Refer to the bold text.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://clemedon.github.io/Makefile_tutor/\" rel=\"nofollow\"\u003e\u003cstrong\u003e→ GitHub Page ←\u003c/strong\u003e\u003c/a\u003e\u003cbr\u003e\n\u003ca href=\"https://github.com/clemedon/Makefile_tutor/\"\u003e\u003cstrong\u003e→ GitHub Repo ←\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"http://creativecommons.org/licenses/by-sa/4.0/\" rel=\"nofollow\"\u003e\u003cimg src=\"https://camo.githubusercontent.com/8893a5ee2d7f73909733da3e88ef024aab2bb1fce0ada8155499b8db59b4d148/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d434325323042592d2d5341253230342e302d6c69676874677265792e737667\" alt=\"CC BY-SA 4.0\" data-canonical-src=\"https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eRoadmap\u003c/strong\u003e\u003c/p\u003e\n\u003cul class=\"contains-task-list\"\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"https://clemedon.github.io/Makefile_tutor/\" rel=\"nofollow\"\u003eGitHub Page\u003c/a\u003e\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e A \u003ca href=\"#usage\"\u003eready to make\u003c/a\u003e project of each template version\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#usage\"\u003ebold text\u003c/a\u003e that acts as a summary\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#version-1\"\u003ev1\u003c/a\u003e Simplest C project\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#version-2\"\u003ev2\u003c/a\u003e Project that include headers\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#version-3\"\u003ev3\u003c/a\u003e Project with any kind of directory structure\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#version-4\"\u003ev4\u003c/a\u003e Static library \u003cem\u003e+ introduce auto-gen dependencies\u003c/em\u003e\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\" checked=\"\"\u003e \u003ca href=\"#version-5\"\u003ev5\u003c/a\u003e Project that uses libraries\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" id=\"\" disabled=\"\" class=\"task-list-item-checkbox\"\u003e POSIX Makefile\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsage\u003c/h1\u003e\u003ca id=\"user-content-usage\" class=\"anchor\" aria-label=\"Permalink: Usage\" href=\"#usage\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis tutorial is designed to be read line by line \u003cstrong\u003elinearly at first\u003c/strong\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThen it can be quickly navigated thanks to the:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eBrief\u003c/strong\u003e of each version which is visible from the \u003ca href=\"#index\"\u003e\u003cstrong\u003eIndex\u003c/strong\u003e\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eText in bold\u003c/strong\u003e that compile the essence of this tutorial.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e buttons at the end of each version.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eEach version of the template has an assigned directory in the\n\u003ca href=\"https://github.com/clemedon/Makefile_tutor/tree/main/projects\"\u003e\u003cstrong\u003eprojects\u003c/strong\u003e\u003c/a\u003e\ndirectory of the repository, to play with a Makefile open a terminal and run:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"git clone https://github.com/clemedon/Makefile_tutor.git\ncd Makefile_tutor/projects\"\u003e\u003cpre\u003egit clone https://github.com/clemedon/Makefile_tutor.git\n\u003cspan class=\"pl-c1\"\u003ecd\u003c/span\u003e Makefile_tutor/projects\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-shell notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"cd \u0026lt;template_version\u0026gt;\nmake \u0026lt;target\u0026gt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003ecd\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e\u0026lt;\u003c/span\u003etemplate_version\u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e\nmake \u003cspan class=\"pl-k\"\u003e\u0026lt;\u003c/span\u003etarget\u003cspan class=\"pl-k\"\u003e\u0026gt;\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003ePS1 \u003cstrong\u003e\u003ccode\u003eC++\u003c/code\u003e users\u003c/strong\u003e have to replace \u003ccode\u003eCC = clang\u003c/code\u003e with \u003ccode\u003eCXX = g++\u003c/code\u003e and \u003ccode\u003eCFLAGS\u003c/code\u003e\nwith \u003ccode\u003eCXXFLAGS\u003c/code\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003ePS2 feel free to \u003cstrong\u003efork me\u003c/strong\u003e so as to remove everything that does not\ninterest you and customize me according to your needs.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eGlossary\u003c/h1\u003e\u003ca id=\"user-content-glossary\" class=\"anchor\" aria-label=\"Permalink: Glossary\" href=\"#glossary\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eEach \u003cstrong\u003eversion\u003c/strong\u003e of the template has \u003cstrong\u003e3 sections\u003c/strong\u003e:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eStructure\u003c/strong\u003e is the project structure sketch.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eBrief\u003c/strong\u003e is a summary made from the bold parts of the template comments.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eTemplate\u003c/strong\u003e is a commented Makefile template with comments (that are always\nplaced at the end of the template part that concerns them).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eOur \u003cstrong\u003etemplate\u003c/strong\u003e will be articulated around the following \u003cstrong\u003eparts\u003c/strong\u003e:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e### BEG\u003c/code\u003e Mark the template \u003cstrong\u003ebeginning\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eINGREDIENTS\u003c/code\u003e Build \u003cstrong\u003evariables\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eUTENSILS\u003c/code\u003e Shell \u003cstrong\u003ecommands\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eRECIPES\u003c/code\u003e Build and extra \u003cstrong\u003erules\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eSPEC\u003c/code\u003e \u003cstrong\u003eSpecial targets\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e#### END\u003c/code\u003e Mark the template \u003cstrong\u003eend\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eAccording to make a \u003cstrong\u003e\u003ccode\u003erule\u003c/code\u003e\u003c/strong\u003e is made of:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003etargets\u003c/code\u003e are the names of the \u003cstrong\u003egoals\u003c/strong\u003e we want to make. It can be a file or\nan action, the latter leading to a \u003cem\u003epseudo target\u003c/em\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eprerequisites\u003c/code\u003e are the goals that must be achieved so that the \u003ccode\u003erule\u003c/code\u003e can\nexecute. Thus prerequisites are the \u003cstrong\u003etargets dependencies\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erecipe\u003c/code\u003e is the set of lines that \u003cstrong\u003ebegins with a \u003ccode\u003eTAB\u003c/code\u003e\u003c/strong\u003e character and appear\nin a rule context.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"target: prerequisite\n recipe line 1\n recipe line 2\n …\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003etarget\u003c/span\u003e: prerequisite\n recipe line 1\n recipe line 2\n …\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSyntax\u003c/h1\u003e\u003ca id=\"user-content-syntax\" class=\"anchor\" aria-label=\"Permalink: Syntax\" href=\"#syntax\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eLike every Makefile the template uses a combination of Makefile syntax and shell\nscript syntax. The \u003cstrong\u003eshell script syntax\u003c/strong\u003e is reserved and limited to recipe\nlines, by default those lines have to \u003cstrong\u003estart with a \u003ccode\u003eTAB\u003c/code\u003e\u003c/strong\u003e character to be\ndifferentiated by make (and passed to the shell). The \u003cstrong\u003eMakefile syntax\u003c/strong\u003e is\nused for \u003cstrong\u003eall the other lines\u003c/strong\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eAbout the \u003cstrong\u003eequal signs\u003c/strong\u003e:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e:=\u003c/code\u003e \u003cstrong\u003esimply expand\u003c/strong\u003e the defined variable (like C \u003ccode\u003e=\u003c/code\u003e).\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e=\u003c/code\u003e \u003cstrong\u003erecursively expand\u003c/strong\u003e the defined variable (the expression is expanded\nafterward, when (and each time) the variable is used).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"A := Did $(C)\nB = Did $(C)\n\nC = you understand ?\n\nall:\n $(info $(A)) # output \u0026quot;Did\u0026quot;\n $(info $(B)) # output \u0026quot;Did you understand ?\u0026quot;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eA\u003c/span\u003e := Did \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eC\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eB\u003c/span\u003e = Did \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eC\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eC\u003c/span\u003e = you understand ?\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e:\n $(info $(A)) \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e output \"Did\"\u003c/span\u003e\n $(info $(B)) \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e output \"Did you understand ?\"\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAbout \u003cstrong\u003evariables\u003c/strong\u003e note that \u003ccode\u003e${VAR}\u003c/code\u003e and \u003ccode\u003e$(VAR)\u003c/code\u003e is exactly the same.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cstrong\u003eAutomatic Variables\u003c/strong\u003e expansion:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e$\u0026lt;\u003c/code\u003e \u003cstrong\u003eleftmost prerequisite\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e$@\u003c/code\u003e \u003cstrong\u003ecurrent target\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e$^\u003c/code\u003e \u003cstrong\u003eall prerequisites\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e$(@D)\u003c/code\u003e \u003cstrong\u003edirectory part\u003c/strong\u003e of the file name of the target\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e$(@F)\u003c/code\u003e \u003cstrong\u003efile part\u003c/strong\u003e of the file name of the target\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eCf. Version 1 / Automatic variables in practice.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTemplate\u003c/h1\u003e\u003ca id=\"user-content-template\" class=\"anchor\" aria-label=\"Permalink: Template\" href=\"#template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eIndex\u003c/h2\u003e\u003ca id=\"user-content-index\" class=\"anchor\" aria-label=\"Permalink: Index\" href=\"#index\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#version-1\"\u003e\u003cstrong\u003eVersion 1 / Simplest C project\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e42 C coding style conventions\u003c/li\u003e\n\u003cli\u003ebuiltin variables\u003c/li\u003e\n\u003cli\u003eThe C compilation implicit rule\u003c/li\u003e\n\u003cli\u003epattern rule contains \u003ccode\u003e%\u003c/code\u003e character\u003c/li\u003e\n\u003cli\u003eAutomatic variables in practice\u003c/li\u003e\n\u003cli\u003eIllustration of a \u003ccode\u003emake all\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eC build recap\u003c/li\u003e\n\u003cli\u003eparallelization enabled by \u003ccode\u003emake --jobs\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ethe \u003ccode\u003e.PHONY:\u003c/code\u003e special target\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#version-2\"\u003e\u003cstrong\u003eVersion 2 / Project that include headers\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003epreprocessor's flags\u003c/li\u003e\n\u003cli\u003eprint a custom message\u003c/li\u003e\n\u003cli\u003eC compilation implicit rule is overwritten\u003c/li\u003e\n\u003cli\u003e\u003cem\u003edefault goal\u003c/em\u003e \u003ccode\u003eall\u003c/code\u003e appears first\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.SILENT:\u003c/code\u003e silences the rules output\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#version-3\"\u003e\u003cstrong\u003eVersion 3 / Project with any kind of directory structure\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003esplit the line with a \u003ccode\u003ebackslash\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003esubstitution reference so \u003ccode\u003emain.c\u003c/code\u003e becomes \u003ccode\u003esrc/main.c\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003egenerate the \u003ccode\u003eOBJ_DIR\u003c/code\u003e based on \u003ccode\u003eSRC_DIR\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ecompilation rule uses multiple source and object directories\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#version-4\"\u003e\u003cstrong\u003eVersion 4 / Static library\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ewhen a header file is modified the executable will rebuild\u003c/li\u003e\n\u003cli\u003eautomatically generate a list of dependencies\u003c/li\u003e\n\u003cli\u003ebuild directory\u003c/li\u003e\n\u003cli\u003edependency files must be included\u003c/li\u003e\n\u003cli\u003ehyphen symbol to prevent make from complaining\u003c/li\u003e\n\u003cli\u003ecreates a static library\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#version-5\"\u003e\u003cstrong\u003eVersion 5 / Project that uses libraries\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003esystem library linked by default\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaddprefix\u003c/code\u003e make function\u003c/li\u003e\n\u003cli\u003eflags and libraries used by the linker\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edir\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003eBuild with a library\u003c/li\u003e\n\u003cli\u003eLinking with a library\u003c/li\u003e\n\u003cli\u003ebuilds each of the required libraries\u003c/li\u003e\n\u003cli\u003ecall rules recursively\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#bonus\"\u003e\u003cstrong\u003eBonus\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003emake\u003c/code\u003e and \u003ccode\u003erun\u003c/code\u003e the \u003cem\u003edefault goal\u003c/em\u003e\u003c/li\u003e\n\u003cli\u003eprint \u003ccode\u003e\u0026lt;target\u0026gt;\u003c/code\u003e recipe without executing it\u003c/li\u003e\n\u003cli\u003eprint the value of an arbitrary variable\u003c/li\u003e\n\u003cli\u003eupdate the git repository\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersion 1\u003c/h2\u003e\u003ca id=\"user-content-version-1\" class=\"anchor\" aria-label=\"Permalink: Version 1\" href=\"#version-1\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev1 Structure\u003c/h3\u003e\u003ca id=\"user-content-v1-structure\" class=\"anchor\" aria-label=\"Permalink: v1 Structure\" href=\"#v1-structure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe simplest, build a program called \u003ccode\u003eicecream\u003c/code\u003e with the following structure:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" before build: after build:\n . .\n ├── Makefile ├── Makefile\n └── main.c ├── main.o\n ├── main.c\n └── icecream\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e before build: after build:\n . .\n ├── Makefile ├── Makefile\n └── main.c ├── main.o\n ├── main.c\n └── icecream\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev1 Brief\u003c/h3\u003e\u003ca id=\"user-content-v1-brief\" class=\"anchor\" aria-label=\"Permalink: v1 Brief\" href=\"#v1-brief\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e42 C coding style conventions\u003c/li\u003e\n\u003cli\u003ebuiltin variables\u003c/li\u003e\n\u003cli\u003eThe C compilation implicit rule\u003c/li\u003e\n\u003cli\u003epattern rule contains \u003ccode\u003e%\u003c/code\u003e character\u003c/li\u003e\n\u003cli\u003eAutomatic variables in practice\u003c/li\u003e\n\u003cli\u003eIllustration of a \u003ccode\u003emake all\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eC build recap\u003c/li\u003e\n\u003cli\u003eparallelization enabled by \u003ccode\u003emake --jobs\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ethe \u003ccode\u003e.PHONY:\u003c/code\u003e special target\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev1 Template\u003c/h3\u003e\u003ca id=\"user-content-v1-template\" class=\"anchor\" aria-label=\"Permalink: v1 Template\" href=\"#v1-template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"####################################### BEG_1 ####\n\nNAME := icecream\n\n#------------------------------------------------#\n# INGREDIENTS #\n#------------------------------------------------#\n# SRCS source files\n# OBJS object files\n#\n# CC compiler\n# CFLAGS compiler flags\n\nSRCS := main.c\nOBJS := main.o\n\nCC := clang\nCFLAGS := -Wall -Wextra -Werror\n\n#------------------------------------------------#\n# UTENSILS #\n#------------------------------------------------#\n# RM force remove\n# MAKEFLAGS make flags\n\nRM := rm -f\nMAKEFLAGS += --no-print-directory\n\n#------------------------------------------------#\n# RECIPES #\n#------------------------------------------------#\n# all default goal\n# $(NAME) linking .o -\u0026gt; binary\n# clean remove .o\n# fclean remove .o + binary\n# re remake default goal\n\nall: $(NAME)\n\n$(NAME): $(OBJS)\n $(CC) $(OBJS) -o $(NAME)\n\nclean:\n $(RM) $(OBJS)\n\nfclean: clean\n $(RM) $(NAME)\n\nre:\n $(MAKE) fclean\n $(MAKE) all\n\n#------------------------------------------------#\n# SPEC #\n#------------------------------------------------#\n\n.PHONY: clean fclean re\n\n####################################### END_1 ####\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### BEG_1 ####\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e := icecream\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INGREDIENTS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRCS source files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJS object files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CC compiler\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CFLAGS compiler flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := main.c\n\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e := main.o\n\n\u003cspan class=\"pl-smi\"\u003eCC\u003c/span\u003e := clang\n\u003cspan class=\"pl-smi\"\u003eCFLAGS\u003c/span\u003e := -Wall -Wextra -Werror\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e UTENSILS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RM force remove\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e MAKEFLAGS make flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eRM\u003c/span\u003e := rm -f\n\u003cspan class=\"pl-smi\"\u003eMAKEFLAGS\u003c/span\u003e += --no-print-directory\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RECIPES #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e all default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(NAME) linking .o -\u0026gt; binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e clean remove .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fclean remove .o + binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re remake default goal\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e\n $(CC) $(OBJS) -o $(NAME)\n\n\u003cspan class=\"pl-en\"\u003eclean\u003c/span\u003e:\n $(RM) $(OBJS)\n\n\u003cspan class=\"pl-en\"\u003efclean\u003c/span\u003e: clean\n $(RM) $(NAME)\n\n\u003cspan class=\"pl-en\"\u003ere\u003c/span\u003e:\n $(MAKE) fclean\n $(MAKE) all\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SPEC #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\n\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: clean fclean re\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### END_1 ####\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe choice of the \u003ccode\u003eCC\u003c/code\u003e and \u003ccode\u003eCFLAGS\u003c/code\u003e values, \u003ccode\u003eNAME\u003c/code\u003e, \u003ccode\u003eclean\u003c/code\u003e, \u003ccode\u003efclean\u003c/code\u003e, \u003ccode\u003eall\u003c/code\u003e\nand \u003ccode\u003ere\u003c/code\u003e as the basic rules as well as not using a wildcard to auto generate\nthe sources list is guided by the \u003cstrong\u003e42 C coding style conventions\u003c/strong\u003e, do not\nhesitate to disagree and change it (like renaming \u003ccode\u003eclean\u003c/code\u003e and \u003ccode\u003efclean\u003c/code\u003e to the\nmore GNU conventional \u003ccode\u003emostlyclean\u003c/code\u003e and \u003ccode\u003eclean\u003c/code\u003e respectively).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eMAKE\u003c/code\u003e and \u003ccode\u003eMAKEFLAGS\u003c/code\u003e are \u003cstrong\u003ebuiltin variables\u003c/strong\u003e like \u003ccode\u003eCFLAGS\u003c/code\u003e and a lot of\nothers that you can find in the \u003cem\u003edata-base\u003c/em\u003e (\u003ccode\u003emake --print-data-base\u003c/code\u003e\ncommand). \u003ccode\u003eMAKE\u003c/code\u003e value corresponds to the \u003ccode\u003emake\u003c/code\u003e executable being run and\n\u003ccode\u003eMAKEFLAGS\u003c/code\u003e to its flags. When a Makefile is executed from another Makefile,\nthe called's \u003ccode\u003eMAKE\u003c/code\u003e \u003ccode\u003eMAKEFLAGS\u003c/code\u003e variables inherit from the caller's \u003ccode\u003eMAKE\u003c/code\u003e\n\u003ccode\u003eMAKEFLAGS\u003c/code\u003e values.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eHere we append \u003ccode\u003e--no-print-directory\u003c/code\u003e to \u003ccode\u003eMAKEFLAGS\u003c/code\u003e content to have a clearer\noutput, try to remove it and \u003ccode\u003emake re\u003c/code\u003e to see the difference.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eThe C compilation implicit rule\u003c/strong\u003e looks like this:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"%.o: %.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhere \u003ccode\u003e%.o\u003c/code\u003e expands to each objects, \u003ccode\u003e%.c\u003c/code\u003e to each sources, \u003ccode\u003e$@\u003c/code\u003e to the first\ntarget (which is \u003ccode\u003e%.o\u003c/code\u003e) and \u003ccode\u003e$\u0026lt;\u003c/code\u003e to the leftmost prerequisite (which is \u003ccode\u003e%.c\u003c/code\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eAs their name implies implicit rules are implicit and do not need to be\nwritten. As well as the builtin variables, all the implicit rules can be found\nin the data-base, accessible with \u003ccode\u003emake -p -f/dev/null | less\u003c/code\u003e command.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eA \u003cstrong\u003epattern rule\u003c/strong\u003e is a rule whose target \u003cstrong\u003econtains\u003c/strong\u003e a \u003cstrong\u003e\u003ccode\u003e%\u003c/code\u003e character\u003c/strong\u003e\n(here \u003ccode\u003e%.o: %.c\u003c/code\u003e). This character means \"exactly one of them\". It is used\nhere to say that each \u003ccode\u003e.o\u003c/code\u003e requires a \u003ccode\u003e.c\u003c/code\u003e with the same name and the \u003ccode\u003e$(CC)…\u003c/code\u003e\nrecipe line will execute as many times as there are \u003ccode\u003e.o: .c\u003c/code\u003e pairs, thus\ncreating for each source its corresponding object, one at a time.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eAutomatic variables in practice\u003c/strong\u003e:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# Linking step\n\n$(NAME): $(OBJS)\n $(CC) $^ -o $@\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Linking step\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e\n $(CC) $^ -o $@\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e$@\u003c/code\u003e expands to the \u003cem\u003ecurrent target\u003c/em\u003e, here we could have used \u003ccode\u003e$(NAME)\u003c/code\u003e instead.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e$^\u003c/code\u003e expands to \u003cem\u003eall prerequisites\u003c/em\u003e, here we could have used \u003ccode\u003e$(OBJS)\u003c/code\u003e instead\nbut not \u003ccode\u003e$\u0026lt;\u003c/code\u003e that expands to the \u003cem\u003eleftmost prerequisite\u003c/em\u003e and so only the first\nitem found in \u003ccode\u003e$(OBJS)\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# Compiling step\n\n%.o: %.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Compiling step\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ccode\u003e$\u0026lt;\u003c/code\u003e expands to the \u003cem\u003eleftmost prerequisite\u003c/em\u003e, here it could not have been\nreplaced with \u003ccode\u003e$(SRCS)\u003c/code\u003e because \u003ccode\u003e$(SRCS)\u003c/code\u003e expands to all the sources at once\nwhich is not the case of the pattern rule \u003ccode\u003e%.c\u003c/code\u003e. On the other hand here \u003ccode\u003e$\u0026lt;\u003c/code\u003e is\nequivalent to \u003ccode\u003e$^\u003c/code\u003e, both will always expand to one source: the current one\nexpanded by \u003ccode\u003e%.c\u003c/code\u003e. For the same reasons \u003ccode\u003e$@\u003c/code\u003e expands to \u003ccode\u003e%.o\u003c/code\u003e not to \u003ccode\u003e$(OBJS)\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eIllustration of a \u003ccode\u003emake all\u003c/code\u003e\u003c/strong\u003e:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"all: $(NAME) 3 ← 2\n\n$(NAME): $(OBJS) 2 ← 1\n $(CC) $(OBJS) -o $(NAME)\n\n%.o: %.c 1 ← 0\n $(CC) $(CFLAGS) -c -o $@ $\u0026lt;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e 3 ← 2\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e 2 ← 1\n $(CC) $(OBJS) -o $(NAME)\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c 1 ← 0\n $(CC) $(CFLAGS) -c -o $@ $\u0026lt;\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eall\u003c/code\u003e target requires \u003ccode\u003eicecream\u003c/code\u003e that requires the \u003ccode\u003eobjects\u003c/code\u003e that require the\n\u003ccode\u003esources\u003c/code\u003e that requires… a programmer. In other words \u003ccode\u003eall\u003c/code\u003e creates \u003ccode\u003eicecream\u003c/code\u003e\nwith the objects created with the sources that you have created.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMake will first trace its path to the lower level where it finds a raw material\n\u003ccode\u003e3 → 2 → 1 → 0\u003c/code\u003e (the \u003ccode\u003esources\u003c/code\u003e) and then do it backward while building each\nresource that is required by the direct upper level encountered \u003ccode\u003e0 → 1 → 2 → 3\u003c/code\u003e\n(the \u003ccode\u003eicecream\u003c/code\u003e, our \u003cem\u003efinal goal\u003c/em\u003e).\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eC build recap\u003c/strong\u003e \u003ccode\u003e%.o\u003c/code\u003e target requires the sources to be compiled into\nobjects, the \u003ccode\u003e-c\u003c/code\u003e option tells the compiler to only compile without linking.\nThe \u003ccode\u003e-o\u003c/code\u003e option is used to specify the objects name. Afterward the \u003ccode\u003e$(NAME)\u003c/code\u003e\ntarget requires the linking the objects into a binary file whose name is\nspecified with the \u003ccode\u003e-o\u003c/code\u003e flag.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eFor the \u003ccode\u003ere\u003c/code\u003e rule we have no choice but make an external call to our Makefile\nbecause we should not rely on the order in which prerequisites are specified.\nFor example \u003ccode\u003ere: fclean all\u003c/code\u003e wouldn't not be reliable if \u003cstrong\u003eparallelization\u003c/strong\u003e\nwas \u003cstrong\u003eenabled by \u003ccode\u003emake --jobs\u003c/code\u003e\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe prerequisites given to \u003cstrong\u003ethe \u003ccode\u003e.PHONY:\u003c/code\u003e special target\u003c/strong\u003e become targets\nthat make will run regardless of whether a file with that name exists. In\nshort these prerequisites are our targets that don't bear the name of a file.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eTry to remove the \u003ccode\u003e.PHONY: re\u003c/code\u003e, create a file named \u003ccode\u003ere\u003c/code\u003e at the Makefile level\nin the project directory and run \u003ccode\u003emake re\u003c/code\u003e. It won't work.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNow if you do the same with \u003ccode\u003eall\u003c/code\u003e it won't cause any problem, as we know\nprerequisites are completed before their targets and \u003ccode\u003eall\u003c/code\u003e has the sole action\nof invoking \u003ccode\u003e$(NAME)\u003c/code\u003e, as long as a rule doesn't have a recipe, \u003ccode\u003e.PHONY\u003c/code\u003e is not\nnecessary.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersion 2\u003c/h2\u003e\u003ca id=\"user-content-version-2\" class=\"anchor\" aria-label=\"Permalink: Version 2\" href=\"#version-2\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev2 Structure\u003c/h3\u003e\u003ca id=\"user-content-v2-structure\" class=\"anchor\" aria-label=\"Permalink: v2 Structure\" href=\"#v2-structure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs above but for a project that \u003cstrong\u003eincludes header files\u003c/strong\u003e:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" before build: after build:\n . .\n ├── Makefile ├── Makefile\n ├── main.c ├── main.o\n └── icecream.h ├── main.c\n ├── icecream.h\n └── icecream\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e before build: after build:\n . .\n ├── Makefile ├── Makefile\n ├── main.c ├── main.o\n └── icecream.h ├── main.c\n ├── icecream.h\n └── icecream\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev2 Brief\u003c/h3\u003e\u003ca id=\"user-content-v2-brief\" class=\"anchor\" aria-label=\"Permalink: v2 Brief\" href=\"#v2-brief\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003epreprocessor's flags\u003c/li\u003e\n\u003cli\u003eprint a custom message\u003c/li\u003e\n\u003cli\u003eC compilation implicit rule is overwritten\u003c/li\u003e\n\u003cli\u003e\u003cem\u003edefault goal\u003c/em\u003e \u003ccode\u003eall\u003c/code\u003e appears first\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e.SILENT:\u003c/code\u003e silences the rules output\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev2 Template\u003c/h3\u003e\u003ca id=\"user-content-v2-template\" class=\"anchor\" aria-label=\"Permalink: v2 Template\" href=\"#v2-template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"####################################### BEG_2 ####\n\nNAME := icecream\n\n#------------------------------------------------#\n# INGREDIENTS #\n#------------------------------------------------#\n# SRCS source files\n# OBJS object files\n#\n# CC compiler\n# CFLAGS compiler flags\n# CPPFLAGS preprocessor flags\n\nSRCS := main.c\nOBJS := main.o\n\nCC := clang\nCFLAGS := -Wall -Wextra -Werror\nCPPFLAGS := -I .\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### BEG_2 ####\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e := icecream\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INGREDIENTS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRCS source files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJS object files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CC compiler\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CFLAGS compiler flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CPPFLAGS preprocessor flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := main.c\n\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e := main.o\n\n\u003cspan class=\"pl-smi\"\u003eCC\u003c/span\u003e := clang\n\u003cspan class=\"pl-smi\"\u003eCFLAGS\u003c/span\u003e := -Wall -Wextra -Werror\n\u003cspan class=\"pl-smi\"\u003eCPPFLAGS\u003c/span\u003e := -I .\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eCPPFLAGS\u003c/code\u003e is dedicated to \u003cstrong\u003epreprocessor's flags\u003c/strong\u003e like \u003ccode\u003e-I \u0026lt;include_dir\u0026gt;\u003c/code\u003e,\nit allows you to no longer have to write the full path of a header but only\nits file name in the sources: \u003ccode\u003e#include \"icecream.h\"\u003c/code\u003e instead of \u003ccode\u003e#include \"../../path/to/include/icecream.h\"\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# UTENSILS #\n#------------------------------------------------#\n# RM force remove\n# MAKEFLAGS make flags\n\nRM := rm -f\nMAKEFLAGS += --no-print-directory\n\n#------------------------------------------------#\n# RECIPES #\n#------------------------------------------------#\n# all default goal\n# $(NAME) linking .o -\u0026gt; binary\n# %.o compilation .c -\u0026gt; .o\n# clean remove .o\n# fclean remove .o + binary\n# re remake default goal\n\nall: $(NAME)\n\n$(NAME): $(OBJS)\n $(CC) $(OBJS) -o $(NAME)\n $(info CREATED $(NAME))\n\n%.o: %.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\nclean:\n $(RM) $(OBJS)\n\nfclean: clean\n $(RM) $(NAME)\n\nre:\n $(MAKE) fclean\n $(MAKE) all\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e UTENSILS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RM force remove\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e MAKEFLAGS make flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eRM\u003c/span\u003e := rm -f\n\u003cspan class=\"pl-smi\"\u003eMAKEFLAGS\u003c/span\u003e += --no-print-directory\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RECIPES #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e all default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(NAME) linking .o -\u0026gt; binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e %.o compilation .c -\u0026gt; .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e clean remove .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fclean remove .o + binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re remake default goal\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e\n $(CC) $(OBJS) -o $(NAME)\n $(info CREATED $(NAME))\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n\u003cspan class=\"pl-en\"\u003eclean\u003c/span\u003e:\n $(RM) $(OBJS)\n\n\u003cspan class=\"pl-en\"\u003efclean\u003c/span\u003e: clean\n $(RM) $(NAME)\n\n\u003cspan class=\"pl-en\"\u003ere\u003c/span\u003e:\n $(MAKE) fclean\n $(MAKE) all\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003ccode\u003einfo\u003c/code\u003e function is used here to \u003cstrong\u003eprint a custom message\u003c/strong\u003e about what has\njust been built.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eWe prefer \u003ccode\u003einfo\u003c/code\u003e to shell \u003ccode\u003eecho\u003c/code\u003e because it is a make function. Also unlike\n\u003ccode\u003eecho\u003c/code\u003e that can only be used inside a recipe, \u003ccode\u003einfo\u003c/code\u003e can be used anywhere in a\nMakefile which makes it powerful for debugging.\u003c/em\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003cstrong\u003eC compilation implicit rule is overwritten\u003c/strong\u003e with an explicit equivalent\nwhich let us add an \u003ccode\u003einfo\u003c/code\u003e statement to it.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe order in which the rules are written does not matter as long as our\n\u003cstrong\u003edefault goal \u003ccode\u003eall\u003c/code\u003e appears first\u003c/strong\u003e (the rule that will be triggered by a\nsimple \u003ccode\u003emake\u003c/code\u003e command).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# SPEC #\n#------------------------------------------------#\n\n.PHONY: clean fclean re\n.SILENT:\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SPEC #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\n\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: clean fclean re\n\u003cspan class=\"pl-c1\"\u003e.SILENT\u003c/span\u003e:\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eNormally make prints each line of a rule's recipe before it is executed. The\nspecial target \u003cstrong\u003e\u003ccode\u003e.SILENT:\u003c/code\u003e silences the rules output\u003c/strong\u003e specified as\nprerequisites, when it is used without prerequisites it silents all the rules\n(implicit included).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eTo silence at the recipe-line level we can prefix the wanted recipe lines with an \u003ccode\u003e@\u003c/code\u003e\nsymbol.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"####################################### END_2 ####\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### END_2 ####\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersion 3\u003c/h2\u003e\u003ca id=\"user-content-version-3\" class=\"anchor\" aria-label=\"Permalink: Version 3\" href=\"#version-3\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev3 Structure\u003c/h3\u003e\u003ca id=\"user-content-v3-structure\" class=\"anchor\" aria-label=\"Permalink: v3 Structure\" href=\"#v3-structure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eAs above but a more complex project structure with \u003cstrong\u003emultiple source\ndirectories\u003c/strong\u003e and their \u003cstrong\u003ecorresponding object directories\u003c/strong\u003e:\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" before build: after build:\n . .\n ├── src ├── src\n │ ├── base │ ├── base\n │ │ ├── water.c │ │ ├── water.c\n │ │ └── milk.c │ │ └── milk.c\n │ ├── arom │ ├── arom\n │ │ └── coco.c │ │ └── coco.c\n │ └── main.c │ └── main.c\n ├── include ├── obj\n │ └── icecream.h │ ├── base\n └── Makefile │ │ ├── water.o\n │ │ └── milk.o\n │ ├── arom\n │ │ └── coco.o\n │ └── main.o\n ├── include\n │ └── icecream.h\n ├── Makefile\n └── icecream\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e before build: after build:\n . .\n ├── src ├── src\n │ ├── base │ ├── base\n │ │ ├── water.c │ │ ├── water.c\n │ │ └── milk.c │ │ └── milk.c\n │ ├── arom │ ├── arom\n │ │ └── coco.c │ │ └── coco.c\n │ └── main.c │ └── main.c\n ├── include ├── obj\n │ └── icecream.h │ ├── base\n └── Makefile │ │ ├── water.o\n │ │ └── milk.o\n │ ├── arom\n │ │ └── coco.o\n │ └── main.o\n ├── include\n │ └── icecream.h\n ├── Makefile\n └── icecream\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev3 Brief\u003c/h3\u003e\u003ca id=\"user-content-v3-brief\" class=\"anchor\" aria-label=\"Permalink: v3 Brief\" href=\"#v3-brief\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003esplit the line with a \u003ccode\u003ebackslash\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003esubstitution reference so \u003ccode\u003emain.c\u003c/code\u003e becomes \u003ccode\u003esrc/main.c\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003egenerate the \u003ccode\u003eOBJ_DIR\u003c/code\u003e based on \u003ccode\u003eSRC_DIR\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003ecompilation rule uses multiple source and object directories\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev3 Template\u003c/h3\u003e\u003ca id=\"user-content-v3-template\" class=\"anchor\" aria-label=\"Permalink: v3 Template\" href=\"#v3-template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"####################################### BEG_3 ####\n\nNAME := icecream\n\n#------------------------------------------------#\n# INGREDIENTS #\n#------------------------------------------------#\n# SRC_DIR source directory\n# OBJ_DIR object directory\n# SRCS source files\n# OBJS object files\n#\n# CC compiler\n# CFLAGS compiler flags\n# CPPFLAGS preprocessor flags\n\nSRC_DIR := src\nOBJ_DIR := obj\nSRCS := \\\n main.c \\\n arom/coco.c \\\n base/milk.c \\\n base/water.c\nSRCS := $(SRCS:%=$(SRC_DIR)/%)\nOBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)\n\nCC := clang\nCFLAGS := -Wall -Wextra -Werror\nCPPFLAGS := -I include\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### BEG_3 ####\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e := icecream\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INGREDIENTS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRC_DIR source directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJ_DIR object directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRCS source files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJS object files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CC compiler\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CFLAGS compiler flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CPPFLAGS preprocessor flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e := src\n\u003cspan class=\"pl-smi\"\u003eOBJ_DIR\u003c/span\u003e := obj\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n main.c \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n arom/coco.c \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n base/milk.c \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n base/water.c\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:%=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%.c=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJ_DIR\u003c/span\u003e)\u003c/span\u003e/%.o\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eCC\u003c/span\u003e := clang\n\u003cspan class=\"pl-smi\"\u003eCFLAGS\u003c/span\u003e := -Wall -Wextra -Werror\n\u003cspan class=\"pl-smi\"\u003eCPPFLAGS\u003c/span\u003e := -I include\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eWe can \u003cstrong\u003esplit the line\u003c/strong\u003e by ending it \u003cstrong\u003ewith a \u003ccode\u003ebackslash\u003c/code\u003e\u003c/strong\u003e to increase the\nreadability of \u003ccode\u003eSRCS\u003c/code\u003e content and facilitate its modification.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eA string \u003cstrong\u003esubstitution reference\u003c/strong\u003e substitutes the value of each item of a\nvariable with the specified alterations. \u003ccode\u003e$(SRCS:%=$(SRC_DIR)/%)\u003c/code\u003e means that\neach item of \u003ccode\u003eSRCS\u003c/code\u003e represented by \u003ccode\u003e%\u003c/code\u003e becomes itself (\u003ccode\u003e%\u003c/code\u003e) plus the\n\u003ccode\u003e$(SRC_DIR)/\u003c/code\u003e alteration, so \u003ccode\u003emain.c\u003c/code\u003e becomes \u003ccode\u003esrc/main.c\u003c/code\u003e. \u003ccode\u003eOBJS\u003c/code\u003e will then\nuse the same process to convert \u003ccode\u003esrc/main.c\u003c/code\u003e into \u003ccode\u003eobj/main.o\u003c/code\u003e, based on \u003ccode\u003eOBJ_DIR\u003c/code\u003e and the new value of \u003ccode\u003eSRCS\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# UTENSILS #\n#------------------------------------------------#\n# RM force remove\n# MAKEFLAGS make flags\n# DIR_DUP duplicate directory tree\n\nRM := rm -f\nMAKEFLAGS += --no-print-directory\nDIR_DUP = mkdir -p $(@D)\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e UTENSILS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RM force remove\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e MAKEFLAGS make flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e DIR_DUP duplicate directory tree\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eRM\u003c/span\u003e := rm -f\n\u003cspan class=\"pl-smi\"\u003eMAKEFLAGS\u003c/span\u003e += --no-print-directory\n\u003cspan class=\"pl-smi\"\u003eDIR_DUP\u003c/span\u003e = mkdir -p \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003e@D\u003c/span\u003e)\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eDIR_DUP\u003c/code\u003e will \u003cstrong\u003egenerate the \u003ccode\u003eOBJ_DIR\u003c/code\u003e based on \u003ccode\u003eSRC_DIR\u003c/code\u003e\u003c/strong\u003e structure with\n\u003ccode\u003emkdir -p\u003c/code\u003e which creates the directory and the parents directories if missing,\nand \u003ccode\u003e$(@D)\u003c/code\u003e that will expand to the directory part of the target, as we've seen in the \u003ca href=\"#syntax\"\u003esyntax\u003c/a\u003e section.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003cem\u003eThis will work with every possible kind of src directory structure.\u003c/em\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# RECIPES #\n#------------------------------------------------#\n# all default goal\n# $(NAME) linking .o -\u0026gt; binary\n# %.o compilation .c -\u0026gt; .o\n# clean remove .o\n# fclean remove .o + binary\n# re remake default goal\n\nall: $(NAME)\n\n$(NAME): $(OBJS)\n $(CC) $(OBJS) -o $(NAME)\n $(info CREATED $(NAME))\n\n$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\nclean:\n $(RM) $(OBJS)\n\nfclean: clean\n $(RM) $(NAME)\n\nre:\n $(MAKE) fclean\n $(MAKE) all\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RECIPES #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e all default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(NAME) linking .o -\u0026gt; binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e %.o compilation .c -\u0026gt; .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e clean remove .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fclean remove .o + binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re remake default goal\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e\n $(CC) $(OBJS) -o $(NAME)\n $(info CREATED $(NAME))\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJ_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n\u003cspan class=\"pl-en\"\u003eclean\u003c/span\u003e:\n $(RM) $(OBJS)\n\n\u003cspan class=\"pl-en\"\u003efclean\u003c/span\u003e: clean\n $(RM) $(NAME)\n\n\u003cspan class=\"pl-en\"\u003ere\u003c/span\u003e:\n $(MAKE) fclean\n $(MAKE) all\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003cstrong\u003ecompilation rule\u003c/strong\u003e \u003ccode\u003e.o: %.c\u003c/code\u003e becomes \u003ccode\u003e$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c\u003c/code\u003e,\nsince our structure \u003cstrong\u003euses dedicated source and object directories\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# SPEC #\n#------------------------------------------------#\n\n.PHONY: clean fclean re\n.SILENT:\n\n####################################### END_3 ####\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SPEC #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\n\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: clean fclean re\n\u003cspan class=\"pl-c1\"\u003e.SILENT\u003c/span\u003e:\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### END_3 ####\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersion 4\u003c/h2\u003e\u003ca id=\"user-content-version-4\" class=\"anchor\" aria-label=\"Permalink: Version 4\" href=\"#version-4\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev4 Structure\u003c/h3\u003e\u003ca id=\"user-content-v4-structure\" class=\"anchor\" aria-label=\"Permalink: v4 Structure\" href=\"#v4-structure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBuilds a \u003cstrong\u003elibrary\u003c/strong\u003e so there are no \u003ccode\u003emain.c\u003c/code\u003e. We generate \u003cstrong\u003edependencies\u003c/strong\u003e\nthat are stored with the objects. Therefor we rename the \u003ccode\u003eobj\u003c/code\u003e directory into a\nmore general \u003ccode\u003e.build\u003c/code\u003e directory.\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" before build: after build:\n . .\n ├── src ├── src\n │ ├── base │ ├── base\n │ │ ├── water.c │ │ ├── water.c\n │ │ └── milk.c │ │ └── milk.c\n │ └── arom │ └── arom\n │ └── coco.c │ └── coco.c\n ├── include ├── include\n │ └── icecream.h │ └── icecream.h\n └── Makefile ├── .build\n │ ├── base\n │ │ ├── water.o\n │ │ ├── water.d\n │ │ ├── milk.o\n │ │ └── milk.d\n │ └── arom\n │ ├── coco.o\n │ └── coco.d\n ├── Makefile\n └── libicecream.a\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e before build: after build:\n . .\n ├── src ├── src\n │ ├── base │ ├── base\n │ │ ├── water.c │ │ ├── water.c\n │ │ └── milk.c │ │ └── milk.c\n │ └── arom │ └── arom\n │ └── coco.c │ └── coco.c\n ├── include ├── include\n │ └── icecream.h │ └── icecream.h\n └── Makefile ├── .build\n │ ├── base\n │ │ ├── water.o\n │ │ ├── water.d\n │ │ ├── milk.o\n │ │ └── milk.d\n │ └── arom\n │ ├── coco.o\n │ └── coco.d\n ├── Makefile\n └── libicecream.a\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev4 Brief\u003c/h3\u003e\u003ca id=\"user-content-v4-brief\" class=\"anchor\" aria-label=\"Permalink: v4 Brief\" href=\"#v4-brief\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003ewhen a header file is modified the executable will rebuild\u003c/li\u003e\n\u003cli\u003eautomatically generate a list of dependencies\u003c/li\u003e\n\u003cli\u003ebuild directory\u003c/li\u003e\n\u003cli\u003edependency files must be included\u003c/li\u003e\n\u003cli\u003ehyphen symbol to prevent make from complaining\u003c/li\u003e\n\u003cli\u003ecreates a static library\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev4 Template\u003c/h3\u003e\u003ca id=\"user-content-v4-template\" class=\"anchor\" aria-label=\"Permalink: v4 Template\" href=\"#v4-template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"####################################### BEG_4 ####\n\nNAME := libicecream.a\n\n#------------------------------------------------#\n# INGREDIENTS #\n#------------------------------------------------#\n# SRC_DIR source directory\n# SRCS source files\n#\n# BUILD_DIR object directory\n# OBJS object files\n# DEPS dependency files\n#\n# CC compiler\n# CFLAGS compiler flags\n# CPPFLAGS preprocessor flags\n\nSRC_DIR := src\nSRCS := \\\n arom/coco.c \\\n base/milk.c \\\n base/water.c\nSRCS := $(SRCS:%=$(SRC_DIR)/%)\n\nBUILD_DIR := .build\nOBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)\nDEPS := $(OBJS:.o=.d)\n\nCC := clang\nCFLAGS := -Wall -Wextra -Werror\nCPPFLAGS := -MMD -MP -I include\nAR := ar\nARFLAGS := -r -c -s\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### BEG_4 ####\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e := libicecream.a\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INGREDIENTS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRC_DIR source directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRCS source files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e BUILD_DIR object directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJS object files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e DEPS dependency files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CC compiler\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CFLAGS compiler flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CPPFLAGS preprocessor flags\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e := src\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n arom/coco.c \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n base/milk.c \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n base/water.c\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:%=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e := .build\n\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%.c=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e)\u003c/span\u003e/%.o\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eDEPS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS:.o=.d\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eCC\u003c/span\u003e := clang\n\u003cspan class=\"pl-smi\"\u003eCFLAGS\u003c/span\u003e := -Wall -Wextra -Werror\n\u003cspan class=\"pl-smi\"\u003eCPPFLAGS\u003c/span\u003e := -MMD -MP -I include\n\u003cspan class=\"pl-smi\"\u003eAR\u003c/span\u003e := ar\n\u003cspan class=\"pl-smi\"\u003eARFLAGS\u003c/span\u003e := -r -c -s\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eUnlike with sources, \u003cstrong\u003ewhen a header file is modified\u003c/strong\u003e make has no way of\nknowing this and will not consider \u003cstrong\u003ethe executable\u003c/strong\u003e to be out of date, and\ntherefor \u003cstrong\u003ewill\u003c/strong\u003e not \u003cstrong\u003erebuild\u003c/strong\u003e it. In order to change this behavior we\nshould add the appropriate header files as additional prerequisites:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#before #after\nmain.o: main.c main.o: main.c icecream.h\n clang -c $\u0026lt; -o $@ clang -c $\u0026lt; -o $@\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003ebefore #after\u003c/span\u003e\n\u003cspan class=\"pl-en\"\u003emain.o\u003c/span\u003e: main.c main.o: main.c icecream.h\n clang -c $\u0026lt; -o $@ clang -c $\u0026lt; -o $@\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\n\u003cp dir=\"auto\"\u003eDoing this manually for multiple sources and headers is both tedious and error\nprone. By adding \u003ccode\u003e-MMD\u003c/code\u003e to \u003ccode\u003eCPPFLAGS\u003c/code\u003e our compiler will \u003cstrong\u003eautomatically\ngenerate a list of dependencies\u003c/strong\u003e for each object file encountered during the\ncompilation. The \u003ccode\u003e-MP\u003c/code\u003e option prevents errors that are triggered if a header\nfile has been deleted or renamed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDependency files must be included into our Makefile right after the objects\ncreation so to obtain their names we copy \u003ccode\u003eOBJS\u003c/code\u003e into \u003ccode\u003eDEPS\u003c/code\u003e and use\n\u003cem\u003esubstitution reference\u003c/em\u003e to turn \u003ccode\u003e.o\u003c/code\u003e part of their name into \u003ccode\u003e.d\u003c/code\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eWe change our old \u003ccode\u003eOBJ_DIR = obj\u003c/code\u003e for a \u003ccode\u003eBUILD_DIR = .build\u003c/code\u003e, a hidden \u003cstrong\u003ebuild\ndirectory\u003c/strong\u003e that will contain our dependency files in addition to our objects.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eA static library is not a binary but a collection of objects so we use \u003ccode\u003ear\u003c/code\u003e to\n\u003cstrong\u003ecreates a static library\u003c/strong\u003e during the linking step of the build. \u003ccode\u003e-r\u003c/code\u003e to\nreplace the older objects with the new ones with \u003ccode\u003e-c\u003c/code\u003e to create the library if\nit does not exist and \u003ccode\u003e-s\u003c/code\u003e to write an index into the archive or update an\nexisting one.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# UTENSILS #\n#------------------------------------------------#\n# RM force remove\n# MAKEFLAGS make flags\n# DIR_DUP duplicate directory tree\n\nRM := rm -f\nMAKEFLAGS += --no-print-directory\nDIR_DUP = mkdir -p $(@D)\n\n#------------------------------------------------#\n# RECIPES #\n#------------------------------------------------#\n# all default goal\n# $(NAME) link .o -\u0026gt; library\n# %.o compilation .c -\u0026gt; .o\n# clean remove .o\n# fclean remove .o + binary\n# re remake default goal\n\nall: $(NAME)\n\n$(NAME): $(OBJS)\n $(AR) $(ARFLAGS) $(NAME) $(OBJS)\n $(info CREATED $(NAME))\n\n$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n-include $(DEPS)\n\nclean:\n $(RM) $(OBJS) $(DEPS)\n\nfclean: clean\n $(RM) $(NAME)\n\nre:\n $(MAKE) fclean\n $(MAKE) all\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e UTENSILS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RM force remove\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e MAKEFLAGS make flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e DIR_DUP duplicate directory tree\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eRM\u003c/span\u003e := rm -f\n\u003cspan class=\"pl-smi\"\u003eMAKEFLAGS\u003c/span\u003e += --no-print-directory\n\u003cspan class=\"pl-smi\"\u003eDIR_DUP\u003c/span\u003e = mkdir -p \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003e@D\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RECIPES #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e all default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(NAME) link .o -\u0026gt; library\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e %.o compilation .c -\u0026gt; .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e clean remove .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fclean remove .o + binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re remake default goal\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e\n $(AR) $(ARFLAGS) $(NAME) $(OBJS)\n $(info CREATED $(NAME))\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n\u003cspan class=\"pl-k\"\u003e-include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eDEPS\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eclean\u003c/span\u003e:\n $(RM) $(OBJS) $(DEPS)\n\n\u003cspan class=\"pl-en\"\u003efclean\u003c/span\u003e: clean\n $(RM) $(NAME)\n\n\u003cspan class=\"pl-en\"\u003ere\u003c/span\u003e:\n $(MAKE) fclean\n $(MAKE) all\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eDependency files\u003c/strong\u003e are written in the make language and \u003cstrong\u003emust be included\u003c/strong\u003e\ninto our Makefile to be read. The \u003ccode\u003einclude\u003c/code\u003e directive work the same as C\n\u003ccode\u003e#include\u003c/code\u003e, it tells make to suspend its current Makefile reading and read the\nincluded files before continuing. Make sure to include the dependencies after\nthey are created → after the compilation rule that invoke \u003ccode\u003e-MMD\u003c/code\u003e via\n\u003ccode\u003e$(CPPFLAGS)\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe purpose of the \u003ccode\u003e-include $(DEPS)\u003c/code\u003e initial \u003cstrong\u003ehyphen symbol\u003c/strong\u003e is \u003cstrong\u003eto\nprevent make from complaining\u003c/strong\u003e when a non-zero status code is encountered,\nwhich can be caused here by a missing files from our generated dependency\nfiles list.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# SPEC #\n#------------------------------------------------#\n\n.PHONY: clean fclean re\n.SILENT:\n\n####################################### END_4 ####\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SPEC #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\n\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: clean fclean re\n\u003cspan class=\"pl-c1\"\u003e.SILENT\u003c/span\u003e:\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### END_4 ####\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eVersion 5\u003c/h2\u003e\u003ca id=\"user-content-version-5\" class=\"anchor\" aria-label=\"Permalink: Version 5\" href=\"#version-5\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev5 Structure\u003c/h3\u003e\u003ca id=\"user-content-v5-structure\" class=\"anchor\" aria-label=\"Permalink: v5 Structure\" href=\"#v5-structure\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBuilds an \u003ccode\u003eicecream\u003c/code\u003e \u003cstrong\u003eprogram that uses\u003c/strong\u003e \u003ccode\u003elibbase\u003c/code\u003e and \u003ccode\u003elibarom\u003c/code\u003e\n\u003cstrong\u003elibraries\u003c/strong\u003e. Both libraries are v4 based.\u003c/p\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\" before build: after build:\n . .\n ├── src ├── src\n │ └── main.c │ └── main.c\n ├── lib ├── lib\n │ ├── libbase │ ├── libbase\n │ │ ├── src │ │ ├── src\n │ │ │ ├── water.c │ │ │ ├── water.c\n │ │ │ └── milk.c │ │ │ └── milk.c\n │ │ ├── include │ │ ├── include\n │ │ │ └── base.h │ │ │ └── base.h\n │ │ └── Makefile │ │ ├── .build\n │ └── libarom │ │ │ ├── water.o\n │ ├── src │ │ │ ├── water.d\n │ │ ├── coco.c │ │ │ ├── milk.o\n │ │ └── cherry.c │ │ │ └── milk.d\n │ ├── include │ │ ├── Makefile\n │ │ └── arom.h │ │ └── libbase.a\n │ └── Makefile │ └── libarom\n ├── include │ ├── src\n │ └── icecream.h │ │ ├── coco.c\n └── Makefile │ │ └── cherry.c\n │ ├── include\n │ │ └── arom.h\n │ ├── .build\n │ │ ├── coco.o\n │ │ ├── coco.d\n │ │ ├── cherry.o\n │ │ └── cherry.d\n │ ├── Makefile\n │ └── libarom.a\n ├── include\n │ └── icecream.h\n ├── .build\n │ ├── main.o\n │ └── main.d\n ├── Makefile\n └── icecream\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003e before build: after build:\n . .\n ├── src ├── src\n │ └── main.c │ └── main.c\n ├── lib ├── lib\n │ ├── libbase │ ├── libbase\n │ │ ├── src │ │ ├── src\n │ │ │ ├── water.c │ │ │ ├── water.c\n │ │ │ └── milk.c │ │ │ └── milk.c\n │ │ ├── include │ │ ├── include\n │ │ │ └── base.h │ │ │ └── base.h\n │ │ └── Makefile │ │ ├── .build\n │ └── libarom │ │ │ ├── water.o\n │ ├── src │ │ │ ├── water.d\n │ │ ├── coco.c │ │ │ ├── milk.o\n │ │ └── cherry.c │ │ │ └── milk.d\n │ ├── include │ │ ├── Makefile\n │ │ └── arom.h │ │ └── libbase.a\n │ └── Makefile │ └── libarom\n ├── include │ ├── src\n │ └── icecream.h │ │ ├── coco.c\n └── Makefile │ │ └── cherry.c\n │ ├── include\n │ │ └── arom.h\n │ ├── .build\n │ │ ├── coco.o\n │ │ ├── coco.d\n │ │ ├── cherry.o\n │ │ └── cherry.d\n │ ├── Makefile\n │ └── libarom.a\n ├── include\n │ └── icecream.h\n ├── .build\n │ ├── main.o\n │ └── main.d\n ├── Makefile\n └── icecream\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev5 Brief\u003c/h3\u003e\u003ca id=\"user-content-v5-brief\" class=\"anchor\" aria-label=\"Permalink: v5 Brief\" href=\"#v5-brief\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003esystem library linked by default\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eaddprefix\u003c/code\u003e make function\u003c/li\u003e\n\u003cli\u003eflags and libraries used by the linker\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003edir\u003c/code\u003e function\u003c/li\u003e\n\u003cli\u003eBuild with a library\u003c/li\u003e\n\u003cli\u003eLinking with a library\u003c/li\u003e\n\u003cli\u003ebuilds each of the required libraries\u003c/li\u003e\n\u003cli\u003ecall rules recursively\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ev5 Template\u003c/h3\u003e\u003ca id=\"user-content-v5-template\" class=\"anchor\" aria-label=\"Permalink: v5 Template\" href=\"#v5-template\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"# @author clemedon (Clément Vidon)\n####################################### BEG_5 ####\n\nNAME := icecream\n\n#------------------------------------------------#\n# INGREDIENTS #\n#------------------------------------------------#\n# LIBS libraries to be used\n# LIBS_TARGET libraries to be built\n#\n# INCS header file locations\n#\n# SRC_DIR source directory\n# SRCS source files\n#\n# BUILD_DIR build directory\n# OBJS object files\n# DEPS dependency files\n#\n# CC compiler\n# CFLAGS compiler flags\n# CPPFLAGS preprocessor flags\n# LDFLAGS linker flags\n# LDLIBS libraries name\n\nLIBS := arom base m\nLIBS_TARGET := \\\n lib/libarom/libarom.a \\\n lib/libbase/libbase.a\n\nINCS := include \\\n lib/libarom/include \\\n lib/libbase/include\n\nSRC_DIR := src\nSRCS := main.c\nSRCS := $(SRCS:%=$(SRC_DIR)/%)\n\nBUILD_DIR := .build\nOBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o)\nDEPS := $(OBJS:.o=.d)\n\nCC := clang\nCFLAGS := -Wall -Wextra -Werror\nCPPFLAGS := $(addprefix -I,$(INCS)) -MMD -MP\nLDFLAGS := $(addprefix -L,$(dir $(LIBS_TARGET)))\nLDLIBS := $(addprefix -l,$(LIBS))\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e @author clemedon (Clément Vidon)\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### BEG_5 ####\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e := icecream\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INGREDIENTS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e LIBS libraries to be used\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e LIBS_TARGET libraries to be built\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e INCS header file locations\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRC_DIR source directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SRCS source files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e BUILD_DIR build directory\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e OBJS object files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e DEPS dependency files\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CC compiler\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CFLAGS compiler flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CPPFLAGS preprocessor flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e LDFLAGS linker flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e LDLIBS libraries name\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eLIBS\u003c/span\u003e := arom base m\n\u003cspan class=\"pl-smi\"\u003eLIBS_TARGET\u003c/span\u003e := \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n lib/libarom/libarom.a \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n lib/libbase/libbase.a\n\n\u003cspan class=\"pl-smi\"\u003eINCS\u003c/span\u003e := include \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n lib/libarom/include \u003cspan class=\"pl-cce\"\u003e\\\u003c/span\u003e\n lib/libbase/include\n\n\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e := src\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := main.c\n\u003cspan class=\"pl-smi\"\u003eSRCS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:%=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e := .build\n\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRCS:\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/%.c=\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e)\u003c/span\u003e/%.o\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eDEPS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS:.o=.d\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eCC\u003c/span\u003e := clang\n\u003cspan class=\"pl-smi\"\u003eCFLAGS\u003c/span\u003e := -Wall -Wextra -Werror\n\u003cspan class=\"pl-smi\"\u003eCPPFLAGS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-c1\"\u003eaddprefix\u003c/span\u003e -I,\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eINCS\u003c/span\u003e)\u003c/span\u003e)\u003c/span\u003e -MMD -MP\n\u003cspan class=\"pl-smi\"\u003eLDFLAGS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-c1\"\u003eaddprefix\u003c/span\u003e -L,\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-c1\"\u003edir\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eLIBS_TARGET\u003c/span\u003e)\u003c/span\u003e)\u003c/span\u003e)\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eLDLIBS\u003c/span\u003e := \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-c1\"\u003eaddprefix\u003c/span\u003e -l,\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eLIBS\u003c/span\u003e)\u003c/span\u003e)\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eWe can notice that the \u003ccode\u003em\u003c/code\u003e library from \u003ccode\u003eLIBS\u003c/code\u003e is not mentionned in\n\u003ccode\u003eLIBS_TARGET\u003c/code\u003e for the reason that \u003ccode\u003em\u003c/code\u003e is a \u003cstrong\u003esystem library\u003c/strong\u003e (\u003ccode\u003elibm\u003c/code\u003e for\nmathematical functions found in \u003ccode\u003emath.h\u003c/code\u003e). Unlike the \u003ccode\u003elibc\u003c/code\u003e which is linked\nby default (we don't need to provide \u003ccode\u003e-lc\u003c/code\u003e flag to our linker) the \u003ccode\u003elibm\u003c/code\u003e is\nnot \u003cstrong\u003elinked by default\u003c/strong\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eIn \u003ccode\u003eCPPFLAGS\u003c/code\u003e we use \u003cstrong\u003e\u003ccode\u003eaddprefix\u003c/code\u003e\u003c/strong\u003e that, as its name suggests is a \u003cstrong\u003emake\nfunction\u003c/strong\u003e that allows you to add a prefix, here a \u003ccode\u003e-I\u003c/code\u003e to each of the item\nfound in \u003ccode\u003e$(INCS)\u003c/code\u003e (that contains the paths to our project and libraries\nheaders).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eLDFLAGS\u003c/code\u003e and \u003ccode\u003eLDLIBS\u003c/code\u003e contain the \u003cstrong\u003eflags and libraries\u003c/strong\u003e that will be \u003cstrong\u003eused\nby the linker\u003c/strong\u003e \u003ccode\u003eld\u003c/code\u003e to link the library to our project sources.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003cstrong\u003e\u003ccode\u003edir\u003c/code\u003e function\u003c/strong\u003e means that we want to keep only directory part of the\ngiven item, there exists a \u003ccode\u003enotdir\u003c/code\u003e function that does the opposite to keep\nonly the file name of the given item.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eBuild with a library\u003c/strong\u003e requires three flags: \u003ccode\u003e-I\u003c/code\u003e tell the compiler where to\nfind the lib header files, \u003ccode\u003e-L\u003c/code\u003e tells the linker where to look for the library\nand \u003ccode\u003e-l\u003c/code\u003e the name of this library (without its conventional \u003ccode\u003elib\u003c/code\u003e prefix).\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eFor example: \u003ccode\u003e-I lib/libarom/include -L lib/libarom -l arom\u003c/code\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\n#------------------------------------------------#\n# UTENSILS #\n#------------------------------------------------#\n# RM force remove\n# MAKEFLAGS make flags\n# DIR_DUP duplicate directory tree\n\nRM := rm -f\nMAKEFLAGS += --silent --no-print-directory\nDIR_DUP = mkdir -p $(@D)\n\n#------------------------------------------------#\n# RECIPES #\n#------------------------------------------------#\n# all default goal\n# $(NAME) link .o -\u0026gt; archive\n# $(LIBS) build libraries\n# %.o compilation .c -\u0026gt; .o\n# clean remove .o\n# fclean remove .o + binary\n# re remake default goal\n# run run the program\n# info print the default goal recipe\n\nall: $(NAME)\n\n$(NAME): $(OBJS) $(LIBS_TARGET)\n $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(NAME)\n $(info CREATED $(NAME))\n\n$(LIBS_TARGET):\n $(MAKE) -C $(@D)\n\n$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n-include $(DEPS)\n\nclean:\n for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f clean; done\n $(RM) $(OBJS) $(DEPS)\n\nfclean: clean\n for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f fclean; done\n $(RM) $(NAME)\n\nre:\n $(MAKE) fclean\n $(MAKE) all\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e UTENSILS #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RM force remove\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e MAKEFLAGS make flags\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e DIR_DUP duplicate directory tree\u003c/span\u003e\n\n\u003cspan class=\"pl-smi\"\u003eRM\u003c/span\u003e := rm -f\n\u003cspan class=\"pl-smi\"\u003eMAKEFLAGS\u003c/span\u003e += --silent --no-print-directory\n\u003cspan class=\"pl-smi\"\u003eDIR_DUP\u003c/span\u003e = mkdir -p \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003e@D\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e RECIPES #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e all default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(NAME) link .o -\u0026gt; archive\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e $(LIBS) build libraries\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e %.o compilation .c -\u0026gt; .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e clean remove .o\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e fclean remove .o + binary\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e re remake default goal\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e run run the program\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e info print the default goal recipe\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eall\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eNAME\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eOBJS\u003c/span\u003e)\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eLIBS_TARGET\u003c/span\u003e)\u003c/span\u003e\n $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(NAME)\n $(info CREATED $(NAME))\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eLIBS_TARGET\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e:\n $(MAKE) -C $(@D)\n\n\u003cspan class=\"pl-en\"\u003e\u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eBUILD_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.o\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eSRC_DIR\u003c/span\u003e)\u003c/span\u003e/\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e.c\n $(DIR_DUP)\n $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $\u0026lt;\n $(info CREATED $@)\n\n\u003cspan class=\"pl-k\"\u003e-include\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e$(\u003cspan class=\"pl-smi\"\u003eDEPS\u003c/span\u003e)\u003c/span\u003e\n\n\u003cspan class=\"pl-en\"\u003eclean\u003c/span\u003e:\n for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f clean; done\n $(RM) $(OBJS) $(DEPS)\n\n\u003cspan class=\"pl-en\"\u003efclean\u003c/span\u003e: clean\n for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f fclean; done\n $(RM) $(NAME)\n\n\u003cspan class=\"pl-en\"\u003ere\u003c/span\u003e:\n $(MAKE) fclean\n $(MAKE) all\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eLinking with a library\u003c/strong\u003e requires special attention to the order of the\nlinking flags. In our case we need to make sure that \u003ccode\u003e$(LDFLAGS)\u003c/code\u003e and\n\u003ccode\u003e$(LDLIBS)\u003c/code\u003e passes respectively before and after the \u003ccode\u003e$(OBJS)\u003c/code\u003e in the linking\nrecipe.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003e$(LIBS_TARGET)\u003c/code\u003e rule \u003cstrong\u003ebuilds each of the required libraries\u003c/strong\u003e found in the\n\u003ccode\u003eINGREDIENTS\u003c/code\u003e part. It is a \u003ccode\u003e$(NAME)\u003c/code\u003e prerequisite for the same reason as\n\u003ccode\u003e$(OBJS)\u003c/code\u003e because our \u003cem\u003efinal goal\u003c/em\u003e needs the libraries as well as the objects\nto be built.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003e\u003csub\u003e\u003csub\u003e\u003c/sub\u003e\u003c/sub\u003e\u003c/p\u003e\u003chr\u003e\u003cp dir=\"auto\"\u003e\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eAs both rules \u003ccode\u003eclean\u003c/code\u003e and \u003ccode\u003efclean\u003c/code\u003e appear in the Makefile of all our\n\u003ccode\u003e$(LIBS_TARGET)\u003c/code\u003e we can \u003cstrong\u003ecall\u003c/strong\u003e these \u003cstrong\u003erules\u003c/strong\u003e for each of them\n\u003cstrong\u003erecursively\u003c/strong\u003e using a shell \u003ccode\u003efor\u003c/code\u003e loop. Here again we use the \u003ccode\u003edir\u003c/code\u003e\nfunction to only keep the directory part of the library.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"#------------------------------------------------#\n# SPEC #\n#------------------------------------------------#\n\n.PHONY: clean fclean re\n.SILENT:\n\n####################################### end_5 ####\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e SPEC #\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e------------------------------------------------#\u003c/span\u003e\n\n\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: clean fclean re\n\u003cspan class=\"pl-c1\"\u003e.SILENT\u003c/span\u003e:\n\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e###################################### end_5 ####\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#index\"\u003e\u003cstrong\u003eReturn to Index ↑\u003c/strong\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eBonus\u003c/h2\u003e\u003ca id=\"user-content-bonus\" class=\"anchor\" aria-label=\"Permalink: Bonus\" href=\"#bonus\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eExtra rules\u003c/h3\u003e\u003ca id=\"user-content-extra-rules\" class=\"anchor\" aria-label=\"Permalink: Extra rules\" href=\"#extra-rules\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\".PHONY: run\nrun: re\n -./$(NAME)\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: run\n\u003cspan class=\"pl-en\"\u003erun\u003c/span\u003e: re\n -./$(NAME)\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003erun\u003c/code\u003e is a simple rule that \u003cstrong\u003e\u003ccode\u003emake\u003c/code\u003e and \u003ccode\u003erun\u003c/code\u003e the default goal\u003c/strong\u003e. We start\nthe shell command with the \u003ccode\u003ehyphen\u003c/code\u003e symbol to prevent make from interrupting\nits own execution if our program execution returns a non-zero value.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"info-%:\n $(MAKE) --dry-run --always-make $* | grep -v \u0026quot;info\u0026quot;\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003einfo-\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e\u003c/span\u003e:\n $(MAKE) --dry-run --always-make $* | grep -v \"info\"\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003einfo-\u0026lt;target\u0026gt;\u003c/code\u003e rule will execute a \u003ccode\u003emake \u0026lt;target\u0026gt;\u003c/code\u003e command with \u003ccode\u003e--dry-run\u003c/code\u003e to\n\u003cstrong\u003eprint\u003c/strong\u003e the \u003cstrong\u003e\u003ccode\u003e\u0026lt;target\u0026gt;\u003c/code\u003e recipe without executing it\u003c/strong\u003e, \u003ccode\u003e--always-make\u003c/code\u003e to\n\u003ccode\u003emake\u003c/code\u003e even if the targets already exist and \u003ccode\u003egrep -v\u003c/code\u003e to filter the output.\n\u003ccode\u003e$*\u003c/code\u003e expands to the value given in place of the \u003ccode\u003e%\u003c/code\u003e at the rule call. For\nexample with \u003ccode\u003emake info-re\u003c/code\u003e \u003ccode\u003e$*\u003c/code\u003e will expand to \u003ccode\u003ere\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"print-%:\n $(info '$*'='$($*)')\"\u003e\u003cpre\u003e\u003cspan class=\"pl-en\"\u003eprint-\u003cspan class=\"pl-c1\"\u003e%\u003c/span\u003e\u003c/span\u003e:\n $(info '$*'='$($*)')\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003ccode\u003eprint-\u0026lt;variable\u0026gt;\u003c/code\u003e that works like \u003ccode\u003eprint-\u0026lt;rule\u0026gt;\u003c/code\u003e will \u003cstrong\u003eprint the value\nof an arbitrary variable\u003c/strong\u003e, for example a \u003ccode\u003emake print-CC\u003c/code\u003e will output\n\u003ccode\u003eCC=clang\u003c/code\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight highlight-source-makefile notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\".PHONY: update\nupdate:\n git stash\n git pull\n git submodule update --init\n git stash pop\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e.PHONY\u003c/span\u003e: update\n\u003cspan class=\"pl-en\"\u003eupdate\u003c/span\u003e:\n git stash\n git pull\n git submodule update --init\n git stash pop\u003c/pre\u003e\u003c/div\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe \u003ccode\u003eupdate\u003c/code\u003e rule will \u003cstrong\u003eupdate the git repository\u003c/strong\u003e to its last version, as\nwell as its \u003cem\u003egit submodules\u003c/em\u003e. \u003ccode\u003estash\u003c/code\u003e commands saves eventual uncommitted\nchanges and put them back in place once the update is done.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eSources\u003c/h1\u003e\u003ca id=\"user-content-sources\" class=\"anchor\" aria-label=\"Permalink: Sources\" href=\"#sources\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eTopic\u003c/th\u003e\n\u003cth\u003eWebsite\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003edoc\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://docs.w3cub.com/gnu_make/\" rel=\"nofollow\"\u003e\u003cstrong\u003edocs.w3cub.com\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003emanual\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://www.gnu.org/software/make/manual/html_node\" rel=\"nofollow\"\u003e\u003cstrong\u003egnu.org\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ea richer tutorial\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://makefiletutorial.com/\" rel=\"nofollow\"\u003e\u003cstrong\u003emakefiletutorial.com\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eorder-only exquisite\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://stackoverflow.com/a/68584653\" rel=\"nofollow\"\u003e\u003cstrong\u003estackoverflow.com\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ec libraries\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://docencia.ac.upc.edu/FIB/USO/Bibliografia/unix-c-libraries.html#creating_static_archive\" rel=\"nofollow\"\u003e\u003cstrong\u003edocencia.ac.upc.edu\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eauto-deps gen\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/\" rel=\"nofollow\"\u003e\u003cstrong\u003emake.mad-scientist.net\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eauto-deps gen\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://scottmcpeak.com/autodepend/autodepend.html\" rel=\"nofollow\"\u003e\u003cstrong\u003escottmcpeak.com\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eauto-deps gen\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html\" rel=\"nofollow\"\u003e\u003cstrong\u003emicrohowto.info\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003einclude statement\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://www.gnu.org/software/make/manual/html_node/Include.html\" rel=\"nofollow\"\u003e\u003cstrong\u003egnu.org\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eredis makefile\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"https://github.com/redis/redis/blob/unstable/src/Makefile\"\u003e\u003cstrong\u003egithub.com\u003c/strong\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eContact\u003c/h1\u003e\u003ca id=\"user-content-contact\" class=\"anchor\" aria-label=\"Permalink: Contact\" href=\"#contact\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"snippet-clipboard-content notranslate position-relative overflow-auto\" data-snippet-clipboard-copy-content=\"cvidon 42\nclemedon icloud\"\u003e\u003cpre class=\"notranslate\"\u003e\u003ccode\u003ecvidon 42\nclemedon icloud\n\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003c/article\u003e","loaded":true,"timedOut":false,"errorMessage":null,"headerInfo":{"toc":[{"level":1,"text":"\n MAKEFILE TUTOR (GNU)\n","anchor":"----makefile-tutor-gnu","htmlText":"\n MAKEFILE TUTOR (GNU)\n"},{"level":3,"text":"Summary · Usage · Glossary · Syntax · Index · Sources · Contact","anchor":"----summary----------usage----------glossary----------syntax----------index----------sources----------contact","htmlText":"Summary · Usage · Glossary · Syntax · Index · Sources · Contact"},{"level":1,"text":"Summary","anchor":"summary","htmlText":"Summary"},{"level":1,"text":"Usage","anchor":"usage","htmlText":"Usage"},{"level":1,"text":"Glossary","anchor":"glossary","htmlText":"Glossary"},{"level":1,"text":"Syntax","anchor":"syntax","htmlText":"Syntax"},{"level":1,"text":"Template","anchor":"template","htmlText":"Template"},{"level":2,"text":"Index","anchor":"index","htmlText":"Index"},{"level":2,"text":"Version 1","anchor":"version-1","htmlText":"Version 1"},{"level":3,"text":"v1 Structure","anchor":"v1-structure","htmlText":"v1 Structure"},{"level":3,"text":"v1 Brief","anchor":"v1-brief","htmlText":"v1 Brief"},{"level":3,"text":"v1 Template","anchor":"v1-template","htmlText":"v1 Template"},{"level":2,"text":"Version 2","anchor":"version-2","htmlText":"Version 2"},{"level":3,"text":"v2 Structure","anchor":"v2-structure","htmlText":"v2 Structure"},{"level":3,"text":"v2 Brief","anchor":"v2-brief","htmlText":"v2 Brief"},{"level":3,"text":"v2 Template","anchor":"v2-template","htmlText":"v2 Template"},{"level":2,"text":"Version 3","anchor":"version-3","htmlText":"Version 3"},{"level":3,"text":"v3 Structure","anchor":"v3-structure","htmlText":"v3 Structure"},{"level":3,"text":"v3 Brief","anchor":"v3-brief","htmlText":"v3 Brief"},{"level":3,"text":"v3 Template","anchor":"v3-template","htmlText":"v3 Template"},{"level":2,"text":"Version 4","anchor":"version-4","htmlText":"Version 4"},{"level":3,"text":"v4 Structure","anchor":"v4-structure","htmlText":"v4 Structure"},{"level":3,"text":"v4 Brief","anchor":"v4-brief","htmlText":"v4 Brief"},{"level":3,"text":"v4 Template","anchor":"v4-template","htmlText":"v4 Template"},{"level":2,"text":"Version 5","anchor":"version-5","htmlText":"Version 5"},{"level":3,"text":"v5 Structure","anchor":"v5-structure","htmlText":"v5 Structure"},{"level":3,"text":"v5 Brief","anchor":"v5-brief","htmlText":"v5 Brief"},{"level":3,"text":"v5 Template","anchor":"v5-template","htmlText":"v5 Template"},{"level":2,"text":"Bonus","anchor":"bonus","htmlText":"Bonus"},{"level":3,"text":"Extra rules","anchor":"extra-rules","htmlText":"Extra rules"},{"level":1,"text":"Sources","anchor":"sources","htmlText":"Sources"},{"level":1,"text":"Contact","anchor":"contact","htmlText":"Contact"}],"siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor"}},{"displayName":"LICENCE","repoName":"Makefile_tutor","refName":"main","path":"LICENCE","preferredFileType":"license","tabName":"CC-BY-SA-4.0","richText":null,"loaded":false,"timedOut":false,"errorMessage":null,"headerInfo":{"toc":null,"siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor"}}],"overviewFilesProcessingTime":0}},"appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-7d7eb7c71814.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-96e76d5fdb2c.js","githubDevUrl":null,"enabled_features":{"copilot_workspace":null,"code_nav_ui_events":false,"overview_shared_code_dropdown_button":false,"react_blob_overlay":false,"accessible_code_button":true,"github_models_repo_integration":false}}}}</script> <div data-target="react-partial.reactRoot"><style data-styled="true" data-styled-version="5.3.11">.iVEunk{margin-top:16px;margin-bottom:16px;}/*!sc*/ .jzuOtQ{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;}/*!sc*/ .bGojzy{margin-bottom:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;row-gap:16px;}/*!sc*/ .iNSVHo{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding-bottom:16px;padding-top:8px;}/*!sc*/ .bVgnfw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:8px;}/*!sc*/ @media screen and (max-width:320px){.bVgnfw{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}}/*!sc*/ .CEgMp{position:relative;}/*!sc*/ @media screen and (max-width:380px){.CEgMp .ref-selector-button-text-container{max-width:80px;}}/*!sc*/ @media screen and (max-width:320px){.CEgMp{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.CEgMp .overview-ref-selector{width:100%;}.CEgMp .overview-ref-selector > span{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;}.CEgMp .overview-ref-selector > span > span[data-component="text"]{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}}/*!sc*/ .gMOVLe[data-size="medium"]{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:0;}/*!sc*/ .gMOVLe[data-size="medium"] svg{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .gMOVLe[data-size="medium"] > span{width:inherit;}/*!sc*/ .gUkoLg{-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}/*!sc*/ .bZBlpz{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;}/*!sc*/ .lhTYNA{margin-right:4px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .ffLUq{font-size:14px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}/*!sc*/ .bmcJak{min-width:0;}/*!sc*/ .fLXEGX{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ @media screen and (max-width:1079px){.fLXEGX{display:none;}}/*!sc*/ .lmSMZJ[data-size="medium"]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));padding-left:4px;padding-right:4px;}/*!sc*/ .lmSMZJ[data-size="medium"] span[data-component="leadingVisual"]{margin-right:4px !important;}/*!sc*/ .dqfxud{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ @media screen and (min-width:1080px){.dqfxud{display:none;}}/*!sc*/ @media screen and (max-width:543px){.dqfxud{display:none;}}/*!sc*/ .fGwBZA[data-size="medium"][data-no-visuals]{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));}/*!sc*/ .jxTzTd{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;padding-left:8px;gap:8px;}/*!sc*/ .gqqBXN{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:8px;}/*!sc*/ @media screen and (max-width:543px){.gqqBXN{display:none;}}/*!sc*/ .dzXgxt{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ @media screen and (max-width:1011px){.dzXgxt{display:none;}}/*!sc*/ .iWFGlI{margin-left:8px;margin-right:8px;margin:0;}/*!sc*/ .vcvyP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-width:160px;}/*!sc*/ .YUPas{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ @media screen and (min-width:1012px){.YUPas{display:none;}}/*!sc*/ .izFOf{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}/*!sc*/ @media screen and (min-width:544px){.izFOf{display:none;}}/*!sc*/ .vIPPs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:16px;}/*!sc*/ .fdROMU{width:100%;border-collapse:separate;border-spacing:0;border:1px solid;border-color:var(--borderColor-default,var(--color-border-default,#d0d7de));border-radius:6px;table-layout:fixed;overflow:unset;}/*!sc*/ .jGKpsv{height:0px;line-height:0px;}/*!sc*/ .jGKpsv tr{height:0px;font-size:0px;}/*!sc*/ .jdgHnn{padding:16px;color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:12px;text-align:left;height:40px;}/*!sc*/ .jdgHnn th{padding-left:16px;background-color:var(--bgColor-muted,var(--color-canvas-subtle,#f6f8fa));}/*!sc*/ .bQivRW{width:100%;border-top-left-radius:6px;}/*!sc*/ @media screen and (min-width:544px){.bQivRW{display:none;}}/*!sc*/ .ldkMIO{width:40%;border-top-left-radius:6px;}/*!sc*/ @media screen and (max-width:543px){.ldkMIO{display:none;}}/*!sc*/ .jMbWeI{text-align:right;padding-right:16px;width:136px;border-top-right-radius:6px;}/*!sc*/ .gpqjiB{color:var(--fgColor-muted,var(--color-fg-muted,#656d76));font-size:12px;height:40px;}/*!sc*/ .dzCJzi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:8px;min-width:273px;padding:8px;}/*!sc*/ @media screen and (min-width:544px){.dzCJzi{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;}}/*!sc*/ .eNCcrz{text-align:center;vertical-align:center;height:40px;border-top:1px solid;border-color:var(--borderColor-default,var(--color-border-default,#d0d7de));}/*!sc*/ .bHTcCe{border-top:1px solid var(--borderColor-default,var(--color-border-default));cursor:pointer;}/*!sc*/ .csrIcr{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;gap:16px;}/*!sc*/ .bUQNHB{border:1px solid;border-color:var(--borderColor-default,var(--color-border-default,#d0d7de));border-radius:6px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}/*!sc*/ @media screen and (max-width:543px){.bUQNHB{margin-left:-16px;margin-right:-16px;max-width:calc(100% + 32px);}}/*!sc*/ @media screen and (min-width:544px){.bUQNHB{max-width:100%;}}/*!sc*/ .jPdcfu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;border-bottom:1px solid;border-bottom-color:var(--borderColor-default,var(--color-border-default,#d0d7de));-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-right:8px;position:-webkit-sticky;position:sticky;top:0;background-color:var(--bgColor-default,var(--color-canvas-default,#ffffff));z-index:1;border-top-left-radius:6px;border-top-right-radius:6px;}/*!sc*/ .iphEWz{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;border-bottom:none;max-width:100%;padding-left:8px;padding-right:8px;}/*!sc*/ .hUCRAk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/ .cwoBXV[data-size="medium"]{color:var(--fgColor-muted,var(--color-fg-subtle,#6e7781));padding-left:8px;padding-right:8px;}/*!sc*/ .QkQOb{padding:32px;overflow:auto;}/*!sc*/ data-styled.g1[id="Box-sc-g0xbh4-0"]{content:"iVEunk,jzuOtQ,bGojzy,iNSVHo,bVgnfw,CEgMp,gMOVLe,gUkoLg,bZBlpz,lhTYNA,ffLUq,bmcJak,fLXEGX,lmSMZJ,dqfxud,fGwBZA,jxTzTd,gqqBXN,dzXgxt,iWFGlI,vcvyP,YUPas,izFOf,vIPPs,fdROMU,jGKpsv,jdgHnn,bQivRW,ldkMIO,jMbWeI,gpqjiB,dzCJzi,eNCcrz,bHTcCe,csrIcr,bUQNHB,jPdcfu,iphEWz,hUCRAk,cwoBXV,QkQOb,"}/*!sc*/ .brGdpi{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;-webkit-clip:rect(0,0,0,0);clip:rect(0,0,0,0);white-space:nowrap;border-width:0;}/*!sc*/ data-styled.g5[id="_VisuallyHidden__VisuallyHidden-sc-11jhm7a-0"]{content:"brGdpi,"}/*!sc*/ .hWlpPn{position:relative;display:inline-block;}/*!sc*/ .hWlpPn::after{position:absolute;z-index:1000000;display:none;padding:0.5em 0.75em;font:normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";-webkit-font-smoothing:subpixel-antialiased;color:var(--tooltip-fgColor,var(--fgColor-onEmphasis,var(--color-fg-on-emphasis,#ffffff)));text-align:center;-webkit-text-decoration:none;text-decoration:none;text-shadow:none;text-transform:none;-webkit-letter-spacing:normal;-moz-letter-spacing:normal;-ms-letter-spacing:normal;letter-spacing:normal;word-wrap:break-word;white-space:pre;pointer-events:none;content:attr(aria-label);background:var(--tooltip-bgColor,var(--bgColor-emphasis,var(--color-neutral-emphasis-plus,#24292f)));border-radius:6px;opacity:0;}/*!sc*/ @-webkit-keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ @keyframes tooltip-appear{from{opacity:0;}to{opacity:1;}}/*!sc*/ .hWlpPn:hover::after,.hWlpPn:active::after,.hWlpPn:focus::after,.hWlpPn:focus-within::after{display:inline-block;-webkit-text-decoration:none;text-decoration:none;-webkit-animation-name:tooltip-appear;animation-name:tooltip-appear;-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-no-delay:hover::after,.hWlpPn.tooltipped-no-delay:active::after,.hWlpPn.tooltipped-no-delay:focus::after,.hWlpPn.tooltipped-no-delay:focus-within::after{-webkit-animation-delay:0s;animation-delay:0s;}/*!sc*/ .hWlpPn.tooltipped-multiline:hover::after,.hWlpPn.tooltipped-multiline:active::after,.hWlpPn.tooltipped-multiline:focus::after,.hWlpPn.tooltipped-multiline:focus-within::after{display:table-cell;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-se::after,.hWlpPn.tooltipped-sw::after{top:100%;right:50%;margin-top:6px;}/*!sc*/ .hWlpPn.tooltipped-se::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-sw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-n::after,.hWlpPn.tooltipped-ne::after,.hWlpPn.tooltipped-nw::after{right:50%;bottom:100%;margin-bottom:6px;}/*!sc*/ .hWlpPn.tooltipped-ne::after{right:auto;left:50%;margin-left:-16px;}/*!sc*/ .hWlpPn.tooltipped-nw::after{margin-right:-16px;}/*!sc*/ .hWlpPn.tooltipped-s::after,.hWlpPn.tooltipped-n::after{-webkit-transform:translateX(50%);-ms-transform:translateX(50%);transform:translateX(50%);}/*!sc*/ .hWlpPn.tooltipped-w::after{right:100%;bottom:50%;margin-right:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-e::after{bottom:50%;left:100%;margin-left:6px;-webkit-transform:translateY(50%);-ms-transform:translateY(50%);transform:translateY(50%);}/*!sc*/ .hWlpPn.tooltipped-multiline::after{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:250px;word-wrap:break-word;white-space:pre-line;border-collapse:separate;}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-s::after,.hWlpPn.tooltipped-multiline.tooltipped-n::after{right:auto;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);}/*!sc*/ .hWlpPn.tooltipped-multiline.tooltipped-w::after,.hWlpPn.tooltipped-multiline.tooltipped-e::after{right:100%;}/*!sc*/ .hWlpPn.tooltipped-align-right-2::after{right:0;margin-right:0;}/*!sc*/ .hWlpPn.tooltipped-align-left-2::after{left:0;margin-left:0;}/*!sc*/ data-styled.g16[id="Tooltip__TooltipBase-sc-17tf59c-0"]{content:"hWlpPn,"}/*!sc*/ .liVpTx{display:inline-block;overflow:hidden;text-overflow:ellipsis;vertical-align:top;white-space:nowrap;max-width:125px;}/*!sc*/ data-styled.g18[id="Truncate__StyledTruncate-sc-23o1d2-0"]{content:"liVpTx,"}/*!sc*/ </style> <!-- --> <!-- --> <div class="Box-sc-g0xbh4-0 iVEunk"><div class="Box-sc-g0xbh4-0 jzuOtQ"><div class="Box-sc-g0xbh4-0 bGojzy"></div></div><div class="Box-sc-g0xbh4-0 iNSVHo"><div class="Box-sc-g0xbh4-0 bVgnfw"><div class="Box-sc-g0xbh4-0 CEgMp"><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="main branch" data-testid="anchor-button" class="Box-sc-g0xbh4-0 gMOVLe prc-Button-ButtonBase-c50BI overview-ref-selector width-full" data-loading="false" data-size="medium" data-variant="default" aria-describedby="branch-picker-repos-header-ref-selector-loading-announcement" id="branch-picker-repos-header-ref-selector"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x"><div class="Box-sc-g0xbh4-0 bZBlpz"><div class="Box-sc-g0xbh4-0 lhTYNA"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></div><div class="Box-sc-g0xbh4-0 ffLUq ref-selector-button-text-container"><span class="Box-sc-g0xbh4-0 bmcJak prc-Text-Text-0ima0"> <!-- -->main</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><button hidden="" data-hotkey-scope="read-only-cursor-text-area"></button></div><div class="Box-sc-g0xbh4-0 fLXEGX"><a style="--button-color:fg.muted" type="button" href="/clementvidon/Makefile_tutor/branches" class="Box-sc-g0xbh4-0 lmSMZJ prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="invisible" aria-describedby=":Rclab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Branches</span></span></a><a style="--button-color:fg.muted" type="button" href="/clementvidon/Makefile_tutor/tags" class="Box-sc-g0xbh4-0 lmSMZJ prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="invisible" aria-describedby=":Rklab:-loading-announcement"><span data-component="buttonContent" class="Box-sc-g0xbh4-0 gUkoLg prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-tag" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Tags</span></span></a></div><div class="Box-sc-g0xbh4-0 dqfxud"><a style="--button-color:fg.muted" type="button" aria-label="Go to Branches page" href="/clementvidon/Makefile_tutor/branches" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-describedby=":Relab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></a><a style="--button-color:fg.muted" type="button" aria-label="Go to Tags page" href="/clementvidon/Makefile_tutor/tags" class="Box-sc-g0xbh4-0 fGwBZA prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-describedby=":Rmlab:-loading-announcement"><svg aria-hidden="true" focusable="false" class="octicon octicon-tag" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path></svg></a></div></div><div class="Box-sc-g0xbh4-0 jxTzTd"><div class="Box-sc-g0xbh4-0 gqqBXN"><div class="Box-sc-g0xbh4-0 dzXgxt"><!--$--><div class="Box-sc-g0xbh4-0 iWFGlI"><span class="Box-sc-g0xbh4-0 vcvyP TextInput-wrapper prc-components-TextInputWrapper-i1ofR prc-components-TextInputBaseWrapper-ueK9q" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id=":R2j5ab:" aria-hidden="true"><svg aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellcheck="false" placeholder="Go to file" aria-describedby=":R2j5ab: :R2j5abH1:" data-component="input" class="prc-components-Input-Ic-y8" value=""/><span class="TextInput-icon" id=":R2j5abH1:" aria-hidden="true"></span></span></div><!--/$--></div><div class="Box-sc-g0xbh4-0 YUPas"><button type="button" class="prc-Button-ButtonBase-c50BI" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":Rr5ab:-loading-announcement"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="text" class="prc-Button-Label-pTQ3x">Go to file</span></span></button></div><div class="react-directory-add-file-icon"></div><div class="react-directory-remove-file-icon"></div></div><button type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="primary" aria-describedby=":R55ab:-loading-announcement" id=":R55ab:"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-code hide-sm" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x">Code</span><span data-component="trailingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="Box-sc-g0xbh4-0 izFOf"><button data-component="IconButton" type="button" aria-label="Open more actions menu" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-c50BI prc-Button-IconButton-szpyj" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-describedby=":R75ab:-loading-announcement" id=":R75ab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button></div></div></div><div class="Box-sc-g0xbh4-0 vIPPs"><div data-hpc="true"><button hidden="" data-testid="focus-next-element-button" data-hotkey="j"></button><button hidden="" data-testid="focus-previous-element-button" data-hotkey="k"></button><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading" id="folders-and-files">Folders and files</h2><table aria-labelledby="folders-and-files" class="Box-sc-g0xbh4-0 fdROMU"><thead class="Box-sc-g0xbh4-0 jGKpsv"><tr class="Box-sc-g0xbh4-0 jdgHnn"><th colSpan="2" class="Box-sc-g0xbh4-0 bQivRW"><span class="text-bold">Name</span></th><th colSpan="1" class="Box-sc-g0xbh4-0 ldkMIO"><span class="text-bold">Name</span></th><th class="hide-sm"><div title="Last commit message" class="Truncate__StyledTruncate-sc-23o1d2-0 liVpTx width-fit"><span class="text-bold">Last commit message</span></div></th><th colSpan="1" class="Box-sc-g0xbh4-0 jMbWeI"><div title="Last commit date" class="Truncate__StyledTruncate-sc-23o1d2-0 liVpTx width-fit"><span class="text-bold">Last commit date</span></div></th></tr></thead><tbody><tr class="Box-sc-g0xbh4-0 gpqjiB"><td colSpan="3" class="bgColor-muted p-1 rounded-top-2"><div class="Box-sc-g0xbh4-0 dzCJzi"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone--vW4Cq prc-Heading-Heading-6CmGO" data-testid="screen-reader-heading">History</h2><a href="/clementvidon/Makefile_tutor/commits/main/" class="prc-Button-ButtonBase-c50BI d-none d-lg-flex LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":Raqj8pab:-loading-announcement"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-pTQ3x"><span class="fgColor-default">140 Commits</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><span role="tooltip" aria-label="140 Commits" id="history-icon-button-tooltip" class="Tooltip__TooltipBase-sc-17tf59c-0 hWlpPn tooltipped-n"><a href="/clementvidon/Makefile_tutor/commits/main/" class="prc-Button-ButtonBase-c50BI LinkButton-module__code-view-link-button--xvCGA flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby=":R1iqj8pab:-loading-announcement history-icon-button-tooltip"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-HKbr-"><span data-component="leadingVisual" class="prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB"><svg aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a></span></div></div></div></div></td></tr><tr class="react-directory-row undefined" id="folder-row-0"><td class="react-directory-row-name-cell-small-screen" colSpan="2"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file-directory-fill icon-directory" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="projects" aria-label="projects, (Directory)" class="Link--primary" href="/clementvidon/Makefile_tutor/tree/main/projects">projects</a></div></div></div></div></td><td class="react-directory-row-name-cell-large-screen" colSpan="1"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file-directory-fill icon-directory" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="projects" aria-label="projects, (Directory)" class="Link--primary" href="/clementvidon/Makefile_tutor/tree/main/projects">projects</a></div></div></div></div></td><td class="react-directory-row-commit-cell"><div class="Skeleton Skeleton--text"> </div></td><td><div class="Skeleton Skeleton--text"> </div></td></tr><tr class="react-directory-row undefined" id="folder-row-1"><td class="react-directory-row-name-cell-small-screen" colSpan="2"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title=".gitignore" aria-label=".gitignore, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/.gitignore">.gitignore</a></div></div></div></div></td><td class="react-directory-row-name-cell-large-screen" colSpan="1"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title=".gitignore" aria-label=".gitignore, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/.gitignore">.gitignore</a></div></div></div></div></td><td class="react-directory-row-commit-cell"><div class="Skeleton Skeleton--text"> </div></td><td><div class="Skeleton Skeleton--text"> </div></td></tr><tr class="react-directory-row undefined" id="folder-row-2"><td class="react-directory-row-name-cell-small-screen" colSpan="2"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="LICENCE" aria-label="LICENCE, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/LICENCE">LICENCE</a></div></div></div></div></td><td class="react-directory-row-name-cell-large-screen" colSpan="1"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="LICENCE" aria-label="LICENCE, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/LICENCE">LICENCE</a></div></div></div></div></td><td class="react-directory-row-commit-cell"><div class="Skeleton Skeleton--text"> </div></td><td><div class="Skeleton Skeleton--text"> </div></td></tr><tr class="react-directory-row undefined" id="folder-row-3"><td class="react-directory-row-name-cell-small-screen" colSpan="2"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="README.md" aria-label="README.md, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/README.md">README.md</a></div></div></div></div></td><td class="react-directory-row-name-cell-large-screen" colSpan="1"><div class="react-directory-filename-column"><svg aria-hidden="true" focusable="false" class="octicon octicon-file color-fg-muted" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Zm6.75.062V4.25c0 .138.112.25.25.25h2.688l-.011-.013-2.914-2.914-.013-.011Z"></path></svg><div class="overflow-hidden"><div class="react-directory-filename-cell"><div class="react-directory-truncate"><a title="README.md" aria-label="README.md, (File)" class="Link--primary" href="/clementvidon/Makefile_tutor/blob/main/README.md">README.md</a></div></div></div></div></td><td class="react-directory-row-commit-cell"><div class="Skeleton Skeleton--text"> </div></td><td><div class="Skeleton Skeleton--text"> </div></td></tr><tr class="Box-sc-g0xbh4-0 eNCcrz d-none" data-testid="view-all-files-row"><td colSpan="3" class="Box-sc-g0xbh4-0 bHTcCe"><div><button class="prc-Link-Link-85e08">View all files</button></div></td></tr></tbody></table></div><div class="Box-sc-g0xbh4-0 csrIcr"><div class="Box-sc-g0xbh4-0 bUQNHB"><div itemscope="" itemType="https://schema.org/abstract" class="Box-sc-g0xbh4-0 jPdcfu"><h2 class="_VisuallyHidden__VisuallyHidden-sc-11jhm7a-0 brGdpi">Repository files navigation</h2><nav class="Box-sc-g0xbh4-0 iphEWz prc-components-UnderlineWrapper-oOh5J" aria-label="Repository files"><ul class="prc-components-UnderlineItemList-b23Hf" role="list"><li class="Box-sc-g0xbh4-0 hUCRAk"><a class="prc-components-UnderlineItem-lJsg-" href="#" aria-current="page"><span data-component="icon"><svg aria-hidden="true" focusable="false" class="octicon octicon-book" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path></svg></span><span data-component="text" data-content="README">README</span></a></li><li class="Box-sc-g0xbh4-0 hUCRAk"><a class="prc-components-UnderlineItem-lJsg-" href="#"><span data-component="icon"><svg aria-hidden="true" focusable="false" class="octicon octicon-law" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path></svg></span><span data-component="text" data-content="CC-BY-SA-4.0 license">CC-BY-SA-4.0 license</span></a></li></ul></nav><button style="--button-color:fg.subtle" type="button" aria-label="Outline" aria-haspopup="true" aria-expanded="false" tabindex="0" class="Box-sc-g0xbh4-0 cwoBXV prc-Button-ButtonBase-c50BI" data-loading="false" data-size="medium" data-variant="invisible" aria-describedby=":Rr9ab:-loading-announcement" id=":Rr9ab:"><svg aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button></div><div class="Box-sc-g0xbh4-0 QkQOb js-snippet-clipboard-copy-unpositioned undefined" data-hpc="true"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 align="center" tabindex="-1" class="heading-element" dir="auto"> MAKEFILE TUTOR (GNU) </h1><a id="user-content-----makefile-tutor-gnu" class="anchor" aria-label="Permalink: MAKEFILE TUTOR (GNU) " href="#----makefile-tutor-gnu"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 align="center" tabindex="-1" class="heading-element" dir="auto"> <a href="#summary">Summary</a> <span> · </span> <a href="#usage">Usage</a> <span> · </span> <a href="#glossary">Glossary</a> <span> · </span> <a href="#syntax">Syntax</a> <span> · </span> <a href="#index">Index</a> <span> · </span> <a href="#sources">Sources</a> <span> · </span> <a href="#contact">Contact</a> </h3><a id="user-content-----summary----------usage----------glossary----------syntax----------index----------sources----------contact" class="anchor" aria-label="Permalink: Summary · Usage · Glossary · Syntax · Index · Sources · Contact" href="#----summary----------usage----------glossary----------syntax----------index----------sources----------contact"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Summary</h1><a id="user-content-summary" class="anchor" aria-label="Permalink: Summary" href="#summary"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Addressed to beginners and not to newcomers, the idea behind this tutorial is to <strong>focus on the essential</strong>. Anything that is not directly related to the template we are going to explore will not be covered here. On the other hand everything that is covered in this tutorial will be carefully detailed.</p> <p dir="auto">Initially intended to help 42 students to step up their Makefile skills through <strong>a C-focused documented template</strong> that evolves gradually, <strong>version by version</strong>. With the aim of making them more digestible and even tasty 🍔</p> <p dir="auto">Allow <strong>1 hour</strong> to complete this tutorial, plus some additional time to work with the <a href="https://github.com/clemedon/Makefile_tutor/tree/main/projects"><strong>examples</strong></a>. For those of you who are wondering, as I write this line, I have invested a total of 102 hours and 50 minutes in creating this tutorial.</p> <p dir="auto"><strong>TL;DR</strong> Refer to the bold text.</p> <p dir="auto"><a href="https://clemedon.github.io/Makefile_tutor/" rel="nofollow"><strong>→ GitHub Page ←</strong></a><br> <a href="https://github.com/clemedon/Makefile_tutor/"><strong>→ GitHub Repo ←</strong></a></p> <p dir="auto"><a href="http://creativecommons.org/licenses/by-sa/4.0/" rel="nofollow"><img src="https://camo.githubusercontent.com/8893a5ee2d7f73909733da3e88ef024aab2bb1fce0ada8155499b8db59b4d148/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d434325323042592d2d5341253230342e302d6c69676874677265792e737667" alt="CC BY-SA 4.0" data-canonical-src="https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg" style="max-width: 100%;"></a></p> <hr> <p dir="auto"><strong>Roadmap</strong></p> <ul class="contains-task-list"> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="https://clemedon.github.io/Makefile_tutor/" rel="nofollow">GitHub Page</a></li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> A <a href="#usage">ready to make</a> project of each template version</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#usage">bold text</a> that acts as a summary</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#version-1">v1</a> Simplest C project</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#version-2">v2</a> Project that include headers</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#version-3">v3</a> Project with any kind of directory structure</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#version-4">v4</a> Static library <em>+ introduce auto-gen dependencies</em></li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="#version-5">v5</a> Project that uses libraries</li> <li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> POSIX Makefile</li> </ul> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Usage</h1><a id="user-content-usage" class="anchor" aria-label="Permalink: Usage" href="#usage"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">This tutorial is designed to be read line by line <strong>linearly at first</strong>.</p> <p dir="auto">Then it can be quickly navigated thanks to the:</p> <ul dir="auto"> <li><strong>Brief</strong> of each version which is visible from the <a href="#index"><strong>Index</strong></a>.</li> <li><strong>Text in bold</strong> that compile the essence of this tutorial.</li> <li><a href="#index"><strong>Return to Index ↑</strong></a> buttons at the end of each version.</li> </ul> <p dir="auto">Each version of the template has an assigned directory in the <a href="https://github.com/clemedon/Makefile_tutor/tree/main/projects"><strong>projects</strong></a> directory of the repository, to play with a Makefile open a terminal and run:</p> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="git clone https://github.com/clemedon/Makefile_tutor.git cd Makefile_tutor/projects"><pre>git clone https://github.com/clemedon/Makefile_tutor.git <span class="pl-c1">cd</span> Makefile_tutor/projects</pre></div> <div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="cd <template_version> make <target>"><pre><span class="pl-c1">cd</span> <span class="pl-k"><</span>template_version<span class="pl-k">></span> make <span class="pl-k"><</span>target<span class="pl-k">></span></pre></div> <p dir="auto"><em>PS1 <strong><code>C++</code> users</strong> have to replace <code>CC = clang</code> with <code>CXX = g++</code> and <code>CFLAGS</code> with <code>CXXFLAGS</code>.</em></p> <p dir="auto"><em>PS2 feel free to <strong>fork me</strong> so as to remove everything that does not interest you and customize me according to your needs.</em></p> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Glossary</h1><a id="user-content-glossary" class="anchor" aria-label="Permalink: Glossary" href="#glossary"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Each <strong>version</strong> of the template has <strong>3 sections</strong>:</p> <ul dir="auto"> <li><strong>Structure</strong> is the project structure sketch.</li> <li><strong>Brief</strong> is a summary made from the bold parts of the template comments.</li> <li><strong>Template</strong> is a commented Makefile template with comments (that are always placed at the end of the template part that concerns them).</li> </ul> <p dir="auto">Our <strong>template</strong> will be articulated around the following <strong>parts</strong>:</p> <ul dir="auto"> <li><code>### BEG</code> Mark the template <strong>beginning</strong>.</li> <li><code>INGREDIENTS</code> Build <strong>variables</strong>.</li> <li><code>UTENSILS</code> Shell <strong>commands</strong>.</li> <li><code>RECIPES</code> Build and extra <strong>rules</strong>.</li> <li><code>SPEC</code> <strong>Special targets</strong>.</li> <li><code>#### END</code> Mark the template <strong>end</strong>.</li> </ul> <p dir="auto">According to make a <strong><code>rule</code></strong> is made of:</p> <ul dir="auto"> <li><code>targets</code> are the names of the <strong>goals</strong> we want to make. It can be a file or an action, the latter leading to a <em>pseudo target</em>.</li> <li><code>prerequisites</code> are the goals that must be achieved so that the <code>rule</code> can execute. Thus prerequisites are the <strong>targets dependencies</strong>.</li> <li><code>recipe</code> is the set of lines that <strong>begins with a <code>TAB</code></strong> character and appear in a rule context.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="target: prerequisite recipe line 1 recipe line 2 …"><pre><span class="pl-en">target</span>: prerequisite recipe line 1 recipe line 2 …</pre></div> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Syntax</h1><a id="user-content-syntax" class="anchor" aria-label="Permalink: Syntax" href="#syntax"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Like every Makefile the template uses a combination of Makefile syntax and shell script syntax. The <strong>shell script syntax</strong> is reserved and limited to recipe lines, by default those lines have to <strong>start with a <code>TAB</code></strong> character to be differentiated by make (and passed to the shell). The <strong>Makefile syntax</strong> is used for <strong>all the other lines</strong>.</p> <p dir="auto">About the <strong>equal signs</strong>:</p> <ul dir="auto"> <li><code>:=</code> <strong>simply expand</strong> the defined variable (like C <code>=</code>).</li> <li><code>=</code> <strong>recursively expand</strong> the defined variable (the expression is expanded afterward, when (and each time) the variable is used).</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="A := Did $(C) B = Did $(C) C = you understand ? all: $(info $(A)) # output "Did" $(info $(B)) # output "Did you understand ?""><pre><span class="pl-smi">A</span> := Did <span class="pl-s">$(<span class="pl-smi">C</span>)</span> <span class="pl-smi">B</span> = Did <span class="pl-s">$(<span class="pl-smi">C</span>)</span> <span class="pl-smi">C</span> = you understand ? <span class="pl-en">all</span>: $(info $(A)) <span class="pl-c"><span class="pl-c">#</span> output "Did"</span> $(info $(B)) <span class="pl-c"><span class="pl-c">#</span> output "Did you understand ?"</span></pre></div> <p dir="auto">About <strong>variables</strong> note that <code>${VAR}</code> and <code>$(VAR)</code> is exactly the same.</p> <p dir="auto"><strong>Automatic Variables</strong> expansion:</p> <ul dir="auto"> <li><code>$<</code> <strong>leftmost prerequisite</strong></li> <li><code>$@</code> <strong>current target</strong></li> <li><code>$^</code> <strong>all prerequisites</strong></li> <li><code>$(@D)</code> <strong>directory part</strong> of the file name of the target</li> <li><code>$(@F)</code> <strong>file part</strong> of the file name of the target</li> </ul> <p dir="auto"><em>Cf. Version 1 / Automatic variables in practice.</em></p> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Template</h1><a id="user-content-template" class="anchor" aria-label="Permalink: Template" href="#template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Index</h2><a id="user-content-index" class="anchor" aria-label="Permalink: Index" href="#index"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto"><a href="#version-1"><strong>Version 1 / Simplest C project</strong></a></p> <blockquote> <ul dir="auto"> <li>42 C coding style conventions</li> <li>builtin variables</li> <li>The C compilation implicit rule</li> <li>pattern rule contains <code>%</code> character</li> <li>Automatic variables in practice</li> <li>Illustration of a <code>make all</code></li> <li>C build recap</li> <li>parallelization enabled by <code>make --jobs</code></li> <li>the <code>.PHONY:</code> special target</li> </ul> </blockquote> <p dir="auto"><a href="#version-2"><strong>Version 2 / Project that include headers</strong></a></p> <blockquote> <ul dir="auto"> <li>preprocessor's flags</li> <li>print a custom message</li> <li>C compilation implicit rule is overwritten</li> <li><em>default goal</em> <code>all</code> appears first</li> <li><code>.SILENT:</code> silences the rules output</li> </ul> </blockquote> <p dir="auto"><a href="#version-3"><strong>Version 3 / Project with any kind of directory structure</strong></a></p> <blockquote> <ul dir="auto"> <li>split the line with a <code>backslash</code></li> <li>substitution reference so <code>main.c</code> becomes <code>src/main.c</code></li> <li>generate the <code>OBJ_DIR</code> based on <code>SRC_DIR</code></li> <li>compilation rule uses multiple source and object directories</li> </ul> </blockquote> <p dir="auto"><a href="#version-4"><strong>Version 4 / Static library</strong></a></p> <blockquote> <ul dir="auto"> <li>when a header file is modified the executable will rebuild</li> <li>automatically generate a list of dependencies</li> <li>build directory</li> <li>dependency files must be included</li> <li>hyphen symbol to prevent make from complaining</li> <li>creates a static library</li> </ul> </blockquote> <p dir="auto"><a href="#version-5"><strong>Version 5 / Project that uses libraries</strong></a></p> <blockquote> <ul dir="auto"> <li>system library linked by default</li> <li><code>addprefix</code> make function</li> <li>flags and libraries used by the linker</li> <li><code>dir</code> function</li> <li>Build with a library</li> <li>Linking with a library</li> <li>builds each of the required libraries</li> <li>call rules recursively</li> </ul> </blockquote> <p dir="auto"><a href="#bonus"><strong>Bonus</strong></a></p> <blockquote> <ul dir="auto"> <li><code>make</code> and <code>run</code> the <em>default goal</em></li> <li>print <code><target></code> recipe without executing it</li> <li>print the value of an arbitrary variable</li> <li>update the git repository</li> </ul> </blockquote> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Version 1</h2><a id="user-content-version-1" class="anchor" aria-label="Permalink: Version 1" href="#version-1"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v1 Structure</h3><a id="user-content-v1-structure" class="anchor" aria-label="Permalink: v1 Structure" href="#v1-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">The simplest, build a program called <code>icecream</code> with the following structure:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" before build: after build: . . ├── Makefile ├── Makefile └── main.c ├── main.o ├── main.c └── icecream"><pre class="notranslate"><code> before build: after build: . . ├── Makefile ├── Makefile └── main.c ├── main.o ├── main.c └── icecream </code></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v1 Brief</h3><a id="user-content-v1-brief" class="anchor" aria-label="Permalink: v1 Brief" href="#v1-brief"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>42 C coding style conventions</li> <li>builtin variables</li> <li>The C compilation implicit rule</li> <li>pattern rule contains <code>%</code> character</li> <li>Automatic variables in practice</li> <li>Illustration of a <code>make all</code></li> <li>C build recap</li> <li>parallelization enabled by <code>make --jobs</code></li> <li>the <code>.PHONY:</code> special target</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v1 Template</h3><a id="user-content-v1-template" class="anchor" aria-label="Permalink: v1 Template" href="#v1-template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="####################################### BEG_1 #### NAME := icecream #------------------------------------------------# # INGREDIENTS # #------------------------------------------------# # SRCS source files # OBJS object files # # CC compiler # CFLAGS compiler flags SRCS := main.c OBJS := main.o CC := clang CFLAGS := -Wall -Wextra -Werror #------------------------------------------------# # UTENSILS # #------------------------------------------------# # RM force remove # MAKEFLAGS make flags RM := rm -f MAKEFLAGS += --no-print-directory #------------------------------------------------# # RECIPES # #------------------------------------------------# # all default goal # $(NAME) linking .o -> binary # clean remove .o # fclean remove .o + binary # re remake default goal all: $(NAME) $(NAME): $(OBJS) $(CC) $(OBJS) -o $(NAME) clean: $(RM) $(OBJS) fclean: clean $(RM) $(NAME) re: $(MAKE) fclean $(MAKE) all #------------------------------------------------# # SPEC # #------------------------------------------------# .PHONY: clean fclean re ####################################### END_1 ####"><pre><span class="pl-c"><span class="pl-c">#</span>###################################### BEG_1 ####</span> <span class="pl-smi">NAME</span> := icecream <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> INGREDIENTS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SRCS source files</span> <span class="pl-c"><span class="pl-c">#</span> OBJS object files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> CC compiler</span> <span class="pl-c"><span class="pl-c">#</span> CFLAGS compiler flags</span> <span class="pl-smi">SRCS</span> := main.c <span class="pl-smi">OBJS</span> := main.o <span class="pl-smi">CC</span> := clang <span class="pl-smi">CFLAGS</span> := -Wall -Wextra -Werror <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> UTENSILS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RM force remove</span> <span class="pl-c"><span class="pl-c">#</span> MAKEFLAGS make flags</span> <span class="pl-smi">RM</span> := rm -f <span class="pl-smi">MAKEFLAGS</span> += --no-print-directory <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RECIPES #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> all default goal</span> <span class="pl-c"><span class="pl-c">#</span> $(NAME) linking .o -> binary</span> <span class="pl-c"><span class="pl-c">#</span> clean remove .o</span> <span class="pl-c"><span class="pl-c">#</span> fclean remove .o + binary</span> <span class="pl-c"><span class="pl-c">#</span> re remake default goal</span> <span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> $(CC) $(OBJS) -o $(NAME) <span class="pl-en">clean</span>: $(RM) $(OBJS) <span class="pl-en">fclean</span>: clean $(RM) $(NAME) <span class="pl-en">re</span>: $(MAKE) fclean $(MAKE) all <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SPEC #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c1">.PHONY</span>: clean fclean re <span class="pl-c"><span class="pl-c">#</span>###################################### END_1 ####</span></pre></div> <ul dir="auto"> <li>The choice of the <code>CC</code> and <code>CFLAGS</code> values, <code>NAME</code>, <code>clean</code>, <code>fclean</code>, <code>all</code> and <code>re</code> as the basic rules as well as not using a wildcard to auto generate the sources list is guided by the <strong>42 C coding style conventions</strong>, do not hesitate to disagree and change it (like renaming <code>clean</code> and <code>fclean</code> to the more GNU conventional <code>mostlyclean</code> and <code>clean</code> respectively).</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><code>MAKE</code> and <code>MAKEFLAGS</code> are <strong>builtin variables</strong> like <code>CFLAGS</code> and a lot of others that you can find in the <em>data-base</em> (<code>make --print-data-base</code> command). <code>MAKE</code> value corresponds to the <code>make</code> executable being run and <code>MAKEFLAGS</code> to its flags. When a Makefile is executed from another Makefile, the called's <code>MAKE</code> <code>MAKEFLAGS</code> variables inherit from the caller's <code>MAKE</code> <code>MAKEFLAGS</code> values.</li> </ul> <p dir="auto">Here we append <code>--no-print-directory</code> to <code>MAKEFLAGS</code> content to have a clearer output, try to remove it and <code>make re</code> to see the difference.</p> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><strong>The C compilation implicit rule</strong> looks like this:</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<"><pre><span class="pl-en"><span class="pl-c1">%</span>.o</span>: <span class="pl-c1">%</span>.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<</pre></div> <p dir="auto">Where <code>%.o</code> expands to each objects, <code>%.c</code> to each sources, <code>$@</code> to the first target (which is <code>%.o</code>) and <code>$<</code> to the leftmost prerequisite (which is <code>%.c</code>).</p> <p dir="auto"><em>As their name implies implicit rules are implicit and do not need to be written. As well as the builtin variables, all the implicit rules can be found in the data-base, accessible with <code>make -p -f/dev/null | less</code> command.</em></p> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>A <strong>pattern rule</strong> is a rule whose target <strong>contains</strong> a <strong><code>%</code> character</strong> (here <code>%.o: %.c</code>). This character means "exactly one of them". It is used here to say that each <code>.o</code> requires a <code>.c</code> with the same name and the <code>$(CC)…</code> recipe line will execute as many times as there are <code>.o: .c</code> pairs, thus creating for each source its corresponding object, one at a time.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><strong>Automatic variables in practice</strong>:</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Linking step $(NAME): $(OBJS) $(CC) $^ -o $@"><pre><span class="pl-c"><span class="pl-c">#</span> Linking step</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> $(CC) $^ -o $@</pre></div> <p dir="auto"><code>$@</code> expands to the <em>current target</em>, here we could have used <code>$(NAME)</code> instead.</p> <p dir="auto"><code>$^</code> expands to <em>all prerequisites</em>, here we could have used <code>$(OBJS)</code> instead but not <code>$<</code> that expands to the <em>leftmost prerequisite</em> and so only the first item found in <code>$(OBJS)</code>.</p> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Compiling step %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<"><pre><span class="pl-c"><span class="pl-c">#</span> Compiling step</span> <span class="pl-en"><span class="pl-c1">%</span>.o</span>: <span class="pl-c1">%</span>.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<</pre></div> <p dir="auto"><code>$<</code> expands to the <em>leftmost prerequisite</em>, here it could not have been replaced with <code>$(SRCS)</code> because <code>$(SRCS)</code> expands to all the sources at once which is not the case of the pattern rule <code>%.c</code>. On the other hand here <code>$<</code> is equivalent to <code>$^</code>, both will always expand to one source: the current one expanded by <code>%.c</code>. For the same reasons <code>$@</code> expands to <code>%.o</code> not to <code>$(OBJS)</code>.</p> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><strong>Illustration of a <code>make all</code></strong>:</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="all: $(NAME) 3 ← 2 $(NAME): $(OBJS) 2 ← 1 $(CC) $(OBJS) -o $(NAME) %.o: %.c 1 ← 0 $(CC) $(CFLAGS) -c -o $@ $<"><pre><span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> 3 ← 2 <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> 2 ← 1 $(CC) $(OBJS) -o $(NAME) <span class="pl-en"><span class="pl-c1">%</span>.o</span>: <span class="pl-c1">%</span>.c 1 ← 0 $(CC) $(CFLAGS) -c -o $@ $<</pre></div> <p dir="auto">The <code>all</code> target requires <code>icecream</code> that requires the <code>objects</code> that require the <code>sources</code> that requires… a programmer. In other words <code>all</code> creates <code>icecream</code> with the objects created with the sources that you have created.</p> <p dir="auto">Make will first trace its path to the lower level where it finds a raw material <code>3 → 2 → 1 → 0</code> (the <code>sources</code>) and then do it backward while building each resource that is required by the direct upper level encountered <code>0 → 1 → 2 → 3</code> (the <code>icecream</code>, our <em>final goal</em>).</p> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><strong>C build recap</strong> <code>%.o</code> target requires the sources to be compiled into objects, the <code>-c</code> option tells the compiler to only compile without linking. The <code>-o</code> option is used to specify the objects name. Afterward the <code>$(NAME)</code> target requires the linking the objects into a binary file whose name is specified with the <code>-o</code> flag.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>For the <code>re</code> rule we have no choice but make an external call to our Makefile because we should not rely on the order in which prerequisites are specified. For example <code>re: fclean all</code> wouldn't not be reliable if <strong>parallelization</strong> was <strong>enabled by <code>make --jobs</code></strong>.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>The prerequisites given to <strong>the <code>.PHONY:</code> special target</strong> become targets that make will run regardless of whether a file with that name exists. In short these prerequisites are our targets that don't bear the name of a file.</li> </ul> <p dir="auto">Try to remove the <code>.PHONY: re</code>, create a file named <code>re</code> at the Makefile level in the project directory and run <code>make re</code>. It won't work.</p> <p dir="auto">Now if you do the same with <code>all</code> it won't cause any problem, as we know prerequisites are completed before their targets and <code>all</code> has the sole action of invoking <code>$(NAME)</code>, as long as a rule doesn't have a recipe, <code>.PHONY</code> is not necessary.</p> <p dir="auto"><a href="#index"><strong>Return to Index ↑</strong></a></p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Version 2</h2><a id="user-content-version-2" class="anchor" aria-label="Permalink: Version 2" href="#version-2"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v2 Structure</h3><a id="user-content-v2-structure" class="anchor" aria-label="Permalink: v2 Structure" href="#v2-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">As above but for a project that <strong>includes header files</strong>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" before build: after build: . . ├── Makefile ├── Makefile ├── main.c ├── main.o └── icecream.h ├── main.c ├── icecream.h └── icecream"><pre class="notranslate"><code> before build: after build: . . ├── Makefile ├── Makefile ├── main.c ├── main.o └── icecream.h ├── main.c ├── icecream.h └── icecream </code></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v2 Brief</h3><a id="user-content-v2-brief" class="anchor" aria-label="Permalink: v2 Brief" href="#v2-brief"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>preprocessor's flags</li> <li>print a custom message</li> <li>C compilation implicit rule is overwritten</li> <li><em>default goal</em> <code>all</code> appears first</li> <li><code>.SILENT:</code> silences the rules output</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v2 Template</h3><a id="user-content-v2-template" class="anchor" aria-label="Permalink: v2 Template" href="#v2-template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="####################################### BEG_2 #### NAME := icecream #------------------------------------------------# # INGREDIENTS # #------------------------------------------------# # SRCS source files # OBJS object files # # CC compiler # CFLAGS compiler flags # CPPFLAGS preprocessor flags SRCS := main.c OBJS := main.o CC := clang CFLAGS := -Wall -Wextra -Werror CPPFLAGS := -I ."><pre><span class="pl-c"><span class="pl-c">#</span>###################################### BEG_2 ####</span> <span class="pl-smi">NAME</span> := icecream <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> INGREDIENTS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SRCS source files</span> <span class="pl-c"><span class="pl-c">#</span> OBJS object files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> CC compiler</span> <span class="pl-c"><span class="pl-c">#</span> CFLAGS compiler flags</span> <span class="pl-c"><span class="pl-c">#</span> CPPFLAGS preprocessor flags</span> <span class="pl-smi">SRCS</span> := main.c <span class="pl-smi">OBJS</span> := main.o <span class="pl-smi">CC</span> := clang <span class="pl-smi">CFLAGS</span> := -Wall -Wextra -Werror <span class="pl-smi">CPPFLAGS</span> := -I .</pre></div> <ul dir="auto"> <li><code>CPPFLAGS</code> is dedicated to <strong>preprocessor's flags</strong> like <code>-I <include_dir></code>, it allows you to no longer have to write the full path of a header but only its file name in the sources: <code>#include "icecream.h"</code> instead of <code>#include "../../path/to/include/icecream.h"</code>.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # UTENSILS # #------------------------------------------------# # RM force remove # MAKEFLAGS make flags RM := rm -f MAKEFLAGS += --no-print-directory #------------------------------------------------# # RECIPES # #------------------------------------------------# # all default goal # $(NAME) linking .o -> binary # %.o compilation .c -> .o # clean remove .o # fclean remove .o + binary # re remake default goal all: $(NAME) $(NAME): $(OBJS) $(CC) $(OBJS) -o $(NAME) $(info CREATED $(NAME)) %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) clean: $(RM) $(OBJS) fclean: clean $(RM) $(NAME) re: $(MAKE) fclean $(MAKE) all"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> UTENSILS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RM force remove</span> <span class="pl-c"><span class="pl-c">#</span> MAKEFLAGS make flags</span> <span class="pl-smi">RM</span> := rm -f <span class="pl-smi">MAKEFLAGS</span> += --no-print-directory <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RECIPES #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> all default goal</span> <span class="pl-c"><span class="pl-c">#</span> $(NAME) linking .o -> binary</span> <span class="pl-c"><span class="pl-c">#</span> %.o compilation .c -> .o</span> <span class="pl-c"><span class="pl-c">#</span> clean remove .o</span> <span class="pl-c"><span class="pl-c">#</span> fclean remove .o + binary</span> <span class="pl-c"><span class="pl-c">#</span> re remake default goal</span> <span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> $(CC) $(OBJS) -o $(NAME) $(info CREATED $(NAME)) <span class="pl-en"><span class="pl-c1">%</span>.o</span>: <span class="pl-c1">%</span>.c $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) <span class="pl-en">clean</span>: $(RM) $(OBJS) <span class="pl-en">fclean</span>: clean $(RM) $(NAME) <span class="pl-en">re</span>: $(MAKE) fclean $(MAKE) all</pre></div> <ul dir="auto"> <li>The <code>info</code> function is used here to <strong>print a custom message</strong> about what has just been built.</li> </ul> <p dir="auto"><em>We prefer <code>info</code> to shell <code>echo</code> because it is a make function. Also unlike <code>echo</code> that can only be used inside a recipe, <code>info</code> can be used anywhere in a Makefile which makes it powerful for debugging.</em></p> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>The <strong>C compilation implicit rule is overwritten</strong> with an explicit equivalent which let us add an <code>info</code> statement to it.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>The order in which the rules are written does not matter as long as our <strong>default goal <code>all</code> appears first</strong> (the rule that will be triggered by a simple <code>make</code> command).</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # SPEC # #------------------------------------------------# .PHONY: clean fclean re .SILENT:"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SPEC #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c1">.PHONY</span>: clean fclean re <span class="pl-c1">.SILENT</span>:</pre></div> <ul dir="auto"> <li>Normally make prints each line of a rule's recipe before it is executed. The special target <strong><code>.SILENT:</code> silences the rules output</strong> specified as prerequisites, when it is used without prerequisites it silents all the rules (implicit included).</li> </ul> <p dir="auto"><em>To silence at the recipe-line level we can prefix the wanted recipe lines with an <code>@</code> symbol.</em></p> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="####################################### END_2 ####"><pre><span class="pl-c"><span class="pl-c">#</span>###################################### END_2 ####</span></pre></div> <p dir="auto"><a href="#index"><strong>Return to Index ↑</strong></a></p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Version 3</h2><a id="user-content-version-3" class="anchor" aria-label="Permalink: Version 3" href="#version-3"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v3 Structure</h3><a id="user-content-v3-structure" class="anchor" aria-label="Permalink: v3 Structure" href="#v3-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">As above but a more complex project structure with <strong>multiple source directories</strong> and their <strong>corresponding object directories</strong>:</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" before build: after build: . . ├── src ├── src │ ├── base │ ├── base │ │ ├── water.c │ │ ├── water.c │ │ └── milk.c │ │ └── milk.c │ ├── arom │ ├── arom │ │ └── coco.c │ │ └── coco.c │ └── main.c │ └── main.c ├── include ├── obj │ └── icecream.h │ ├── base └── Makefile │ │ ├── water.o │ │ └── milk.o │ ├── arom │ │ └── coco.o │ └── main.o ├── include │ └── icecream.h ├── Makefile └── icecream"><pre class="notranslate"><code> before build: after build: . . ├── src ├── src │ ├── base │ ├── base │ │ ├── water.c │ │ ├── water.c │ │ └── milk.c │ │ └── milk.c │ ├── arom │ ├── arom │ │ └── coco.c │ │ └── coco.c │ └── main.c │ └── main.c ├── include ├── obj │ └── icecream.h │ ├── base └── Makefile │ │ ├── water.o │ │ └── milk.o │ ├── arom │ │ └── coco.o │ └── main.o ├── include │ └── icecream.h ├── Makefile └── icecream </code></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v3 Brief</h3><a id="user-content-v3-brief" class="anchor" aria-label="Permalink: v3 Brief" href="#v3-brief"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>split the line with a <code>backslash</code></li> <li>substitution reference so <code>main.c</code> becomes <code>src/main.c</code></li> <li>generate the <code>OBJ_DIR</code> based on <code>SRC_DIR</code></li> <li>compilation rule uses multiple source and object directories</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v3 Template</h3><a id="user-content-v3-template" class="anchor" aria-label="Permalink: v3 Template" href="#v3-template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="####################################### BEG_3 #### NAME := icecream #------------------------------------------------# # INGREDIENTS # #------------------------------------------------# # SRC_DIR source directory # OBJ_DIR object directory # SRCS source files # OBJS object files # # CC compiler # CFLAGS compiler flags # CPPFLAGS preprocessor flags SRC_DIR := src OBJ_DIR := obj SRCS := \ main.c \ arom/coco.c \ base/milk.c \ base/water.c SRCS := $(SRCS:%=$(SRC_DIR)/%) OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) CC := clang CFLAGS := -Wall -Wextra -Werror CPPFLAGS := -I include"><pre><span class="pl-c"><span class="pl-c">#</span>###################################### BEG_3 ####</span> <span class="pl-smi">NAME</span> := icecream <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> INGREDIENTS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SRC_DIR source directory</span> <span class="pl-c"><span class="pl-c">#</span> OBJ_DIR object directory</span> <span class="pl-c"><span class="pl-c">#</span> SRCS source files</span> <span class="pl-c"><span class="pl-c">#</span> OBJS object files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> CC compiler</span> <span class="pl-c"><span class="pl-c">#</span> CFLAGS compiler flags</span> <span class="pl-c"><span class="pl-c">#</span> CPPFLAGS preprocessor flags</span> <span class="pl-smi">SRC_DIR</span> := src <span class="pl-smi">OBJ_DIR</span> := obj <span class="pl-smi">SRCS</span> := <span class="pl-cce">\</span> main.c <span class="pl-cce">\</span> arom/coco.c <span class="pl-cce">\</span> base/milk.c <span class="pl-cce">\</span> base/water.c <span class="pl-smi">SRCS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:%=<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%</span>)</span> <span class="pl-smi">OBJS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%.c=<span class="pl-s">$(<span class="pl-smi">OBJ_DIR</span>)</span>/%.o</span>)</span> <span class="pl-smi">CC</span> := clang <span class="pl-smi">CFLAGS</span> := -Wall -Wextra -Werror <span class="pl-smi">CPPFLAGS</span> := -I include</pre></div> <ul dir="auto"> <li>We can <strong>split the line</strong> by ending it <strong>with a <code>backslash</code></strong> to increase the readability of <code>SRCS</code> content and facilitate its modification.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>A string <strong>substitution reference</strong> substitutes the value of each item of a variable with the specified alterations. <code>$(SRCS:%=$(SRC_DIR)/%)</code> means that each item of <code>SRCS</code> represented by <code>%</code> becomes itself (<code>%</code>) plus the <code>$(SRC_DIR)/</code> alteration, so <code>main.c</code> becomes <code>src/main.c</code>. <code>OBJS</code> will then use the same process to convert <code>src/main.c</code> into <code>obj/main.o</code>, based on <code>OBJ_DIR</code> and the new value of <code>SRCS</code>.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # UTENSILS # #------------------------------------------------# # RM force remove # MAKEFLAGS make flags # DIR_DUP duplicate directory tree RM := rm -f MAKEFLAGS += --no-print-directory DIR_DUP = mkdir -p $(@D)"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> UTENSILS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RM force remove</span> <span class="pl-c"><span class="pl-c">#</span> MAKEFLAGS make flags</span> <span class="pl-c"><span class="pl-c">#</span> DIR_DUP duplicate directory tree</span> <span class="pl-smi">RM</span> := rm -f <span class="pl-smi">MAKEFLAGS</span> += --no-print-directory <span class="pl-smi">DIR_DUP</span> = mkdir -p <span class="pl-s">$(<span class="pl-smi">@D</span>)</span></pre></div> <ul dir="auto"> <li><code>DIR_DUP</code> will <strong>generate the <code>OBJ_DIR</code> based on <code>SRC_DIR</code></strong> structure with <code>mkdir -p</code> which creates the directory and the parents directories if missing, and <code>$(@D)</code> that will expand to the directory part of the target, as we've seen in the <a href="#syntax">syntax</a> section.</li> </ul> <p dir="auto"><em>This will work with every possible kind of src directory structure.</em></p> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # RECIPES # #------------------------------------------------# # all default goal # $(NAME) linking .o -> binary # %.o compilation .c -> .o # clean remove .o # fclean remove .o + binary # re remake default goal all: $(NAME) $(NAME): $(OBJS) $(CC) $(OBJS) -o $(NAME) $(info CREATED $(NAME)) $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) clean: $(RM) $(OBJS) fclean: clean $(RM) $(NAME) re: $(MAKE) fclean $(MAKE) all"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RECIPES #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> all default goal</span> <span class="pl-c"><span class="pl-c">#</span> $(NAME) linking .o -> binary</span> <span class="pl-c"><span class="pl-c">#</span> %.o compilation .c -> .o</span> <span class="pl-c"><span class="pl-c">#</span> clean remove .o</span> <span class="pl-c"><span class="pl-c">#</span> fclean remove .o + binary</span> <span class="pl-c"><span class="pl-c">#</span> re remake default goal</span> <span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> $(CC) $(OBJS) -o $(NAME) $(info CREATED $(NAME)) <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">OBJ_DIR</span>)</span>/<span class="pl-c1">%</span>.o</span>: <span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/<span class="pl-c1">%</span>.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) <span class="pl-en">clean</span>: $(RM) $(OBJS) <span class="pl-en">fclean</span>: clean $(RM) $(NAME) <span class="pl-en">re</span>: $(MAKE) fclean $(MAKE) all</pre></div> <ul dir="auto"> <li>The <strong>compilation rule</strong> <code>.o: %.c</code> becomes <code>$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c</code>, since our structure <strong>uses dedicated source and object directories</strong>.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # SPEC # #------------------------------------------------# .PHONY: clean fclean re .SILENT: ####################################### END_3 ####"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SPEC #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c1">.PHONY</span>: clean fclean re <span class="pl-c1">.SILENT</span>: <span class="pl-c"><span class="pl-c">#</span>###################################### END_3 ####</span></pre></div> <p dir="auto"><a href="#index"><strong>Return to Index ↑</strong></a></p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Version 4</h2><a id="user-content-version-4" class="anchor" aria-label="Permalink: Version 4" href="#version-4"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v4 Structure</h3><a id="user-content-v4-structure" class="anchor" aria-label="Permalink: v4 Structure" href="#v4-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Builds a <strong>library</strong> so there are no <code>main.c</code>. We generate <strong>dependencies</strong> that are stored with the objects. Therefor we rename the <code>obj</code> directory into a more general <code>.build</code> directory.</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" before build: after build: . . ├── src ├── src │ ├── base │ ├── base │ │ ├── water.c │ │ ├── water.c │ │ └── milk.c │ │ └── milk.c │ └── arom │ └── arom │ └── coco.c │ └── coco.c ├── include ├── include │ └── icecream.h │ └── icecream.h └── Makefile ├── .build │ ├── base │ │ ├── water.o │ │ ├── water.d │ │ ├── milk.o │ │ └── milk.d │ └── arom │ ├── coco.o │ └── coco.d ├── Makefile └── libicecream.a"><pre class="notranslate"><code> before build: after build: . . ├── src ├── src │ ├── base │ ├── base │ │ ├── water.c │ │ ├── water.c │ │ └── milk.c │ │ └── milk.c │ └── arom │ └── arom │ └── coco.c │ └── coco.c ├── include ├── include │ └── icecream.h │ └── icecream.h └── Makefile ├── .build │ ├── base │ │ ├── water.o │ │ ├── water.d │ │ ├── milk.o │ │ └── milk.d │ └── arom │ ├── coco.o │ └── coco.d ├── Makefile └── libicecream.a </code></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v4 Brief</h3><a id="user-content-v4-brief" class="anchor" aria-label="Permalink: v4 Brief" href="#v4-brief"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>when a header file is modified the executable will rebuild</li> <li>automatically generate a list of dependencies</li> <li>build directory</li> <li>dependency files must be included</li> <li>hyphen symbol to prevent make from complaining</li> <li>creates a static library</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v4 Template</h3><a id="user-content-v4-template" class="anchor" aria-label="Permalink: v4 Template" href="#v4-template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="####################################### BEG_4 #### NAME := libicecream.a #------------------------------------------------# # INGREDIENTS # #------------------------------------------------# # SRC_DIR source directory # SRCS source files # # BUILD_DIR object directory # OBJS object files # DEPS dependency files # # CC compiler # CFLAGS compiler flags # CPPFLAGS preprocessor flags SRC_DIR := src SRCS := \ arom/coco.c \ base/milk.c \ base/water.c SRCS := $(SRCS:%=$(SRC_DIR)/%) BUILD_DIR := .build OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) DEPS := $(OBJS:.o=.d) CC := clang CFLAGS := -Wall -Wextra -Werror CPPFLAGS := -MMD -MP -I include AR := ar ARFLAGS := -r -c -s"><pre><span class="pl-c"><span class="pl-c">#</span>###################################### BEG_4 ####</span> <span class="pl-smi">NAME</span> := libicecream.a <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> INGREDIENTS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SRC_DIR source directory</span> <span class="pl-c"><span class="pl-c">#</span> SRCS source files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> BUILD_DIR object directory</span> <span class="pl-c"><span class="pl-c">#</span> OBJS object files</span> <span class="pl-c"><span class="pl-c">#</span> DEPS dependency files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> CC compiler</span> <span class="pl-c"><span class="pl-c">#</span> CFLAGS compiler flags</span> <span class="pl-c"><span class="pl-c">#</span> CPPFLAGS preprocessor flags</span> <span class="pl-smi">SRC_DIR</span> := src <span class="pl-smi">SRCS</span> := <span class="pl-cce">\</span> arom/coco.c <span class="pl-cce">\</span> base/milk.c <span class="pl-cce">\</span> base/water.c <span class="pl-smi">SRCS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:%=<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%</span>)</span> <span class="pl-smi">BUILD_DIR</span> := .build <span class="pl-smi">OBJS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%.c=<span class="pl-s">$(<span class="pl-smi">BUILD_DIR</span>)</span>/%.o</span>)</span> <span class="pl-smi">DEPS</span> := <span class="pl-s">$(<span class="pl-smi">OBJS:.o=.d</span>)</span> <span class="pl-smi">CC</span> := clang <span class="pl-smi">CFLAGS</span> := -Wall -Wextra -Werror <span class="pl-smi">CPPFLAGS</span> := -MMD -MP -I include <span class="pl-smi">AR</span> := ar <span class="pl-smi">ARFLAGS</span> := -r -c -s</pre></div> <ul dir="auto"> <li>Unlike with sources, <strong>when a header file is modified</strong> make has no way of knowing this and will not consider <strong>the executable</strong> to be out of date, and therefor <strong>will</strong> not <strong>rebuild</strong> it. In order to change this behavior we should add the appropriate header files as additional prerequisites:</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#before #after main.o: main.c main.o: main.c icecream.h clang -c $< -o $@ clang -c $< -o $@"><pre><span class="pl-c"><span class="pl-c">#</span>before #after</span> <span class="pl-en">main.o</span>: main.c main.o: main.c icecream.h clang -c $< -o $@ clang -c $< -o $@</pre></div> <ul dir="auto"> <li> <p dir="auto">Doing this manually for multiple sources and headers is both tedious and error prone. By adding <code>-MMD</code> to <code>CPPFLAGS</code> our compiler will <strong>automatically generate a list of dependencies</strong> for each object file encountered during the compilation. The <code>-MP</code> option prevents errors that are triggered if a header file has been deleted or renamed.</p> <p dir="auto">Dependency files must be included into our Makefile right after the objects creation so to obtain their names we copy <code>OBJS</code> into <code>DEPS</code> and use <em>substitution reference</em> to turn <code>.o</code> part of their name into <code>.d</code>.</p> </li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>We change our old <code>OBJ_DIR = obj</code> for a <code>BUILD_DIR = .build</code>, a hidden <strong>build directory</strong> that will contain our dependency files in addition to our objects.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>A static library is not a binary but a collection of objects so we use <code>ar</code> to <strong>creates a static library</strong> during the linking step of the build. <code>-r</code> to replace the older objects with the new ones with <code>-c</code> to create the library if it does not exist and <code>-s</code> to write an index into the archive or update an existing one.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # UTENSILS # #------------------------------------------------# # RM force remove # MAKEFLAGS make flags # DIR_DUP duplicate directory tree RM := rm -f MAKEFLAGS += --no-print-directory DIR_DUP = mkdir -p $(@D) #------------------------------------------------# # RECIPES # #------------------------------------------------# # all default goal # $(NAME) link .o -> library # %.o compilation .c -> .o # clean remove .o # fclean remove .o + binary # re remake default goal all: $(NAME) $(NAME): $(OBJS) $(AR) $(ARFLAGS) $(NAME) $(OBJS) $(info CREATED $(NAME)) $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) -include $(DEPS) clean: $(RM) $(OBJS) $(DEPS) fclean: clean $(RM) $(NAME) re: $(MAKE) fclean $(MAKE) all"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> UTENSILS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RM force remove</span> <span class="pl-c"><span class="pl-c">#</span> MAKEFLAGS make flags</span> <span class="pl-c"><span class="pl-c">#</span> DIR_DUP duplicate directory tree</span> <span class="pl-smi">RM</span> := rm -f <span class="pl-smi">MAKEFLAGS</span> += --no-print-directory <span class="pl-smi">DIR_DUP</span> = mkdir -p <span class="pl-s">$(<span class="pl-smi">@D</span>)</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RECIPES #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> all default goal</span> <span class="pl-c"><span class="pl-c">#</span> $(NAME) link .o -> library</span> <span class="pl-c"><span class="pl-c">#</span> %.o compilation .c -> .o</span> <span class="pl-c"><span class="pl-c">#</span> clean remove .o</span> <span class="pl-c"><span class="pl-c">#</span> fclean remove .o + binary</span> <span class="pl-c"><span class="pl-c">#</span> re remake default goal</span> <span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> $(AR) $(ARFLAGS) $(NAME) $(OBJS) $(info CREATED $(NAME)) <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">BUILD_DIR</span>)</span>/<span class="pl-c1">%</span>.o</span>: <span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/<span class="pl-c1">%</span>.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) <span class="pl-k">-include</span> <span class="pl-s">$(<span class="pl-smi">DEPS</span>)</span> <span class="pl-en">clean</span>: $(RM) $(OBJS) $(DEPS) <span class="pl-en">fclean</span>: clean $(RM) $(NAME) <span class="pl-en">re</span>: $(MAKE) fclean $(MAKE) all</pre></div> <ul dir="auto"> <li><strong>Dependency files</strong> are written in the make language and <strong>must be included</strong> into our Makefile to be read. The <code>include</code> directive work the same as C <code>#include</code>, it tells make to suspend its current Makefile reading and read the included files before continuing. Make sure to include the dependencies after they are created → after the compilation rule that invoke <code>-MMD</code> via <code>$(CPPFLAGS)</code>.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>The purpose of the <code>-include $(DEPS)</code> initial <strong>hyphen symbol</strong> is <strong>to prevent make from complaining</strong> when a non-zero status code is encountered, which can be caused here by a missing files from our generated dependency files list.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # SPEC # #------------------------------------------------# .PHONY: clean fclean re .SILENT: ####################################### END_4 ####"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SPEC #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c1">.PHONY</span>: clean fclean re <span class="pl-c1">.SILENT</span>: <span class="pl-c"><span class="pl-c">#</span>###################################### END_4 ####</span></pre></div> <p dir="auto"><a href="#index"><strong>Return to Index ↑</strong></a></p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Version 5</h2><a id="user-content-version-5" class="anchor" aria-label="Permalink: Version 5" href="#version-5"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v5 Structure</h3><a id="user-content-v5-structure" class="anchor" aria-label="Permalink: v5 Structure" href="#v5-structure"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <p dir="auto">Builds an <code>icecream</code> <strong>program that uses</strong> <code>libbase</code> and <code>libarom</code> <strong>libraries</strong>. Both libraries are v4 based.</p> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" before build: after build: . . ├── src ├── src │ └── main.c │ └── main.c ├── lib ├── lib │ ├── libbase │ ├── libbase │ │ ├── src │ │ ├── src │ │ │ ├── water.c │ │ │ ├── water.c │ │ │ └── milk.c │ │ │ └── milk.c │ │ ├── include │ │ ├── include │ │ │ └── base.h │ │ │ └── base.h │ │ └── Makefile │ │ ├── .build │ └── libarom │ │ │ ├── water.o │ ├── src │ │ │ ├── water.d │ │ ├── coco.c │ │ │ ├── milk.o │ │ └── cherry.c │ │ │ └── milk.d │ ├── include │ │ ├── Makefile │ │ └── arom.h │ │ └── libbase.a │ └── Makefile │ └── libarom ├── include │ ├── src │ └── icecream.h │ │ ├── coco.c └── Makefile │ │ └── cherry.c │ ├── include │ │ └── arom.h │ ├── .build │ │ ├── coco.o │ │ ├── coco.d │ │ ├── cherry.o │ │ └── cherry.d │ ├── Makefile │ └── libarom.a ├── include │ └── icecream.h ├── .build │ ├── main.o │ └── main.d ├── Makefile └── icecream"><pre class="notranslate"><code> before build: after build: . . ├── src ├── src │ └── main.c │ └── main.c ├── lib ├── lib │ ├── libbase │ ├── libbase │ │ ├── src │ │ ├── src │ │ │ ├── water.c │ │ │ ├── water.c │ │ │ └── milk.c │ │ │ └── milk.c │ │ ├── include │ │ ├── include │ │ │ └── base.h │ │ │ └── base.h │ │ └── Makefile │ │ ├── .build │ └── libarom │ │ │ ├── water.o │ ├── src │ │ │ ├── water.d │ │ ├── coco.c │ │ │ ├── milk.o │ │ └── cherry.c │ │ │ └── milk.d │ ├── include │ │ ├── Makefile │ │ └── arom.h │ │ └── libbase.a │ └── Makefile │ └── libarom ├── include │ ├── src │ └── icecream.h │ │ ├── coco.c └── Makefile │ │ └── cherry.c │ ├── include │ │ └── arom.h │ ├── .build │ │ ├── coco.o │ │ ├── coco.d │ │ ├── cherry.o │ │ └── cherry.d │ ├── Makefile │ └── libarom.a ├── include │ └── icecream.h ├── .build │ ├── main.o │ └── main.d ├── Makefile └── icecream </code></pre></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v5 Brief</h3><a id="user-content-v5-brief" class="anchor" aria-label="Permalink: v5 Brief" href="#v5-brief"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <ul dir="auto"> <li>system library linked by default</li> <li><code>addprefix</code> make function</li> <li>flags and libraries used by the linker</li> <li><code>dir</code> function</li> <li>Build with a library</li> <li>Linking with a library</li> <li>builds each of the required libraries</li> <li>call rules recursively</li> </ul> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">v5 Template</h3><a id="user-content-v5-template" class="anchor" aria-label="Permalink: v5 Template" href="#v5-template"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# @author clemedon (Clément Vidon) ####################################### BEG_5 #### NAME := icecream #------------------------------------------------# # INGREDIENTS # #------------------------------------------------# # LIBS libraries to be used # LIBS_TARGET libraries to be built # # INCS header file locations # # SRC_DIR source directory # SRCS source files # # BUILD_DIR build directory # OBJS object files # DEPS dependency files # # CC compiler # CFLAGS compiler flags # CPPFLAGS preprocessor flags # LDFLAGS linker flags # LDLIBS libraries name LIBS := arom base m LIBS_TARGET := \ lib/libarom/libarom.a \ lib/libbase/libbase.a INCS := include \ lib/libarom/include \ lib/libbase/include SRC_DIR := src SRCS := main.c SRCS := $(SRCS:%=$(SRC_DIR)/%) BUILD_DIR := .build OBJS := $(SRCS:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) DEPS := $(OBJS:.o=.d) CC := clang CFLAGS := -Wall -Wextra -Werror CPPFLAGS := $(addprefix -I,$(INCS)) -MMD -MP LDFLAGS := $(addprefix -L,$(dir $(LIBS_TARGET))) LDLIBS := $(addprefix -l,$(LIBS))"><pre><span class="pl-c"><span class="pl-c">#</span> @author clemedon (Clément Vidon)</span> <span class="pl-c"><span class="pl-c">#</span>###################################### BEG_5 ####</span> <span class="pl-smi">NAME</span> := icecream <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> INGREDIENTS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> LIBS libraries to be used</span> <span class="pl-c"><span class="pl-c">#</span> LIBS_TARGET libraries to be built</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> INCS header file locations</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> SRC_DIR source directory</span> <span class="pl-c"><span class="pl-c">#</span> SRCS source files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> BUILD_DIR build directory</span> <span class="pl-c"><span class="pl-c">#</span> OBJS object files</span> <span class="pl-c"><span class="pl-c">#</span> DEPS dependency files</span> <span class="pl-c"><span class="pl-c">#</span></span> <span class="pl-c"><span class="pl-c">#</span> CC compiler</span> <span class="pl-c"><span class="pl-c">#</span> CFLAGS compiler flags</span> <span class="pl-c"><span class="pl-c">#</span> CPPFLAGS preprocessor flags</span> <span class="pl-c"><span class="pl-c">#</span> LDFLAGS linker flags</span> <span class="pl-c"><span class="pl-c">#</span> LDLIBS libraries name</span> <span class="pl-smi">LIBS</span> := arom base m <span class="pl-smi">LIBS_TARGET</span> := <span class="pl-cce">\</span> lib/libarom/libarom.a <span class="pl-cce">\</span> lib/libbase/libbase.a <span class="pl-smi">INCS</span> := include <span class="pl-cce">\</span> lib/libarom/include <span class="pl-cce">\</span> lib/libbase/include <span class="pl-smi">SRC_DIR</span> := src <span class="pl-smi">SRCS</span> := main.c <span class="pl-smi">SRCS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:%=<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%</span>)</span> <span class="pl-smi">BUILD_DIR</span> := .build <span class="pl-smi">OBJS</span> := <span class="pl-s">$(<span class="pl-smi">SRCS:<span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/%.c=<span class="pl-s">$(<span class="pl-smi">BUILD_DIR</span>)</span>/%.o</span>)</span> <span class="pl-smi">DEPS</span> := <span class="pl-s">$(<span class="pl-smi">OBJS:.o=.d</span>)</span> <span class="pl-smi">CC</span> := clang <span class="pl-smi">CFLAGS</span> := -Wall -Wextra -Werror <span class="pl-smi">CPPFLAGS</span> := <span class="pl-s">$(<span class="pl-c1">addprefix</span> -I,<span class="pl-s">$(<span class="pl-smi">INCS</span>)</span>)</span> -MMD -MP <span class="pl-smi">LDFLAGS</span> := <span class="pl-s">$(<span class="pl-c1">addprefix</span> -L,<span class="pl-s">$(<span class="pl-c1">dir</span> <span class="pl-s">$(<span class="pl-smi">LIBS_TARGET</span>)</span>)</span>)</span> <span class="pl-smi">LDLIBS</span> := <span class="pl-s">$(<span class="pl-c1">addprefix</span> -l,<span class="pl-s">$(<span class="pl-smi">LIBS</span>)</span>)</span></pre></div> <ul dir="auto"> <li>We can notice that the <code>m</code> library from <code>LIBS</code> is not mentionned in <code>LIBS_TARGET</code> for the reason that <code>m</code> is a <strong>system library</strong> (<code>libm</code> for mathematical functions found in <code>math.h</code>). Unlike the <code>libc</code> which is linked by default (we don't need to provide <code>-lc</code> flag to our linker) the <code>libm</code> is not <strong>linked by default</strong>.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>In <code>CPPFLAGS</code> we use <strong><code>addprefix</code></strong> that, as its name suggests is a <strong>make function</strong> that allows you to add a prefix, here a <code>-I</code> to each of the item found in <code>$(INCS)</code> (that contains the paths to our project and libraries headers).</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><code>LDFLAGS</code> and <code>LDLIBS</code> contain the <strong>flags and libraries</strong> that will be <strong>used by the linker</strong> <code>ld</code> to link the library to our project sources.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>The <strong><code>dir</code> function</strong> means that we want to keep only directory part of the given item, there exists a <code>notdir</code> function that does the opposite to keep only the file name of the given item.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><strong>Build with a library</strong> requires three flags: <code>-I</code> tell the compiler where to find the lib header files, <code>-L</code> tells the linker where to look for the library and <code>-l</code> the name of this library (without its conventional <code>lib</code> prefix).</li> </ul> <p dir="auto">For example: <code>-I lib/libarom/include -L lib/libarom -l arom</code></p> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content=" #------------------------------------------------# # UTENSILS # #------------------------------------------------# # RM force remove # MAKEFLAGS make flags # DIR_DUP duplicate directory tree RM := rm -f MAKEFLAGS += --silent --no-print-directory DIR_DUP = mkdir -p $(@D) #------------------------------------------------# # RECIPES # #------------------------------------------------# # all default goal # $(NAME) link .o -> archive # $(LIBS) build libraries # %.o compilation .c -> .o # clean remove .o # fclean remove .o + binary # re remake default goal # run run the program # info print the default goal recipe all: $(NAME) $(NAME): $(OBJS) $(LIBS_TARGET) $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(NAME) $(info CREATED $(NAME)) $(LIBS_TARGET): $(MAKE) -C $(@D) $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) -include $(DEPS) clean: for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f clean; done $(RM) $(OBJS) $(DEPS) fclean: clean for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f fclean; done $(RM) $(NAME) re: $(MAKE) fclean $(MAKE) all"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> UTENSILS #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RM force remove</span> <span class="pl-c"><span class="pl-c">#</span> MAKEFLAGS make flags</span> <span class="pl-c"><span class="pl-c">#</span> DIR_DUP duplicate directory tree</span> <span class="pl-smi">RM</span> := rm -f <span class="pl-smi">MAKEFLAGS</span> += --silent --no-print-directory <span class="pl-smi">DIR_DUP</span> = mkdir -p <span class="pl-s">$(<span class="pl-smi">@D</span>)</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> RECIPES #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> all default goal</span> <span class="pl-c"><span class="pl-c">#</span> $(NAME) link .o -> archive</span> <span class="pl-c"><span class="pl-c">#</span> $(LIBS) build libraries</span> <span class="pl-c"><span class="pl-c">#</span> %.o compilation .c -> .o</span> <span class="pl-c"><span class="pl-c">#</span> clean remove .o</span> <span class="pl-c"><span class="pl-c">#</span> fclean remove .o + binary</span> <span class="pl-c"><span class="pl-c">#</span> re remake default goal</span> <span class="pl-c"><span class="pl-c">#</span> run run the program</span> <span class="pl-c"><span class="pl-c">#</span> info print the default goal recipe</span> <span class="pl-en">all</span>: <span class="pl-s">$(<span class="pl-smi">NAME</span>)</span> <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">NAME</span>)</span></span>: <span class="pl-s">$(<span class="pl-smi">OBJS</span>)</span> <span class="pl-s">$(<span class="pl-smi">LIBS_TARGET</span>)</span> $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(NAME) $(info CREATED $(NAME)) <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">LIBS_TARGET</span>)</span></span>: $(MAKE) -C $(@D) <span class="pl-en"><span class="pl-s">$(<span class="pl-smi">BUILD_DIR</span>)</span>/<span class="pl-c1">%</span>.o</span>: <span class="pl-s">$(<span class="pl-smi">SRC_DIR</span>)</span>/<span class="pl-c1">%</span>.c $(DIR_DUP) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(info CREATED $@) <span class="pl-k">-include</span> <span class="pl-s">$(<span class="pl-smi">DEPS</span>)</span> <span class="pl-en">clean</span>: for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f clean; done $(RM) $(OBJS) $(DEPS) <span class="pl-en">fclean</span>: clean for f in $(dir $(LIBS_TARGET)); do $(MAKE) -C $$f fclean; done $(RM) $(NAME) <span class="pl-en">re</span>: $(MAKE) fclean $(MAKE) all</pre></div> <ul dir="auto"> <li><strong>Linking with a library</strong> requires special attention to the order of the linking flags. In our case we need to make sure that <code>$(LDFLAGS)</code> and <code>$(LDLIBS)</code> passes respectively before and after the <code>$(OBJS)</code> in the linking recipe.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li><code>$(LIBS_TARGET)</code> rule <strong>builds each of the required libraries</strong> found in the <code>INGREDIENTS</code> part. It is a <code>$(NAME)</code> prerequisite for the same reason as <code>$(OBJS)</code> because our <em>final goal</em> needs the libraries as well as the objects to be built.</li> </ul> <p dir="auto"><sub><sub></sub></sub></p><hr><p dir="auto"></p> <ul dir="auto"> <li>As both rules <code>clean</code> and <code>fclean</code> appear in the Makefile of all our <code>$(LIBS_TARGET)</code> we can <strong>call</strong> these <strong>rules</strong> for each of them <strong>recursively</strong> using a shell <code>for</code> loop. Here again we use the <code>dir</code> function to only keep the directory part of the library.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="#------------------------------------------------# # SPEC # #------------------------------------------------# .PHONY: clean fclean re .SILENT: ####################################### end_5 ####"><pre><span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c"><span class="pl-c">#</span> SPEC #</span> <span class="pl-c"><span class="pl-c">#</span>------------------------------------------------#</span> <span class="pl-c1">.PHONY</span>: clean fclean re <span class="pl-c1">.SILENT</span>: <span class="pl-c"><span class="pl-c">#</span>###################################### end_5 ####</span></pre></div> <p dir="auto"><a href="#index"><strong>Return to Index ↑</strong></a></p> <div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Bonus</h2><a id="user-content-bonus" class="anchor" aria-label="Permalink: Bonus" href="#bonus"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Extra rules</h3><a id="user-content-extra-rules" class="anchor" aria-label="Permalink: Extra rules" href="#extra-rules"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content=".PHONY: run run: re -./$(NAME)"><pre><span class="pl-c1">.PHONY</span>: run <span class="pl-en">run</span>: re -./$(NAME)</pre></div> <ul dir="auto"> <li><code>run</code> is a simple rule that <strong><code>make</code> and <code>run</code> the default goal</strong>. We start the shell command with the <code>hyphen</code> symbol to prevent make from interrupting its own execution if our program execution returns a non-zero value.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="info-%: $(MAKE) --dry-run --always-make $* | grep -v "info""><pre><span class="pl-en">info-<span class="pl-c1">%</span></span>: $(MAKE) --dry-run --always-make $* | grep -v "info"</pre></div> <ul dir="auto"> <li><code>info-<target></code> rule will execute a <code>make <target></code> command with <code>--dry-run</code> to <strong>print</strong> the <strong><code><target></code> recipe without executing it</strong>, <code>--always-make</code> to <code>make</code> even if the targets already exist and <code>grep -v</code> to filter the output. <code>$*</code> expands to the value given in place of the <code>%</code> at the rule call. For example with <code>make info-re</code> <code>$*</code> will expand to <code>re</code>.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="print-%: $(info '$*'='$($*)')"><pre><span class="pl-en">print-<span class="pl-c1">%</span></span>: $(info '$*'='$($*)')</pre></div> <ul dir="auto"> <li>The <code>print-<variable></code> that works like <code>print-<rule></code> will <strong>print the value of an arbitrary variable</strong>, for example a <code>make print-CC</code> will output <code>CC=clang</code>.</li> </ul> <div class="highlight highlight-source-makefile notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content=".PHONY: update update: git stash git pull git submodule update --init git stash pop"><pre><span class="pl-c1">.PHONY</span>: update <span class="pl-en">update</span>: git stash git pull git submodule update --init git stash pop</pre></div> <ul dir="auto"> <li>The <code>update</code> rule will <strong>update the git repository</strong> to its last version, as well as its <em>git submodules</em>. <code>stash</code> commands saves eventual uncommitted changes and put them back in place once the update is done.</li> </ul> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Sources</h1><a id="user-content-sources" class="anchor" aria-label="Permalink: Sources" href="#sources"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <markdown-accessiblity-table><table> <thead> <tr> <th>Topic</th> <th>Website</th> </tr> </thead> <tbody> <tr> <td>doc</td> <td><a href="https://docs.w3cub.com/gnu_make/" rel="nofollow"><strong>docs.w3cub.com</strong></a></td> </tr> <tr> <td>manual</td> <td><a href="https://www.gnu.org/software/make/manual/html_node" rel="nofollow"><strong>gnu.org</strong></a></td> </tr> <tr> <td>a richer tutorial</td> <td><a href="https://makefiletutorial.com/" rel="nofollow"><strong>makefiletutorial.com</strong></a></td> </tr> <tr> <td>order-only exquisite</td> <td><a href="https://stackoverflow.com/a/68584653" rel="nofollow"><strong>stackoverflow.com</strong></a></td> </tr> <tr> <td>c libraries</td> <td><a href="https://docencia.ac.upc.edu/FIB/USO/Bibliografia/unix-c-libraries.html#creating_static_archive" rel="nofollow"><strong>docencia.ac.upc.edu</strong></a></td> </tr> <tr> <td>auto-deps gen</td> <td><a href="http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/" rel="nofollow"><strong>make.mad-scientist.net</strong></a></td> </tr> <tr> <td>auto-deps gen</td> <td><a href="https://scottmcpeak.com/autodepend/autodepend.html" rel="nofollow"><strong>scottmcpeak.com</strong></a></td> </tr> <tr> <td>auto-deps gen</td> <td><a href="http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html" rel="nofollow"><strong>microhowto.info</strong></a></td> </tr> <tr> <td>include statement</td> <td><a href="https://www.gnu.org/software/make/manual/html_node/Include.html" rel="nofollow"><strong>gnu.org</strong></a></td> </tr> <tr> <td>redis makefile</td> <td><a href="https://github.com/redis/redis/blob/unstable/src/Makefile"><strong>github.com</strong></a></td> </tr> </tbody> </table></markdown-accessiblity-table> <div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">Contact</h1><a id="user-content-contact" class="anchor" aria-label="Permalink: Contact" href="#contact"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div> <div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="cvidon 42 clemedon icloud"><pre class="notranslate"><code>cvidon 42 clemedon icloud </code></pre></div> </article></div></div></div></div></div> <!-- --> <!-- --> <script type="application/json" id="__PRIMER_DATA_:R0:__">{"resolvedServerColorMode":"day"}</script></div> </react-partial> <input type="hidden" data-csrf="true" value="xK3JSwPa4Bjae1miBEB4gKtwKdfcjJemo/kkML2VBgrD0ONxPTSVaCmPoOTYed82A9O2MNsax1d4ImdRcn2lug==" /> </div> <div data-view-component="true" class="Layout-sidebar"> <div class="BorderGrid about-margin" data-pjax> <div class="BorderGrid-row"> <div class="BorderGrid-cell"> <div class="hide-sm hide-md"> <h2 class="mb-3 h4">About</h2> <p class="f4 my-3"> This project aims to create a crystal clear tutorial on a cryptic looking topic. </p> <div class="my-3 d-flex flex-items-center"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-link flex-shrink-0 mr-2"> <path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path> </svg> <span class="flex-auto min-width-0 css-truncate css-truncate-target width-fit"> <a title="https://clemedon.github.io/Makefile_tutor/" role="link" target="_blank" rel="noopener noreferrer nofollow" class="text-bold" href="https://clemedon.github.io/Makefile_tutor/">clemedon.github.io/Makefile_tutor/</a> </span> </div> <h3 class="sr-only">Topics</h3> <div class="my-3"> <div class="f6"> <a href="/topics/template" title="Topic: template" data-view-component="true" class="topic-tag topic-tag-link"> template </a> <a href="/topics/tutorial" title="Topic: tutorial" data-view-component="true" class="topic-tag topic-tag-link"> tutorial </a> <a href="/topics/howto" title="Topic: howto" data-view-component="true" class="topic-tag topic-tag-link"> howto </a> <a href="/topics/makefile" title="Topic: makefile" data-view-component="true" class="topic-tag topic-tag-link"> makefile </a> <a href="/topics/make" title="Topic: make" data-view-component="true" class="topic-tag topic-tag-link"> make </a> <a href="/topics/makefile-template" title="Topic: makefile-template" data-view-component="true" class="topic-tag topic-tag-link"> makefile-template </a> <a href="/topics/42born2code" title="Topic: 42born2code" data-view-component="true" class="topic-tag topic-tag-link"> 42born2code </a> <a href="/topics/42" title="Topic: 42" data-view-component="true" class="topic-tag topic-tag-link"> 42 </a> <a href="/topics/makefiles" title="Topic: makefiles" data-view-component="true" class="topic-tag topic-tag-link"> makefiles </a> <a href="/topics/42school" title="Topic: 42school" data-view-component="true" class="topic-tag topic-tag-link"> 42school </a> <a href="/topics/stepbystep" title="Topic: stepbystep" data-view-component="true" class="topic-tag topic-tag-link"> stepbystep </a> <a href="/topics/howto-tutorial" title="Topic: howto-tutorial" data-view-component="true" class="topic-tag topic-tag-link"> howto-tutorial </a> <a href="/topics/gnumake" title="Topic: gnumake" data-view-component="true" class="topic-tag topic-tag-link"> gnumake </a> <a href="/topics/learnbydoing" title="Topic: learnbydoing" data-view-component="true" class="topic-tag topic-tag-link"> learnbydoing </a> <a href="/topics/42projects" title="Topic: 42projects" data-view-component="true" class="topic-tag topic-tag-link"> 42projects </a> <a href="/topics/42paris" title="Topic: 42paris" data-view-component="true" class="topic-tag topic-tag-link"> 42paris </a> <a href="/topics/42cursus" title="Topic: 42cursus" data-view-component="true" class="topic-tag topic-tag-link"> 42cursus </a> <a href="/topics/42network" title="Topic: 42network" data-view-component="true" class="topic-tag topic-tag-link"> 42network </a> <a href="/topics/template-makefile" title="Topic: template-makefile" data-view-component="true" class="topic-tag topic-tag-link"> template-makefile </a> </div> </div> <h3 class="sr-only">Resources</h3> <div class="mt-2"> <a class="Link--muted" data-analytics-event="{"category":"Repository Overview","action":"click","label":"location:sidebar;file:readme"}" href="#readme-ov-file"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-book mr-2"> <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z"></path> </svg> Readme </a> </div> <h3 class="sr-only">License</h3> <div class="mt-2"> <a href="#CC-BY-SA-4.0-1-ov-file" class="Link--muted" data-analytics-event="{"category":"Repository Overview","action":"click","label":"location:sidebar;file:license"}" > <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-law mr-2"> <path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"></path> </svg> CC-BY-SA-4.0 license </a> </div> <include-fragment src="/clementvidon/Makefile_tutor/hovercards/citation/sidebar_partial?tree_name=main"> </include-fragment> <div class="mt-2"> <a href="/clementvidon/Makefile_tutor/activity" data-view-component="true" class="Link Link--muted"><svg text="gray" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-pulse mr-2"> <path d="M6 2c.306 0 .582.187.696.471L10 10.731l1.304-3.26A.751.751 0 0 1 12 7h3.25a.75.75 0 0 1 0 1.5h-2.742l-1.812 4.528a.751.751 0 0 1-1.392 0L6 4.77 4.696 8.03A.75.75 0 0 1 4 8.5H.75a.75.75 0 0 1 0-1.5h2.742l1.812-4.529A.751.751 0 0 1 6 2Z"></path> </svg> <span class="color-fg-muted">Activity</span></a> </div> <h3 class="sr-only">Stars</h3> <div class="mt-2"> <a href="/clementvidon/Makefile_tutor/stargazers" data-view-component="true" class="Link Link--muted"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star mr-2"> <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path> </svg> <strong>626</strong> stars</a> </div> <h3 class="sr-only">Watchers</h3> <div class="mt-2"> <a href="/clementvidon/Makefile_tutor/watchers" data-view-component="true" class="Link Link--muted"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-eye mr-2"> <path d="M8 2c1.981 0 3.671.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.45.678-1.367 1.932-2.637 3.023C11.67 13.008 9.981 14 8 14c-1.981 0-3.671-.992-4.933-2.078C1.797 10.83.88 9.576.43 8.898a1.62 1.62 0 0 1 0-1.798c.45-.677 1.367-1.931 2.637-3.022C4.33 2.992 6.019 2 8 2ZM1.679 7.932a.12.12 0 0 0 0 .136c.411.622 1.241 1.75 2.366 2.717C5.176 11.758 6.527 12.5 8 12.5c1.473 0 2.825-.742 3.955-1.715 1.124-.967 1.954-2.096 2.366-2.717a.12.12 0 0 0 0-.136c-.412-.621-1.242-1.75-2.366-2.717C10.824 4.242 9.473 3.5 8 3.5c-1.473 0-2.825.742-3.955 1.715-1.124.967-1.954 2.096-2.366 2.717ZM8 10a2 2 0 1 1-.001-3.999A2 2 0 0 1 8 10Z"></path> </svg> <strong>10</strong> watching</a> </div> <h3 class="sr-only">Forks</h3> <div class="mt-2"> <a href="/clementvidon/Makefile_tutor/forks" data-view-component="true" class="Link Link--muted"><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2"> <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path> </svg> <strong>30</strong> forks</a> </div> <div class="mt-2"> <a class="Link--muted" href="/contact/report-content?content_url=https%3A%2F%2Fgithub.com%2Fclementvidon%2FMakefile_tutor&report=clementvidon+%28user%29"> Report repository </a> </div> </div> </div> </div> <div class="BorderGrid-row" hidden> <div class="BorderGrid-cell"> <include-fragment src="/clementvidon/Makefile_tutor/used_by_list" accept="text/fragment+html"> </include-fragment> </div> </div> <div class="BorderGrid-row"> <div class="BorderGrid-cell"> <h2 class="h4 mb-3"> <a href="/clementvidon/Makefile_tutor/graphs/contributors" data-view-component="true" class="Link--primary no-underline Link d-flex flex-items-center">Contributors <span title="2" data-view-component="true" class="Counter ml-1">2</span></a></h2> <include-fragment src="/clementvidon/Makefile_tutor/contributors_list?count=2&current_repository=Makefile_tutor&items_to_show=2" aria-busy="true" aria-label="Loading contributors"> <ul class="list-style-none "> <li class="mb-2 d-flex"> <div class="Skeleton avatar avatar-user mr-2" style="width:32px;height:32px;"></div> <div class="Skeleton Skeleton--text flex-1 flex-self-center f4"> </div> </li> <li class="mb-2 d-flex"> <div class="Skeleton avatar avatar-user mr-2" style="width:32px;height:32px;"></div> <div class="Skeleton Skeleton--text flex-1 flex-self-center f4"> </div> </li> </ul> </include-fragment> </div> </div> <div class="BorderGrid-row"> <div class="BorderGrid-cell"> <h2 class="h4 mb-3">Languages</h2> <div class="mb-2"> <span data-view-component="true" class="Progress"> <span style="background-color:#427819 !important;;width: 87.4%;" itemprop="keywords" data-view-component="true" class="Progress-item color-bg-success-emphasis"></span> <span style="background-color:#555555 !important;;width: 12.6%;" itemprop="keywords" data-view-component="true" class="Progress-item color-bg-success-emphasis"></span> </span></div> <ul class="list-style-none"> <li class="d-inline"> <a class="d-inline-flex flex-items-center flex-nowrap Link--secondary no-underline text-small mr-3" href="/clementvidon/Makefile_tutor/search?l=makefile" data-ga-click="Repository, language stats search click, location:repo overview"> <svg style="color:#427819;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill mr-2"> <path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path> </svg> <span class="color-fg-default text-bold mr-1">Makefile</span> <span>87.4%</span> </a> </li> <li class="d-inline"> <a class="d-inline-flex flex-items-center flex-nowrap Link--secondary no-underline text-small mr-3" href="/clementvidon/Makefile_tutor/search?l=c" data-ga-click="Repository, language stats search click, location:repo overview"> <svg style="color:#555555;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-dot-fill mr-2"> <path d="M8 4a4 4 0 1 1 0 8 4 4 0 0 1 0-8Z"></path> </svg> <span class="color-fg-default text-bold mr-1">C</span> <span>12.6%</span> </a> </li> </ul> </div> </div> </div> </div> </div></div> </div> </div> </turbo-frame> </main> </div> </div> <footer class="footer pt-8 pb-6 f6 color-fg-muted p-responsive" role="contentinfo" > <h2 class='sr-only'>Footer</h2> <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap"> <div class="d-flex flex-items-center flex-shrink-0 mx-2"> <a aria-label="Homepage" title="GitHub" class="footer-octicon mr-2" href="https://github.com"> <svg aria-hidden="true" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github"> <path d="M12 1C5.9225 1 1 5.9225 1 12C1 16.8675 4.14875 20.9787 8.52125 22.4362C9.07125 22.5325 9.2775 22.2025 9.2775 21.9137C9.2775 21.6525 9.26375 20.7862 9.26375 19.865C6.5 20.3737 5.785 19.1912 5.565 18.5725C5.44125 18.2562 4.905 17.28 4.4375 17.0187C4.0525 16.8125 3.5025 16.3037 4.42375 16.29C5.29 16.2762 5.90875 17.0875 6.115 17.4175C7.105 19.0812 8.68625 18.6137 9.31875 18.325C9.415 17.61 9.70375 17.1287 10.02 16.8537C7.5725 16.5787 5.015 15.63 5.015 11.4225C5.015 10.2262 5.44125 9.23625 6.1425 8.46625C6.0325 8.19125 5.6475 7.06375 6.2525 5.55125C6.2525 5.55125 7.17375 5.2625 9.2775 6.67875C10.1575 6.43125 11.0925 6.3075 12.0275 6.3075C12.9625 6.3075 13.8975 6.43125 14.7775 6.67875C16.8813 5.24875 17.8025 5.55125 17.8025 5.55125C18.4075 7.06375 18.0225 8.19125 17.9125 8.46625C18.6138 9.23625 19.04 10.2125 19.04 11.4225C19.04 15.6437 16.4688 16.5787 14.0213 16.8537C14.42 17.1975 14.7638 17.8575 14.7638 18.8887C14.7638 20.36 14.75 21.5425 14.75 21.9137C14.75 22.2025 14.9563 22.5462 15.5063 22.4362C19.8513 20.9787 23 16.8537 23 12C23 5.9225 18.0775 1 12 1Z"></path> </svg> </a> <span> © 2025 GitHub, Inc. </span> </div> <nav aria-label="Footer"> <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3> <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading"> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to Terms","label":"text:terms"}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a> </li> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to privacy","label":"text:privacy"}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a> </li> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to security","label":"text:security"}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a> </li> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to status","label":"text:status"}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a> </li> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to docs","label":"text:docs"}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a> </li> <li class="mx-2"> <a data-analytics-event="{"category":"Footer","action":"go to contact","label":"text:contact"}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a> </li> <li class="mx-2" > <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{"location":"footer","action":"cookies","context":"subfooter","tag":"link","label":"cookies_link_subfooter_footer"}" > Manage cookies </button> </cookie-consent-link> </li> <li class="mx-2"> <cookie-consent-link> <button type="button" class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent" data-action="click:cookie-consent-link#showConsentManagement" data-analytics-event="{"location":"footer","action":"dont_share_info","context":"subfooter","tag":"link","label":"dont_share_info_link_subfooter_footer"}" > Do not share my personal information </button> </cookie-consent-link> </li> </ul> </nav> </div> </footer> <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999" data-initial-cookie-consent-allowed="" data-cookie-consent-required="false"></ghcc-consent> <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert"> <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path> </svg> <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> You can’t perform that action at this time. </div> <template id="site-details-dialog"> <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open> <summary role="button" aria-label="Close dialog"></summary> <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal"> <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x"> <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path> </svg> </button> <div class="octocat-spinner my-6 js-details-dialog-spinner"></div> </details-dialog> </details> </template> <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;"> <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;"> </div> </div> <template id="snippet-clipboard-copy-button"> <div class="zeroclipboard-container position-absolute right-0 top-0"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> <template id="snippet-clipboard-copy-button-unpositioned"> <div class="zeroclipboard-container"> <clipboard-copy aria-label="Copy" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w"> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> </template> </div> <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div> <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div> </body> </html>