{"id":1917,"date":"2022-02-01T15:44:55","date_gmt":"2022-02-01T18:44:55","guid":{"rendered":"https:\/\/elemarjr.com\/cppmoderno\/?p=1917"},"modified":"2025-06-18T16:07:19","modified_gmt":"2025-06-18T19:07:19","slug":"como-funciona-o-build-em-c-apendice-a-v-1-0","status":"publish","type":"post","link":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/como-funciona-o-build-em-c-apendice-a-v-1-0\/","title":{"rendered":"Como funciona o &#8220;build&#8221; em C++ \/\/ Ap\u00eandice A v 1.0"},"content":{"rendered":"Fica mais f\u00e1cil entender algumas caracter\u00edsticas de C++ sabendo como arquivos com c\u00f3digo-fonte na linguagem s\u00e3o processados e combinados para gerar, finalmente, execut\u00e1veis e bibliotecas din\u00e2micas ou est\u00e1ticas.\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Lufga;\">Bibliotecas est\u00e1ticas e din\u00e2micas<\/p>\r\n<\/p>\n<p>Bibliotecas s\u00e3o blocos de c\u00f3digo que s\u00e3o reutiliz\u00e1veis em v\u00e1rios programas. Us\u00e1-las economiza tempo, eliminando a necessidade de reescrever o c\u00f3digo v\u00e1rias vezes.<\/p>\n<p>Bibliotecas est\u00e1ticas (geralmente, em Windows, arquivos com extens\u00e3o <code>.lib<\/code>), embora reutiliz\u00e1veis em v\u00e1rios programas, s\u00e3o bloqueadas em um programa no <em>build<\/em>. Por outro lado, bibliotecas din\u00e2micas ou compartilhadas (em Windows, extens\u00e3o <code>.dll<\/code>) existem como arquivos separados fora do arquivo execut\u00e1vel.<\/p>\n<p><\/div>\n<p>Neste ap\u00eandice, apresento alguns fundamentos do processo de\u00a0<em>build\u00a0<\/em>do C++, fundamentais, para que voc\u00ea consiga ser &#8220;efetivo&#8221; em menos tempo, com menos chances de &#8220;atirar no pr\u00f3prio p\u00e9&#8221;.<\/p>\n<div class=\"nota-alerta\">\r\n<table class=\"tabelaalerta\" style=\"width: 100%;\">\r\n<tbody>\r\n<tr>\r\n<td class=\"nota-coluna-1\" valign=\"top\"><img decoding=\"async\" class=\"img-citacao\" src=\"\/cppmoderno\/wp-content\/uploads\/2021\/11\/ico-citacao-2-1.png\" alt=\"\" width=\"60\" height=\"60\" \/><\/td>\r\n<td class=\"nota-coluna-2\"><img decoding=\"async\" class=\"nota-img\" src=\"\/cppmoderno\/wp-content\/uploads\/2021\/11\/ico-citacao-2-1.png\" alt=\"\" width=\"60\" height=\"60\" \/> <\/p>\n<p><em>Um p\u00e9ssimo trabalhador culpa suas ferramentas.<\/em><\/p>\n<p>\r\n<p><strong>Prov\u00e9rbios Islandenses<\/strong><\/p>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<\/div>\n<h2>Compila\u00e7\u00e3o e <em>linking<\/em><\/h2>\n<p>Comecemos simples. O\u00a0<em>build\u00a0<\/em>em C++ inclui duas etapas principais: <span style=\"text-decoration: underline;\">compila\u00e7\u00e3o<\/span> e\u00a0<span style=\"text-decoration: underline;\"><em>linking<\/em><\/span>.<\/p>\n<p><strong>O processo de <span style=\"text-decoration: underline;\">compila\u00e7\u00e3o<\/span> processa todos os arquivos contendo c\u00f3digo-fonte individualmente e de maneira isolada.<\/strong> Ou seja, para o compilador, quando um arquivo est\u00e1 sendo processado \u00e9 como se fosse o \u00fanico, devendo dispor, de alguma meneira, todas as informa\u00e7\u00f5es necess\u00e1rias para sua valida\u00e7\u00e3o.<\/p>\n<p>Obviamente, nenhum &#8220;arquivo com c\u00f3digo-fonte&#8221; \u00e9 uma ilha. A raz\u00e3o de um sistema ter v\u00e1rios arquivos \u00e9, exatamente, dividir o c\u00f3digo, segundo algum crit\u00e9rio, para facilitar manuten\u00e7\u00e3o e evolu\u00e7\u00e3o, de forma que \u00e9 natural que c\u00f3digo de um arquivo &#8220;chame&#8221; c\u00f3digo (fun\u00e7\u00f5es e tipos de usu\u00e1rio) em outros arquivos. <strong>A &#8220;liga\u00e7\u00e3o&#8221; entre os programas de diversos arquivos com c\u00f3digo-fonte \u00e9 realizada atrav\u00e9s do processo <em><span style=\"text-decoration: underline;\">linking<\/span>.<\/em><\/strong><\/p>\n<h2>O compilador &#8220;entende&#8221; o c\u00f3digo &#8220;de cima para baixo&#8221;<\/h2>\n<p>Como j\u00e1 foi dito, <strong>durante a compila\u00e7\u00e3o, cada arquivo \u00e9 processado individualmente e de maneira isolada<\/strong>. Mais do que isso, na medida em que o compilador &#8220;l\u00ea&#8221; um c\u00f3digo em um arquivo, precisa conhecer qualquer refer\u00eancia utilizada de maneira a determinar\u00a0 sua validade e corre\u00e7\u00e3o.<\/p>\n<p>No c\u00f3digo que segue, por exemplo, o compilador consegue &#8220;entender&#8221; o c\u00f3digo porque, n\u00e3o h\u00e1, em momento algum, informa\u00e7\u00e3o faltando para valida\u00e7\u00f5es.<\/p>\n<pre>\/\/ main.cpp\r\nint doSomething() {\r\n    return 0;\r\n}\r\n\r\nint main(){\r\n    auto a = doSomething();\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>J\u00e1 o c\u00f3digo abaixo n\u00e3o compila! No momento em que acontece chamada para a fun\u00e7\u00e3o <code>doSomething<\/code> ela ainda n\u00e3o \u00e9 &#8220;conhecida&#8221;.<\/p>\n<pre class=\"erro\">\/\/ main.cpp\r\nint main(){\r\n    auto a = doSomething(); \/\/ THIS CODE DOES NOT COMPILE!\r\n    \/\/ ...\r\n}\r\n\r\nint doSomething() {\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Para que n\u00e3o nos preocupemos com a ordem em que as fun\u00e7\u00f5es aparecem no c\u00f3digo, a sa\u00edda \u00e9 incluir no in\u00edcio &#8220;defini\u00e7\u00f5es&#8221; das implementa\u00e7\u00f5es que aparecer\u00e3o a seguir. No exemplo que segue, definimos a fun\u00e7\u00e3o <code>doSomething<\/code> antes de qualquer evoca\u00e7\u00e3o. Dessa forma, o compilador &#8220;sabe&#8221; que h\u00e1 uma fun\u00e7\u00e3o com esse nome e, tamb\u00e9m, consegue determinar corretamente o tipo da vari\u00e1vel <code>a<\/code>.<\/p>\n<pre>\/\/ main.cpp\r\nint doSomething();\r\n\r\nint main(){\r\n    auto a = doSomething();\r\n    \/\/ ...\r\n}\r\n\r\nint doSomething() {\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Essa medida, ali\u00e1s, autoriza &#8220;levar&#8221; a implementa\u00e7\u00e3o concreta de <code>doSomething<\/code> para outro arquivo com c\u00f3digo fonte (<code>func.cpp<\/code>).<\/p>\n<pre>\/\/ func.cpp\r\nint doSomething() {\r\n    return 0;\r\n}\r\n<\/pre>\n<h2><code>#include<\/code> explicado<\/h2>\n<p><strong>Incluir no in\u00edcio de um arquivo de c\u00f3digo-fonte uma rela\u00e7\u00e3o exaustiva de declara\u00e7\u00f5es de fun\u00e7\u00f5es e tipos (classes e estruturas) torna o c\u00f3digo mais dif\u00edcil de entender, manter e evoluir.<\/strong> Afinal, caso ocorram <em>breaking changes<\/em> nas implementa\u00e7\u00f5es concretas, elas s\u00f3 ser\u00e3o percebidas durante o <em>linking<\/em>.<\/p>\n<p>O &#8220;estilo C++&#8221; para lidar com declara\u00e7\u00f5es \u00e9, para cada arquivo de c\u00f3digo-fonte, criar um arquivo de &#8220;cabe\u00e7alho&#8221; relacionando as defini\u00e7\u00f5es de fun\u00e7\u00f5es e tipos que ele devem ficar expostas.<\/p>\n<pre>\/\/ func.h\r\n#ifndef FUNC_H\r\n#define FUNC_H\r\n\r\nint doSomething();\r\n\r\n#endif \/* FUNC_H *\/\r\n<\/pre>\n<p>Os arquivos de cabe\u00e7alho s\u00e3o, ent\u00e3o, &#8220;inclu\u00eddos&#8221; em arquivos de c\u00f3digo-fonte que ser\u00e3o consumidores.<\/p>\n<pre>\/\/ main.cpp\r\n#include \"func.h\"\r\n\r\nint main(){\r\n    auto a = doSomething();\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<p>A inclus\u00e3o, \u00e9 executada pela diretiva de pr\u00e9-processamento <code>#include<\/code>, antes do trabalho do compilador, por um &#8220;pr\u00e9-processador&#8221; que, literalmente, deixa o c\u00f3digo pronto para a compila\u00e7\u00e3o.<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Lufga;\">Pr\u00e9-processador<\/p>\r\n<\/p>\n<p>Pr\u00e9-processamento \u00e9 uma esp\u00e9cie de &#8220;etapa pr\u00e9via&#8221; executada antes da compila\u00e7\u00e3o e \u00e9 executado por um &#8220;motor&#8221; designado como &#8220;pr\u00e9-processador&#8221;.<\/p>\n<p>O pr\u00e9-processador procura quaisquer diretivas de pr\u00e9-processamento (linhas de c\u00f3digo come\u00e7ando com um <code>#<\/code>) e altera o c\u00f3digo de alguma forma, geralmente adicionando ou removendo linhas.<\/p>\n<p>A diretiva <code>#include<\/code>, por exemplo, literalmente insere o conte\u00fado do arquivo especificado na posi\u00e7\u00e3o em que aparece.<\/p>\n<p><\/div>\n<p>As diretivas <code>#ifndef<\/code>, <code>#define<\/code>e <code>#endif<\/code> ajudam o pr\u00e9-processador a n\u00e3o &#8220;incluir acidentalmente&#8221; um mesmo conjunto de defini\u00e7\u00f5es mais de uma vez.<\/p>\n<div class=\"card-insight\" style=\"background-color: #f0f0f0; width: 100%; padding: 35px 30px 20px 35px; border-radius: 5px 5px 5px 5px; margin-top: 30px; margin-bottom: 35px; font-size: 16px; box-shadow: 0px 4px 0px 0px #dddddd;\">\r\n<p style=\"font-size: 24px; font-weight:bold; line-height: 28px; font-family: Lufga;\"><code>#pragma once<\/code><\/p>\r\n<\/p>\n<p>As diretivas <code>#ifndef<\/code>, <code>#define<\/code>e <code>#endif<\/code>para impedir duplicidade de inclus\u00e3o de declara\u00e7\u00f5es \u00e9 um <em>pattern <\/em>consolidado, aderente a especifica\u00e7\u00e3o do C++. Entretanto, \u00e9 uma solu\u00e7\u00e3o &#8220;verbosa&#8221; para um problema recorrente.<\/p>\n<p>Atualmente, todos os compiladores do mercado suportam a diretiva <code>#pragma once<\/code> que atende ao mesmo objetivo do <em>pattern.<\/em><\/p>\n<pre>\/\/ func.h\r\n#pragma once\r\n\r\nint doSomething();\r\n<\/pre>\n<p><\/div>\n<h2>Macros<\/h2>\n<p><strong>O pr\u00e9-processador do C++ \u00e9 tremendamente poderoso e perigoso. Ele &#8220;altera&#8221; o c\u00f3digo fonte, expandindo trechos conforme defini\u00e7\u00f5es, aparentando &#8220;enganosamente&#8221; uma fun\u00e7\u00e3o.<\/strong><\/p>\n<pre>#define MAX(a,b) (a &gt; b ? a : b)\r\n\r\n#include &lt;iostream&gt;\r\nusing namespace std ;\r\n\r\nint main() {\t\r\n    int x = 10, y = 20;\r\n    cout &lt;&lt; \"Macro Max(x,y) = \" &lt;&lt; MAX(x,y) &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>No exemplo acima, a macro <code>MAX<\/code>, quando interpretada pelo pr\u00e9-processador altera o c\u00f3digo-fonte fazendo substitui\u00e7\u00e3o conforme indicado no modelo. Ap\u00f3s o pr\u00e9-processador, o c\u00f3digo resultante ser\u00e1 como segue:<\/p>\n<pre>\/\/ ... conteudo de iostream ...\r\nusing namespace std ;\r\n\r\nint main() {\t\r\n    int x = 10, y = 20;\r\n    cout &lt;&lt; \"Macro Max(x,y) = \" &lt;&lt; (x &gt; y ? x : y) &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Macros s\u00e3o &#8220;entregues&#8221; pelo pr\u00e9-processador que n\u00e3o valida, de forma alguma, a corre\u00e7\u00e3o do c\u00f3digo. O exemplo abaixo, por exemplo, n\u00e3o acusa falta de um par\u00eantese na macro. O erro ser\u00e1 indicado, s\u00f3 mais tarde, pelo compillador, na linha onde aconteceu a substitui\u00e7\u00e3o.<\/p>\n<pre class=\"erro\">#define MAX(a,b) (a &gt; b ? a : b\r\n\r\n#include &lt;iostream&gt;\r\nusing namespace std ;\r\n\r\nint main() {\t\r\n    int x = 10, y = 20;\r\n    cout &lt;&lt; \"Macro Max(x,y) = \" &lt;&lt; MAX(x,y) &lt;&lt; endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>No passado, macros eram utilizadas em demasia e dificultavam consideravelmente a identifica\u00e7\u00e3o de erros de compila\u00e7\u00e3o. Modernamente, os benef\u00edcios do\u00a0<em>inlining\u00a0<\/em>proporcionado pelas macros \u00e9 resolvido de maneira mais eficiente com o modificador <code>inline<\/code> em fun\u00e7\u00f5es.<\/p>\n<h2>H\u00e1 bem mais&#8230;<\/h2>\n<p>Essa \u00e9 apenas uma breve introdu\u00e7\u00e3o a como funciona o\u00a0<em>build\u00a0<\/em>do C++. H\u00e1 muitos detalhes e recursos adicionais que podem e precisam ser explorados.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste ap\u00eandice, apresento alguns fundamentos do processo de\u00a0build\u00a0do C++, fundamentais, para que voc\u00ea consiga ser &#8220;efetivo&#8221; em menos tempo, com menos chances de &#8220;atirar no pr\u00f3prio p\u00e9&#8221;. Compila\u00e7\u00e3o e linking Comecemos simples. O\u00a0build\u00a0em C++ inclui duas etapas principais: compila\u00e7\u00e3o e\u00a0linking. O processo de compila\u00e7\u00e3o processa todos os arquivos contendo c\u00f3digo-fonte individualmente e de maneira isolada. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1981,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"hashtags":[],"tipo":[39],"url":[37],"apendices":[33],"capitulos":[],"class_list":["post-1917","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tipo-apendice","url-permanente","apendices-apendice-a"],"_links":{"self":[{"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/posts\/1917","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/comments?post=1917"}],"version-history":[{"count":41,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/posts\/1917\/revisions"}],"predecessor-version":[{"id":1980,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/posts\/1917\/revisions\/1980"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/media\/1981"}],"wp:attachment":[{"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/media?parent=1917"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/categories?post=1917"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/tags?post=1917"},{"taxonomy":"hashtags","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/hashtags?post=1917"},{"taxonomy":"tipo","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/tipo?post=1917"},{"taxonomy":"url","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/url?post=1917"},{"taxonomy":"apendices","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/apendices?post=1917"},{"taxonomy":"capitulos","embeddable":true,"href":"https:\/\/elemarjr.com\/livros\/cpp-moderno\/wp-json\/wp\/v2\/capitulos?post=1917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}