How can I make emacs and/or Projectile recognize external C/C++ defines (e.g. in the makefile)? - makefile

My project has a number of defines configured in build scripts. Because emacs isn't aware of them, hide-ifdefs collapses sections that should be visible and find-definitions misses some targets.
Is there a way to tell emacs or Projectile to default to the defines in a certain build target, or even to manually set flags for a particular project? The caveat is that it can't affect the build or the actual source code.

Related

Specifying uncached compile-time constants in CMakeLists file

In one of my CMakeList files I specified an option which conditionally defines a compile-time constant in a generated header file.
However, I recognized that the value of the option is being cached by cmake.
This leads to the unintentional behaviour that I need to delete the cmake cache everytime I change the option and issue cmake ..
Currently this is the only option being used. Later on I would like to use more options.
It is really confusing to me that the CMakeLists.txt does not represent the actual build setting due to the caching mechanism.
E.g. an build flag set in the CMakeLists.txt but still unset in the cache.
I don't want to disable caching, I just want that my build is always in sync with the build flag set in the CMakeLists.txt. I understand that cmake's caching mechanism is saving lot of time during large builds. Which is actually good.
Does there exist some means to force an option to be up-to-date on cmake .?
I tried to turn the option into a set instruction. The cmake still uses the cached value instead of the actual one.
What am I doing wrong?
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
option(MY_BUILD_FLAG "bla" OFF)
configure_file(TestConfig.h.in TestConfig.h)
Here is my change which I unsuccessfully tried out:
cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
# Here you can set several build flags ON or OFF
set(MY_BUILD_FLAG "bla" OFF)
configure_file(TestConfig.h.in TestConfig.h)
I understand that cmake's caching mechanism is saving lot of time during large builds.
This is incorrect. The purpose of cmake cache variables is to persist variables across information for subsequent reconfigurations of the same build directory.
The fact that e.g. .o files remain in the build directory unless explicitly cleared and aren't rebuilt, if the sources for compiling it is an entirely different mechanism.
Note that you may in fact see improvements of the CMake configuration time, since e.g. results of try_compile are cached. This may actually result in a perceived improved build time, if you often rewrite the cmake files and therefore trigger an automatic cmake reconfiguration of your project before the actual build starts. However if you do not change the cmake logic, the use of CMake cache variables doesn't improve build times at all (or conditionally applying other logic resulting in a different amount of work for compiler or linker).
Note: Another notable use for cache variables is to provide project configuration options to the user. I'm not elaborating on this, since this doesn't affect build times without additional CMake logic dependent on the value influencing the amount of code to build.

Where does Xcode save preprocessor macro settings

I am working on a project that was created using cmake. (It's a project that is built for lots of different platforms, including Linux Mac OS, and now iOS.)
The cmake process creates an Xcode project which I then am modifying manually.
One of the things the project contains is dozens of preprocessor macros that drive #ifdefs in the code.
The cmake tool only defines these macros for debug builds. I need to build a release version so I can profile the project. however, the release build fails because of missing preprocessor macros, which cause the #ifdef/#ifndef compiler directives to be set wrong.
I'd really rather not manually enter 35 preprocessor settings, especially since the Xcode editor displays this awkward popup with + and - buttons to add/remove one at a time, and when I'm editing release symbols, I can't see the debug symbols, and copy/paste doesn't work.
What I really want to do is find the internal file in the xcode project that sets these macros, copy it out of the debug settings, and either paste it into the release version, or at the very least, manually enter one macro at a time into the release version by copying it from a textfile containing the macros that were defined in the debug version.
Can somebody tell me where the debug and release preprocessor macros are saved in the Xcode project file hierarchy so I can go read the raw file and possibly modify it?
In your project.pbxproj, search for GCC_PREPROCESSOR_DEFINITIONS. That should be a list of the macros. It should be pretty easy to copy and paste the list from one configuration to the other.

CMake - Build custom build paths for different configurations

I have a project whose make process generates different build artifacts for each configuration, e.g. if initiated with make a=a0 b=b0 it would build object files into builds/a0.b0, generate a binary myproject.a0.b0, and finally update an ambiguous executable link to point to the most recently built project ln -s myproject.a0.b0 myproject. For this project, this is a useful feature mainly because:
It separates the object files for different configurations (so when I rebuild in another configuration I don't have to recompile every single source with new defines and configurations set, (unfortunately) a very common procedure).
It retains the binaries for each configuration (so it's not required to rebuild to use a different configuration if it has already been built).
It makes a copy (or link) to the last built binary which is useful in testing.
Right now this is implemented in an ugly decades-old non-portable Makefile. I'd like to reproduce the same behavior in CMake to allow easier building on other platforms but I have not been able to reproduce it in any reasonable manner. It seems like adding targets with add_library/executable, but doing this for each possible permutation of input parameters seems wrong. And I'm not sure I could get the utilization correct, allowing make, make a=a0, make b=b0 a=a0 as opposed to what specifying a cmake target would require: make myproject-a0.b0.
Is this possible to do in cmake? Namely:
Specify the build directory based on input parameters.
Accept the parameters as make arguments which can be left out (defaulted) to select the appropriate target at the level of the makefile (so it's not required to rerun cmake for a new configuration).

$(shell some-command) equivalent for Visual Studio project macros?

With Makefiles I'm used to being able to write things like:
includedir=$(shell pg_config --includedir)/server
to run an external program, pg_config, with argument(s) --includedir, and include the result in a variable or as part of a variable. So if pg_config --includedir output /usr/include to stdout, the value of includedir would become:
includedir=/usr/include/server
Is there any way to do the equivalent with a Visual Studio project? Run a command, get the result, and substitute it into a property?
I find myself having to edit properties pages all over the place - changing the include directories and library directories for both the x86 and x64 configurations of a project whenever I want to build an extension against a different PostgreSQL version. It is intensely frustrating.
I want to be able to put something like this into Configuration Properties -> C/C++ -> General -> Additional Include Directories:
%(shell pg_config --includedir)
or even better:
%(shell %(PG_CONFIG) --includedir)
where %(PG_CONFIG)'s location is defined in a single place for each platform in the project.
So I'm looking for at least user-defined macros, and preferably the ability to invoke a command line tool and replace the macro with the resulting standard output.
(Preferably in a way that doesn't involve delving into semi-documented UI elements that move and get renamed in every VS version, and that appear and disappear from the various Express editions).
This has been possible in Makefiles for 20 years, there must be a way to do it in VS, right? Or do "Real Windows Developers" generate their VS projects with scripts and build them using MSBuild?
I've looked at some similar questions without finding much of use, e.g.:
Visual Studio - Where to define custom path macros?
In particular, I'm aware of property sheets (View -> Other Windows -> Property Manager), but they don't seem to provide a way to set a value in just one place, they're still per-configuration and per-architecture, so if you have four configurations and two architectures it gets awkward. Unlike with the normal project property editor you can't even apply a change across a group of architectures/configurations, either.
I could use a VS extension, but they require installation into the user's VS, can be version-specific, and seem like a very big hammer for a small problem.
I find myself having to edit properties pages all over the place
That bugged me to no end as well. Property sheets to the rescue! When setting up a major solution in VS10, for example, I had every project pull in a settings.props that contained the common settings, made in only one place. Then go through all the generated or imported projects and kill any explicit value (even if blank) for everything possible. That way things will inherit from property sheets. Select "all configurations" and on each properly use the drop-down to "inherit from...".
I have property sheets for each special library too, just defining the proper #define, include paths, lib paths, etc. Projects that use that particular external lib simply use that property sheet. Users are told, in the worst case, to “edit the XML to change the path to where you have Boost”.
As for setting such a properly to a dynamic determined value, you can do that too. There are property functions you can use.
It sounds like you're going down the same path as I did.
More notes: “prop sheets are per configuration/platform”: If you include a prop sheet at the top-level node for the project itself (not the Debug|Win32, etc. child nodes) it will include it into all current configurations at once. If you edit the properly page, you can choose Multiple or All configurations on the Property dialog box, just as with the usual project use of the Property dialog.
“Custom user macros are well hidden” A property page shows up for that when in a property sheet you created, but not when opening property dialog on a proj file as in the normal File View. The macro will be set in one place (the prop page) and usable as a $(name) in all projects that include it, and even in other property pages that come later in the evaluation sequence.
Let me know how it goes. You should be able to do everything you asked.
—John
In addition to #jdlugosz's answer:
It looks like the traditional way to do this with Visual Studio, before the advent of property functions, was to write a new MSBuild Task. The task can potentially do things like modify a property sheet.
MSBuild supports "inline tasks" where the task code is in the MSBuild project file, rather than a separate assembly, so it might not be neccessary to create a new subproject just for the task.
There are a bunch of built-in tasks, like Exec and CreateProperty that may be useful.
The docs say that:
[The Exec task] is useful when a specific MSBuild task for the job that you want to perform is not available. However, the Exec task, unlike a more specific task, cannot gather output from the tool or command that it runs.
... but that seems to be outdated/wrong so you don't need horrible workarounds.
So, prior to .NET 4.5 I'd probably have to write a custom task for this simple job, because there's no way to feed the command stdout/stderr into the CreateProperty task or have Exec create a property directly. But in 4.5 it looks like I can do it directly. At least in VS Express support for tasks etc is very limited so you'll probably land up editing the XML.

How do I suppress Xcode from generating a folder named after the build configuration in cmake?

I have a cmake configuration that works great for my project on Windows and Linux. We're tinkering with MacOS right now and we're at the point where Xcode spits out the libraries built one directory off from what we define. Instead of it being dropped in ~/bin it is dropped in ~/bin/Debug, for example. As best I can tell Xcode is taking upon itself to add this folder to the path and I don't want that.
How can I disable Xcode from doing this from within my cmake configuration?
You'll need to specify the target properties ARCHIVE_OUTPUT_DIRECTORY_<CONFIG>, LIBRARY_OUTPUT_DIRECTORY_<CONFIG>, and/or RUNTIME_OUTPUT_DIRECTORY_<CONFIG> for each config type and each target you want to affect.
To affect all targets, you can set variables named as these with CMAKE_ prepended. Any relevant target added after these have been set will be affected.
So, for example you could either do:
add_library(MyLib ${Sources})
set_target_properties(MyLib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
or you could do:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
add_library(MyLib ${Sources})
Having said that, I normally find it's best to let multi-configuration generators like XCode and MSVC just add the config-specific directories. Unless you plan to also change the default names of exes and libs, these multi-config IDEs will overwrite one config's outputs with another's. So, it's hard to tell whether you're looking at a Debug or Release exe for example.
For single-config generators, I think it's common to have separate build trees per configuration to keep the distinction clear.
Basically, I wouldn't fight against the generator. CMake automates so much of the build process that I never find this slight difference between generators to be a problem. You rarely have to consider whether the output path contains a config dir or not.

Resources