I have a class (NDTrie on github) which uses c struct for its internal structure, it would make it easier for users to use it in their projects with automatic reference counting by adding the fno-objc-arc to the source file instead of requiring users to set it in the build phase for that source file, is there a way to do that.
Per-file compiler flags are tacked onto files on a per-project basis (files meant to be compiled down to some form of machine code generally try to avoid metadata). If you'd like to specify the flag and have it update the required field in any Xcode project, you can use CocoaPods to write a pod file for your dependancy. Let the underlying tool handle the rest.
No, it's not possible to separate portions of translations based on features and alter their flags for that translation in this case.
You should approach it from another angle. The ARC feature treats all preprocessed input as having ARC enabled or not, based on the compiler flags of the current translation.
The most obvious workarounds:
0) Impact reduction: Hide the implementation, where possible
1) Translation specific conditions: Use __has_feature(objc_arc) to determine whether you are or are not dealing with an ARC-enabled translation -- if you are using clang, the expression __has_feature(objc_arc) expands to 1 when ARC is enabled. Then you can conditionally make portions of your program visible or annotate it differently, depending on whether or not ARC is enabled.
2) Detect and fail: In some remaining cases, you may opt for:
// >> detect clang or GCC if needed
#if __has_feature(objc_arc)
#error This file cannot be compiled with ARC enabled (+HYPERLINK so you don't get a flooded inbox)
#endif
// << detect clang or GCC if needed
Related
In CMake, we can set target properties as either PRIVATE, PUBLIC, or INTERFACE. Both PUBLIC and INTERFACE properties are inherited by any targets that depend on the current target. However, unless I'm missing something, there doesn't seem to be an easy way to define a property that must propagate in the other direction (i.e., inherited by dependencies of the current target).
Most linkers/compilers require that all linked targets have the same value for certain properties (e.g., the exception handling model). If we want to change one of these properties for an executable it requires that it be set on all of its dependencies. Often these dependencies are submodules in our code where we can't modify their CMakeLists.txt files for our specific use-case. This leaves us with two options:
Set a global property (e.g., CMAKE_CXX_FLAGS or add_compile_options) that propagates to all targets in any subdirectories regardless of whether they are dependencies or not.
Explicitly set the properties on each dependent target using target_compile_options. This gets excessive and repetitive depending on the number of dependencies.
It would be nice if there was a functionality that would pass properties down only to dependency targets without having to specify them all individually. Does anyone know how to do this?
For the case of compiler flags that must be consistent for an entire program (including parts that are dynamically linked), such as MSVC's exception handling model, I think the set-something-global approach is suitable. To me, it seems pragmatic and slightly more robust than adding flags to each third-party target one-by-one (ie. what if you forget to handle to one? or what if third-party targets are added or removed in a new version? it seems like a ripe opportunity for human error).
Setting the environment variable [CMAKE_<LANG>_FLAGS] is a good start. You may need to do more if you are building external projects via ExternalProject.
A word of caution for such settings like the exception handling model: You might be tempted to hardcode this global setting inthe CMake files for your project. If your project is used by people other than just you or your company, and especially if its main component is a library and not an executable, it's good practice not to do that. Don't take away your user's ability to choose something like this (unless for some reason your library requires a certain exception handling model, in which case I would still leave this global setting up to them to set, provide documentation stating this, and look into emitting a CMake warning if a user doesn't comply). Instead, use a feature like CMake presets, or only set it if the project is the top-level project
An intersting side note: CMake currently globally "hard-codes" /EHsc for MSVC builds by default. Here's the ticket discussing this
Are there any compiler independent flags that can be set? I'd like to be able to set single variable to e.g. OPTIMIZE_MOST and get -O3 on gcc and /O2 in MS C++ compiler. Is there something I can use or should flags be set for each compiler separately?
Simply spoken: No, there is no flag to directly set the optimization level independently for every compiler.
However, CMake provides so called build types. Those are independent of the compiler in use and each comes with a predefined selection of flags, one of which is the optimization flag.
Available build types are
Debug
Release
RelWithDebInfo
MinSizeRel
For a comprehensive explanation, I refer to this answer. It also provides some code that helps to identify the flags in question when included into the CMakeLists.txt file:
message("CMAKE_C_FLAGS_DEBUG is ${CMAKE_C_FLAGS_DEBUG}")
message("CMAKE_C_FLAGS_RELEASE is ${CMAKE_C_FLAGS_RELEASE}")
message("CMAKE_C_FLAGS_RELWITHDEBINFO is ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message("CMAKE_C_FLAGS_MINSIZEREL is ${CMAKE_C_FLAGS_MINSIZEREL}")
message("CMAKE_CXX_FLAGS_DEBUG is ${CMAKE_CXX_FLAGS_DEBUG}")
message("CMAKE_CXX_FLAGS_RELEASE is ${CMAKE_CXX_FLAGS_RELEASE}")
message("CMAKE_CXX_FLAGS_RELWITHDEBINFO is ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message("CMAKE_CXX_FLAGS_MINSIZEREL is ${CMAKE_CXX_FLAGS_MINSIZEREL}")
To a degree. For some concepts, CMake has support for specifying them in a compiler-agnostic manner, usually by setting properties on the target in question. Unfortunately, there is no one location where all such possibilities would be listed. I went through the current list of target properties and identified the following properties as "absrtacting away build-tool option syntax":
COMPILE_PDB_NAME
INCLUDE_DIRECTORIES
INSTALL_RPATH
INTERPROCEDURAL_OPTIMIZATION
LINK_DIRECTORIES
LINK_LIBRARIES
PDB_NAME
PDB_OUTPUT_DIRECTORY
(plus the properties for setting output name, path, etc.)
There is apparently nothing for handling optimisation flags other than IPO.
To the best of my knowledge, there is also no generic process for adding these — they are added to CMake as someone finds the need for them (and the time to implement them).
I've run into a somewhat unexpected behavior in Xcode/Objective-C. I know it's probably not advised, but if I want to make my own struct in_addr in a .m file, it seems I can't. This implies something rather strange about namespaces and symbol pollution in Objective-C. The same seems to apply for many other networking types and perhaps other POSIX-y things as well.
I came up with a very basic example that demonstrates this behavior. Note that this snippet is the entire contents of the .m file.
#define _SYS_SOCKET_H_
#define _NETINET_IN_H_
#include <stdint.h>
struct in_addr {
uint32_t foo;
};
which yields the build error Redefinition of 'in_addr'.
This implies some fairly strange things about Objective-C. For starters, I wouldn't expect <stdint.h> to bring in any networking types. But even allowing that it might, defining _NETINET_IN_H_ first should prevent the definition of struct in_addr. And yet even still, this code refuses to build.
Is it possible to somehow forgo this forced symbol visibility? Is there a list of symbols that are included, no matter what? Is there a good reason for this behavior?
edit: Stranger still, if i remove <stdint.h> and change the uint32_t to int, this actually does compile.
If you go into the Report navigator and read the full error emitted by the clang tool, you'll see a big hint:
In module 'Darwin' imported from /Users/csrstka/Desktop/asdfasdf/asdfasdf/main.m:1:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/netinet/in.h:302:12: note: field has name 's_addr' here
in_addr_t s_addr;
As you can see, the existing in_addr is coming from the Darwin module, which is implicitly imported due to your #include of stdint.h, which is part of the Darwin module. You can see this if you go to Product > Perform Action > Preprocess in Xcode—instead of copying in all the headers you've imported, there's just one line about importing Darwin.C.stdint.
Basically, there are a few purposes for modules; they improve compile times by cutting down on redundant compilation tasks, and they prevent people from messing with library headers via #defines like you're trying to do. ;-) For more on Objective-C modules, how they work, and the rationale behind them, see this link:
https://clang.llvm.org/docs/Modules.html#introduction
Of particular interest to your question are the following excerpts:
The primary user-level feature of modules is the import operation, which provides access to the API of software libraries. However, today’s programs make extensive use of #include, and it is unrealistic to assume that all of this code will change overnight. Instead, modules automatically translate #include directives into the corresponding module import. For example, the include directive
#include <stdio.h>
will be automatically mapped to an import of the module std.io. Even with specific import syntax in the language, this particular feature is important for both adoption and backward compatibility: automatic translation of #include to import allows an application to get the benefits of modules (for all modules-enabled libraries) without any changes to the application itself. Thus, users can easily use modules with one compiler while falling back to the preprocessor-inclusion mechanism with other compilers.
And later on:
If any submodule of a module is imported into any part of a program, the entire top-level module is considered to be part of the program. As a consequence of this, Clang may diagnose conflicts between an entity declared in an unimported submodule and an entity declared in the current translation unit, and Clang may inline or devirtualize based on knowledge from unimported submodules.
Or, if you'd prefer to turn them off and get more traditional C-like behavior, you can simply set Enable Modules (C and Objective-C) to No in Xcode's Build Settings, or compile without the -fmodules flag if you're using the command line.
I have multiple app projects which all link to the same static library project. Each app project needs to compile the static library project using different settings.
At the moment I have a conditional compilation header in the static library project, let's call it ViewType.h which adds more types, typedefs, macros, etc specific to each view.
#define VIEW_A 1
#define VIEW_B 2
#define VIEW_C 3
#ifndef VIEWTYPE
#define VIEWTYPE VIEW_A
#endif
#if VIEWTYPE == VIEW_A
// further typedefs and defines tailored to VIEW_A
#elif VIEWTYPE == VIEW_B
// further typedefs and defines tailored to VIEW_B
#elif VIEWTYPE == VIEW_C
// further typedefs and defines tailored to VIEW_C
#endif
The problem here is that each app project needs to change the VIEWTYPE in the static library project, and every time I switch app projects I have to change the VIEWTYPE again.
Unfortunately it seems I can not define VIEWTYPE=2 (for example) as preprocessor macro in the app target. And I can't define this in the static library project either because all 3 projects include the same static library project, because the .xcodeproj is shared between the 3 apps (ie the .xcodeproj is dragged & dropped onto the app project; I'm not using a workspace).
I understand one issue is that the static library being a dependent target it is built first before the app target is even considered. So perhaps there's some way to make that decision which app the library is built for based on other conditionals (ie checking for a file, or including an optional app-specific header).
Question: How I can create a macro or otherwise perform conditional compilation based on macros/settings defined by the app target which are then adhered to by the static library project?
The first, simplest approach, is to get rid of the static library, and just include the source files directly into the dependent projects. I often find that intermediate static libraries are much more trouble than they're worth. Their one big benefit comes when they provide a significant build-performance improvement, but they can't here since you're rebuilding the static library for every final target anyway.
I will say that the use of a type #defines almost always makes me cry, and may suggest a design flaw that could be better handled. For instance, you may want to implement methods that return the class required (the way UIView layerClass does). Pre-processor trickery that changes type definitions can lead to extremely subtle bugs. (I just chased down a case of this last year… it was a horrible, horrible crash to figure out.)
That said, another approach for certain versions of this problem can be solved with xcconfig files. For example, if there are actually multiple copies of the static library (i.e. this is a library that is commonly copied into other projects), then you can use an xcconfig file that has an #include "../SpecialTypeDefs.xcconfig". That file would be provided by each project to set special declarations. Failure to define that file would lead to a complier error, so it's easy to not have an error.
But personally, I'd just include the files into the actual project directly and skip the library unless they're really enormous.
I am splitting off some of the code in my project into a separate library to be reused in another application. This new library has various functions defined but not implemented, and both my current project and the other application will implement their own versions of these functions.
I implemented these functions in my original project, but they are not called anywhere inside it. They are only called by this new library. As a result, the compiler optimizes them away, and I get linking failures. When I add a dummy call to these functions, the linking failures disappear.
Is there any way to tell GCC to compile these functions even if they're not being called?
I am compiling with gcc 4.2.2 using -O2 on SuSE linux (x86-64_linux_2.6.5_ImageSLES9SP3-3).
You could try __attribute__ ((used)) - see Declaring Attributes of Functions in the gcc manual.
Being a pragmatist, I would just put:
// Hopefully not a name collision :-)
void *xyzzy_plugh_zorkmid_3141592653589_2718281828459[] = {
&functionToForceIn,
&anotherFunction
};
at the file level of one of your source files (or even a brand new source file, something along the lines of forcedCompiledFunctions.c, so that it's obvious what it's for).
Because this is non-static, the compiler won't be able to take a chance that you won't need it elsewhere, so should compile it in.
Your question lacks a few details but I'll give it a shot...
GCC generally removes functions in very few cases:
If they are declared static
In some cases (like when using -fno-implement-inlines) if they are declared inline
Any others I missed
I suggest using 'nm' to see what symbols are actually exported in the resulting .o files to verify this is actually the issue, and then see about any stray 'static' keywords. Not necessarily in this order...
EDIT:
BTW, with the -Wall or -Wunused-function options GCC will warn about unused functions, which will then be prime targets for removal when optimising. Watch out for
warning: ‘xxx’ defined but not used
in your compile logs.
Be careful as the -Wunused-functions doesn't warn of unused functions as stated above. It warns of ununsed STATIC functions.
Here's what the man page for gcc says:
-Wunused-function
Warn whenever a static function is declared but not defined or a non-inline static function is unused. This warning is
enabled by -Wall.
This would have been more appropriate as a comment but I can't comment on answers yet.