XCode Preprocessor Macro for Configuration? - objective-c

I want my XCode Objective-C project to be able to detect which configuration it is being built with. How can I achieve this?

You can have per-configuration macro definitions. Open up your project settings, select your configuration from the Configuration drop-down menu, and go to Preprocessor Macros. For Debug, I recommend defining the macro _DEBUG, and for release I recommend defining _RELEASE, as these are the typical ones which are used. These are passed on to the compiler as -D options, e.g. -D_DEBUG.
You can also put -D options directly into the Other C Flags setting.

Related

How to build multiple configurations of an ESP-IDF application

I have one ESP-IDF application and two hardware boards. I use a preprocessor definition to control which hardware board version to build. For now, I'm modifying the config in the sdkconfig file via menuconfig. But I would like to build both versions at once from a script, or build only one specific config without the manual process of menuconfig.
I have a header that looks like this, and works when HW_VER is set correctly:
#if HW_VER == 2
#define BTN_GPIO 9
#elif HW_VER == 3
#define BTN_GPIO 10
#endif
And from the a script I would like to build each by selecting a value for HW_VER, for example:
idf.py build -DHW_VER=2
idf.py build -DHW_VER=3
The idf.py build command runs cmake and ninja. I'm new to cmake, so perhaps there is a natural way to do this?
I would also like to build release and debug builds, turn on/off memory debugging etc. from the command line.
I've tried idf.py build -DHW_VER=2 but I've learned that these vars are only sent to cmake and not to the preprocessor. The HW_VER macro remains undefined.
Using add_definitions() in my CMakeLists.txt can set HW_VER, but doesn't help me make different builds from the same files.
Using a config variable like CONFIG_HW_VER in the sdkconfig works to control builds using menuconfig but I don't see a way to automate this.
I've considered modifying the configuration variable, CONFIG_HW_VER in the sdkconfig file programmatically, but this file is under source control, and it is auto generated by menuconfig, so that doesn't seem wise.
Similarly I can modify the CMakeLists.txt file programmatically, but that file is also under source control, and isn't a trivial format.
I use two ways to feed custom configurations into an ESP IDF project.
Firstly, the light weight stuff like preprocessor definitions from the environment are quite simple. You have to configure CMakeLists.txt file (the one in project root) to pass variable values from environment into the build process. For example, to create something equivalent to preprocessor definitions -DMY_NUMBER=123 and -DMY_STRING="abc" add this somewhere before the "project" line:
add_compile_definitions(MY_NUMBER=$ENV{MY_NUMBER})
add_compile_definitions(MY_STRING=\"$ENV{MY_STRING}\")
...
project(myproject)
Assuming you're working in Bash, build with:
$ MY_NUMBER=123 MY_STRING="abc" idf.py build
or (for a slightly more "sticky" enviroment):
$ export MY_NUMBER=123 MY_STRING="abc"
$ idf.py build
You can use cmake to add more advanced logic, e.g. setting default values in case the environment doesn't set anything.
Secondly, the more powerful configuration tool for ESP IDF is the menuconfig target and sdkconfig file. As you've already noticed, playing with sdkconfig directly is not so easy. In my projects I consider this a generated temporary file and I never commit it to git. Instead I delete it. When sdkconfig is missing, idf.py will take file sdkconfig.defaults, copy it into sdkconfig and work with this. That is your best mechanism for supporting different hardware configurations - no sdkconfig and instead different variants of sdkconfig.defaults for each hardware you wish to support.
As an example, assume you have two different HW versions described in sdkconfig.defaults.hw_ver1 and sdkconfig.defaults.hw_ver2 and you wish to build for HW ver2 configuration:
$ rm sdkconfig && cp sdkconfig.defaults.hw_ver2 sdkconfig.defaults
$ idf.py reconfigure
Now you can build for this configuration like you usually would:
$ idf.py build
When you wish to build for the other FW configuration, re-execute the previous commands with sdkconfig.defaults.hw_ver1
All this is rather thoroughly documented in the Build System documentation, so feel free to dig in.

Can one use CLion macro's in Run/Debug Configurations?

I have added a GDB Remote Debug via CLion to debug my nRF52 chip but in order to debug the gdb needs a symbol (.out) file. This symbol file name changes when the projects file name changes aswell, so I want to add a macro from CMake, such as ${PROJECT_NAME} or something. I have tried using $ProjectName$.out but it looks like CLion does not recognize this. .
Does such a feature exist?
For anyone wondering, I figured out that you cannot, however it turned out you need CLion EAP (Early Acces program, in order to debug remotely with Embedded GDB Server. One can download it here.

Adding a "preprocessor include" doesn't seem to have effect

I want the Ecplise CDT parser to pre-include a file not specified in my source file, for reasons I won't go into, so as not to complain about undeclared identifiers in various places.
I tried to do this using Project | Properties | C/C++ General | Preprocesor Includes | Entries and adding the relevant file for all languages. However, this doesn't seem to have an effect. If I go to Paths and Symbols | Includes, I can only add include directories, not include files.
What am I doing wrong and how can I get the C/C++ parser to include my file?
Note: I'm using nVIDIA CUDA 8.0's nsight, a modified CUDA-enabled Eclipse; the platform version is 4.4.0.
As you noticed, Paths and Symbols | Includes only supports include directories, so Preprocessor Include Paths, Macros etc. is the way to go.
Some common pitfalls that you may be running into:
In the Entries tab, are you selecting the correct language under Languages? Each language has its own set of entries.
In the Providers tab, for CDT User Setting Entries (assuming that's the one you're adding the entries to), is Use global provider shared between projects unchecked? If it's checked, project-specific entries will be ignored.
Have you rebuilt the project's index (Project -> C/C++ Index -> Rebuild)? New settings are typically not picked up until a rebuild of the index.
Other things that may help:
If, in the Add Include dialog you are specifying the include file as a Project Path or Workspace Path, try using a Filesystem Path instead, even if the file is inside your project or workspace. This sometimes helps.
In the same dialog, try checking Treat as built-in. I'm not sure what exactly this does for Include Files, but it has helped me in the past for Include Directories.
Finally, if none of this works, there is a more direct way to specify -include or any other flag:
In the Providers tab, select the Built-in Compiler Settings provider.
Be sure Use global provider shared between projects is unchecked
Append -include <path> or whatever other flag to the Command to get compiler specs.

How can I add an #ifdef DEBUG to Xcode?

I have some code in a project which should never be used in the release build, but is useful when testing. I'd like to do something like this:
#ifdef DEBUG
// Run my debugging only code
#endif
Where do I add the DEBUG setting in Xcode 4? I tried putting it in the "Edit Scheme" under Run MyApp->Arguments Passed On Launch, but it didn't work. Alternatively, is there a flag already available for this?
In recent Xcode project templates there’s already a DEBUG=1 macro defined for the Debug build configuration (in the Preprocessor Macros section). You can test it using the #if preprocessor directive.
I usually add my -DDEBUG=1 to the OTHER_C_FLAGS section in my XCode 4 project's build settings.
And yes, they can even discriminate between Debug / Release / ADHOC / Store builds.

Making my program compile on both windows and linux, what should I do about libraries?

I'm using CMake to generate my makefiles and VC solutions. I have my program running on linux just fine. I'm using a bunch of libraries, e.g. Lua. On my linux computer I just link to them and make sure in include the headers. All of the .so files are in some standard place. On Windows though I'm not sure what to do. Should I just include the entire Lua project into my own repository and link to that instead? Do I install Lua to some standard place like c:\program files\lua5.1 and link to that? Something else?
Your libraries can be in any place, you just need to say - where are they.
Before running cmake set up pathes of all your extern libs with some .bat file:
set LIBRARYPATH =path\to\your\library\
set include=%include%;%LIBRARYPATH%\include
set lib=%lib%;%LIBRARYPATH%\lib
Start cmd, run this .bat and then cmake should find all
I would provide a configuration field/variable for ccmake that the user can or must specify.
The mark_as_advanced can be used to make a custom variable only appear in the advanced mode. This would be suitable if you have a standard path (as you have mostly on windows). Yet, it still let's the user specify the value if needed.
Or you can simply set a variable the with the 'set' command if you don't want it in advanced.
Just make sure you check if the users entered a valid value.