1

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) 
Benkevitch
  • 415
  • 1
  • 5
  • 13

1 Answers1

2

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.

utopia
  • 1,477
  • 8
  • 7
  • 1
    Oh, I see... Really, it is like in bash scripts, where ${something} and $(something) have very different meanings. Also, thank you very much for the useful explanations and new (for me) information. – Benkevitch Jul 16 '17 at 22:56
  • One more question on the suggested 'target_compile_definitions(mytarget, ...)': How to find what targets a project has, if the project is not yours? I tried target_compile_definitions(pcbnew, ...), but cmake said 'no such target' or so. I tried to find my question on stackoverflow, but did not find specifically this one. – Benkevitch Jul 20 '17 at 17:26
  • @Benkevitch I don't think there is any way to do that directly in code. People normally just look at the documentation or CMakeLists.txt file or its output files. It is best to ask that as a separate question anyway. – utopia Jul 20 '17 at 17:31
  • Thank you. I will do that, but later. – Benkevitch Jul 21 '17 at 18:13