Reflection on one-year usage of OpenBSD

I have used OpenBSD for more than one year, and it is time to give a summary of the experience:

(1) What do I get from OpenBSD?

a) A good UNIX tutorial. When I am curious about some UNIXcommands’ implementation, I will refer to OpenBSD source code, and I actually gain something every time. E.g., refresh socket programming skills from nc; know how to process file efficiently from cat.

b) A better test bed. Although my work focus on developing programs on Linux, I will try to compile and run applications on OpenBSD if it is possible. One reason is OpenBSD usually gives more helpful warnings. E.g., hint like this:

......
warning: sprintf() is often misused, please use snprintf()
......

Or you can refer this post which I wrote before. The other is sometimes program run well on Linux may crash on OpenBSD, and OpenBSD can help you find hidden bugs.

c) Some handy tools. E.g. I find tcpbench is useful, so I ported it into Linuxfor my own usage (project is here).

(2) What I give back to OpenBSD?

a) Patches. Although most of them are trivial modifications, they are still my contributions.

b) Write blog posts to share experience about using OpenBSD.

c) Develop programs for OpenBSD/*BSD: lscpu and free.

d) Porting programs into OpenBSD: E.g., I find google/benchmark is a nifty tool, but lacks OpenBSD support, I submitted PR and it is accepted. So you can use google/benchmark on OpenBSD now.

Generally speaking, the time invested on OpenBSD is rewarding. If you are still hesitating, why not give a shot?

Be wary of “Boost”, not “boost” in CMakeLists.txt

In Cygwin, the following statements in CMakeLists.txt:

......
find_package(boost 1.66 REQUIRED COMPONENTS system)
if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(play main.cpp)
    target_link_libraries(play ${Boost_LIBRARIES})
endif()
......

causes following errors:

......
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_code::error_code()':
/usr/include/boost/system/error_code.hpp:449: undefined reference to `boost::system::system_category()'
/usr/include/boost/system/error_code.hpp:449:(.text$_ZN5boost6system10error_codeC1Ev[_ZN5boost6system10error_codeC1Ev]+0x17): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::system_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_category::std_category::equivalent(int, std::error_condition const&) const':
/usr/include/boost/system/error_code.hpp:676: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:676:(.text$_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xa9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:679: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:679:(.text$_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition[_ZNK5boost6system14error_category12std_category10equivalentEiRKSt15error_condition]+0xe4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::system::error_category::std_category::equivalent(std::error_code const&, int) const':
/usr/include/boost/system/error_code.hpp:706: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:706:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xab): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:709: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:709:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0xe6): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:721: undefined reference to `boost::system::generic_category()'
/usr/include/boost/system/error_code.hpp:721:(.text$_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei[_ZNK5boost6system14error_category12std_category10equivalentERKSt10error_codei]+0x1be): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::generic_category()'
CMakeFiles/play.dir/main.cpp.o: In function `boost::asio::error::get_system_category()':
/usr/include/boost/asio/error.hpp:229: undefined reference to `boost::system::system_category()'
/usr/include/boost/asio/error.hpp:229:(.text$_ZN5boost4asio5error19get_system_categoryEv[_ZN5boost4asio5error19get_system_categoryEv]+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `boost::system::system_category()'
collect2: error: ld returned 1 exit status

Change boost to Boost:

find_package(Boost 1.66 REQUIRED COMPONENTS system)
......

All is OK now!

Fix “error: file owned by …” issue on Arch Linux

I tried to install caffe on my Arch Linux, but it prompted following errors:

$ yaourt -S caffe
......
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/BasicThreadPool.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/FFT.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/FacVec.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/GF2.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/GF2E.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/GF2EX.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/GF2EXFactoring.h'
error: file owned by 'ntl' and 'ntl-threading': 'usr/include/NTL/GF2X.h'\
......

The reason is I installed NTL through pacman before. So the solution is uninstalling NTL first:

$ sudo pacman -R ntl

Then installing caffe successfully:

$ yaourt -S caffe
......
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
No database errors have been found!

Reference:
pacman a file owned by two packages.

Define multiple exclusive macros in CMake

My program needs FOO or BAR macro defined, but not both. By default, FOO is defined. Following is the snippet of CMakeList.txt:

OPTION(BAR "BAR" OFF)
OPTION(FOO "FOO" ON)
IF(BAR)
    SET(FOO OFF CACHE BOOL "Use BAR" FORCE)
    MESSAGE(STATUS "Use BAR\n")
    ADD_DEFINITIONS(-DBAR)
ELSE()
    MESSAGE(STATUS "Use FOO\n")
    ADD_DEFINITIONS(-DFOO)
ENDIF()

Notice: for simplicity, I just use the same name for macro and option variable. It may not be what you want.

Use boost on OpenBSD

Installing boost on OpenBSD is simple:

$ pkg_add boost

Write a simple test program:

#include <boost/asio.hpp>
#include <iostream>

int main()
{
    boost::system::error_code ec{};
    auto server_addr{boost::asio::ip::make_address("127.0.0.1", ec)};
    if (ec.value())
    {
        std::cerr << "Failed to parse the IP address. Error code = "
                    << ec.value() << ". Message: " << ec.message();
        return ec.value();
    }

    boost::asio::ip::tcp::endpoint ep{server_addr, 3003};
    return 0;
}

Compile it:

$ c++ client.cpp
/tmp/client-238877.o: In function `boost::asio::error::get_system_category()':
client.cpp:(.text._ZN5boost4asio5error19get_system_categoryEv[_ZN5boost4asio5error19get_system_categoryEv]+0x5): undefined reference to `boost::system::system_category()'
/tmp/client-238877.o: In function `boost::system::error_code::error_code()':
client.cpp:(.text._ZN5boost6system10error_codeC2Ev[_ZN5boost6system10error_codeC2Ev]+0x1b): undefined reference to `boost::system::system_category()'
/tmp/client-238877.o: In function `boost::system::error_category::std_category::equivalent(int, std::__1::error_condition const&) const':
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE[_ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE]+0x129): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE[_ZNK5boost6system14error_category12std_category10equivalentEiRKNSt3__115error_conditionE]+0x16a): undefined reference to `boost::system::generic_category()'
/tmp/client-238877.o: In function `boost::system::error_category::std_category::equivalent(std::__1::error_code const&, int) const':
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x137): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x178): undefined reference to `boost::system::generic_category()'
client.cpp:(.text._ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi[_ZNK5boost6system14error_category12std_category10equivalentERKNSt3__110error_codeEi]+0x2d2): undefined reference to `boost::system::generic_category()'
c++: error: linker command failed with exit code 1 (use -v to see invocation)

Whoops!, it means linker can’t find related library. boost libraries are installed in /usr/local/lib:

$ ls -lt /usr/local/lib/libboost*
-rw-r--r--  1 root  bin  2632774 Jul  2 05:58 /usr/local/lib/libboost_regex-mt.a
-rw-r--r--  1 root  bin  1398613 Jul  2 05:58 /usr/local/lib/libboost_regex-mt.so.8.0
-rw-r--r--  1 root  bin  2632774 Jul  2 05:58 /usr/local/lib/libboost_regex.a
-rw-r--r--  1 root  bin  1398613 Jul  2 05:58 /usr/local/lib/libboost_regex.so.8.0
-rw-r--r--  1 root  bin   994564 Jul  2 05:58 /usr/local/lib/libboost_serialization-mt.a
-rw-r--r--  1 root  bin   484918 Jul  2 05:58 /usr/local/lib/libboost_serialization-mt.so.8.0
-rw-r--r--  1 root  bin   994564 Jul  2 05:58 /usr/local/lib/libboost_serialization.a
-rw-r--r--  1 root  bin   484918 Jul  2 05:58 /usr/local/lib/libboost_serialization.so.8.0
-rw-r--r--  1 root  bin   260322 Jul  2 05:58 /usr/local/lib/libboost_signals-mt.a
-rw-r--r--  1 root  bin   154973 Jul  2 05:58 /usr/local/lib/libboost_signals-mt.so.8.0
-rw-r--r--  1 root  bin   260322 Jul  2 05:58 /usr/local/lib/libboost_signals.a
......

So I should specify boost_system library during compilation:

$ c++ -L/usr/local/lib client.cpp -lboost_system
$

This time it works!