Search code examples
cmakeg++c-preprocessorkicad

Successful build of Kicad 4.0.6 in Linux Mageia 5 via fixing a wx-3.0 symbol


I have managed to build the Kicad 4.0.6 in Linux Mageia 5.1 with gcc version 4.9.2. I first manually fixed two wxWidgets 3.0.2 header files in the /usr/include/wx-3.0/wx/ directory: regex.h and features.h. Kicad then compiled successfully. With the native wx-3.0 headers, the compiler generated the error in pcbnew/netlist_reader.cpp due to the undefined variable wxRE_ADVANCED.

The features.h header checks if the macro WX_NO_REGEX_ADVANCED is defined. If yes, features.h UNdefines wxHAS_REGEX_ADVANCED macro, and defines it, if no. The macro wxHAS_REGEX_ADVANCED, in turn, is used in regex.h to determine if among the enum constants wxRE_ADVANCED = 1 is present. The standard prebuilt Mageia 5 packages wxgtku3.0_0 and lib64wxgtku3.0-devel that I installed with the use of Mageia's software manager urpmi from Mageia repository WX_NO_REGEX_ADVANCED is defined, therefore wxHAS_REGEX_ADVANCED is undefined, and, hence, wxRE_ADVANCED is undefined either. Kicad 4.0.6 source package assumes wxRE_ADVANCED = 1, therefore the build process stops with the error.

Then I reverted /usr/include/wx-3.0/wx/regex.h and features.h to their original state and learned how to add the definition of wxRE_ADVANCED to CMakeLists.txt. However, I still have a question.

The recommended format of adding the definition to CMakeLists.txt I found at CMake command line for C++ #define is this:

if (NOT DEFINED wxRE_ADVANCED)
  set(wxRE_ADVANCED 1)
endif()

add_definitions(-DwxRE_ADVANCED=$(wxRE_ADVANCED))

However, it did not work! The macro expansion for wxRE_ADVANCED in pcbnew/netlist_reader.cpp was empty. I printed it at compile time inserting the following lines into the netlist_reader.cpp file (this was hard to find, most of the recommended formats did not work. The correct one is in C preprocessor: expand macro in a #warning):

#define __STRINGIFY(TEXT) #TEXT
#define __WARNING(TEXT) __STRINGIFY(GCC warning TEXT)
#define WARNING(VALUE) __WARNING(__STRINGIFY(wxRE_ADVANCED = VALUE))

Pragma (WARNING(wxRE_ADVANCED))

Finally, I simplified the CMakeLists.txt definition down to this, and it was a success:

if (NOT DEFINED wxRE_ADVANCED)
  set(wxRE_ADVANCED 1)
endif()

add_definitions(-DwxRE_ADVANCED=1)

My question: what is the meaning of "-DwxRE_ADVANCED=$(wxRE_ADVANCED)" if it does not work? Is it possible not to use set(wxRE_ADVANCED 1), and simply write add_definitions(-DwxRE_ADVANCED=1)? Thank you.

P.S. Yes, the Kicad 4.0.6 build process successfully finished with only one line added to the top level CMakeLists.txt file:

add_definitions(-DwxRE_ADVANCED=1) 

Solution

  • A variable is called via $variable or ${variable}. Note the curly brackets, not parentheses.

    Also, it is recommended to use:

    target_compile_definitions(mytarget PUBLIC wxRE_ADVANCED=1)
    

    on a target directly, rather than the general add_definitions() command.