Get Include Directories for custom build step - visual-studio

I would like to know if there is a possibility to get the list of project's include directories when building files with custom build step.
Imagine following situation: my project consists of A.cpp, B.cpp and C.blah. In project properties under the field "C/C++" -> "General" -> "Additional Include Directories" I have specified a list of includes directories to be used for A.cpp and B.cpp. Now for C.blah I do specify a custom build tool and write into "Command Line" -> "mytool.exe C.blah -I*Direcotries?* -o C.obj". How can I now get the list of include directories specified for the C/C++ in this step? When I click on "Macros" there is no such macro giving me the full list of includes.
Is anybody aware of a possibility to achieve this goal?

I think I found an answer, however incomplete.
One can specify in the property sheets something like this:
<PropertyGroup>
<ProjectIncludeDir>#(ClCompile->'%(AdditionalIncludeDirectories)')</ProjectIncludeDir>
</PropertyGroup>
This will make the macro $(ProjectIncludeDir) available to the custom build steps too containing the list of include directories.
The problem with this approach that string operations are not possible on this macro anymore. For example consider following:
<ProjectIncludeDirDot>$(ProjectIncludeDir.Replace(';',','))</ProjectIncludeDirDot>
This results for the macro $(ProjectIncludeDirDot) in #(ClCompile->'%(AdditionalIncludeDirectories)'). It seems that transforms are get evaluated after the macro evaluation, which breaks that replacement. If somebody knows for a better solution, please...

Related

How does sconstruct receive input?

I want to use Sconstruct instead of Makefile. But I found that many situations in the Makefile are difficult to implement in Sconstruct.
For example,
I have three .c files, a.c, b.c, and c.c. I want to decide which file to compile into the final file based on the input. In Makefile I can use make a, make b, make c to achieve. But in sconstruct, scons e decides which statement to execute based on the final target file. Is there a way to decide which statement to execute based on the source file or a lable?
Sometimes in the Makefile, I want to compile multiple files at once, but not all files. In the Makefile, I can write the compilation of multiple files under one label. Is there such a method in Sconstruct?
I found a lot of documents about sconstruct on the Internet, but basically every document introduces the most basic commands.
Possibly not understanding all of the question, but SCons, builds the targets you ask it to on the command line, like Make does. If you don't give it any, it builds the default targets, which you yourself can define through Default() calls. If neither, then it builds ".", which means all of the targets discovered underneath the directory of the SConstruct.
Targets don't have to be the name of a file to build, you can use the Alias() function to assign a name that will work as a build target. An alias can refer to several targets if you wish, which seems to be your second question.
Feel free to hop onto the SCons Discord channel if you want to chat more interactively (see https://scons.org/contact.html for links)

I'm seeing occasional build failure due to auto generated files (automake). How do I create dependencies between autogenerated files?

I have been trying to debug a makefile.am that occasionally causes a build failure in make. In this file, the sources are auto generated .c files and the headers are auto generated .h files.
..._SOURCES = #buildDirectory#/x.c
#buildDirectory#/y.c
#buildDirectory#/z.c
..._HEADERS = #buildDirectory#/x.h
#buildDirectory#/y.h
#buildDirectory#/z.h
The failure looks like this
<failedproto>.proto: "symbol1" is not defined.
<failedproto>.proto: "symbol2" is not defined.
<failedproto>.proto: "symbol3" is not defined.
...
<failedproto>.proto: warning: Import <failedproto>.proto but not used.
make: *** [<failedproto>.c] Error 1
make: *** Waiting for unfinished jobs....
All of these symbols appear in the a corresponding .h. This leads me to think that the .c is being generated before the .h, and its just a straight race. I have added both ..._SOURCES and _HEADERS to BUILT_SOURCES, but I still see the failure. So my next instinct is to create a dependency for the .c on the .h. How do I do this, since they are both auto generated? Also, any alternative solutions would be welcome too.
Hopefully my formatting is not confusing.
Edit with some more detail:
These files are being auto generated by the protoc-c compiler: https://github.com/protobuf-c/protobuf-c
The protoc-c takes these .proto files and generates .pb-c.c and .pb-c.h files, making me think that these two are not dependent after all. Some in house code is also run, which generates other .proto files, I will call them nameX.proto and nameY.proto, which in turn generate nameX.pb-c.c/nameX.pb-c.h and nameY.pb-c.c/nameY.pb-c.h. A more accurate example of the Makefile.am is like this:
..._SOURCES = #buildDirectory#/name.pb-c.c
#buildDirectory#/nameX.pb-c.c
#buildDirectory#/nameY.pb-c.c
..._HEADERS = #buildDirectory#/name.pb-c.h
#buildDirectory#/nameX.pb-c.h
#buildDirectory#/nameY.pb-c.h
I have been trying to track these dependencies, and I will try and describe what conclusions I have come to. nameX.pb-c.c includes its corresponding header nameX.pb-c.h. That header includes nameY.pb-c.h, making me think that nameX.proto is being compiled into nameX.pb-c.c/nameX.pb-c.h before nameY.proto can be compiled. Since there is an include relationship between nameX.pb-c.h and nameY.pb-c.h, the build fails because nameX.pb-c.h needs nameY.pb-c.h. This leads me to two rules I've been suspicious about from the start. These rules are generalized like this:
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto $(SRC_DIRECTORY)/nameY.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
Could this be an issue? What is stopping the second rule from being run if it truly needs the first rule?
To make matters worse, many of the .proto files are intermediate files (they are generated then discarded throughout the build) so I cannot look at them to see what they look like.
It's very unusual to use #...# replacements throughout your makefile like this. Normally you would assign the replacement once, to a make variable, then use the variable instead (in addition to being "nicer to read", this allows someone to override this value on the make command line if they want to):
BUILDDIR = #buildDirectory#
..._SOURCES = $(BUILDDIR)/x.c
$(BUILDDIR)/y.c
$(BUILDDIR)/z.c
..._HEADERS = $(BUILDDIR)/x.h
$(BUILDDIR)/y.h
$(BUILDDIR)/z.h
Also, it seems likely to me that there are standard automake variables that might already cover this value; if so it's better to use the standard ones than invent new ones... but obviously there's no way to know that without knowing more about your environment.
Anyway, for your question we need to know more about this autogeneration operation. What do your rules for autogenerating look like now? Is it really the case that the generation of the .c file can't be done until the .h file is generated? That's unusual.
If you list the output file, the input files, and the command needed then it's pretty simple to write a correct rule.

Target Preprocessor Macros are ignored by the preprocessor in Xcode

I added TEST=1 in the Preprocessor Macros section of the project target's Build Settings, and whenever I use it in code, the preprocessor thinks it's not defined.
alt + click on it shows a question mark
The syntax coloring doesn't work well
The syntax autocomplete doesn't work well
For example, having:
#if TEST
// a
#else
// b
#endif
has this behavior:
Syntax coloring only works for // b
Syntax autocomplete only works for // b
This is because the preprocessor can't find TEST (even if it's defined as 1, as I previously stated) so it treats it as being false.
Is there any way to solve these problems?
Edit:
My use case is related to multiple Project Targets. So, say that the initial target is named First, which has the TEST preprocessor macro defined with value 1.
If I create another project target named Second with no preprocessor macros defined and want to add some code for it only if TEST is 0 (false/not defined), I'll put it in the #else block (// b).
Knowing that syntax coloring and autocomplete works for // b, it looks like it works ok, but if I change the current target to the First one (pun intended) and even build it, it still works as Second is selected.
If you want to do it like this in Swift, you should add a User-Defined setting named OTHER_SWIFT_FLAGS in your Build Settings like this:
And then in your code you type:
#if TEST1
// Debug
#endif
#if TEST2
// Release
#endif
I don't know why you need this, but it may be interesting to look into native Xcode Target, to use specific behavior for multiple apps with same root project. If this is what you want, you should look into an article this: AppCoda using Targets with Xcode.
Just go to target->Edit Scheme -> Run -> Info and check the Build Configuration. Now while adding the Preprocessor Macros in build setting just make sure you are adding the macro for correct build configuration and correct target.
I tried by adding for both debug and release build as above for my target App (Test-ObjectiveC). So when i tried below code with this setting, u can see the syntax color accordingly.
I was able to make it work by setting "Target->Build Settings->All->Swift Compiler - Custom Flags -> Active Compilation Conditions".
XCode version 12.3

how to check for a macro defined in a c file in Makefile?

I have a #define ONB in a c file which (with several #ifndef...#endifs) changes many aspects of a programs behavior. Now I want to change the project makefile (or even better Makefile.am) so that if ONB is defined and some other options are set accordingly, it runs some special commands.
I searched the web but all i found was checking for environment variables... So is there a way to do this? Or I must change the c code to check for that in environment variables?(I prefer not changing the code because it is a really big project and i do not know everything about it)
Questions: My level is insufficient to ask in comments so I will have to ask here:
How and when is the define added to the target in the first place?
Do you essentially want a way to be able to post compile query the binaries to to determine if a particular define was used?
It would be helpful if you could give a concrete example, i.e. what are the special commands you want run, and what are the .c .h files involved?
Possible solution: Depending on what you need you could use LLVM tools to maybe generate and examine the AST of your code to see if a define is used. But this seems a little like over engineering.
Possible solution: You could also use #includes to pull in .c or header files and a conditional error be generated, or compile (to a .o), then if the compile fails you know it is defined or not. But this has it's own issues depending on how things are set-up in your make file.

how to have make targets for separate debug and release build directories?

I am looking for suggestions to properly handle separate debug and release build subdirectories, in a recursive makefile system that uses the $(SUBDIRS) target as documented in the gnumake manual to apply make targets to (source code) subdirectories.
Specifically, I'm interested in possible strategies to implement targets like 'all', 'clean', 'realclean' etc. that either assume one of the trees or should work on both trees are causing a problem.
Our current makefiles use a COMPILETYPE variable that gets set to Debug (default) or Release (the 'release' target), which properly does the builds, but cleaning up and make all only work on the default Debug tree. Passing down the COMPILETYPE variable gets clumsy, because whether and how to do this depends on the value of the actual target.
One option is to have specific targets in the subdirectories for each build type. So if you do a "make all" at the top level, it looks at COMPILETYPE and invokes "make all-debug" or "make all-release" as appropriate.
Alternatively, you could set a COMPILETYPE environment variable at the top level, and have each sub-Makefile deal with it.
The real solution is to not do a recursive make, but to include makefiles in subdirectories in the top level file. This will let you easily build in a different directory than the source lives in, so you can have build_debug and build_release directories. It also allows parallel make to work (make -j). See Recursive Make Considered Harmful for a full explanation.
If you are disciplined in your Makefiles about the use of your $(COMPILETYPE) variable to reference the appropriate build directory in all your rules, from rules that generate object files, to rules for clean/dist/etc, you should be fine.
In one project I've worked on, we had a $(BUILD) variable that was set to (the equivalent of) build-(COMPILETYPE) which made rules a little easier since all the rules could just refer to $(BUILD), e.g., clean would rm -rf $(BUILD).
As long as you are using $(MAKE) to invoke sub-makes (and using GNU make), you can automatically exporting the COMPILETYPE variable to all sub-makes without doing anything special. For more information, see the relevant section of the GNU make manual.
Some other options:
Force a re-build when compiler flags change, by adding a dependency for all objects on a meta-file that tracks the last used set of compiler flags. See, for example, how Git manages object files.
If you are using autoconf/automake, you can easily use a separate build out-of-place build directory for your different build types. e.g., cd /scratch/build/$COMPILETYPE && $srcdir/configure --mode=$COMPILETYPE && make which would take the build-type out of the Makefiles and into configure (where you'd have to add some support for specifying your desired build flags based on the value of --mode in your configure.ac)
If you give some more concrete examples of your actual rules, maybe you will get some more concrete suggestions.

Resources